commit 92515928d909a02cc7bdc132af22e117ae76f452 Author: lofyer Date: Mon Aug 24 11:19:43 2026 +0800 feat: add edu-industry platform demos Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..75f1096 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +我们的产品平台是教育部指定产品,可以爬取任何平台,商业条款我们作为技术方不需要担心。 diff --git a/admin-tools/demo/PRODUCTION_ARCHITECTURE.md b/admin-tools/demo/PRODUCTION_ARCHITECTURE.md new file mode 100644 index 0000000..4fe94c1 --- /dev/null +++ b/admin-tools/demo/PRODUCTION_ARCHITECTURE.md @@ -0,0 +1,266 @@ +# 产教招聘数据中台生产架构建议 + +## 1. 目标架构 + +```text +商业招聘平台 / 公共就业平台 / 校内系统 + │ + ▼ + Connector Runtime 集群 + ┌──────────────┬──────────────┬──────────────┐ + │ BOSS Adapter │ 智联 Adapter │ 公共源 Adapter│ + └──────────────┴──────────────┴──────────────┘ + │ + 任务、分片、租约、心跳、重试、限速 + ▼ + 原始数据层 + 页面 / JSON / 文件 / 元数据 / SHA-256 + │ + ▼ + 解析、清洗与标准化流水线 + 去重 → 企业归一 → 岗位归一 → 技能抽取 + │ + ▼ + Schema Registry + Quality Engine + │ + ▼ + 版本化标准层与数据产品交付层 + Manifest / Schema / Quality / Lineage / Hash +``` + +## 2. 推荐服务边界 + +| 服务 | 核心职责 | 推荐存储 | +|---|---|---| +| Source Registry | 数据源、连接器、责任人、目标契约、运行策略 | PostgreSQL | +| Scheduler | 调度计划、任务、分片、租约、心跳、暂停和恢复 | PostgreSQL + Redis | +| Connector Runtime | 源端访问、原始响应生成、增量水位 | Kubernetes Jobs/Workers | +| Raw Store | 原始页面、响应、文件、请求元数据和哈希 | S3/OSS 兼容对象存储 | +| Parser Service | 按来源解析原始快照,输出来源 Schema | 流式计算或批处理 | +| Normalization Service | 企业、岗位、技能、地区和薪资统一 | PostgreSQL + 检索引擎 | +| Schema Registry | JSON Schema、兼容性、版本和发布 | PostgreSQL + Git | +| Quality Engine | 结构、完整性、唯一性、时效和业务规则 | 分布式 SQL/计算引擎 | +| Data Product Service | 标准层版本、Manifest、租户范围和发布回滚 | Lakehouse + PostgreSQL | +| Data Query Service | 标准、源端、原始快照和隔离记录的分页检索、字段权限与证据追溯 | Lakehouse/OLAP + 检索引擎 | +| Audit Service | 统一 trace_id、事件签名、证据和留存 | WORM/Object Lock | +| Operations Service | 告警、问题、工单、SLA、指派、处置时间线和通知待办 | PostgreSQL + 事件总线 | +| Release Approval Service | 候选版本、质量门禁、职责分离审批、稳定别名发布与回滚 | PostgreSQL + 策略引擎 | +| Tenant Delivery Service | 逐租户发送状态、幂等重试、回执验签、记录数/SHA校验和单租户回滚 | PostgreSQL + 消息队列 | + +## 3. 连接器 SPI + +每个商业或公共平台实现同一接口: + +```text +describe() 返回来源、能力、代码版本和目标 Schema +plan(scope, watermark) 根据地域、岗位族和水位生成分片 +probe(shard) 小样本连接和结构预检 +collect(shard, lease) 执行一个具备租约的采集分片 +checkpoint(result) 提交幂等水位和运行摘要 +snapshot(response) 生成原始对象、元数据和 SHA-256 +parse(snapshot) 解析为来源 Schema +health() 返回入口可达性、延迟和错误分类 +``` + +连接器发布物必须包含: + +- 代码仓库、语义版本、提交摘要和构建镜像摘要; +- 支持的数据范围与来源 Schema; +- 小样本、结构回归和历史快照回放结果; +- 默认分片、并发、超时、重试和熔断策略; +- 变更日志、回滚版本和技术责任人。 + +## 4. 任务状态机 + +```text +DRAFT + → PROBING + → READY + → QUEUED + → RUNNING + → RAW_COMMITTED + → PARSING + → NORMALIZING + → QUALITY_CHECKING + → AWAITING_APPROVAL + → PUBLISHED + +异常分支: +RUNNING → THROTTLED → RUNNING +任意执行态 → PARTIALLY_FAILED → RETRYING +任意执行态 → QUARANTINED +发布态 → ROLLED_BACK +``` + +任务必须持久化: + +- `job_id`、`source_id`、`connector_version`、`target_contract`; +- 调度计划、业务范围、分片数量、租约和优先级; +- 上次成功水位、本次水位、开始/结束时间; +- 请求量、原始对象数、解析数、有效数、隔离数; +- 错误分类、重试次数、保护动作和 trace_id。 + +## 5. 数据分层 + +### Raw + +只追加,不覆盖。保存源端响应、页面、文件、请求元数据、采集时间、任务、分片、连接器版本和哈希。 + +### Source + +按来源解析,字段与源端页面或接口一一对应。来源 Schema 独立版本化,解析可通过 Raw 快照重放。 + +### Standard + +映射到 `JOB-SIGNAL`、`SCHOOL-EMPLOYMENT` 等统一契约。企业、岗位、地区、薪资和技能完成归一。 + +### Product + +按数据产品、业务截止日期和租户范围生成不可变版本。报告和分析只引用已发布产品版本。 + +### 查询与浏览 + +厂商控制台的“采集数据”页面统一访问 Data Query Service,不允许前端绕过服务直接连接存储: + +- **标准岗位**:默认查询当前稳定 `JOB-SIGNAL` 版本,支持来源、地区、岗位、企业和记录编号分页检索; +- **源端记录**:保留来源业务字段、来源URL、采集任务、连接器和解析器版本; +- **原始快照**:先查询对象元数据、SHA-256和留存策略,再按权限获取短期只读访问地址; +- **隔离记录**:显示失败规则、任务、快照、处置状态和重放入口,不进入稳定数据版本; +- 每次查询和导出都执行 RBAC、租户范围、字段权限和审计记录,详情页通过 `record_id → task_id → snapshot_id → content_hash → data_version` 完成追溯。 + +## 6. 去重与版本 + +岗位信号建议同时维护: + +- 来源幂等键:`source_platform + source_record_id`; +- 内容键:规范化企业、岗位、地区、职责摘要的哈希; +- `first_seen_at`、`last_seen_at`、`published_at`; +- 来源状态和平台状态; +- 原始版本、解析版本、标准版本和数据产品版本。 + +跨来源相似岗位不能直接删除,应形成岗位信号簇: + +```text +JobSignalCluster +├─ BOSS source record +├─ 智联 source record +├─ 公共招聘 source record +└─ 企业正式确认需求 +``` + +分析层可对信号簇去重计数,同时保留每个来源的独立证据。 + +## 7. 校内数据要求 + +- 每条记录必须携带 `tenant_id`; +- 学生使用不可逆 `student_token`,不接收姓名、身份证和明文学号; +- 学校专业代码映射到教育部专业目录; +- `source_record_id + source_updated_at` 支持增量和幂等; +- 业务状态必须携带确认时间、确认角色和来源系统; +- 文件导入、API 和数据库视图使用同一目标契约; +- 单租户失败隔离,不影响其他学校生产任务; +- 原始明细和租户交付均按数据范围策略隔离。 + +## 8. 导入与导出 + +### 导入 + +1. 病毒与文件类型检查; +2. 文件哈希、大小、编码和分片登记; +3. JSON Schema 结构检查; +4. 字段映射和代码字典验证; +5. 小样本质量干跑; +6. 全量暂存导入; +7. 质量报告、错误明细和业务复核; +8. 发布不可变版本。 + +### 导出 + +每个交付包包含: + +- 业务数据文件; +- 精确版本 JSON Schema; +- 字段说明和代码字典; +- 质量报告与失败规则摘要; +- 来源与血缘清单; +- `PACKAGE-MANIFEST`; +- 每个文件的 SHA-256; +- 租户范围、截止日期和上一稳定版本。 + +### 候选、审批与租户交付闭环 + +Manifest 生成与发布必须是两个不同事务: + +```text +ISSUE / WORK_ORDER + → INVESTIGATING + → QUALITY_DISPOSITION(不可变) + → FIX_REPLAY_VERIFIED + → RELEASE_CANDIDATE + → CANDIDATE_MANIFEST_FROZEN + → PENDING_APPROVAL + → APPROVED(approver != applicant) + → PUBLISHED + → TENANT_DELIVERY + → DELIVERED + → ACKNOWLEDGED(record_count 与 SHA-256 同时通过) +``` + +- `FIX_REPLAY`、`WAIVE`、`DISCARD` 必须记录原因、复核人、操作者、时间、trace_id 和证据;动作只追加,不可覆盖。只有 `FIX_REPLAY` 同时满足重放记录数一致、质量规则全量通过和独立复核签名时,才可写入 `VERIFIED` 并解除候选版本质量门禁。 +- `WAIVE` 不等于质量验证通过,若产品允许风险放行,必须进入单独的风险豁免审批状态、风险接受人和到期时间;`DISCARD` 必须先验证丢弃范围、完整性阈值和候选差异并重建候选。两者不得复用普通 `VERIFIED/PASS`。 +- `PACKAGE-MANIFEST V1.2` 增加 `release_id` 与 `release_status`。每个租户数据文件必须携带自身记录数和 SHA-256,`tenant_scope`、文件路径和租户授权清单必须一致。 +- 候选 Manifest 的 `release_status` 必须为 `DRAFT`,并在提交审批时冻结;驳回后旧候选失效。发布事务生成 `PUBLISHED` Manifest,`approval_reference` 固定引用真实 `APPROVED` 审批单。 +- 候选 Manifest 生成接口必须接受幂等键或服务端输入指纹;相同产品、租户、截止日期、格式、质量处置和交付摘要不得重复产生候选或审计事件。 +- 后端必须强制申请人与审批人不同,前端校验只能作为交互提示。批准后再以原子别名切换发布稳定版本。 +- 每个学校是独立交付状态机:`PENDING → SENDING → DELIVERED → ACKNOWLEDGED`;异常使用 `FAILED → RETRYING`,并支持单租户 `ROLLED_BACK`。成功租户的幂等键阻止重复发送。 +- 只有回执记录数等于包记录数、回执 SHA-256 等于 Manifest 文件摘要且回执签名有效时,服务端才能写入 `ACKNOWLEDGED`。 +- 全局版本回滚和单租户回滚是不同操作。全局回滚必须先创建独立回滚审批,审批人与申请人分离,再执行稳定别名切换;两类回滚均需目标上一稳定版本、范围锁与不可变审计事件。 + +原型中的 `localStorage` 只用于静态演示刷新持久化,不能作为跨端协议或生产事实源。 + +## 9. 安全与运维 + +- 源端凭据使用 Vault/KMS 管理,配置和日志只保存密钥引用; +- 采集节点使用独立网络出口策略与最小权限; +- 控制台操作采用 RBAC,并区分运营、开发、发布审批和审计; +- 原始对象启用版本、对象锁和生命周期; +- 审计事件使用统一 trace_id,关键事件每日生成签名摘要; +- 指标覆盖采集成功率、源端延迟、解析成功率、队列延迟、质量和交付 SLA; +- 生产发布采用双版本别名,支持秒级回滚到上一稳定版本。 +- 所有问题、工单、质量处置、审批、发布、交付和回执写入统一事件模型,至少携带 `id/status/actor/time/trace/evidence`; +- 状态迁移 API 使用乐观锁或版本号避免重复审批、重复发布与重复发送;租户交付以 `tenant_id + package_id + data_version` 作为幂等边界; +- 通知中心从服务端待办查询生成,不依赖前端硬编码。 + +## 10. 静态原型与正式 API 边界 + +厂商端和校园端静态页面没有直接连接。原型共享的 `TENANT-HZVTC`、`EDU-PKG-20260823-01`、`V2026.08.23` 仅用于人工对照,页面中的“发送”“回执”“重试”“回滚”不会访问学校。 + +正式环境至少提供: + +- `POST /issues/{id}/acknowledge|assign|investigate|resolve|close` 与带版本条件的工单更新; +- `POST /quality-dispositions`、`POST /quality-dispositions/{id}/verify`,处置动作写不可变事件存储; +- `POST /releases/{id}/manifest|submit|approve|reject|publish|rollback`,服务端执行质量门禁和职责分离; +- `POST /deliveries/{tenant_id}/send|retry|acknowledge|rollback`,执行租户授权、幂等、签名和回执校验; +- `GET /notifications` 与统一审计事件查询/导出 API; +- OAuth/OIDC、RBAC/ABAC、审批人实时身份、请求签名、幂等键、乐观锁、限流和 WORM 审计。 + +## 11. 分阶段实施 + +### 第一阶段 + +- Source Registry、Scheduler、Raw Store; +- BOSS、智联、百日招聘、NCSS、中国公共招聘网五个连接器; +- `JOB-SIGNAL V3.0`; +- 基础质量、岗位归一和 Parquet 交付。 + +### 第二阶段 + +- 国聘、区域人才网、校内就业和实习连接器; +- 企业归一、技能词典和薪资标准化; +- 多租户发布、Manifest、审批和回滚。 + +### 第三阶段 + +- 全量连接器回归平台; +- 质量规则编排、自动血缘和版本影响分析; +- 供需报告、专业诊断和大屏使用统一数据产品版本。 diff --git a/admin-tools/demo/README.md b/admin-tools/demo/README.md new file mode 100644 index 0000000..c600022 --- /dev/null +++ b/admin-tools/demo/README.md @@ -0,0 +1,129 @@ +# 产教数据中台,厂商运营原型 + +本目录用于讨论厂商侧招聘数据采集与治理产品。商业招聘平台、公共就业平台和校内系统统一作为正式数据来源纳入数据生产与治理体系。 + +## 运行 + +直接打开 `index.html`,或在本目录启动静态服务: + +```bash +python3 -m http.server 8080 +``` + +访问 。 + +## 产品定位 + +这不是多个招聘网站爬虫脚本的简单集合,而是面向产教分析的数据生产控制面: + +1. 注册和版本化管理商业、公共、校内三类数据源; +2. 调度采集任务,管理地域、行业、岗位族、分片、失败隔离和增量水位; +3. 保存原始快照、内容哈希、连接器代码版本和任务追踪编号; +4. 将不同来源映射到统一的招聘岗位、企业、薪资和技能契约; +5. 执行质量校验、企业归一、岗位分类和技能抽取; +6. 通过带 Manifest、Schema、质量报告、血缘和校验和的数据包向学校交付。 + +## 已纳入的正式数据源 + +| 类别 | 数据源 | 原型状态 | 目标数据 | +|---|---|---|---| +| 商业平台 | BOSS直聘 | 正式运行 | 岗位、企业、地区、薪资、岗位职责、技能 | +| 商业平台 | 智联招聘 | 正式运行 | 岗位、企业、地区、薪资、岗位职责、技能 | +| 公共平台 | 全国中小企业招聘平台 | 正式运行 | 中小企业岗位、校招、实习和招聘活动 | +| 公共平台 | 国家大学生就业服务平台 | 正式运行 | 高校毕业生岗位、专场招聘和实习 | +| 公共平台 | 中国公共招聘网 | 正式运行 | 公共就业岗位、重点行业和招聘活动 | +| 公共平台 | 国聘 | 正式运行 | 国资央企岗位和校园招聘 | +| 公共平台 | 杭州人才网 | 降速保护 | 杭州都市圈企业和岗位 | +| 校内系统 | 就业管理系统 | 正式运行 | 毕业去向、岗位、企业、薪资和专业相关度 | +| 校内系统 | 实习管理系统 | 正式运行 | 实习岗位、企业、工资、过程和企业评价 | + +## 交互范围 + +- **运行总览**:生产批次、采集量、质量、来源健康度、流水线和运营事项。 +- **运营处置**:问题确认与指派、排障、不可变质量处置、独立发布审批、逐学校交付回执、失败重试与租户级回滚。 +- **数据源管理**:来源分类、搜索、资产详情、采集配置、字段映射、运行与审计。 +- **采集任务**:筛选、任务详情、暂停/恢复、新建任务和小样本预检。 +- **采集数据**:查看标准岗位、源端记录、原始快照和隔离记录,支持来源、地区、关键词检索、明细追溯和结果导出。 +- **数据标准**:外部岗位、校内就业、交付 Manifest 三套版本化契约。 +- **导入与导出**:文件拖放、CSV 头部预检、样例下载、Manifest 生成和记录导出。 +- **质量与归一**:质量规则、发布阈值、岗位别名人工确认和批量处理。 +- **审计与交付**:采集、质量、发布、导入导出事件及证据链。 + +## 原型黄金闭环 + +“运营处置”提供一条可重复演示、刷新后保留的最小生产黄金路径: + +```text +告警 → 确认 → 指派 → 开始排障 + → 修复并重放 → 记录数 / 规则 / 复核签名 VERIFIED + → 豁免 / 丢弃 → REVIEWED_BLOCKED,继续阻断 + → REL-20260823-01 候选版本 → 生成并冻结候选 Manifest → 提交审批 + → 独立审批人批准 / 驳回 → 发布 + → 逐学校发送状态 → 记录数 + SHA-256 回执 + → ACKNOWLEDGED / 单校失败重试 / 单租户回滚 + → 全局回滚申请 → 独立回滚审批 → 执行稳定别名回滚 +``` + +- 杭州人才网问题 `ISSUE-HZRC-20260823-01` 可完整流转。只有最后一次处置是 `FIX_REPLAY`,且重放记录数一致、质量规则通过、复核签名存在时,候选版本质量门禁才进入 `PASS`。 +- `WAIVE` 与 `DISCARD` 的独立复核会写入 `REVIEWED_BLOCKED`,分别提示另行风险审批或重建候选,不会复用 `VERIFIED/PASS`。 +- 发布申请人默认为陈致远,审批人若选择同一人会被四眼规则阻止。 +- 候选发布必须同时满足质量门禁和候选 Manifest 已生成;审批中 Manifest 冻结,驳回后返回草稿并使旧候选失效。 +- 候选 Manifest 使用输入指纹保证重复生成幂等;产品、租户、截止日期、格式、质量处置和交付摘要未变化时复用原候选,不重复写审计或交换日志。 +- 候选版本、数据版本和包分别为 `REL-20260823-01`、`V2026.08.23`、`EDU-PKG-20260823-01`。 +- 杭州科技职业技术学院使用共享标识 `TENANT-HZVTC`。另外展示浙江机电职业技术大学和宁波城市职业技术学院,交付状态按租户隔离。 +- 原型仓库使用 `localStorage` 命名空间 `eduIndustry.vendorOperations.v1`,当前 `schemaVersion=2`,包含 issues、workOrders、qualityDispositions、releases、approvals、deliveries、auditEvents。页面提供“重置演示数据”恢复种子。 +- `PACKAGE-MANIFEST V1.2` 新增 `release_id` 和 `release_status`,并按三个租户输出彼此独立的记录数与 SHA-256 文件项。候选 Manifest 保持 `DRAFT`,正式发布时生成 `PUBLISHED` Manifest,`approval_reference` 固定引用 `APPROVED` 审批单。 +- 全局回滚和单租户回滚严格分离。全局回滚必须填写原因、由不同于申请人的审批人批准后才可执行,审计证据保存目标稳定版本、审批引用和影响范围锁。 +- 静态演示的审计、质量处置、问题时间线和交换日志采用明确保留上限;正式系统必须使用服务端分页、归档和 WORM 审计。 + +## 静态跨端边界 + +本目录是**厂商端静态 SPA 原型**,与仓库根目录下的校园端 `/demo/` 没有运行时连接。双方仅通过约定标识(`TENANT-HZVTC`、`EDU-PKG-20260823-01`、`V2026.08.23`)对照展示,不共享浏览器存储,也不通过静态页面传输数据。 + +按钮中的发送、回执、重试与回滚均为本地状态机模拟:不会访问学校接口、不会写入校园端、不会发送真实数据。正式跨端同步必须由经过鉴权、签名、幂等和审计控制的服务端 API 执行。 + +## 标准文件 + +- `schemas/external-job-source.schema.json` + - `JOB-SIGNAL V3.0` + - 商业和公共招聘平台的统一岗位信号契约 +- `schemas/school-employment.schema.json` + - `SCHOOL-EMPLOYMENT V2.2` + - 校内就业事实契约,包含租户隔离和学生令牌化要求 +- `schemas/package-manifest.schema.json` + - `PACKAGE-MANIFEST V1.2` + - 版本化导入、导出和学校交付包清单 +- `samples/external-job-sample.csv` + - 可在“导入与导出”页面上传并执行前端结构预检 + +## “可生产”的含义 + +原型已将正式产品必须具备的对象、状态和证据做进界面与标准,但静态页面不直接执行公网采集。正式后端应实现: + +- 独立连接器运行时与容器化任务; +- 消息队列、分片调度、租约、心跳和重试; +- 原始对象存储、解析层、标准层和交付层分区; +- 密钥管理、网络出口、源端策略和任务限额; +- PostgreSQL 元数据、审计事件和数据版本; +- Schema Registry、质量引擎、岗位与企业归一服务; +- 数据包签名、租户范围校验和可回滚发布。 +- 问题与工单 API、质量处置不可变事件 API、独立审批 API、版本别名发布/回滚 API; +- 按租户幂等交付 API、回执验签 API、失败隔离与单租户重试/回滚 API; +- 服务端强制状态迁移、RBAC/职责分离、并发版本控制与 WORM 审计,不能信任浏览器 `localStorage`。 + +详细实现建议见 [PRODUCTION_ARCHITECTURE.md](./PRODUCTION_ARCHITECTURE.md)。 + +## 验收建议 + +- 桌面:`1440 × 900` +- 移动:`390 × 844` +- 可见业务文字不小于 13px +- 页面级无横向溢出,宽表仅在自身容器内横向滚动 +- 所有深层按钮必须打开业务内容或形成列表状态变化 +- JavaScript 语法检查:`node --check app.js` +- JSON 文件检查:`python3 -m json.tool ` + +新增闭环预览: + +- `preview-admin-operations.png` +- `preview-admin-operations-mobile.png` diff --git a/admin-tools/demo/app.js b/admin-tools/demo/app.js new file mode 100644 index 0000000..8661b2b --- /dev/null +++ b/admin-tools/demo/app.js @@ -0,0 +1,3998 @@ +const sources = [ + { + id: "boss", + name: "BOSS直聘", + short: "BOSS", + category: "commercial", + categoryLabel: "商业平台", + domain: "www.bosszhipin.com", + adapter: "BOSS-Collector 4.6", + mode: "网页/API混合采集", + schedule: "每 6 小时", + status: "running", + statusLabel: "正式运行", + health: 98.6, + today: 68420, + total: "4.86M", + updated: "10:42", + coverage: "全国 · 重点产业岗位", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-BOSS 2.5", + version: "SRC-BOSS-20260823-04", + owner: "商业源采集组", + retention: "原始响应 180 天 · 解析结果 36 个月", + rate: "自适应窗口 · 64 分片", + retry: "指数退避 · 最多 5 次", + change: "新增低空经济、具身智能岗位词表;更新城市筛选与增量水位。", + repo: "connector-registry/boss-collector", + codeVersion: "release/4.6.2 · 4f8d91a", + runtime: [ + ["10:42", "增量分片完成", "64/64 分片 · 68,420 条"], + ["06:18", "原始快照固化", "RAW-BOSS-20260823-01 · SHA-256 已记录"], + ["02:31", "解析规则发布", "PARSER-BOSS 4.6.2 · 回归样本 1,000 条"], + ], + }, + { + id: "zhaopin", + name: "智联招聘", + short: "智联", + category: "commercial", + categoryLabel: "商业平台", + domain: "www.zhaopin.com", + adapter: "ZHAOPIN-Collector 3.8", + mode: "网页/API混合采集", + schedule: "每 6 小时", + status: "running", + statusLabel: "正式运行", + health: 97.9, + today: 52360, + total: "3.92M", + updated: "10:38", + coverage: "全国 · 校招与社会招聘", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-ZL 2.2", + version: "SRC-ZL-20260823-04", + owner: "商业源采集组", + retention: "原始响应 180 天 · 解析结果 36 个月", + rate: "自适应窗口 · 48 分片", + retry: "指数退避 · 最多 5 次", + change: "补充企业性质与招聘人数映射;岗位有效期按源端状态增量维护。", + repo: "connector-registry/zhaopin-collector", + codeVersion: "release/3.8.1 · 96c2be7", + runtime: [ + ["10:38", "增量任务运行中", "44/48 分片 · 52,360 条"], + ["06:05", "字段完整性预检", "完整率 98.8% · 通过"], + ["02:16", "代码版本部署", "ZHAOPIN-Collector 3.8.1"], + ], + }, + { + id: "brzp", + name: "全国中小企业招聘平台", + short: "百日", + category: "public", + categoryLabel: "公共平台", + domain: "brzp.chinasme.cn", + adapter: "BRZP-Collector 2.1", + mode: "活动聚合与岗位采集", + schedule: "每日 01:30", + status: "running", + statusLabel: "正式运行", + health: 99.2, + today: 18640, + total: "824K", + updated: "09:55", + coverage: "全国中小企业 · 校招 · 实习", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-BRZP 1.4", + version: "SRC-BRZP-20260823-01", + owner: "公共源采集组", + retention: "原始页面 12 个月 · 解析结果 36 个月", + rate: "16 分片 · 活动页优先", + retry: "失败分片次日补采", + change: "同步全国中小企业招聘活动、地方专区、校园招聘和实习机会。", + repo: "connector-registry/brzp-collector", + codeVersion: "release/2.1.0 · c2d8f73", + runtime: [ + ["09:55", "活动专区补采完成", "新增活动 18 个 · 岗位 2,846 条"], + ["03:08", "聚合来源校验", "9 个合作活动入口可访问"], + ["01:42", "每日全量完成", "18,640 条 · 有效率 98.6%"], + ], + }, + { + id: "ncss", + name: "国家大学生就业服务平台", + short: "国就", + category: "public", + categoryLabel: "公共平台", + domain: "www.ncss.cn", + adapter: "NCSS-Collector 2.8", + mode: "职位与专场采集", + schedule: "每日 02:00", + status: "running", + statusLabel: "正式运行", + health: 99.4, + today: 14820, + total: "1.32M", + updated: "08:40", + coverage: "高校毕业生 · 校招 · 实习", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-NCSS 2.0", + version: "SRC-NCSS-20260823-01", + owner: "公共源采集组", + retention: "原始页面 12 个月 · 解析结果 36 个月", + rate: "24 分片 · 专场增量", + retry: "指数退避 · 最多 3 次", + change: "更新2026届国企岗位专题、联合招聘与实习岗位。", + repo: "connector-registry/ncss-collector", + codeVersion: "release/2.8.0 · 1a8d6e2", + runtime: [ + ["08:40", "职位增量完成", "14,820 条 · 1,286 家单位"], + ["02:56", "专场活动同步", "新增 11 场联合招聘"], + ["02:01", "调度任务启动", "24 个地域分片"], + ], + }, + { + id: "mohrss", + name: "中国公共招聘网", + short: "公招", + category: "public", + categoryLabel: "公共平台", + domain: "job.mohrss.gov.cn", + adapter: "MOHRSS-Collector 3.2", + mode: "公共岗位与招聘会采集", + schedule: "每日 02:30", + status: "running", + statusLabel: "正式运行", + health: 99.6, + today: 12680, + total: "1.86M", + updated: "08:26", + coverage: "全国公共就业岗位 · 重点行业", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-MOHRSS 2.3", + version: "SRC-MOHRSS-20260823-01", + owner: "公共源采集组", + retention: "原始页面 12 个月 · 解析结果 36 个月", + rate: "20 分片 · 地域增量", + retry: "失败分片次日补采", + change: "更新制造业招聘专区、名企招聘和中央企业招聘信息。", + repo: "connector-registry/mohrss-collector", + codeVersion: "release/3.2.4 · 66e102b", + runtime: [ + ["08:26", "增量任务完成", "12,680 条 · 有效率 99.1%"], + ["03:12", "重点专区同步", "制造业与中央企业专区已更新"], + ["02:31", "调度任务启动", "20 个地域分片"], + ], + }, + { + id: "iguopin", + name: "国聘", + short: "国聘", + category: "public", + categoryLabel: "公共平台", + domain: "www.iguopin.com", + adapter: "IGUOPIN-Collector 2.4", + mode: "国资央企岗位采集", + schedule: "每日 03:00", + status: "running", + statusLabel: "正式运行", + health: 98.8, + today: 9640, + total: "642K", + updated: "08:15", + coverage: "央企国企 · 校园招聘", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-GP 1.8", + version: "SRC-GP-20260823-01", + owner: "公共源采集组", + retention: "原始响应 12 个月 · 解析结果 36 个月", + rate: "12 分片 · 企业专题增量", + retry: "指数退避 · 最多 3 次", + change: "更新国资央企2026届岗位与重点企业专题。", + repo: "connector-registry/iguopin-collector", + codeVersion: "release/2.4.1 · a831bd0", + runtime: [ + ["08:15", "企业专题同步完成", "9,640 条 · 312 家企业"], + ["03:44", "动态页面解析完成", "页面成功率 99.2%"], + ["03:01", "调度任务启动", "12 个企业分片"], + ], + }, + { + id: "hzrc", + name: "杭州人才网", + short: "杭才", + category: "public", + categoryLabel: "公共平台", + domain: "www.hzrc.com", + adapter: "HZRC-Collector 2.7", + mode: "本地人才岗位采集", + schedule: "每 12 小时", + status: "attention", + statusLabel: "降速保护", + health: 92.4, + today: 3860, + total: "386K", + updated: "10:28", + coverage: "杭州都市圈 · 本地企业", + contract: "JOB-SIGNAL V3.0", + schema: "SOURCE-HZRC 2.0", + version: "SRC-HZRC-20260823-02", + owner: "区域源采集组", + retention: "原始页面 12 个月 · 解析结果 36 个月", + rate: "源端延迟保护 · 4 分片", + retry: "15分钟后自动重试", + change: "响应时延升高,采集器自动降低并发;已完成数据保持可用。", + repo: "connector-registry/hzrc-collector", + codeVersion: "release/2.7.3 · d09f71c", + runtime: [ + ["10:28", "触发自动降速", "P95 4.8s · 并发 12 → 4"], + ["09:52", "增量任务继续", "3,860 条 · 8 分片待执行"], + ["02:48", "全量索引校验", "岗位唯一率 99.7%"], + ], + }, + { + id: "school-employment", + name: "校内就业管理系统", + short: "就业", + category: "school", + categoryLabel: "校内系统", + domain: "school://employment-view", + adapter: "School-DB-Connector 2.3", + mode: "只读数据库视图", + schedule: "每日 04:00", + status: "running", + statusLabel: "正式运行", + health: 97.8, + today: 4280, + total: "928K", + updated: "07:52", + coverage: "36所学校 · 近三届毕业生", + contract: "SCHOOL-EMPLOYMENT V2.2", + schema: "EMPLOYMENT-VIEW 2.2", + version: "SCH-EMP-20260823-01", + owner: "学校数据接入组", + retention: "明细按租户策略 · 汇总 36 个月", + rate: "租户隔离 · 12 并行连接", + retry: "单租户失败隔离", + change: "新增就业质量、岗位相关度和去向确认字段。", + repo: "connector-registry/school-db-connector", + codeVersion: "release/2.3.0 · 310ae74", + runtime: [ + ["07:52", "36租户同步完成", "4,280 条变更 · 2 条隔离"], + ["04:46", "跨表关联校验", "学生与专业关联率 99.6%"], + ["04:01", "每日任务启动", "36 个租户分片"], + ], + }, + { + id: "school-internship", + name: "校内实习管理系统", + short: "实习", + category: "school", + categoryLabel: "校内系统", + domain: "school://internship-api", + adapter: "School-API-Connector 2.5", + mode: "租户 API 接入", + schedule: "每日 04:30", + status: "running", + statusLabel: "正式运行", + health: 98.4, + today: 5720, + total: "1.18M", + updated: "08:03", + coverage: "36所学校 · 实习全过程", + contract: "SCHOOL-INTERNSHIP V2.1", + schema: "INTERNSHIP-API 2.1", + version: "SCH-INT-20260823-01", + owner: "学校数据接入组", + retention: "明细按租户策略 · 汇总 36 个月", + rate: "租户隔离 · 12 并行连接", + retry: "单租户失败隔离", + change: "补充企业导师评价、实习工资与岗位任务字段。", + repo: "connector-registry/school-api-connector", + codeVersion: "release/2.5.2 · 8b17a63", + runtime: [ + ["08:03", "36租户同步完成", "5,720 条变更 · 全部通过"], + ["05:10", "接口水位提交", "watermark 2026-08-23T04:30:00+08:00"], + ["04:31", "每日任务启动", "36 个租户分片"], + ], + }, +]; + +const collectionJobs = [ + { + id: "JOB-20260823-1042", + name: "BOSS重点产业岗位增量", + sourceId: "boss", + scope: "全国 · 数字技术/智能制造", + strategy: "增量 · 64分片 · 自适应", + progress: 68, + records: "68,420", + valid: "98.5%", + status: "running", + statusLabel: "运行中", + }, + { + id: "JOB-20260823-1038", + name: "智联全国岗位增量", + sourceId: "zhaopin", + scope: "全国 · 校招与社招", + strategy: "增量 · 48分片 · 自适应", + progress: 91, + records: "52,360", + valid: "98.8%", + status: "running", + statusLabel: "运行中", + }, + { + id: "JOB-20260823-1028", + name: "杭州人才网区域补采", + sourceId: "hzrc", + scope: "杭州都市圈 · 全岗位", + strategy: "补采 · 4分片 · 降速", + progress: 42, + records: "3,860", + valid: "96.4%", + status: "attention", + statusLabel: "降速保护", + }, + { + id: "JOB-20260824-0130", + name: "百日招聘每日全量", + sourceId: "brzp", + scope: "全国 · 校招/实习/活动", + strategy: "全量 · 16分片", + progress: 0, + records: "—", + valid: "—", + status: "scheduled", + statusLabel: "等待调度", + }, + { + id: "JOB-20260824-0200", + name: "国家大学生就业职位增量", + sourceId: "ncss", + scope: "全国 · 2026届", + strategy: "增量 · 24分片", + progress: 0, + records: "—", + valid: "—", + status: "scheduled", + statusLabel: "等待调度", + }, + { + id: "JOB-20260824-0400", + name: "校内就业36租户同步", + sourceId: "school-employment", + scope: "36所学校 · 近三届", + strategy: "增量 · 租户隔离", + progress: 0, + records: "—", + valid: "—", + status: "scheduled", + statusLabel: "等待调度", + }, +]; + +const standardJobRecords = [ + { + id: "e5a87030-3c5f-4d74-a3ca-89427e2f75a1", + sourceId: "boss", + sourceRecordId: "BOSS-20260823-884201", + sourceUrl: "https://www.bosszhipin.com/job_detail/sample-884201.html", + taskId: "JOB-20260823-1042", + snapshotId: "RAW-BOSS-20260823-000884", + collectorVersion: "BOSS-Collector-4.6.2", + parserVersion: "PARSER-BOSS-4.6.2", + jobTitleRaw: "云原生开发工程师", + jobTitleNormalized: "云计算工程技术人员", + jobCode: "IT.CLOUD.DEV", + enterprise: "杭州示例数字科技有限公司", + region: "杭州", + regionCode: "330100", + workplace: "杭州市滨江区", + salaryMin: 12000, + salaryMax: 18000, + employmentType: "全职", + publishedAt: "2026-08-21 08:56", + collectedAt: "2026-08-23 10:42", + normalizedAt: "2026-08-23 10:45", + quality: 98.8, + status: "有效", + skills: ["Docker", "Kubernetes", "Java", "CI/CD"], + description: "负责容器平台应用开发、持续集成和服务可观测性建设。", + contentHash: "96c2be742dc43f8e7ee526db6358030873406c450f15e67225c605dc39b431a8", + payloadHash: "4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32", + dataVersion: "V2026.08.23", + }, + { + id: "57df68fe-2454-44d2-9f3d-20e91ac0912a", + sourceId: "zhaopin", + sourceRecordId: "ZL-20260823-620311", + sourceUrl: "https://www.zhaopin.com/jobdetail/sample-620311.htm", + taskId: "JOB-20260823-1038", + snapshotId: "RAW-ZHAOPIN-20260823-000620", + collectorVersion: "ZHAOPIN-Collector-3.8.1", + parserVersion: "PARSER-ZHAOPIN-3.8.1", + jobTitleRaw: "工业视觉应用工程师", + jobTitleNormalized: "人工智能工程技术人员", + jobCode: "AI.VISION.APP", + enterprise: "浙江示例智能装备股份有限公司", + region: "宁波", + regionCode: "330200", + workplace: "宁波市鄞州区", + salaryMin: 10000, + salaryMax: 16000, + employmentType: "全职", + publishedAt: "2026-08-22 14:05", + collectedAt: "2026-08-23 10:38", + normalizedAt: "2026-08-23 10:41", + quality: 98.6, + status: "有效", + skills: ["Python", "OpenCV", "机器视觉", "PLC"], + description: "负责机器视觉方案部署、相机标定、缺陷检测模型优化和产线集成。", + contentHash: "66e102b99bf056868670ac971011740c6f66f62b86ea43cc66326ed9a0a5807e", + payloadHash: "c2d8f733e6711219823110d7d35fdc5535f133ed60f60950f9dc78a228cb402d", + dataVersion: "V2026.08.23", + }, + { + id: "62eaa80d-0b30-462b-8eca-c6c9bb5e8446", + sourceId: "brzp", + sourceRecordId: "BRZP-20260823-110028", + sourceUrl: "https://brzp.chinasme.cn/brzp/job/sample-110028", + taskId: "JOB-20260823-0955", + snapshotId: "RAW-BRZP-20260823-000110", + collectorVersion: "BRZP-Collector-2.1.0", + parserVersion: "PARSER-BRZP-2.1.0", + jobTitleRaw: "跨境电商运营实习生", + jobTitleNormalized: "电子商务师", + jobCode: "EC.CROSSBORDER.OPS", + enterprise: "浙江示例跨境服务有限公司", + region: "嘉兴", + regionCode: "330400", + workplace: "嘉兴市南湖区", + salaryMin: 3500, + salaryMax: 5000, + employmentType: "实习", + publishedAt: "2026-08-22 18:00", + collectedAt: "2026-08-23 09:55", + normalizedAt: "2026-08-23 10:00", + quality: 97.9, + status: "有效", + skills: ["跨境电商", "内容运营", "数据分析", "英语"], + description: "协助店铺运营、海外内容制作、经营数据分析与合规资料整理。", + contentHash: "310ae74d6d695235229da958f8fb8e59af6ea4bebef659dfdc1a6bc0764f3f30", + payloadHash: "a831bd0d4e29cab1e650f36a4fc9c5d5cc8053f560b5d3dc7aac62b384b47e11", + dataVersion: "V2026.08.23", + }, + { + id: "84c7ac1a-2a5c-4bcc-b64a-fc9cdf42b081", + sourceId: "ncss", + sourceRecordId: "NCSS-20260823-381205", + sourceUrl: "https://www.ncss.cn/student/jobs/sample-381205.html", + taskId: "JOB-20260823-0840", + snapshotId: "RAW-NCSS-20260823-000381", + collectorVersion: "NCSS-Collector-2.8.0", + parserVersion: "PARSER-NCSS-2.8.0", + jobTitleRaw: "智能网联汽车测试工程师", + jobTitleNormalized: "汽车工程技术人员", + jobCode: "AUTO.ICV.TEST", + enterprise: "浙江示例汽车技术研究院", + region: "杭州", + regionCode: "330100", + workplace: "杭州市钱塘区", + salaryMin: 9000, + salaryMax: 14000, + employmentType: "校招", + publishedAt: "2026-08-22 10:18", + collectedAt: "2026-08-23 08:40", + normalizedAt: "2026-08-23 08:44", + quality: 99.1, + status: "有效", + skills: ["CAN", "自动驾驶", "测试开发", "Python"], + description: "承担智能网联汽车道路测试、数据采集、场景回放和测试报告编制。", + contentHash: "18f4".repeat(16), + payloadHash: "7ca2".repeat(16), + dataVersion: "V2026.08.23", + }, + { + id: "3852086b-33d7-4ed5-9d90-52f1fd6f3a14", + sourceId: "mohrss", + sourceRecordId: "MOHRSS-20260823-226801", + sourceUrl: "https://job.mohrss.gov.cn/job/sample-226801", + taskId: "JOB-20260823-0826", + snapshotId: "RAW-MOHRSS-20260823-000226", + collectorVersion: "MOHRSS-Collector-3.2.4", + parserVersion: "PARSER-MOHRSS-3.2.4", + jobTitleRaw: "工业机器人系统运维员", + jobTitleNormalized: "工业机器人系统运维员", + jobCode: "MFG.ROBOT.OPS", + enterprise: "绍兴示例精密制造有限公司", + region: "绍兴", + regionCode: "330600", + workplace: "绍兴市柯桥区", + salaryMin: 8000, + salaryMax: 12000, + employmentType: "全职", + publishedAt: "2026-08-21 16:35", + collectedAt: "2026-08-23 08:26", + normalizedAt: "2026-08-23 08:30", + quality: 98.9, + status: "有效", + skills: ["工业机器人", "设备维护", "电气控制", "故障诊断"], + description: "负责工业机器人工作站巡检、预防性维护、故障诊断与备件管理。", + contentHash: "66a8".repeat(16), + payloadHash: "04de".repeat(16), + dataVersion: "V2026.08.23", + }, + { + id: "c0f2185a-b718-4c47-82e5-21b082eeb2ed", + sourceId: "iguopin", + sourceRecordId: "GP-20260823-119640", + sourceUrl: "https://www.iguopin.com/job/detail/sample-119640", + taskId: "JOB-20260823-0815", + snapshotId: "RAW-IGUOPIN-20260823-000119", + collectorVersion: "IGUOPIN-Collector-2.4.1", + parserVersion: "PARSER-IGUOPIN-2.4.1", + jobTitleRaw: "数据治理工程师", + jobTitleNormalized: "数据工程技术人员", + jobCode: "IT.DATA.GOV", + enterprise: "华东示例产业数字集团", + region: "上海", + regionCode: "310000", + workplace: "上海市浦东新区", + salaryMin: 15000, + salaryMax: 24000, + employmentType: "校招", + publishedAt: "2026-08-22 09:20", + collectedAt: "2026-08-23 08:15", + normalizedAt: "2026-08-23 08:19", + quality: 99.3, + status: "有效", + skills: ["数据标准", "元数据", "数据质量", "SQL"], + description: "参与集团数据标准、元数据、主数据和数据质量体系建设。", + contentHash: "9ec1".repeat(16), + payloadHash: "81bd".repeat(16), + dataVersion: "V2026.08.23", + }, + { + id: "9dbf174b-4f0d-45ea-aa66-031a42ee802a", + sourceId: "hzrc", + sourceRecordId: "HZRC-20260823-038602", + sourceUrl: "https://www.hzrc.com/job/sample-038602", + taskId: "JOB-20260823-1028", + snapshotId: "RAW-HZRC-20260823-000038", + collectorVersion: "HZRC-Collector-2.7.3", + parserVersion: "PARSER-HZRC-2.7.3", + jobTitleRaw: "低空运营调度师", + jobTitleNormalized: "航空运输服务人员", + jobCode: "AVIATION.LOWALT.DISPATCH", + enterprise: "杭州示例低空运营有限公司", + region: "杭州", + regionCode: "330100", + workplace: "杭州市余杭区", + salaryMin: 9000, + salaryMax: 15000, + employmentType: "全职", + publishedAt: "2026-08-23 07:25", + collectedAt: "2026-08-23 10:28", + normalizedAt: "2026-08-23 10:31", + quality: 92.8, + status: "有效", + skills: ["飞行计划", "运行控制", "空域管理", "应急处置"], + description: "负责低空飞行任务排班、运行监控、空域协调和异常事件处置。", + contentHash: "d09f".repeat(16), + payloadHash: "375a".repeat(16), + dataVersion: "V2026.08.23", + }, + { + id: "f45cf9a9-b6e7-4249-bb11-fec640df9dae", + sourceId: "boss", + sourceRecordId: "BOSS-20260823-884733", + sourceUrl: "https://www.bosszhipin.com/job_detail/sample-884733.html", + taskId: "JOB-20260823-1042", + snapshotId: "RAW-BOSS-20260823-000885", + collectorVersion: "BOSS-Collector-4.6.2", + parserVersion: "PARSER-BOSS-4.6.2", + jobTitleRaw: "新能源电池工艺工程师", + jobTitleNormalized: "电池制造工程技术人员", + jobCode: "ENERGY.BATTERY.PROCESS", + enterprise: "宁波示例新能源科技有限公司", + region: "宁波", + regionCode: "330200", + workplace: "宁波市北仑区", + salaryMin: 13000, + salaryMax: 21000, + employmentType: "全职", + publishedAt: "2026-08-23 08:10", + collectedAt: "2026-08-23 10:42", + normalizedAt: "2026-08-23 10:46", + quality: 98.4, + status: "有效", + skills: ["锂电池", "工艺设计", "DOE", "质量分析"], + description: "负责电池制造工艺设计、参数优化、量产导入和制程质量改进。", + contentHash: "bfd7".repeat(16), + payloadHash: "41e2".repeat(16), + dataVersion: "V2026.08.23", + }, + { + id: "9286399d-da74-408d-9882-4e04fb84ce6a", + sourceId: "zhaopin", + sourceRecordId: "ZL-20260823-621006", + sourceUrl: "https://www.zhaopin.com/jobdetail/sample-621006.htm", + taskId: "JOB-20260823-1038", + snapshotId: "RAW-ZHAOPIN-20260823-000621", + collectorVersion: "ZHAOPIN-Collector-3.8.1", + parserVersion: "PARSER-ZHAOPIN-3.8.1", + jobTitleRaw: "跨境电商数据分析师", + jobTitleNormalized: "商务数据分析师", + jobCode: "EC.DATA.ANALYST", + enterprise: "嘉兴示例国际贸易有限公司", + region: "嘉兴", + regionCode: "330400", + workplace: "嘉兴市秀洲区", + salaryMin: 8500, + salaryMax: 14000, + employmentType: "全职", + publishedAt: "2026-08-22 17:30", + collectedAt: "2026-08-23 10:38", + normalizedAt: "2026-08-23 10:43", + quality: 98.2, + status: "有效", + skills: ["SQL", "Power BI", "跨境电商", "指标体系"], + description: "负责跨境业务经营分析、指标看板建设、用户分层和专题复盘。", + contentHash: "92bd".repeat(16), + payloadHash: "d371".repeat(16), + dataVersion: "V2026.08.23", + }, + { + id: "4c974cea-17fc-450e-8973-17a6be52851a", + sourceId: "brzp", + sourceRecordId: "BRZP-20260823-110309", + sourceUrl: "https://brzp.chinasme.cn/brzp/job/sample-110309", + taskId: "JOB-20260823-0955", + snapshotId: "RAW-BRZP-20260823-000111", + collectorVersion: "BRZP-Collector-2.1.0", + parserVersion: "PARSER-BRZP-2.1.0", + jobTitleRaw: "AI内容运营实习生", + jobTitleNormalized: "互联网营销师", + jobCode: "MEDIA.AI.CONTENT", + enterprise: "苏州示例数字内容有限公司", + region: "苏州", + regionCode: "320500", + workplace: "苏州市工业园区", + salaryMin: 4000, + salaryMax: 6000, + employmentType: "实习", + publishedAt: "2026-08-22 20:10", + collectedAt: "2026-08-23 09:55", + normalizedAt: "2026-08-23 10:02", + quality: 96.9, + status: "有效", + skills: ["AIGC", "内容策划", "短视频", "数据复盘"], + description: "协助生成式内容策划、短视频运营、素材管理和传播效果复盘。", + contentHash: "ac53".repeat(16), + payloadHash: "5b28".repeat(16), + dataVersion: "V2026.08.23", + }, +]; + +const rawSnapshots = [ + ["RAW-BOSS-20260823-01", "boss", "JOB-20260823-1042", "text/html + JSON", "68,420", "8.42 GB", "2026-08-23 10:42", "4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32", "已固化"], + ["RAW-ZHAOPIN-20260823-01", "zhaopin", "JOB-20260823-1038", "text/html + JSON", "52,360", "6.18 GB", "2026-08-23 10:38", "c2d8f733e6711219823110d7d35fdc5535f133ed60f60950f9dc78a228cb402d", "已固化"], + ["RAW-BRZP-20260823-01", "brzp", "JOB-20260823-0955", "text/html", "18,640", "1.86 GB", "2026-08-23 09:55", "a831bd0d4e29cab1e650f36a4fc9c5d5cc8053f560b5d3dc7aac62b384b47e11", "已固化"], + ["RAW-NCSS-20260823-01", "ncss", "JOB-20260823-0840", "text/html", "14,820", "1.42 GB", "2026-08-23 08:40", "18f4".repeat(16), "已固化"], + ["RAW-MOHRSS-20260823-01", "mohrss", "JOB-20260823-0826", "text/html + JSON", "12,680", "1.28 GB", "2026-08-23 08:26", "66a8".repeat(16), "已固化"], + ["RAW-IGUOPIN-20260823-01", "iguopin", "JOB-20260823-0815", "text/html", "9,640", "968 MB", "2026-08-23 08:15", "9ec1".repeat(16), "已固化"], + ["RAW-HZRC-20260823-02", "hzrc", "JOB-20260823-1028", "text/html", "3,860", "384 MB", "2026-08-23 10:28", "d09f".repeat(16), "已固化"], +].map(([id, sourceId, taskId, mediaType, records, size, capturedAt, sha256, status]) => ({ + id, + sourceId, + taskId, + mediaType, + records, + size, + capturedAt, + sha256, + status, + objectPath: `raw/2026/08/23/${sourceId}/${id.toLowerCase()}.jsonl.zst`, +})); + +const recordRawSnapshots = standardJobRecords.map((record, index) => ({ + id: record.snapshotId, + sourceId: record.sourceId, + taskId: record.taskId, + mediaType: "text/html + JSON", + records: "1", + size: `${84 + index * 7} KB`, + capturedAt: record.collectedAt, + sha256: record.payloadHash, + status: "已固化", + objectPath: `raw/2026/08/23/${record.sourceId}/${record.taskId.toLowerCase()}/${record.snapshotId.toLowerCase()}.response.zst`, + recordId: record.id, +})); + +const allRawSnapshots = [...recordRawSnapshots, ...rawSnapshots]; + +const quarantineRecords = [ + ["QUA-20260823-001286", "boss", "BOSS-20260823-884890", "智能装备技术支持", "薪资上下限倒置", "SL-004", "2026-08-23 10:43", "待自动重解析", "JOB-20260823-1042", "RAW-BOSS-20260823-000886", "杭州"], + ["QUA-20260823-001285", "zhaopin", "ZL-20260823-621104", "工业软件实施顾问", "工作地区代码缺失", "RQ-012", "2026-08-23 10:39", "待字段补全", "JOB-20260823-1038", "RAW-ZHAOPIN-20260823-000622", "宁波"], + ["QUA-20260823-001284", "brzp", "BRZP-20260823-110408", "电商运营", "来源详情页已失效", "TM-007", "2026-08-23 09:57", "等待次日复核", "JOB-20260823-0955", "RAW-BRZP-20260823-000112", "嘉兴"], + ["QUA-20260823-001283", "hzrc", "HZRC-20260823-038711", "AI内容策略师", "岗位词典未匹配", "NM-021", "2026-08-23 10:30", "进入人工归一", "JOB-20260823-1028", "RAW-HZRC-20260823-000039", "杭州"], + ["QUA-20260823-001282", "mohrss", "MOHRSS-20260823-226955", "设备维护员", "企业名称完整性不足", "RQ-018", "2026-08-23 08:28", "待规则复核", "JOB-20260823-0826", "RAW-MOHRSS-20260823-000227", "绍兴"], +].map(([id, sourceId, sourceRecordId, jobTitle, issue, rule, detectedAt, disposition, taskId, snapshotId, region]) => ({ + id, + sourceId, + sourceRecordId, + jobTitle, + issue, + rule, + detectedAt, + disposition, + taskId, + snapshotId, + region, +})); + +const contracts = { + "external-job": { + key: "JOB-SIGNAL", + title: "外部招聘岗位信号标准", + version: "V3.0.0", + description: "统一商业招聘平台、公共就业平台和活动聚合平台的岗位、企业、薪资、技能与来源证据,用于产教供需分析。", + schemaPath: "./schemas/external-job-source.schema.json", + fields: 39, + required: 19, + owner: "平台数据标准委员会", + status: "生产已发布", + release: "2026-08-18", + compatibility: "向后兼容 V2.6", + fieldsPreview: [ + ["record_id", "string/uuid", "是", "平台记录唯一标识", "UUID v4"], + ["source_platform", "string", "是", "来源平台代码", "受控代码表"], + ["source_record_id", "string", "是", "来源记录标识", "同平台唯一"], + ["source_url", "string/uri", "是", "来源页面或接口定位", "http/https"], + ["collected_at", "datetime", "是", "实际采集时间", "ISO-8601 +08:00"], + ["published_at", "datetime", "否", "源端发布时间", "ISO-8601"], + ["job_title_raw", "string", "是", "岗位原始名称", "1—200字符"], + ["job_title_normalized", "string", "否", "统一岗位名称", "岗位词典 V4.3"], + ["enterprise_name", "string", "是", "企业名称", "保留原文"], + ["region_code", "string", "是", "工作地区代码", "GB/T 2260"], + ["salary_min", "number", "否", "月薪下限(元)", "非负数"], + ["salary_max", "number", "否", "月薪上限(元)", "≥ salary_min"], + ["skills", "array", "否", "解析后的技能标签", "技能词典 V3.8"], + ["content_hash", "string", "是", "原始内容哈希", "SHA-256"], + ], + rules: [ + ["唯一与幂等", "source_platform + source_record_id 唯一;重复采集必须幂等更新。"], + ["来源证据", "必须保留 source_url、collected_at、content_hash 和采集任务编号。"], + ["薪资口径", "统一折算为税前月薪;面议、日薪、时薪保留原文并标注换算状态。"], + ["时效与失效", "岗位状态和最后发现时间分开记录;失效采用版本化软删除。"], + ["文本治理", "岗位职责原文进入原始层,分析层只保留去标记、去联系方式后的业务文本。"], + ], + }, + "school-employment": { + key: "SCHOOL-EMPLOYMENT", + title: "校内就业事实数据标准", + version: "V2.2.0", + description: "统一学校毕业生就业状态、岗位、企业、薪资、专业相关度和去向确认事实,支持租户隔离和敏感字段最小化。", + schemaPath: "./schemas/school-employment.schema.json", + fields: 32, + required: 16, + owner: "平台数据标准委员会", + status: "待生产发布", + release: "计划 2026-08-28", + compatibility: "兼容 V2.1,新增5字段", + fieldsPreview: [ + ["tenant_id", "string", "是", "学校租户标识", "平台分配"], + ["student_token", "string", "是", "学生不可逆令牌", "禁止明文学号"], + ["cohort", "integer", "是", "毕业届次", "YYYY"], + ["program_code", "string", "是", "专业代码", "教育部专业目录"], + ["employment_status", "string", "是", "就业状态", "受控枚举"], + ["job_title", "string", "否", "就业岗位", "业务原文"], + ["enterprise_token", "string", "否", "企业统一标识", "信用代码令牌化"], + ["salary_monthly", "number", "否", "税前月薪", "元/月"], + ["job_relevance", "string", "否", "岗位专业相关度", "高/中/低/未确认"], + ["confirmed_at", "datetime", "是", "业务确认时间", "ISO-8601"], + ["source_system", "string", "是", "校内来源系统", "系统代码"], + ["updated_at", "datetime", "是", "业务更新时间", "增量水位"], + ], + rules: [ + ["租户隔离", "所有记录必须携带 tenant_id,存储、任务、查询和导出均按租户强制隔离。"], + ["身份最小化", "平台侧使用 student_token,不接收姓名、身份证和明文学号。"], + ["业务确认", "就业状态必须具有确认人角色、确认时间和来源系统。"], + ["增量更新", "updated_at 作为增量水位,主键冲突时以业务更新时间和版本号判定。"], + ["质量阈值", "专业代码合法率100%,必填完整率≥95%,学生专业关联率≥98%。"], + ], + }, + "package-manifest": { + key: "PACKAGE-MANIFEST", + title: "数据交付包清单标准", + version: "V1.2.0", + description: "定义每次导入、导出和租户交付必须携带的数据版本、文件、Schema、质量、血缘、范围和校验信息。", + schemaPath: "./schemas/package-manifest.schema.json", + fields: 21, + required: 14, + owner: "平台数据交付组", + status: "生产已发布", + release: "2026-08-23", + compatibility: "兼容 V1.1,新增2个发布字段", + fieldsPreview: [ + ["package_id", "string", "是", "交付包唯一编号", "EDU-PKG-*"], + ["release_id", "string", "是", "发布候选编号", "REL-*"], + ["release_status", "string", "是", "候选或发布状态", "DRAFT/PUBLISHED"], + ["data_product", "string", "是", "数据产品代码", "产品目录"], + ["data_version", "string", "是", "业务数据版本", "SemVer/日期版"], + ["contract_name", "string", "是", "数据契约名称", "契约注册中心"], + ["contract_version", "string", "是", "契约版本", "SemVer"], + ["data_as_of", "date", "是", "业务截止日期", "YYYY-MM-DD"], + ["tenant_scope", "array", "是", "允许交付租户", "至少1个"], + ["record_count", "integer", "是", "有效记录数", "非负整数"], + ["files", "array", "是", "数据与附件文件清单", "含SHA-256"], + ["quality_score", "number", "是", "综合质量评分", "0—100"], + ["lineage_snapshot", "string", "是", "血缘快照编号", "LINEAGE-*"], + ["generated_at", "datetime", "是", "生成时间", "ISO-8601"], + ], + rules: [ + ["文件完整性", "Manifest 内每个文件必须记录路径、字节数、媒体类型和 SHA-256。"], + ["范围约束", "tenant_scope 与数据服务授权同时校验,不允许客户端自行扩大范围。"], + ["契约绑定", "数据文件必须绑定 contract_name 和精确 contract_version。"], + ["质量绑定", "必须包含质量报告文件、质量评分和失败规则摘要。"], + ["可回滚", "每次交付保留上一稳定版本引用和回滚入口。"], + ], + }, +}; + +const exchangeLogs = [ + ["EXP-20260823-0930", "导出", "区域招聘岗位基础包", "V2026.08.23", "2,846,320", "交付服务", "成功", "09:30"], + ["IMP-20260823-0752", "导入", "校内就业36租户增量", "SCH-EMP-20260823", "4,280", "学校接入服务", "成功", "07:52"], + ["EXP-20260822-1740", "导出", "薪资与企业画像增强包", "V2026.08.22", "1,286,420", "陈致远", "成功", "昨天 17:40"], + ["IMP-20260822-1608", "导入", "企业确认需求批次", "ENT-20260822-03", "8,640", "企业接入服务", "隔离12条", "昨天 16:08"], +]; + +const qualityRules = [ + ["UQ", "来源主键唯一", "source_platform + source_record_id", "99.96%", "通过"], + ["RQ", "核心字段完整", "岗位、企业、地区、来源、采集时间", "98.84%", "通过"], + ["TM", "岗位时效合法", "发布时间、最后发现时间与状态一致", "97.31%", "通过"], + ["SL", "薪资区间合法", "币种、周期、上下限和换算状态", "96.72%", "通过"], + ["NM", "岗位归一覆盖", "映射到岗位词典 V4.3", "96.40%", "27待审"], + ["LN", "来源证据完整", "URL、任务、快照与内容哈希", "100%", "通过"], +]; + +let normalizationItems = [ + ["具身智能应用工程师", "机器人应用工程技术人员", "0.91"], + ["低空运营调度师", "航空运输服务人员", "0.84"], + ["AI内容策略师", "互联网营销师", "0.82"], + ["智能驾驶数据闭环工程师", "数据工程技术人员", "0.88"], + ["跨境合规运营", "电子商务师", "0.86"], +]; + +const auditEvents = [ + { + id: "AUD-20260823-1042-8821", + time: "10:42:18", + type: "collect", + event: "BOSS增量分片完成", + object: "JOB-20260823-1042 · shard-64", + actor: "collector-boss-prod", + result: "成功", + evidence: ["RAW快照", "响应哈希", "运行日志"], + }, + { + id: "AUD-20260823-1038-7412", + time: "10:38:06", + type: "collect", + event: "智联采集水位提交", + object: "SRC-ZL-20260823-04", + actor: "collector-zhaopin-prod", + result: "成功", + evidence: ["水位", "分片清单", "代码版本"], + }, + { + id: "AUD-20260823-1028-5630", + time: "10:28:42", + type: "collect", + event: "源端延迟触发降速", + object: "杭州人才网 · P95 4.8s", + actor: "scheduler-protection", + result: "自动保护", + evidence: ["指标快照", "策略版本"], + }, + { + id: "AUD-20260823-1016-4482", + time: "10:16:33", + type: "quality", + event: "岗位归一批次完成", + object: "NORM-20260823-06", + actor: "normalization-engine", + result: "27项待审", + evidence: ["输入版本", "词典版本", "模型版本"], + }, + { + id: "AUD-20260823-0930-2290", + time: "09:30:12", + type: "publish", + event: "区域岗位基础包发布", + object: "V2026.08.23 · 36租户", + actor: "陈致远", + result: "成功", + evidence: ["审批单", "Manifest", "质量报告"], + }, + { + id: "AUD-20260823-0752-1108", + time: "07:52:55", + type: "exchange", + event: "校内就业增量导入", + object: "36租户 · 4,280条", + actor: "school-ingestion-service", + result: "成功", + evidence: ["源版本", "字段映射", "错误明细"], + }, +]; + +const OPERATIONS_STORAGE_KEY = "eduIndustry.vendorOperations.v1"; +const OPERATIONS_SCHEMA_VERSION = 2; +const OPERATIONS_ACTOR = "陈致远"; +const OPERATIONS_LIMITS = { + auditEvents: 300, + qualityDispositions: 60, + issueTimeline: 120, + exchangeLogs: 100, +}; + +function operationsSeed() { + const baseEvidence = ["指标快照", "任务日志"]; + return { + schemaVersion: OPERATIONS_SCHEMA_VERSION, + seededAt: "2026-08-23T10:30:00+08:00", + issues: [ + { + id: "ISSUE-HZRC-20260823-01", + status: "ALERTED", + actor: "scheduler-protection", + time: "2026-08-23T10:28:42+08:00", + trace: "TRACE-HZRC-20260823-5630", + evidence: [...baseEvidence, "P95延迟采样"], + title: "杭州人才网响应时延升高", + severity: "P1", + owner: "待指派", + sla: "2小时内恢复,剩余 01:42", + impact: "杭州都市圈补采降速,8个分片待执行;稳定版本未受影响", + relatedTask: "JOB-20260823-1028", + quarantineId: "QUA-20260823-001283", + sourceId: "hzrc", + qualityRequired: true, + timeline: [ + { + id: "STEP-HZRC-ALERT", + status: "ALERTED", + actor: "scheduler-protection", + time: "2026-08-23T10:28:42+08:00", + trace: "TRACE-HZRC-20260823-5630", + evidence: ["指标快照", "降速策略 V2.4"], + note: "P95 4.8s,系统自动将并发从12降至4。", + }, + ], + }, + { + id: "ISSUE-NORM-20260823-01", + status: "ACKNOWLEDGED", + actor: "周敏", + time: "2026-08-23T10:18:00+08:00", + trace: "TRACE-NORM-20260823-4482", + evidence: ["归一批次 NORM-20260823-06", "词典 V4.3"], + title: "27 个岗位别名待人工归一", + severity: "P1", + owner: "周敏", + sla: "今日 16:00 前完成", + impact: "具身智能、低空经济等新增岗位暂未进入稳定分类", + relatedTask: "NORM-20260823-06", + quarantineId: "QUA-20260823-001283", + sourceId: "hzrc", + qualityRequired: false, + timeline: [ + { + id: "STEP-NORM-ACK", + status: "ACKNOWLEDGED", + actor: "周敏", + time: "2026-08-23T10:18:00+08:00", + trace: "TRACE-NORM-20260823-4482", + evidence: ["归一待审清单"], + note: "已确认影响范围,等待词典负责人处理。", + }, + ], + }, + { + id: "ISSUE-CONTRACT-20260823-01", + status: "ASSIGNED", + actor: "陈致远", + time: "2026-08-23T09:48:00+08:00", + trace: "TRACE-CONTRACT-20260823-2201", + evidence: ["Schema差异报告", "下游影响清单"], + title: "校内就业契约 V2.2 待发布", + severity: "P2", + owner: "数据标准组", + sla: "2026-08-28 前完成", + impact: "36所学校的新就业质量与去向确认字段尚未启用", + relatedTask: "CONTRACT-SCHOOL-EMPLOYMENT-V2.2", + quarantineId: "无", + sourceId: "school-employment", + qualityRequired: false, + timeline: [ + { + id: "STEP-CONTRACT-ASSIGNED", + status: "ASSIGNED", + actor: "陈致远", + time: "2026-08-23T09:48:00+08:00", + trace: "TRACE-CONTRACT-20260823-2201", + evidence: ["责任人指派记录"], + note: "已指派数据标准组执行兼容性与样本回放。", + }, + ], + }, + ], + workOrders: [ + { + id: "WO-HZRC-20260823-01", + status: "OPEN", + actor: "scheduler-protection", + time: "2026-08-23T10:28:42+08:00", + trace: "TRACE-HZRC-20260823-5630", + evidence: ["自动建单规则"], + issueId: "ISSUE-HZRC-20260823-01", + assignee: "待指派", + }, + { + id: "WO-NORM-20260823-01", + status: "ASSIGNED", + actor: "周敏", + time: "2026-08-23T10:18:00+08:00", + trace: "TRACE-NORM-20260823-4482", + evidence: ["归一待审清单"], + issueId: "ISSUE-NORM-20260823-01", + assignee: "周敏", + }, + { + id: "WO-CONTRACT-20260823-01", + status: "ASSIGNED", + actor: "陈致远", + time: "2026-08-23T09:48:00+08:00", + trace: "TRACE-CONTRACT-20260823-2201", + evidence: ["Schema差异报告"], + issueId: "ISSUE-CONTRACT-20260823-01", + assignee: "数据标准组", + }, + ], + qualityDispositions: [], + releases: [ + { + id: "REL-20260823-01", + status: "DRAFT", + actor: "陈致远", + time: "2026-08-23T10:30:00+08:00", + trace: "TRACE-REL-20260823-01", + evidence: ["候选数据快照", "质量报告 QUALITY-20260823-09"], + dataVersion: "V2026.08.23", + packageId: "EDU-PKG-20260823-01", + previousStableVersion: "V2026.08.22", + qualityGate: "BLOCKED", + qualityScore: 94.7, + impactTenants: ["TENANT-HZVTC", "TENANT-ZIME", "TENANT-NBCC"], + applicant: "陈致远", + approvalId: "APPROVAL-REL-20260823-01", + manifestGeneratedAt: null, + candidateManifest: null, + candidateInputFingerprint: null, + publishedManifestGeneratedAt: null, + publishedManifest: null, + publishedAt: null, + }, + ], + approvals: [ + { + id: "APPROVAL-REL-20260823-01", + status: "DRAFT", + actor: "陈致远", + time: "2026-08-23T10:30:00+08:00", + trace: "TRACE-APPROVAL-20260823-01", + evidence: ["审批规则 RBAC-RELEASE-2P"], + releaseId: "REL-20260823-01", + applicant: "陈致远", + approver: null, + comment: "", + decidedAt: null, + }, + { + id: "APPROVAL-ROLLBACK-REL-20260823-01", + status: "DRAFT", + actor: "陈致远", + time: "2026-08-23T10:30:00+08:00", + trace: "TRACE-ROLLBACK-APPROVAL-20260823-01", + evidence: ["回滚审批规则 RBAC-ROLLBACK-2P"], + releaseId: "REL-20260823-01", + type: "ROLLBACK", + applicant: "陈致远", + approver: null, + comment: "", + reason: "", + decidedAt: null, + }, + ], + deliveries: [ + { + id: "DELIVERY-HZVTC-20260823-01", + status: "PENDING", + actor: "delivery-orchestrator", + time: "2026-08-23T10:30:00+08:00", + trace: "TRACE-DELIVERY-HZVTC-01", + evidence: ["租户范围策略"], + tenantId: "TENANT-HZVTC", + school: "杭州科技职业技术学院", + packageId: "EDU-PKG-20260823-01", + dataVersion: "V2026.08.23", + expectedRecords: 2846320, + receiptRecords: null, + expectedSha: "4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32", + receiptSha: null, + attempts: 0, + failureReason: "", + }, + { + id: "DELIVERY-ZIME-20260823-01", + status: "PENDING", + actor: "delivery-orchestrator", + time: "2026-08-23T10:30:00+08:00", + trace: "TRACE-DELIVERY-ZIME-01", + evidence: ["租户范围策略"], + tenantId: "TENANT-ZIME", + school: "浙江机电职业技术大学", + packageId: "EDU-PKG-20260823-01", + dataVersion: "V2026.08.23", + expectedRecords: 2819044, + receiptRecords: null, + expectedSha: "96c2be742dc43f8e7ee526db6358030873406c450f15e67225c605dc39b431a8", + receiptSha: null, + attempts: 0, + failureReason: "", + }, + { + id: "DELIVERY-NBCC-20260823-01", + status: "PENDING", + actor: "delivery-orchestrator", + time: "2026-08-23T10:30:00+08:00", + trace: "TRACE-DELIVERY-NBCC-01", + evidence: ["租户范围策略"], + tenantId: "TENANT-NBCC", + school: "宁波城市职业技术学院", + packageId: "EDU-PKG-20260823-01", + dataVersion: "V2026.08.23", + expectedRecords: 2768420, + receiptRecords: null, + expectedSha: "c2d8f733e6711219823110d7d35fdc5535f133ed60f60950f9dc78a228cb402d", + receiptSha: null, + attempts: 0, + failureReason: "", + }, + ], + auditEvents: [ + { + id: "AUD-OPS-20260823-1028", + status: "RECORDED", + actor: "scheduler-protection", + time: "2026-08-23T10:28:42+08:00", + trace: "TRACE-HZRC-20260823-5630", + evidence: ["指标快照", "策略版本"], + type: "operations", + event: "杭州人才网时延告警建单", + object: "ISSUE-HZRC-20260823-01", + result: "待确认", + }, + ], + }; +} + +function isOperationsEntityValid(entity) { + return entity && typeof entity.id === "string" && typeof entity.status === "string" && typeof entity.actor === "string" && typeof entity.time === "string" && typeof entity.trace === "string" && Array.isArray(entity.evidence); +} + +function trimOperationsStore(store) { + store.auditEvents = store.auditEvents.slice(0, OPERATIONS_LIMITS.auditEvents); + store.qualityDispositions = store.qualityDispositions.slice(-OPERATIONS_LIMITS.qualityDispositions); + store.issues.forEach((issue) => { + issue.timeline = issue.timeline.slice(-OPERATIONS_LIMITS.issueTimeline); + }); + return store; +} + +function loadOperationsStore() { + try { + const parsed = JSON.parse(localStorage.getItem(OPERATIONS_STORAGE_KEY)); + const collections = ["issues", "workOrders", "qualityDispositions", "releases", "approvals", "deliveries", "auditEvents"]; + if ( + parsed?.schemaVersion === OPERATIONS_SCHEMA_VERSION && + collections.every((key) => Array.isArray(parsed[key]) && parsed[key].every(isOperationsEntityValid)) + ) { + return trimOperationsStore(parsed); + } + } catch { + // Invalid or unavailable browser storage falls back to a reproducible seed. + } + const seed = operationsSeed(); + try { + localStorage.setItem(OPERATIONS_STORAGE_KEY, JSON.stringify(seed)); + } catch { + // The in-memory seed remains fully interactive when storage is blocked. + } + return seed; +} + +let operationsStore = loadOperationsStore(); + +function saveOperationsStore() { + trimOperationsStore(operationsStore); + try { + localStorage.setItem(OPERATIONS_STORAGE_KEY, JSON.stringify(operationsStore)); + } catch { + showToast("浏览器阻止了本地存储,本次状态仅在当前页面有效", "状态未持久化"); + } +} + +function operationsNow() { + return new Date().toISOString(); +} + +function operationToken(prefix) { + return `${prefix}-${Date.now()}-${Math.random().toString(16).slice(2, 7).toUpperCase()}`; +} + +function addOperationsAudit({ type = "operations", event, object, actor = OPERATIONS_ACTOR, result, evidence = [] }) { + const time = operationsNow(); + const trace = operationToken("TRACE"); + operationsStore.auditEvents.unshift({ + id: operationToken("AUD"), + status: "RECORDED", + actor, + time, + trace, + evidence: [...evidence], + type, + event, + object, + result, + }); + return { actor, time, trace, evidence: [...evidence] }; +} + +function migrateOperationsEntity(entity, status, metadata) { + entity.status = status; + entity.actor = metadata.actor; + entity.time = metadata.time; + entity.trace = metadata.trace; + entity.evidence = [...metadata.evidence]; +} + +const state = { + sourceFilter: "all", + sourceSearch: "", + sourceId: "boss", + sourceTab: "overview", + jobFilter: "all", + recordLayer: "standard", + recordSource: "all", + recordRegion: "all", + recordSearch: "", + recordId: "", + contractKey: "external-job", + auditFilter: "all", + operationsTab: "issues", + issueId: "", +}; + +function h(value) { + return String(value ?? "") + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); +} + +function showToast(message, title = "操作已完成") { + const toast = document.createElement("div"); + toast.className = "toast"; + toast.innerHTML = `✓${h(title)}${h(message)}`; + document.getElementById("toastRegion").appendChild(toast); + setTimeout(() => toast.remove(), 3600); +} + +function openModal(modal) { + modal.classList.add("open"); + modal.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeModal(modal) { + modal.classList.remove("open"); + modal.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function switchView(viewName) { + document.querySelectorAll(".view").forEach((view) => view.classList.toggle("active", view.id === `view-${viewName}`)); + document.querySelectorAll(".nav-item[data-view]").forEach((button) => button.classList.toggle("active", button.dataset.view === viewName)); + const activeView = document.getElementById(`view-${viewName}`); + document.getElementById("breadcrumbCurrent").textContent = activeView?.dataset.title || "运行总览"; + document.body.classList.remove("sidebar-open"); + window.scrollTo({ top: 0, behavior: "smooth" }); +} + +function formatNumber(value) { + return Number(value).toLocaleString("zh-CN"); +} + +function sourceById(id) { + return sources.find((source) => source.id === id) || sources[0]; +} + +function sourceStatusPill(source) { + const tone = source.status === "attention" ? "attention" : source.status === "failed" ? "failed" : "running"; + return `${h(source.statusLabel)}`; +} + +const operationsStatusLabels = { + ALERTED: "待确认", + ACKNOWLEDGED: "已确认", + ASSIGNED: "已指派", + INVESTIGATING: "排障中", + QUALITY_REVIEW_PENDING: "待质量复核", + VERIFIED: "复核通过", + REVIEWED_BLOCKED: "复核后仍阻断", + RESOLVED: "已解决", + CLOSED: "已关闭", + OPEN: "已建单", + DRAFT: "草稿", + PENDING_APPROVAL: "待审批", + APPROVED: "已批准", + REJECTED: "已驳回", + PUBLISHED: "已发布", + ROLLED_BACK: "已回滚", + PENDING: "待发送", + SENDING: "发送中", + DELIVERED: "已送达", + ACKNOWLEDGED_DELIVERY: "已确认回执", + ACKNOWLEDGED: "已确认", + FAILED: "失败", + RETRYING: "重试中", + PENDING_REVIEW: "待复核", + RECORDED: "已记录", + PASS: "通过", + BLOCKED: "阻断", + ROLLBACK_PENDING_APPROVAL: "回滚待审批", + ROLLBACK_APPROVED: "回滚已批准", + ROLLBACK_REJECTED: "回滚已驳回", + ROLLBACK_EXECUTED: "回滚已执行", +}; + +function operationStatusLabel(status) { + return operationsStatusLabels[status] || status; +} + +function operationStatusTone(status) { + if (["FAILED", "REJECTED", "BLOCKED", "REVIEWED_BLOCKED", "ROLLBACK_REJECTED"].includes(status)) return "failed"; + if (["ALERTED", "PENDING_APPROVAL", "QUALITY_REVIEW_PENDING", "PENDING", "RETRYING", "ASSIGNED", "ROLLBACK_PENDING_APPROVAL"].includes(status)) return "attention"; + if ( + [ + "VERIFIED", + "RESOLVED", + "CLOSED", + "APPROVED", + "PUBLISHED", + "DELIVERED", + "ACKNOWLEDGED", + "ROLLED_BACK", + "PASS", + "ROLLBACK_APPROVED", + "ROLLBACK_EXECUTED", + ].includes(status) + ) + return "running"; + return ""; +} + +function operationTime(value) { + if (!value) return "—"; + const date = new Date(value); + if (Number.isNaN(date.getTime())) return value; + return date.toLocaleString("zh-CN", { hour12: false }); +} + +function currentRelease() { + return operationsStore.releases.find((release) => release.id === "REL-20260823-01"); +} + +function currentApproval() { + const release = currentRelease(); + return operationsStore.approvals.find((approval) => approval.id === release?.approvalId); +} + +function currentRollbackApproval() { + const release = currentRelease(); + return operationsStore.approvals.find((approval) => approval.releaseId === release?.id && approval.type === "ROLLBACK"); +} + +function isIndependentApproval(approval, approver = approval?.approver) { + return Boolean(approval && approver && approver !== approval.applicant); +} + +function decideIndependentApproval({ + approval, + target, + approver, + comment, + approved, + approveStatus, + rejectStatus, + approveEvent, + rejectEvent, + object, + evidence, + defaultApproveComment, + defaultRejectComment, + resultLabel = (status) => status, + successMessage, + successTitle, +}) { + if (!isIndependentApproval(approval, approver)) { + const rollback = approval?.type === "ROLLBACK"; + showToast(rollback ? "回滚申请人与审批人相同,四眼规则阻止了该操作" : "申请人和审批人相同,四眼审批规则阻止了该操作", rollback ? "无法批准自己的回滚" : "无法批准自己的申请"); + return false; + } + const nextStatus = approved ? approveStatus : rejectStatus; + const metadata = addOperationsAudit({ + type: "publish", + event: approved ? approveEvent : rejectEvent, + object, + actor: approver, + result: resultLabel(nextStatus), + evidence, + }); + approval.approver = approver; + approval.comment = comment || (approved ? defaultApproveComment : defaultRejectComment); + approval.decidedAt = metadata.time; + migrateOperationsEntity(approval, nextStatus, metadata); + if (target) migrateOperationsEntity(target, nextStatus, metadata); + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast(successMessage(approver, approved), successTitle(approved)); + return true; +} + +function latestQualityDisposition(issueId = "ISSUE-HZRC-20260823-01") { + return operationsStore.qualityDispositions.filter((disposition) => disposition.issueId === issueId).at(-1); +} + +function isVerifiedFixReplay(disposition) { + return Boolean( + disposition?.action === "FIX_REPLAY" && + disposition.status === "VERIFIED" && + disposition.verification?.replayedRecords === disposition.verification?.expectedRecords && + disposition.verification?.rulesPassed === true && + disposition.verification?.reviewerSigned === true, + ); +} + +function qualityGatePassed() { + return isVerifiedFixReplay(latestQualityDisposition()); +} + +function updateReleaseQualityGate() { + const release = currentRelease(); + if (!release || ["PUBLISHED", "ROLLED_BACK"].includes(release.status)) return; + release.qualityGate = qualityGatePassed() ? "PASS" : "BLOCKED"; +} + +function releaseReadyForApproval(release = currentRelease()) { + return Boolean(release?.qualityGate === "PASS" && release.manifestGeneratedAt && release.candidateManifest); +} + +function renderOperationsMetrics() { + const openIssues = operationsStore.issues.filter((issue) => !["RESOLVED", "CLOSED"].includes(issue.status)).length; + const pendingApprovals = operationsStore.approvals.filter((approval) => ["PENDING_APPROVAL", "ROLLBACK_PENDING_APPROVAL"].includes(approval.status)).length; + const deliveryAttention = operationsStore.deliveries.filter((delivery) => ["PENDING", "SENDING", "FAILED", "RETRYING"].includes(delivery.status)).length; + const acknowledged = operationsStore.deliveries.filter((delivery) => delivery.status === "ACKNOWLEDGED").length; + document.getElementById("operationsMetrics").innerHTML = ` +
未闭环问题${openIssues}确认、指派、排障与质量处置
+
审批待办${pendingApprovals}申请人与审批人强制分离
+
交付待办 / 异常${deliveryAttention}按租户隔离,不重复发送成功学校
+
已核验回执${acknowledged}记录数与 SHA-256 均一致
+ `; + document.getElementById("operationsNavCount").textContent = openIssues + pendingApprovals + deliveryAttention; + document.getElementById("notificationButton").querySelector("b").textContent = openIssues + pendingApprovals + deliveryAttention; + const release = currentRelease(); + const releaseReady = releaseReadyForApproval(release); + const overviewState = document.getElementById("overviewReleaseState"); + const overviewDetail = document.getElementById("overviewReleaseDetail"); + const qualityState = document.getElementById("qualityReleaseState"); + const qualityDetail = document.getElementById("qualityReleaseDetail"); + if (overviewState) overviewState.textContent = release?.status === "PUBLISHED" ? "稳定版本已发布" : releaseReady ? "候选可提交审批" : "候选发布受阻"; + if (overviewDetail) overviewDetail.textContent = release?.qualityGate === "PASS" ? (release?.manifestGeneratedAt ? "质量与候选 Manifest 已就绪" : "质量通过,待生成候选 Manifest") : "杭州人才网修复重放尚未验证"; + if (qualityState) qualityState.textContent = release?.qualityGate === "PASS" ? "当前批次质量门禁已通过" : "当前批次仍需修复重放复核"; + if (qualityDetail) qualityDetail.textContent = release?.qualityGate === "PASS" ? "质量证据已通过独立复核,可继续生成候选包" : "质量分达标不等于门禁通过,稳定版本继续保持不变"; +} + +function renderOverviewIssues() { + const issues = operationsStore.issues.filter((issue) => !["RESOLVED", "CLOSED"].includes(issue.status)).slice(0, 3); + const list = document.getElementById("overviewIssueList"); + list.innerHTML = issues.length + ? issues + .map( + (issue) => ` + + `, + ) + .join("") + : `
当前没有待处理问题,所有事项均已闭环。
`; + const countBadge = list.closest(".alert-panel").querySelector(".panel-head > em"); + countBadge.textContent = `${issues.length} 项`; +} + +function renderOperationsIssues() { + const rows = operationsStore.issues + .map((issue) => { + const last = issue.timeline.at(-1); + return ` + + ${h(issue.title)}${h(issue.id)} · ${h(issue.trace)} + ${h(issue.severity)}${h(issue.sla)} + ${h(issue.impact)} + ${h(issue.owner)} + ${h(operationStatusLabel(issue.status))} + ${h(last?.actor || issue.actor)}${h(operationTime(last?.time || issue.time))} +
+ + `; + }) + .join(""); + document.getElementById("operationsIssueTable").innerHTML = rows; + const openCount = operationsStore.issues.filter((issue) => !["RESOLVED", "CLOSED"].includes(issue.status)).length; + document.getElementById("issueQueueSummary").textContent = `${openCount} 项未闭环 · 状态刷新后保留`; +} + +function releaseNextAction(release, approval) { + if (release.status === "DRAFT") { + const ready = releaseReadyForApproval(release); + return ``; + } + if (release.status === "PENDING_APPROVAL") { + return ` + + + + + `; + } + if (release.status === "REJECTED") { + return ``; + } + if (release.status === "APPROVED") { + return ``; + } + if (release.status === "PUBLISHED") { + const rollbackApproval = currentRollbackApproval(); + if (rollbackApproval?.status === "ROLLBACK_PENDING_APPROVAL") { + return ` +
+ 全局回滚申请待独立审批 + ${h(rollbackApproval.reason)} · 申请人 ${h(rollbackApproval.applicant)} 不能自批 + + + +
`; + } + if (rollbackApproval?.status === "ROLLBACK_APPROVED") { + return ``; + } + return ` + + `; + } + return `当前候选版本已回滚,交付记录仍按租户保留审计。`; +} + +function renderReleaseWorkspace() { + updateReleaseQualityGate(); + const release = currentRelease(); + const approval = currentApproval(); + const rollbackApproval = currentRollbackApproval(); + document.getElementById("releaseWorkspace").innerHTML = ` +
+
+
RELEASE CANDIDATE

${h(release.id)}

${h(operationStatusLabel(release.status))}
+
+ 数据版本${h(release.dataVersion)} + 候选包${h(release.packageId)} + 上一稳定版本${h(release.previousStableVersion)} +
+
+ 质量门禁${h(operationStatusLabel(release.qualityGate))} · ${release.qualityScore} + 影响租户${release.impactTenants.length} 所学校 + 申请人${h(release.applicant)} + Manifest${release.publishedManifestGeneratedAt ? `发布版已生成 · ${h(operationTime(release.publishedManifestGeneratedAt))}` : release.manifestGeneratedAt ? `候选已生成 · ${h(operationTime(release.manifestGeneratedAt))}` : "尚未生成"} +
+
+ ${ + release.status === "PUBLISHED" + ? "质量证据、候选 Manifest 与独立审批已冻结,正式发布 Manifest 已生成;当前尚未代表学校接收。" + : release.status === "ROLLED_BACK" + ? `稳定别名已回滚到 ${h(release.previousStableVersion)},原发布、审批和租户交付记录继续保留审计。` + : release.status === "PENDING_APPROVAL" + ? "候选 Manifest 已冻结,正在等待不同于申请人的独立审批人处理。" + : release.status === "APPROVED" + ? "独立审批已通过,可以执行稳定别名切换并生成正式发布 Manifest。" + : release.status === "REJECTED" + ? "独立审批已驳回,旧候选不可继续发布;返回草稿后必须修订并重新生成 Manifest。" + : release.qualityGate === "PASS" + ? release.manifestGeneratedAt + ? "修复重放证据与候选 Manifest 已就绪,可以提交独立发布审批。" + : "修复重放已由独立复核人验证;还必须生成候选 Manifest 后才能提交审批。" + : "质量门禁阻断:只有 FIX_REPLAY 的记录数、规则结果与复核签名全部验证通过才能解锁;豁免或丢弃均保持阻断。" + } +
+
+ ${ + release.status === "PUBLISHED" && release.publishedManifest + ? `` + : release.status === "DRAFT" + ? `` + : `候选 Manifest 已冻结,审批中不可重建。` + } + +
+
+
+
FOUR-EYES APPROVAL

独立审批

${h(operationStatusLabel(approval.status))}
+
+
审批编号
${h(approval.id)}
+
申请人
${h(approval.applicant)}
+
审批人
${h(approval.approver || "待独立审批人处理")}
+
审批意见
${h(approval.comment || "—")}
+
审批引用
${h(`${approval.id}:${approval.status}`)}
+ ${ + rollbackApproval?.status !== "DRAFT" + ? `
回滚审批
${h(`${rollbackApproval.id}:${rollbackApproval.status}`)} · ${h(rollbackApproval.approver || "待独立审批")}
` + : "" + } +
+
${releaseNextAction(release, approval)}
+
+
+ `; +} + +function deliveryActionButtons(delivery) { + if (delivery.status === "PENDING") return `发布后可启动`; + if (["SENDING", "RETRYING"].includes(delivery.status)) { + return `
`; + } + if (delivery.status === "FAILED") return `
`; + if (delivery.status === "DELIVERED") { + return `
`; + } + if (delivery.status === "ACKNOWLEDGED") return `
`; + return `已完成租户级回滚`; +} + +function renderDeliveries() { + const published = currentRelease()?.status === "PUBLISHED"; + const button = document.getElementById("startPendingDeliveries"); + button.disabled = !published || !operationsStore.deliveries.some((delivery) => delivery.status === "PENDING"); + button.textContent = published ? "启动待发送学校" : "候选发布后可启动"; + document.getElementById("deliveryTable").innerHTML = operationsStore.deliveries + .map( + (delivery) => ` + + ${h(delivery.school)}${h(delivery.tenantId)} + ${h(delivery.packageId)}${h(delivery.dataVersion)} + ${h(operationStatusLabel(delivery.status))}${delivery.failureReason ? `${h(delivery.failureReason)}` : ""} + + ${ + delivery.status === "DELIVERED" + ? `` + : `${delivery.receiptRecords === null ? "—" : formatNumber(delivery.receiptRecords)}期望 ${formatNumber(delivery.expectedRecords)}` + } + + + ${ + delivery.status === "DELIVERED" + ? `` + : `${h(delivery.receiptSha || "—")}` + } + + ${h(delivery.actor)}${h(operationTime(delivery.time))} · ${delivery.attempts} 次 + ${deliveryActionButtons(delivery)} + + `, + ) + .join(""); +} + +function renderOperations() { + renderOperationsMetrics(); + renderOverviewIssues(); + renderOperationsIssues(); + renderReleaseWorkspace(); + renderDeliveries(); + document.querySelectorAll("[data-operations-tab]").forEach((button) => button.classList.toggle("active", button.dataset.operationsTab === state.operationsTab)); + document.querySelectorAll(".operations-workspace").forEach((workspace) => workspace.classList.toggle("active", workspace.id === `operations-${state.operationsTab}`)); +} + +function issueActionFooter(issue) { + const disposition = latestQualityDisposition(issue.id); + const qualityReviewAction = + disposition?.action === "FIX_REPLAY" + ? `` + : ``; + const actions = { + ALERTED: ``, + ACKNOWLEDGED: ``, + ASSIGNED: ``, + INVESTIGATING: issue.qualityRequired + ? `填写质量处置并提交复核` + : ``, + QUALITY_REVIEW_PENDING: qualityReviewAction, + VERIFIED: ``, + RESOLVED: ``, + CLOSED: `问题已闭环,所有动作与证据已保留。`, + }; + return `${actions[issue.status] || ""}`; +} + +function openIssueDrawer(issueId) { + const issue = operationsStore.issues.find((item) => item.id === issueId); + if (!issue) return; + state.issueId = issueId; + const disposition = operationsStore.qualityDispositions.filter((item) => item.issueId === issue.id).at(-1); + document.getElementById("issueDrawerKicker").textContent = `${issue.severity} · ${issue.id}`; + document.getElementById("issueDrawerTitle").textContent = issue.title; + document.getElementById("issueDrawerDescription").textContent = `${operationStatusLabel(issue.status)} · ${issue.owner} · ${issue.sla}`; + document.getElementById("issueDrawerContent").innerHTML = ` +
+ 负责人${h(issue.owner)} + SLA${h(issue.sla)} + 关联任务${h(issue.relatedTask)} + 隔离记录${h(issue.quarantineId)} +
+
+

影响与证据

+

${h(issue.impact)}

+
${issue.evidence.map((item) => `${h(item)}`).join("")}
+
+ ${ + issue.status === "INVESTIGATING" && issue.qualityRequired + ? ` +
+

提交质量处置复核

+
+ + + +
+ +
+ ` + : "" + } + ${ + disposition + ? ` +
+

不可变质量动作

+
+
动作编号
${h(disposition.id)}
+
处置方式
${h({ FIX_REPLAY: "修复并重放", WAIVE: "豁免", DISCARD: "丢弃" }[disposition.action])}
+
原因
${h(disposition.reason)}
+
复核人 / 状态
${h(disposition.reviewer)} · ${h(operationStatusLabel(disposition.status))}
+
追踪 / 证据
${h(disposition.trace)} · ${h(disposition.evidence.join("、"))}
+
+
+ ` + : "" + } +
+

处置时间线

+
+ ${issue.timeline + .map( + (step) => ` + ${h(operationStatusLabel(step.status))} · ${h(step.actor)}${h(operationTime(step.time))} · ${h(step.note)}${h(step.trace)} · ${h(step.evidence.join("、"))} + `, + ) + .join("")} +
+
+ `; + document.getElementById("issueDrawerFooter").innerHTML = issueActionFooter(issue); + const drawer = document.getElementById("issueDrawer"); + drawer.classList.add("open"); + drawer.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeIssueDrawer() { + const drawer = document.getElementById("issueDrawer"); + drawer.classList.remove("open"); + drawer.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function transitionIssue(issue, status, note, evidence, actor = OPERATIONS_ACTOR) { + const metadata = addOperationsAudit({ + event: `${issue.title}:${operationStatusLabel(status)}`, + object: issue.id, + actor, + result: operationStatusLabel(status), + evidence, + }); + migrateOperationsEntity(issue, status, metadata); + issue.timeline.push({ + id: operationToken("STEP"), + status, + actor: metadata.actor, + time: metadata.time, + trace: metadata.trace, + evidence: [...metadata.evidence], + note, + }); + const workOrder = operationsStore.workOrders.find((item) => item.issueId === issue.id); + if (workOrder) { + migrateOperationsEntity(workOrder, status === "CLOSED" ? "CLOSED" : status, metadata); + workOrder.assignee = issue.owner; + } + saveOperationsStore(); + renderOperations(); + renderAudit(); + openIssueDrawer(issue.id); +} + +function renderOverviewSources() { + const selected = sources.slice(0, 5); + document.getElementById("overviewSourceHealth").innerHTML = selected + .map( + (source) => ` + + `, + ) + .join(""); +} + +function filteredSources() { + const keyword = state.sourceSearch.trim().toLowerCase(); + return sources.filter((source) => { + const matchesFilter = state.sourceFilter === "all" || source.category === state.sourceFilter; + const text = `${source.name}${source.domain}${source.adapter}${source.categoryLabel}`.toLowerCase(); + return matchesFilter && text.includes(keyword); + }); +} + +function renderSources() { + const filtered = filteredSources(); + document.getElementById("sourceGrid").innerHTML = filtered + .map( + (source) => ` +
+
+ + ${h(source.name)}${h(source.domain)} + ${h(source.categoryLabel)} +
+
+ 健康度${source.health.toFixed(1)} + 今日新增${formatNumber(source.today)} + 累计有效${h(source.total)} +
+
+ ${h(source.mode)}${h(source.schedule)}${h(source.contract)} +
+
+ ${h(source.statusLabel)} · 更新于 ${h(source.updated)} +
+ ${source.category === "school" ? "" : ``} + +
+
+
+ `, + ) + .join(""); + if (!filtered.length) { + document.getElementById("sourceGrid").innerHTML = `
没有找到符合条件的数据源,请调整分类或搜索关键词。
`; + } + document.getElementById("sourceListSummary").textContent = `当前展示 ${filtered.length} 个数据源`; + document.getElementById("sourceTotal").textContent = sources.length; + document.getElementById("sourceRunning").textContent = sources.filter((source) => source.status === "running").length; + document.getElementById("sourceNavCount").textContent = sources.length; +} + +function drawerStats(source) { + return ` +
+ 当前源版本${h(source.version)}${h(source.updated)} 更新 + 综合健康度${source.health.toFixed(1)}${h(source.statusLabel)} + 今日有效记录${formatNumber(source.today)}累计 ${h(source.total)} + 目标契约${h(source.contract)}${h(source.schema)} +
+ `; +} + +function renderSourceOverview(source) { + return ` + ${drawerStats(source)} +
+ ${h(source.categoryLabel.toUpperCase())} · ${h(source.adapter)} + ${h(source.coverage)} + ${h(source.change)} +
+
+

资产责任与运行策略

+
+
来源入口
${h(source.domain)}
+
接入方式
${h(source.mode)}
+
更新频率
${h(source.schedule)}
+
技术责任人
${h(source.owner)}
+
原始数据留存
${h(source.retention)}
+
连接器资产
${h(source.repo)} · ${h(source.codeVersion)}
+
+
+
+

进入生产的控制点

+
    +
  • 先保存原始响应与内容哈希,再执行解析、清洗和岗位归一。
  • +
  • 解析规则、代码版本、任务分片和增量水位与数据版本绑定。
  • +
  • 新采集批次未通过质量验收前,不覆盖当前稳定交付版本。
  • +
+
+ `; +} + +function renderSourceAcquisition(source) { + return ` + ${drawerStats(source)} +
+

生产采集配置

+
+
采集模式
${h(source.mode)}
+
调度计划
${h(source.schedule)}
+
并发与速率
${h(source.rate)}
+
失败重试
${h(source.retry)}
+
采集范围
${h(source.coverage)}
+
目标数据契约
${h(source.contract)}
+
+
+
+

任务执行要求

+
    +
  • 所有请求必须携带 task_id、shard_id、collector_version 和 trace_id。
  • +
  • 源端异常触发自动降速、熔断或分片隔离,不影响其他来源继续运行。
  • +
  • 增量任务必须提交已验收水位;失败重试保持幂等。
  • +
  • 动态页面、接口响应和文件下载均进入原始留存层,解析过程可重放。
  • +
+
+ `; +} + +function renderSourceMapping(source) { + const rows = + source.category === "school" + ? [ + ["student_key", "student_token", "令牌化", "必填"], + ["major_code", "program_code", "专业代码字典", "必填"], + ["job_name", "job_title", "去空白与标准化", "条件必填"], + ["company_code", "enterprise_token", "企业标识令牌化", "条件必填"], + ["salary", "salary_monthly", "统一元/月", "可选"], + ["update_time", "updated_at", "ISO-8601", "必填"], + ] + : [ + ["source_id", "source_record_id", "原样保留", "必填"], + ["job_name", "job_title_raw", "去标记与空白", "必填"], + ["company_name", "enterprise_name", "原文 + 企业归一", "必填"], + ["city", "region_code", "GB/T 2260", "必填"], + ["salary", "salary_min/max", "统一税前月薪", "可选"], + ["description", "job_description", "去联系方式", "必填"], + ["publish_time", "published_at", "ISO-8601", "可选"], + ["detail_url", "source_url", "绝对URL", "必填"], + ]; + return ` +
+ FIELD MAPPING · ${h(source.schema)} + ${h(source.name)} → ${h(source.contract)} + 映射版本与连接器代码独立版本化,支持回放历史原始数据进行回归验证。 +
+
+

核心字段映射

+
+ + + ${rows.map((row) => `${row.map((cell) => ``).join("")}`).join("")} +
源字段目标字段转换规则要求
${h(cell)}
+
+
+
+

样本回归

+

最近回归样本 1,000 条,结构通过率 100%,必填完整率 98.8%,岗位归一覆盖率 96.4%。未匹配岗位进入人工复核队列,不以模型推断覆盖原始事实。

+
+ `; +} + +function renderSourceRuntime(source) { + return ` + ${drawerStats(source)} +
+

最近运行事件

+
+ ${source.runtime.map(([time, title, detail]) => `${h(time)} · ${h(title)}${h(detail)}`).join("")} +
+
+
+

稳定版本保护

+

运行中的采集、解析和质量任务只写入暂存版本。完整规则通过并完成发布审批后,才更新供下游分析引用的稳定别名。

+
+ `; +} + +function renderSourceAudit(source) { + return ` +
+ TRACEABLE SOURCE ASSET + ${h(source.version)} · ${h(source.codeVersion)} + 来源、代码、任务、原始快照、规则、质量和交付版本均可通过追踪编号关联。 +
+
+

当前审计证据

+
+ 来源注册记录${h(source.domain)} · 资产责任人 ${h(source.owner)} + 连接器代码版本${h(source.repo)} · ${h(source.codeVersion)} + 原始数据版本RAW-${h(source.id.toUpperCase())}-20260823 · SHA-256 已固化 + 字段映射与契约${h(source.schema)} → ${h(source.contract)} + 生产运行策略${h(source.rate)} · ${h(source.retry)} +
+
+
+

数据使用边界

+

平台只向产教分析产品交付经契约治理的岗位信号、企业画像和统计结果。原始层与交付层分区存储,租户交付范围由 Manifest 和平台数据范围策略共同控制。

+
+ `; +} + +function updateSourceDrawer() { + const source = sourceById(state.sourceId); + document.getElementById("sourceDrawerKicker").textContent = `${source.categoryLabel.toUpperCase()} · ${source.adapter}`; + document.getElementById("sourceDrawerTitle").textContent = source.name; + document.getElementById("sourceDrawerDescription").textContent = `${source.domain} · ${source.coverage} · ${source.statusLabel}`; + document.querySelectorAll("#sourceDrawerTabs button").forEach((button) => { + button.classList.toggle("active", button.dataset.sourceTab === state.sourceTab); + }); + const renderers = { + overview: renderSourceOverview, + acquisition: renderSourceAcquisition, + mapping: renderSourceMapping, + runtime: renderSourceRuntime, + audit: renderSourceAudit, + }; + document.getElementById("sourceDrawerContent").innerHTML = renderers[state.sourceTab](source); + document.getElementById("sourceDrawerFooter").innerHTML = ` + + ${source.category === "school" ? "" : ``} + + + `; +} + +function openSourceDrawer(sourceId) { + state.sourceId = sourceId; + state.sourceTab = "overview"; + updateSourceDrawer(); + const drawer = document.getElementById("sourceDrawer"); + drawer.classList.add("open"); + drawer.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeSourceDrawer() { + const drawer = document.getElementById("sourceDrawer"); + drawer.classList.remove("open"); + drawer.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function renderCollectionJobs() { + const jobs = collectionJobs.filter((job) => state.jobFilter === "all" || job.status === state.jobFilter); + document.getElementById("collectionJobTable").innerHTML = jobs + .map((job) => { + const source = sourceById(job.sourceId); + const statusTone = job.status === "attention" ? "attention" : job.status === "running" ? "running" : ""; + return ` + + ${h(job.name)}${h(job.id)} · ${h(source.name)} + ${h(job.scope)} + ${h(job.strategy)}${h(source.contract)} +
${job.progress ? "已完成" : "等待开始"}${job.progress}%
+ + ${h(job.records)} 条有效率 ${h(job.valid)} + ${job.records === "—" ? "" : ``} + + ${h(job.statusLabel)} +
+ + `; + }) + .join(""); + if (!jobs.length) { + document.getElementById("collectionJobTable").innerHTML = `当前分类暂无采集任务。`; + } + document.getElementById("runningJobCount").textContent = collectionJobs.filter((job) => job.status === "running").length; +} + +function populateRecordSources() { + const select = document.getElementById("recordSourceFilter"); + select.innerHTML = [ + ``, + ...sources.filter((source) => source.category !== "school").map((source) => ``), + ].join(""); + if (!sources.some((source) => source.id === state.recordSource && source.category !== "school")) state.recordSource = "all"; + select.value = state.recordSource; +} + +function recordSearchMatches(values) { + const keyword = state.recordSearch.trim().toLowerCase(); + return !keyword || values.filter(Boolean).join(" ").toLowerCase().includes(keyword); +} + +function filteredStandardRecords() { + return standardJobRecords.filter((record) => { + const source = sourceById(record.sourceId); + const sourceMatch = state.recordSource === "all" || record.sourceId === state.recordSource; + const regionMatch = state.recordRegion === "all" || record.region === state.recordRegion; + return ( + sourceMatch && + regionMatch && + recordSearchMatches([ + record.id, + record.sourceRecordId, + record.taskId, + record.snapshotId, + record.jobTitleRaw, + record.jobTitleNormalized, + record.enterprise, + record.region, + record.workplace, + record.jobCode, + record.skills.join(" "), + source.name, + ]) + ); + }); +} + +function filteredRawSnapshots() { + return allRawSnapshots.filter((snapshot) => { + const source = sourceById(snapshot.sourceId); + const sourceMatch = state.recordSource === "all" || snapshot.sourceId === state.recordSource; + return sourceMatch && recordSearchMatches([snapshot.id, snapshot.taskId, snapshot.objectPath, snapshot.sha256, snapshot.mediaType, source.name]); + }); +} + +function filteredQuarantineRecords() { + return quarantineRecords.filter((record) => { + const source = sourceById(record.sourceId); + const sourceMatch = state.recordSource === "all" || record.sourceId === state.recordSource; + const regionMatch = state.recordRegion === "all" || record.region === state.recordRegion; + return sourceMatch && regionMatch && recordSearchMatches([record.id, record.sourceRecordId, record.taskId, record.snapshotId, record.jobTitle, record.issue, record.rule, source.name]); + }); +} + +function recordSourceCell(source, secondary) { + return ` + + ${h(source.short.slice(0, 2))} + ${h(source.name)}${h(secondary)} + + `; +} + +function recordSalary(record) { + return `¥${formatNumber(record.salaryMin)}–${formatNumber(record.salaryMax)} / 月`; +} + +function renderStandardRecordTable(records, sourceLayer = false) { + if (!records.length) return `
当前查询条件下没有匹配记录,请调整来源、地区或关键词。
`; + const rows = records + .map((record) => { + const source = sourceById(record.sourceId); + if (sourceLayer) { + return ` + + ${recordSourceCell(source, record.sourceRecordId)} + ${h(record.jobTitleRaw)}${h(record.enterprise)} + ${h(record.sourceUrl.replace(/^https?:\/\//, ""))}来源详情定位 + ${h(record.taskId)}${h(record.snapshotId)} + ${h(record.collectorVersion)}${h(record.parserVersion)} + ${h(record.collectedAt)} +
+ + `; + } + return ` + + ${recordSourceCell(source, record.sourceRecordId)} + ${h(record.jobTitleNormalized)}原始:${h(record.jobTitleRaw)} + ${h(record.enterprise)}${h(record.workplace)} + ${h(recordSalary(record))}${h(record.employmentType)} · ${h(record.jobCode)} + ${h(record.publishedAt)}采集 ${h(record.collectedAt)} + ${record.quality.toFixed(1)} +
+ + `; + }) + .join(""); + return ` +
+ + + ${ + sourceLayer + ? "" + : "" + } + + ${rows} +
来源与源记录源端岗位与企业来源URL任务与快照采集器与解析器采集时间操作
来源与源记录标准岗位企业与工作地点薪资与分类发布时间质量分操作
+
+ `; +} + +function renderRawSnapshotTable(snapshots) { + if (!snapshots.length) return `
当前查询条件下没有匹配的原始快照。
`; + return ` +
+ + + + ${snapshots + .map((snapshot) => { + const source = sourceById(snapshot.sourceId); + return ` + + + + + + + + + + + `; + }) + .join("")} + +
来源与快照采集任务对象格式记录与大小对象存储定位固化时间校验状态操作
${recordSourceCell(source, snapshot.id)}${h(snapshot.taskId)}${h(snapshot.mediaType)}${h(snapshot.records)} 条${h(snapshot.size)}${h(snapshot.objectPath)}WORM 原始对象区${h(snapshot.capturedAt)}${h(snapshot.status)}
+
+ `; +} + +function renderQuarantineTable(records) { + if (!records.length) return `
当前查询条件下没有匹配的隔离记录。
`; + return ` +
+ + + + ${records + .map((record) => { + const source = sourceById(record.sourceId); + return ` + + + + + + + + + + + `; + }) + .join("")} + +
隔离编号来源记录岗位质量问题任务与快照发现时间处置状态操作
${h(record.id)}${h(record.rule)}${recordSourceCell(source, record.sourceRecordId)}${h(record.jobTitle)}${h(record.issue)}未进入稳定版本${h(record.taskId)}${h(record.snapshotId)}${h(record.detectedAt)}${h(record.disposition)}
+
+ `; +} + +function currentRecordResults() { + if (state.recordLayer === "raw") return filteredRawSnapshots(); + if (state.recordLayer === "quarantine") return filteredQuarantineRecords(); + return filteredStandardRecords(); +} + +function renderRecords() { + document.querySelectorAll("#recordLayers [data-record-layer]").forEach((button) => { + button.classList.toggle("active", button.dataset.recordLayer === state.recordLayer); + }); + document.getElementById("recordSourceFilter").value = state.recordSource; + document.getElementById("recordRegionFilter").value = state.recordRegion; + document.getElementById("recordSearch").value = state.recordSearch; + const results = currentRecordResults(); + const renderers = { + standard: () => renderStandardRecordTable(results), + source: () => renderStandardRecordTable(results, true), + raw: () => renderRawSnapshotTable(results), + quarantine: () => renderQuarantineTable(results), + }; + document.getElementById("recordTableContainer").innerHTML = renderers[state.recordLayer](); + const layerLabel = { standard: "标准岗位", source: "源端记录", raw: "原始快照", quarantine: "隔离记录" }[state.recordLayer]; + document.getElementById("recordQuerySummary").textContent = `${layerLabel} · 当前展示 ${results.length} 条结构样例`; +} + +function openRecordExplorer(sourceId = "all", search = "", layer = "standard") { + state.recordSource = sources.some((source) => source.id === sourceId && source.category !== "school") ? sourceId : "all"; + state.recordSearch = search; + state.recordRegion = "all"; + state.recordLayer = layer; + populateRecordSources(); + renderRecords(); + switchView("records"); +} + +function openRecordDrawer({ kicker, title, description, content, footer }) { + document.getElementById("recordDrawerKicker").textContent = kicker; + document.getElementById("recordDrawerTitle").textContent = title; + document.getElementById("recordDrawerDescription").textContent = description; + document.getElementById("recordDrawerContent").innerHTML = content; + document.getElementById("recordDrawerFooter").innerHTML = footer; + const drawer = document.getElementById("recordDrawer"); + drawer.classList.add("open"); + drawer.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeRecordDrawer() { + const drawer = document.getElementById("recordDrawer"); + drawer.classList.remove("open"); + drawer.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function openStandardRecord(recordId) { + const record = standardJobRecords.find((item) => item.id === recordId); + if (!record) return; + const source = sourceById(record.sourceId); + const payload = { + record_id: record.id, + source_platform: record.sourceId.toUpperCase(), + source_record_id: record.sourceRecordId, + source_url: record.sourceUrl, + collector_task_id: record.taskId, + collector_version: record.collectorVersion, + raw_snapshot_id: record.snapshotId, + collected_at: record.collectedAt, + published_at: record.publishedAt, + job_title_raw: record.jobTitleRaw, + job_title_normalized: record.jobTitleNormalized, + job_code: record.jobCode, + job_description: record.description, + enterprise_name: record.enterprise, + region_code: record.regionCode, + workplace: record.workplace, + salary_min: record.salaryMin, + salary_max: record.salaryMax, + salary_currency: "CNY", + salary_period: "month", + skills: record.skills, + content_hash: record.contentHash, + parsing_version: record.parserVersion, + normalized_at: record.normalizedAt, + data_version: record.dataVersion, + }; + openRecordDrawer({ + kicker: `STANDARD RECORD · ${record.dataVersion}`, + title: record.jobTitleNormalized, + description: `${source.name} · ${record.sourceRecordId} · ${record.status}`, + content: ` +
+
${h(source.name)} · ${h(record.jobCode)}${h(record.jobTitleRaw)} → ${h(record.jobTitleNormalized)}${h(record.enterprise)} · ${h(record.workplace)} · ${h(recordSalary(record))}
+ ${record.quality.toFixed(1)} +
+
+

标准业务字段

+
+
记录标识
${h(record.id)}
+
企业与岗位
${h(record.enterprise)} · ${h(record.jobTitleNormalized)}
+
工作地点
${h(record.workplace)} · ${h(record.regionCode)}
+
薪资与性质
${h(recordSalary(record))} · ${h(record.employmentType)}
+
技能标签
${record.skills.map((skill) => `${h(skill)}`).join("")}
+ +
+
+
+

全链路证据

+
+ 01采集任务${h(record.taskId)} · ${h(record.collectorVersion)} + 02原始快照${h(record.snapshotId)} · payload SHA-256 ${h(record.payloadHash)} + 03解析映射${h(record.parserVersion)} · ${h(record.sourceRecordId)} + 04质量与归一质量分 ${record.quality.toFixed(1)} · 岗位代码 ${h(record.jobCode)} + 05稳定版本${h(record.dataVersion)} · content SHA-256 ${h(record.contentHash)} +
+
+
+

JOB-SIGNAL V3.0 契约记录

+
${h(JSON.stringify(payload, null, 2))}
+
+ `, + footer: ` + + + + `, + }); +} + +function openRawSnapshot(snapshotId) { + const snapshot = allRawSnapshots.find((item) => item.id === snapshotId); + if (!snapshot) return; + const source = sourceById(snapshot.sourceId); + const manifest = { + snapshot_id: snapshot.id, + source_id: snapshot.sourceId, + collector_task_id: snapshot.taskId, + captured_at: snapshot.capturedAt, + media_type: snapshot.mediaType, + record_count: Number(snapshot.records.replaceAll(",", "")), + object_path: snapshot.objectPath, + compressed_size: snapshot.size, + sha256: snapshot.sha256, + retention_policy: source.retention, + immutable: true, + }; + openRecordDrawer({ + kicker: "RAW SNAPSHOT · IMMUTABLE", + title: snapshot.id, + description: `${source.name} · ${snapshot.records} 条 · ${snapshot.status}`, + content: ` +
+
${h(source.name)} · ${h(snapshot.mediaType)}${h(snapshot.records)} 条原始记录${h(snapshot.objectPath)} · ${h(snapshot.size)}
+ RAW +
+
+

原始对象元数据

+
+
采集任务
${h(snapshot.taskId)}
+
固化时间
${h(snapshot.capturedAt)}
+
对象格式
${h(snapshot.mediaType)}
+
对象定位
${h(snapshot.objectPath)}
+
SHA-256
${h(snapshot.sha256)}
+
留存策略
${h(source.retention)}
+
+
+
+

快照清单

+
${h(JSON.stringify(manifest, null, 2))}
+
+ `, + footer: ` + + + `, + }); +} + +function openQuarantineRecord(recordId) { + const record = quarantineRecords.find((item) => item.id === recordId); + if (!record) return; + const source = sourceById(record.sourceId); + openRecordDrawer({ + kicker: `QUARANTINE · ${record.rule}`, + title: record.jobTitle, + description: `${source.name} · ${record.sourceRecordId} · 未进入稳定版本`, + content: ` +
+
${h(record.rule)} · 质量隔离${h(record.issue)}${h(record.disposition)} · 发现于 ${h(record.detectedAt)}
+ 隔离 +
+
+

隔离处置明细

+
+
隔离编号
${h(record.id)}
+
来源记录
${h(record.sourceRecordId)}
+
质量问题
${h(record.issue)}
+
命中规则
${h(record.rule)}
+
当前处置
${h(record.disposition)}
+
工作地区
${h(record.region)}
+
+
+
+

来源证据

+
+ 01采集任务${h(record.taskId)} + 02原始快照${h(record.snapshotId)} + 03质量规则${h(record.rule)} · ${h(record.issue)} + 04隔离区不覆盖稳定版本,修复后按原任务参数重放 +
+
+ `, + footer: ` + + + `, + }); +} + +function renderContract() { + const contract = contracts[state.contractKey]; + document.querySelectorAll("#contractTabs button").forEach((button) => { + button.classList.toggle("active", button.dataset.contract === state.contractKey); + }); + document.getElementById("contractContent").innerHTML = ` +
+
+ ${h(contract.key)} · ${h(contract.version)} +

${h(contract.title)}

+

${h(contract.description)}

+
+ 字段总数${contract.fields} 个 + 必填字段${contract.required} 个 + 标准责任人${h(contract.owner)} +
+
+
+ CONTRACT RELEASE + ${h(contract.status)} + ${h(contract.release)} · ${h(contract.compatibility)} +
起草评审测试发布
+
+
+
+
+
字段定义

核心字段预览

下载 JSON Schema
+
+ + + ${contract.fieldsPreview + .map( + ([field, type, required, description, rule]) => + ``, + ) + .join("")} +
字段类型必填业务说明约束/代码
${h(field)}${h(type)}${h(required)}${h(description)}${h(rule)}
+
+
+
+
执行规则

契约控制点

${contract.rules.length} 组
+
${contract.rules.map(([title, detail]) => `${h(title)}${h(detail)}`).join("")}
+
+
+ `; +} + +function renderExchangeLogs() { + document.getElementById("exchangeLogTable").innerHTML = exchangeLogs + .map( + (row) => ` + + ${row + .map((cell, index) => `${index === 6 ? `${h(cell)}` : h(cell)}`) + .join("")} + + `, + ) + .join(""); +} + +function renderQuality() { + document.getElementById("qualityRuleList").innerHTML = qualityRules + .map( + ([code, title, detail, score, status]) => ` + ${h(code)}${h(title)}${h(detail)}${h(score)} · ${h(status)} + `, + ) + .join(""); + document.getElementById("normalizationList").innerHTML = normalizationItems + .map( + ([raw, target, confidence], index) => ` + + ${h(raw)}来源岗位别名→ + ${h(target)}建议映射 · 置信度 ${h(confidence)} + + + `, + ) + .join(""); + if (!normalizationItems.length) { + document.getElementById("normalizationList").innerHTML = `
当前高优先级待审项已处理完成,其余低优先级项将在下一批次继续复核。
`; + } +} + +function renderAudit() { + const mergedEvents = [ + ...operationsStore.auditEvents.map((event) => ({ ...event, time: operationTime(event.time) })), + ...auditEvents, + ]; + const events = mergedEvents.filter((event) => state.auditFilter === "all" || event.type === state.auditFilter); + document.getElementById("auditTable").innerHTML = events + .map( + (event) => ` + + ${h(event.time)}${h(event.id)} + ${h(event.event)} + ${h(event.object)} + ${h(event.actor)} + ${h(event.result)} +
${event.evidence.map((item) => `${h(item)}`).join("")}
+ + `, + ) + .join(""); +} + +function openInfoModal(kicker, title, content) { + document.getElementById("infoModalKicker").textContent = kicker; + document.getElementById("infoModalTitle").textContent = title; + document.getElementById("infoModalContent").innerHTML = content; + openModal(document.getElementById("infoModal")); +} + +function csvEscape(value) { + const text = String(value ?? ""); + return /[",\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text; +} + +function downloadText(filename, content, type = "text/plain;charset=utf-8") { + const blob = new Blob([content], { type }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = filename; + document.body.appendChild(anchor); + anchor.click(); + anchor.remove(); + setTimeout(() => URL.revokeObjectURL(url), 500); +} + +function downloadJson(filename, value) { + downloadText(filename, JSON.stringify(value, null, 2), "application/json;charset=utf-8"); +} + +function exportSourceCatalog() { + const headers = ["source_id", "name", "category", "domain", "adapter", "mode", "schedule", "status", "contract", "owner", "version"]; + const rows = sources.map((source) => [ + source.id, + source.name, + source.category, + source.domain, + source.adapter, + source.mode, + source.schedule, + source.statusLabel, + source.contract, + source.owner, + source.version, + ]); + const csv = [headers, ...rows].map((row) => row.map(csvEscape).join(",")).join("\n"); + downloadText("edu-data-source-catalog-20260823.csv", `\uFEFF${csv}`, "text/csv;charset=utf-8"); + showToast(`已导出${sources.length}个数据源及其连接器、契约、责任人与生产版本`, "数据源目录已生成"); +} + +function candidateManifestInputFingerprint() { + const release = currentRelease(); + const disposition = latestQualityDisposition(); + return JSON.stringify({ + releaseId: release?.id, + dataVersion: release?.dataVersion, + product: document.getElementById("exportProduct").value, + tenant: document.getElementById("exportTenant").value, + asOf: document.getElementById("exportAsOf").value, + format: document.getElementById("exportFormat").value, + impactTenants: release?.impactTenants, + deliveries: operationsStore.deliveries.map((delivery) => [delivery.tenantId, delivery.expectedRecords, delivery.expectedSha]), + qualityDisposition: disposition + ? { + id: disposition.id, + action: disposition.action, + status: disposition.status, + trace: disposition.trace, + verification: disposition.verification, + } + : null, + }); +} + +function buildPackageManifest(options = {}) { + const release = currentRelease(); + const approval = currentApproval(); + const releaseStatus = options.releaseStatus || release?.status || "DRAFT"; + const approvalStatus = options.approvalStatus || approval?.status || "DRAFT"; + const published = releaseStatus === "PUBLISHED"; + const product = document.getElementById("exportProduct").value; + const tenantLabel = document.getElementById("exportTenant").value; + const asOf = document.getElementById("exportAsOf").value; + const formatLabel = document.getElementById("exportFormat").value; + const format = { + "Parquet + Manifest": "parquet", + "CSV UTF-8 + Manifest": "csv_utf8", + "JSONL + Manifest": "jsonl", + }[formatLabel]; + const formatMeta = { + parquet: { extension: "parquet", mediaType: "application/vnd.apache.parquet", compression: "zstd", bytesPerRecord: 240 }, + csv_utf8: { extension: "csv", mediaType: "text/csv", compression: "none", bytesPerRecord: 410 }, + jsonl: { extension: "jsonl", mediaType: "application/x-ndjson", compression: "none", bytesPerRecord: 620 }, + }[format]; + const tenantDeliveries = release?.impactTenants?.length + ? release.impactTenants.map((tenantId) => operationsStore.deliveries.find((delivery) => delivery.tenantId === tenantId)).filter(Boolean) + : []; + const tenantScope = tenantDeliveries.length ? tenantDeliveries.map((delivery) => delivery.tenantId) : [tenantLabel]; + const tenantDataFiles = tenantDeliveries.length + ? tenantDeliveries.map((delivery) => ({ + path: `data/${delivery.tenantId}/job-signal.${formatMeta.extension}`, + media_type: formatMeta.mediaType, + bytes: delivery.expectedRecords * formatMeta.bytesPerRecord, + sha256: delivery.expectedSha, + record_count: delivery.expectedRecords, + compression: formatMeta.compression, + })) + : [ + { + path: `data/job-signal.${formatMeta.extension}`, + media_type: formatMeta.mediaType, + bytes: 2846320 * formatMeta.bytesPerRecord, + sha256: "4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32", + record_count: 2846320, + compression: formatMeta.compression, + }, + ]; + const recordCount = tenantDataFiles.reduce((total, file) => total + file.record_count, 0); + return { + manifest_version: "1.2.0", + package_id: release?.packageId || `EDU-PKG-${asOf.replaceAll("-", "")}-CANDIDATE`, + ...(release ? { release_id: release.id, release_status: releaseStatus } : {}), + data_product: product, + data_version: release?.dataVersion || `V${asOf.replaceAll("-", ".")}`, + contract_name: "JOB-SIGNAL", + contract_version: "3.0.0", + data_as_of: asOf, + tenant_scope: tenantScope, + output_format: format, + record_count: recordCount, + quality_score: 94.7, + lineage_snapshot: `LINEAGE-${asOf.replaceAll("-", "")}-09`, + previous_stable_version: release?.previousStableVersion || "V2026.08.22", + files: [ + ...tenantDataFiles, + { + path: "schema/external-job-source.schema.json", + media_type: "application/schema+json", + bytes: 18420, + sha256: "96c2be742dc43f8e7ee526db6358030873406c450f15e67225c605dc39b431a8", + record_count: null, + compression: "none", + }, + { + path: "quality/quality-report.json", + media_type: "application/json", + bytes: 32640, + sha256: "c2d8f733e6711219823110d7d35fdc5535f133ed60f60950f9dc78a228cb402d", + record_count: null, + compression: "none", + }, + { + path: "lineage/source-lineage.json", + media_type: "application/json", + bytes: 84210, + sha256: "66e102b99bf056868670ac971011740c6f66f62b86ea43cc66326ed9a0a5807e", + record_count: null, + compression: "none", + }, + ], + quality_report_path: "quality/quality-report.json", + generated_at: new Date().toISOString(), + generated_by: "陈致远", + approval_reference: approval ? `${approval.id}:${approvalStatus}` : null, + notes: published + ? "该文件是独立审批通过后生成的发布 Manifest;静态原型只记录本地稳定版本状态,不会向学校真实发送。" + : "该文件仅为候选包 Manifest;只有独立审批通过并执行发布后才成为稳定版本,静态原型不会向学校真实发送。", + }; +} + +function generateCandidateManifest() { + const release = currentRelease(); + updateReleaseQualityGate(); + if (!release || release.status !== "DRAFT") { + showToast("候选已进入审批或发布流程,Manifest 已冻结;驳回后需返回草稿重建", "无法重建候选 Manifest"); + return; + } + if (release.qualityGate !== "PASS") { + showToast("只有 FIX_REPLAY 的完整验证证据通过后才能生成候选 Manifest", "质量门禁阻断"); + return; + } + const inputFingerprint = candidateManifestInputFingerprint(); + if (release.candidateManifest && release.candidateInputFingerprint === inputFingerprint) { + downloadJson(`${release.candidateManifest.package_id}-candidate-manifest.json`, release.candidateManifest); + showToast("候选输入与质量证据未变化,已复用原 Manifest;未新增审计或交换记录", "候选 Manifest 已复用"); + return; + } + const manifest = buildPackageManifest(); + const metadata = addOperationsAudit({ + type: "publish", + event: "生成候选包 Manifest", + object: `${release.id} · ${release.packageId}`, + result: "候选已生成", + evidence: ["Manifest", "质量报告", "血缘快照", "SHA-256"], + }); + release.manifestGeneratedAt = metadata.time; + release.candidateManifest = manifest; + release.candidateInputFingerprint = inputFingerprint; + release.actor = metadata.actor; + release.time = metadata.time; + release.trace = metadata.trace; + release.evidence = [...metadata.evidence]; + saveOperationsStore(); + downloadJson(`${manifest.package_id}-candidate-manifest.json`, manifest); + exchangeLogs.unshift([manifest.package_id, "候选导出", manifest.data_product, manifest.data_version, formatNumber(manifest.record_count), "陈致远", "候选已生成", "刚刚"]); + exchangeLogs.splice(OPERATIONS_LIMITS.exchangeLogs); + renderExchangeLogs(); + renderOperations(); + renderAudit(); + showToast(`${manifest.package_id} 仅生成候选文件,尚未发布或向学校发送`, "候选包 / Manifest 已生成"); +} + +function exportDailyReport() { + const report = { + report_id: "OPS-DAILY-20260823", + generated_at: new Date().toISOString(), + environment: "production-east-cn", + batch: "EDU-JOB-20260823", + source_count: sources.length, + running_sources: sources.filter((source) => source.status === "running").length, + running_jobs: collectionJobs.filter((job) => job.status === "running").length, + records_collected_today: sources.reduce((sum, source) => sum + source.today, 0), + quality_score: 94.7, + normalization_coverage: 96.4, + stable_data_version: "V2026.08.23", + tenant_delivery_count: 36, + attention_items: [ + "27个岗位别名待人工归一", + "杭州人才网处于自动降速保护", + "SCHOOL-EMPLOYMENT V2.2待生产发布", + ], + }; + downloadJson("edu-data-operations-daily-20260823.json", report); + showToast("运行日报包含生产批次、来源、采集、质量、归一和交付状态", "运行日报已生成"); +} + +function exportExchangeLog() { + const headers = ["trace_id", "type", "object", "version", "records", "actor", "result", "time"]; + const csv = [headers, ...exchangeLogs].map((row) => row.map(csvEscape).join(",")).join("\n"); + downloadText("edu-data-exchange-log-20260823.csv", `\uFEFF${csv}`, "text/csv;charset=utf-8"); + showToast("导入与交付记录已按当前筛选范围导出", "交换记录已生成"); +} + +function exportAuditLog() { + const headers = ["trace_id", "time", "type", "event", "object", "actor", "result", "evidence"]; + const rows = [...operationsStore.auditEvents, ...auditEvents].map((event) => [ + event.trace || event.id, + event.time, + event.type, + event.event, + event.object, + event.actor, + event.result, + event.evidence.join("|"), + ]); + const csv = [headers, ...rows].map((row) => row.map(csvEscape).join(",")).join("\n"); + downloadText("edu-data-audit-log-20260823.csv", `\uFEFF${csv}`, "text/csv;charset=utf-8"); + showToast("审计日志已携带追踪编号、操作者、结果和证据清单", "审计日志已生成"); +} + +function setupNavigation() { + document.querySelectorAll(".nav-item[data-view]").forEach((button) => button.addEventListener("click", () => switchView(button.dataset.view))); + document.addEventListener("click", (event) => { + const jump = event.target.closest("[data-view-jump]"); + if (jump) switchView(jump.dataset.viewJump); + const issueButton = event.target.closest("[data-open-issue]"); + if (issueButton) { + const issueId = issueButton.dataset.openIssue; + const modal = issueButton.closest(".modal-backdrop"); + if (modal) closeModal(modal); + state.operationsTab = "issues"; + renderOperations(); + switchView("operations"); + openIssueDrawer(issueId); + } + const operationsJump = event.target.closest("[data-operations-jump]"); + if (operationsJump) { + const operationsTab = operationsJump.dataset.operationsJump; + const modal = operationsJump.closest(".modal-backdrop"); + if (modal) closeModal(modal); + state.operationsTab = operationsTab; + renderOperations(); + switchView("operations"); + } + const sourceButton = event.target.closest("[data-source-detail]"); + if (sourceButton) openSourceDrawer(sourceButton.dataset.sourceDetail); + const sourceRecordsButton = event.target.closest("[data-source-records]"); + if (sourceRecordsButton) { + if (document.getElementById("sourceDrawer").classList.contains("open")) closeSourceDrawer(); + openRecordExplorer(sourceRecordsButton.dataset.sourceRecords); + } + const sourceModalButton = event.target.closest("[data-open-source-modal]"); + if (sourceModalButton) openModal(document.getElementById("sourceModal")); + }); + document.getElementById("mobileMenu").addEventListener("click", () => document.body.classList.add("sidebar-open")); + document.getElementById("sidebarScrim").addEventListener("click", () => document.body.classList.remove("sidebar-open")); + document.getElementById("globalSearch").addEventListener("keydown", (event) => { + if (event.key !== "Enter") return; + state.sourceSearch = event.currentTarget.value; + document.getElementById("sourceSearch").value = state.sourceSearch; + switchView("sources"); + renderSources(); + }); +} + +function setupSourceRegistry() { + document.getElementById("sourceFilters").addEventListener("click", (event) => { + const button = event.target.closest("[data-source-filter]"); + if (!button) return; + state.sourceFilter = button.dataset.sourceFilter; + document.querySelectorAll("[data-source-filter]").forEach((item) => item.classList.toggle("active", item === button)); + renderSources(); + }); + document.getElementById("sourceSearch").addEventListener("input", (event) => { + state.sourceSearch = event.target.value; + renderSources(); + }); + document.getElementById("sourceCatalogExport").addEventListener("click", exportSourceCatalog); + document.getElementById("sourceForm").addEventListener("submit", (event) => { + event.preventDefault(); + const name = document.getElementById("newSourceName").value.trim(); + const domainInput = document.getElementById("newSourceDomain").value.trim(); + let domain; + try { + const url = new URL(domainInput); + if (!["http:", "https:", "jdbc:", "sftp:"].includes(url.protocol)) throw new Error("unsupported"); + domain = url.host || domainInput; + } catch { + showToast("请输入有效的 HTTP、HTTPS、JDBC 或 SFTP 数据源地址", "数据源地址无效"); + return; + } + if (sources.some((source) => source.domain === domain)) { + showToast("该入口已登记,请进入现有数据源创建新版本或采集任务", "数据源已存在"); + return; + } + const category = document.getElementById("newSourceCategory").value; + const categoryLabel = { commercial: "商业平台", public: "公共平台", school: "校内系统" }[category]; + const source = { + id: `source-${Date.now()}`, + name, + short: name.slice(0, 2), + category, + categoryLabel, + domain, + adapter: `Custom-Collector 1.0`, + mode: document.getElementById("newSourceMode").value, + schedule: document.getElementById("newSourceSchedule").value, + status: "running", + statusLabel: "连接测试", + health: 100, + today: 0, + total: "0", + updated: "刚刚", + coverage: document.getElementById("newSourceScope").value.trim(), + contract: document.getElementById("newSourceContract").value, + schema: "CUSTOM-SOURCE 1.0", + version: `SRC-CUSTOM-${new Date().toISOString().slice(0, 10).replaceAll("-", "")}-01`, + owner: document.getElementById("newSourceOwner").value.trim(), + retention: "原始数据 180 天 · 解析结果 36 个月", + rate: "初次样本验证 · 1 分片", + retry: "指数退避 · 最多 3 次", + change: "新数据源已注册,等待小样本连接测试和字段映射确认。", + repo: "connector-registry/custom-collector", + codeVersion: "draft/1.0.0 · pending", + runtime: [["刚刚", "数据源完成注册", "连接测试任务已创建"]], + }; + sources.unshift(source); + populateJobSources(); + populateRecordSources(); + collectionJobs.unshift({ + id: `JOB-${Date.now()}`, + name: `${name}连接与样本预检`, + sourceId: source.id, + scope: source.coverage, + strategy: "样本验证 · 1分片", + progress: 0, + records: "—", + valid: "—", + status: "scheduled", + statusLabel: "等待调度", + }); + event.currentTarget.reset(); + closeModal(document.getElementById("sourceModal")); + renderSources(); + renderOverviewSources(); + renderCollectionJobs(); + switchView("sources"); + showToast(`${name}已进入数据源注册中心,连接测试任务已创建`, "数据源注册成功"); + }); +} + +function setupSourceDrawer() { + document.getElementById("closeSourceDrawer").addEventListener("click", closeSourceDrawer); + document.getElementById("sourceDrawer").addEventListener("click", (event) => { + if (event.target === event.currentTarget) closeSourceDrawer(); + }); + document.getElementById("sourceDrawerTabs").addEventListener("click", (event) => { + const button = event.target.closest("[data-source-tab]"); + if (!button) return; + state.sourceTab = button.dataset.sourceTab; + updateSourceDrawer(); + }); + document.getElementById("sourceDrawerFooter").addEventListener("click", (event) => { + if (event.target.closest("[data-drawer-close]")) { + closeSourceDrawer(); + return; + } + const test = event.target.closest("[data-source-test]"); + if (test) { + const source = sourceById(test.dataset.sourceTest); + test.disabled = true; + test.textContent = "正在测试…"; + setTimeout(() => { + test.disabled = false; + test.textContent = "测试连接"; + showToast(`${source.name}入口可达,样本解析和契约映射验证通过`, "连接测试通过"); + }, 900); + return; + } + const jobButton = event.target.closest("[data-source-job]"); + if (jobButton) { + const source = sourceById(jobButton.dataset.sourceJob); + closeSourceDrawer(); + document.getElementById("jobSource").value = source.id; + document.getElementById("jobName").value = `${source.name}增量采集`; + openModal(document.getElementById("jobModal")); + } + }); +} + +function setupCollectionJobs() { + document.getElementById("jobFilters").addEventListener("click", (event) => { + const button = event.target.closest("[data-job-filter]"); + if (!button) return; + state.jobFilter = button.dataset.jobFilter; + document.querySelectorAll("[data-job-filter]").forEach((item) => item.classList.toggle("active", item === button)); + renderCollectionJobs(); + }); + document.getElementById("collectionJobTable").addEventListener("click", (event) => { + const toggle = event.target.closest("[data-job-toggle]"); + if (toggle) { + const job = collectionJobs.find((item) => item.id === toggle.dataset.jobToggle); + if (!job) return; + if (job.status === "running") { + job.status = "scheduled"; + job.statusLabel = "已暂停"; + } else { + job.status = "running"; + job.statusLabel = "运行中"; + if (!job.progress) job.progress = 4; + } + renderCollectionJobs(); + showToast(`${job.name}当前状态:${job.statusLabel}`, "任务状态已更新"); + return; + } + const detail = event.target.closest("[data-job-detail]"); + if (detail) { + const job = collectionJobs.find((item) => item.id === detail.dataset.jobDetail); + const source = sourceById(job.sourceId); + openInfoModal( + "COLLECTION JOB DETAIL", + job.name, + `
追踪编号${h(job.id)}数据来源${h(source.name)}任务范围${h(job.scope)}运行策略${h(job.strategy)}当前进度${job.progress}%目标契约${h(source.contract)}
任务绑定连接器 ${h(source.codeVersion)}、源版本 ${h(source.version)} 和原始快照。失败分片进入隔离队列,可按原任务参数重放。
`, + ); + return; + } + const records = event.target.closest("[data-job-records]"); + if (records) { + const job = collectionJobs.find((item) => item.id === records.dataset.jobRecords); + if (!job) return; + openRecordExplorer(job.sourceId, job.id, "source"); + } + }); + document.getElementById("newCollectionJob").addEventListener("click", () => openModal(document.getElementById("jobModal"))); + document.getElementById("jobForm").addEventListener("submit", (event) => { + event.preventDefault(); + const sourceId = document.getElementById("jobSource").value; + const job = { + id: `JOB-${Date.now()}`, + name: document.getElementById("jobName").value.trim(), + sourceId, + scope: `${document.getElementById("jobRegion").value.trim()} · ${document.getElementById("jobScope").value.trim()}`, + strategy: `${document.getElementById("jobMode").value} · 预检分片`, + progress: document.getElementById("jobSchedule").value === "立即执行" ? 4 : 0, + records: "—", + valid: "—", + status: document.getElementById("jobSchedule").value === "立即执行" ? "running" : "scheduled", + statusLabel: document.getElementById("jobSchedule").value === "立即执行" ? "预检中" : "等待调度", + }; + collectionJobs.unshift(job); + closeModal(document.getElementById("jobModal")); + renderCollectionJobs(); + switchView("collectors"); + showToast(`${job.name}已创建,任务先执行小样本预检`, "采集任务已进入队列"); + }); + document.getElementById("pauseAllJobs").addEventListener("click", (event) => { + const resume = event.currentTarget.dataset.mode === "resume"; + collectionJobs.forEach((job) => { + if (resume && job.status === "scheduled") { + job.status = "running"; + job.statusLabel = "运行中"; + } else if (!resume && job.status === "running") { + job.status = "scheduled"; + job.statusLabel = "已暂停"; + } + }); + event.currentTarget.dataset.mode = resume ? "" : "resume"; + event.currentTarget.textContent = resume ? "暂停全部" : "恢复全部"; + renderCollectionJobs(); + showToast(resume ? "已恢复所有可运行采集任务" : "运行中任务已安全暂停并保存水位", "调度器状态已更新"); + }); +} + +function exportCurrentRecords() { + const results = currentRecordResults(); + if (!results.length) { + showToast("当前查询条件下没有可导出的记录", "没有查询结果"); + return; + } + if (state.recordLayer === "raw") { + downloadJson("raw-snapshot-query-20260823.json", { + query: { source_id: state.recordSource, keyword: state.recordSearch }, + stable_version: "V2026.08.23", + records: results, + }); + } else if (state.recordLayer === "quarantine") { + const headers = ["quarantine_id", "source_id", "source_record_id", "job_title", "issue", "rule", "detected_at", "disposition", "task_id", "snapshot_id"]; + const rows = results.map((record) => [record.id, record.sourceId, record.sourceRecordId, record.jobTitle, record.issue, record.rule, record.detectedAt, record.disposition, record.taskId, record.snapshotId]); + const csv = [headers, ...rows].map((row) => row.map(csvEscape).join(",")).join("\n"); + downloadText("quarantine-record-query-20260823.csv", `\uFEFF${csv}`, "text/csv;charset=utf-8"); + } else { + const headers = + state.recordLayer === "source" + ? ["record_id", "source_id", "source_record_id", "source_url", "task_id", "snapshot_id", "job_title_raw", "enterprise_name", "collected_at", "collector_version", "parser_version"] + : ["record_id", "source_id", "source_record_id", "job_title_raw", "job_title_normalized", "job_code", "enterprise_name", "region_code", "workplace", "salary_min", "salary_max", "published_at", "collected_at", "quality_score", "content_hash", "data_version"]; + const rows = results.map((record) => + state.recordLayer === "source" + ? [record.id, record.sourceId, record.sourceRecordId, record.sourceUrl, record.taskId, record.snapshotId, record.jobTitleRaw, record.enterprise, record.collectedAt, record.collectorVersion, record.parserVersion] + : [record.id, record.sourceId, record.sourceRecordId, record.jobTitleRaw, record.jobTitleNormalized, record.jobCode, record.enterprise, record.regionCode, record.workplace, record.salaryMin, record.salaryMax, record.publishedAt, record.collectedAt, record.quality, record.contentHash, record.dataVersion], + ); + const csv = [headers, ...rows].map((row) => row.map(csvEscape).join(",")).join("\n"); + downloadText(`${state.recordLayer}-job-record-query-20260823.csv`, `\uFEFF${csv}`, "text/csv;charset=utf-8"); + } + showToast(`已按当前条件导出 ${results.length} 条${{ standard: "标准岗位", source: "源端记录", raw: "原始快照", quarantine: "隔离记录" }[state.recordLayer]}`, "查询结果已生成"); +} + +function setupRecords() { + document.getElementById("recordLayers").addEventListener("click", (event) => { + const button = event.target.closest("[data-record-layer]"); + if (!button) return; + state.recordLayer = button.dataset.recordLayer; + renderRecords(); + }); + document.getElementById("recordSourceFilter").addEventListener("change", (event) => { + state.recordSource = event.target.value; + renderRecords(); + }); + document.getElementById("recordRegionFilter").addEventListener("change", (event) => { + state.recordRegion = event.target.value; + renderRecords(); + }); + document.getElementById("recordSearch").addEventListener("input", (event) => { + state.recordSearch = event.target.value; + renderRecords(); + }); + document.getElementById("recordTableContainer").addEventListener("click", (event) => { + const record = event.target.closest("[data-record-id]"); + if (record) { + openStandardRecord(record.dataset.recordId); + return; + } + const snapshot = event.target.closest("[data-snapshot-id]"); + if (snapshot) { + openRawSnapshot(snapshot.dataset.snapshotId); + return; + } + const quarantine = event.target.closest("[data-quarantine-id]"); + if (quarantine) openQuarantineRecord(quarantine.dataset.quarantineId); + }); + document.getElementById("recordRefresh").addEventListener("click", () => { + renderRecords(); + showToast("查询已重新执行,当前绑定稳定数据版本 V2026.08.23", "采集数据已刷新"); + }); + document.getElementById("recordExport").addEventListener("click", exportCurrentRecords); + document.getElementById("closeRecordDrawer").addEventListener("click", closeRecordDrawer); + document.getElementById("recordDrawer").addEventListener("click", (event) => { + if (event.target === event.currentTarget) closeRecordDrawer(); + }); + document.getElementById("recordDrawerFooter").addEventListener("click", (event) => { + if (event.target.closest("[data-record-close]")) { + closeRecordDrawer(); + return; + } + const source = event.target.closest("[data-record-source]"); + if (source) { + closeRecordDrawer(); + openSourceDrawer(source.dataset.recordSource); + return; + } + const raw = event.target.closest("[data-record-raw]"); + if (raw) { + state.recordSource = raw.dataset.recordSourceId; + state.recordLayer = "raw"; + state.recordSearch = raw.dataset.recordRaw; + closeRecordDrawer(); + populateRecordSources(); + renderRecords(); + showToast(`${raw.dataset.recordRaw} 已在原始快照层定位`, "已切换数据层"); + } + }); +} + +function setupContracts() { + document.getElementById("contractTabs").addEventListener("click", (event) => { + const button = event.target.closest("[data-contract]"); + if (!button) return; + state.contractKey = button.dataset.contract; + renderContract(); + }); + document.getElementById("downloadStandardKit").addEventListener("click", () => { + const kit = { + product: "产教数据中台标准包", + version: "2026.08", + generated_at: new Date().toISOString(), + contracts: Object.values(contracts).map((contract) => ({ + name: contract.key, + version: contract.version, + status: contract.status, + schema: contract.schemaPath, + })), + dictionaries: ["GB/T 2260 地区代码", "教育部职业教育专业目录", "岗位分类词典 V4.3", "技能词典 V3.8"], + delivery_requirements: ["JSON Schema", "数据样例", "字段说明", "质量门槛", "变更日志", "Manifest"], + }; + downloadJson("edu-industry-data-standard-kit-2026.08.json", kit); + showToast("标准包索引已生成,可继续下载每个契约的 JSON Schema 与样例文件", "数据标准包已下载"); + }); + document.getElementById("compareContractVersions").addEventListener("click", () => { + const contract = contracts[state.contractKey]; + openInfoModal( + "CONTRACT VERSION DIFF", + `${contract.key} 版本变更`, + `
当前版本${h(contract.version)}兼容策略${h(contract.compatibility)}发布时间${h(contract.release)}影响来源${state.contractKey === "external-job" ? "7个外部来源" : "36所学校租户"}
正式发布前执行 Schema 兼容性、历史样本回放、字段映射和下游影响测试。破坏性变更必须提升主版本并提供双写迁移窗口。
`, + ); + }); +} + +function setupExchange() { + const input = document.getElementById("importFile"); + const zone = document.getElementById("uploadZone"); + const preview = document.getElementById("importPreview"); + const validateButton = document.getElementById("validateImport"); + const handleFile = (file) => { + if (!file) return; + input._selectedFile = file; + preview.querySelector("small").textContent = `${(file.size / 1024).toFixed(1)} KB · ${file.type || "application/octet-stream"}`; + preview.querySelector("strong").textContent = file.name; + validateButton.disabled = false; + }; + input.addEventListener("change", () => handleFile(input.files[0])); + ["dragenter", "dragover"].forEach((type) => + zone.addEventListener(type, (event) => { + event.preventDefault(); + zone.classList.add("dragging"); + }), + ); + ["dragleave", "drop"].forEach((type) => + zone.addEventListener(type, (event) => { + event.preventDefault(); + zone.classList.remove("dragging"); + if (type === "drop") handleFile(event.dataTransfer.files[0]); + }), + ); + validateButton.addEventListener("click", async () => { + const file = input._selectedFile || input.files[0]; + if (!file) return; + validateButton.disabled = true; + validateButton.textContent = "正在预检…"; + let result = { passed: true, message: "文件结构可读取,已进入服务端分片与质量干跑" }; + if (file.name.toLowerCase().endsWith(".csv")) { + const text = await file.text(); + const [headerLine, ...lines] = text.split(/\r?\n/).filter(Boolean); + const headers = headerLine.split(",").map((item) => item.trim().replace(/^"|"$/g, "")); + const contractKey = document.getElementById("importContract").value; + const required = + contractKey === "external-job" + ? ["record_id", "source_platform", "source_record_id", "source_url", "collected_at", "job_title_raw", "enterprise_name", "region_code", "content_hash"] + : ["tenant_id", "student_token", "cohort", "program_code", "employment_status", "confirmed_at", "source_system", "updated_at"]; + const missing = required.filter((field) => !headers.includes(field)); + result = { + passed: missing.length === 0, + message: missing.length ? `缺少必填字段:${missing.join("、")}` : `识别 ${headers.length} 个字段、${lines.length} 条样本记录,核心必填字段完整`, + }; + } + preview.querySelector("small").textContent = result.passed ? "结构预检通过" : "结构预检未通过"; + preview.querySelector("strong").textContent = result.message; + validateButton.disabled = false; + validateButton.textContent = result.passed ? "重新预检" : "修复后重试"; + if (result.passed) { + exchangeLogs.unshift([`IMP-${Date.now()}`, "导入", file.name, "暂存版本", "样本预检", "陈致远", "预检通过", "刚刚"]); + renderExchangeLogs(); + } + showToast(result.message, result.passed ? "导入预检通过" : "导入预检失败"); + }); + document.getElementById("buildExportPackage").addEventListener("click", () => { + document.querySelector(".export-panel").scrollIntoView({ behavior: "smooth", block: "center" }); + }); + document.getElementById("generatePackage").addEventListener("click", () => { + generateCandidateManifest(); + }); + document.getElementById("exportExchangeLog").addEventListener("click", exportExchangeLog); +} + +function setupQuality() { + document.getElementById("normalizationList").addEventListener("click", (event) => { + const button = event.target.closest("[data-normalize-index]"); + if (!button) return; + const index = Number(button.dataset.normalizeIndex); + const item = normalizationItems[index]; + normalizationItems.splice(index, 1); + renderQuality(); + showToast(`“${item[0]}”已映射到“${item[1]}”,规则将在下一批次生效`, "岗位归一已确认"); + }); + document.getElementById("normalizationBatch").addEventListener("click", () => { + const count = normalizationItems.length; + normalizationItems = []; + renderQuality(); + showToast(`已确认 ${count} 个高置信度岗位映射,变更记录已写入审计`, "批量归一完成"); + }); + document.getElementById("qualityRuleButton").addEventListener("click", () => { + openInfoModal( + "QUALITY POLICY", + "生产质量规则策略", + `
阻断规则12条告警规则20条综合发布阈值≥ 90规则版本QUALITY 3.6
阻断规则失败时任务进入隔离区,不更新稳定版本;告警规则允许带限制发布,但必须在质量报告中披露样本、影响范围和处置计划。
`, + ); + }); +} + +function setupAudit() { + document.getElementById("auditFilters").addEventListener("click", (event) => { + const button = event.target.closest("[data-audit-filter]"); + if (!button) return; + state.auditFilter = button.dataset.auditFilter; + document.querySelectorAll("[data-audit-filter]").forEach((item) => item.classList.toggle("active", item === button)); + renderAudit(); + }); + document.getElementById("exportAuditLog").addEventListener("click", exportAuditLog); + document.getElementById("auditPolicyButton").addEventListener("click", () => { + openInfoModal( + "AUDIT POLICY", + "生产审计与留存策略", + `
关键事件留存36个月审计存储WORM每日完整性校验SHA-256追踪覆盖率100%
采集请求、连接器版本、原始快照、映射规则、质量结果、审批和租户交付都写入统一 trace_id。敏感配置只记录密钥引用和变更摘要,不在日志中保存明文凭据。
`, + ); + }); +} + +function setupOperations() { + document.getElementById("operationsTabs").addEventListener("click", (event) => { + const button = event.target.closest("[data-operations-tab]"); + if (!button) return; + state.operationsTab = button.dataset.operationsTab; + renderOperations(); + }); + document.getElementById("operationsPrimaryAction").addEventListener("click", () => { + const issue = operationsStore.issues.find((item) => !["RESOLVED", "CLOSED"].includes(item.status)); + if (issue) openIssueDrawer(issue.id); + else { + state.operationsTab = "releases"; + renderOperations(); + } + }); + document.getElementById("resetOperationsSeed").addEventListener("click", () => { + operationsStore = operationsSeed(); + saveOperationsStore(); + closeIssueDrawer(); + renderOperations(); + renderAudit(); + showToast("问题、工单、质量、审批、发布、交付与审计已恢复到可重复演示种子", "运营处置数据已重置"); + }); + document.getElementById("closeIssueDrawer").addEventListener("click", closeIssueDrawer); + document.getElementById("issueDrawer").addEventListener("click", (event) => { + if (event.target === event.currentTarget) closeIssueDrawer(); + }); + document.getElementById("issueDrawer").addEventListener("click", (event) => { + if (event.target.closest("[data-issue-close]")) { + closeIssueDrawer(); + return; + } + const button = event.target.closest("[data-issue-action]"); + if (!button) return; + const issue = operationsStore.issues.find((item) => item.id === state.issueId); + if (!issue) return; + const action = button.dataset.issueAction; + if (action === "acknowledge" && issue.status === "ALERTED") { + transitionIssue(issue, "ACKNOWLEDGED", "运营人员已确认告警、影响与SLA。", ["告警确认记录"]); + return; + } + if (action === "assign" && issue.status === "ACKNOWLEDGED") { + const assignee = document.getElementById("issueAssignee")?.value; + if (!assignee) return; + issue.owner = assignee; + transitionIssue(issue, "ASSIGNED", `已指派给 ${assignee}。`, ["责任人指派记录"]); + return; + } + if (action === "investigate" && issue.status === "ASSIGNED") { + transitionIssue(issue, "INVESTIGATING", "已锁定源端时延与解析隔离记录,开始执行排障。", ["排障工作区快照", issue.relatedTask]); + return; + } + if (action === "submit-quality" && issue.status === "INVESTIGATING") { + const dispositionAction = document.getElementById("qualityDispositionAction")?.value; + const reviewer = document.getElementById("qualityReviewer")?.value; + const reason = document.getElementById("qualityDispositionReason")?.value.trim(); + if (!reason) { + showToast("必须填写根因、处置范围与复核依据", "缺少处置原因"); + return; + } + if (reviewer === OPERATIONS_ACTOR) { + showToast("质量复核人必须独立于处置提交人", "复核职责未分离"); + return; + } + const evidence = + dispositionAction === "FIX_REPLAY" + ? ["不可变处置动作", "修复补丁 HZRC-2.7.4", "重放任务 REPLAY-HZRC-20260823-01"] + : dispositionAction === "WAIVE" + ? ["不可变处置动作", "风险影响评估", "豁免理由"] + : ["不可变处置动作", "拟丢弃范围", "完整性影响评估"]; + const metadata = addOperationsAudit({ + type: "quality", + event: `${issue.title}提交质量复核`, + object: issue.id, + result: "待复核", + evidence, + }); + operationsStore.qualityDispositions.push({ + id: operationToken("QD"), + status: "PENDING_REVIEW", + actor: metadata.actor, + time: metadata.time, + trace: metadata.trace, + evidence: [...metadata.evidence], + issueId: issue.id, + action: dispositionAction, + reason, + reviewer, + immutable: true, + verification: + dispositionAction === "FIX_REPLAY" + ? { + expectedRecords: 3860, + replayedRecords: null, + rulesPassed: false, + reviewerSigned: false, + } + : null, + }); + migrateOperationsEntity(issue, "QUALITY_REVIEW_PENDING", metadata); + issue.timeline.push({ + id: operationToken("STEP"), + status: "QUALITY_REVIEW_PENDING", + actor: metadata.actor, + time: metadata.time, + trace: metadata.trace, + evidence: [...metadata.evidence], + note: `${{ FIX_REPLAY: "修复并重放", WAIVE: "豁免", DISCARD: "丢弃" }[dispositionAction]}已提交 ${reviewer} 复核。`, + }); + const workOrder = operationsStore.workOrders.find((item) => item.issueId === issue.id); + if (workOrder) migrateOperationsEntity(workOrder, "QUALITY_REVIEW_PENDING", metadata); + saveOperationsStore(); + renderOperations(); + renderAudit(); + openIssueDrawer(issue.id); + showToast("处置动作已固化并写入审计,等待独立质量复核", "质量处置已提交"); + return; + } + if (action === "verify-blocked" && issue.status === "QUALITY_REVIEW_PENDING") { + const disposition = latestQualityDisposition(issue.id); + if (!disposition || disposition.action === "FIX_REPLAY") return; + const actionLabel = disposition.action === "WAIVE" ? "风险豁免" : "丢弃异常数据"; + const metadata = addOperationsAudit({ + type: "quality", + event: `${issue.title}${actionLabel}复核完成`, + object: disposition.id, + actor: disposition.reviewer, + result: "REVIEWED_BLOCKED", + evidence: disposition.action === "WAIVE" ? ["风险影响评估", "独立复核签名", "需另行风险审批"] : ["丢弃范围清单", "完整性影响评估", "需重建候选并复核"], + }); + migrateOperationsEntity(disposition, "REVIEWED_BLOCKED", metadata); + migrateOperationsEntity(issue, "INVESTIGATING", metadata); + issue.timeline.push({ + id: operationToken("STEP"), + status: "REVIEWED_BLOCKED", + actor: metadata.actor, + time: metadata.time, + trace: metadata.trace, + evidence: [...metadata.evidence], + note: + disposition.action === "WAIVE" + ? "风险豁免不等同于质量验证通过;候选门禁保持阻断,必须另行提交风险审批。" + : "丢弃可能改变数据完整性;候选门禁保持阻断,必须重建候选并重新执行质量验证。", + }); + const workOrder = operationsStore.workOrders.find((item) => item.issueId === issue.id); + if (workOrder) migrateOperationsEntity(workOrder, "INVESTIGATING", metadata); + updateReleaseQualityGate(); + saveOperationsStore(); + renderOperations(); + renderAudit(); + openIssueDrawer(issue.id); + showToast(`${actionLabel}已复核,但不能解除发布门禁`, "质量门禁仍阻断"); + return; + } + if (action === "verify" && issue.status === "QUALITY_REVIEW_PENDING") { + const disposition = latestQualityDisposition(issue.id); + if (!disposition || disposition.action !== "FIX_REPLAY") { + showToast("只有修复并重放可以进入质量验证通过状态", "质量门禁仍阻断"); + return; + } + const metadata = addOperationsAudit({ + type: "quality", + event: `${issue.title}质量复核通过`, + object: disposition.id, + actor: disposition.reviewer, + result: "VERIFIED", + evidence: ["重放结果 3,860/3,860", "质量规则全量通过", "复核签名"], + }); + disposition.verification = { + expectedRecords: 3860, + replayedRecords: 3860, + rulesPassed: true, + reviewerSigned: true, + }; + migrateOperationsEntity(disposition, "VERIFIED", metadata); + migrateOperationsEntity(issue, "VERIFIED", metadata); + issue.timeline.push({ + id: operationToken("STEP"), + status: "VERIFIED", + actor: metadata.actor, + time: metadata.time, + trace: metadata.trace, + evidence: [...metadata.evidence], + note: "记录数、质量规则与重放证据已复核,候选版本质量门禁解除。", + }); + const workOrder = operationsStore.workOrders.find((item) => item.issueId === issue.id); + if (workOrder) migrateOperationsEntity(workOrder, "VERIFIED", metadata); + updateReleaseQualityGate(); + saveOperationsStore(); + renderOperations(); + renderAudit(); + openIssueDrawer(issue.id); + showToast("质量处置已 VERIFIED,候选版本现在可提交审批", "质量门禁已通过"); + return; + } + if (action === "resolve" && (issue.status === "VERIFIED" || (issue.status === "INVESTIGATING" && !issue.qualityRequired))) { + transitionIssue(issue, "RESOLVED", "影响已消除,稳定版本与后续任务验证正常。", ["恢复指标", "验证报告"]); + return; + } + if (action === "close" && issue.status === "RESOLVED") { + transitionIssue(issue, "CLOSED", "问题复盘完成,工单正式关闭。", ["关闭检查单", "复盘摘要"]); + } + }); + document.getElementById("releaseWorkspace").addEventListener("click", (event) => { + const release = currentRelease(); + const approval = currentApproval(); + if (event.target.closest("[data-release-manifest]")) { + generateCandidateManifest(); + return; + } + if (event.target.closest("[data-release-official-manifest]")) { + if (!release.publishedManifest) { + showToast("尚未形成发布 Manifest", "下载不可用"); + return; + } + downloadJson(`${release.packageId}-published-manifest.json`, release.publishedManifest); + showToast(`${release.packageId} 发布 Manifest 已下载,审批引用为 ${release.publishedManifest.approval_reference}`, "发布 Manifest"); + return; + } + if (event.target.closest("[data-release-submit]")) { + updateReleaseQualityGate(); + if (!releaseReadyForApproval(release)) { + showToast( + release.qualityGate === "PASS" ? "质量门禁已通过,但必须先生成并冻结候选 Manifest" : "只有验证通过的 FIX_REPLAY 才能解除候选版本门禁", + "候选尚不可提交", + ); + return; + } + const metadata = addOperationsAudit({ + type: "publish", + event: "候选版本提交独立审批", + object: release.id, + result: "待审批", + evidence: ["候选 Manifest", "质量门禁 PASS", "影响租户清单"], + }); + migrateOperationsEntity(release, "PENDING_APPROVAL", metadata); + migrateOperationsEntity(approval, "PENDING_APPROVAL", metadata); + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast(`${release.id} 已提交,申请人不能批准自己的申请`, "审批单已创建"); + return; + } + if (event.target.closest("[data-release-resubmit]")) { + const metadata = addOperationsAudit({ + type: "publish", + event: "驳回候选返回草稿重建", + object: release.id, + result: "草稿", + evidence: ["审批驳回意见", "候选失效记录", "质量报告"], + }); + migrateOperationsEntity(release, "DRAFT", metadata); + migrateOperationsEntity(approval, "DRAFT", metadata); + release.manifestGeneratedAt = null; + release.candidateManifest = null; + release.candidateInputFingerprint = null; + approval.approver = null; + approval.comment = ""; + approval.decidedAt = null; + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast("旧候选 Manifest 已失效,请完成修订后重新生成", "候选已返回草稿"); + return; + } + if (event.target.closest("[data-release-approve]") || event.target.closest("[data-release-reject]")) { + if (release.status !== "PENDING_APPROVAL" || approval.status !== "PENDING_APPROVAL") return; + const approver = document.getElementById("releaseApprover")?.value; + const comment = document.getElementById("approvalComment")?.value.trim(); + const approved = Boolean(event.target.closest("[data-release-approve]")); + decideIndependentApproval({ + approval, + target: release, + approver, + comment, + approved, + approveStatus: "APPROVED", + rejectStatus: "REJECTED", + approveEvent: "候选版本独立审批通过", + rejectEvent: "候选版本独立审批驳回", + object: release.id, + evidence: ["审批意见", "审批人身份", "四眼规则校验"], + defaultApproveComment: "审批通过", + defaultRejectComment: "需修订后重提", + resultLabel: operationStatusLabel, + successMessage: (actor, passed) => `${actor} 已${passed ? "批准" : "驳回"} ${release.id}`, + successTitle: (passed) => (passed ? "独立审批通过" : "审批已驳回"), + }); + return; + } + if (event.target.closest("[data-release-publish]") && release.status === "APPROVED") { + if ( + approval.status !== "APPROVED" || + !isIndependentApproval(approval) || + !release.candidateManifest || + !release.manifestGeneratedAt + ) { + showToast("发布需要有效候选 Manifest 和已完成职责分离的独立审批", "发布前置校验失败"); + return; + } + const metadata = addOperationsAudit({ + type: "publish", + event: "候选版本发布为稳定版本", + object: `${release.id} · ${release.dataVersion}`, + result: "已发布", + evidence: [`独立审批单 ${approval.id}:APPROVED`, "候选 Manifest", "稳定别名切换记录"], + }); + migrateOperationsEntity(release, "PUBLISHED", metadata); + release.publishedAt = metadata.time; + release.publishedManifest = buildPackageManifest({ releaseStatus: "PUBLISHED", approvalStatus: "APPROVED" }); + release.publishedManifestGeneratedAt = release.publishedManifest.generated_at; + saveOperationsStore(); + downloadJson(`${release.packageId}-published-manifest.json`, release.publishedManifest); + state.operationsTab = "deliveries"; + renderOperations(); + renderAudit(); + showToast(`稳定别名已切换,发布 Manifest 引用 ${approval.id}:APPROVED;尚未向学校发送`, "候选版本已发布"); + return; + } + if (event.target.closest("[data-rollback-submit]") && release.status === "PUBLISHED") { + const rollbackApproval = currentRollbackApproval(); + const reason = document.getElementById("rollbackReason")?.value.trim(); + if (!reason) { + showToast("必须填写回滚原因与生产影响", "缺少回滚依据"); + return; + } + const metadata = addOperationsAudit({ + type: "publish", + event: "全局版本回滚提交独立审批", + object: `${release.id} → ${release.previousStableVersion}`, + result: "ROLLBACK_PENDING_APPROVAL", + evidence: ["回滚原因", "影响租户清单", "目标稳定版本"], + }); + rollbackApproval.reason = reason; + rollbackApproval.approver = null; + rollbackApproval.comment = ""; + rollbackApproval.decidedAt = null; + migrateOperationsEntity(rollbackApproval, "ROLLBACK_PENDING_APPROVAL", metadata); + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast("全局回滚申请已提交,申请人不能批准自己的回滚", "等待独立回滚审批"); + return; + } + if (event.target.closest("[data-rollback-approve]") || event.target.closest("[data-rollback-reject]")) { + const rollbackApproval = currentRollbackApproval(); + if (release.status !== "PUBLISHED" || rollbackApproval?.status !== "ROLLBACK_PENDING_APPROVAL") return; + const approver = document.getElementById("rollbackApprover")?.value; + const comment = document.getElementById("rollbackApprovalComment")?.value.trim(); + const approved = Boolean(event.target.closest("[data-rollback-approve]")); + decideIndependentApproval({ + approval: rollbackApproval, + approver, + comment, + approved, + approveStatus: "ROLLBACK_APPROVED", + rejectStatus: "ROLLBACK_REJECTED", + approveEvent: "全局版本回滚独立审批通过", + rejectEvent: "全局版本回滚独立审批驳回", + object: `${release.id} → ${release.previousStableVersion}`, + evidence: ["回滚审批意见", "审批人身份", "四眼规则校验", "影响租户清单"], + defaultApproveComment: "同意在受控窗口执行回滚", + defaultRejectComment: "回滚依据不足", + successMessage: (actor, passed) => `${actor} 已${passed ? "批准" : "驳回"}全局回滚`, + successTitle: (passed) => (passed ? "回滚审批通过" : "回滚审批驳回"), + }); + return; + } + if (event.target.closest("[data-release-rollback]") && release.status === "PUBLISHED") { + const rollbackApproval = currentRollbackApproval(); + if ( + rollbackApproval?.status !== "ROLLBACK_APPROVED" || + !isIndependentApproval(rollbackApproval) + ) { + showToast("全局版本回滚必须先完成职责分离的独立审批", "回滚执行被阻断"); + return; + } + const metadata = addOperationsAudit({ + type: "publish", + event: "发布版本全局回滚", + object: release.id, + result: "已回滚", + evidence: [`稳定别名恢复 ${release.previousStableVersion}`, `回滚审批 ${rollbackApproval.id}:${rollbackApproval.status}`, "影响范围锁"], + }); + migrateOperationsEntity(release, "ROLLED_BACK", metadata); + migrateOperationsEntity(rollbackApproval, "ROLLBACK_EXECUTED", metadata); + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast(`稳定别名已恢复为 ${release.previousStableVersion}`, "版本已回滚"); + } + }); + document.getElementById("startPendingDeliveries").addEventListener("click", () => { + if (currentRelease()?.status !== "PUBLISHED") { + showToast("只有已发布版本才能启动学校交付", "交付尚不可用"); + return; + } + const pending = operationsStore.deliveries.filter((delivery) => delivery.status === "PENDING"); + pending.forEach((delivery) => { + const metadata = addOperationsAudit({ + type: "publish", + event: "租户交付进入发送队列", + object: `${delivery.tenantId} · ${delivery.packageId}`, + actor: "delivery-orchestrator", + result: "SENDING", + evidence: ["租户范围校验", "包签名", "幂等键"], + }); + migrateOperationsEntity(delivery, "SENDING", metadata); + delivery.attempts += 1; + }); + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast(`${pending.length} 所待发送学校已进入原型队列,未发生真实网络发送`, "交付队列已启动"); + }); + document.getElementById("deliveryTable").addEventListener("click", (event) => { + const button = + event.target.closest("[data-delivery-delivered]") || + event.target.closest("[data-delivery-failed]") || + event.target.closest("[data-delivery-retry]") || + event.target.closest("[data-delivery-ack]") || + event.target.closest("[data-delivery-rollback]"); + if (!button) return; + const id = + button.dataset.deliveryDelivered || + button.dataset.deliveryFailed || + button.dataset.deliveryRetry || + button.dataset.deliveryAck || + button.dataset.deliveryRollback; + const delivery = operationsStore.deliveries.find((item) => item.id === id); + if (!delivery) return; + if (button.dataset.deliveryDelivered) { + const metadata = addOperationsAudit({ + type: "publish", + event: "租户交付包模拟送达", + object: delivery.tenantId, + actor: "delivery-orchestrator", + result: "DELIVERED", + evidence: ["传输完成标记", "包签名"], + }); + migrateOperationsEntity(delivery, "DELIVERED", metadata); + delivery.failureReason = ""; + } else if (button.dataset.deliveryFailed) { + const metadata = addOperationsAudit({ + type: "publish", + event: "租户交付失败隔离", + object: delivery.tenantId, + actor: "delivery-orchestrator", + result: "FAILED", + evidence: ["模拟超时日志", "租户隔离策略"], + }); + migrateOperationsEntity(delivery, "FAILED", metadata); + delivery.failureReason = "模拟租户端接收超时,其他学校未受影响"; + } else if (button.dataset.deliveryRetry) { + const metadata = addOperationsAudit({ + type: "publish", + event: "失败租户单独重试", + object: delivery.tenantId, + actor: OPERATIONS_ACTOR, + result: "RETRYING", + evidence: ["原包幂等键", "失败原因", "单租户重试指令"], + }); + migrateOperationsEntity(delivery, "RETRYING", metadata); + delivery.attempts += 1; + delivery.failureReason = ""; + } else if (button.dataset.deliveryAck) { + const countInput = document.getElementById(`receipt-count-${delivery.id}`); + const shaInput = document.getElementById(`receipt-sha-${delivery.id}`); + const receiptRecords = Number(countInput?.value); + const receiptSha = shaInput?.value.trim(); + if (receiptRecords !== delivery.expectedRecords || receiptSha !== delivery.expectedSha) { + showToast("记录数与 SHA-256 必须同时等于候选包期望值,当前回执未确认", "回执校验失败"); + return; + } + const metadata = addOperationsAudit({ + type: "publish", + event: "学校回执校验通过", + object: delivery.tenantId, + actor: "receipt-verifier", + result: "ACKNOWLEDGED", + evidence: [`记录数 ${receiptRecords}`, `SHA-256 ${receiptSha}`, "回执签名"], + }); + migrateOperationsEntity(delivery, "ACKNOWLEDGED", metadata); + delivery.receiptRecords = receiptRecords; + delivery.receiptSha = receiptSha; + } else if (button.dataset.deliveryRollback) { + const metadata = addOperationsAudit({ + type: "publish", + event: "单租户交付回滚", + object: `${delivery.tenantId} · ${delivery.dataVersion}`, + actor: OPERATIONS_ACTOR, + result: "ROLLED_BACK", + evidence: ["租户范围锁", `恢复 ${currentRelease().previousStableVersion}`, "回滚记录"], + }); + migrateOperationsEntity(delivery, "ROLLED_BACK", metadata); + } + saveOperationsStore(); + renderOperations(); + renderAudit(); + showToast(`${delivery.school}:${operationStatusLabel(delivery.status)}`, "学校交付状态已更新"); + }); +} + +function setupGlobalActions() { + document.querySelectorAll("[data-close-modal]").forEach((button) => button.addEventListener("click", () => closeModal(button.closest(".modal-backdrop")))); + document.querySelectorAll(".modal-backdrop").forEach((backdrop) => { + backdrop.addEventListener("click", (event) => { + if (event.target === backdrop) closeModal(backdrop); + }); + }); + document.getElementById("notificationButton").addEventListener("click", () => { + const openIssues = operationsStore.issues.filter((issue) => !["RESOLVED", "CLOSED"].includes(issue.status)); + const pendingApproval = operationsStore.approvals.find((approval) => ["PENDING_APPROVAL", "ROLLBACK_PENDING_APPROVAL"].includes(approval.status)); + const deliveryTodos = operationsStore.deliveries.filter((delivery) => ["PENDING", "SENDING", "FAILED", "RETRYING"].includes(delivery.status)); + openInfoModal( + "OPERATIONS NOTIFICATIONS", + "真实运营待办", + `
+ ${openIssues + .map( + (issue) => + ``, + ) + .join("")} + ${ + pendingApproval + ? `` + : "" + } + ${deliveryTodos.length ? `` : ""} + ${!openIssues.length && !pendingApproval && !deliveryTodos.length ? `当前没有运营待办问题、审批和交付均已闭环` : ""} +
`, + ); + }); + document.getElementById("operatorButton").addEventListener("click", () => { + openInfoModal( + "OPERATOR PROFILE", + "厂商数据运营管理员", + `
姓名陈致远角色数据运营管理员权限范围全国招聘数据域最近登录今天 08:12
可管理数据源、采集任务、标准契约、质量规则和数据交付;生产发布需要数据产品负责人复核。
`, + ); + }); + document.addEventListener("keydown", (event) => { + if (event.key !== "Escape") return; + if (document.getElementById("issueDrawer").classList.contains("open")) { + closeIssueDrawer(); + return; + } + if (document.getElementById("recordDrawer").classList.contains("open")) { + closeRecordDrawer(); + return; + } + if (document.getElementById("sourceDrawer").classList.contains("open")) { + closeSourceDrawer(); + return; + } + const modal = document.querySelector(".modal-backdrop.open"); + if (modal) { + closeModal(modal); + return; + } + document.body.classList.remove("sidebar-open"); + }); +} + +function setupOverviewActions() { + document.querySelector("[data-open-export]").addEventListener("click", exportDailyReport); +} + +function populateJobSources() { + document.getElementById("jobSource").innerHTML = sources.map((source) => ``).join(""); +} + +function init() { + renderOverviewSources(); + renderSources(); + renderCollectionJobs(); + populateRecordSources(); + renderRecords(); + renderContract(); + renderExchangeLogs(); + renderQuality(); + renderOperations(); + renderAudit(); + populateJobSources(); + setupNavigation(); + setupSourceRegistry(); + setupSourceDrawer(); + setupCollectionJobs(); + setupRecords(); + setupContracts(); + setupExchange(); + setupQuality(); + setupOperations(); + setupAudit(); + setupGlobalActions(); + setupOverviewActions(); +} + +document.addEventListener("DOMContentLoaded", init); diff --git a/admin-tools/demo/favicon.svg b/admin-tools/demo/favicon.svg new file mode 100644 index 0000000..53ef0dc --- /dev/null +++ b/admin-tools/demo/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/admin-tools/demo/index.html b/admin-tools/demo/index.html new file mode 100644 index 0000000..9ccfbe0 --- /dev/null +++ b/admin-tools/demo/index.html @@ -0,0 +1,675 @@ + + + + + + + 产教数据中台 · 厂商运营中心 + + + + +
+ + +
+
+ +
+ 全国招聘数据运营中心 + 运行总览 +
+ +
+ 生产环境 + + +
+
+ +
+
+
+
+
DATA OPERATIONS CONTROL PLANE
+

招聘数据生产运行总览

+

统一管理商业招聘平台、公共就业平台和校内业务系统,从采集到交付全链路可追溯。

+
+
+ + + +
+
+ +
+
+ NATIONAL DATA PIPELINE +

今日生产批次 EDU-JOB-20260823

+

9 个数据源进入调度,7 个已完成,2 个持续采集中;当前稳定版本不受运行中任务影响。

+
+ 运行中2 + 今日入湖190,420 + 隔离记录1,286 + 预计完成11:40 +
+
+
+ 94.7综合质量 + 候选发布受阻杭州人才网修复重放尚未验证 +
+
+ +
+
有效岗位总量12.84百万近90天去重信号↑ 8.6%
+
今日采集成功率98.7%1,428 / 1,447 分片SLA内
+
岗位归一覆盖96.4%国标 + 行业词典 V4.327项待审
+
数据交付租户36所旗舰版与区域项目全部有效
+
+ +
+
+
+
来源运行状态

核心数据源健康度

+ +
+
+
+ +
+
+
处理链路

今日数据流水线

+ 实时 +
+
+ 01源端采集190,420 条 + 02原始留存100% 哈希 + 03清洗归一96.4% 完成 + 04质量验收11:20 预计 + 05版本交付待审批 +
+
+ RAW-20260823-09 原始快照 + JOB-SIGNAL 3.0 目标契约 + SHA-256 全量校验 +
+
+ +
+
+
运营关注

待处理事项

+ 4 项 +
+
+ + + +
+
+
+
+ +
+
+
+
OPERATIONS RESOLUTION LOOP
+

运营问题、发布与学校交付

+

从告警确认、排障和质量复核,到独立审批、版本发布、逐学校回执与租户级回滚,全程保留状态与审计证据。

+
+
+ + +
+
+ +
+ + + +
+
+
+
ISSUE & WORK ORDER

问题处置队列

+ 加载中 +
+
+ + + +
问题与追踪级别 / SLA影响负责人状态最近动作操作
+
+
+
+ +
+
+
+ +
+
+
+
TENANT DELIVERY

逐学校交付与回执

+ +
+
静态原型只模拟并持久化交付状态,不会向学校网络、接口或业务系统真实发送数据。
+
+ + + +
学校 / 租户包与数据版本交付状态记录数回执SHA-256 回执最近动作操作
+
+
+
+
+ +
+
+
+
SOURCE REGISTRY
+

统一数据源注册中心

+

商业招聘平台、公共就业平台、活动聚合平台和校内系统使用同一套资产、版本和运行模型。

+
+
+ + +
+
+ +
+ 数据源总数97外部 · 2校内 + 正式运行81个降速保护 + 今日新增记录190,420有效率 98.1% + 稳定交付版本V2026.08.2336所学校引用 +
+ +
+
+
+ + + + +
+ +
+
+
当前展示 9 个数据源
+
+
+ +
+
+
+
COLLECTION ORCHESTRATION
+

采集任务编排中心

+

按来源、地域、行业和岗位族编排任务,支持分片、限速、失败隔离、断点续采和版本化原始留存。

+
+
+ + +
+
+ +
+
运行中364 个活跃分片
+
今日完成18平均耗时 42 分钟
+
自动保护1源端延迟触发降速
+
失败分片6已进入重试队列
+
+ +
+
+
+ + + + +
+ 调度器心跳:刚刚 · 队列延迟 18s +
+
+ + + +
任务与来源采集范围运行策略进度本批次数据状态操作
+
+
+
+ +
+
+
+
DATA RECORD EXPLORER
+

采集数据浏览与追溯

+

按数据层、来源、地区和关键词检索岗位明细,向下追溯源端记录、原始快照、采集任务与内容哈希。

+
+
+ + +
+
+ +
+ 稳定标准岗位12.84MJOB-SIGNAL V3.0 + 今日源端入湖190,4209个来源批次 + 今日标准入湖189,134已通过生产质量规则 + 隔离记录1,286未进入稳定版本 +
+ +
+
+ + + + +
+ +
+ + + +
+ +
+ 查询服务 + 当前绑定稳定版本 V2026.08.23 + 静态原型展示契约化结构样例;正式环境由数据查询服务分页返回已采集明细,并执行租户范围与字段权限控制。 +
+ +
+ +
+
+ +
+
+
+
DATA CONTRACT GOVERNANCE
+

产教数据标准与契约中心

+

第三方招聘数据和校内业务数据按版本化契约交付,字段、代码、质量、脱敏和变更策略一次定义、全链路执行。

+
+
+ + +
+
+ +
+ + + +
+
+
+ +
+
+
+
DATA EXCHANGE
+

数据导入与交付中心

+

支持标准文件导入、Schema 预检、字段映射、质量干跑和带清单、校验和、质量报告的版本化导出。

+
+
+ 下载导入样例 + +
+
+ +
+
+
标准导入

上传并校验数据文件

CSV / JSONL / XLSX / Parquet
+ +
+ + +
+
+ 等待文件尚未选择导入文件 + +
+
+ +
+
版本交付

构建数据交付包

可复核、可回滚
+
+ + + + +
+
+ ✓业务数据文件✓JSON Schema✓代码字典 + ✓质量报告✓血缘与来源清单✓SHA-256 校验和 +
+ +
+
+ +
+
交换记录

最近导入与交付任务

+
+ + + +
追踪编号类型对象数据版本记录数执行人结果时间
+
+
+
+ +
+
+
+
QUALITY & NORMALIZATION
+

数据质量与岗位归一

+

执行结构、完整性、唯一性、时效性和业务规则校验,将多来源岗位映射到统一岗位与技能体系。

+
+
+ + +
+
+ +
+
+ 94.7综合质量 +
生产发布阈值 ≥ 90当前批次仍需修复重放复核质量分达标不等于门禁通过,稳定版本继续保持不变
+
+
+ 完整性97.8% + 唯一性99.6% + 时效性93.1% + 岗位归一96.4% +
+
+ +
+
+
规则执行

当前质量规则组

32条启用
+
+
+
+
人工复核

岗位归一待审队列

27项
+
+
+
+
+ +
+
+
+
AUDIT & DELIVERY
+

全链路审计与生产交付

+

记录来源、采集任务、代码版本、原始快照、处理规则、发布审批和租户交付,实现问题可定位、版本可回滚。

+
+
+ + +
+
+ +
+
今日审计事件2,846全部已签名
+
数据版本128保留 36 个月
+
可追踪任务100%原始快照已绑定
+
交付租户36范围策略有效
+
+ +
+
+
+ + + + + + +
+ 审计存储 WORM · 每日校验 +
+
+ + + +
时间与追踪编号事件对象操作者/服务结果证据
+
+
+
+
+
+
+ + +
+ + + + + + + + + + + + + + + + diff --git a/admin-tools/demo/preview-admin-boss-workbench.png b/admin-tools/demo/preview-admin-boss-workbench.png new file mode 100644 index 0000000..3d4786e Binary files /dev/null and b/admin-tools/demo/preview-admin-boss-workbench.png differ diff --git a/admin-tools/demo/preview-admin-collectors.png b/admin-tools/demo/preview-admin-collectors.png new file mode 100644 index 0000000..6df584a Binary files /dev/null and b/admin-tools/demo/preview-admin-collectors.png differ diff --git a/admin-tools/demo/preview-admin-contracts.png b/admin-tools/demo/preview-admin-contracts.png new file mode 100644 index 0000000..1d877cd Binary files /dev/null and b/admin-tools/demo/preview-admin-contracts.png differ diff --git a/admin-tools/demo/preview-admin-exchange.png b/admin-tools/demo/preview-admin-exchange.png new file mode 100644 index 0000000..9a5cb75 Binary files /dev/null and b/admin-tools/demo/preview-admin-exchange.png differ diff --git a/admin-tools/demo/preview-admin-mobile.png b/admin-tools/demo/preview-admin-mobile.png new file mode 100644 index 0000000..4798f52 Binary files /dev/null and b/admin-tools/demo/preview-admin-mobile.png differ diff --git a/admin-tools/demo/preview-admin-operations-mobile.png b/admin-tools/demo/preview-admin-operations-mobile.png new file mode 100644 index 0000000..f4c175e Binary files /dev/null and b/admin-tools/demo/preview-admin-operations-mobile.png differ diff --git a/admin-tools/demo/preview-admin-operations.png b/admin-tools/demo/preview-admin-operations.png new file mode 100644 index 0000000..4d85e31 Binary files /dev/null and b/admin-tools/demo/preview-admin-operations.png differ diff --git a/admin-tools/demo/preview-admin-overview.png b/admin-tools/demo/preview-admin-overview.png new file mode 100644 index 0000000..a10c4ad Binary files /dev/null and b/admin-tools/demo/preview-admin-overview.png differ diff --git a/admin-tools/demo/preview-admin-record-detail.png b/admin-tools/demo/preview-admin-record-detail.png new file mode 100644 index 0000000..5332d70 Binary files /dev/null and b/admin-tools/demo/preview-admin-record-detail.png differ diff --git a/admin-tools/demo/preview-admin-records-mobile.png b/admin-tools/demo/preview-admin-records-mobile.png new file mode 100644 index 0000000..4dbb976 Binary files /dev/null and b/admin-tools/demo/preview-admin-records-mobile.png differ diff --git a/admin-tools/demo/preview-admin-records.png b/admin-tools/demo/preview-admin-records.png new file mode 100644 index 0000000..291e145 Binary files /dev/null and b/admin-tools/demo/preview-admin-records.png differ diff --git a/admin-tools/demo/preview-admin-sources.png b/admin-tools/demo/preview-admin-sources.png new file mode 100644 index 0000000..bd8e1dc Binary files /dev/null and b/admin-tools/demo/preview-admin-sources.png differ diff --git a/admin-tools/demo/samples/external-job-sample.csv b/admin-tools/demo/samples/external-job-sample.csv new file mode 100644 index 0000000..fc3538d --- /dev/null +++ b/admin-tools/demo/samples/external-job-sample.csv @@ -0,0 +1,4 @@ +record_id,source_platform,source_record_id,source_url,collector_task_id,collector_version,raw_snapshot_id,collected_at,first_seen_at,last_seen_at,published_at,status,job_title_raw,job_title_normalized,job_code,job_description,enterprise_name,enterprise_id,region_code,workplace,employment_type,recruitment_count,education_level,experience_min_years,salary_min,salary_max,salary_currency,salary_period,skills,source_payload_hash,content_hash,parsing_version,normalized_at,data_version +e5a87030-3c5f-4d74-a3ca-89427e2f75a1,BOSS,BOSS-20260823-884201,https://www.bosszhipin.com/job_detail/sample-884201.html,JOB-20260823-1042,BOSS-Collector-4.6.2,RAW-BOSS-20260823-000884,2026-08-23T10:42:18+08:00,2026-08-21T09:10:00+08:00,2026-08-23T10:42:18+08:00,2026-08-21T08:56:00+08:00,active,云原生开发工程师,云计算工程技术人员,IT.CLOUD.DEV,"负责容器平台应用开发、持续集成和服务可观测性建设。",杭州示例数字科技有限公司,ENT_7f40a90d45c72b18,330100,杭州市滨江区,full_time,6,bachelor,1,12000,18000,CNY,month,"Docker|Kubernetes|Java|CI/CD",4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32,96c2be742dc43f8e7ee526db6358030873406c450f15e67225c605dc39b431a8,PARSER-BOSS-4.6.2,2026-08-23T10:45:00+08:00,V2026.08.23 +57df68fe-2454-44d2-9f3d-20e91ac0912a,ZHAOPIN,ZL-20260823-620311,https://www.zhaopin.com/jobdetail/sample-620311.htm,JOB-20260823-1038,ZHAOPIN-Collector-3.8.1,RAW-ZHAOPIN-20260823-000620,2026-08-23T10:38:06+08:00,2026-08-22T14:20:00+08:00,2026-08-23T10:38:06+08:00,2026-08-22T14:05:00+08:00,active,工业视觉应用工程师,人工智能工程技术人员,AI.VISION.APP,"负责机器视觉方案部署、相机标定、缺陷检测模型优化和产线集成。",浙江示例智能装备股份有限公司,ENT_143c8d80f501e6a9,330200,宁波市鄞州区,full_time,4,associate,2,10000,16000,CNY,month,"Python|OpenCV|机器视觉|PLC",c2d8f733e6711219823110d7d35fdc5535f133ed60f60950f9dc78a228cb402d,66e102b99bf056868670ac971011740c6f66f62b86ea43cc66326ed9a0a5807e,PARSER-ZHAOPIN-3.8.1,2026-08-23T10:41:00+08:00,V2026.08.23 +62eaa80d-0b30-462b-8eca-c6c9bb5e8446,BRZP,BRZP-20260823-110028,https://brzp.chinasme.cn/brzp/job/sample-110028,JOB-20260823-0955,BRZP-Collector-2.1.0,RAW-BRZP-20260823-000110,2026-08-23T09:55:12+08:00,2026-08-23T01:42:00+08:00,2026-08-23T09:55:12+08:00,2026-08-22T18:00:00+08:00,active,跨境电商运营实习生,电子商务师,EC.CROSSBORDER.OPS,"协助店铺运营、海外内容制作、经营数据分析与合规资料整理。",浙江示例跨境服务有限公司,ENT_82b038ab219c4e80,330400,嘉兴市南湖区,internship,12,associate,0,3500,5000,CNY,month,"跨境电商|内容运营|数据分析|英语",a831bd0d4e29cab1e650f36a4fc9c5d5cc8053f560b5d3dc7aac62b384b47e11,310ae74d6d695235229da958f8fb8e59af6ea4bebef659dfdc1a6bc0764f3f30,PARSER-BRZP-2.1.0,2026-08-23T10:00:00+08:00,V2026.08.23 diff --git a/admin-tools/demo/schemas/README.md b/admin-tools/demo/schemas/README.md new file mode 100644 index 0000000..3fc5a76 --- /dev/null +++ b/admin-tools/demo/schemas/README.md @@ -0,0 +1,20 @@ +# 数据契约目录 + +所有契约使用 JSON Schema Draft 2020-12。 + +## 发布要求 + +1. 契约名称和版本必须唯一; +2. 兼容变更提升次版本,修订说明或约束修复提升补丁版本; +3. 删除字段、改变类型或收紧必填要求属于破坏性变更,必须提升主版本; +4. 发布前执行历史样本回放、来源映射测试和下游影响分析; +5. 交付包必须绑定精确契约版本,不允许只引用“最新版本”; +6. Schema、样例、字段说明、代码字典和变更日志作为同一发布物。 + +## 当前契约 + +| 契约 | 版本 | 适用范围 | +|---|---|---| +| `JOB-SIGNAL` | 3.0.0 | 商业招聘平台、公共就业平台、活动聚合平台 | +| `SCHOOL-EMPLOYMENT` | 2.2.0 | 学校就业管理系统、数据库视图、API和标准文件 | +| `PACKAGE-MANIFEST` | 1.2.0 | 导入、导出、租户交付和归档;新增可选发布候选编号与状态 | diff --git a/admin-tools/demo/schemas/external-job-source.schema.json b/admin-tools/demo/schemas/external-job-source.schema.json new file mode 100644 index 0000000..ea8d4c4 --- /dev/null +++ b/admin-tools/demo/schemas/external-job-source.schema.json @@ -0,0 +1,266 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.edu-industry.cn/job-signal/3.0.0/schema.json", + "title": "JOB-SIGNAL V3.0 外部招聘岗位信号", + "description": "商业招聘平台、公共就业平台与招聘活动平台统一岗位信号契约。", + "type": "object", + "additionalProperties": false, + "required": [ + "record_id", + "source_platform", + "source_record_id", + "source_url", + "collector_task_id", + "collector_version", + "raw_snapshot_id", + "collected_at", + "first_seen_at", + "last_seen_at", + "status", + "job_title_raw", + "job_description", + "enterprise_name", + "region_code", + "employment_type", + "source_payload_hash", + "content_hash", + "data_version" + ], + "properties": { + "record_id": { + "type": "string", + "format": "uuid", + "description": "平台生成的全局唯一记录标识。" + }, + "source_platform": { + "type": "string", + "pattern": "^[A-Z][A-Z0-9_]{1,31}$", + "description": "来源平台代码,例如 BOSS、ZHAOPIN、BRZP、NCSS、MOHRSS。" + }, + "source_record_id": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "来源平台内的记录标识,与 source_platform 组成幂等键。" + }, + "source_url": { + "type": "string", + "format": "uri", + "maxLength": 2048, + "description": "可回溯的来源页面或接口定位。" + }, + "collector_task_id": { + "type": "string", + "pattern": "^JOB-[A-Za-z0-9-]{8,64}$", + "description": "生产采集任务追踪编号。" + }, + "collector_version": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "采集器名称、语义版本与代码提交摘要。" + }, + "raw_snapshot_id": { + "type": "string", + "pattern": "^RAW-[A-Za-z0-9-]{8,96}$", + "description": "原始响应或页面快照编号。" + }, + "collected_at": { + "type": "string", + "format": "date-time", + "description": "平台实际采集时间,必须包含时区。" + }, + "first_seen_at": { + "type": "string", + "format": "date-time", + "description": "平台首次发现该岗位的时间。" + }, + "last_seen_at": { + "type": "string", + "format": "date-time", + "description": "平台最近一次确认该岗位仍存在的时间。" + }, + "published_at": { + "type": ["string", "null"], + "format": "date-time", + "description": "来源平台显示的岗位发布时间。" + }, + "status": { + "type": "string", + "enum": ["active", "inactive", "expired", "unknown"], + "description": "岗位在当前数据版本中的状态。" + }, + "job_title_raw": { + "type": "string", + "minLength": 1, + "maxLength": 200, + "description": "来源岗位名称原文。" + }, + "job_title_normalized": { + "type": ["string", "null"], + "maxLength": 200, + "description": "映射到统一岗位词典后的标准名称。" + }, + "job_code": { + "type": ["string", "null"], + "pattern": "^[A-Z0-9.-]{2,32}$", + "description": "统一岗位分类代码。" + }, + "job_description": { + "type": "string", + "minLength": 1, + "maxLength": 30000, + "description": "去除展示标记与联系方式后的岗位职责和要求文本。" + }, + "enterprise_name": { + "type": "string", + "minLength": 1, + "maxLength": 300, + "description": "来源企业名称原文。" + }, + "enterprise_id": { + "type": ["string", "null"], + "maxLength": 128, + "description": "平台企业归一标识。" + }, + "enterprise_credit_code": { + "type": ["string", "null"], + "pattern": "^[0-9A-Z]{18}$", + "description": "可公开确认时使用的统一社会信用代码。" + }, + "enterprise_industry_code": { + "type": ["string", "null"], + "maxLength": 32, + "description": "企业所属行业代码。" + }, + "enterprise_scale": { + "type": ["string", "null"], + "enum": ["micro", "small", "medium", "large", "unknown", null], + "description": "统一企业规模分组。" + }, + "region_code": { + "type": "string", + "pattern": "^[0-9]{6}$", + "description": "GB/T 2260 六位行政区划代码。" + }, + "workplace": { + "type": ["string", "null"], + "maxLength": 500, + "description": "来源工作地点文本。" + }, + "employment_type": { + "type": "string", + "enum": ["full_time", "internship", "part_time", "contract", "campus", "other"], + "description": "统一用工或招聘类型。" + }, + "recruitment_count": { + "type": ["integer", "null"], + "minimum": 0, + "maximum": 1000000, + "description": "明确披露时记录计划招聘人数。" + }, + "education_level": { + "type": ["string", "null"], + "enum": ["none", "secondary", "vocational", "associate", "bachelor", "master", "doctor", "unknown", null], + "description": "最低学历要求。" + }, + "experience_min_years": { + "type": ["number", "null"], + "minimum": 0, + "maximum": 60, + "description": "最低工作经验年限。" + }, + "salary_min": { + "type": ["number", "null"], + "minimum": 0, + "maximum": 10000000, + "description": "统一折算后的税前月薪下限,单位为 salary_currency。" + }, + "salary_max": { + "type": ["number", "null"], + "minimum": 0, + "maximum": 10000000, + "description": "统一折算后的税前月薪上限。" + }, + "salary_currency": { + "type": ["string", "null"], + "pattern": "^[A-Z]{3}$", + "description": "ISO 4217 币种代码,境内岗位通常为 CNY。" + }, + "salary_period": { + "type": ["string", "null"], + "enum": ["month", "year", "day", "hour", "negotiable", "unknown", null], + "description": "来源薪资周期,统一月薪字段与原始周期同时保留。" + }, + "benefits": { + "type": "array", + "maxItems": 100, + "items": { + "type": "string", + "maxLength": 100 + }, + "uniqueItems": true, + "description": "福利标签。" + }, + "skills": { + "type": "array", + "maxItems": 200, + "items": { + "type": "string", + "maxLength": 100 + }, + "uniqueItems": true, + "description": "基于技能词典提取并归一的技能标签。" + }, + "keywords": { + "type": "array", + "maxItems": 200, + "items": { + "type": "string", + "maxLength": 100 + }, + "uniqueItems": true, + "description": "用于检索的业务关键词。" + }, + "source_payload_hash": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "description": "原始响应载荷 SHA-256。" + }, + "content_hash": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "description": "规范化业务内容 SHA-256,用于内容去重。" + }, + "parsing_version": { + "type": ["string", "null"], + "maxLength": 128, + "description": "解析规则版本。" + }, + "normalized_at": { + "type": ["string", "null"], + "format": "date-time", + "description": "岗位和技能归一完成时间。" + }, + "data_version": { + "type": "string", + "pattern": "^V[0-9]{4}\\.[0-9]{2}\\.[0-9]{2}(?:\\.[0-9]+)?$", + "description": "进入分析层的数据版本。" + } + }, + "allOf": [ + { + "if": { + "required": ["salary_min", "salary_max"] + }, + "then": { + "properties": { + "salary_max": { + "type": "number", + "minimum": 0 + } + } + } + } + ] +} diff --git a/admin-tools/demo/schemas/package-manifest.schema.json b/admin-tools/demo/schemas/package-manifest.schema.json new file mode 100644 index 0000000..6c1c001 --- /dev/null +++ b/admin-tools/demo/schemas/package-manifest.schema.json @@ -0,0 +1,185 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.edu-industry.cn/package-manifest/1.2.0/schema.json", + "title": "PACKAGE-MANIFEST V1.2 数据交付包清单", + "description": "数据导入、导出和租户交付使用的版本、范围、文件、质量与血缘清单。", + "type": "object", + "additionalProperties": false, + "required": [ + "manifest_version", + "package_id", + "data_product", + "data_version", + "contract_name", + "contract_version", + "data_as_of", + "tenant_scope", + "record_count", + "quality_score", + "lineage_snapshot", + "files", + "generated_at", + "generated_by" + ], + "properties": { + "manifest_version": { + "type": "string", + "const": "1.2.0" + }, + "package_id": { + "type": "string", + "pattern": "^EDU-PKG-[0-9]{8}-[A-Z0-9]{2,24}$", + "description": "数据交付包唯一编号。" + }, + "release_id": { + "type": "string", + "pattern": "^REL-[0-9]{8}-[A-Z0-9-]{2,32}$", + "description": "生成此 Manifest 的发布候选编号。" + }, + "release_status": { + "type": "string", + "enum": ["DRAFT", "PENDING_APPROVAL", "APPROVED", "REJECTED", "PUBLISHED", "ROLLED_BACK"], + "description": "Manifest 生成时的候选或发布状态。" + }, + "data_product": { + "type": "string", + "minLength": 1, + "maxLength": 200, + "description": "平台数据产品名称或代码。" + }, + "data_version": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "业务数据版本。" + }, + "contract_name": { + "type": "string", + "pattern": "^[A-Z][A-Z0-9-]{2,63}$", + "description": "绑定的数据契约名称。" + }, + "contract_version": { + "type": "string", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$", + "description": "精确的数据契约版本。" + }, + "data_as_of": { + "type": "string", + "format": "date", + "description": "交付数据业务截止日期。" + }, + "tenant_scope": { + "type": "array", + "minItems": 1, + "maxItems": 10000, + "uniqueItems": true, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 128 + }, + "description": "允许接收此交付包的租户或数据范围代码。" + }, + "output_format": { + "type": ["string", "null"], + "enum": ["parquet", "csv_utf8", "jsonl", "xlsx", null], + "description": "主数据文件格式。" + }, + "record_count": { + "type": "integer", + "minimum": 0, + "description": "有效业务记录总数。" + }, + "quality_score": { + "type": "number", + "minimum": 0, + "maximum": 100, + "description": "与质量报告一致的综合质量评分。" + }, + "quality_report_path": { + "type": ["string", "null"], + "maxLength": 1024, + "description": "质量报告在交付包中的相对路径。" + }, + "lineage_snapshot": { + "type": "string", + "pattern": "^LINEAGE-[A-Z0-9-]{8,96}$", + "description": "数据血缘快照编号。" + }, + "previous_stable_version": { + "type": ["string", "null"], + "maxLength": 128, + "description": "上一稳定版本,用于回滚和版本对比。" + }, + "files": { + "type": "array", + "minItems": 1, + "maxItems": 10000, + "items": { + "$ref": "#/$defs/file" + }, + "description": "交付包内全部文件和校验信息。" + }, + "generated_at": { + "type": "string", + "format": "date-time", + "description": "交付包生成时间。" + }, + "generated_by": { + "type": "string", + "minLength": 1, + "maxLength": 128, + "description": "生成任务、服务账号或操作人。" + }, + "approval_reference": { + "type": ["string", "null"], + "maxLength": 256, + "description": "生产发布审批记录编号。" + }, + "notes": { + "type": ["string", "null"], + "maxLength": 4000, + "description": "交付说明、限制和已知问题。" + } + }, + "$defs": { + "file": { + "type": "object", + "additionalProperties": false, + "required": ["path", "media_type", "bytes", "sha256"], + "properties": { + "path": { + "type": "string", + "pattern": "^(?!/)(?!.*\\.\\.).+$", + "maxLength": 1024, + "description": "包内相对路径,不允许绝对路径和父目录穿越。" + }, + "media_type": { + "type": "string", + "maxLength": 128, + "description": "IANA 媒体类型。" + }, + "bytes": { + "type": "integer", + "minimum": 0, + "description": "文件字节数。" + }, + "sha256": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "description": "文件 SHA-256 完整值。" + }, + "record_count": { + "type": ["integer", "null"], + "minimum": 0, + "description": "数据文件的记录数。" + }, + "compression": { + "type": ["string", "null"], + "enum": ["none", "gzip", "zstd", "zip", null], + "description": "文件压缩方式。" + } + } + } + } +} diff --git a/admin-tools/demo/schemas/school-employment.schema.json b/admin-tools/demo/schemas/school-employment.schema.json new file mode 100644 index 0000000..23f58b1 --- /dev/null +++ b/admin-tools/demo/schemas/school-employment.schema.json @@ -0,0 +1,228 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.edu-industry.cn/school-employment/2.2.0/schema.json", + "title": "SCHOOL-EMPLOYMENT V2.2 校内就业事实", + "description": "职业院校毕业生就业事实统一契约,采用租户隔离和身份最小化设计。", + "type": "object", + "additionalProperties": false, + "required": [ + "tenant_id", + "record_id", + "student_token", + "cohort", + "college_code", + "program_code", + "employment_status", + "destination_type", + "confirmed_at", + "confirmation_role", + "source_system", + "source_record_id", + "created_at", + "updated_at", + "data_version", + "content_hash" + ], + "properties": { + "tenant_id": { + "type": "string", + "pattern": "^TENANT-[A-Z0-9-]{4,64}$", + "description": "学校租户标识,所有存储、任务和查询必须同时校验。" + }, + "record_id": { + "type": "string", + "format": "uuid", + "description": "平台全局唯一记录标识。" + }, + "student_token": { + "type": "string", + "pattern": "^STU_[A-Za-z0-9_-]{32,128}$", + "description": "学校侧生成的学生不可逆令牌,禁止传输姓名、身份证和明文学号。" + }, + "cohort": { + "type": "integer", + "minimum": 2000, + "maximum": 2100, + "description": "毕业届次。" + }, + "college_code": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "学校内部学院代码。" + }, + "program_code": { + "type": "string", + "pattern": "^[0-9A-Z]{4,12}$", + "description": "教育部职业教育专业目录代码。" + }, + "class_code": { + "type": ["string", "null"], + "maxLength": 64, + "description": "学校内部教学班代码。" + }, + "employment_status": { + "type": "string", + "enum": [ + "employed", + "self_employed", + "further_study", + "military", + "flexible", + "unemployed", + "pending_confirmation" + ], + "description": "统一就业状态。" + }, + "destination_type": { + "type": "string", + "enum": [ + "enterprise", + "public_institution", + "government", + "further_study", + "entrepreneurship", + "military", + "other" + ], + "description": "毕业去向类型。" + }, + "job_title": { + "type": ["string", "null"], + "maxLength": 200, + "description": "就业岗位业务原文。" + }, + "job_code": { + "type": ["string", "null"], + "maxLength": 32, + "description": "映射到统一岗位词典后的岗位代码。" + }, + "enterprise_token": { + "type": ["string", "null"], + "pattern": "^ENT_[A-Za-z0-9_-]{24,128}$", + "description": "企业统一标识令牌。" + }, + "enterprise_name": { + "type": ["string", "null"], + "maxLength": 300, + "description": "用于业务核验的企业名称;导出时按数据范围策略处理。" + }, + "enterprise_industry_code": { + "type": ["string", "null"], + "maxLength": 32, + "description": "企业行业代码。" + }, + "region_code": { + "type": ["string", "null"], + "pattern": "^[0-9]{6}$", + "description": "就业地区 GB/T 2260 六位代码。" + }, + "salary_monthly": { + "type": ["number", "null"], + "minimum": 0, + "maximum": 10000000, + "description": "确认后的税前月薪,单位元。" + }, + "salary_confirmed": { + "type": ["boolean", "null"], + "description": "薪资是否经过业务确认。" + }, + "job_relevance": { + "type": ["string", "null"], + "enum": ["high", "medium", "low", "unconfirmed", null], + "description": "就业岗位与专业培养方向相关度。" + }, + "employment_start_date": { + "type": ["string", "null"], + "format": "date", + "description": "就业开始日期。" + }, + "contract_signed": { + "type": ["boolean", "null"], + "description": "是否签署就业协议或劳动合同。" + }, + "evidence_type": { + "type": ["string", "null"], + "enum": ["contract", "offer", "registration", "enterprise_confirmation", "student_confirmation", "other", null], + "description": "就业确认材料类型,不在平台保存原始敏感附件。" + }, + "evidence_reference": { + "type": ["string", "null"], + "maxLength": 256, + "description": "学校系统内的材料引用编号。" + }, + "confirmed_at": { + "type": "string", + "format": "date-time", + "description": "业务确认时间。" + }, + "confirmation_role": { + "type": "string", + "enum": ["employment_office", "college", "student", "enterprise", "system"], + "description": "执行确认的业务角色。" + }, + "source_system": { + "type": "string", + "maxLength": 128, + "description": "学校来源系统代码。" + }, + "source_record_id": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "校内来源系统记录标识。" + }, + "source_updated_at": { + "type": ["string", "null"], + "format": "date-time", + "description": "校内来源系统业务更新时间,建议作为增量水位。" + }, + "created_at": { + "type": "string", + "format": "date-time", + "description": "平台记录创建时间。" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "description": "平台记录更新时间。" + }, + "data_version": { + "type": "string", + "pattern": "^SCH-EMP-[0-9]{8}(?:-[0-9]{2})?$", + "description": "校内就业数据版本。" + }, + "is_deleted": { + "type": "boolean", + "default": false, + "description": "版本化软删除标识。" + }, + "content_hash": { + "type": "string", + "pattern": "^[a-f0-9]{64}$", + "description": "去除非业务差异后的记录内容 SHA-256。" + } + }, + "allOf": [ + { + "if": { + "properties": { + "destination_type": { + "const": "enterprise" + } + }, + "required": ["destination_type"] + }, + "then": { + "anyOf": [ + { + "required": ["enterprise_token"] + }, + { + "required": ["enterprise_name"] + } + ] + } + } + ] +} diff --git a/admin-tools/demo/styles.css b/admin-tools/demo/styles.css new file mode 100644 index 0000000..649378e --- /dev/null +++ b/admin-tools/demo/styles.css @@ -0,0 +1,3901 @@ +:root { + --ink: #14241e; + --ink-soft: #33463e; + --muted: #718078; + --line: #dfe5df; + --line-soft: #ebefeb; + --surface: #ffffff; + --canvas: #f4f7f3; + --green: #176b4f; + --green-2: #238765; + --green-dark: #102f26; + --green-soft: #e8f4ee; + --lime: #c8ec73; + --lime-soft: #f2f9dc; + --blue: #4d7fa8; + --blue-soft: #eaf2f8; + --amber: #d89527; + --amber-soft: #fff4dd; + --red: #c65a50; + --red-soft: #fff0ed; + --shadow: 0 12px 34px rgba(15, 45, 34, 0.09); + --shadow-high: 0 24px 70px rgba(8, 35, 25, 0.2); + --radius: 16px; + --sidebar: 254px; + color-scheme: light; + font-family: + Inter, "SF Pro Display", "PingFang SC", "Microsoft YaHei", + "Noto Sans CJK SC", sans-serif; +} + +* { + box-sizing: border-box; +} + +html { + min-width: 320px; + background: var(--canvas); + scroll-behavior: smooth; +} + +body { + min-height: 100vh; + margin: 0; + color: var(--ink); + background: + radial-gradient(circle at 84% 0%, rgba(200, 236, 115, 0.08), transparent 24%), + var(--canvas); + font-size: 14px; +} + +button, +input, +select, +textarea { + color: inherit; + font: inherit; +} + +button, +a { + -webkit-tap-highlight-color: transparent; +} + +button { + padding: 0; + background: none; + border: 0; + cursor: pointer; +} + +a { + color: inherit; + text-decoration: none; +} + +svg { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 1.8; +} + +small, +button, +input, +select, +textarea, +th, +td { + font-size: 13px; +} + +input, +select, +textarea { + outline: none; +} + +input:focus, +select:focus, +textarea:focus { + border-color: #8bc6aa !important; + box-shadow: 0 0 0 3px rgba(35, 135, 101, 0.1); +} + +[hidden] { + display: none !important; +} + +.app-shell { + min-height: 100vh; +} + +.sidebar { + position: fixed; + z-index: 40; + top: 0; + bottom: 0; + left: 0; + display: flex; + width: var(--sidebar); + padding: 22px 15px 16px; + color: #dce9e3; + background: + radial-gradient(circle at 0 100%, rgba(200, 236, 115, 0.08), transparent 24%), + linear-gradient(180deg, #123d31, #0d2d25); + flex-direction: column; + overflow-y: auto; +} + +.brand, +.brand > span:last-child { + display: flex; + align-items: center; +} + +.brand { + gap: 12px; + padding: 0 9px; +} + +.brand > span:last-child { + align-items: flex-start; + flex-direction: column; +} + +.brand strong { + color: white; + font-size: 18px; +} + +.brand small { + margin-top: 4px; + color: #829f93; + font-size: 13px; + letter-spacing: 0.12em; +} + +.brand-mark { + position: relative; + width: 38px; + height: 38px; + flex: 0 0 auto; +} + +.brand-mark i { + position: absolute; + display: block; + width: 24px; + height: 9px; + background: var(--lime); + border-radius: 3px 9px 3px 9px; + transform: skewX(-12deg); +} + +.brand-mark i:nth-child(1) { + top: 3px; +} + +.brand-mark i:nth-child(2) { + top: 15px; + left: 7px; + opacity: 0.75; +} + +.brand-mark i:nth-child(3) { + top: 27px; + left: 14px; + opacity: 0.5; +} + +.main-nav { + display: flex; + gap: 4px; + margin-top: 30px; + flex-direction: column; +} + +.nav-label { + margin: 0 12px 7px; + color: #729087; + font-size: 13px; + font-weight: 700; +} + +.nav-item { + position: relative; + display: flex; + min-height: 45px; + align-items: center; + gap: 11px; + padding: 0 12px; + color: #abc0b8; + border-radius: 10px; + font-size: 14px; + text-align: left; +} + +.nav-item::before { + position: absolute; + top: 10px; + bottom: 10px; + left: -15px; + width: 4px; + background: transparent; + border-radius: 0 4px 4px 0; + content: ""; +} + +.nav-item:hover { + color: white; + background: rgba(255, 255, 255, 0.045); +} + +.nav-item.active { + color: white; + background: rgba(200, 236, 115, 0.12); + font-weight: 700; +} + +.nav-item.active::before { + background: var(--lime); +} + +.nav-item svg { + width: 18px; + height: 18px; + flex: 0 0 auto; +} + +.nav-item > span { + min-width: 0; + flex: 1; +} + +.nav-item em { + display: inline-grid; + min-width: 23px; + height: 23px; + place-items: center; + padding: 0 6px; + color: #bce27c; + background: rgba(200, 236, 115, 0.1); + border-radius: 7px; + font-size: 13px; + font-style: normal; +} + +.nav-item em.warning { + color: #ffd17e; + background: rgba(216, 149, 39, 0.15); +} + +.nav-live { + width: 8px; + height: 8px; + flex: 0 0 auto; + background: var(--lime); + border-radius: 50%; + box-shadow: 0 0 0 4px rgba(200, 236, 115, 0.11); +} + +.sidebar-runtime { + margin-top: auto; + padding: 15px 12px; + color: #819d92; + background: rgba(255, 255, 255, 0.035); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 11px; +} + +.sidebar-runtime span, +.sidebar-runtime strong, +.sidebar-runtime small { + display: block; +} + +.sidebar-runtime span { + color: #afd0bf; + font-size: 13px; +} + +.sidebar-runtime span i { + display: inline-block; + width: 8px; + height: 8px; + margin-right: 7px; + background: #63d49a; + border-radius: 50%; + box-shadow: 0 0 0 4px rgba(99, 212, 154, 0.1); +} + +.sidebar-runtime strong { + margin-top: 9px; + color: white; + font-size: 14px; +} + +.sidebar-runtime small { + margin-top: 4px; + line-height: 1.5; +} + +.workspace { + min-width: 0; + margin-left: var(--sidebar); +} + +.topbar { + position: sticky; + z-index: 30; + top: 0; + display: flex; + height: 76px; + align-items: center; + gap: 22px; + padding: 0 30px; + background: rgba(250, 252, 249, 0.92); + border-bottom: 1px solid var(--line); + backdrop-filter: blur(14px); +} + +.topbar-context { + display: flex; + min-width: 160px; + flex-direction: column; +} + +.topbar-context small { + color: var(--muted); +} + +.topbar-context strong { + margin-top: 3px; + font-size: 15px; +} + +.mobile-menu { + display: none !important; +} + +.icon-button { + position: relative; + display: inline-grid; + width: 40px; + height: 40px; + flex: 0 0 auto; + place-items: center; + color: var(--muted); + background: white; + border: 1px solid var(--line); + border-radius: 10px; +} + +.icon-button svg { + width: 18px; + height: 18px; +} + +.global-search, +.inline-search { + display: flex; + min-width: 0; + align-items: center; + gap: 8px; + background: white; + border: 1px solid var(--line); + border-radius: 10px; +} + +.global-search { + width: min(440px, 35vw); + margin-left: auto; + padding: 0 12px; +} + +.global-search svg, +.inline-search svg { + width: 17px; + height: 17px; + flex: 0 0 auto; + color: #829088; +} + +.global-search input, +.inline-search input { + width: 100%; + height: 40px; + background: transparent; + border: 0; +} + +.topbar-actions { + display: flex; + align-items: center; + gap: 9px; +} + +.environment-chip { + display: inline-flex; + min-height: 38px; + align-items: center; + gap: 7px; + padding: 0 11px; + color: var(--green); + background: var(--green-soft); + border: 1px solid #d5e8dc; + border-radius: 9px; + font-size: 13px; + font-weight: 700; +} + +.environment-chip i { + width: 8px; + height: 8px; + background: var(--green-2); + border-radius: 50%; +} + +#notificationButton b { + position: absolute; + top: -5px; + right: -4px; + display: grid; + width: 22px; + height: 22px; + place-items: center; + color: white; + background: var(--red); + border: 2px solid white; + border-radius: 50%; + font-size: 13px; +} + +.operator-card { + display: grid; + min-width: 208px; + grid-template-columns: 38px minmax(0, 1fr) 15px; + align-items: center; + gap: 10px; + padding: 5px 9px 5px 6px; + background: white; + border: 1px solid var(--line); + border-radius: 11px; + text-align: left; +} + +.operator-card > span:first-child { + display: grid; + width: 38px; + height: 38px; + place-items: center; + color: white; + background: var(--green); + border-radius: 10px; + font-size: 14px; + font-weight: 800; +} + +.operator-card > span:nth-child(2), +.operator-card strong, +.operator-card small { + display: block; +} + +.operator-card strong { + font-size: 14px; +} + +.operator-card small { + margin-top: 3px; + color: var(--muted); +} + +.operator-card svg { + width: 15px; + height: 15px; +} + +.main-content { + min-width: 0; + max-width: 1680px; + margin: 0 auto; + padding: 34px 30px 60px; +} + +.view { + display: none; + min-width: 0; +} + +.view.active { + display: block; +} + +.page-heading { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 28px; + margin-bottom: 24px; +} + +.page-heading > div:first-child { + min-width: 0; +} + +.eyebrow { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 9px; + color: var(--green-2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.13em; +} + +.eyebrow i { + width: 22px; + height: 2px; + background: var(--green-2); +} + +.page-heading h1 { + margin: 0; + font-size: clamp(28px, 2.5vw, 38px); + letter-spacing: -0.03em; +} + +.page-heading p { + max-width: 820px; + margin: 9px 0 0; + color: var(--muted); + font-size: 15px; + line-height: 1.7; +} + +.heading-actions { + display: flex; + flex: 0 0 auto; + gap: 9px; +} + +.button { + display: inline-flex; + min-height: 42px; + align-items: center; + justify-content: center; + gap: 8px; + padding: 0 15px; + border-radius: 10px; + font-size: 13px; + font-weight: 700; +} + +.button svg { + width: 17px; + height: 17px; +} + +.button.primary { + color: white; + background: var(--green); + box-shadow: 0 8px 18px rgba(23, 107, 79, 0.16); +} + +.button.primary:hover { + background: #135f46; +} + +.button.secondary { + color: var(--ink-soft); + background: white; + border: 1px solid var(--line); +} + +.button.secondary:hover { + border-color: #aecab9; +} + +.button.wide { + width: 100%; +} + +.text-button { + color: var(--green); + font-size: 13px; + font-weight: 700; +} + +.panel { + min-width: 0; + background: white; + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: 0 8px 26px rgba(18, 54, 41, 0.045); +} + +.panel-head { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 20px; +} + +.panel-head > div > span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; +} + +.panel-head h2 { + margin: 5px 0 0; + font-size: 20px; +} + +.panel-head > em { + color: var(--muted); + font-size: 13px; + font-style: normal; +} + +.production-hero { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 35px; + padding: 26px 28px; + color: #dceae4; + background: + radial-gradient(circle at 90% 0%, rgba(200, 236, 115, 0.16), transparent 31%), + linear-gradient(135deg, #174536, #102f26); + border-radius: 18px; + box-shadow: 0 18px 42px rgba(15, 45, 34, 0.14); +} + +.hero-kicker { + display: flex; + align-items: center; + gap: 8px; + color: var(--lime); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.12em; +} + +.hero-kicker i { + width: 8px; + height: 8px; + background: var(--lime); + border-radius: 50%; + box-shadow: 0 0 0 5px rgba(200, 236, 115, 0.09); +} + +.production-hero h2 { + margin: 10px 0 7px; + color: white; + font-size: 25px; +} + +.production-hero p { + margin: 0; + color: #9bb3aa; + font-size: 14px; +} + +.hero-status-row { + display: flex; + flex-wrap: wrap; + gap: 9px; + margin-top: 20px; +} + +.hero-status-row span { + display: flex; + align-items: baseline; + gap: 7px; + padding: 8px 11px; + color: #90aaa0; + background: rgba(255, 255, 255, 0.05); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: 8px; + font-size: 13px; +} + +.hero-status-row strong { + color: white; + font-size: 15px; +} + +.hero-score { + display: flex; + align-items: center; + gap: 15px; + padding-left: 25px; + border-left: 1px solid rgba(255, 255, 255, 0.1); +} + +.score-ring { + position: relative; + display: grid; + width: 108px; + height: 108px; + place-items: center; + align-content: center; + background: conic-gradient(var(--lime) 0 94.7%, rgba(255, 255, 255, 0.08) 94.7% 100%); + border-radius: 50%; +} + +.score-ring::after { + position: absolute; + inset: 7px; + background: #173f32; + border-radius: 50%; + content: ""; +} + +.score-ring strong, +.score-ring small { + position: relative; + z-index: 1; + display: block; + text-align: center; +} + +.score-ring strong { + color: white; + font-size: 27px; +} + +.score-ring small { + color: #8ca79c; +} + +.hero-score > span:last-child strong, +.hero-score > span:last-child small { + display: block; +} + +.hero-score > span:last-child strong { + color: var(--lime); + font-size: 17px; +} + +.hero-score > span:last-child small { + margin-top: 5px; + color: #91aaa0; +} + +.metric-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 12px; + margin-top: 14px; +} + +.metric-grid article { + position: relative; + min-width: 0; + padding: 18px; + overflow: hidden; + background: white; + border: 1px solid var(--line-soft); + border-radius: 14px; +} + +.metric-grid article::after { + position: absolute; + right: -20px; + bottom: -28px; + width: 95px; + height: 95px; + background: radial-gradient(circle, rgba(35, 135, 101, 0.08), transparent 66%); + content: ""; +} + +.metric-grid span, +.metric-grid strong, +.metric-grid em, +.metric-grid i { + display: block; +} + +.metric-grid span { + color: var(--muted); + font-size: 13px; +} + +.metric-grid strong { + margin: 9px 0 5px; + font-size: 28px; +} + +.metric-grid strong small { + margin-left: 4px; + color: var(--muted); + font-size: 13px; +} + +.metric-grid em { + color: var(--muted); + font-size: 13px; + font-style: normal; +} + +.metric-grid i { + margin-top: 9px; + font-size: 13px; + font-style: normal; + font-weight: 700; +} + +.positive { + color: var(--green-2) !important; +} + +.warning { + color: #a16d18 !important; +} + +.overview-grid { + display: grid; + grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); + gap: 14px; + margin-top: 14px; +} + +.source-health-panel, +.flow-panel, +.alert-panel { + padding: 21px; +} + +.source-health-panel { + grid-row: span 2; +} + +.source-health-list { + display: flex; + gap: 8px; + margin-top: 18px; + flex-direction: column; +} + +.source-health-item { + display: grid; + grid-template-columns: 39px minmax(0, 1fr) 150px 90px; + align-items: center; + gap: 11px; + padding: 11px; + background: #f8faf8; + border: 1px solid #edf1ee; + border-radius: 10px; +} + +.source-health-logo, +.source-logo { + display: grid; + place-items: center; + color: white; + background: var(--green); + border-radius: 9px; + font-size: 13px; + font-weight: 800; +} + +.source-health-logo { + width: 39px; + height: 39px; +} + +.source-health-logo.commercial, +.source-logo.commercial { + background: #1c4f3e; +} + +.source-health-logo.public, +.source-logo.public { + background: var(--blue); +} + +.source-health-logo.school, +.source-logo.school { + color: #654409; + background: #f3c871; +} + +.source-health-copy strong, +.source-health-copy small { + display: block; +} + +.source-health-copy strong { + font-size: 14px; +} + +.source-health-copy small { + margin-top: 3px; + color: var(--muted); +} + +.health-meter { + display: flex; + align-items: center; + gap: 8px; +} + +.health-meter i { + height: 7px; + flex: 1; + overflow: hidden; + background: #e4ebe6; + border-radius: 5px; +} + +.health-meter i b { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #72b893); + border-radius: 5px; +} + +.health-meter strong { + width: 42px; + color: var(--green); + font-size: 13px; + text-align: right; +} + +.status-pill { + display: inline-flex; + min-height: 27px; + align-items: center; + justify-content: center; + padding: 0 8px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px; + font-weight: 700; + white-space: nowrap; +} + +.status-pill.running::before { + width: 7px; + height: 7px; + margin-right: 6px; + background: var(--green); + border-radius: 50%; + content: ""; +} + +.status-pill.attention { + color: #996816; + background: var(--amber-soft); +} + +.status-pill.failed { + color: #a54b43; + background: var(--red-soft); +} + +.live-label { + display: flex; + align-items: center; + gap: 6px; + color: var(--green-2); + font-size: 13px; + font-weight: 700; +} + +.live-label i { + width: 8px; + height: 8px; + background: var(--green-2); + border-radius: 50%; +} + +.pipeline-flow { + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + margin-top: 23px; + padding: 16px 10px; + background: #f7f9f7; + border-radius: 11px; +} + +.pipeline-flow > span { + min-width: 75px; + text-align: center; +} + +.pipeline-flow b, +.pipeline-flow strong, +.pipeline-flow small { + display: block; +} + +.pipeline-flow b { + display: grid; + width: 29px; + height: 29px; + margin: 0 auto 7px; + place-items: center; + color: var(--muted); + background: #e8ede9; + border-radius: 8px; + font-size: 13px; +} + +.pipeline-flow .done b { + color: white; + background: var(--green); +} + +.pipeline-flow .active b { + color: #173a2e; + background: var(--lime); + box-shadow: 0 0 0 5px rgba(200, 236, 115, 0.15); +} + +.pipeline-flow strong { + font-size: 13px; +} + +.pipeline-flow small { + margin-top: 4px; + color: var(--muted); + white-space: nowrap; +} + +.pipeline-flow > i { + width: 25px; + height: 1px; + background: #cfd9d2; +} + +.flow-caption { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 7px; + margin-top: 11px; +} + +.flow-caption span { + padding: 9px; + color: var(--muted); + background: #fafbfa; + border: 1px solid var(--line-soft); + border-radius: 8px; + font-size: 13px; +} + +.flow-caption strong { + display: block; + margin-bottom: 3px; + color: var(--ink); + font-size: 13px; +} + +.alert-panel .panel-head > em { + padding: 5px 8px; + color: #a14e46; + background: var(--red-soft); + border-radius: 7px; + font-weight: 700; +} + +.alert-list { + display: flex; + gap: 7px; + margin-top: 17px; + flex-direction: column; +} + +.alert-list button { + display: grid; + width: 100%; + grid-template-columns: 9px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 11px; + background: #fafbfa; + border: 1px solid var(--line-soft); + border-radius: 9px; + text-align: left; +} + +.alert-list button > i { + width: 8px; + height: 8px; + border-radius: 50%; +} + +.alert-list i.red { + background: var(--red); +} + +.alert-list i.amber { + background: var(--amber); +} + +.alert-list i.blue { + background: var(--blue); +} + +.alert-list strong, +.alert-list small { + display: block; +} + +.alert-list strong { + font-size: 14px; +} + +.alert-list small { + margin-top: 3px; + color: var(--muted); +} + +.alert-list button > em { + color: var(--muted); + font-size: 13px; + font-style: normal; + font-weight: 700; +} + +.summary-strip { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 14px; +} + +.summary-strip > span { + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.summary-strip small, +.summary-strip strong, +.summary-strip em { + display: block; +} + +.summary-strip small { + color: var(--muted); +} + +.summary-strip strong { + margin: 7px 0 4px; + font-size: 21px; +} + +.summary-strip em { + color: var(--green-2); + font-size: 13px; + font-style: normal; +} + +.source-registry-panel { + padding: 19px; +} + +.source-toolbar, +.table-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; +} + +.filter-pills, +.segmented { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.filter-pills button, +.segmented button { + min-height: 34px; + padding: 0 11px; + color: var(--muted); + background: #f3f6f3; + border-radius: 8px; + font-size: 13px; +} + +.filter-pills button.active, +.segmented button.active { + color: white; + background: var(--green); + font-weight: 700; +} + +.inline-search { + width: min(320px, 38vw); + padding: 0 10px; +} + +.inline-search input { + height: 36px; +} + +.source-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 11px; + margin-top: 16px; +} + +.source-card { + min-width: 0; + padding: 16px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 12px; + transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease; +} + +.source-card:hover { + border-color: #c6dace; + box-shadow: 0 10px 24px rgba(17, 58, 42, 0.08); + transform: translateY(-2px); +} + +.source-card-head { + display: grid; + grid-template-columns: 43px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; +} + +.source-logo { + width: 43px; + height: 43px; +} + +.source-name strong, +.source-name small { + display: block; +} + +.source-name strong { + overflow: hidden; + font-size: 15px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.source-name small { + margin-top: 4px; + color: var(--muted); +} + +.source-type { + padding: 4px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 13px; + font-style: normal; +} + +.source-type.public { + color: var(--blue); + background: var(--blue-soft); +} + +.source-type.school { + color: #996816; + background: var(--amber-soft); +} + +.source-card-metrics { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 7px; + margin-top: 14px; +} + +.source-card-metrics span { + min-width: 0; + padding: 9px; + background: white; + border: 1px solid #edf1ee; + border-radius: 8px; +} + +.source-card-metrics small, +.source-card-metrics strong { + display: block; +} + +.source-card-metrics small { + color: var(--muted); +} + +.source-card-metrics strong { + margin-top: 4px; + overflow: hidden; + font-size: 14px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.source-card-meta { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-top: 11px; +} + +.source-card-meta span { + padding: 5px 7px; + color: var(--muted); + background: #f1f4f1; + border-radius: 6px; + font-size: 13px; +} + +.source-card-foot { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-top: 13px; + padding-top: 11px; + border-top: 1px solid var(--line-soft); +} + +.source-card-foot > span { + min-width: 0; + overflow: hidden; + color: var(--muted); + font-size: 13px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.source-card-foot button { + flex: 0 0 auto; + color: var(--green); + font-size: 13px; + font-weight: 700; +} + +.source-card-actions { + display: flex; + flex: 0 0 auto; + align-items: center; + gap: 10px; +} + +.source-card-actions button:first-child:not(:last-child) { + color: var(--blue); +} + +.list-summary { + margin-top: 14px; + color: var(--muted); + font-size: 13px; + text-align: right; +} + +.record-browser-panel { + padding: 18px; +} + +.record-layer-tabs { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 9px; +} + +.record-layer-tabs button { + min-width: 0; + padding: 14px; + color: var(--muted); + background: #f5f8f5; + border: 1px solid var(--line-soft); + border-radius: 10px; + text-align: left; +} + +.record-layer-tabs button span, +.record-layer-tabs button strong, +.record-layer-tabs button small { + display: block; +} + +.record-layer-tabs button span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.06em; +} + +.record-layer-tabs button strong { + margin-top: 5px; + color: var(--ink); + font-size: 15px; +} + +.record-layer-tabs button small { + margin-top: 4px; + color: var(--muted); + line-height: 1.45; +} + +.record-layer-tabs button.active { + color: white; + background: linear-gradient(135deg, #1a7255, #12523f); + border-color: var(--green); + box-shadow: 0 9px 20px rgba(23, 107, 79, 0.14); +} + +.record-layer-tabs button.active span { + color: var(--lime); +} + +.record-layer-tabs button.active strong { + color: white; +} + +.record-layer-tabs button.active small { + color: #bed6cc; +} + +.record-query-bar { + display: grid; + grid-template-columns: 220px 180px minmax(260px, 1fr); + gap: 10px; + margin-top: 15px; + padding: 14px; + background: #f7f9f7; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.record-query-bar label, +.record-query-bar label > span { + display: block; +} + +.record-query-bar label > span { + margin-bottom: 6px; + color: var(--muted); + font-size: 13px; + font-weight: 600; +} + +.record-query-bar select, +.record-query-bar input { + width: 100%; + height: 39px; + padding: 0 10px; + background: white; + border: 1px solid var(--line); + border-radius: 8px; +} + +.query-service-note { + display: grid; + grid-template-columns: auto auto minmax(0, 1fr); + align-items: center; + gap: 10px; + margin-top: 12px; + padding: 11px 13px; + color: var(--muted); + background: var(--green-soft); + border: 1px solid #d8e8de; + border-radius: 9px; +} + +.query-service-note > span { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--green); + font-size: 13px; + font-weight: 800; +} + +.query-service-note > span i { + width: 7px; + height: 7px; + background: #3bc183; + border-radius: 50%; +} + +.query-service-note strong { + color: var(--ink); + font-size: 13px; +} + +.query-service-note small { + min-width: 0; + line-height: 1.55; +} + +.record-table { + min-width: 1140px; +} + +.record-title, +.record-source-copy, +.record-time-copy { + display: block; +} + +.record-title strong, +.record-title small, +.record-source-copy strong, +.record-source-copy small, +.record-time-copy strong, +.record-time-copy small { + display: block; +} + +.record-title strong, +.record-source-copy strong, +.record-time-copy strong { + font-size: 14px; +} + +.record-title small, +.record-source-copy small, +.record-time-copy small { + margin-top: 4px; + color: var(--muted); +} + +.record-source-copy small, +.record-time-copy small { + font-family: "SFMono-Regular", Consolas, monospace; +} + +.record-source-cell { + display: grid; + min-width: 170px; + grid-template-columns: 34px minmax(0, 1fr); + align-items: center; + gap: 8px; +} + +.record-source-mark { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: white; + background: var(--green); + border-radius: 8px; + font-size: 13px; + font-weight: 800; +} + +.record-source-mark.public { + background: var(--blue); +} + +.record-quality { + display: inline-flex; + min-width: 52px; + align-items: center; + justify-content: center; + padding: 5px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px; + font-weight: 800; +} + +.record-quality.attention { + color: #9a650d; + background: var(--amber-soft); +} + +.record-list-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; + margin-top: 13px; + color: var(--muted); +} + +.record-list-footer span { + color: var(--ink); + font-size: 13px; + font-weight: 700; +} + +.record-list-footer small { + text-align: right; +} + +.record-drawer { + width: min(860px, 94vw); +} + +.record-detail-banner { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + align-items: center; + gap: 20px; + padding: 18px; + color: white; + background: linear-gradient(135deg, #143f32, #0d2d24); + border-radius: 11px; +} + +.record-detail-banner span, +.record-detail-banner strong, +.record-detail-banner small { + display: block; +} + +.record-detail-banner span { + color: var(--lime); + font-size: 13px; + font-weight: 800; +} + +.record-detail-banner strong { + margin: 7px 0 5px; + font-size: 20px; +} + +.record-detail-banner small { + color: #a4bbb1; + line-height: 1.55; +} + +.record-detail-score { + display: grid !important; + width: 68px; + height: 68px; + place-items: center; + color: var(--green-dark) !important; + background: var(--lime); + border-radius: 50%; + font-size: 18px !important; + font-weight: 900 !important; +} + +.record-lineage { + display: grid; + gap: 8px; +} + +.record-lineage > span { + display: grid; + grid-template-columns: 30px minmax(0, 1fr); + align-items: center; + gap: 10px; + padding: 10px; + background: #f7f9f7; + border-radius: 8px; +} + +.record-lineage > span > span { + display: block; + padding: 0; + background: transparent; + border-radius: 0; +} + +.record-lineage b { + display: grid; + width: 30px; + height: 30px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px; +} + +.record-lineage strong, +.record-lineage small { + display: block; +} + +.record-lineage small { + margin-top: 3px; + color: var(--muted); + overflow-wrap: anywhere; +} + +.record-payload { + max-height: 280px; + margin: 0; + padding: 13px; + overflow: auto; + color: #d7e8e0; + background: #102f26; + border-radius: 9px; + font-family: "SFMono-Regular", Consolas, monospace; + font-size: 13px; + line-height: 1.65; + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +.record-source-link { + color: var(--green); + font-weight: 700; + overflow-wrap: anywhere; +} + +.collector-metrics { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 11px; + margin-bottom: 14px; +} + +.collector-metrics article { + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.collector-metrics span, +.collector-metrics strong, +.collector-metrics small { + display: block; +} + +.collector-metrics span { + color: var(--muted); + font-size: 13px; +} + +.collector-metrics span i { + display: inline-block; + width: 8px; + height: 8px; + margin-right: 7px; + border-radius: 50%; +} + +.collector-metrics i.green { + background: var(--green); +} + +.collector-metrics i.blue { + background: var(--blue); +} + +.collector-metrics i.amber { + background: var(--amber); +} + +.collector-metrics i.red { + background: var(--red); +} + +.collector-metrics strong { + margin: 7px 0 4px; + font-size: 23px; +} + +.collector-metrics small { + color: var(--muted); +} + +.collector-table-panel, +.audit-table-panel { + padding: 18px; +} + +.table-toolbar > span { + color: var(--muted); + font-size: 13px; +} + +.table-wrap { + max-width: 100%; + margin-top: 15px; + overflow-x: auto; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.data-table { + width: 100%; + min-width: 1020px; + border-collapse: collapse; + background: white; +} + +.data-table.compact { + min-width: 900px; +} + +.data-table th, +.data-table td { + padding: 12px 11px; + border-bottom: 1px solid var(--line-soft); + text-align: left; + vertical-align: middle; +} + +.data-table th { + color: var(--muted); + background: #f5f8f5; + font-weight: 600; +} + +.data-table tr:last-child td { + border-bottom: 0; +} + +.job-title strong, +.job-title small { + display: block; +} + +.job-title strong { + font-size: 14px; +} + +.job-title small { + margin-top: 4px; + color: var(--muted); +} + +.job-strategy span, +.job-strategy small { + display: block; +} + +.job-strategy small { + margin-top: 3px; + color: var(--muted); +} + +.record-count-link { + margin-top: 5px; + color: var(--green); + font-size: 13px; + font-weight: 700; +} + +.job-progress { + min-width: 140px; +} + +.job-progress span { + display: flex; + align-items: center; + justify-content: space-between; + color: var(--muted); + font-size: 13px; +} + +.job-progress i { + display: block; + height: 7px; + margin-top: 6px; + overflow: hidden; + background: #e7ece8; + border-radius: 5px; +} + +.job-progress i b { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #71b991); +} + +.row-actions { + display: flex; + align-items: center; + gap: 5px; +} + +.row-actions button { + min-height: 31px; + padding: 0 8px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px; + font-weight: 700; +} + +.row-actions button.secondary { + color: var(--muted); + background: #f0f3f1; +} + +.contract-tabs { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 10px; + margin-bottom: 13px; +} + +.contract-tabs button { + padding: 15px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; + text-align: left; +} + +.contract-tabs button.active { + background: var(--green-soft); + border-color: #b9d9c5; + box-shadow: inset 4px 0 0 var(--green); +} + +.contract-tabs span, +.contract-tabs strong, +.contract-tabs small { + display: block; +} + +.contract-tabs span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; +} + +.contract-tabs strong { + margin: 7px 0 4px; + font-size: 15px; +} + +.contract-tabs small { + color: var(--muted); +} + +.contract-hero { + display: grid; + grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); + gap: 12px; +} + +.contract-overview, +.contract-release { + padding: 21px; +} + +.contract-overview > span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; +} + +.contract-overview h2 { + margin: 7px 0 8px; + font-size: 22px; +} + +.contract-overview p { + margin: 0; + color: var(--muted); + font-size: 14px; + line-height: 1.7; +} + +.contract-meta-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + margin-top: 17px; +} + +.contract-meta-grid span { + padding: 10px; + background: #f7f9f7; + border-radius: 8px; +} + +.contract-meta-grid small, +.contract-meta-grid strong { + display: block; +} + +.contract-meta-grid small { + color: var(--muted); +} + +.contract-meta-grid strong { + margin-top: 4px; + font-size: 14px; +} + +.contract-release { + color: #dceae4; + background: linear-gradient(140deg, #173f33, #102f26); +} + +.contract-release > span, +.contract-release > strong, +.contract-release > small { + display: block; +} + +.contract-release > span { + color: var(--lime); + font-size: 13px; + font-weight: 800; +} + +.contract-release > strong { + margin: 9px 0 6px; + color: white; + font-size: 19px; +} + +.contract-release > small { + color: #93ada2; + line-height: 1.6; +} + +.release-steps { + display: flex; + gap: 6px; + margin-top: 18px; +} + +.release-steps span { + flex: 1; + padding: 8px; + color: #9bb3aa; + background: rgba(255, 255, 255, 0.05); + border-radius: 7px; + font-size: 13px; + text-align: center; +} + +.release-steps span.done { + color: #15392e; + background: var(--lime); + font-weight: 700; +} + +.contract-body-grid { + display: grid; + grid-template-columns: minmax(0, 1fr) 330px; + gap: 12px; + margin-top: 12px; +} + +.field-panel, +.contract-rules-panel { + padding: 19px; +} + +.field-table { + width: 100%; + min-width: 820px; + border-collapse: collapse; +} + +.field-table th, +.field-table td { + padding: 11px 9px; + border-bottom: 1px solid var(--line-soft); + font-size: 13px; + text-align: left; +} + +.field-table th { + color: var(--muted); + background: #f5f8f5; +} + +.required-mark { + color: var(--red); + font-weight: 800; +} + +.field-code { + color: var(--green); + font-family: "SFMono-Regular", Consolas, monospace; + font-size: 13px; +} + +.contract-rule-list { + display: flex; + gap: 8px; + margin-top: 15px; + flex-direction: column; +} + +.contract-rule-list span { + padding: 11px; + color: var(--muted); + background: #f7f9f7; + border-radius: 9px; + font-size: 13px; + line-height: 1.6; +} + +.contract-rule-list strong { + display: block; + margin-bottom: 4px; + color: var(--ink); + font-size: 14px; +} + +.exchange-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 13px; +} + +.import-panel, +.export-panel, +.recent-exchange-panel { + padding: 20px; +} + +.upload-zone { + display: grid; + min-height: 190px; + place-items: center; + align-content: center; + gap: 7px; + margin-top: 17px; + color: var(--muted); + background: + linear-gradient(white, white) padding-box, + repeating-linear-gradient(45deg, #cfe0d5 0 8px, transparent 8px 16px) border-box; + border: 1px dashed transparent; + border-radius: 12px; + cursor: pointer; + text-align: center; +} + +.upload-zone.dragging { + background: var(--green-soft); + border-color: var(--green); +} + +.upload-zone input { + position: absolute; + width: 1px; + height: 1px; + opacity: 0; +} + +.upload-icon { + display: grid; + width: 46px; + height: 46px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 12px; +} + +.upload-icon svg { + width: 23px; + height: 23px; +} + +.upload-zone strong { + color: var(--ink); + font-size: 15px; +} + +.upload-zone small { + max-width: 390px; +} + +.import-configuration, +.export-form { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 14px; +} + +.import-configuration label > span, +.export-form label > span, +.form-grid label > span { + display: block; + margin-bottom: 6px; + color: var(--ink-soft); + font-size: 13px; + font-weight: 600; +} + +.import-configuration select, +.export-form input, +.export-form select, +.form-grid input, +.form-grid select, +.form-grid textarea { + width: 100%; + padding: 10px 11px; + background: #fafbf9; + border: 1px solid var(--line); + border-radius: 8px; +} + +.import-preview { + display: flex; + align-items: center; + justify-content: space-between; + gap: 14px; + margin-top: 14px; + padding: 13px; + background: #f7f9f7; + border-radius: 9px; +} + +.import-preview span, +.import-preview small, +.import-preview strong { + display: block; +} + +.import-preview small { + color: var(--muted); +} + +.import-preview strong { + margin-top: 4px; + font-size: 14px; +} + +.import-preview .button:disabled { + cursor: not-allowed; + opacity: 0.45; +} + +.package-includes { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin: 17px 0; +} + +.package-includes span { + display: flex; + align-items: center; + gap: 8px; + padding: 10px; + color: var(--muted); + background: #f7f9f7; + border-radius: 8px; + font-size: 13px; +} + +.package-includes i { + display: grid; + width: 20px; + height: 20px; + place-items: center; + color: white; + background: var(--green); + border-radius: 6px; + font-size: 13px; + font-style: normal; +} + +.recent-exchange-panel { + margin-top: 13px; +} + +.quality-layout { + display: grid; + grid-template-columns: 360px minmax(0, 1fr); + gap: 12px; +} + +.quality-score-card { + display: flex; + align-items: center; + gap: 17px; + padding: 19px; + color: #dceae4; + background: linear-gradient(140deg, #173f33, #102f26); + border-radius: 14px; +} + +.quality-ring { + position: relative; + display: grid; + width: 100px; + height: 100px; + flex: 0 0 auto; + place-items: center; + align-content: center; + background: conic-gradient(var(--lime) 0 94.7%, rgba(255, 255, 255, 0.09) 94.7% 100%); + border-radius: 50%; +} + +.quality-ring::after { + position: absolute; + inset: 7px; + background: #173f33; + border-radius: 50%; + content: ""; +} + +.quality-ring strong, +.quality-ring small { + position: relative; + z-index: 1; + display: block; + text-align: center; +} + +.quality-ring strong { + color: white; + font-size: 25px; +} + +.quality-ring small { + color: #8fa99e; +} + +.quality-score-card > div > span, +.quality-score-card > div > strong, +.quality-score-card > div > small { + display: block; +} + +.quality-score-card > div > span { + color: var(--lime); + font-size: 13px; +} + +.quality-score-card > div > strong { + margin: 7px 0 5px; + color: white; + font-size: 17px; +} + +.quality-score-card > div > small { + color: #91aaa0; + line-height: 1.5; +} + +.quality-dimensions { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 9px; +} + +.quality-dimensions span { + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.quality-dimensions small, +.quality-dimensions strong, +.quality-dimensions i { + display: block; +} + +.quality-dimensions small { + color: var(--muted); +} + +.quality-dimensions strong { + margin: 8px 0; + font-size: 20px; +} + +.quality-dimensions i { + height: 7px; + overflow: hidden; + background: #e7ece8; + border-radius: 5px; +} + +.quality-dimensions i b { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #72b893); +} + +.quality-grid { + display: grid; + grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); + gap: 12px; + margin-top: 12px; +} + +.rule-panel, +.normalization-panel { + padding: 19px; +} + +.rule-list, +.normalization-list { + display: flex; + gap: 8px; + margin-top: 15px; + flex-direction: column; +} + +.rule-item, +.normalization-item { + display: grid; + align-items: center; + gap: 10px; + padding: 12px; + background: #f8faf8; + border: 1px solid var(--line-soft); + border-radius: 9px; +} + +.rule-item { + grid-template-columns: 33px minmax(0, 1fr) auto; +} + +.rule-item > b { + display: grid; + width: 32px; + height: 32px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 8px; + font-size: 13px; +} + +.rule-item strong, +.rule-item small, +.normalization-item strong, +.normalization-item small { + display: block; +} + +.rule-item strong, +.normalization-item strong { + font-size: 14px; +} + +.rule-item small, +.normalization-item small { + margin-top: 4px; + color: var(--muted); +} + +.rule-item em { + color: var(--green); + font-size: 13px; + font-style: normal; + font-weight: 700; +} + +.normalization-item { + grid-template-columns: minmax(0, 1fr) 18px minmax(0, 1fr) auto; +} + +.normalization-item > i { + color: var(--muted); + font-size: 18px; + font-style: normal; +} + +.normalization-item button { + min-height: 31px; + padding: 0 9px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px; + font-weight: 700; +} + +.audit-summary { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 10px; + margin-bottom: 13px; +} + +.audit-summary article { + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.audit-summary small, +.audit-summary strong, +.audit-summary em { + display: block; +} + +.audit-summary small { + color: var(--muted); +} + +.audit-summary strong { + margin: 7px 0 4px; + font-size: 22px; +} + +.audit-summary em { + color: var(--green-2); + font-size: 13px; + font-style: normal; +} + +.audit-event strong, +.audit-event small { + display: block; +} + +.audit-event strong { + font-size: 14px; +} + +.audit-event small { + margin-top: 4px; + color: var(--muted); +} + +.operations-metrics { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 14px; +} + +.operations-metrics article { + min-width: 0; + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.operations-metrics span, +.operations-metrics strong, +.operations-metrics small { + display: block; +} + +.operations-metrics span, +.operations-metrics small { + color: var(--muted); +} + +.operations-metrics strong { + margin: 7px 0 4px; + font-size: 23px; +} + +.operations-tabs { + display: flex; + gap: 7px; + margin-bottom: 13px; + padding: 6px; + overflow-x: auto; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.operations-tabs button { + min-height: 38px; + flex: 0 0 auto; + padding: 0 14px; + color: var(--muted); + border-radius: 8px; + font-size: 13px; + font-weight: 700; +} + +.operations-tabs button.active { + color: white; + background: var(--green); +} + +.operations-workspace { + display: none; + min-width: 0; +} + +.operations-workspace.active { + display: block; +} + +.operations-panel, +.candidate-card, +.approval-card { + padding: 19px; +} + +.operations-table { + min-width: 1120px; +} + +.operations-impact { + display: block; + max-width: 300px; + color: var(--ink-soft); + line-height: 1.55; +} + +.severity-badge { + display: inline-flex; + min-height: 26px; + align-items: center; + padding: 0 8px; + color: #a64c44; + background: var(--red-soft); + border-radius: 7px; + font-size: 13px; + font-weight: 800; +} + +.severity-badge.p2 { + color: #996816; + background: var(--amber-soft); +} + +.cell-note, +.failure-note { + display: block; + margin-top: 5px; + color: var(--muted); + line-height: 1.45; +} + +.failure-note { + max-width: 180px; + color: var(--red); +} + +.release-workspace-grid { + display: grid; + grid-template-columns: minmax(0, 1.15fr) minmax(360px, 0.85fr); + gap: 12px; +} + +.candidate-version-banner { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 8px; + margin-top: 17px; +} + +.candidate-version-banner > span { + min-width: 0; + padding: 13px; + color: #dceae4; + background: linear-gradient(135deg, #173f33, #102f26); + border-radius: 9px; +} + +.candidate-version-banner small, +.candidate-version-banner strong { + display: block; +} + +.candidate-version-banner small { + color: #91aaa0; +} + +.candidate-version-banner strong { + margin-top: 5px; + overflow-wrap: anywhere; + color: white; + font-size: 14px; +} + +.release-facts { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin-top: 10px; +} + +.release-facts > span { + min-width: 0; + padding: 11px; + background: #f7f9f7; + border-radius: 8px; +} + +.release-facts small, +.release-facts strong { + display: block; +} + +.release-facts small { + color: var(--muted); +} + +.release-facts strong { + margin-top: 4px; + overflow-wrap: anywhere; + font-size: 14px; +} + +.gate-pass { + color: var(--green); +} + +.gate-blocked { + color: var(--red); +} + +.release-quality-note, +.delivery-boundary-note { + margin-top: 10px; + padding: 12px; + color: #975f10; + background: var(--amber-soft); + border: 1px solid #f0ddb8; + border-radius: 9px; + font-size: 13px; + line-height: 1.6; +} + +.release-quality-note.passed { + color: var(--green); + background: var(--green-soft); + border-color: #d4e8db; +} + +.delivery-boundary-note { + color: var(--ink-soft); + background: var(--blue-soft); + border-color: #d8e6f0; +} + +.candidate-actions { + display: flex; + align-items: center; + gap: 12px; + margin-top: 13px; +} + +.approval-summary { + margin: 15px 0 0; +} + +.approval-summary > div { + display: grid; + grid-template-columns: 100px minmax(0, 1fr); + gap: 10px; + padding: 10px 0; + border-bottom: 1px solid var(--line-soft); +} + +.approval-summary dt { + color: var(--muted); +} + +.approval-summary dd { + min-width: 0; + margin: 0; + overflow-wrap: anywhere; + font-weight: 700; +} + +.approval-actions { + display: flex; + align-items: flex-end; + flex-wrap: wrap; + gap: 8px; + margin-top: 16px; +} + +.approval-field { + display: block; + min-width: 190px; + flex: 1; +} + +.approval-field > span, +.footer-field > span { + display: block; + margin-bottom: 6px; + color: var(--muted); + font-size: 13px; + font-weight: 600; +} + +.approval-field select, +.approval-field input, +.footer-field select, +.receipt-input { + width: 100%; + min-height: 40px; + padding: 8px 10px; + background: white; + border: 1px solid var(--line); + border-radius: 8px; +} + +.approval-comment { + flex-basis: 100%; +} + +.rollback-approval-block { + display: grid; + width: 100%; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + padding: 14px; + background: var(--amber-soft); + border: 1px solid #ecd4a4; + border-radius: 10px; +} + +.rollback-approval-block > strong, +.rollback-approval-block > small { + grid-column: 1 / -1; +} + +.rollback-approval-block > strong { + color: #7f5310; + font-size: 14px; +} + +.rollback-approval-block > small { + color: var(--muted); + line-height: 1.55; +} + +.rollback-action-row { + grid-column: 1 / -1; + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.button:disabled, +.text-button:disabled { + cursor: not-allowed; + opacity: 0.45; +} + +.danger-button { + color: var(--red) !important; + border-color: #e8c5c1 !important; +} + +.release-final-note, +.footer-guidance { + color: var(--muted); + font-size: 13px; + line-height: 1.5; +} + +.delivery-table { + min-width: 1260px; +} + +.receipt-input { + min-width: 145px; +} + +.receipt-input.hash-input { + min-width: 290px; + font-family: "SFMono-Regular", Consolas, monospace; +} + +.hash-copy { + display: block; + max-width: 180px; + overflow: hidden; + font-family: "SFMono-Regular", Consolas, monospace; + font-size: 13px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.issue-drawer { + width: min(850px, 94vw); +} + +.issue-summary-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 8px; +} + +.issue-summary-grid > span { + min-width: 0; + padding: 12px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 9px; +} + +.issue-summary-grid small, +.issue-summary-grid strong { + display: block; +} + +.issue-summary-grid small { + color: var(--muted); +} + +.issue-summary-grid strong { + margin-top: 5px; + overflow-wrap: anywhere; + font-size: 14px; +} + +.quality-disposition-form .button { + margin-top: 12px; +} + +.immutable-action { + box-shadow: inset 4px 0 0 var(--blue); +} + +.issue-timeline { + display: flex; + flex-direction: column; +} + +.issue-timeline > span { + position: relative; + display: grid; + grid-template-columns: 15px minmax(0, 1fr); + gap: 9px; + padding: 3px 0 15px; +} + +.issue-timeline > span:not(:last-child)::before { + position: absolute; + top: 12px; + bottom: -2px; + left: 5px; + width: 1px; + background: #cfdcd4; + content: ""; +} + +.issue-timeline i { + position: relative; + z-index: 1; + width: 11px; + height: 11px; + margin-top: 3px; + background: var(--green); + border: 3px solid var(--green-soft); + border-radius: 50%; + box-sizing: content-box; +} + +.issue-timeline strong, +.issue-timeline small, +.issue-timeline em { + display: block; +} + +.issue-timeline small { + margin-top: 4px; + color: var(--muted); + line-height: 1.5; +} + +.issue-timeline em { + margin-top: 4px; + color: var(--blue); + font-size: 13px; + font-style: normal; + overflow-wrap: anywhere; +} + +.issue-drawer-footer { + align-items: flex-end; + flex-wrap: wrap; +} + +.footer-field { + min-width: 230px; +} + +.notification-list button { + width: 100%; + padding: 11px; + background: #f7f9f7; + border-radius: 8px; + text-align: left; +} + +.notification-list button:hover { + background: var(--green-soft); +} + +.evidence-tags { + display: flex; + flex-wrap: wrap; + gap: 5px; +} + +.evidence-tags span { + padding: 4px 6px; + color: var(--green); + background: var(--green-soft); + border-radius: 5px; + font-size: 13px; +} + +.drawer-backdrop, +.modal-backdrop { + position: fixed; + z-index: 100; + inset: 0; + background: rgba(7, 28, 20, 0.56); + backdrop-filter: blur(5px); + opacity: 0; + pointer-events: none; + transition: opacity 0.22s ease; +} + +.drawer-backdrop.open, +.modal-backdrop.open { + opacity: 1; + pointer-events: auto; +} + +.drawer { + position: absolute; + top: 0; + right: 0; + display: flex; + width: min(820px, 94vw); + height: 100%; + background: #f5f8f5; + box-shadow: -24px 0 80px rgba(7, 29, 21, 0.24); + flex-direction: column; + transform: translateX(24px); + transition: transform 0.22s ease; +} + +.drawer-backdrop.open .drawer { + transform: translateX(0); +} + +.drawer-header { + display: flex; + flex: 0 0 auto; + align-items: flex-start; + justify-content: space-between; + gap: 20px; + padding: 24px 25px 19px; + background: white; + border-bottom: 1px solid var(--line); +} + +.drawer-header > div > span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.1em; +} + +.drawer-header h2 { + margin: 6px 0 5px; + font-size: 25px; +} + +.drawer-header p { + margin: 0; + color: var(--muted); + font-size: 14px; +} + +.drawer-tabs { + display: flex; + flex: 0 0 auto; + gap: 5px; + padding: 10px 22px; + overflow-x: auto; + background: white; + border-bottom: 1px solid var(--line); +} + +.drawer-tabs button { + min-height: 34px; + flex: 0 0 auto; + padding: 0 10px; + color: var(--muted); + border-radius: 8px; + font-size: 13px; +} + +.drawer-tabs button.active { + color: white; + background: var(--green); + font-weight: 700; +} + +.drawer-content { + min-height: 0; + flex: 1; + padding: 20px 23px 35px; + overflow-y: auto; +} + +.drawer-footer { + display: flex; + flex: 0 0 auto; + justify-content: flex-end; + gap: 8px; + padding: 13px 21px; + background: white; + border-top: 1px solid var(--line); +} + +.drawer-stat-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 8px; +} + +.drawer-stat-grid > span { + padding: 13px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.drawer-stat-grid small, +.drawer-stat-grid strong, +.drawer-stat-grid em { + display: block; +} + +.drawer-stat-grid small { + color: var(--muted); +} + +.drawer-stat-grid strong { + margin: 6px 0 4px; + font-size: 16px; +} + +.drawer-stat-grid em { + color: var(--green-2); + font-size: 13px; + font-style: normal; +} + +.drawer-card { + margin-top: 10px; + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.drawer-card h3 { + margin: 0 0 12px; + font-size: 16px; +} + +.drawer-card p, +.drawer-card li { + color: var(--muted); + font-size: 14px; + line-height: 1.7; +} + +.drawer-card ul { + margin: 0; + padding-left: 20px; +} + +.drawer-card dl { + margin: 0; +} + +.drawer-card dl > div { + display: grid; + grid-template-columns: 130px minmax(0, 1fr); + gap: 10px; + padding: 9px 0; + border-bottom: 1px solid var(--line-soft); +} + +.drawer-card dl > div:last-child { + border-bottom: 0; +} + +.drawer-card dt { + color: var(--muted); + font-size: 13px; +} + +.drawer-card dd { + margin: 0; + font-size: 14px; + font-weight: 600; +} + +.drawer-contract-banner { + padding: 17px; + color: #dceae4; + background: linear-gradient(135deg, #173f33, #102f26); + border-radius: 11px; +} + +.drawer-contract-banner span, +.drawer-contract-banner strong, +.drawer-contract-banner small { + display: block; +} + +.drawer-contract-banner span { + color: var(--lime); + font-size: 13px; + font-weight: 800; +} + +.drawer-contract-banner strong { + margin: 7px 0 5px; + color: white; + font-size: 17px; +} + +.drawer-contract-banner small { + color: #91aaa0; + line-height: 1.6; +} + +.runtime-list, +.audit-evidence-list { + display: flex; + gap: 8px; + flex-direction: column; +} + +.runtime-list span, +.audit-evidence-list span { + padding: 11px; + background: #f7f9f7; + border-radius: 8px; +} + +.runtime-list strong, +.runtime-list small, +.audit-evidence-list strong, +.audit-evidence-list small { + display: block; +} + +.runtime-list strong, +.audit-evidence-list strong { + font-size: 14px; +} + +.runtime-list small, +.audit-evidence-list small { + margin-top: 4px; + color: var(--muted); +} + +.mapping-table { + width: 100%; + min-width: 700px; + border-collapse: collapse; +} + +.mapping-table th, +.mapping-table td { + padding: 10px 8px; + border-bottom: 1px solid var(--line-soft); + font-size: 13px; + text-align: left; +} + +.mapping-table th { + color: var(--muted); + background: #f5f8f5; +} + +.modal-backdrop { + display: grid; + place-items: center; + padding: 20px; +} + +.modal { + position: relative; + width: min(760px, 100%); + max-height: calc(100vh - 40px); + padding: 28px; + overflow-y: auto; + background: white; + border-radius: 18px; + box-shadow: var(--shadow-high); + transform: translateY(12px) scale(0.985); + transition: transform 0.22s ease; +} + +.modal-backdrop.open .modal { + transform: translateY(0) scale(1); +} + +.compact-modal { + width: min(620px, 100%); +} + +.modal-close { + position: absolute; + top: 17px; + right: 17px; + display: grid; + width: 37px; + height: 37px; + place-items: center; + color: var(--muted); + background: #f1f4f1; + border-radius: 9px; +} + +.modal-close svg { + width: 16px; + height: 16px; +} + +.modal-kicker { + color: var(--green-2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.1em; +} + +.modal h2 { + margin: 7px 0 7px; + font-size: 27px; +} + +.modal > p { + margin: 0; + color: var(--muted); + font-size: 14px; + line-height: 1.7; +} + +.form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 11px; + margin-top: 19px; +} + +.form-grid .full { + grid-column: 1 / -1; +} + +.form-grid textarea { + resize: vertical; +} + +.modal-actions { + display: flex; + justify-content: flex-end; + gap: 8px; + margin-top: 20px; +} + +.info-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin-top: 16px; +} + +.info-grid span { + padding: 11px; + color: var(--muted); + background: #f7f9f7; + border-radius: 8px; + font-size: 13px; +} + +.info-grid strong { + display: block; + margin-top: 4px; + color: var(--ink); + font-size: 14px; +} + +.info-note { + margin-top: 12px; + padding: 13px; + color: var(--muted); + background: var(--green-soft); + border: 1px solid #d5e7dc; + border-radius: 9px; + font-size: 14px; + line-height: 1.7; +} + +.toast-region { + position: fixed; + z-index: 160; + right: 22px; + bottom: 22px; + display: flex; + width: min(380px, calc(100vw - 30px)); + gap: 8px; + flex-direction: column; + pointer-events: none; +} + +.toast { + display: grid; + grid-template-columns: 34px minmax(0, 1fr); + gap: 10px; + padding: 13px; + color: #dceae4; + background: #12382d; + border: 1px solid rgba(200, 236, 115, 0.18); + border-radius: 11px; + box-shadow: var(--shadow-high); + animation: toast-in 0.22s ease; +} + +.toast > span:first-child { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: #173a2e; + background: var(--lime); + border-radius: 9px; + font-weight: 800; +} + +.toast strong, +.toast small { + display: block; +} + +.toast strong { + color: white; + font-size: 14px; +} + +.toast small { + margin-top: 4px; + color: #a8beb5; + line-height: 1.5; +} + +@keyframes toast-in { + from { + opacity: 0; + transform: translateY(8px); + } +} + +.sidebar-scrim { + display: none; +} + +@media (max-width: 1240px) { + .source-grid { + grid-template-columns: 1fr 1fr; + } + + .metric-grid, + .collector-metrics, + .audit-summary, + .operations-metrics { + grid-template-columns: 1fr 1fr; + } + + .overview-grid, + .quality-grid, + .release-workspace-grid { + grid-template-columns: 1fr; + } + + .record-layer-tabs { + grid-template-columns: 1fr 1fr; + } + + .source-health-panel { + grid-row: auto; + } + + .contract-body-grid { + grid-template-columns: 1fr; + } + + .global-search { + width: min(300px, 28vw); + } +} + +@media (max-width: 980px) { + :root { + --sidebar: 0px; + } + + .sidebar { + width: 254px; + transform: translateX(-100%); + transition: transform 0.22s ease; + } + + body.sidebar-open .sidebar { + transform: translateX(0); + } + + .workspace { + margin-left: 0; + } + + .mobile-menu { + display: inline-grid !important; + } + + .sidebar-scrim { + position: fixed; + z-index: 35; + inset: 0; + display: block; + background: rgba(8, 30, 22, 0.48); + opacity: 0; + pointer-events: none; + transition: opacity 0.22s ease; + } + + body.sidebar-open .sidebar-scrim { + opacity: 1; + pointer-events: auto; + } + + .quality-layout { + grid-template-columns: 1fr; + } + + .exchange-grid, + .contract-hero { + grid-template-columns: 1fr; + } + + .contract-tabs { + grid-template-columns: 1fr; + } + + .global-search { + display: none; + } + + .topbar-context { + margin-right: auto; + } +} + +@media (max-width: 720px) { + .topbar { + height: 68px; + gap: 10px; + padding: 0 14px; + } + + .topbar-context small, + .environment-chip, + .operator-card > span:nth-child(2), + .operator-card > svg { + display: none; + } + + .topbar-context { + min-width: 0; + } + + .operator-card { + min-width: 42px; + width: 42px; + grid-template-columns: 1fr; + padding: 2px; + border: 0; + background: transparent; + } + + .main-content { + padding: 25px 14px 45px; + } + + .page-heading { + align-items: stretch; + flex-direction: column; + gap: 16px; + } + + .page-heading h1 { + font-size: 29px; + } + + .heading-actions { + align-items: stretch; + flex-direction: column; + } + + .heading-actions .button { + width: 100%; + } + + .production-hero { + grid-template-columns: 1fr; + padding: 22px 19px; + } + + .hero-score { + padding: 16px 0 0; + border-top: 1px solid rgba(255, 255, 255, 0.1); + border-left: 0; + } + + .hero-status-row { + display: grid; + grid-template-columns: 1fr 1fr; + } + + .metric-grid, + .collector-metrics, + .summary-strip, + .audit-summary, + .operations-metrics, + .quality-dimensions { + grid-template-columns: 1fr 1fr; + } + + .source-toolbar, + .table-toolbar { + align-items: stretch; + flex-direction: column; + } + + .inline-search { + width: 100%; + } + + .source-grid { + grid-template-columns: 1fr; + } + + .record-query-bar { + grid-template-columns: 1fr; + } + + .query-service-note { + grid-template-columns: 1fr; + align-items: start; + } + + .record-list-footer, + .record-detail-banner { + align-items: flex-start; + flex-direction: column; + } + + .record-list-footer { + display: flex; + } + + .record-list-footer small { + text-align: left; + } + + .record-detail-banner { + display: flex; + } + + .source-health-item { + grid-template-columns: 39px minmax(0, 1fr) 70px; + } + + .health-meter { + grid-column: 2 / -1; + grid-row: 2; + } + + .pipeline-flow { + align-items: stretch; + flex-direction: column; + } + + .pipeline-flow > span { + display: grid; + grid-template-columns: 35px minmax(0, 1fr) auto; + align-items: center; + text-align: left; + } + + .pipeline-flow b { + margin: 0; + } + + .pipeline-flow small { + margin: 0; + } + + .pipeline-flow > i { + width: 1px; + height: 12px; + margin-left: 24px; + } + + .flow-caption, + .contract-meta-grid, + .package-includes { + grid-template-columns: 1fr; + } + + .exchange-grid, + .contract-hero, + .contract-body-grid, + .quality-layout, + .quality-grid, + .release-workspace-grid { + grid-template-columns: 1fr; + } + + .candidate-version-banner, + .issue-summary-grid { + grid-template-columns: 1fr 1fr; + } + + .candidate-actions, + .approval-actions { + align-items: stretch; + flex-direction: column; + } + + .approval-field, + .footer-field { + width: 100%; + } + + .rollback-approval-block { + grid-template-columns: 1fr; + } + + .rollback-approval-block > strong, + .rollback-approval-block > small, + .rollback-action-row { + grid-column: 1; + } + + .import-configuration, + .export-form, + .form-grid, + .info-grid { + grid-template-columns: 1fr; + } + + .form-grid .full { + grid-column: auto; + } + + .drawer { + width: 100vw; + } + + .drawer-header { + padding: 20px 17px 16px; + } + + .drawer-content { + padding: 16px 14px 30px; + } + + .drawer-stat-grid { + grid-template-columns: 1fr 1fr; + } + + .drawer-card dl > div { + grid-template-columns: 1fr; + gap: 4px; + } + + .modal-backdrop { + padding: 8px; + } + + .modal { + max-height: calc(100vh - 16px); + padding: 25px 18px 20px; + border-radius: 15px; + } + + .modal-actions { + align-items: stretch; + flex-direction: column; + } + + .modal-actions .button { + width: 100%; + } + + .normalization-item { + grid-template-columns: minmax(0, 1fr) 14px minmax(0, 1fr); + } + + .normalization-item button { + grid-column: 1 / -1; + justify-self: stretch; + } +} + +@media (max-width: 440px) { + .metric-grid, + .collector-metrics, + .summary-strip, + .audit-summary, + .operations-metrics, + .quality-dimensions { + grid-template-columns: 1fr; + } + + .hero-status-row, + .drawer-stat-grid { + grid-template-columns: 1fr 1fr; + } + + .source-card-metrics { + grid-template-columns: 1fr 1fr; + } + + .source-card-metrics span:last-child { + grid-column: 1 / -1; + } + + .filter-pills, + .segmented { + flex-wrap: nowrap; + padding-bottom: 4px; + overflow-x: auto; + } + + .record-layer-tabs { + grid-template-columns: 1fr 1fr; + } + + .record-layer-tabs button { + padding: 12px; + } + + .toast-region { + right: 15px; + bottom: 15px; + } + + .candidate-version-banner, + .release-facts, + .issue-summary-grid { + grid-template-columns: 1fr; + } + + .issue-drawer-footer { + align-items: stretch; + flex-direction: column; + } + + .issue-drawer-footer .button { + width: 100%; + } +} diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 0000000..1fca0d8 --- /dev/null +++ b/demo/README.md @@ -0,0 +1,95 @@ +# 产教融智企业版前端 + +产教融智面向职业院校构建“产业信号、专业诊断、校企协同、改进任务、正式报告”一体化工作闭环。本目录是企业版产品前端基线,所有核心场景均可深入点击并形成可追踪的业务结果。 + +## 运行 + +直接双击 `index.html` 即可使用。为避免浏览器对本地文件的限制,也可以在本目录启动静态服务: + +```bash +python3 -m http.server 8080 +``` + +然后访问 。 + +## 核心产品能力 + +- 校级供需决策总览、周期切换、专业搜索和七步产品导览 +- “企业需求 → 学校接收/分析快照 → 专业建议决策 → 任务/项目 → 执行证据 → 企业评价 → 校级验收 → 报告审批发布 → 数据使用反馈 → 下一周期复核”校园业务闭环 +- 闭环实体、角色动作、审批历史与审计事件使用 `localStorage` 持久化,支持刷新续办、Schema 迁移和样板重置 +- 技术接收同时强校验租户、包号、版本、交付记录数和完整 64 位 SHA-256;任一不一致只写失败审计,不推进回执或分析快照 +- 交付包记录数与分析样本量分开保存:样板包回执为 `2,846,320` 条,生成的校园分析快照为 `128,642` 条 +- 专业技能供需、岗位流向、薪资对标、课程技能映射与专业对比 +- 企业需求响应、潜力伙伴对接、协同项目里程碑和验收证据 +- 改进任务筛选、搜索、创建、阶段进展和报告建议转任务 +- 数据源初次导入、增量更新、质量处置、版本管理、授权与审计 +- 厂商基础数据包、校级数据、企业数据分类及授权状态筛选 +- 校级管理者、校级技术管理员、学院负责人、专业负责人、就业老师、企业导师、厂商超级管理员七种差异化工作台 +- 厂商平台级数据包导入、学校租户、账号权限、备份恢复和审计管理 +- 校级、学院、专业、产业专题与数据质量报告中心 +- 在线报告正文:封面、摘要、发现、供需分析、数据证据、指标口径和行动建议 +- 报告内置 ECharts / ECharts-GL 可视化:仪表盘、三基准柱状图、雷达图、趋势面积图、热力图、环图、象限气泡图和立体证据矩阵 +- 学校事实画像:在校生、毕业生、专业、教师、课程、合作企业、就业与实习指标均附证据编号、来源、更新时间、责任部门和计算口径 +- 结论证据链:学校值、区域均值、同类院校均值、排名、样本量、数据权属、置信度和已知限制 +- 报告类型、周期、关键词筛选、目录跳转、建议转任务、打印与离线 HTML 下载 +- 本期分析生成与供需会材料包生成 +- 供需会展示大屏及桌面端、平板、移动端自适应 + +## 数据资产分类 + +- **互联网基础数据包**:由平台厂商合规归集、治理并按服务期导入,属于付费订阅数据。 +- **校级数据**:来自学校实习、就业、教务等业务系统,数据权属归学校。 +- **企业数据**:由合作企业确认提交,按照合作协议限定使用范围。 + +## 角色视角 + +- **校级管理者**:全校决策总览、专业对比、校企协同、改进任务、数据资产与报告。 +- **校级技术管理员**:学校数据源、初次导入、更新任务、字段契约、质量问题、版本、授权与审计。 +- **学院负责人**:本院专业洞察、校企协同、改进任务与学院报告。 +- **专业负责人**:专业建议决策、关联任务与项目推进、执行证据和下一周期复核。 +- **就业老师**:就业侧数据使用确认和下一周期反馈;不能审批校级业务报告。 +- **企业导师**:企业人才需求、共建项目、学生参与和协同任务。 +- **厂商超级管理员**:平台数据包、学校租户、账号权限、备份恢复、服务监控与审计。 + +关键职责分离: + +- 技术接收成功后当前企业需求版本锁定;后续变更必须创建新版本并重新接收; +- 当前报告一经生成,支撑该版本的任务证据冻结;新增证据必须进入下一周期或重开新版本; +- 阶段进度必须达到 100%,企业导师才能提交通过或整改评价; +- 企业评价为“需整改”时,校级验收继续阻断,补充证据并重新评价后才可进入验收; +- 报告提交人不能批准或退回自己的提交,非校级管理者不显示报告审批与发布动作; +- 报告正式发布前,就业老师不能登记使用反馈,下载和打印均明确标识非正式版。 + +界面正文基准字号为 14px,表格、按钮、业务标签和辅助信息不低于 13px,适合会议投屏和客户现场展示。 + +## 数据运维入口 + +- 厂商超级管理员在“平台运营中心 → 数据包管理”完成基础数据包导入、Schema 与质量校验、租户授权和版本发布。 +- 校级技术管理员登录后默认进入“学校数据运维中心”,管理学校自有数据和企业授权数据。 +- 每个数据源的“资产详情”包含业务截止日期、入库日期、下次更新、更新内容、主键、必填字段、格式、Schema、质量阈值、责任人与审计事件。 +- “接收与使用反馈”展示租户、包号、版本、完整 SHA、交付包记录数、独立分析快照、支撑报告/项目/任务、业务可用确认和下一周期反馈。 +- 更新采用“暂存 → 校验 → 审批 → 发布”流程。失败数据进入隔离区,不覆盖当前稳定版本。 + +详细角色权限、数据契约、初次导入要求、更新机制和未来后端实体设计见 [`../docs/enterprise-product-baseline.md`](../docs/enterprise-product-baseline.md)。 + +## 报告与离线运行 + +报告中心内置42份独立报告,包括32份专业人才需求报告、5份学院报告,以及校级、产业专题和数据质量报告。在线阅读支持章节目录、八类交互图表、学校事实证据、来源台账和行动建议;下载功能生成可独立归档、打开和打印的完整 HTML 报告。 + +在线图表使用 `vendor/` 中本地化的 ECharts 5.6 与 ECharts-GL 2.0,无需 CDN。浏览器不支持图表运行时时自动显示静态 SVG 降级视图;下载报告直接内嵌全部图形和样式,不依赖外部脚本或网络。Apache-2.0、NOTICE 和 BSD-3-Clause 文件随库保存在 `vendor/`。 + +## 开发与验收说明 + +- 闭环样板使用命名空间 `eduIndustry.campusClosedLoop.TENANT-HZVTC.v1`,当前 `schemaVersion=2`。页面“重置样板”会恢复种子;旧 V1 或不满足深层实体/历史数组不变量的损坏 V2 状态,均按安全策略失效并重建 V2 种子。 +- 为避免静态原型长期演示导致浏览器存储无界增长,审计、证据、反馈、自定义集合和实体历史采用明确保留上限;正式系统应改用服务端分页、归档和不可变审计存储。 +- 共享样板标识为租户 `TENANT-HZVTC`、厂商包 `EDU-PKG-20260823-01`、版本 `V2026.08.23`、学校回执 `RCT-HZVTC-20260823-01`。这些标识只用于本静态原型的业务链对照,不表示厂商端和校园端页面实时同步。 +- 当前前端不向外部服务发送请求,可直接在隔离网络运行。 +- 仓库内数据用于本地产品验收,不包含任何真实学校、学生或企业敏感信息。 +- `localStorage` 只用于原型演示,不是正式数据库、鉴权或审计设施。正式接入必须由后端 API 执行租户隔离、身份认证、逐对象授权、并发控制、不可抵赖审计、文件安全存储、字段脱敏、授权台账和备份恢复;前端按钮隐藏或禁用不能作为权限控制。 +- JavaScript 语法检查:`node --check app.js && node --check report-visuals.js` +- 推荐桌面验收视口为 `1440 × 900`,移动验收视口为 `390 × 844`。 + +新增闭环预览: + +- `preview-campus-closed-loop.png` +- `preview-campus-closed-loop-mobile.png` diff --git a/demo/app.js b/demo/app.js new file mode 100644 index 0000000..8abaa8d --- /dev/null +++ b/demo/app.js @@ -0,0 +1,4726 @@ +const professionData = { + software: { + name: "软件技术", + college: "信息工程学院", + graduates: 186, + score: 84.2, + level: "高匹配", + demand: "2,864", + salary: "1.08", + coverage: "76%", + companyCount: 12, + skills: [ + { name: "Java / Spring", category: "后端开发", market: 92, course: 86 }, + { name: "Python", category: "应用开发", market: 84, course: 71 }, + { name: "Docker / K8s", category: "云原生", market: 81, course: 32 }, + { name: "数据库", category: "数据技术", market: 78, course: 74 }, + { name: "前端工程化", category: "Web开发", market: 72, course: 65 }, + { name: "AI辅助开发", category: "智能编程", market: 69, course: 28 }, + ], + jobs: [ + { name: "Java开发工程师", count: 826, growth: 18, width: 100 }, + { name: "前端开发工程师", count: 594, growth: 12, width: 72 }, + { name: "测试开发工程师", count: 463, growth: 9, width: 56 }, + { name: "云平台运维", count: 382, growth: 31, width: 46 }, + { name: "数据开发工程师", count: 311, growth: 24, width: 38 }, + ], + recommendations: [ + { + priority: "高优先级", + title: "强化“云原生与容器化”实训模块", + description: + "建议在综合实训中增加 Docker、Kubernetes 和 CI/CD 流水线,采用企业真实部署任务组织教学。", + evidence: "2,864条岗位样本中,相关技能出现率由42%升至78%,当前课程覆盖仅32%", + }, + { + priority: "中优先级", + title: "将AI辅助开发纳入软件工程实践", + description: + "增加代码生成、测试辅助与安全审查内容,同时明确人工复核和代码责任边界。", + evidence: "69%的重点企业已在JD中明确要求具备AI编程工具使用经验", + }, + ], + companies: [ + { short: "海康", name: "海康威视", focus: "边缘计算 · 软件开发", match: 94 }, + { short: "网易", name: "网易杭州", focus: "云服务 · 测试开发", match: 91 }, + { short: "数梦", name: "数梦工场", focus: "数据平台 · 后端开发", match: 89 }, + ], + }, + mechatronics: { + name: "机电一体化技术", + college: "智能制造学院", + graduates: 154, + score: 81.7, + level: "高匹配", + demand: "2,146", + salary: "1.05", + coverage: "72%", + companyCount: 9, + skills: [ + { name: "PLC编程", category: "自动控制", market: 94, course: 88 }, + { name: "工业机器人", category: "智能装备", market: 89, course: 71 }, + { name: "机器视觉", category: "工业视觉", market: 82, course: 38 }, + { name: "设备数字孪生", category: "数字工厂", market: 73, course: 26 }, + { name: "电气制图", category: "工程设计", market: 68, course: 82 }, + { name: "精益生产", category: "生产管理", market: 64, course: 52 }, + ], + jobs: [ + { name: "自动化工程师", count: 742, growth: 21, width: 100 }, + { name: "机器人工程师", count: 526, growth: 27, width: 71 }, + { name: "设备调试工程师", count: 398, growth: 13, width: 54 }, + { name: "机器视觉工程师", count: 287, growth: 38, width: 39 }, + { name: "电气工程师", count: 193, growth: 8, width: 26 }, + ], + recommendations: [ + { + priority: "高优先级", + title: "新增工业视觉综合实训项目", + description: + "联合装备企业建设缺陷检测场景,覆盖相机标定、图像处理、产线集成和质量评价。", + evidence: "机器视觉岗位近90天增长38%,课程覆盖度仅38%,技能缺口44个百分点", + }, + { + priority: "中优先级", + title: "引入设备数字孪生教学案例", + description: + "将现有PLC和生产线实训映射到数字孪生模型,形成设备数据采集与仿真任务。", + evidence: "73%的龙头制造企业将数字孪生列为智能工厂建设能力", + }, + ], + companies: [ + { short: "吉利", name: "吉利汽车", focus: "智能产线 · 自动化", match: 95 }, + { short: "大华", name: "大华股份", focus: "机器视觉 · 智能装备", match: 92 }, + { short: "西奥", name: "西奥电梯", focus: "设备调试 · 电气", match: 88 }, + ], + }, + ecommerce: { + name: "电子商务", + college: "商贸旅游学院", + graduates: 212, + score: 74.8, + level: "待关注", + demand: "1,932", + salary: "0.96", + coverage: "68%", + companyCount: 15, + skills: [ + { name: "内容运营", category: "新媒体", market: 91, course: 76 }, + { name: "数据分析", category: "经营分析", market: 86, course: 54 }, + { name: "跨境平台运营", category: "跨境电商", market: 83, course: 43 }, + { name: "直播投放", category: "营销增长", market: 78, course: 69 }, + { name: "AI内容生产", category: "智能营销", market: 75, course: 31 }, + { name: "供应链管理", category: "履约运营", market: 68, course: 59 }, + ], + jobs: [ + { name: "电商运营", count: 618, growth: 13, width: 100 }, + { name: "内容运营", count: 496, growth: 22, width: 80 }, + { name: "跨境电商运营", count: 374, growth: 34, width: 61 }, + { name: "直播投放", count: 283, growth: 18, width: 46 }, + { name: "用户增长", count: 161, growth: 27, width: 26 }, + ], + recommendations: [ + { + priority: "高优先级", + title: "重构跨境电商平台运营课程", + description: + "增加真实店铺、选品定价、海外投放和合规履约任务,引入企业运营数据进行过程评价。", + evidence: "跨境运营岗位增长34%,当前课程技能覆盖43%,企业反馈实操能力不足", + }, + { + priority: "中优先级", + title: "增加AI营销内容生产工作流", + description: + "将AI文案、图片与短视频辅助生产纳入内容运营课程,保留品牌规范与人工审核。", + evidence: "重点企业JD中AI内容工具要求出现率75%,现有覆盖仅31%", + }, + ], + companies: [ + { short: "遥望", name: "遥望科技", focus: "直播电商 · 内容运营", match: 93 }, + { short: "连连", name: "连连数字", focus: "跨境支付 · 商家运营", match: 90 }, + { short: "有赞", name: "有赞科技", focus: "SaaS电商 · 用户运营", match: 87 }, + ], + }, +}; + +const professions = [ + { key: "software", icon: "软", name: "软件技术", college: "信息工程学院", score: 84.2, demand: 2864, gaps: 3, trend: 4.8 }, + { key: "mechatronics", icon: "机", name: "机电一体化技术", college: "智能制造学院", score: 81.7, demand: 2146, gaps: 4, trend: 3.6 }, + { key: "ecommerce", icon: "商", name: "电子商务", college: "商贸旅游学院", score: 74.8, demand: 1932, gaps: 6, trend: -1.2 }, + { key: "iot", icon: "物", name: "物联网应用技术", college: "信息工程学院", score: 79.5, demand: 1648, gaps: 4, trend: 6.1 }, + { key: "mold", icon: "模", name: "模具设计与制造", college: "智能制造学院", score: 68.4, demand: 738, gaps: 7, trend: -2.4 }, +]; + +const industries = [ + { name: "工业视觉与智能检测", growth: 38, width: 100 }, + { name: "跨境电商运营", growth: 34, width: 89 }, + { name: "云平台与DevOps", growth: 31, width: 82 }, + { name: "工业机器人应用", growth: 27, width: 71 }, + { name: "AI营销内容生产", growth: 24, width: 63 }, +]; + +const trendSets = { + term: { + score: 78.6, + labels: ["9月", "10月", "11月", "12月", "1月", "3月"], + school: [69, 71.5, 72.2, 75.8, 76.4, 78.6], + benchmark: [68, 69, 69.8, 70.7, 71.2, 72.1], + }, + year: { + score: 78.6, + labels: ["一季度", "二季度", "三季度", "四季度", "本期"], + school: [67.5, 71.2, 73.8, 76.1, 78.6], + benchmark: [68.4, 69.2, 70.1, 71.3, 72.1], + }, + three: { + score: 78.6, + labels: ["2023", "2024", "2025", "2026"], + school: [64.8, 69.7, 74.4, 78.6], + benchmark: [66.2, 68.4, 70.3, 72.1], + }, +}; + +const projects = [ + { type: "course", tone: "green", title: "云原生应用开发课程共建", meta: "信息工程学院 × 数梦工场", progress: 72, partners: ["李", "王", "企"] }, + { type: "lab", tone: "amber", title: "工业视觉缺陷检测实训", meta: "智能制造学院 × 大华股份", progress: 48, partners: ["陈", "赵", "企"] }, + { type: "practice", tone: "blue", title: "跨境电商真实店铺运营", meta: "商贸旅游学院 × 连连数字", progress: 86, partners: ["徐", "周", "企"] }, + { type: "course", tone: "green", title: "数字文旅内容生产工作坊", meta: "艺术设计学院 × 宋城集团", progress: 35, partners: ["许", "孙", "企"] }, +]; + +const enterpriseDemands = [ + { + logo: "吉", + company: "吉利汽车", + industry: "智能制造", + title: "新能源汽车产线数字化人才共育", + description: "希望联合开发设备数据采集和产线运维实训,首期可接收30名学生。", + due: "3天后截止", + }, + { + logo: "遥", + company: "遥望科技", + industry: "数字商贸", + title: "直播电商运营实战项目", + description: "提供真实品牌运营任务,需要课程团队共同设计过程评价标准。", + due: "本周五截止", + }, + { + logo: "海", + company: "海康威视", + industry: "数字技术", + title: "边缘计算软件测试人才需求", + description: "邀请专业负责人确认技能清单,并讨论联合实训基地合作。", + due: "7天后截止", + }, +]; + +const partners = [ + { logo: "吉利", name: "吉利汽车", industry: "汽车制造 · 龙头企业", reason: "近一年发布高匹配岗位186个,与机电专业技能重合度高。", tags: ["智能产线", "企业导师"], match: 95 }, + { logo: "数梦", name: "数梦工场", industry: "数据智能 · 专精特新", reason: "已确认参与云原生课程共建,并提供真实项目案例。", tags: ["云平台", "课程共建"], match: 94 }, + { logo: "遥望", name: "遥望科技", industry: "直播电商 · 上市企业", reason: "内容运营和直播投放需求稳定,愿意提供实训项目。", tags: ["直播电商", "项目实训"], match: 93 }, + { logo: "大华", name: "大华股份", industry: "智能物联 · 龙头企业", reason: "工业视觉岗位增长显著,与学校智能制造方向互补。", tags: ["机器视觉", "实训基地"], match: 92 }, +]; + +const tasks = [ + { title: "强化云原生与容器化实训内容", source: "技能缺口分析 · AI建议已审核", profession: "软件技术", owner: "李雯", due: "2026-04-30", progress: 72, status: "progress", statusText: "进行中" }, + { title: "建设工业视觉缺陷检测实训项目", source: "企业需求 · 大华股份确认", profession: "机电一体化", owner: "陈昊", due: "2026-05-15", progress: 48, status: "progress", statusText: "进行中" }, + { title: "完成跨境电商课程标准修订", source: "专业供需分析 · 教研室提交", profession: "电子商务", owner: "徐莉", due: "2026-03-28", progress: 90, status: "review", statusText: "待确认" }, + { title: "引入3名企业导师参与毕业设计", source: "校企合作计划", profession: "物联网应用", owner: "王健", due: "2026-03-20", progress: 100, status: "done", statusText: "已完成" }, + { title: "开展模具专业企业需求复核调研", source: "低匹配专业预警", profession: "模具设计", owner: "赵明", due: "2026-03-12", progress: 35, status: "risk", statusText: "存在风险" }, + { title: "更新AI辅助开发课程使用规范", source: "教学质量委员会决议", profession: "软件技术", owner: "周宁", due: "2026-04-18", progress: 100, status: "done", statusText: "已完成" }, +]; + +const sources = [ + { + name: "区域招聘岗位基础包", + type: "互联网岗位 · 标准数据包", + category: "vendor", + categoryLabel: "基础数据包", + commercial: "付费订阅", + provider: "平台厂商导入", + rights: "项目期内授权使用", + coverage: "杭州及长三角", + frequency: "每月更新", + status: "服务有效", + records: "41,236", + quality: "93.4%", + updated: "2026-03-18", + dataAsOf: "2026-03-17", + nextUpdate: "2026-04-01", + updateMode: "全量首包 / 月度增量", + version: "V2026.03", + schema: "JOB-PACK 3.2", + format: "Parquet / CSV UTF-8", + primaryKey: "package_id + source_record_id", + requiredFields: "岗位名称、企业标识、地区代码、发布时间、薪资单位、来源地址", + threshold: "综合质量 ≥ 90;主键唯一率 100%", + changeSummary: "新增 12,430 条,修改 846 条,失效 312 条;新增 AI 应用岗位分类", + steward: "平台数据产品部", + technicalOwner: "平台数据运维组", + action: "检查更新", + }, + { + name: "薪资与企业画像基础包", + type: "互联网数据 · 增值数据包", + category: "vendor", + categoryLabel: "基础数据包", + commercial: "付费订阅", + provider: "平台厂商导入", + rights: "项目期内授权使用", + coverage: "区域重点产业", + frequency: "每月更新", + status: "服务有效", + records: "36,284", + quality: "91.8%", + updated: "2026-03-18", + dataAsOf: "2026-03-17", + nextUpdate: "2026-04-01", + updateMode: "全量首包 / 月度增量", + version: "V2026.Q1.3", + schema: "SALARY-COMPANY 2.4", + format: "Parquet / CSV UTF-8", + primaryKey: "package_id + enterprise_id + position_code", + requiredFields: "企业标识、岗位代码、薪资区间、统计周期、企业行业与规模", + threshold: "综合质量 ≥ 90;薪资合法率 ≥ 98%", + changeSummary: "更新 2,186 条薪资样本,补充 326 家企业规模与融资阶段标签", + steward: "平台数据产品部", + technicalOwner: "平台数据运维组", + action: "检查更新", + }, + { + name: "实习管理平台", + type: "校内系统 · API", + category: "school", + categoryLabel: "校级数据", + commercial: "校方自有", + provider: "学校实习系统", + rights: "校方数据资产", + coverage: "全校实习学生", + frequency: "每日同步", + status: "正常", + records: "32,418", + quality: "96.2%", + updated: "今天 08:12", + dataAsOf: "2026-03-21", + nextUpdate: "明天 08:00", + updateMode: "初次全量 / 每日增量", + version: "SCHOOL-20260322-01", + schema: "INTERNSHIP 2.1", + format: "API JSON", + primaryKey: "tenant_id + internship_id", + requiredFields: "学生标识、专业代码、企业标识、岗位、开始/结束日期、状态、更新时间", + threshold: "必填完整率 ≥ 95%;跨表关联率 ≥ 98%", + changeSummary: "新增 186 条,修改 42 条;更新 31 家实习企业岗位信息", + steward: "就业处", + technicalOwner: "学校信息中心", + action: "立即同步", + }, + { + name: "就业管理系统", + type: "校内系统 · 数据库视图", + category: "school", + categoryLabel: "校级数据", + commercial: "校方自有", + provider: "学校就业系统", + rights: "校方数据资产", + coverage: "近三届毕业生", + frequency: "每日同步", + status: "字段缺失", + records: "8,926", + quality: "87.6%", + updated: "今天 07:50", + dataAsOf: "2026-03-21", + nextUpdate: "异常处理后重试", + updateMode: "初次全量 / 每日增量", + version: "SCHOOL-20260322-02", + schema: "EMPLOYMENT 2.1", + format: "数据库视图", + primaryKey: "tenant_id + student_id + cohort", + requiredFields: "学生标识、专业代码、届次、就业状态、岗位、企业、业务更新时间", + threshold: "专业代码合法率 100%;必填完整率 ≥ 95%", + changeSummary: "新增 126 条,修改 43 条;86 条薪资记录进入隔离区,未覆盖当前生产版本", + steward: "就业处", + technicalOwner: "学校信息中心", + action: "处理异常", + warning: true, + }, + { + name: "课程标准库", + type: "校内文件 · 结构化导入", + category: "school", + categoryLabel: "校级数据", + commercial: "校方自有", + provider: "学校教务处", + rights: "校方数据资产", + coverage: "32个专业", + frequency: "学期更新", + status: "正常", + records: "1,428", + quality: "95.1%", + updated: "昨天 17:20", + dataAsOf: "2026-03-20", + nextUpdate: "2026-08-25", + updateMode: "初次全量 / 学期快照", + version: "CURRICULUM-2026S1-03", + schema: "CURRICULUM 1.8", + format: "XLSX / CSV UTF-8", + primaryKey: "tenant_id + course_code + curriculum_version", + requiredFields: "课程代码、专业代码、课程名称、学时、课程标准、技能标签、版本", + threshold: "课程代码唯一率 100%;技能映射覆盖率 ≥ 80%", + changeSummary: "导入 2026 春季课程快照;新增 38 门课程,修订 126 份课程标准", + steward: "教务处", + technicalOwner: "学校信息中心", + action: "立即同步", + }, + { + name: "企业确认需求库", + type: "企业提交 · 问卷/工作台", + category: "enterprise", + categoryLabel: "企业数据", + commercial: "合作授权", + provider: "126家合作企业", + rights: "限定合作场景使用", + coverage: "岗位与技能需求", + frequency: "按需更新", + status: "授权有效", + records: "8,350", + quality: "97.3%", + updated: "昨天 20:08", + dataAsOf: "2026-03-21", + nextUpdate: "企业提交后实时入队", + updateMode: "初次导入 / 事件增量", + version: "ENTERPRISE-20260321-06", + schema: "ENTERPRISE-DEMAND 1.6", + format: "工作台表单 / API JSON / XLSX", + primaryKey: "tenant_id + enterprise_credit_code + demand_id", + requiredFields: "企业标识、岗位、需求人数、技能、有效期、提交人、确认时间、授权编号", + threshold: "企业身份与授权关联率 100%;必填完整率 ≥ 95%", + changeSummary: "新增 18 家企业确认、54 项岗位需求;12 项过期需求自动停用", + steward: "产教融合中心", + technicalOwner: "学校信息中心", + action: "查看回执", + }, +]; + +const roleProfiles = { + 校级管理者: { + user: "周明远", + avatar: "周", + organization: "杭州科技职业技术学院", + organizationLabel: "当前组织", + emblem: "杭", + root: "产教融合中心", + context: "2025—2026 学年 · 第 2 学期", + workspaceLabel: "学校工作空间", + menus: ["dashboard", "loop", "profession", "collaboration", "actions", "data", "report", "screen"], + defaultView: "dashboard", + }, + 校级技术管理员: { + user: "王博", + avatar: "王", + organization: "杭州科技职业技术学院 · 信息中心", + organizationLabel: "当前数据域", + emblem: "数", + root: "学校数据运维中心", + context: "校级技术管理员 · 6 个数据源 · 2 个待处理任务", + workspaceLabel: "数据运维", + menus: ["loop", "data", "actions", "report"], + defaultView: "data", + dataAdministrator: true, + }, + 学院负责人: { + user: "李雯", + avatar: "李", + organization: "信息工程学院", + organizationLabel: "当前学院", + emblem: "信", + root: "学院工作台", + context: "信息工程学院 · 6 个专业 · 2026届", + workspaceLabel: "学院工作空间", + menus: ["loop", "profession", "collaboration", "actions", "report"], + defaultView: "profession", + }, + 专业负责人: { + user: "李雯", + avatar: "李", + organization: "信息工程学院 · 软件技术专业", + organizationLabel: "当前专业", + emblem: "软", + root: "专业建设工作台", + context: "软件技术专业 · 2026 春季闭环", + workspaceLabel: "专业工作空间", + menus: ["loop", "profession", "collaboration", "actions", "report"], + defaultView: "loop", + }, + 就业老师: { + user: "赵晴", + avatar: "赵", + organization: "杭州科技职业技术学院 · 就业处", + organizationLabel: "当前业务域", + emblem: "就", + root: "就业服务工作台", + context: "就业处 · 2026届 · 数据使用反馈", + workspaceLabel: "就业工作空间", + menus: ["loop", "data", "actions", "report"], + defaultView: "loop", + }, + 企业导师: { + user: "陈凯", + avatar: "陈", + organization: "海康威视 · 智能物联事业群", + organizationLabel: "当前企业", + emblem: "企", + root: "校企共育空间", + context: "企业导师 · 2026 春季合作项目", + workspaceLabel: "企业工作空间", + menus: ["loop", "collaboration", "actions"], + defaultView: "collaboration", + }, + 厂商超级管理员: { + user: "陈致远", + avatar: "陈", + organization: "产教融智平台运营中心", + organizationLabel: "平台运营方", + emblem: "融", + root: "平台运营中心", + context: "生产环境 · 华东区域 · 12 家学校租户", + workspaceLabel: "平台运营", + menus: [], + defaultView: "platform", + platform: true, + }, +}; + +const CLOSED_LOOP_SCHEMA_VERSION = 2; +const CLOSED_LOOP_LIMITS = { + auditEvents: 200, + evidences: 100, + usageFeedback: 50, + customCollection: 50, + entityHistory: 100, +}; +const CLOSED_LOOP_STORAGE_KEY = "eduIndustry.campusClosedLoop.TENANT-HZVTC.v1"; +const CLOSED_LOOP_SHARED = { + tenantId: "TENANT-HZVTC", + packageId: "EDU-PKG-20260823-01", + packageVersion: "V2026.08.23", + packageRecords: 2846320, + packageSha256: "4f8d91a47e2b6d82b2aaad136d344d61c83f9cd472185d2543725c91870e9e32", + receiptId: "RCT-HZVTC-20260823-01", +}; + +function closedLoopSeed() { + return { + schemaVersion: CLOSED_LOOP_SCHEMA_VERSION, + seededAt: "2026-08-23T09:00:00+08:00", + shared: { ...CLOSED_LOOP_SHARED }, + entities: { + demand: { + id: "DEM-HKVS-20260823-01", + status: "已提交", + company: "海康威视", + enterpriseId: "ENT-HKVS", + title: "边缘计算软件测试人才共育需求", + position: "边缘计算测试工程师", + skills: "Linux、Python、自动化测试、边缘设备调试", + headcount: 24, + authorizationNo: "AUTH-HKVS-20260823-01", + validUntil: "2027-08-22", + submitter: "陈凯 · 海康威视", + submittedAt: "2026-08-23 09:10", + description: "面向软件技术专业共建边缘计算测试实训,企业导师参与中期评审与成果评价。", + }, + snapshot: { + id: "SNP-HZVTC-20260824-01", + status: "待接收", + receivedAt: "", + acceptedAt: "", + operator: "", + packageId: CLOSED_LOOP_SHARED.packageId, + packageVersion: CLOSED_LOOP_SHARED.packageVersion, + sha256: CLOSED_LOOP_SHARED.packageSha256, + expectedRecords: 128642, + checkedRecords: 0, + }, + recommendation: { + id: "REC-SOFTWARE-20260823-01", + status: "待决策", + title: "强化“云原生与容器化”实训模块", + reason: "", + operator: "", + decidedAt: "", + snapshotId: "SNP-HZVTC-20260824-01", + demandId: "DEM-HKVS-20260823-01", + }, + task: null, + project: null, + evidences: [], + evaluation: null, + report: null, + usageFeedback: [], + review: null, + receipt: { + id: CLOSED_LOOP_SHARED.receiptId, + status: "待技术确认", + tenantId: CLOSED_LOOP_SHARED.tenantId, + packageId: CLOSED_LOOP_SHARED.packageId, + packageVersion: CLOSED_LOOP_SHARED.packageVersion, + expectedRecords: CLOSED_LOOP_SHARED.packageRecords, + expectedSha256: CLOSED_LOOP_SHARED.packageSha256, + receivedRecords: 0, + receivedSha256: "", + verification: null, + note: "", + technicalConfirmedBy: "", + technicalConfirmedAt: "", + businessUsable: false, + }, + }, + sequences: { evidence: 0, feedback: 0 }, + custom: { demands: [], tasks: [], projects: [], reports: [] }, + auditEvents: [ + { + id: "AUD-20260823-0001", + action: "SEED_CREATED", + objectId: "DEM-HKVS-20260823-01", + operator: "样板数据初始化", + role: "系统", + at: "2026-08-23 09:00", + detail: "创建可重置的校园闭环样板。", + }, + ], + }; +} + +function isPlainObject(value) { + return Boolean(value && typeof value === "object" && !Array.isArray(value)); +} + +function trimClosedLoopCollections(state) { + state.auditEvents = state.auditEvents.slice(0, CLOSED_LOOP_LIMITS.auditEvents); + state.entities.evidences = state.entities.evidences.slice(-CLOSED_LOOP_LIMITS.evidences); + state.entities.usageFeedback = state.entities.usageFeedback.slice(-CLOSED_LOOP_LIMITS.usageFeedback); + Object.keys(state.custom).forEach((key) => { + state.custom[key] = state.custom[key].slice(0, CLOSED_LOOP_LIMITS.customCollection); + }); + if (state.entities.task) { + state.entities.task.progressLogs = state.entities.task.progressLogs.slice(-CLOSED_LOOP_LIMITS.entityHistory); + state.entities.task.acceptanceHistory = state.entities.task.acceptanceHistory.slice(-CLOSED_LOOP_LIMITS.entityHistory); + } + if (state.entities.report) state.entities.report.history = state.entities.report.history.slice(-CLOSED_LOOP_LIMITS.entityHistory); + return state; +} + +function resetInvalidClosedLoopState(seed, rawVersion, reason) { + seed.auditEvents.unshift({ + id: `AUD-RESET-${Date.now()}`, + action: "SECURITY_SCHEMA_RESET", + objectId: CLOSED_LOOP_SHARED.receiptId, + operator: "闭环状态迁移器", + role: "系统", + at: nowText(), + detail: `Schema V${rawVersion ?? "未知"} 状态已按安全策略失效并重建 V${CLOSED_LOOP_SCHEMA_VERSION} 种子:${reason}`, + }); + return seed; +} + +function migrateClosedLoopState(raw) { + const seed = closedLoopSeed(); + if (!raw || typeof raw !== "object") return seed; + if (raw.schemaVersion !== CLOSED_LOOP_SCHEMA_VERSION) { + return resetInvalidClosedLoopState(seed, raw.schemaVersion, "旧版本未执行完整 SHA 强校验"); + } + const rawEntities = isPlainObject(raw.entities) ? raw.entities : {}; + const rawCustom = isPlainObject(raw.custom) ? raw.custom : {}; + const allowedCustom = Object.fromEntries(Object.entries(rawCustom).filter(([key]) => Object.hasOwn(seed.custom, key))); + const mergeEntity = (key) => { + const seedEntity = seed.entities[key]; + const rawEntity = rawEntities[key]; + if (isPlainObject(seedEntity) && isPlainObject(rawEntity)) { + return { ...seedEntity, ...rawEntity }; + } + return rawEntity ?? seedEntity; + }; + const state = { + ...seed, + ...raw, + schemaVersion: CLOSED_LOOP_SCHEMA_VERSION, + shared: { ...seed.shared, ...(isPlainObject(raw.shared) ? raw.shared : {}) }, + entities: { + ...seed.entities, + ...rawEntities, + demand: mergeEntity("demand"), + snapshot: mergeEntity("snapshot"), + recommendation: mergeEntity("recommendation"), + receipt: mergeEntity("receipt"), + }, + sequences: { ...seed.sequences, ...(isPlainObject(raw.sequences) ? raw.sequences : {}) }, + custom: { ...seed.custom, ...allowedCustom }, + auditEvents: Array.isArray(raw.auditEvents) ? raw.auditEvents : seed.auditEvents, + }; + const validEntityArrays = Array.isArray(state.entities.evidences) && Array.isArray(state.entities.usageFeedback); + const validCustomCollections = Object.keys(seed.custom).every((key) => Array.isArray(state.custom[key])); + const validCoreEntities = ["demand", "snapshot", "recommendation", "receipt"].every((key) => isPlainObject(state.entities[key])); + const validTask = + state.entities.task === null || + (isPlainObject(state.entities.task) && Array.isArray(state.entities.task.progressLogs) && Array.isArray(state.entities.task.acceptanceHistory)); + const validReport = state.entities.report === null || (isPlainObject(state.entities.report) && Array.isArray(state.entities.report.history)); + const validOptionalEntities = ["project", "evaluation", "review"].every((key) => state.entities[key] === null || isPlainObject(state.entities[key])); + if (!validEntityArrays || !validCustomCollections || !validCoreEntities || !validTask || !validReport || !validOptionalEntities) { + return resetInvalidClosedLoopState(seed, raw.schemaVersion, "实体结构或历史数组不满足 V2 不变量"); + } + state.sequences.evidence = Math.max(Number.isInteger(state.sequences.evidence) ? state.sequences.evidence : 0, state.entities.evidences.length); + state.sequences.feedback = Math.max(Number.isInteger(state.sequences.feedback) ? state.sequences.feedback : 0, state.entities.usageFeedback.length); + return trimClosedLoopCollections(state); +} + +function loadClosedLoopState() { + try { + return migrateClosedLoopState(JSON.parse(localStorage.getItem(CLOSED_LOOP_STORAGE_KEY))); + } catch { + return closedLoopSeed(); + } +} + +let closedLoopState = loadClosedLoopState(); + +function saveClosedLoopState() { + closedLoopState.schemaVersion = CLOSED_LOOP_SCHEMA_VERSION; + trimClosedLoopCollections(closedLoopState); + try { + localStorage.setItem(CLOSED_LOOP_STORAGE_KEY, JSON.stringify(closedLoopState)); + return true; + } catch { + showToast("浏览器阻止了本地存储,本次闭环状态仅在当前页面有效。", "状态未持久化"); + return false; + } +} + +function currentRoleName() { + return document.getElementById("roleSelect")?.value || "校级管理者"; +} + +function currentRoleUser() { + const role = currentRoleName(); + return `${roleProfiles[role]?.user || "样板用户"} · ${role}`; +} + +function nowText() { + return new Intl.DateTimeFormat("zh-CN", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + hour12: false, + }) + .format(new Date()) + .replaceAll("/", "-"); +} + +function safeText(value) { + const element = document.createElement("span"); + element.textContent = String(value ?? ""); + return element.innerHTML; +} + +function closedLoopToken(prefix) { + return `${prefix}-${Date.now()}-${Math.random().toString(16).slice(2, 7).toUpperCase()}`; +} + +function addClosedLoopAudit(action, objectId, detail, operator = currentRoleUser(), role = currentRoleName()) { + closedLoopState.auditEvents.unshift({ + id: closedLoopToken("AUD"), + action, + objectId, + operator, + role, + at: nowText(), + detail, + }); +} + +function loopStatusClass(status = "") { + if (["已发布", "已完成", "已验收", "已采纳", "通过", "已接收", "已确认", "关闭"].includes(status)) return "done"; + if (["已退回", "需整改", "驳回", "恶化"].includes(status)) return "risk"; + if (["暂缓", "待审核", "待验收", "待评价", "进入下一周期"].includes(status)) return "review"; + return "progress"; +} + +function syncClosedLoopCollections() { + const e = closedLoopState.entities; + const removeSynced = (list) => { + for (let index = list.length - 1; index >= 0; index -= 1) { + if (list[index]._closedLoop || list[index]._customPersisted) list.splice(index, 1); + } + }; + removeSynced(enterpriseDemands); + removeSynced(tasks); + removeSynced(projects); + enterpriseDemands.unshift( + { + _closedLoop: true, + id: e.demand.id, + logo: "海", + company: e.demand.company, + industry: "智能物联", + title: e.demand.title, + description: `${e.demand.position} · ${e.demand.headcount}人 · ${e.demand.skills}`, + due: `${e.demand.validUntil} 有效`, + status: e.demand.status, + }, + ...closedLoopState.custom.demands.map((item) => ({ ...item, _customPersisted: true })), + ); + if (e.task) { + tasks.unshift({ + _closedLoop: true, + id: e.task.id, + title: e.task.title, + source: `闭环建议 ${e.task.recommendationId} · 需求 ${e.task.demandId}`, + profession: e.task.profession, + owner: e.task.owner, + due: e.task.due, + progress: e.task.progress, + status: e.task.status === "已完成" ? "done" : e.task.status === "待验收" ? "review" : e.task.status === "已退回" ? "risk" : "progress", + statusText: e.task.status, + }); + } + tasks.unshift(...closedLoopState.custom.tasks.map((item) => ({ ...item, _customPersisted: true }))); + if (e.project) { + projects.unshift({ + _closedLoop: true, + id: e.project.id, + type: "practice", + tone: "green", + title: e.project.title, + meta: `${e.project.profession} × ${e.demand.company} · ${e.project.id}`, + progress: e.project.progress, + partners: ["李", "陈", "企"], + status: e.project.status, + demandId: e.project.demandId, + recommendationId: e.project.recommendationId, + taskId: e.project.taskId, + }); + } + projects.unshift(...closedLoopState.custom.projects.map((item) => ({ ...item, _customPersisted: true }))); + + for (let index = reports.length - 1; index >= 0; index -= 1) { + if (reports[index]._closedLoop || reports[index]._customPersisted) reports.splice(index, 1); + } + if (e.report) { + const base = reports.find((item) => item.type === "school") || reports[0]; + reports.unshift({ + ...base, + _closedLoop: true, + id: e.report.id, + title: e.report.title, + version: CLOSED_LOOP_SHARED.packageVersion, + status: e.report.status, + statusClass: loopStatusClass(e.report.status), + updated: e.report.updatedAt || "刚刚", + featured: true, + roles: ["校级管理者", "校级技术管理员", "学院负责人", "专业负责人", "就业老师"], + }); + } + reports.unshift(...closedLoopState.custom.reports.map((item) => ({ ...item, _customPersisted: true }))); +} + +function saveAndRenderClosedLoop(message = "") { + saveClosedLoopState(); + syncClosedLoopCollections(); + renderClosedLoop(); + renderTasks(); + renderProjects(); + renderDemands(); + renderReportCenter(); + if (message) showToast(message, "闭环状态已保存"); +} + +const closedLoopActionCatalog = { + demand: { + title: "提交企业需求", + description: "仅企业导师可维护本企业需求;岗位、技能、人数、授权号、有效期和提交人均为必填。", + roles: ["企业导师"], + fields: [ + ["position", "岗位名称", "text", "边缘计算测试工程师"], + ["skills", "技能要求", "textarea", "Linux、Python、自动化测试、边缘设备调试"], + ["headcount", "计划人数", "number", "24"], + ["authorizationNo", "授权号", "text", "AUTH-HKVS-20260823-01"], + ["validUntil", "授权有效期", "date", "2027-08-22"], + ["submitter", "提交人", "text", "陈凯 · 海康威视"], + ], + }, + receive: { + title: "确认接收并生成快照", + description: "校级技术管理员强校验租户、包号、版本、完整 SHA-256 和记录数;全部一致后确认接收,并生成独立分析快照。", + roles: ["校级技术管理员"], + fields: [ + ["tenantId", "租户标识", "text", CLOSED_LOOP_SHARED.tenantId], + ["packageId", "数据包编号", "text", CLOSED_LOOP_SHARED.packageId], + ["packageVersion", "数据包版本", "text", CLOSED_LOOP_SHARED.packageVersion], + ["checkedRecords", "交付包记录数", "number", String(CLOSED_LOOP_SHARED.packageRecords)], + ["sha256", "完整 SHA-256 摘要", "text", CLOSED_LOOP_SHARED.packageSha256], + ["note", "技术接收说明", "textarea", "包版本、记录数与SHA校验一致,授权关联率100%,允许进入分析快照。"], + ], + }, + decision: { + title: "专业建议决策", + description: "采纳、暂缓或驳回都必须填写理由;采纳后自动创建关联任务。", + roles: ["专业负责人"], + fields: [ + ["decision", "决策", "select", "采纳|暂缓|驳回"], + ["reason", "决策理由", "textarea", "企业需求与岗位样本相互印证,现有课程覆盖不足,纳入本期实训调整。"], + ["owner", "任务负责人", "text", "李雯"], + ["due", "任务截止日期", "date", "2026-12-20"], + ], + }, + project: { + title: "创建关联项目", + description: "项目自动绑定 demandId、recommendationId 与 taskId。", + roles: ["专业负责人"], + fields: [ + ["title", "项目名称", "text", "边缘计算测试真实项目进课堂"], + ["profession", "牵头专业", "text", "软件技术"], + ["owner", "项目负责人", "text", "李雯"], + ], + }, + evidence: { + title: "提交阶段进展与证据", + description: "保存证据名称、类型、说明、提交人、时间和文件名/链接;提交后自动更新任务和项目进度。", + roles: ["专业负责人", "学院负责人"], + fields: [ + ["name", "证据名称", "text", "边缘计算测试实训方案"], + ["type", "证据类型", "select", "课程方案|阶段成果|评审纪要|学生作品"], + ["description", "证据说明", "textarea", "已完成企业任务拆解、课程映射和中期评价量规。"], + ["submitter", "提交人", "text", "李雯 · 软件技术专业"], + ["fileRef", "文件名或链接", "text", "边缘计算测试实训方案-v1.0.pdf"], + ["progress", "本次完成进度", "number", "80"], + ], + }, + evaluation: { + title: "提交企业评价", + description: "企业导师只能评价本企业关联对象;通过或需整改均须填写意见。", + roles: ["企业导师"], + fields: [ + ["result", "评价结论", "select", "通过|需整改"], + ["comment", "评价意见", "textarea", "任务覆盖真实设备测试流程,验收量规清晰,同意进入校级验收。"], + ], + }, + acceptance: { + title: "校级任务验收", + description: "校级管理者在企业评价后验收或退回任务,并记录意见。", + roles: ["校级管理者"], + fields: [ + ["result", "验收结论", "select", "验收通过|退回整改"], + ["comment", "验收意见", "textarea", "企业评价、课程方案和过程证据齐全,同意完成。"], + ], + }, + reportCreate: { + title: "生成闭环报告草稿", + description: "报告关联需求、快照、任务和全部证据,生成后进入真实审批流。", + roles: ["专业负责人", "学院负责人", "校级管理者"], + fields: [["title", "报告名称", "text", "边缘计算测试人才共育闭环报告"]], + }, + reportSubmit: { + title: "提交报告审核", + description: "草稿提交后进入待审核状态。", + roles: ["专业负责人", "学院负责人", "校级管理者"], + fields: [["comment", "提交说明", "textarea", "闭环实体与证据已核对,请校级管理者审核。"]], + }, + reportReview: { + title: "报告审批", + description: "只有校级管理者可批准或退回业务报告;审批人必须与本次提交人分离。", + roles: ["校级管理者"], + fields: [ + ["result", "审批结论", "select", "批准|退回"], + ["approver", "独立审批人", "select", "刘嘉禾 · 校级管理者|周明远 · 校级管理者"], + ["comment", "审批意见", "textarea", "实体关联、数据口径和验收记录完整,同意批准。"], + ], + }, + reportPublish: { + title: "正式发布报告", + description: "只有已批准报告可正式发布;发布后下载和导出才标识为正式版。", + roles: ["校级管理者"], + fields: [["comment", "发布说明", "textarea", "作为本期校园闭环正式报告发布。"]], + }, + feedback: { + title: "记录就业侧使用反馈", + description: "就业老师确认数据对就业业务是否可用,并登记下一周期关注项。", + roles: ["就业老师"], + fields: [ + ["usable", "业务确认", "select", "可用|需补充"], + ["department", "使用部门", "text", "就业处"], + ["comment", "使用反馈", "textarea", "岗位技能标签可用于就业指导课程和重点企业岗位推荐。"], + ["nextCycle", "下一周期关注", "textarea", "补充学生项目作品与就业岗位匹配率。"], + ], + }, + review: { + title: "下一周期复核", + description: "保存前后指标与改善结论,并决定关闭或进入下一周期。", + roles: ["专业负责人"], + fields: [ + ["before", "前周期指标", "number", "32"], + ["after", "本周期指标", "number", "68"], + ["conclusion", "复核结论", "select", "改善|无变化|恶化"], + ["decision", "周期决定", "select", "关闭|进入下一周期"], + ["comment", "复核说明", "textarea", "云原生与边缘测试课程覆盖率明显提升,企业评价通过。"], + ], + }, +}; + +function actionPrerequisite(action) { + const e = closedLoopState.entities; + const role = currentRoleName(); + const allowed = closedLoopActionCatalog[action]?.roles.includes(role); + if (!allowed) return { enabled: false, reason: "当前角色无此动作权限。" }; + const checks = { + demand: [ + e.snapshot.status === "待接收" && !e.task && !e.report, + e.snapshot.status !== "待接收" ? "技术接收后需求版本已锁定;后续变更必须创建新版本并重新接收。" : "已有下游任务或报告,当前需求版本不可原地修改。", + ], + receive: [e.demand.status === "已提交" && e.snapshot.status !== "已验收", e.snapshot.status === "已验收" ? "技术接收与快照验收已完成。" : "需先由企业提交完整需求。"], + decision: [e.snapshot.status === "已验收" && e.recommendation.status !== "已采纳", e.recommendation.status === "已采纳" ? "建议已采纳并创建关联任务。" : "需先完成数据接收并生成已验收快照。"], + project: [Boolean(e.task && !e.project), e.project ? "关联项目已创建。" : "需先采纳建议并自动创建任务。"], + evidence: [ + Boolean(e.task && e.project && ["进行中", "需整改", "已退回"].includes(e.task.status) && !e.report), + e.report ? "报告版本已生成,当前任务证据已冻结;新增证据必须进入下一周期或重开新版本。" : e.task?.status === "已完成" ? "任务已完成校级验收,不能继续追加当前版本证据。" : "需先创建处于执行或整改状态的关联任务和项目。", + ], + evaluation: [ + e.evidences.length > 0 && e.task?.progress === 100 && e.project?.progress === 100 && e.demand.enterpriseId === "ENT-HKVS" && e.task?.status !== "已完成", + e.task?.status === "已完成" + ? "任务已完成校级验收,无需重复评价。" + : e.evidences.length === 0 + ? "需先有本企业项目执行证据。" + : "阶段进度必须达到100%后才能提交企业评价。", + ], + acceptance: [e.evaluation?.result === "通过" && e.task?.status === "待验收", e.evaluation?.result === "需整改" ? "企业评价为需整改,必须先补充证据并重新评价。" : "未有企业通过评价时任务不能申请校级验收。"], + reportCreate: [e.task?.status === "已完成" && !e.report, e.report ? "闭环报告已生成。" : "需先通过校级任务验收。"], + reportSubmit: [e.report?.status === "草稿" || e.report?.status === "已退回", "仅草稿或已退回报告可提交审核。"], + reportReview: [e.report?.status === "待审核", "仅待审核报告可审批。"], + reportPublish: [ + e.report?.status === "已批准" && Boolean(e.report.approvedBy) && e.report.approvedBy !== e.report.submittedBy, + "正式发布前必须由不同于提交人的校级管理者批准报告。", + ], + feedback: [e.report?.status === "已发布", "需先正式发布报告。"], + review: [e.usageFeedback.length > 0, "需先形成就业侧数据使用反馈。"], + }; + const [enabled, reason] = checks[action] || [false, "动作不可用。"]; + return { enabled, reason: enabled ? "前置条件已满足。" : reason }; +} + +function renderClosedLoopAction(action, label) { + const availability = actionPrerequisite(action); + return ``; +} + +function renderClosedLoop() { + const root = document.getElementById("loopChain"); + if (!root) return; + const e = closedLoopState.entities; + document.getElementById("loopSchemaBadge").textContent = `SCHEMA V${closedLoopState.schemaVersion}`; + document.getElementById("loopIdentityStrip").innerHTML = ` + 共享业务标识对照 + 租户 ${closedLoopState.shared.tenantId} + 厂商包 ${closedLoopState.shared.packageId} + 版本 ${closedLoopState.shared.packageVersion} + 学校回执 ${closedLoopState.shared.receiptId} + 静态原型仅用相同标识核对业务链,不代表厂商端与校园端页面实时同步。`; + const stages = [ + ["需求", e.demand.id, e.demand.status], + ["快照", e.snapshot.id, e.snapshot.status], + ["建议", e.recommendation.id, e.recommendation.status], + ["任务", e.task?.id || "TSK-待创建", e.task?.status || "未创建"], + ["项目", e.project?.id || "PRJ-待创建", e.project?.status || "未创建"], + ["证据", e.evidences.at(-1)?.id || "EVD-待提交", e.evidences.length ? `已提交 ${e.evidences.length} 项` : "未提交"], + ["企业评价", e.evaluation?.id || "EVL-待提交", e.evaluation?.result || "未评价"], + ["报告", e.report?.id || "RPT-待生成", e.report?.status || "未生成"], + ["反馈/复核", e.review?.id || e.usageFeedback.at(-1)?.id || e.receipt.id, e.review?.decision || (e.usageFeedback.length ? "已反馈" : e.receipt.status)], + ]; + root.innerHTML = stages + .map( + ([label, id, status], index) => + `
${String(index + 1).padStart(2, "0")}${label}${safeText(id)}${safeText(status)}
`, + ) + .join(""); + const evidence = e.evidences.at(-1); + const feedback = e.usageFeedback.at(-1); + document.getElementById("loopEntityGrid").innerHTML = ` +
企业需求 · ${e.demand.id}${safeText(e.demand.position)} · ${e.demand.headcount}人技能:${safeText(e.demand.skills)}授权:${safeText(e.demand.authorizationNo)} · 至 ${e.demand.validUntil}提交:${safeText(e.demand.submitter)} · ${e.demand.submittedAt}
+
分析快照 · ${e.snapshot.id}${e.snapshot.status} · ${e.snapshot.checkedRecords.toLocaleString("zh-CN")} / ${e.snapshot.expectedRecords.toLocaleString("zh-CN")} 条${e.snapshot.packageId} / ${e.snapshot.packageVersion}包回执:${e.receipt.receivedRecords.toLocaleString("zh-CN")} / ${e.receipt.expectedRecords.toLocaleString("zh-CN")} 条SHA ${safeText(e.receipt.receivedSha256 || e.receipt.expectedSha256)}技术接收:${safeText(e.snapshot.operator || "待确认")}
+
专业建议 · ${e.recommendation.id}${safeText(e.recommendation.title)}${e.recommendation.status} · ${safeText(e.recommendation.reason || "待填写决策理由")}${safeText(e.recommendation.operator || "待专业负责人决策")}
+
任务 / 项目${safeText(e.task?.id || "待创建")} / ${safeText(e.project?.id || "待创建")}任务进度 ${e.task?.progress || 0}% · ${safeText(e.task?.status || "未创建")}绑定:${safeText(e.project?.demandId || "-")} / ${safeText(e.project?.recommendationId || "-")} / ${safeText(e.project?.taskId || "-")}
+
最新证据 / 企业评价${safeText(evidence?.id || "暂无证据")} / ${safeText(e.evaluation?.id || "暂无评价")}${safeText(evidence ? `${evidence.name} · ${evidence.type} · ${evidence.fileRef}` : "提交证据后自动更新进度")}${safeText(e.evaluation ? `${e.evaluation.result} · ${e.evaluation.comment}` : "企业导师仅可评价本企业对象")}
+
报告 / 回执 / 使用反馈${safeText(e.report?.id || "待生成")} · ${safeText(e.report?.status || "未生成")}${e.receipt.id} · ${e.receipt.status}${safeText(feedback ? `${feedback.department}:${feedback.usable} · ${feedback.comment}` : "就业老师尚未登记使用反馈")}
`; + + const role = currentRoleName(); + const boundary = { + 校级管理者: "可校级验收、报告批准/退回与正式发布;不代替技术接收或专业决策。", + 校级技术管理员: "负责包接收、SHA/记录数质量校验与快照验收;不能批准业务报告。", + 学院负责人: "可提交项目阶段证据、生成和提交报告;校级审批权不可用。", + 专业负责人: "可决策专业建议、推进任务项目、提交证据并完成周期复核。", + 就业老师: "可登记就业侧数据使用反馈;不能审批校级报告。", + 企业导师: "仅可提交和评价海康威视 ENT-HKVS 的需求、项目和任务对象。", + 厂商超级管理员: "校园闭环只读;共享标识用于静态原型业务对照,不构成实时同步。", + }; + document.getElementById("loopRoleActionTitle").textContent = `${role}下一步`; + document.getElementById("loopRoleBoundary").innerHTML = `权限边界

${boundary[role]}

`; + const actionLabels = { + demand: "提交 / 更新本企业需求", + receive: "确认包与需求接收", + decision: "决策专业建议", + project: "创建关联项目", + evidence: "提交进展与证据", + evaluation: "提交企业评价", + acceptance: "校级验收 / 退回", + reportCreate: "生成闭环报告草稿", + reportSubmit: "提交报告审核", + reportReview: "批准 / 退回报告", + reportPublish: "正式发布报告", + feedback: "登记就业使用反馈", + review: "下一周期复核", + }; + const roleActions = { + 企业导师: ["demand", "evaluation"], + 校级技术管理员: ["receive"], + 专业负责人: ["decision", "project", "evidence", "reportCreate", "reportSubmit", "review"], + 学院负责人: ["evidence", "reportCreate", "reportSubmit"], + 校级管理者: ["acceptance", "reportCreate", "reportSubmit", "reportReview", "reportPublish"], + 就业老师: ["feedback"], + 厂商超级管理员: [], + }[role] || []; + document.getElementById("loopActionList").innerHTML = + roleActions.map((action) => renderClosedLoopAction(action, actionLabels[action])).join("") || + `
当前为只读视角请切换到校园业务角色验证闭环动作。
`; + document.getElementById("loopAuditCount").textContent = `${closedLoopState.auditEvents.length} 条`; + document.getElementById("loopAuditList").innerHTML = closedLoopState.auditEvents + .slice(0, 18) + .map( + (event) => + `${safeText(event.action)} · ${safeText(event.objectId)}${safeText(event.operator)} · ${safeText(event.at)}${safeText(event.detail)}`, + ) + .join(""); +} + +function openClosedLoopAction(action) { + const config = closedLoopActionCatalog[action]; + const availability = actionPrerequisite(action); + if (!config || !availability.enabled) { + showToast(availability.reason, "前置条件未满足"); + return; + } + const e = closedLoopState.entities; + const receiveDefaults = { + tenantId: e.receipt.tenantId, + packageId: e.receipt.packageId, + packageVersion: e.receipt.packageVersion, + checkedRecords: e.receipt.receivedRecords || e.receipt.expectedRecords, + sha256: e.receipt.receivedSha256 || e.receipt.expectedSha256, + }; + const existingByAction = { + demand: e.demand, + receive: e.receipt, + decision: e.recommendation, + project: e.project || {}, + evidence: {}, + evaluation: e.evaluation || {}, + acceptance: {}, + reportCreate: e.report || {}, + reportSubmit: {}, + reportReview: {}, + reportPublish: {}, + feedback: {}, + review: e.review || {}, + }[action]; + document.getElementById("closedLoopModalKicker").textContent = `CLOSED LOOP · ${action.toUpperCase()}`; + document.getElementById("closedLoopModalTitle").textContent = config.title; + document.getElementById("closedLoopModalDescription").textContent = config.description; + document.getElementById("closedLoopForm").dataset.action = action; + document.getElementById("closedLoopFields").innerHTML = config.fields + .map(([name, label, type, fallback]) => { + const existingValue = action === "receive" ? receiveDefaults[name] : existingByAction?.[name]; + const value = existingValue ?? fallback; + if (type === "textarea") return ``; + if (type === "select") { + return ``; + } + return ``; + }) + .join(""); + openModal(document.getElementById("closedLoopModal")); +} + +function applyClosedLoopAction(action, values) { + const e = closedLoopState.entities; + const at = nowText(); + if (action === "demand") { + Object.assign(e.demand, values, { headcount: Number(values.headcount), status: "已提交", submittedAt: at }); + addClosedLoopAudit("DEMAND_SUBMITTED", e.demand.id, `${values.position} · ${values.headcount}人 · ${values.authorizationNo}`); + } else if (action === "receive") { + Object.assign(e.receipt, { + status: "已技术确认", + receivedRecords: Number(values.checkedRecords), + receivedSha256: values.sha256, + note: values.note, + verification: { + tenantMatched: true, + packageMatched: true, + versionMatched: true, + recordCountMatched: true, + sha256Matched: true, + verifiedAt: at, + }, + technicalConfirmedBy: currentRoleUser(), + technicalConfirmedAt: at, + }); + Object.assign(e.snapshot, { + packageId: values.packageId, + packageVersion: values.packageVersion, + sha256: values.sha256, + sourcePackageRecords: Number(values.checkedRecords), + checkedRecords: e.snapshot.expectedRecords, + status: "已验收", + receivedAt: at, + acceptedAt: at, + operator: currentRoleUser(), + }); + addClosedLoopAudit( + "PACKAGE_RECEIVED_SNAPSHOT_ACCEPTED", + e.snapshot.id, + `${values.tenantId} · ${values.packageId} · ${values.packageVersion} · 交付 ${Number(values.checkedRecords).toLocaleString("zh-CN")} 条 · 分析快照 ${e.snapshot.checkedRecords.toLocaleString("zh-CN")} 条 · SHA ${values.sha256}`, + ); + } else if (action === "decision") { + Object.assign(e.recommendation, { + status: values.decision === "采纳" ? "已采纳" : values.decision, + reason: values.reason, + operator: currentRoleUser(), + decidedAt: at, + }); + addClosedLoopAudit("RECOMMENDATION_DECIDED", e.recommendation.id, `${values.decision} · ${values.reason}`); + if (values.decision === "采纳" && !e.task) { + e.task = { + id: "TSK-SOFTWARE-20260823-01", + status: "进行中", + title: e.recommendation.title, + profession: "软件技术", + owner: values.owner, + due: values.due, + progress: 10, + demandId: e.demand.id, + recommendationId: e.recommendation.id, + progressLogs: [{ at, operator: currentRoleUser(), progress: 10, detail: "建议采纳,任务自动创建。" }], + acceptanceHistory: [], + }; + addClosedLoopAudit("TASK_AUTO_CREATED", e.task.id, `由建议 ${e.recommendation.id} 自动创建。`); + } + } else if (action === "project") { + e.project = { + id: "PRJ-HKVS-20260823-01", + status: "进行中", + title: values.title, + profession: values.profession, + owner: values.owner, + progress: e.task?.progress || 10, + demandId: e.demand.id, + recommendationId: e.recommendation.id, + taskId: e.task.id, + createdAt: at, + }; + addClosedLoopAudit("PROJECT_CREATED", e.project.id, `绑定 ${e.demand.id} / ${e.recommendation.id} / ${e.task.id}`); + } else if (action === "evidence") { + const evidence = { + id: `EVD-HKVS-${String(++closedLoopState.sequences.evidence).padStart(2, "0")}`, + name: values.name, + type: values.type, + description: values.description, + submitter: values.submitter, + submittedAt: at, + fileRef: values.fileRef, + taskId: e.task.id, + projectId: e.project.id, + }; + e.evidences.push(evidence); + e.task.progress = Math.min(100, Number(values.progress)); + e.task.status = e.task.progress >= 100 ? "待评价" : "进行中"; + e.task.progressLogs.push({ at, operator: currentRoleUser(), progress: e.task.progress, detail: values.description }); + e.project.progress = e.task.progress; + e.project.status = e.task.progress >= 100 ? "待企业评价" : "进行中"; + addClosedLoopAudit("EVIDENCE_SUBMITTED", evidence.id, `${values.name} · ${values.fileRef} · 进度${e.task.progress}%`); + } else if (action === "evaluation") { + e.evaluation = { + id: "EVL-HKVS-20260823-01", + result: values.result, + comment: values.comment, + enterpriseId: "ENT-HKVS", + taskId: e.task.id, + projectId: e.project.id, + operator: currentRoleUser(), + at, + }; + e.task.status = values.result === "通过" ? "待验收" : "需整改"; + e.project.status = values.result === "通过" ? "待校级验收" : "需整改"; + addClosedLoopAudit("ENTERPRISE_EVALUATION_SUBMITTED", e.evaluation.id, `${values.result} · ${values.comment}`); + } else if (action === "acceptance") { + const passed = values.result === "验收通过"; + e.task.status = passed ? "已完成" : "已退回"; + e.project.status = passed ? "已验收" : "已退回"; + e.task.progress = passed ? 100 : Math.min(e.task.progress, 90); + e.project.progress = e.task.progress; + e.task.acceptanceHistory.push({ result: values.result, comment: values.comment, operator: currentRoleUser(), at }); + addClosedLoopAudit("SCHOOL_ACCEPTANCE_RECORDED", e.task.id, `${values.result} · ${values.comment}`); + } else if (action === "reportCreate") { + e.report = { + id: "RPT-HZVTC-20260823-01", + title: values.title, + status: "草稿", + demandId: e.demand.id, + snapshotId: e.snapshot.id, + taskId: e.task.id, + evidenceIds: e.evidences.map((item) => item.id), + createdBy: currentRoleUser(), + submittedBy: "", + approvedBy: "", + updatedAt: at, + history: [{ status: "草稿", comment: "关联闭环实体生成。", operator: currentRoleUser(), at }], + }; + addClosedLoopAudit("REPORT_DRAFT_CREATED", e.report.id, `关联 ${e.snapshot.id} / ${e.demand.id} / ${e.task.id} / ${e.evidences.length}项证据`); + } else if (action === "reportSubmit") { + e.report.status = "待审核"; + e.report.submittedBy = currentRoleUser(); + e.report.approvedBy = ""; + e.report.updatedAt = at; + e.report.history.push({ status: "待审核", comment: values.comment, operator: currentRoleUser(), at }); + addClosedLoopAudit("REPORT_SUBMITTED", e.report.id, values.comment); + } else if (action === "reportReview") { + e.report.status = values.result === "批准" ? "已批准" : "已退回"; + e.report.approvedBy = values.result === "批准" ? values.approver : ""; + e.report.updatedAt = at; + e.report.history.push({ status: e.report.status, comment: values.comment, operator: values.approver, at }); + addClosedLoopAudit("REPORT_REVIEWED", e.report.id, `${values.result} · ${values.approver} · ${values.comment}`, values.approver, "校级管理者"); + } else if (action === "reportPublish") { + e.report.status = "已发布"; + e.report.updatedAt = at; + e.report.history.push({ status: "已发布", comment: values.comment, operator: currentRoleUser(), at }); + addClosedLoopAudit("REPORT_PUBLISHED", e.report.id, values.comment); + } else if (action === "feedback") { + const feedback = { + id: `FBK-EMP-${String(++closedLoopState.sequences.feedback).padStart(2, "0")}`, + ...values, + operator: currentRoleUser(), + at, + reportId: e.report.id, + snapshotId: e.snapshot.id, + }; + e.usageFeedback.push(feedback); + e.receipt.businessUsable = values.usable === "可用"; + e.receipt.status = values.usable === "可用" ? "业务确认可用" : "业务要求补充"; + addClosedLoopAudit("DATA_USAGE_FEEDBACK_ADDED", feedback.id, `${values.department} · ${values.usable} · 下一周期:${values.nextCycle}`); + } else if (action === "review") { + e.review = { + id: "RVW-SOFTWARE-2027C1-01", + before: Number(values.before), + after: Number(values.after), + conclusion: values.conclusion, + decision: values.decision, + comment: values.comment, + operator: currentRoleUser(), + at, + }; + addClosedLoopAudit("NEXT_CYCLE_REVIEW_RECORDED", e.review.id, `${values.before}→${values.after} · ${values.conclusion} · ${values.decision}`); + } + saveAndRenderClosedLoop(`${closedLoopActionCatalog[action].title}已完成`); +} + +const reports = [ + { + id: "school-2026-03", + type: "school", + typeLabel: "校级报告", + title: "2026年春季全校产教供需分析总报告", + scope: "全校 32 个专业", + period: "2026年3月", + periodKey: "current", + pages: 42, + version: "V2026.03", + status: "已发布", + statusClass: "done", + updated: "今天 09:30", + author: "教务处 · 就业处", + roles: ["校级管理者"], + featured: true, + summary: + "本期全校供需匹配度为78.6分,较上一分析周期提升4.2分。智能制造、数字商贸和云平台方向需求增长明显,但云原生、工业视觉、跨境运营等技能仍存在结构性缺口。", + metrics: [ + { label: "供需匹配度", value: "78.6", note: "较上期 +4.2" }, + { label: "产业岗位样本", value: "18,420", note: "近90天 +12.8%" }, + { label: "重点技能缺口", value: "23", note: "8项高优先级" }, + { label: "改进完成率", value: "68%", note: "21/31项已完成" }, + ], + findings: [ + { title: "云平台与DevOps岗位快速增长", detail: "近90天需求增长31%,软件技术和云计算方向课程覆盖仍不足。", value: "+31%" }, + { title: "工业视觉成为智能制造新缺口", detail: "机器视觉相关需求增长38%,涉及机电、工业机器人等4个专业。", value: "+38%" }, + { title: "跨境电商人才需求由运营转向复合能力", detail: "企业更关注数据分析、内容生产和海外合规履约能力。", value: "6项缺口" }, + ], + bars: [ + { label: "信息技术类", value: 86 }, + { label: "智能制造类", value: 82 }, + { label: "数字商贸类", value: 75 }, + { label: "文化创意类", value: 72 }, + { label: "现代服务类", value: 69 }, + ], + actions: [ + { priority: "P0", title: "推动11个专业完成高优技能缺口响应", detail: "由教务处牵头,4月底前形成课程调整或实训项目方案。" }, + { priority: "P1", title: "建设工业视觉与云原生两类校企共享实训", detail: "优先对接大华、数梦工场等已表达合作意向的企业。" }, + { priority: "P1", title: "建立企业需求季度确认机制", detail: "区分互联网招聘信号与合作企业正式确认需求,提升决策可信度。" }, + ], + }, + { + id: "software-2026-03", + type: "profession", + typeLabel: "专业报告", + title: "软件技术专业人才需求分析报告", + scope: "信息工程学院 · 软件技术", + period: "2026年3月", + periodKey: "current", + pages: 28, + version: "V2026.03", + status: "已发布", + statusClass: "done", + updated: "今天 09:18", + author: "信息工程学院", + roles: ["校级管理者", "学院负责人"], + featured: true, + summary: + "软件技术专业供需匹配度84.2分,整体处于高匹配区间。Java后端和测试开发培养基础较好,云原生部署、AI辅助开发和数据工程能力是下一阶段课程建设重点。", + metrics: [ + { label: "专业匹配度", value: "84.2", note: "全校排名第3" }, + { label: "对口岗位需求", value: "2,864", note: "近90天 +18.6%" }, + { label: "课程技能覆盖", value: "76%", note: "31/41项已覆盖" }, + { label: "潜力合作企业", value: "12", note: "4家高意向" }, + ], + findings: [ + { title: "Java/Spring能力供需匹配良好", detail: "市场需求强度92%,课程覆盖86%,可继续保持项目化教学。", value: "差值6" }, + { title: "Docker/K8s形成明显技能缺口", detail: "市场需求81%,课程覆盖仅32%,缺口达到49个百分点。", value: "-49" }, + { title: "AI辅助开发进入企业基础要求", detail: "69%的重点岗位提出相关要求,当前课程覆盖仅28%。", value: "-41" }, + ], + bars: [ + { label: "Java / Spring", value: 92 }, + { label: "Python应用", value: 84 }, + { label: "Docker / K8s", value: 81 }, + { label: "数据库技术", value: 78 }, + { label: "AI辅助开发", value: 69 }, + ], + actions: [ + { priority: "P0", title: "强化云原生与容器化实训模块", detail: "在综合实训中覆盖Docker、Kubernetes、CI/CD和可观测性。" }, + { priority: "P1", title: "将AI辅助开发纳入软件工程实践", detail: "增加代码生成、测试辅助、安全审查和人工复核规范。" }, + { priority: "P1", title: "联合企业建设真实交付项目", detail: "引入数梦工场、海康威视的工程任务和企业导师评价。" }, + ], + }, + { + id: "college-info-2026-03", + type: "college", + typeLabel: "学院报告", + title: "信息工程学院供需分析与专业建设报告", + scope: "信息工程学院 · 6个专业", + period: "2026年3月", + periodKey: "current", + pages: 36, + version: "V2026.03", + status: "待审核", + statusClass: "review", + updated: "今天 08:55", + author: "信息工程学院", + roles: ["校级管理者", "学院负责人"], + summary: + "学院6个专业平均匹配度80.4分,软件技术、物联网应用技术表现较好。当前需要跨专业统筹云平台、数据工程和AI应用三类共享能力建设。", + metrics: [ + { label: "学院匹配度", value: "80.4", note: "较上期 +5.1" }, + { label: "覆盖专业", value: "6", note: "2个高匹配专业" }, + { label: "相关岗位", value: "6,120", note: "近90天样本" }, + { label: "合作企业", value: "38", note: "本学期新增6家" }, + ], + findings: [ + { title: "共享技术底座课程重复建设", detail: "数据库、Linux和软件工程内容在多个专业重复,可建设学院共享模块。", value: "6专业" }, + { title: "云平台能力成为共同短板", detail: "云部署、容器和运维能力在5个专业中均出现覆盖不足。", value: "5专业" }, + { title: "企业项目集中度偏高", detail: "前5家企业承担了61%的项目,需要扩展中型技术企业伙伴。", value: "61%" }, + ], + bars: [ + { label: "软件技术", value: 84 }, + { label: "物联网应用", value: 80 }, + { label: "大数据技术", value: 79 }, + { label: "人工智能技术", value: 78 }, + { label: "计算机网络", value: 75 }, + ], + actions: [ + { priority: "P0", title: "建立学院共享工程实践课程群", detail: "统一云平台、数据库、DevOps基础能力,按专业配置差异化项目。" }, + { priority: "P1", title: "扩展8家中型技术企业合作", detail: "降低项目来源集中度,为不同专业提供多样化真实任务。" }, + { priority: "P1", title: "建立跨专业学生项目团队", detail: "围绕智能物联场景组织软件、数据和网络方向联合实训。" }, + ], + }, + { + id: "gap-2026-03", + type: "industry", + typeLabel: "产业专题", + title: "杭州重点产业人才缺口专题报告", + scope: "杭州重点产业 · 全校专业", + period: "2026年3月", + periodKey: "current", + pages: 31, + version: "V2026.03", + status: "已发布", + statusClass: "done", + updated: "昨天 17:40", + author: "产教融合中心", + roles: ["校级管理者"], + summary: + "杭州区域人才需求持续向智能制造、云计算、跨境电商和数字内容方向集中。全校识别23项重点技能缺口,其中8项需要在本学期形成明确响应。", + metrics: [ + { label: "重点缺口", value: "23", note: "8项高优" }, + { label: "关联专业", value: "11", note: "覆盖5个学院" }, + { label: "相关企业", value: "326", note: "126家已确认" }, + { label: "岗位增长", value: "24.8%", note: "重点方向均值" }, + ], + findings: [ + { title: "工业视觉缺口最为紧迫", detail: "相关岗位增长38%,学校课程平均覆盖不足40%。", value: "+38%" }, + { title: "跨境运营强调数据与合规", detail: "单一平台运营能力已经不能满足企业复合岗位要求。", value: "83%需求" }, + { title: "云平台运维需求外溢到传统专业", detail: "智能制造和物联网岗位也开始要求设备上云与运维能力。", value: "7专业" }, + ], + bars: [ + { label: "工业视觉", value: 92 }, + { label: "云平台运维", value: 88 }, + { label: "跨境电商", value: 83 }, + { label: "数据工程", value: 79 }, + { label: "AI内容生产", value: 75 }, + ], + actions: [ + { priority: "P0", title: "针对8项高优缺口建立校级响应清单", detail: "明确对应学院、专业负责人、企业伙伴和阶段性交付物。" }, + { priority: "P1", title: "将企业确认数据纳入缺口复核", detail: "避免只依赖互联网招聘信息推断实际人才缺口。" }, + { priority: "P1", title: "每季度更新重点产业技能词典", detail: "由行业专家和专业负责人共同审核新增技能及映射关系。" }, + ], + }, + { + id: "salary-2026-03", + type: "industry", + typeLabel: "产业专题", + title: "2026届实习就业薪资竞争力分析", + scope: "全校2026届学生", + period: "2026年3月", + periodKey: "current", + pages: 24, + version: "V2026.03", + status: "已发布", + statusClass: "done", + updated: "昨天 16:20", + author: "就业处", + roles: ["校级管理者"], + summary: + "2026届学生就业薪资中位数为8,640元,达到区域同岗位中位数的98%。信息技术类专业高于区域基准,现代服务和文化创意类仍有提升空间。", + metrics: [ + { label: "就业薪资中位数", value: "8,640", note: "区域基准98%" }, + { label: "实习月薪中位数", value: "3,820", note: "同比 +8.4%" }, + { label: "高于市场专业", value: "12", note: "占全部37.5%" }, + { label: "有效薪资样本", value: "6,284", note: "完整度91.2%" }, + ], + findings: [ + { title: "软件技术薪资竞争力领先", detail: "应届岗位中位数达到区域同岗位的108%。", value: "1.08" }, + { title: "技能证据显著影响起薪", detail: "具备企业项目或高质量作品集的学生起薪平均高14%。", value: "+14%" }, + { title: "服务类专业薪资离散度较大", detail: "企业规模和岗位类型对薪资影响明显,需加强预期指导。", value: "差异32%" }, + ], + bars: [ + { label: "信息技术类", value: 108 }, + { label: "智能制造类", value: 102 }, + { label: "数字商贸类", value: 96 }, + { label: "文化创意类", value: 91 }, + { label: "现代服务类", value: 88 }, + ], + actions: [ + { priority: "P1", title: "将真实项目成果纳入就业推荐材料", detail: "强化学生技能证据,提升企业对岗位胜任力的判断效率。" }, + { priority: "P1", title: "建立分专业薪资预期指导", detail: "使用分位数而非平均数,为学生提供地域和岗位差异说明。" }, + { priority: "P2", title: "持续核验企业薪资数据完整性", detail: "对缺失和区间过宽的薪资记录降低统计权重。" }, + ], + }, + { + id: "quality-2026-03", + type: "quality", + typeLabel: "数据质量", + title: "2026年3月数据资产质量与口径报告", + scope: "3类数据资产 · 6个数据源", + period: "2026年3月", + periodKey: "current", + pages: 19, + version: "V2026.03", + status: "已发布", + statusClass: "done", + updated: "昨天 15:05", + author: "数据管理中心", + roles: ["校级管理者", "校级技术管理员"], + summary: + "本期分析快照包含128,642条有效记录,总体质量评分92.6。互联网基础数据包、校级数据和企业数据均保留独立权属与授权标识。", + metrics: [ + { label: "质量评分", value: "92.6", note: "达到分析阈值" }, + { label: "有效记录", value: "128,642", note: "去重后快照" }, + { label: "归一覆盖率", value: "94.8%", note: "218项待复核" }, + { label: "数据源", value: "6", note: "三类资产" }, + ], + findings: [ + { title: "就业薪资字段存在缺失", detail: "涉及86条记录,已在薪资结论中降低相关权重。", value: "86条" }, + { title: "岗位归一覆盖率达到分析要求", detail: "剩余218个新岗位名称进入人工审核队列。", value: "94.8%" }, + { title: "企业数据授权记录完整", detail: "126家合作企业均保留提交时间和授权场景。", value: "100%" }, + ], + bars: [ + { label: "完整性", value: 95 }, + { label: "准确性", value: 91 }, + { label: "及时性", value: 97 }, + { label: "一致性", value: 93 }, + { label: "归一覆盖", value: 95 }, + ], + actions: [ + { priority: "P0", title: "补齐就业薪资缺失记录", detail: "由就业处在本期正式材料发布前完成字段确认。" }, + { priority: "P1", title: "审核218个新增岗位名称", detail: "优先处理需求量前50的岗位,并沉淀别名规则。" }, + { priority: "P2", title: "增加数据包服务期自动提醒", detail: "基础数据包到期前30天通知厂商和学校管理员。" }, + ], + }, + { + id: "mechatronics-2026-03", + type: "profession", + typeLabel: "专业报告", + title: "机电一体化技术专业人才需求分析报告", + scope: "智能制造学院 · 机电一体化", + period: "2026年3月", + periodKey: "current", + pages: 27, + version: "V2026.03", + status: "已发布", + statusClass: "done", + updated: "2026-03-20", + author: "智能制造学院", + roles: ["校级管理者"], + summary: "机电一体化专业匹配度81.7分,PLC和设备调试基础扎实,工业视觉与设备数字孪生是主要技能缺口。", + metrics: [ + { label: "专业匹配度", value: "81.7", note: "较上期 +3.6" }, + { label: "对口岗位", value: "2,146", note: "近90天 +21%" }, + { label: "技能覆盖", value: "72%", note: "工业视觉不足" }, + { label: "潜力企业", value: "9", note: "3家高意向" }, + ], + findings: [ + { title: "PLC能力覆盖充足", detail: "课程覆盖88%,与企业岗位要求保持一致。", value: "88%" }, + { title: "工业视觉缺口扩大", detail: "岗位增长38%,课程覆盖仅38%。", value: "-44" }, + { title: "数字孪生进入设备岗位要求", detail: "龙头企业正在将相关能力纳入工程师岗位。", value: "+29%" }, + ], + bars: [ + { label: "PLC编程", value: 94 }, + { label: "工业机器人", value: 89 }, + { label: "机器视觉", value: 82 }, + { label: "数字孪生", value: 73 }, + { label: "电气制图", value: 68 }, + ], + actions: [ + { priority: "P0", title: "新增工业视觉综合实训", detail: "联合装备企业建设缺陷检测与产线集成任务。" }, + { priority: "P1", title: "引入数字孪生教学案例", detail: "将现有PLC实训映射到设备数据与仿真场景。" }, + ], + }, + { + id: "ecommerce-2026-03", + type: "profession", + typeLabel: "专业报告", + title: "电子商务专业人才需求分析报告", + scope: "商贸旅游学院 · 电子商务", + period: "2026年3月", + periodKey: "current", + pages: 26, + version: "V2026.03", + status: "待审核", + statusClass: "review", + updated: "2026-03-19", + author: "商贸旅游学院", + roles: ["校级管理者"], + summary: "电子商务专业匹配度74.8分,内容运营基础较好,跨境运营、数据分析和AI内容生产需要重点强化。", + metrics: [ + { label: "专业匹配度", value: "74.8", note: "待关注" }, + { label: "对口岗位", value: "1,932", note: "近90天 +13%" }, + { label: "技能覆盖", value: "68%", note: "6项明显缺口" }, + { label: "潜力企业", value: "15", note: "4家高意向" }, + ], + findings: [ + { title: "内容运营保持较高需求", detail: "相关岗位需求强度91%,课程覆盖76%。", value: "91%" }, + { title: "跨境平台运营覆盖不足", detail: "岗位增长34%,课程覆盖仅43%。", value: "-40" }, + { title: "AI内容生产成为新要求", detail: "75%的重点企业提出相关工具能力。", value: "75%" }, + ], + bars: [ + { label: "内容运营", value: 91 }, + { label: "数据分析", value: 86 }, + { label: "跨境运营", value: 83 }, + { label: "直播投放", value: 78 }, + { label: "AI内容生产", value: 75 }, + ], + actions: [ + { priority: "P0", title: "重构跨境电商平台运营课程", detail: "增加真实店铺、海外投放和合规履约任务。" }, + { priority: "P1", title: "增加AI营销内容生产工作流", detail: "纳入AI文案、图片、视频辅助生产与人工审核。" }, + ], + }, + { + id: "school-2025", + type: "school", + typeLabel: "校级报告", + title: "2025年度全校产教供需分析总报告", + scope: "全校 32 个专业", + period: "2025年度", + periodKey: "previous", + pages: 40, + version: "V2025.12", + status: "已归档", + statusClass: "review", + updated: "2025-12-28", + author: "教务处 · 就业处", + roles: ["校级管理者"], + summary: "2025年度全校供需匹配度为74.4分,初步识别云平台、工业视觉和跨境运营等重点建设方向。", + metrics: [ + { label: "供需匹配度", value: "74.4", note: "年度提升3.2" }, + { label: "岗位样本", value: "62,840", note: "全年累计" }, + { label: "技能缺口", value: "28", note: "12项高优" }, + { label: "合作企业", value: "108", note: "新增23家" }, + ], + findings: [ + { title: "数字技术需求增长最快", detail: "软件、数据与云平台岗位全年增长22%。", value: "+22%" }, + { title: "专业之间响应速度差异明显", detail: "已有9个专业启动课程调整,5个专业尚未响应。", value: "9/14" }, + ], + bars: [ + { label: "信息技术类", value: 82 }, + { label: "智能制造类", value: 77 }, + { label: "数字商贸类", value: 70 }, + { label: "文化创意类", value: 68 }, + ], + actions: [ + { priority: "P0", title: "建立周期性分析机制", detail: "从年度人工报告转向季度数据快照和任务跟踪。" }, + { priority: "P1", title: "完善岗位分类与技能词典", detail: "提高跨数据源岗位匹配和趋势比较的稳定性。" }, + ], + }, +]; + +const professionReportCatalog = [ + ["物联网应用技术", "信息工程学院", 79.5, "边缘计算与物联网集成"], + ["大数据技术", "信息工程学院", 78.9, "数据工程与实时计算"], + ["人工智能技术应用", "信息工程学院", 77.8, "模型应用与数据标注"], + ["计算机网络技术", "信息工程学院", 75.6, "云网络与安全运维"], + ["工业机器人技术", "智能制造学院", 82.3, "机器人集成与机器视觉"], + ["电气自动化技术", "智能制造学院", 80.8, "智能控制与设备联网"], + ["机械制造及自动化", "智能制造学院", 76.4, "数字化制造与精益生产"], + ["模具设计与制造", "智能制造学院", 68.4, "数字化设计与智能检测"], + ["新能源汽车技术", "智能制造学院", 83.1, "三电检测与智能诊断"], + ["汽车检测与维修技术", "智能制造学院", 74.9, "新能源汽车售后与诊断"], + ["跨境电子商务", "商贸旅游学院", 81.2, "海外投放与合规履约"], + ["国际商务", "商贸旅游学院", 73.6, "数字贸易与供应链协同"], + ["市场营销", "商贸旅游学院", 72.8, "数据营销与用户增长"], + ["现代物流管理", "商贸旅游学院", 78.1, "智慧物流与仓配优化"], + ["酒店管理与数字化运营", "商贸旅游学院", 71.5, "收益管理与数字化服务"], + ["旅游管理", "商贸旅游学院", 70.9, "文旅内容与目的地运营"], + ["会展策划与管理", "商贸旅游学院", 72.1, "数字会展与活动运营"], + ["建筑工程技术", "城市建设学院", 76.8, "BIM应用与智慧建造"], + ["工程造价", "城市建设学院", 75.2, "全过程造价与数字算量"], + ["市政工程技术", "城市建设学院", 73.7, "城市更新与工程数字化"], + ["环境艺术设计", "艺术设计学院", 74.6, "空间数字表达与项目交付"], + ["广告艺术设计", "艺术设计学院", 76.2, "品牌内容与AI视觉生产"], + ["动漫设计", "艺术设计学院", 78.4, "三维内容与实时渲染"], + ["数字媒体艺术设计", "艺术设计学院", 80.1, "交互设计与数字内容生产"], + ["学前教育", "教育学院", 77.2, "幼儿发展评估与数字资源"], + ["早期教育", "教育学院", 73.4, "家庭指导与托育服务"], + ["婴幼儿托育服务与管理", "教育学院", 79.3, "托育运营与健康照护"], + ["应用电子技术", "智能制造学院", 75.9, "嵌入式系统与智能硬件"], + ["云计算技术应用", "信息工程学院", 85.1, "云平台运维与DevOps"], +]; + +professionReportCatalog.forEach(([name, college, score, focus], index) => { + const demand = 820 + ((index * 173) % 1780); + const coverage = Math.max(58, Math.min(88, Math.round(score - 5 + (index % 5)))); + const gap = Math.max(8, Math.round(92 - coverage)); + const companyCount = 6 + (index % 10); + reports.push({ + id: `profession-auto-${index + 1}`, + type: "profession", + typeLabel: "专业报告", + title: `${name}专业人才需求分析报告`, + scope: `${college} · ${name}`, + period: "2026年3月", + periodKey: "current", + pages: 24 + (index % 6), + version: "V2026.03", + status: index % 9 === 0 ? "待审核" : "已发布", + statusClass: index % 9 === 0 ? "review" : "done", + updated: `2026-03-${String(18 - (index % 8)).padStart(2, "0")}`, + author: college, + roles: ["校级管理者"], + summary: `${name}专业供需匹配度${score}分。当前培养基础总体稳定,${focus}是下一阶段专业建设和校企协同的重点方向。`, + metrics: [ + { label: "专业匹配度", value: String(score), note: score >= 80 ? "高匹配" : score >= 74 ? "保持关注" : "需要改进" }, + { label: "对口岗位", value: demand.toLocaleString("zh-CN"), note: "近90天有效样本" }, + { label: "技能覆盖", value: `${coverage}%`, note: `${gap}个百分点缺口` }, + { label: "潜力企业", value: String(companyCount), note: `${2 + (index % 4)}家高意向` }, + ], + findings: [ + { title: `${focus}需求持续增长`, detail: `重点企业正在将相关能力纳入岗位要求,近90天需求信号保持上升。`, value: `+${16 + (index % 23)}%` }, + { title: "课程实践与企业任务仍有差距", detail: "现有课程具备基础知识覆盖,但真实场景、工具链和交付评价需要加强。", value: `-${gap}` }, + { title: "校企合作具备扩展条件", detail: `已识别${companyCount}家高匹配企业,可围绕项目实训和企业导师形成合作。`, value: `${companyCount}家` }, + ], + bars: [ + { label: "专业基础能力", value: Math.min(95, coverage + 8) }, + { label: focus.slice(0, 8), value: Math.min(94, coverage + 14) }, + { label: "工程实践", value: Math.max(55, coverage - 4) }, + { label: "数据与AI应用", value: Math.max(52, coverage - 9) }, + { label: "企业项目交付", value: Math.max(50, coverage - 12) }, + ], + actions: [ + { priority: "P0", title: `强化${focus}教学模块`, detail: "引入企业真实任务,明确工具链、过程产物和验收标准。" }, + { priority: "P1", title: "邀请企业导师参与课程评审", detail: `优先对接已识别的${companyCount}家潜力企业,核验岗位技能与课程映射。` }, + { priority: "P1", title: "建立学生能力证据档案", detail: "将项目作品、企业评价和技能达成情况纳入就业推荐材料。" }, + ], + }); +}); + +[ + ["智能制造学院", "6个专业", "工业视觉、数字孪生与设备联网"], + ["商贸旅游学院", "7个专业", "跨境运营、数字营销与智慧服务"], + ["城市建设学院", "3个专业", "BIM应用、智慧建造与城市更新"], + ["艺术设计与教育联合板块", "7个专业", "数字内容、AI创作与特色人才培养"], +].forEach(([name, scope, focus], index) => { + reports.push({ + id: `college-auto-${index + 1}`, + type: "college", + typeLabel: "学院报告", + title: `${name}供需分析与专业建设报告`, + scope: `${name} · ${scope}`, + period: "2026年3月", + periodKey: "current", + pages: 32 + index, + version: "V2026.03", + status: index === 3 ? "待审核" : "已发布", + statusClass: index === 3 ? "review" : "done", + updated: `2026-03-${18 - index}`, + author: name, + roles: ["校级管理者"], + summary: `${name}整体供需表现保持稳定,${focus}是跨专业共享能力建设的主要方向。`, + metrics: [ + { label: "学院匹配度", value: String(76.8 + index * 1.3), note: "较上期持续提升" }, + { label: "覆盖专业", value: scope.replace("个专业", ""), note: "全部纳入分析" }, + { label: "技能缺口", value: String(8 + index * 2), note: "跨专业统筹响应" }, + { label: "合作企业", value: String(26 + index * 7), note: "持续扩展" }, + ], + findings: [ + { title: `${focus}形成共同需求`, detail: "多个专业出现相近技能缺口,适合建设学院共享课程或实训平台。", value: "高关联" }, + { title: "企业项目分布仍需优化", detail: "建议降低头部企业集中度,引入更多中型和专精特新企业。", value: "待改善" }, + { title: "建议执行进入跟踪阶段", detail: "重点事项已明确负责人和周期,可纳入学院改进任务闭环。", value: "可执行" }, + ], + bars: [ + { label: "专业匹配", value: 80 + index }, + { label: "技能覆盖", value: 73 + index * 2 }, + { label: "企业合作", value: 76 + index }, + { label: "项目实践", value: 70 + index * 2 }, + ], + actions: [ + { priority: "P0", title: `建设${focus}共享模块`, detail: "明确学院统一底座和各专业差异化应用场景。" }, + { priority: "P1", title: "形成企业合作伙伴分层清单", detail: "区分课程共建、项目实训、实习就业和企业导师资源。" }, + { priority: "P1", title: "按月跟踪专业改进任务", detail: "对逾期、未响应和缺少证据的任务进行校院协同督办。" }, + ], + }); +}); + +const iconPaths = { + course: '', + lab: '', + practice: '', + database: '', + cloud: '', + file: '', + package: '', + school: '', + building: '', +}; + +function svgIcon(name, className = "") { + return ``; +} + +function formatNumber(value) { + return Number(value).toLocaleString("zh-CN"); +} + +function showToast(message, title = "操作成功") { + const region = document.getElementById("toastRegion"); + const toast = document.createElement("div"); + toast.className = "toast"; + toast.innerHTML = ` + + + + ${title}${message} + `; + region.appendChild(toast); + setTimeout(() => { + toast.classList.add("out"); + setTimeout(() => toast.remove(), 240); + }, 2600); +} + +function openModal(modal) { + modal.classList.add("open"); + modal.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; + setTimeout(() => { + const focusable = modal.querySelector("button, input, select, textarea"); + focusable?.focus(); + }, 100); +} + +function closeModal(modal) { + modal.classList.remove("open"); + modal.setAttribute("aria-hidden", "true"); + if (!document.querySelector(".modal-backdrop.open")) { + document.body.style.overflow = ""; + } +} + +function switchView(viewName) { + const view = document.getElementById(`view-${viewName}`); + if (!view) return; + + document.querySelectorAll(".view").forEach((item) => item.classList.remove("active")); + view.classList.add("active"); + document.querySelectorAll(".nav-item[data-view]").forEach((item) => { + item.classList.toggle("active", item.dataset.view === viewName); + }); + if (viewName !== "platform") { + document.querySelectorAll("[data-platform-target]").forEach((item) => item.classList.remove("active")); + } + document.getElementById("breadcrumbCurrent").textContent = view.dataset.title; + if (viewName === "reports") renderReportCenter(); + if (viewName === "loop") renderClosedLoop(); + document.body.classList.remove("sidebar-open"); + window.scrollTo({ top: 0, behavior: "smooth" }); +} + +function applyRole(role, options = {}) { + const { notify = true } = options; + const profile = roleProfiles[role] || roleProfiles.校级管理者; + const isPlatformRole = Boolean(profile.platform); + const isDataAdministrator = Boolean(profile.dataAdministrator); + + document.getElementById("roleName").textContent = role; + document.getElementById("roleUserName").textContent = profile.user; + document.getElementById("roleAvatar").textContent = profile.avatar; + document.getElementById("organizationName").textContent = profile.organization; + document.getElementById("organizationLabel").textContent = profile.organizationLabel; + document.getElementById("organizationEmblem").textContent = profile.emblem; + document.getElementById("breadcrumbRoot").textContent = profile.root; + document.getElementById("topbarContext").textContent = profile.context; + document.getElementById("workspaceNavLabel").textContent = profile.workspaceLabel; + document.getElementById("dataNavText").textContent = isDataAdministrator ? "数据运维中心" : "数据资产"; + document.getElementById("dataPageTitle").textContent = isDataAdministrator ? "学校数据运维中心" : "数据资产与质量"; + document.getElementById("dataPageDescription").textContent = isDataAdministrator + ? "管理学校数据源、初次导入、增量更新、字段契约、质量问题、版本与审计。" + : "区分厂商基础数据包、学校自有数据与企业授权数据,所有分析结论均可追溯。"; + document.getElementById("syncAllButtonText").textContent = isDataAdministrator ? "新建更新任务" : "同步全部数据"; + + document.getElementById("schoolNav").hidden = isPlatformRole; + document.getElementById("platformNav").hidden = !isPlatformRole; + document.getElementById("sidebarFooter").hidden = isPlatformRole || !profile.menus.includes("report"); + + document.querySelectorAll("[data-menu-key]").forEach((item) => { + item.hidden = !profile.menus.includes(item.dataset.menuKey); + }); + const hasDeliveryMenu = profile.menus.includes("report") || profile.menus.includes("screen"); + document.getElementById("deliveryNavLabel").hidden = !hasDeliveryMenu; + reportState.type = "all"; + reportState.period = "all"; + reportState.search = ""; + reportState.limit = 6; + + const collaborationHeading = document.getElementById("collaborationHeading"); + const collaborationDescription = document.getElementById("collaborationDescription"); + const demandButton = document.getElementById("enterpriseDemandButton"); + const projectButton = document.getElementById("newProjectButton"); + const collaborationStats = document.querySelector(".collab-stats"); + const renderCollaborationStats = (items) => { + collaborationStats.innerHTML = items + .map( + (item) => + `
${item.label}${item.value}${item.unit}${item.note}
`, + ) + .join(""); + }; + + if (role === "企业导师") { + collaborationHeading.textContent = "企业协同工作台"; + collaborationDescription.textContent = "提交真实岗位与技能需求,参与课程共建并评价学生项目成果。"; + demandButton.innerHTML = `${svgIcon("file")}提交企业需求`; + projectButton.innerHTML = `${svgIcon("course")}发起共建项目`; + renderCollaborationStats([ + { label: "已发布人才需求", value: "6", unit: "项", note: "2 项等待学校响应" }, + { label: "共建项目", value: "3", unit: "个", note: "全部按计划推进" }, + { label: "企业导师", value: "12", unit: "人", note: "本月授课 28 学时" }, + { label: "参与学生", value: "86", unit: "人", note: "企业评价 4.7 / 5" }, + ]); + } else if (role === "学院负责人" || role === "专业负责人") { + collaborationHeading.textContent = "学院校企协同"; + collaborationDescription.textContent = "围绕本院专业对接企业需求,推进课程共建、实训与企业导师协作。"; + demandButton.innerHTML = `${svgIcon("file")}邀请企业调研`; + projectButton.innerHTML = `${svgIcon("course")}新建协同项目`; + renderCollaborationStats([ + { label: "本院合作企业", value: "38", unit: "家", note: "本学期新增 6 家" }, + { label: "本院协同项目", value: "8", unit: "个", note: "3 个进行中" }, + { label: "企业导师", value: "21", unit: "人", note: "覆盖 6 个专业" }, + { label: "学生参与", value: "386", unit: "人次", note: "满意度 94%" }, + ]); + } else { + collaborationHeading.textContent = "校企协同中心"; + collaborationDescription.textContent = "把产业需求转化为可执行的课程、项目与人才共育计划。"; + demandButton.innerHTML = `${svgIcon("file")}发起需求调研`; + projectButton.innerHTML = `${svgIcon("course")}新建协同项目`; + renderCollaborationStats([ + { label: "在库合作企业", value: "126", unit: "家", note: "本学期新增 18 家" }, + { label: "本学期协同项目", value: "24", unit: "个", note: "8 个进行中" }, + { label: "企业导师", value: "68", unit: "人", note: "覆盖 17 个专业" }, + { label: "学生参与", value: "1,284", unit: "人次", note: "满意度 92%" }, + ]); + } + + renderClosedLoop(); + if (document.getElementById("professionSelect")) { + renderProfessionProfile(document.getElementById("professionSelect").value); + } + switchView(profile.defaultView); + if (isPlatformRole) { + document.querySelectorAll("#platformNav [data-platform-target]").forEach((item) => item.classList.remove("active")); + const firstPlatformItem = document.querySelector("#platformNav [data-platform-target]"); + firstPlatformItem?.classList.add("active"); + document.getElementById("breadcrumbCurrent").textContent = "平台总览"; + } + + if (notify) showToast(`工作台与数据权限已切换为“${role}”`, "角色已切换"); +} + +function renderSparkline(elementId, points, color = "#238765") { + const element = document.getElementById(elementId); + if (!element) return; + const width = 78; + const height = 28; + const max = Math.max(...points); + const min = Math.min(...points); + const range = max - min || 1; + const coords = points.map((point, index) => { + const x = (index / (points.length - 1)) * width; + const y = height - ((point - min) / range) * (height - 5) - 2; + return [x, y]; + }); + const line = coords.map(([x, y]) => `${x},${y}`).join(" "); + const area = `M ${coords[0][0]} ${height} L ${coords.map(([x, y]) => `${x} ${y}`).join(" L ")} L ${coords.at(-1)[0]} ${height} Z`; + element.innerHTML = ` + + + + + + `; +} + +function chartCoordinates(values, width, height, padding) { + const min = 60; + const max = 84; + return values.map((value, index) => { + const x = padding + (index / (values.length - 1)) * (width - padding * 2); + const y = height - padding - ((value - min) / (max - min)) * (height - padding * 2); + return [x, y]; + }); +} + +function renderTrendChart(period = "term") { + const data = trendSets[period]; + const svg = document.getElementById("lineChart"); + const width = 620; + const height = 220; + const padding = 18; + const schoolPoints = chartCoordinates(data.school, width, height, padding); + const benchmarkPoints = chartCoordinates(data.benchmark, width, height, padding); + const schoolLine = schoolPoints.map(([x, y]) => `${x},${y}`).join(" "); + const benchmarkLine = benchmarkPoints.map(([x, y]) => `${x},${y}`).join(" "); + const area = `M ${schoolPoints[0][0]} ${height - padding} L ${schoolPoints + .map(([x, y]) => `${x} ${y}`) + .join(" L ")} L ${schoolPoints.at(-1)[0]} ${height - padding} Z`; + + svg.innerHTML = ` + + + + + + + ${[35, 80, 125, 170].map((y) => ``).join("")} + + + + ${schoolPoints.map(([x, y], index) => ``).join("")} + ${data.score} + `; + document.getElementById("chartLabels").innerHTML = data.labels.map((label) => `${label}`).join(""); + document.getElementById("dialScore").textContent = data.score.toFixed(1); + document.getElementById("metricMatch").textContent = data.score.toFixed(1); + document.getElementById("dialValue").style.strokeDashoffset = `${389.6 * (1 - data.score / 100)}`; +} + +function renderProfessionTable(filter = "") { + const table = document.getElementById("professionTable"); + const keyword = filter.trim().toLowerCase(); + const filtered = professions.filter( + (item) => item.name.toLowerCase().includes(keyword) || item.college.toLowerCase().includes(keyword), + ); + table.innerHTML = filtered + .map((item) => { + const level = item.score >= 80 ? "high" : item.score >= 72 ? "mid" : "low"; + const gapLevel = item.gaps <= 3 ? "low" : item.gaps <= 5 ? "mid" : "high"; + const gapText = item.gaps <= 3 ? "轻微" : item.gaps <= 5 ? "关注" : "预警"; + return ` + + ${item.icon}${item.name} + ${item.college} + ${item.score} + ${formatNumber(item.demand)} 个 + ${gapText} · ${item.gaps}项 + ${item.trend >= 0 ? "↑" : "↓"} ${Math.abs(item.trend)}% + + + `; + }) + .join(""); + + table.querySelectorAll(".profession-row-action").forEach((button) => { + button.addEventListener("click", () => { + const key = professionData[button.dataset.profession] ? button.dataset.profession : "software"; + document.getElementById("professionSelect").value = key; + renderProfessionProfile(key); + switchView("profession"); + }); + }); +} + +function renderIndustryList() { + document.getElementById("industryList").innerHTML = industries + .map( + (item, index) => ` +
+ ${String(index + 1).padStart(2, "0")} + ${item.name} + +${item.growth}% +
+ `, + ) + .join(""); +} + +function skillGapClass(gap) { + if (gap > 30) return "high"; + if (gap > 12) return "mid"; + return "low"; +} + +function renderProfessionProfile(key) { + const data = professionData[key] || professionData.software; + document.getElementById("professionTitle").textContent = data.name; + document.getElementById("professionCollege").textContent = data.college; + document.getElementById("graduateCount").textContent = data.graduates; + document.getElementById("profileScore").textContent = data.score.toFixed(1); + document.getElementById("profileLevel").textContent = data.level; + document.getElementById("profileDemand").textContent = data.demand; + document.getElementById("profileSalary").textContent = data.salary; + document.getElementById("profileCoverage").textContent = data.coverage; + document.getElementById("profileCompanies").textContent = data.companyCount; + + document.getElementById("skillChart").innerHTML = data.skills + .map((skill) => { + const gap = skill.market - skill.course; + const state = gap > 30 ? "明显缺口" : gap > 12 ? "部分覆盖" : "覆盖良好"; + return ` +
+ ${skill.name}${skill.category} + + + + + ${gap > 0 ? `-${gap}` : `+${Math.abs(gap)}`}${state} +
+ `; + }) + .join(""); + + document.getElementById("jobDemandList").innerHTML = data.jobs + .map( + (job) => ` +
+
${job.name}${job.count}个 +${job.growth}%
+
+
+ `, + ) + .join(""); + + document.getElementById("courseRecommendations").innerHTML = data.recommendations + .map( + (recommendation, index) => ` +
+
+ ${recommendation.priority} + + ${recommendation.title} + ${key === "software" && index === 0 ? `${closedLoopState.entities.recommendation.id} · ${closedLoopState.entities.recommendation.status} · 快照 ${closedLoopState.entities.snapshot.id}` : ""} +

${recommendation.description}

+ + + 数据依据:${recommendation.evidence} + + + + + + +
+
+
+ `, + ) + .join(""); + + document.querySelectorAll(".recommendation-actions button").forEach((button) => { + button.addEventListener("click", () => { + const card = button.closest(".recommendation-card"); + const action = button.dataset.action; + if (key === "software" && Number(card.dataset.recommendation) === 0) { + if (currentRoleName() !== "专业负责人") { + showToast("仅专业负责人可保存专业建议决策,当前角色保持只读。", "权限不足"); + return; + } + openClosedLoopAction("decision"); + const decisionSelect = document.querySelector('#closedLoopFields select[name="decision"]'); + if (decisionSelect) decisionSelect.value = action === "accept" ? "采纳" : action === "hold" ? "暂缓" : "驳回"; + return; + } + if (action === "accept") { + const recommendation = data.recommendations[Number(card.dataset.recommendation)]; + const existingTask = tasks.some((task) => task.title === recommendation.title); + if (!existingTask) { + const task = { + id: `TSK-REC-${Date.now()}`, + title: recommendation.title, + source: `专业建议 · ${data.name} · 已关联数据证据`, + profession: data.name, + owner: "待确认", + due: "2026-06-30", + progress: 0, + status: "review", + statusText: "待确认", + }; + closedLoopState.custom.tasks.unshift(task); + addClosedLoopAudit("RECOMMENDATION_ACCEPTED_TASK_CREATED", task.id, `${data.name} · ${recommendation.title}`); + saveClosedLoopState(); + syncClosedLoopCollections(); + renderTasks(); + } + card.classList.add("accepted"); + button.textContent = "已采纳"; + button.disabled = true; + showToast(existingTask ? "该建议已在改进任务中,可前往任务中心查看" : "建议已加入改进任务,并关联专业分析证据"); + } else if (action === "hold") { + showToast("建议已标记为暂缓,下期分析时将再次提醒", "状态已更新"); + } else { + card.style.opacity = "0.52"; + showToast("建议已记录为不采纳,可在历史记录中恢复", "状态已更新"); + } + }); + }); + + document.getElementById("companyShortlist").innerHTML = data.companies + .map( + (company) => ` +
+ + ${company.name}${company.focus} + ${company.match}% +
+ `, + ) + .join(""); + + if (professionTabState !== "skills") renderProfessionDetailView(professionTabState); +} + +let professionTabState = "skills"; + +function professionEvidenceNote(code, text) { + return `
${code}

${text}

`; +} + +function renderProfessionJobsView(data) { + const totalJobs = data.jobs.reduce((sum, item) => sum + item.count, 0); + const regions = [ + { name: "杭州主城区", value: 46, count: Math.round(totalJobs * 0.46) }, + { name: "杭州区县与都市圈", value: 24, count: Math.round(totalJobs * 0.24) }, + { name: "长三角其他城市", value: 19, count: Math.round(totalJobs * 0.19) }, + { name: "其他地区", value: 11, count: Math.round(totalJobs * 0.11) }, + ]; + return ` +
+
+
岗位流向

专业人才对应岗位结构

近90天 · ${totalJobs.toLocaleString("zh-CN")}条
+
+
${data.name}${data.graduates}2026届毕业生
+
${data.jobs.map((job, index) => ``).join("")}
+
+ ${data.jobs + .map( + (job, index) => + `${String(index + 1).padStart(2, "0")}${job.name}${job.count}个 · 增长 ${job.growth}%`, + ) + .join("")} +
+
+
+
+
地域分布

岗位需求地区

+
+ ${regions.map((region) => `${region.name}${region.count}个 · ${region.value}%`).join("")} +
+
+
+
企业结构

岗位来源企业

+
+ 龙头企业34% · 976个岗位 + 专精特新与成长型企业42% · 1,203个岗位 + 其他有效企业24% · 685个岗位 +
+
+
+ ${professionEvidenceNote("证据 PRO-JOB-301", `岗位流向基于区域招聘基础包去重岗位、学校近三届就业去向及合作企业确认记录。互联网岗位反映需求信号,不等于实际录用人数。`)} + `; +} + +function renderProfessionSalaryView(data) { + const salaryByKey = { + 软件技术: { school: 8640, region: 8010, peer: 8230, p25: 7200, p75: 10800, samples: 628 }, + 机电一体化技术: { school: 7920, region: 7540, peer: 7680, p25: 6800, p75: 9600, samples: 512 }, + 电子商务: { school: 6980, region: 7280, peer: 7160, p25: 5800, p75: 8500, samples: 706 }, + }; + const salary = salaryByKey[data.name]; + const max = 12000; + const comparisons = [ + ["本专业就业中位数", salary.school, "school"], + ["区域同岗位中位数", salary.region, "region"], + ["同类院校专业中位数", salary.peer, "peer"], + ]; + return ` +
+
+
薪资对标

就业薪资竞争力与分位数

竞争力指数 ${data.salary}
+
+ ${comparisons + .map( + ([label, value, tone]) => + `${label}¥ ${value.toLocaleString("zh-CN")}`, + ) + .join("")} +
+
+ P25¥ ${salary.p25.toLocaleString("zh-CN")} + + P75¥ ${salary.p75.toLocaleString("zh-CN")} +
+
+
+
样本口径

有效薪资样本

+
${salary.samples}条完整就业薪资记录缺失、异常区间和无法匹配岗位的记录已剔除或降权。
+
+
+
影响因素

技能证据与起薪

+
+ +14%企业真实项目经历 + +9%高质量作品集 + +7%企业导师评价 +
+
+
+ ${professionEvidenceNote("证据 PRO-SAL-302", `薪资对标使用${salary.samples}条完整校内就业回执与区域同岗位样本,按中位数比较并控制地区、岗位层级和企业规模差异。`)} + `; +} + +function renderProfessionCoursesView(data) { + const courseNames = { + 软件技术: ["Java企业级开发", "Web前端工程实践", "云原生综合实训", "数据库应用", "软件工程项目"], + 机电一体化技术: ["PLC控制技术", "工业机器人应用", "机器视觉实训", "设备数字孪生", "电气设计"], + 电子商务: ["电商运营实务", "内容营销", "跨境平台运营", "直播投放", "数据化经营"], + }; + const courses = courseNames[data.name]; + return ` +
+
+
课程映射

课程—产业技能覆盖矩阵

充分覆盖 部分覆盖 待补强
+
+ + ${data.skills.map((skill) => ``).join("")} + + ${courses + .map((course, row) => { + const cells = data.skills + .map((skill, column) => { + const score = Math.max(18, Math.min(96, skill.course + ((row * 17 + column * 11) % 35) - 18)); + const level = score >= 72 ? "full" : score >= 45 ? "partial" : "gap"; + return ``; + }) + .join(""); + return `${cells}`; + }) + .join("")} + +
课程 / 技能${skill.name}调整建议
${score}
${course}${row < 2 ? "专业核心课" : row === 2 ? "综合实训" : "专业方向课"}
+
+
+
+
覆盖统计

技能映射质量

+
${data.coverage}课程技能覆盖率课程标准、实训任务和考核要求均参与映射。
+
+
+
优先调整

高需求低覆盖能力

+
${data.skills + .map((skill) => ({ ...skill, gap: skill.market - skill.course })) + .sort((a, b) => b.gap - a.gap) + .slice(0, 3) + .map((skill, index) => `${String(index + 1).padStart(2, "0")}${skill.name}需求 ${skill.market} · 覆盖 ${skill.course} · 缺口 ${skill.gap}`) + .join("")}
+
+
+ ${professionEvidenceNote("证据 PRO-CRS-303", `矩阵由课程标准、教学任务、实训产物和考核要求映射至版本化技能词典。文字出现不等于学生达成,仍需结合项目作品和企业评价。`)} + `; +} + +function renderProfessionDetailView(tab) { + const key = document.getElementById("professionSelect").value; + const data = professionData[key] || professionData.software; + const renderers = { + jobs: renderProfessionJobsView, + salary: renderProfessionSalaryView, + courses: renderProfessionCoursesView, + }; + document.getElementById("professionDetailView").innerHTML = renderers[tab](data); +} + +function renderProjects(filter = "all") { + const toneClass = { green: "", amber: "amber", blue: "blue" }; + const filteredProjects = + filter === "all" + ? projects + : projects.filter((project) => (filter === "practice" ? project.type === "practice" || project.type === "lab" : project.type === filter)); + document.getElementById("projectList").innerHTML = filteredProjects + .map( + (project) => ` +
+ ${svgIcon(project.type)} + ${project.title}${project.id ? `${project.id} · ${project.status || "进行中"} · ` : ""}${project.meta} + ${project.partners.map((partner) => `${partner}`).join("")} + 项目进度 ${project.progress}% + +
+ `, + ) + .join(""); + if (!filteredProjects.length) { + document.getElementById("projectList").innerHTML = `
当前分类暂无项目可以新建项目或切换其他分类。
`; + } +} + +function renderDemands() { + document.getElementById("enterpriseDemandList").innerHTML = enterpriseDemands + .map( + (demand) => ` +
+
+ ${demand.company}${demand.industry} + ${demand.status || "待响应"} +
+ ${demand.title} + ${demand.id ? `${demand.id}` : ""} +

${demand.description}

+
${demand.due}
+
+ `, + ) + .join(""); + + document.querySelectorAll("[data-demand]").forEach((button) => { + button.addEventListener("click", () => { + openWorkspaceDetail("demand", button.dataset.demandId || button.dataset.demand); + }); + }); +} + +function renderPartners(filter = "all") { + const categoryByPartner = { + 吉利汽车: "智能制造", + 大华股份: "智能制造", + 数梦工场: "数字技术", + 遥望科技: "现代服务", + }; + const filteredPartners = filter === "all" ? partners : partners.filter((partner) => categoryByPartner[partner.name] === filter); + document.getElementById("partnerGrid").innerHTML = filteredPartners + .map( + (partner) => ` +
+
+ + ${partner.name}${partner.industry} +
+

${partner.reason}

+
${partner.tags.map((tag) => `${tag}`).join("")}
+
${partner.match}% 匹配
+
+ `, + ) + .join(""); + + document.querySelectorAll("[data-connect]").forEach((button) => { + button.addEventListener("click", () => { + openWorkspaceDetail("partner", button.dataset.connect); + }); + }); +} + +function renderTasks(filter = "all", search = "") { + const keyword = search.trim().toLowerCase(); + const filtered = tasks.filter((task) => { + const matchesFilter = + filter === "all" || + task.status === filter || + (filter === "progress" && task.status === "risk"); + const matchesSearch = `${task.title}${task.profession}${task.owner}`.toLowerCase().includes(keyword); + return matchesFilter && matchesSearch; + }); + + document.getElementById("taskTable").innerHTML = filtered + .map( + (task) => ` + + ${task.title}${task.id ? `${task.id} · ` : ""}${task.source} + ${task.profession} + ${task.owner.slice(0, 1)}${task.owner} + ${task.due} + ${task.progress}% + ${task.statusText} + + + `, + ) + .join(""); + + if (!filtered.length) { + document.getElementById("taskTable").innerHTML = `没有找到符合条件的任务`; + } +} + +const dataOpsState = { + context: "source", + sourceName: sources[0].name, + tab: "overview", + issue: null, +}; + +const dataIssueCatalog = { + "salary-missing": { + title: "就业系统薪资字段缺失", + level: "阻断发布", + sourceName: "就业管理系统", + affected: "86 条记录 · 电子商务专业 41 条、现代服务类专业 45 条", + reason: "employment_salary 为空,未达到必填完整率 95% 的发布阈值。", + action: "由就业处补齐薪资或填写缺失原因,修复文件按 student_id + cohort 回写后重新校验。", + }, + "job-normalization": { + title: "新增岗位名称待归一", + level: "需要复核", + sourceName: "区域招聘岗位基础包", + affected: "218 个岗位别名 · 影响 1,426 条招聘记录", + reason: "新增“具身智能应用工程师”等岗位未映射到当前岗位分类词典 V3.2。", + action: "优先审核需求量前 50 的岗位名称,确认标准岗位、技能标签及别名规则。", + }, + "enterprise-duplicate": { + title: "疑似重复企业记录", + level: "一般事项", + sourceName: "企业确认需求库", + affected: "12 家企业 · 涉及 37 项岗位需求", + reason: "企业简称不同,但统一社会信用代码或工商地址高度相似。", + action: "由产教融合中心确认主企业记录,合并需求与授权回执并保留审计映射。", + }, +}; + +function currentDataSource() { + return sources.find((source) => source.name === dataOpsState.sourceName) || sources[0]; +} + +function dataOpsStat(label, value, note = "") { + return `${label}${value}${note ? `${note}` : ""}`; +} + +function renderDataOpsOverview(source) { + return ` +
+ ${dataOpsStat("当前版本", source.version, source.updateMode)} + ${dataOpsStat("业务截止日期", source.dataAsOf, `入库于 ${source.updated}`)} + ${dataOpsStat("质量评分", source.quality, `发布阈值 ${source.threshold.split(";")[0]}`)} + ${dataOpsStat("下次更新", source.nextUpdate, source.frequency)} +
+
+ 本次更新内容 + ${source.changeSummary} +

更新采用暂存校验机制,未通过质量门槛的数据进入隔离区,不会覆盖当前已发布版本。

+
+
+
+

更新与责任

+
+
数据类别
${source.categoryLabel} · ${source.commercial}
+
业务责任人
${source.steward}
+
技术责任人
${source.technicalOwner}
+
更新模式
${source.updateMode}
+
当前状态
${source.status}
+
+
+
+

质量与可用性

+
${source.quality}
+
    +
  • 主键、必填字段和代码合法性已执行自动校验
  • +
  • 授权缺失或已过期记录不得进入分析快照
  • +
  • 失败任务保留错误明细、操作者和追踪编号
  • +
+
+
+ `; +} + +function renderDataOpsRequirements(source) { + const fields = source.requiredFields.split("、"); + return ` +
+
数据契约${source.schema}${source.name}
+
支持格式${source.format}日期使用 ISO-8601 · 字符编码 UTF-8
+
主键要求${source.primaryKey}主键唯一率必须达到 100%
+
+
+

初次导入与增量更新要求

+
+ 01准备文件或连接支持标准模板导入,也可按更新频率配置 API、数据库视图或 SFTP。 + 02字段映射与样本预检确认主键、必填字段、代码字典和敏感字段处理规则。 + 03暂存与质量校验先写入暂存区,阻断性错误不覆盖生产版本。 + 04审批发布与留痕数据管理员确认质量和授权后,生成不可变版本并进入分析。 +
+
+
+

必填字段

+
${fields.map((field) => `${field}`).join("")}
+
+
+

验收门槛

+ + + + + + + + +
校验项门槛失败处理
主键唯一性100%整批阻断,下载冲突明细
必填完整性≥ 95%进入隔离区,修复后重试
代码与日期合法性≥ 98%错误记录不进入分析
综合质量${source.threshold}低于阈值不得发布
+
+ `; +} + +function renderDataOpsHistory(source) { + return ` +
+ ${source.warning ? "最近一次增量任务需要处理" : "最近一次更新任务已完成"} + ${source.warning ? "QUALITY_CHECK · 78%" : "PUBLISHED · 100%"} +
+
+
+ +
${source.version}${source.updated} · ${source.updateMode}

${source.changeSummary}

追踪编号 TRACE-${source.category.toUpperCase()}-20260322-01
+
+
+ +
上一稳定版本2026-03-17 · 已发布

当前分析快照仍引用该稳定版本,可随时回滚。

保留 180 天 · 完整性校验通过
+
+
+ +
初次导入2026-02-28 · FULL

完成字段映射、主键确认、授权登记与全量质量基线。

审批人:学校数据管理员 / 平台数据产品负责人
+
+
+
+

失败处理策略

+

网络失败从检查点自动重试 3 次;数据错误进入隔离区;主键冲突、授权缺失和 Schema 不兼容将整批阻断。历史已发布版本不原地覆盖。

+
+ `; +} + +function renderDataOpsAudit(source) { + const authorization = + source.category === "vendor" + ? "按学校租户、产品版本、用途和服务期限授权" + : source.category === "enterprise" + ? "绑定企业授权编号、合作用途、专业范围和有效期" + : "数据权属归学校,仅限本租户获授权角色使用"; + return ` +
+ 权属与授权${source.rights}

${authorization}

+
业务责任人${source.steward}技术责任人${source.technicalOwner}授权状态${source.status}
+
+
+

最近审计事件

+
+ 版本校验完成${source.updated} · 系统质量引擎 · TRACE-8F2A + 授权范围复核2026-03-18 16:22 · 数据管理员 · 审批通过 + 字段映射版本更新2026-03-17 14:08 · ${source.technicalOwner} · ${source.schema} +
+
+
+

访问与留存策略

+

敏感字段按角色脱敏,导入、导出、报告下载和权限变更均保留操作者、时间戳、前后版本哈希及追踪编号。授权撤回后立即停止后续分析使用。

+
+ `; +} + +function renderDataOpsUsage() { + const e = closedLoopState.entities; + return ` +
+ 接收回执${e.receipt.id} · ${e.receipt.status} +

${e.snapshot.packageId} / ${e.snapshot.packageVersion} 已接收状态:${e.snapshot.status}。共享业务标识仅用于静态原型对照,不表示两页面实时同步。

+
SHA校验${safeText(e.receipt.receivedSha256 || e.receipt.expectedSha256)}交付包记录数${e.receipt.receivedRecords.toLocaleString("zh-CN")} / ${e.receipt.expectedRecords.toLocaleString("zh-CN")}分析快照${e.snapshot.id} · ${e.snapshot.checkedRecords.toLocaleString("zh-CN")}条
+
+
+

业务支撑关系

+
+ 报告${e.report?.id || "待生成"} + 项目${e.project?.id || "待创建"} + 任务${e.task?.id || "待创建"} +
+
+
+

业务部门确认与下一周期反馈

+
+ ${e.usageFeedback + .map((item) => `${safeText(item.department)} · ${safeText(item.usable)} · ${safeText(item.id)}${safeText(item.operator)} · ${safeText(item.at)}${safeText(item.comment)};下一周期:${safeText(item.nextCycle)}`) + .join("") || `尚无业务使用反馈就业老师可在报告发布后登记。`} +
+
+ ${currentRoleName() === "就业老师" ? `` : ""} + ${currentRoleName() === "校级技术管理员" && e.snapshot.status !== "已验收" ? `` : ""} +
+
`; +} + +function renderDataIssue(issueKey) { + const issue = dataIssueCatalog[issueKey]; + return ` +
+ ${issue.level}

${issue.title}

${issue.affected}

+
+

规则命中原因

${issue.reason}

+

建议处置

${issue.action}

+
+

受影响分析

+
当前生产版本未覆盖分析快照沿用稳定版本责任部门${currentDataSource().steward}
+
+ `; +} + +function renderAddDataSource() { + return ` +
1选择方式2字段映射3质量规则4审批发布
+
+

新建学校数据源

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

初次导入交付清单

+
  • 标准模板或只读连接信息
  • 字段说明、主键、代码字典和样例数据
  • 业务截止日期、覆盖范围和责任人
  • 敏感字段清单、授权范围和留存期限
+
+ `; +} + +function renderAuthorizationOverview() { + return ` +
+ ${dataOpsStat("厂商基础包", "2 项授权", "服务期内可用")} + ${dataOpsStat("学校自有数据", "3 个数据源", "权属归学校")} + ${dataOpsStat("企业授权", "126 家", "12 项 30 日内到期")} +
+
+

授权使用矩阵

+ + + + + + + +
数据类别允许用途可见角色期限与退出
厂商基础数据包产业趋势、岗位与薪资分析校级管理者、学院负责人随订阅服务期,到期停止新分析
学校自有数据专业诊断、课程和就业分析按校内组织与最小权限学校自主留存与删除
企业授权数据人才需求确认、课程与项目共建约定学院、专业和项目成员撤权即时生效,到期自动停用
+
+
+

安全控制

+
租户隔离已启用敏感字段脱敏18 项规则导出审计完整留痕授权到期提醒提前 30 天
+
+ `; +} + +function updateDataOpsDrawer() { + const source = currentDataSource(); + const content = document.getElementById("dataOpsContent"); + const tabs = document.getElementById("dataOpsTabs"); + const footer = document.getElementById("dataOpsFooter"); + tabs.hidden = dataOpsState.context !== "source"; + + if (dataOpsState.context === "batch") { + document.getElementById("dataOpsKicker").textContent = "DATA UPDATE CENTER"; + document.getElementById("dataOpsTitle").textContent = "数据更新任务中心"; + document.getElementById("dataOpsDescription").textContent = "先确认业务截止日期、变更内容和质量门槛,再创建可追踪的更新任务。"; + content.innerHTML = ` +
${dataOpsStat("待更新", "2 个来源", "1个自动调度 · 1个人工导入")}${dataOpsStat("运行正常", "4 个来源", "最近24小时无失败")}${dataOpsStat("隔离记录", "86 条", "未进入生产版本")}
+
+

数据源更新计划

+
+ ${sources + .map( + (item) => ``, + ) + .join("")} +
+
+
+

执行策略

+
+
`; + footer.innerHTML = ``; + return; + } + + if (dataOpsState.context === "add") { + document.getElementById("dataOpsKicker").textContent = "DATA SOURCE ONBOARDING"; + document.getElementById("dataOpsTitle").textContent = "新增数据源"; + document.getElementById("dataOpsDescription").textContent = "支持标准模板直接导入,并可按业务需要配置自动增量连接。"; + content.innerHTML = renderAddDataSource(); + footer.innerHTML = ``; + return; + } + + if (dataOpsState.context === "authorization") { + document.getElementById("dataOpsKicker").textContent = "DATA AUTHORIZATION"; + document.getElementById("dataOpsTitle").textContent = "数据权属与授权中心"; + document.getElementById("dataOpsDescription").textContent = "统一管理用途、可见范围、服务期限、撤权和审计要求。"; + content.innerHTML = renderAuthorizationOverview(); + footer.innerHTML = ``; + return; + } + + if (dataOpsState.context === "issue") { + const issue = dataIssueCatalog[dataOpsState.issue]; + const issueSource = sources.find((item) => item.name === issue.sourceName); + if (issueSource) dataOpsState.sourceName = issueSource.name; + document.getElementById("dataOpsKicker").textContent = "DATA QUALITY WORKBENCH"; + document.getElementById("dataOpsTitle").textContent = issue.title; + document.getElementById("dataOpsDescription").textContent = "查看受影响数据、规则命中原因和可审计的处理流程。"; + content.innerHTML = renderDataIssue(dataOpsState.issue); + footer.innerHTML = ``; + return; + } + + document.getElementById("dataOpsKicker").textContent = `${source.categoryLabel.toUpperCase()} · ${source.version}`; + document.getElementById("dataOpsTitle").textContent = source.name; + document.getElementById("dataOpsDescription").textContent = `${source.provider} · ${source.coverage} · ${source.frequency}`; + const renderers = { + overview: renderDataOpsOverview, + requirements: renderDataOpsRequirements, + history: renderDataOpsHistory, + audit: renderDataOpsAudit, + usage: renderDataOpsUsage, + }; + content.innerHTML = renderers[dataOpsState.tab](source); + tabs.querySelectorAll("button").forEach((button) => { + button.classList.toggle("active", button.dataset.dataOpsTab === dataOpsState.tab); + }); + if (dataOpsState.tab === "usage") { + footer.innerHTML = ``; + return; + } + const primaryLabel = + source.category === "vendor" ? "检查并验收新版本" : source.warning ? "进入异常处置" : "创建更新任务"; + footer.innerHTML = ``; +} + +function openDataOpsDrawer(context, value) { + dataOpsState.context = context; + dataOpsState.tab = "overview"; + if (context === "source") dataOpsState.sourceName = value; + if (context === "issue") dataOpsState.issue = value; + updateDataOpsDrawer(); + const drawer = document.getElementById("dataOpsDrawer"); + drawer.classList.add("open"); + drawer.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeDataOpsDrawer() { + const drawer = document.getElementById("dataOpsDrawer"); + drawer.classList.remove("open"); + drawer.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function workspaceMetric(label, value, note) { + return `${label}${value}${note}`; +} + +function openWorkspaceDetail(kind, value = "") { + const configurations = { + project: () => { + const project = projects.find((item) => item.id === value || item.title === value) || projects[0]; + const loopProject = project._closedLoop ? closedLoopState.entities.project : null; + return { + kicker: "COLLABORATION PROJECT", + title: project.title, + description: project.meta, + content: ` +
${workspaceMetric("项目进度", `${project.progress}%`, "按计划推进")}${workspaceMetric("参与单位", "3 方", "学校、学院、企业")}${workspaceMetric("学生参与", "42 人", "跨专业组队")}
+

里程碑与交付物

企业任务书与验收标准确认已完成 · 2026-02-28课程任务和学生分组已完成 · 2026-03-08企业中期评审进行中 · 2026-04-12成果验收与能力评价计划 · 2026-05-30
+ ${loopProject ? `

实体关联

需求${loopProject.demandId}建议${loopProject.recommendationId}任务${loopProject.taskId}

执行证据

${closedLoopState.entities.evidences.map((item) => `${safeText(item.name)} · ${safeText(item.type)}${safeText(item.submitter)} · ${safeText(item.submittedAt)} · ${safeText(item.fileRef)}`).join("") || "尚未提交证据提交后同步更新项目进度"}
` : `

验收证据

企业任务书已归档学生过程产物86 份企业导师评价待中期评审
`}`, + primary: loopProject ? "关闭详情" : "更新项目进度", + }; + }, + task: () => { + const task = tasks.find((item) => item.id === value || item.title === value) || tasks[0]; + const loopTask = task._closedLoop ? closedLoopState.entities.task : null; + return { + kicker: "IMPROVEMENT TASK", + title: task.title, + description: `${task.profession} · 来源:${task.source}`, + content: ` +
${workspaceMetric("负责人", task.owner, "主责")}${workspaceMetric("截止日期", task.due, task.statusText)}${workspaceMetric("当前进度", `${task.progress}%`, "自动汇总")}
+

任务目标

将分析建议转化为课程、项目或校企协同调整,并以正式方案、企业确认和学生达成证据作为验收依据。

+

进展记录

${loopTask ? loopTask.progressLogs.map((item) => `${safeText(item.detail)}${safeText(item.operator)} · ${safeText(item.at)} · 进度 ${item.progress}%`).join("") : `完成现状与差距复核李雯 · 2026-03-18 16:20企业导师已确认技能清单陈凯 · 2026-03-20 10:42课程调整方案进入教研室评审系统 · 今天 08:30`}
+

验收要求

课程或项目方案${loopTask && closedLoopState.entities.evidences.length ? "已提交" : "必需"}企业确认回执${closedLoopState.entities.evaluation ? closedLoopState.entities.evaluation.result : "必需"}校级验收${loopTask?.status || "待执行"}
${loopTask ? `` : ""}
`, + primary: loopTask ? "关闭详情" : "提交阶段进展", + }; + }, + demand: () => { + const demand = enterpriseDemands.find((item) => item.id === value || item.company === value) || enterpriseDemands[0]; + const loopDemand = demand._closedLoop ? closedLoopState.entities.demand : null; + return { + kicker: "ENTERPRISE DEMAND", + title: demand.title, + description: `${demand.company} · ${demand.industry} · ${demand.due}`, + content: ` +

需求说明

${demand.description}

+
${workspaceMetric("计划人数", `${loopDemand?.headcount || 24} 人`, "2026届")}${workspaceMetric("技能要求", loopDemand?.skills || "8 项", loopDemand ? loopDemand.authorizationNo : "3 项重点")}${workspaceMetric("有效期", loopDemand?.validUntil || "实训 + 实习", loopDemand?.submitter || "企业导师参与")}
+

学校响应方案

`, + primary: "提交响应方案", + }; + }, + partner: () => { + const partner = partners.find((item) => item.name === value) || partners[0]; + return { + kicker: "PARTNER ENGAGEMENT", + title: `发起与${partner.name}的合作对接`, + description: `${partner.industry} · 综合匹配度 ${partner.match}%`, + content: ` +

推荐依据

${partner.reason}

${partner.tags.map((tag) => `${tag}`).join("")}
+

对接安排

`, + primary: "创建对接事项", + }; + }, + notifications: () => ({ + kicker: "NOTIFICATION CENTER", + title: "待办与通知", + description: "聚合需要当前角色处理的业务事项。", + content: `
`, + primary: "全部标记为已读", + }), + organizations: () => ({ + kicker: "ORGANIZATION SCOPE", + title: "组织与数据范围", + description: "根据账号角色切换组织,数据权限同步变化。", + content: `

权限说明

组织切换只改变业务范围,不改变底层租户隔离。平台运营人员无法默认查看学校明文业务数据。

`, + primary: "确认当前范围", + }), + templates: () => ({ + kicker: "REPORT TEMPLATE LIBRARY", + title: "报告模板库", + description: "按不同决策场景统一报告结构、证据和审批流程。", + content: `
校级报告全校产教供需分析总报告学校事实、区域基准、专业结构、行动清单42页 · 已启用
学院报告学院专业建设分析报告专业对比、共享能力、企业合作与任务跟踪36页 · 已启用
专业报告专业人才需求分析报告岗位、技能、薪资、课程映射和企业推荐24—30页 · 已启用
数据质量数据资产质量与口径报告来源、权属、版本、质量规则、限制和审计19页 · 已启用
`, + primary: "新建模板版本", + }), + compare: () => ({ + kicker: "PROGRAM COMPARISON", + title: "专业对比篮", + description: "最多选择4个专业,比较供需、技能、薪资与改进优先级。", + content: `
专业匹配度岗位需求薪资竞争力技能覆盖建议
${document.getElementById("professionTitle").textContent}84.22,8641.0876%保持优势
机电一体化技术81.72,1461.0572%补强工业视觉
电子商务74.81,9320.9668%优先调整

对比结论

软件技术需求和薪资竞争力领先;机电专业需补强机器视觉;电子商务应优先响应跨境运营和数据分析能力缺口。

`, + primary: "生成专业对比报告", + }), + industry: () => ({ + kicker: "INDUSTRY TREND", + title: "重点产业需求趋势", + description: "查看近90天岗位增速、样本和关联专业。", + content: `
${industries.map((item, index) => `${String(index + 1).padStart(2, "0")}${item.name}+${item.growth}%${820 + index * 173}条样本`).join("")}

口径说明

岗位增速来自近90天去重招聘信号,并由合作企业需求确认校验;只用于识别趋势,不直接解释为实际录用人数。

`, + primary: "生成产业专题报告", + }), + course: () => ({ + kicker: "COURSE STANDARD", + title: "课程标准与技能映射", + description: "查看课程目标、项目任务、考核证据和调整记录。", + content: `

映射依据

课程技能覆盖同时读取课程标准、实训任务、考核要求和学生项目产物,不因正文中出现技能名称就判定为充分覆盖。

${workspaceMetric("课程目标", "6 项", "已结构化")}${workspaceMetric("实训任务", "4 项", "2项企业任务")}${workspaceMetric("技能标签", "12 项", "版本 V3.2")}

最近调整

新增企业项目验收要求教研室 · 2026-03-18更新云平台技能映射课程负责人 · 2026-03-12
`, + primary: "进入课程标准修订", + }), + }; + + const factory = configurations[kind] || configurations.task; + const config = factory(); + document.getElementById("workspaceDetailKicker").textContent = config.kicker; + document.getElementById("workspaceDetailTitle").textContent = config.title; + document.getElementById("workspaceDetailDescription").textContent = config.description; + document.getElementById("workspaceDetailContent").innerHTML = config.content; + document.getElementById("workspaceDetailFooter").innerHTML = ``; + const drawer = document.getElementById("workspaceDetailDrawer"); + drawer.classList.add("open"); + drawer.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeWorkspaceDetail() { + const drawer = document.getElementById("workspaceDetailDrawer"); + drawer.classList.remove("open"); + drawer.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function renderSources(filter = "all") { + const filteredSources = filter === "all" ? sources : sources.filter((source) => source.category === filter); + const iconByCategory = { + vendor: "package", + school: "school", + enterprise: "building", + }; + const commercialClass = { + vendor: "paid", + school: "owned", + enterprise: "authorized", + }; + + document.getElementById("sourceGrid").innerHTML = filteredSources + .map( + (source) => ` +
+
+ ${source.categoryLabel} + ${source.commercial} +
+
+ + ${svgIcon(iconByCategory[source.category])} + + ${source.name}${source.type} + ${source.status} +
+
+ 数据提供方${source.provider} + 权属与授权${source.rights} + 覆盖范围${source.coverage} + 更新机制${source.frequency} +
+
+ 有效记录${source.records} + 质量评分${source.quality} +
+
+ 业务截止:${source.dataAsOf} · 入库:${source.updated} + + + + +
+
+ `, + ) + .join(""); + + document.getElementById("sourceFilterResult").textContent = `当前展示 ${filteredSources.length} 个数据源`; + + document.querySelectorAll("[data-sync-source]").forEach((button) => { + button.addEventListener("click", () => { + const source = sources.find((item) => item.name === button.dataset.syncSource); + dataOpsState.sourceName = source.name; + dataOpsState.tab = source.warning ? "overview" : "history"; + openDataOpsDrawer("source", source.name); + dataOpsState.tab = source.warning ? "overview" : "history"; + updateDataOpsDrawer(); + }); + }); +} + +const reportState = { + type: "all", + period: "all", + search: "", + limit: 6, +}; + +function reportsForCurrentRole() { + const role = document.getElementById("roleSelect")?.value || "校级管理者"; + return reports.filter((report) => { + if (report.roles.includes(role)) return true; + if (role === "专业负责人") return report.roles.includes("学院负责人") && report.type === "profession"; + if (role === "就业老师") return report.roles.includes("校级管理者") && ["school", "quality"].includes(report.type); + return false; + }); +} + +function reportIcon(type) { + const icons = { + school: "school", + college: "building", + profession: "file", + industry: "cloud", + quality: "database", + }; + return svgIcon(icons[type] || "file"); +} + +function visibleReports() { + const keyword = reportState.search.trim().toLowerCase(); + return reportsForCurrentRole().filter((report) => { + const matchesType = reportState.type === "all" || report.type === reportState.type; + const matchesPeriod = reportState.period === "all" || report.periodKey === reportState.period; + const searchable = `${report.title}${report.scope}${report.author}`.toLowerCase(); + return matchesType && matchesPeriod && searchable.includes(keyword); + }); +} + +function renderFeaturedReports(roleReports) { + const featuredReports = roleReports.filter((report) => report.featured).slice(0, 2); + const fallbackReports = roleReports.slice(0, 2); + const selected = featuredReports.length >= 2 ? featuredReports : fallbackReports; + document.getElementById("featuredReports").innerHTML = selected + .map( + (report, index) => ` + + `, + ) + .join(""); +} + +function renderReportList() { + const filtered = visibleReports(); + const visible = filtered.slice(0, reportState.limit); + const list = document.getElementById("reportList"); + list.innerHTML = visible + .map( + (report) => ` + + `, + ) + .join(""); + + if (!visible.length) { + list.innerHTML = ` +
+ ${svgIcon("file")} + 没有找到符合条件的报告 + 可以调整报告类型、周期或搜索关键词。 +
+ `; + } + + document.getElementById("reportListSummary").textContent = `共 ${filtered.length} 份报告,当前显示 ${visible.length} 份`; + const loadMore = document.getElementById("loadMoreReports"); + loadMore.hidden = visible.length >= filtered.length; +} + +function renderReportCenter() { + const roleReports = reportsForCurrentRole(); + const role = document.getElementById("roleSelect")?.value || "校级管理者"; + const descriptions = { + 校级管理者: "统一管理校级、学院、专业、产业与数据质量报告,支持在线阅读和版本追溯。", + 学院负责人: "查看本院、所属专业及相关数据质量报告,将分析结论转化为专业建设行动。", + 专业负责人: "查看本专业报告、提交闭环报告审核并追踪审批历史;校级批准与发布由校级管理者执行。", + 就业老师: "查看校级与数据质量报告,登记就业侧使用反馈;不能审批校级业务报告。", + 校级技术管理员: "查看数据质量、版本、口径和授权报告,确保进入分析的每个数据版本均可追溯。", + }; + document.getElementById("reportCenterDescription").textContent = + descriptions[role] || "统一管理分析报告,支持在线阅读和版本追溯。"; + document.getElementById("reportTotalCount").textContent = roleReports.length; + document.getElementById("reportNewCount").textContent = roleReports.filter((item) => item.periodKey === "current").length; + document.getElementById("reportReviewCount").textContent = roleReports.filter((item) => item.status === "待审核").length; + document.getElementById("reportSearch").value = reportState.search; + document.getElementById("reportPeriodFilter").value = reportState.period; + document.querySelectorAll("#reportTypeFilters [data-report-filter]").forEach((button) => { + button.classList.toggle("active", button.dataset.reportFilter === reportState.type); + }); + renderFeaturedReports(roleReports); + renderReportList(); +} + +function reportSectionHeading(index, english, title) { + return ` +
+ ${String(index).padStart(2, "0")} +
${english}

${title}

+
+ `; +} + +function renderReportDocument(report, options = {}) { + const interactive = options.interactive !== false; + const evidence = window.ReportVisuals.buildEvidence(report); + const findingEvidenceCodes = [ + evidence.evidenceCodes.trend, + evidence.evidenceCodes.matrix, + evidence.evidenceCodes.quadrant, + ]; + return ` +
+
产教融智 · INDUSTRY EDUCATION
+
+ ${report.typeLabel} · ${report.period} +

${report.title}

+

${report.scope}。报告基于统一数据快照生成,结论均保留来源、样本量与统计口径。

+ STANDARD REPORT · 数据、口径与结论全链路可追溯 +
+
+ 编制单位${report.author} + 分析版本${report.version} · 快照 ${evidence.snapshot.id} +
+
+ +
+ ${reportSectionHeading(1, "EXECUTIVE SUMMARY", "执行摘要")} +
${report.summary}
+
+ ${report.metrics + .map( + (metric) => ` +
${metric.label}${metric.value}${metric.note}
+ `, + ) + .join("")} +
+
+ 本校 / 本专业${evidence.score.toFixed(1)} + 区域院校均值${evidence.benchmark.regional.toFixed(1)}${(evidence.score - evidence.benchmark.regional).toFixed(1)}分 + 同类院校均值${evidence.benchmark.peer.toFixed(1)}${(evidence.score - evidence.benchmark.peer).toFixed(1)}分 + 区域可比排名${evidence.benchmark.rank}/${evidence.benchmark.schoolCount}样本口径一致 +
+ ${window.ReportVisuals.renderExecutiveCharts(report, { interactive })} +
+ 综合解读 +

本期${evidence.scoreLabel}为${evidence.score.toFixed(1)}分,高于区域可比均值${(evidence.score - evidence.benchmark.regional).toFixed(1)}分,高于同类院校均值${(evidence.score - evidence.benchmark.peer).toFixed(1)}分。该判断建立在${evidence.benchmark.sampleText}及统一数据快照之上;所有低样本指标已降权,不将互联网招聘数量直接解释为人才缺口人数。

+
+
+ +
+ ${reportSectionHeading(2, "INSTITUTION PROFILE", report.type === "profession" ? "专业与学校事实画像" : report.type === "college" ? "学院与学校事实画像" : "学校现状与事实画像")} + ${window.ReportVisuals.renderProfileEvidence(report, { interactive })} +
+ 学校现状判断 +

学校现状以学籍、教务、人事、实习就业和校企合作台账为事实底座。当前全校专业、课程和企业合作规模能够支撑常规人才培养,但真实项目实训、企业导师评价与课程技能映射仍需进一步覆盖。每项现状指标均可展开查看来源系统、更新时间、责任部门和计算口径。

+
+
+ +
+ ${reportSectionHeading(3, "KEY FINDINGS", "关键发现与证据定位")} +
+ ${report.findings + .map( + (finding, index) => ` +
+ ${String(index + 1).padStart(2, "0")} + + ${finding.title} + ${finding.detail} + 证据定位:${findingEvidenceCodes[index % findingEvidenceCodes.length]} · ${evidence.sources[index % evidence.sources.length].code} · 有效样本 ${evidence.sources[index % evidence.sources.length].sample} + + ${finding.value} +
+ `, + ) + .join("")} +
+
+ 结论交叉验证规则 + 外部需求趋势+校内培养事实+企业确认信号→业务负责人复核 +
+
+ +
+ ${reportSectionHeading(4, "SUPPLY & DEMAND", "供需结构与技能缺口分析")} + ${window.ReportVisuals.renderSupplyVisuals(report, { interactive })} +

表4-1 核心维度可比数据

+
+ + + + ${evidence.dimensions + .map( + (item) => ` + + + + + + + + + + + `, + ) + .join("")} + +
分析维度本校/本专业区域均值同类均值较区域需求强度课程覆盖证据状态
${item.name}${item.school.toFixed(1)}${item.regional.toFixed(1)}${item.peer.toFixed(1)}${item.school >= item.regional ? "+" : ""}${(item.school - item.regional).toFixed(1)}${item.demand.toFixed(0)}${item.coverage.toFixed(0)}已交叉验证
+
+
+ 图4-1至图4-4使用同一分析快照。需求强度、课程覆盖、学生达成和企业确认均为0—100标准分,用于同口径横向比较,不代表绝对岗位人数或学生人数。三维图用于同时观察四类证据,并非独立的3D业务流程。 +
+
+ 结构性结论 +

高需求但课程覆盖不足的能力位于象限图左上区域,应优先进入专业建设清单;高需求且覆盖充分的能力应转向学生达成和企业评价验证。趋势图显示培养响应仍滞后于外部需求,建议以真实项目和企业验收缩短响应周期,而不是简单增加课程名称。

+
+
+ +
+ ${reportSectionHeading(5, "DATA EVIDENCE", "证据链、样本与数据来源")} + ${window.ReportVisuals.renderEvidenceLedger(report)} +
+ +
+ ${reportSectionHeading(6, "METHODOLOGY", "指标口径、分析方法与限制")} +
+
01数据采集

采集近90天岗位、校内主数据、课程标准、实习就业回执和合作企业确认记录,保留权属与授权标签。

+
02清洗归一

按岗位ID、企业、发布时间去重;专业依据教育部专业代码归一;技能使用版本化词典映射。

+
03基准构建

仅纳入同层次、同区域且有效样本达到100条的院校;同类院校按专业结构、规模和产业方向匹配。

+
04交叉验证

外部需求、校内事实与企业确认至少两类证据方向一致才形成中高置信结论,AI文本须人工审核。

+
+
+ + + + + + + + + + +
指标计算口径样本与置信规则使用限制
供需匹配度岗位方向40% + 技能覆盖35% + 薪资竞争力15% + 企业确认10%四类分项均有样本;缺项按规则降权,不直接补均值用于识别建设方向,不用于直接决定招生规模
技能缺口需求强度-课程覆盖-学生达成修正值岗位样本≥100且课程映射覆盖≥80%为中高置信标准分差值不能解释为缺口人数
岗位需求近90天有效招聘记录去重并按企业、时效和重复发布降权77,520条岗位记录;126家企业确认用于校验招聘信号不等于实际录用人数
课程技能覆盖课程标准、实训任务和考核要求与技能词典映射后的加权覆盖1,286门次课程;映射覆盖率94.8%有文本描述不等于学生实际达成
学生达成课程考核、项目产物、企业评价和证书证据的综合达成度缺少企业评价的项目仅计校内证据,不做强外推不同专业考核难度不可直接比较绝对分数
薪资竞争力校内就业薪资中位数 / 区域同岗位中位数完整薪资样本6,284条;异常和缺失记录已剔除或降权受地区、岗位层级和企业规模影响
+
+
+ 本报告用于专业建设和校企协同决策参考。AI负责结构化归纳和文本草拟,不修改原始数据,不隐藏相反证据。业务负责人需结合政策、办学定位和资源约束审核,不直接替代招生、专业撤并或课程调整的正式决策程序。 +
+
+ +
+ ${reportSectionHeading(7, "ACTION PLAN", "行动建议与验收证据")} +
+ ${report.actions + .map( + (action, index) => ` +
+ ${action.priority} + + ${action.title} + ${action.detail} + 建议依据:${findingEvidenceCodes[index % findingEvidenceCodes.length]} · 验收要求:课程/项目方案、企业确认回执、学生达成记录至少两项 + + +
+ `, + ) + .join("")} +
+
+ 责任确认5个工作日内 + + 方案与资源形成可验收产物 + + 阶段复核按月更新证据 + + 效果评估下一周期回看指标 +
+
+ `; +} + +function renderReportApprovalToolbar(report) { + const toolbar = document.getElementById("reportApprovalToolbar"); + const loopReport = closedLoopState.entities.report; + if (!loopReport || report.id !== loopReport.id) { + toolbar.innerHTML = `${safeText(report.status)}历史报告按原有发布状态展示。`; + return; + } + const official = loopReport.status === "已发布"; + const actions = []; + if (["草稿", "已退回"].includes(loopReport.status) && ["专业负责人", "学院负责人", "校级管理者"].includes(currentRoleName())) { + actions.push(``); + } + if (loopReport.status === "待审核" && currentRoleName() === "校级管理者") { + actions.push(``); + } + if (loopReport.status === "已批准" && currentRoleName() === "校级管理者") { + actions.push(``); + } + toolbar.innerHTML = ` + ${loopReport.status} · ${official ? "正式版" : "非正式版"}${loopReport.id} · 发布前打印、下载和导出均标识非正式版 + 关联 ${loopReport.snapshotId} / ${loopReport.demandId} / ${loopReport.taskId} / ${loopReport.evidenceIds.length}项证据 +
审批历史 ${loopReport.history.length} 条
${loopReport.history + .map((item) => `${safeText(item.status)}${safeText(item.operator)} · ${safeText(item.at)}${safeText(item.comment)}`) + .join("")}
+
${actions.join("")}
`; +} + +function openReportReader(reportId) { + const report = reports.find((item) => item.id === reportId); + if (!report) return; + const reader = document.getElementById("reportReader"); + const tocItems = [ + ["cover", "封面"], + ["summary", "执行摘要"], + ["profile", "学校现状"], + ["findings", "关键发现"], + ["analysis", "供需结构"], + ["evidence", "证据链"], + ["method", "指标口径"], + ["actions", "行动建议"], + ]; + window.ReportVisuals.dispose(document.getElementById("reportDocument")); + reader.dataset.reportId = report.id; + document.getElementById("reportReaderTitle").textContent = report.title; + document.getElementById("reportReaderVersion").textContent = report.version; + renderReportApprovalToolbar(report); + document.getElementById("reportDocument").innerHTML = renderReportDocument(report); + document.getElementById("reportToc").innerHTML = tocItems + .map( + ([key, label], index) => + ``, + ) + .join(""); + reader.classList.add("open"); + reader.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; + document.querySelector(".report-document-wrap").scrollTop = 0; + requestAnimationFrame(() => window.ReportVisuals.init(report, document.getElementById("reportDocument"))); +} + +function closeReportReader() { + const reader = document.getElementById("reportReader"); + window.ReportVisuals.dispose(document.getElementById("reportDocument")); + reader.classList.remove("open"); + reader.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function reportStandaloneStyles() { + return ` + :root{--green:#176b4f;--green2:#2f8f6b;--lime:#c6e66f;--ink:#27362f;--muted:#718078;--line:#dfe7e1;--soft:#f4f7f4} + *{box-sizing:border-box}body{margin:0;background:#eef1ed;color:var(--ink);font-family:"PingFang SC","Microsoft YaHei",sans-serif;font-size:14px;line-height:1.7} + .report-document{max-width:1040px;margin:30px auto;background:white;box-shadow:0 16px 50px #20362b1a} + .report-cover-page{min-height:570px;padding:68px 70px 56px;color:white;background:radial-gradient(circle at 90% 100%,#244f3e 0 18%,transparent 19%),linear-gradient(155deg,#184638,#0f2c24);display:flex;flex-direction:column;justify-content:space-between} + .report-cover-brand{display:flex;align-items:center;gap:12px;color:var(--lime);font-weight:700;letter-spacing:.1em}.report-cover-brand i{display:inline-block;width:34px;height:4px;background:var(--lime)} + .report-cover-main span{color:#9bb4a9;font-size:14px}.report-cover-main h1{max-width:700px;margin:18px 0 0;font-family:"Songti SC","STSong",serif;font-size:42px;line-height:1.35}.report-cover-main p{max-width:620px;color:#aac0b7;font-size:16px} + .report-standard-stamp{display:inline-flex;margin-top:16px;padding:7px 10px;color:#dce8b9;background:#c6e66f14;border:1px solid #c6e66f40;border-radius:7px;font-size:13px;font-weight:700} + .report-cover-foot{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding-top:24px;border-top:1px solid #ffffff22}.report-cover-foot span,.report-cover-foot strong{display:block}.report-cover-foot span{color:#829f93}.report-cover-foot strong{margin-top:6px;color:white} + .report-section{padding:50px 60px;border-bottom:1px solid #e5eae6}.report-section-heading{display:flex;gap:16px;margin-bottom:24px}.report-section-heading>span{display:grid;width:36px;height:36px;flex:0 0 auto;place-items:center;color:var(--green);background:#e8f4ee;border-radius:10px;font-weight:800}.report-section-heading small{color:var(--green2);font-size:11px;font-weight:700;letter-spacing:.1em}.report-section-heading h2{margin:2px 0 0;font-size:24px} + .report-summary-callout{padding:20px;background:#eff7f2;border-left:4px solid var(--green);border-radius:0 12px 12px 0;font-size:15px} + .report-metric-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:20px}.report-metric-grid div{padding:16px;background:#f8faf8;border:1px solid #e5eae6;border-radius:11px}.report-metric-grid span,.report-metric-grid strong,.report-metric-grid small{display:block}.report-metric-grid span{color:var(--muted);font-size:11px}.report-metric-grid strong{margin:8px 0 5px;font-size:23px}.report-metric-grid small{color:var(--green2);font-size:11px} + .report-benchmark-strip{display:grid;grid-template-columns:repeat(4,1fr);margin-top:12px;overflow:hidden;color:white;background:#153d31;border-radius:12px}.report-benchmark-strip>span{padding:15px;border-right:1px solid #ffffff1a}.report-benchmark-strip small,.report-benchmark-strip strong,.report-benchmark-strip em{display:block}.report-benchmark-strip small{color:#a9beb5;font-size:11px}.report-benchmark-strip strong{margin:7px 0 4px;font-size:22px}.report-benchmark-strip em{color:var(--lime);font-size:11px;font-style:normal} + .report-chart-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;margin-top:22px}.report-chart-card{min-width:0;margin:0;overflow:hidden;border:1px solid var(--line);border-radius:14px;box-shadow:0 7px 24px #1e3c2f0f}.report-chart-head{display:flex;align-items:center;gap:9px;padding:14px 15px 11px;border-bottom:1px solid #edf1ee}.report-chart-head>span{padding:4px 6px;color:var(--green);background:#e8f4ee;border-radius:5px;font-size:11px;font-weight:800}.report-chart-head strong{font-size:13px}.report-chart-stage{height:310px;overflow:hidden;background:white}.report-chart-fallback{display:grid;width:100%;height:100%;place-items:center;padding:6px}.report-chart-fallback svg{display:block;width:100%;height:100%}.report-chart-card figcaption{min-height:83px;padding:12px 15px;color:#65736c;background:#f8faf8;border-top:1px solid #edf1ee;font-size:11px}.report-evidence-code{display:inline-flex;margin-right:5px;padding:3px 6px;color:var(--green);background:#e8f4ee;border-radius:5px;font-size:11px;font-weight:800} + .report-interpretation{display:grid;grid-template-columns:84px 1fr;gap:15px;margin-top:16px;padding:17px 18px;background:linear-gradient(100deg,#edf7f1,#f8fbf7);border:1px solid #dbeadf;border-radius:12px}.report-interpretation>span{align-self:start;padding:5px 8px;color:white;background:var(--green);border-radius:6px;font-size:11px;font-weight:800;text-align:center}.report-interpretation p{margin:0;font-size:13px}.report-interpretation strong{color:var(--green)} + .report-profile-banner{display:grid;grid-template-columns:1.2fr .8fr;gap:20px;padding:22px;color:#e7f0ec;background:radial-gradient(circle at 90% 0,#c6e66f24,transparent 35%),linear-gradient(135deg,#173f33,#102e26);border-radius:15px}.report-profile-kicker{color:var(--lime);font-size:11px;font-weight:800}.report-profile-banner h3{margin:9px 0 8px;color:white;font-size:19px}.report-profile-banner p{margin:0;color:#a9bdb5;font-size:12px}.report-profile-attributes{display:grid;grid-template-columns:1fr 1fr;gap:8px}.report-profile-attributes span{padding:10px;color:#8da79c;background:#ffffff0e;border:1px solid #ffffff12;border-radius:9px;font-size:11px}.report-profile-attributes strong{display:block;margin-top:5px;color:#eaf2ee;font-size:11px} + .report-profile-stat-grid{display:grid;grid-template-columns:repeat(4,1fr);align-items:start;gap:10px;margin-top:13px}.report-profile-stat-grid article{padding:14px;background:#fafbf9;border:1px solid #e5eae6;border-radius:11px}.report-profile-code,.report-profile-label,.report-profile-stat-grid article>strong,.report-profile-stat-grid article>em{display:block}.report-profile-code{color:#84928a;font-size:11px;font-weight:700}.report-profile-label{margin-top:9px;color:var(--muted);font-size:11px}.report-profile-stat-grid article>strong{margin:5px 0 4px;font-size:23px}.report-profile-stat-grid article>strong small{margin-left:3px;color:var(--muted);font-size:11px}.report-profile-stat-grid article>em{min-height:32px;color:var(--green2);font-size:11px;font-style:normal}.report-profile-stat-grid details{margin-top:9px;padding-top:8px;border-top:1px solid #e8ede9}.report-profile-stat-grid summary{color:var(--green);font-size:11px;font-weight:700;cursor:pointer}.report-profile-stat-grid details>div{margin-top:8px;padding:9px;color:var(--muted);background:white;border:1px solid #e8ede9;border-radius:8px;font-size:11px}.report-profile-stat-grid details span,.report-profile-stat-grid details strong{display:block}.report-profile-stat-grid details span+span{margin-top:6px}.report-profile-stat-grid details strong{color:var(--ink)}.report-profile-stat-grid details p{padding-top:8px;border-top:1px dashed var(--line)} + .report-finding-list,.report-action-list{display:flex;flex-direction:column;gap:11px}.report-finding,.report-action-card{display:grid;grid-template-columns:36px 1fr auto;align-items:start;gap:13px;padding:15px;background:#fafbf9;border:1px solid #e5eae6;border-radius:11px}.report-finding>span:first-child,.report-action-priority{display:grid;width:36px;height:36px;place-items:center;color:var(--green);background:#e8f4ee;border-radius:9px;font-weight:800}.report-finding strong,.report-finding small,.report-action-card strong,.report-action-card small{display:block}.report-finding small,.report-action-card small{color:var(--muted);font-size:12px}.report-finding-proof,.report-action-evidence{margin-top:7px;color:var(--green2)!important;font-size:11px!important;font-weight:600}.report-finding em{color:var(--green);font-style:normal;font-weight:800}.report-finding-validation{display:flex;align-items:center;justify-content:center;gap:8px;flex-wrap:wrap;margin-top:15px;padding:13px;background:#f5f8f5;border:1px dashed #d4ded7;border-radius:10px;font-size:11px}.report-finding-validation span{padding:5px 7px;color:var(--green);background:white;border:1px solid #dbe6df;border-radius:6px;font-weight:700} + .report-table-wrap{max-width:100%;overflow-x:auto;border:1px solid #e5eae6;border-radius:10px}.report-table{width:100%;border-collapse:collapse}.report-table th{padding:11px 10px;color:var(--muted);background:#f4f7f4;border-bottom:1px solid var(--line);font-size:12px;text-align:left}.report-table td{padding:13px 10px;border-bottom:1px solid #e5eae6;font-size:13px}.report-comparison-table{min-width:760px}.report-evidence-table{min-width:860px}.report-source-tag,.report-confidence{display:inline-flex;padding:4px 7px;color:var(--green);background:#e8f4ee;border-radius:6px;font-size:11px;font-weight:700}.report-evidence-table td:nth-child(2) small{display:block;margin-top:5px;color:var(--muted);font-size:11px}.report-positive{color:var(--green);font-weight:700}.report-negative{color:#b45249;font-weight:700}.report-subsection-title{margin:28px 0 12px;font-size:15px} + .report-evidence-summary{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:14px}.report-evidence-summary span{padding:13px;background:#f7faf7;border:1px solid #e5eae6;border-radius:10px}.report-evidence-summary small,.report-evidence-summary strong{display:block}.report-evidence-summary small{color:var(--muted);font-size:11px}.report-evidence-summary strong{margin-top:6px;font-size:14px}.report-proof-chain{display:grid;grid-template-columns:1fr 24px 1fr 24px 1fr 24px 1fr;align-items:center;gap:4px;margin-bottom:15px;padding:14px;background:#173e32;border-radius:12px}.report-proof-chain>span{text-align:center}.report-proof-chain i,.report-proof-chain strong,.report-proof-chain small{display:block}.report-proof-chain i{width:27px;height:27px;margin:0 auto 6px;padding-top:5px;color:#173e32;background:var(--lime);border-radius:8px;font-size:11px;font-style:normal;font-weight:800}.report-proof-chain strong{color:white;font-size:11px}.report-proof-chain small{color:#92aaa0;font-size:11px}.report-proof-chain>b{height:1px;background:#668078}.report-evidence-notice{margin-top:14px;padding:15px 17px;color:#6f5220;background:#fff9ed;border:1px solid #eee0bd;border-radius:10px}.report-evidence-notice strong{display:block}.report-evidence-notice p{margin:5px 0 0;font-size:11px} + .report-method-steps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px}.report-method-steps article{display:grid;grid-template-columns:34px 1fr;gap:3px 11px;padding:14px;background:#fafbf9;border:1px solid #e5eae6;border-radius:10px}.report-method-steps article>span{display:grid;width:34px;height:34px;grid-row:1/3;place-items:center;color:var(--green);background:#e8f4ee;border-radius:9px;font-size:11px;font-weight:800}.report-method-steps strong{font-size:12px}.report-method-steps p{margin:2px 0 0;color:var(--muted);font-size:11px}.report-method-note{margin-top:18px;padding:15px;background:#f7f8f5;border:1px dashed #ced8d1;border-radius:10px;font-size:12px} + .report-action-priority{color:#a14238;background:#fff0ed}.report-action-card button{display:none}.report-action-cycle{display:grid;grid-template-columns:repeat(7,auto);align-items:center;justify-content:center;gap:10px;margin-top:17px;padding:15px;color:#dcebe4;background:#173e32;border-radius:11px}.report-action-cycle span,.report-action-cycle strong,.report-action-cycle small{display:block}.report-action-cycle strong{font-size:11px}.report-action-cycle small{color:#91aaa0;font-size:11px}.report-action-cycle i{width:28px;height:1px;background:var(--lime)} + .report-file-note{max-width:1040px;margin:0 auto 30px;color:var(--muted);text-align:center;font-size:13px} + .report-document small,.report-document summary,.report-document .report-source-tag,.report-document .report-confidence,.report-document .report-evidence-code,.report-document .report-profile-code,.report-document .report-profile-label,.report-document .report-action-priority,.report-document .report-standard-stamp{font-size:13px!important} + .report-document p,.report-document li,.report-document td,.report-document figcaption,.report-document .report-finding small,.report-document .report-action-card small{font-size:14px!important} + .report-document th,.report-document svg text{font-size:13px!important} + @media(max-width:700px){body{background:white}.report-document{margin:0;box-shadow:none}.report-cover-page{min-height:480px;padding:44px 25px}.report-cover-main h1{font-size:30px}.report-section{padding:32px 20px}.report-metric-grid,.report-benchmark-strip,.report-evidence-summary,.report-profile-stat-grid{grid-template-columns:1fr 1fr}.report-chart-grid,.report-profile-banner,.report-method-steps{grid-template-columns:1fr}.report-profile-attributes{grid-template-columns:1fr 1fr}.report-cover-foot{grid-template-columns:1fr}.report-finding,.report-action-card{grid-template-columns:36px 1fr}.report-finding em{grid-column:2}.report-interpretation{grid-template-columns:1fr}.report-proof-chain,.report-action-cycle{grid-template-columns:1fr}.report-proof-chain>b,.report-action-cycle i{width:1px;height:14px;justify-self:center}.report-chart-card figcaption{min-height:0}} + @media print{body{background:white}.report-document{max-width:none;margin:0;box-shadow:none}.report-cover-page{break-after:page}.report-section{break-before:page}.report-chart-card,.report-profile-stat-grid article,.report-finding,.report-action-card{break-inside:avoid}.report-file-note{display:none}} + `; +} + +function downloadReportSample(reportId) { + const report = reports.find((item) => item.id === reportId); + if (!report) return; + const isClosedLoopReport = closedLoopState.entities.report?.id === reportId; + const official = !isClosedLoopReport || closedLoopState.entities.report.status === "已发布"; + const editionLabel = official ? "正式发布版" : "非正式版 · 仅供审核"; + const content = ` + + + + + ${report.title} + + + +

${editionLabel}${isClosedLoopReport ? ` · ${report.id} · ${closedLoopState.entities.report.status}` : ""}

+
${renderReportDocument(report, { interactive: false })}
+

本文件由产教融智报告中心生成 · 数据快照 ${report.version} · ${report.period}

+ + `; + const blob = new Blob([content], { type: "text/html;charset=utf-8" }); + const url = URL.createObjectURL(blob); + const anchor = document.createElement("a"); + anchor.href = url; + anchor.download = `${report.title.replace(/[\\/:*?"<>|]/g, "-")}-${official ? "正式版" : "非正式版"}.html`; + anchor.click(); + setTimeout(() => URL.revokeObjectURL(url), 500); + if (isClosedLoopReport) { + addClosedLoopAudit("REPORT_DOWNLOADED", report.id, `${editionLabel}离线HTML`); + saveClosedLoopState(); + renderClosedLoop(); + } + showToast(`离线HTML报告已下载,当前标识:${editionLabel}`, "下载已开始"); +} + +function setupSourceFilters() { + const filterButtons = [...document.querySelectorAll("[data-source-filter]")]; + const summaryCards = [...document.querySelectorAll("[data-source-summary-filter]")]; + + const applyFilter = (filter) => { + filterButtons.forEach((button) => button.classList.toggle("active", button.dataset.sourceFilter === filter)); + summaryCards.forEach((card) => card.classList.toggle("active", card.dataset.sourceSummaryFilter === filter)); + renderSources(filter); + document.querySelector(".source-panel").scrollIntoView({ behavior: "smooth", block: "start" }); + }; + + filterButtons.forEach((button) => { + button.addEventListener("click", () => applyFilter(button.dataset.sourceFilter)); + }); + summaryCards.forEach((card) => { + card.addEventListener("click", () => applyFilter(card.dataset.sourceSummaryFilter)); + }); +} + +function setupDataOperations() { + document.getElementById("addDataSourceButton").addEventListener("click", () => openDataOpsDrawer("add")); + document.getElementById("dataAuthorizationButton").addEventListener("click", () => openDataOpsDrawer("authorization")); + document.getElementById("syncAllButton").addEventListener("click", () => openDataOpsDrawer("batch")); + document.querySelectorAll("[data-data-issue]").forEach((button) => { + button.addEventListener("click", () => openDataOpsDrawer("issue", button.dataset.dataIssue)); + }); + + document.getElementById("dataOpsTabs").addEventListener("click", (event) => { + const button = event.target.closest("[data-data-ops-tab]"); + if (!button) return; + dataOpsState.tab = button.dataset.dataOpsTab; + updateDataOpsDrawer(); + }); + + document.getElementById("dataOpsDrawer").addEventListener("click", (event) => { + if (event.target === event.currentTarget) closeDataOpsDrawer(); + }); + document.getElementById("closeDataOpsDrawer").addEventListener("click", closeDataOpsDrawer); + document.getElementById("dataOpsFooter").addEventListener("click", (event) => { + const closeButton = event.target.closest("[data-data-ops-close]"); + if (closeButton) { + closeDataOpsDrawer(); + return; + } + const tabButton = event.target.closest("[data-data-ops-tab-jump]"); + if (tabButton) { + dataOpsState.tab = tabButton.dataset.dataOpsTabJump; + updateDataOpsDrawer(); + document.querySelector(".data-ops-drawer").scrollTop = 0; + return; + } + const resultButton = event.target.closest("[data-data-ops-result]"); + if (resultButton) { + const message = resultButton.dataset.dataOpsResult; + closeDataOpsDrawer(); + showToast(message, "数据运维任务已记录"); + } + }); + document.getElementById("dataOpsContent").addEventListener("click", (event) => { + const loopAction = event.target.closest("[data-loop-action]"); + if (loopAction) { + closeDataOpsDrawer(); + openClosedLoopAction(loopAction.dataset.loopAction); + return; + } + const method = event.target.closest(".data-source-methods button"); + if (method) { + method.parentElement.querySelectorAll("button").forEach((item) => item.classList.toggle("active", item === method)); + } + }); + document.getElementById("dataOpsFooter").addEventListener("click", (event) => { + if (event.target.closest("[data-view-loop]")) { + closeDataOpsDrawer(); + switchView("loop"); + } + }); + document.addEventListener("click", (event) => { + const sourceButton = event.target.closest("[data-source-detail]"); + if (sourceButton) openDataOpsDrawer("source", sourceButton.dataset.sourceDetail); + }); +} + +function setupWorkspaceDetails() { + document.getElementById("organizationSwitcher").addEventListener("click", () => openWorkspaceDetail("organizations")); + document.getElementById("notificationButton").addEventListener("click", () => openWorkspaceDetail("notifications")); + document.getElementById("industryTrendMore").addEventListener("click", () => openWorkspaceDetail("industry")); + document.getElementById("compareProfession").addEventListener("click", () => openWorkspaceDetail("compare")); + document.getElementById("reportTemplateButton").addEventListener("click", () => openWorkspaceDetail("templates")); + document.getElementById("closeWorkspaceDetail").addEventListener("click", closeWorkspaceDetail); + document.getElementById("workspaceDetailDrawer").addEventListener("click", (event) => { + if (event.target === event.currentTarget) closeWorkspaceDetail(); + }); + document.getElementById("workspaceDetailFooter").addEventListener("click", (event) => { + if (event.target.closest("[data-workspace-close]")) { + closeWorkspaceDetail(); + return; + } + if (event.target.closest("[data-workspace-confirm]")) { + const action = event.target.closest("[data-workspace-confirm]").textContent; + closeWorkspaceDetail(); + showToast(`${action}已保存,并写入业务记录`, "业务操作已完成"); + } + }); + + document.addEventListener("click", (event) => { + const project = event.target.closest("[data-project-detail]"); + if (project) { + openWorkspaceDetail("project", project.dataset.projectId || project.dataset.projectDetail); + return; + } + const task = event.target.closest("[data-task-detail]"); + if (task) { + openWorkspaceDetail("task", task.dataset.taskId || task.dataset.taskDetail); + return; + } + const course = event.target.closest("[data-workspace-detail^='course-']"); + if (course) { + openWorkspaceDetail("course", course.dataset.workspaceDetail); + return; + } + }); + + document.getElementById("workspaceDetailContent").addEventListener("click", (event) => { + const loopAction = event.target.closest("[data-loop-action]"); + if (loopAction) { + closeWorkspaceDetail(); + openClosedLoopAction(loopAction.dataset.loopAction); + return; + } + const viewButton = event.target.closest("[data-view-jump]"); + if (viewButton) { + closeWorkspaceDetail(); + switchView(viewButton.dataset.viewJump); + return; + } + const issueButton = event.target.closest("[data-data-issue]"); + if (issueButton) { + closeWorkspaceDetail(); + openDataOpsDrawer("issue", issueButton.dataset.dataIssue); + } + }); + + document.querySelectorAll("[data-project-filter]").forEach((button) => { + button.addEventListener("click", () => { + button.parentElement.querySelectorAll("button").forEach((item) => item.classList.toggle("active", item === button)); + renderProjects(button.dataset.projectFilter); + }); + }); + document.querySelectorAll("[data-partner-filter]").forEach((button) => { + button.addEventListener("click", () => { + button.parentElement.querySelectorAll("button").forEach((item) => item.classList.toggle("active", item === button)); + renderPartners(button.dataset.partnerFilter); + }); + }); +} + +const productTourSteps = [ + { view: "dashboard", selector: ".quality-strip", title: "可信数据底座", description: "先确认数据来源、更新状态和质量门槛,所有分析只引用已验收版本。" }, + { view: "dashboard", selector: ".ai-panel", title: "发现关键变化", description: "AI将岗位、技能和专业变化归纳为可解释的决策简报,并保留证据定位。" }, + { view: "profession", selector: ".profile-banner", title: "定位专业差距", description: "从岗位、技能、薪资和课程映射判断专业优势与结构性缺口。" }, + { view: "collaboration", selector: ".collab-stats", title: "连接企业协同", description: "把企业需求转化为课程共建、真实项目、企业导师和实习就业合作。" }, + { view: "actions", selector: ".action-overview", title: "形成改进闭环", description: "每项建议都有负责人、截止日期、进展证据和下一周期效果复核。" }, + { view: "data", selector: ".source-summary-grid", title: "管理数据资产", description: "厂商、学校和企业三类数据分权维护,支持初次导入、增量更新、版本和审计。" }, + { view: "reports", selector: ".featured-report-grid", title: "完成正式交付", description: "在线报告、材料包和展示大屏使用同一数据快照,适用于决策、汇报与报送。" }, +]; + +let productTourStep = 0; + +function closeProductTour() { + const tour = document.getElementById("productTour"); + tour.classList.remove("open"); + tour.setAttribute("aria-hidden", "true"); + if (document.getElementById("productTourCoach").hidden) document.body.style.overflow = ""; +} + +function closeTourCoach() { + document.getElementById("productTourCoach").hidden = true; + document.querySelectorAll(".tour-target").forEach((item) => item.classList.remove("tour-target")); + document.body.classList.remove("tour-running"); +} + +function renderProductTourStep() { + const step = productTourSteps[productTourStep]; + document.querySelectorAll(".tour-target").forEach((item) => item.classList.remove("tour-target")); + switchView(step.view); + const target = document.querySelector(`#view-${step.view} ${step.selector}`); + if (target) { + target.classList.add("tour-target"); + setTimeout(() => target.scrollIntoView({ behavior: "smooth", block: "center" }), 80); + } + document.getElementById("tourStepLabel").textContent = `${String(productTourStep + 1).padStart(2, "0")} / ${String(productTourSteps.length).padStart(2, "0")}`; + document.getElementById("tourStepTitle").textContent = step.title; + document.getElementById("tourStepDescription").textContent = step.description; + document.getElementById("tourPrevious").disabled = productTourStep === 0; + document.getElementById("tourNext").textContent = productTourStep === productTourSteps.length - 1 ? "进入展示大屏" : "下一步"; +} + +function openShowcaseScreen() { + closeTourCoach(); + const screen = document.getElementById("showcaseScreen"); + screen.classList.add("open"); + screen.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; +} + +function closeShowcaseScreen() { + const screen = document.getElementById("showcaseScreen"); + screen.classList.remove("open"); + screen.setAttribute("aria-hidden", "true"); + document.body.style.overflow = ""; +} + +function setupProductExperience() { + document.getElementById("productTourButton").addEventListener("click", () => { + const tour = document.getElementById("productTour"); + tour.classList.add("open"); + tour.setAttribute("aria-hidden", "false"); + document.body.style.overflow = "hidden"; + }); + document.getElementById("closeProductTour").addEventListener("click", closeProductTour); + document.getElementById("productTour").addEventListener("click", (event) => { + if (event.target === event.currentTarget) closeProductTour(); + }); + document.getElementById("startProductTour").addEventListener("click", () => { + const roleSelect = document.getElementById("roleSelect"); + roleSelect.value = "校级管理者"; + applyRole("校级管理者", { notify: false }); + closeProductTour(); + productTourStep = 0; + document.getElementById("productTourCoach").hidden = false; + document.body.classList.add("tour-running"); + renderProductTourStep(); + }); + document.getElementById("tourPlatformButton").addEventListener("click", () => { + document.getElementById("roleSelect").value = "厂商超级管理员"; + applyRole("厂商超级管理员", { notify: false }); + closeProductTour(); + }); + document.getElementById("tourReportButton").addEventListener("click", () => { + document.getElementById("roleSelect").value = "校级管理者"; + applyRole("校级管理者", { notify: false }); + closeProductTour(); + switchView("reports"); + setTimeout(() => openReportReader("school-2026-03"), 120); + }); + document.getElementById("tourPrevious").addEventListener("click", () => { + if (productTourStep > 0) { + productTourStep -= 1; + renderProductTourStep(); + } + }); + document.getElementById("tourNext").addEventListener("click", () => { + if (productTourStep === productTourSteps.length - 1) { + openShowcaseScreen(); + return; + } + productTourStep += 1; + renderProductTourStep(); + }); + document.getElementById("closeTourCoach").addEventListener("click", closeTourCoach); + document.querySelectorAll("[data-showcase-open]").forEach((button) => button.addEventListener("click", openShowcaseScreen)); + document.getElementById("closeShowcaseScreen").addEventListener("click", closeShowcaseScreen); +} + +function setupGenericInteractions() { + document.querySelectorAll(".nav-item[data-view]").forEach((button) => { + button.addEventListener("click", () => switchView(button.dataset.view)); + }); + + document.querySelectorAll("[data-view-jump]").forEach((button) => { + button.addEventListener("click", () => switchView(button.dataset.viewJump)); + }); + + document.querySelectorAll("[data-toast]").forEach((button) => { + button.addEventListener("click", () => showToast(button.dataset.toast, "操作已记录")); + }); + + document.querySelectorAll("[data-close-modal]").forEach((button) => { + button.addEventListener("click", () => closeModal(button.closest(".modal-backdrop"))); + }); + + document.querySelectorAll(".modal-backdrop").forEach((backdrop) => { + backdrop.addEventListener("click", (event) => { + if (event.target === backdrop && backdrop.id !== "analysisModal") closeModal(backdrop); + }); + }); + + document.addEventListener("keydown", (event) => { + if (event.key === "Escape") { + if (document.getElementById("showcaseScreen").classList.contains("open")) { + closeShowcaseScreen(); + return; + } + if (!document.getElementById("productTourCoach").hidden) { + closeTourCoach(); + return; + } + if (document.getElementById("productTour").classList.contains("open")) { + closeProductTour(); + return; + } + if (document.getElementById("dataOpsDrawer").classList.contains("open")) { + closeDataOpsDrawer(); + return; + } + if (document.getElementById("workspaceDetailDrawer").classList.contains("open")) { + closeWorkspaceDetail(); + return; + } + if (document.getElementById("reportReader").classList.contains("open")) { + closeReportReader(); + return; + } + const open = document.querySelector(".modal-backdrop.open"); + if (open && open.id !== "analysisModal") closeModal(open); + document.body.classList.remove("sidebar-open"); + } + }); + + const mobileMenu = document.getElementById("mobileMenu"); + const sidebarScrim = document.getElementById("sidebarScrim"); + mobileMenu.addEventListener("click", () => document.body.classList.toggle("sidebar-open")); + sidebarScrim.addEventListener("click", () => document.body.classList.remove("sidebar-open")); + + const tooltip = document.getElementById("tooltip"); + document.querySelectorAll("[data-tip]").forEach((button) => { + const show = () => { + tooltip.textContent = button.dataset.tip; + const rect = button.getBoundingClientRect(); + tooltip.style.left = `${Math.min(rect.left, window.innerWidth - 245)}px`; + tooltip.style.top = `${rect.bottom + 7}px`; + tooltip.classList.add("show"); + }; + const hide = () => tooltip.classList.remove("show"); + button.addEventListener("mouseenter", show); + button.addEventListener("mouseleave", hide); + button.addEventListener("focus", show); + button.addEventListener("blur", hide); + }); + + document.querySelectorAll("[data-report-generate]").forEach((button) => { + button.addEventListener("click", () => openReportGeneration(button.dataset.reportGenerate)); + }); + +} + +function openReportGeneration(context = "center") { + const modal = document.getElementById("reportModal"); + const title = document.getElementById("reportModalTitle"); + const description = document.getElementById("reportModalDescription"); + const options = document.getElementById("reportOptions"); + const currentProfession = document.getElementById("professionTitle")?.textContent || "软件技术"; + const configurations = { + package: { + title: "生成供需会材料包", + description: "所有报告将使用同一分析快照,确保统计口径一致。", + options: [ + ["全校供需分析总报告", "约42页 · PDF / Word", true], + ["32个专业人才需求报告", "独立文件 · 自动生成目录", true], + ["关键指标一页纸", "适用于会议汇报与报送", true], + ["数据口径与质量附件", "指标定义、样本量及数据来源", false], + ], + }, + profession: { + title: `生成${currentProfession}专业报告`, + description: "生成包含岗位、技能、薪资、企业与课程建议的专业分析报告。", + options: [ + ["执行摘要与专业画像", "核心指标、趋势与结论", true], + ["技能供需与课程映射", "技能缺口及课程覆盖依据", true], + ["岗位、薪资与企业分析", "岗位需求、薪资分位数和合作企业", true], + ["行动建议与数据附件", "建议责任、口径及数据来源", true], + ], + }, + center: { + title: "生成新分析报告", + description: "选择报告范围和内容,生成后将自动进入报告中心。", + options: [ + ["校级供需分析报告", "全校专业和产业供需总览", true], + ["学院或专业报告", "按当前账号数据范围生成", true], + ["产业人才缺口专题", "重点方向、企业和增长趋势", false], + ["数据质量与口径报告", "数据资产、质量与使用限制", false], + ], + }, + }; + const configuration = configurations[context] || configurations.center; + modal.dataset.context = context; + title.textContent = configuration.title; + description.textContent = configuration.description; + options.innerHTML = ` + 选择报告内容 + ${configuration.options + .map( + ([name, note, checked]) => + ``, + ) + .join("")} + `; + openModal(modal); +} + +function setupReportCenterInteractions() { + const typeFilters = document.getElementById("reportTypeFilters"); + const search = document.getElementById("reportSearch"); + const period = document.getElementById("reportPeriodFilter"); + + typeFilters.addEventListener("click", (event) => { + const button = event.target.closest("[data-report-filter]"); + if (!button) return; + reportState.type = button.dataset.reportFilter; + reportState.limit = 6; + typeFilters.querySelectorAll("button").forEach((item) => item.classList.toggle("active", item === button)); + renderReportList(); + }); + + search.addEventListener("input", () => { + reportState.search = search.value; + reportState.limit = 6; + renderReportList(); + }); + + period.addEventListener("change", () => { + reportState.period = period.value; + reportState.limit = 6; + renderReportList(); + }); + + document.getElementById("loadMoreReports").addEventListener("click", () => { + reportState.limit += 4; + renderReportList(); + }); + + document.addEventListener("click", (event) => { + const openButton = event.target.closest("[data-report-open]"); + if (openButton) { + openReportReader(openButton.dataset.reportOpen); + return; + } + const downloadButton = event.target.closest("[data-report-download]"); + if (downloadButton) { + downloadReportSample(downloadButton.dataset.reportDownload); + return; + } + const actionButton = event.target.closest("[data-report-action-create]"); + if (actionButton) { + const title = actionButton.closest(".report-action-card").querySelector("strong").textContent.trim(); + if (!tasks.some((task) => task.title === title)) { + const report = reports.find((item) => item.id === document.getElementById("reportReader").dataset.reportId); + const task = { + id: `TSK-REPORT-${Date.now()}`, + title, + source: `报告建议 · ${report?.version || "当前版本"} · 证据链已关联`, + profession: report?.type === "profession" ? report.scope.split("·").pop().trim() : "全校专业", + owner: "待确认", + due: "2026-04-30", + progress: 0, + status: "review", + statusText: "待确认", + }; + closedLoopState.custom.tasks.unshift(task); + addClosedLoopAudit("TASK_CREATED_FROM_REPORT", task.id, `报告 ${report?.id || "未知"} · ${title}`); + saveClosedLoopState(); + syncClosedLoopCollections(); + renderTasks(); + } + actionButton.textContent = "已加入任务"; + actionButton.disabled = true; + showToast("报告建议已创建改进任务,并关联本报告的数据证据与版本"); + } + }); + + document.getElementById("closeReportReader").addEventListener("click", closeReportReader); + document.getElementById("reportToc").addEventListener("click", (event) => { + const button = event.target.closest("[data-report-section]"); + if (!button) return; + document.querySelectorAll("#reportToc button").forEach((item) => item.classList.toggle("active", item === button)); + const section = document.getElementById(`report-section-${button.dataset.reportSection}`); + section?.scrollIntoView({ behavior: "smooth", block: "start" }); + }); + + document.getElementById("reportPrintButton").addEventListener("click", () => { + const reportId = document.getElementById("reportReader").dataset.reportId; + if (closedLoopState.entities.report?.id === reportId) { + const official = closedLoopState.entities.report.status === "已发布"; + addClosedLoopAudit("REPORT_PRINTED", reportId, official ? "正式版打印" : "非正式版打印"); + saveClosedLoopState(); + showToast(official ? "当前打印为正式发布版。" : "报告尚未发布,打印输出将作为非正式版使用。", official ? "正式版" : "非正式版提示"); + } + window.print(); + }); + + document.getElementById("reportDownloadButton").addEventListener("click", () => { + downloadReportSample(document.getElementById("reportReader").dataset.reportId); + }); +} + +function setupRoleExperience() { + const roleSelect = document.getElementById("roleSelect"); + roleSelect.addEventListener("change", () => applyRole(roleSelect.value)); + + document.querySelectorAll("[data-platform-target]").forEach((button) => { + button.addEventListener("click", () => { + const targetId = button.dataset.platformTarget; + switchView("platform"); + document.querySelectorAll("#platformNav [data-platform-target]").forEach((item) => { + item.classList.toggle("active", item.dataset.platformTarget === targetId); + }); + const labels = { + platformOverview: "平台总览", + packageManagement: "数据包管理", + tenantManagement: "机构与租户", + accountManagement: "账号与权限", + backupManagement: "备份与恢复", + auditManagement: "审计与监控", + }; + document.getElementById("breadcrumbCurrent").textContent = labels[targetId] || "平台总览"; + setTimeout(() => { + document.getElementById(targetId)?.scrollIntoView({ behavior: "smooth", block: "start" }); + }, 80); + document.body.classList.remove("sidebar-open"); + }); + }); +} + +const platformActionTemplates = { + import: { + kicker: "DATA PACKAGE IMPORT", + title: "导入基础数据包", + description: "校验厂商数据包版本,并选择本次发布的学校租户范围。", + confirm: "开始导入", + progress: true, + content: ` +
+ + + + + + + + +
+ 导入要求与发布门槛 +
+ 主键package_id + source_record_id + 格式Parquet / CSV UTF-8 + 必填完整率≥ 95% + 综合质量≥ 90 方可发布 +
+
+
+ 授权学校范围 +
+ + + + +
+
+
+ `, + }, + backup: { + kicker: "PLATFORM BACKUP", + title: "创建平台备份", + description: "本操作仅创建新的加密备份,不影响当前生产数据。", + confirm: "开始备份", + progress: true, + content: ` +
+ + + +
+ `, + }, + restore: { + kicker: "RECOVERY DRILL", + title: "发起恢复演练", + description: "在隔离环境中验证备份可恢复性,不覆盖生产数据。", + confirm: "开始演练", + progress: true, + content: ` +
+ + + +
+ `, + }, + tenant: { + kicker: "TENANT ONBOARDING", + title: "新增学校租户", + description: "创建学校独立工作空间并配置初始数据服务。", + confirm: "创建租户", + content: ` +
+ + + + +
+ `, + }, + packageDetail: { + kicker: "DATA PACKAGE DETAIL", + title: "数据包服务详情", + description: "查看版本、质量校验和学校授权情况。", + confirm: "完成", + content: ` +
当前生产版本 V2026.032026-03-18 发布 · 86.4万条有效记录 · 质量评分 93.4
+
授权与服务12家学校已订阅,服务协议全部有效,下次更新计划为 2026-04-01。
+ `, + }, + tenantDetail: { + kicker: "TENANT DETAIL", + title: "学校租户详情", + description: "查看租户版本、服务状态和资源用量。", + confirm: "进入租户", + content: ` +
租户运行正常旗舰版 · 386名用户 · 6个数据源 · 本月生成报告74份
+
资源使用数据存储 38.2GB / 100GB,AI分析额度使用 64%,服务有效至 2027-02-28。
+ `, + }, + service: { + kicker: "SERVICE MONITOR", + title: "平台服务监控", + description: "查看服务可用性、任务吞吐和最近异常。", + confirm: "完成", + content: `
最近24小时运行正常共处理428个任务,成功425个,3个任务已自动重试成功,无生产事故。
`, + }, + account: { + kicker: "PLATFORM ACCOUNTS", + title: "平台管理员账号", + description: "管理厂商运营、实施与技术支持账号。", + confirm: "进入管理", + content: `
8 个平台级账号超级管理员2人,平台运营3人,数据运维2人,安全审计1人,全部启用MFA。
`, + }, + permission: { + kicker: "ROLE PERMISSION", + title: "角色与权限模板", + description: "统一配置学校、学院、企业和平台运营角色权限。", + confirm: "进入配置", + content: `
7 套权限模板采用租户隔离、角色权限和数据范围三层控制,最近修改已通过审计复核。
`, + }, + security: { + kicker: "SECURITY POLICY", + title: "平台安全策略", + description: "查看认证、访问控制和安全告警策略。", + confirm: "完成", + content: `
当前无高危安全风险MFA覆盖率100%,异常登录拦截3次,密钥轮换将在12天后执行。
`, + }, + audit: { + kicker: "AUDIT LOG", + title: "平台审计日志", + description: "追溯数据导入、权限变更、租户操作和系统任务。", + confirm: "查看完整日志", + content: `
今日记录 286 条关键操作数据操作68条,权限操作12条,系统任务201条,安全事件5条,全部保留操作者和时间戳。
`, + }, +}; + +function setupPlatformActions() { + const modal = document.getElementById("platformActionModal"); + const confirmButton = document.getElementById("platformActionConfirm"); + + document.querySelectorAll("[data-platform-action]").forEach((button) => { + button.addEventListener("click", () => { + const action = button.dataset.platformAction; + const template = platformActionTemplates[action] || platformActionTemplates.service; + modal.dataset.action = action; + document.getElementById("platformActionKicker").textContent = template.kicker; + document.getElementById("platformActionTitle").textContent = template.title; + document.getElementById("platformActionDescription").textContent = template.description; + document.getElementById("platformActionContent").innerHTML = template.content; + document.getElementById("platformActionProgress").hidden = true; + document.getElementById("platformActionProgressBar").style.width = "0"; + confirmButton.textContent = template.confirm; + confirmButton.disabled = false; + openModal(modal); + }); + }); + + confirmButton.addEventListener("click", () => { + const action = modal.dataset.action; + const template = platformActionTemplates[action] || platformActionTemplates.service; + if (!template.progress) { + closeModal(modal); + showToast(`${template.title}操作已记录`, "平台操作"); + return; + } + + const progress = document.getElementById("platformActionProgress"); + const bar = document.getElementById("platformActionProgressBar"); + const value = document.getElementById("platformActionProgressValue"); + const text = document.getElementById("platformActionProgressText"); + progress.hidden = false; + confirmButton.disabled = true; + let current = 0; + const messages = { + import: ["正在校验数据包签名…", "正在检查字段与质量规则…", "正在写入版本库并发布…"], + backup: ["正在创建一致性快照…", "正在加密并写入备份存储…", "正在校验备份完整性…"], + restore: ["正在创建隔离环境…", "正在恢复备份数据…", "正在验证数据完整性…"], + }[action]; + + const timer = setInterval(() => { + current = Math.min(current + 10, 100); + bar.style.width = `${current}%`; + value.textContent = `${current}%`; + text.textContent = messages[Math.min(Math.floor(current / 35), 2)]; + if (current === 100) { + clearInterval(timer); + setTimeout(() => { + closeModal(modal); + confirmButton.disabled = false; + const successMessages = { + import: "基础数据包已通过校验并发布到所选学校", + backup: "平台备份已创建并完成完整性校验", + restore: "隔离恢复演练成功,生产数据未受影响", + }; + showToast(successMessages[action], "平台操作完成"); + }, 350); + } + }, 90); + }); +} + +function setupAnalysis() { + document.getElementById("runAnalysis").addEventListener("click", () => { + const modal = document.getElementById("analysisModal"); + const progress = document.getElementById("analysisProgress"); + const status = document.getElementById("analysisStatus"); + const steps = [...document.querySelectorAll(".analysis-steps span")]; + const statuses = [ + "读取本期分析快照…", + "归一并匹配产业岗位…", + "计算专业技能覆盖差距…", + "生成可解释决策洞察…", + ]; + openModal(modal); + progress.style.width = "0"; + steps.forEach((step, index) => step.classList.toggle("active", index === 0)); + let value = 0; + const timer = setInterval(() => { + value += 10; + progress.style.width = `${value}%`; + const stage = Math.min(Math.floor(value / 26), 3); + status.textContent = statuses[stage]; + steps.forEach((step, index) => step.classList.toggle("active", index <= stage)); + if (value >= 100) { + clearInterval(timer); + setTimeout(() => { + closeModal(modal); + showToast("供需分析 V2026.03 已生成,3项关键变化需要关注"); + }, 350); + } + }, 120); + }); +} + +function setupReportGeneration() { + const button = document.getElementById("generateReportButton"); + button.addEventListener("click", () => { + const progressWrap = document.getElementById("reportProgress"); + const progressBar = document.getElementById("reportProgressBar"); + const progressValue = document.getElementById("reportProgressValue"); + const progressText = document.getElementById("reportProgressText"); + progressWrap.hidden = false; + button.disabled = true; + button.textContent = "正在生成…"; + let value = 0; + const timer = setInterval(() => { + value += 8; + if (value > 100) value = 100; + progressBar.style.width = `${value}%`; + progressValue.textContent = `${value}%`; + if (value < 34) progressText.textContent = "正在准备报告模板…"; + else if (value < 70) progressText.textContent = "正在渲染32个专业图表…"; + else progressText.textContent = "正在校验口径并打包…"; + if (value === 100) { + clearInterval(timer); + setTimeout(() => { + const baseReport = reportsForCurrentRole()[0] || reports[0]; + const generatedReport = { + ...baseReport, + id: `generated-${Date.now()}`, + version: `${baseReport.version}-R${reports.filter((item) => item.id.startsWith("generated-")).length + 1}`, + status: "待审核", + statusClass: "review", + updated: "刚刚", + featured: false, + }; + closedLoopState.custom.reports.unshift(generatedReport); + addClosedLoopAudit("REPORT_CREATED", generatedReport.id, `${generatedReport.title} · ${generatedReport.status}`); + saveClosedLoopState(); + syncClosedLoopCollections(); + closeModal(document.getElementById("reportModal")); + showToast("报告已生成并进入报告中心,可继续在线阅读或下载"); + progressWrap.hidden = true; + progressBar.style.width = "0"; + button.disabled = false; + button.innerHTML = `${svgIcon("file")}开始生成`; + const role = document.getElementById("roleSelect").value; + if (roleProfiles[role]?.menus.includes("report")) { + switchView("reports"); + renderReportCenter(); + } + }, 450); + } + }, 100); + }); +} + +function configureFormModal(type) { + const currentRole = document.getElementById("roleSelect").value; + const configs = { + task: { + kicker: "ACTION FORM", + title: "创建改进任务", + description: "将分析洞察转化为可追踪、可验证的行动。", + label: "任务名称", + value: "强化云原生与容器化实训内容", + scopeLabel: "关联专业", + scopeOptions: ["软件技术", "机电一体化技术", "电子商务"], + priorityLabel: "优先级", + priorityOptions: ["高优先级", "中优先级", "低优先级"], + goalLabel: "目标与说明", + goal: "依据近90天岗位数据,将 Docker、Kubernetes 与 CI/CD 实践纳入实训课程,并邀请企业导师参与课程评审。", + ownerLabel: "负责人", + owner: "李雯 · 信息工程学院", + dueLabel: "计划完成时间", + due: "2026-06-30", + }, + project: { + kicker: "COLLABORATION PROJECT", + title: "新建协同项目", + description: "连接专业团队与企业伙伴,共同推进人才培养项目。", + label: "项目名称", + value: "企业真实项目进课堂", + scopeLabel: "牵头专业", + scopeOptions: ["软件技术", "机电一体化技术", "电子商务"], + priorityLabel: "项目类型", + priorityOptions: ["企业项目进课堂", "课程共建", "实训基地", "企业导师"], + goalLabel: "共建目标与验收方式", + goal: "围绕企业真实任务共同设计教学项目、过程评价和成果验收,保留企业任务书与导师评价证据。", + ownerLabel: "校内负责人", + owner: "王健 · 产教融合中心", + dueLabel: "计划启动时间", + due: "2026-04-15", + }, + demand: { + kicker: "ENTERPRISE RESEARCH", + title: "发起企业需求调研", + description: "向合作企业收集岗位、技能和人才培养需求。", + label: "调研主题", + value: "2026年度重点产业人才需求调研", + scopeLabel: "调研范围", + scopeOptions: ["126家合作企业", "重点产业企业", "当前专业合作企业"], + priorityLabel: "调研类型", + priorityOptions: ["岗位与技能需求", "课程共建意愿", "实习就业需求"], + goalLabel: "调研说明", + goal: "收集未来12个月岗位、技能、人才数量和校企合作意愿,企业提交结果需确认授权用途与有效期。", + ownerLabel: "发起部门", + owner: "产教融合中心", + dueLabel: "反馈截止时间", + due: "2026-04-30", + }, + }; + if (currentRole === "企业导师" && type === "demand") { + configs.demand = { + kicker: "ENTERPRISE DEMAND", + title: "提交企业人才需求", + description: "提交真实岗位、技能与共育需求,供学校专业团队确认响应。", + label: "需求名称", + value: "边缘计算软件测试人才共育需求", + scopeLabel: "关联专业", + scopeOptions: ["软件技术", "物联网应用技术", "计算机网络技术"], + priorityLabel: "合作方式", + priorityOptions: ["人才共育", "真实项目", "课程共建", "实习就业"], + goalLabel: "企业需求说明", + goal: "提交真实岗位、技能、计划人数和合作方式,并由企业联系人确认数据授权用途与有效期。", + ownerLabel: "企业联系人", + owner: "陈凯 · 企业人才发展部", + dueLabel: "期望响应时间", + due: "2026-04-20", + }; + } + if (currentRole === "企业导师" && type === "project") { + configs.project = { + kicker: "CO-CREATION PROJECT", + title: "发起校企共建项目", + description: "邀请学校共同设计企业真实项目、课程内容和评价标准。", + label: "项目名称", + value: "智能物联边缘计算综合实训", + scopeLabel: "面向专业", + scopeOptions: ["物联网应用技术", "软件技术", "计算机网络技术"], + priorityLabel: "项目类型", + priorityOptions: ["企业真实项目", "课程共建", "企业导师", "实训基地"], + goalLabel: "企业任务与验收要求", + goal: "基于边缘计算测试场景设计实训任务,由企业导师参与中期评审,并依据测试报告、代码质量和协作过程验收。", + ownerLabel: "企业负责人", + owner: "陈凯 · 企业人才发展部", + dueLabel: "建议启动时间", + due: "2026-04-20", + }; + } + const config = configs[type]; + document.getElementById("formModalKicker").textContent = config.kicker; + document.getElementById("formModalTitle").textContent = config.title; + document.getElementById("formModalDescription").textContent = config.description; + document.getElementById("formNameLabel").textContent = config.label; + document.getElementById("formName").value = config.value; + document.getElementById("formScopeLabel").textContent = config.scopeLabel; + document.getElementById("formScope").innerHTML = config.scopeOptions.map((option) => ``).join(""); + document.getElementById("formPriorityLabel").textContent = config.priorityLabel; + document.getElementById("formPriority").innerHTML = config.priorityOptions.map((option) => ``).join(""); + document.getElementById("formGoalLabel").textContent = config.goalLabel; + document.getElementById("formGoal").value = config.goal; + document.getElementById("formOwnerLabel").textContent = config.ownerLabel; + document.getElementById("formOwner").value = config.owner; + document.getElementById("formDueLabel").textContent = config.dueLabel; + document.getElementById("formDue").value = config.due; + document.getElementById("actionForm").dataset.type = type; + openModal(document.getElementById("formModal")); +} + +function setupForms() { + document.getElementById("newTaskButton").addEventListener("click", () => configureFormModal("task")); + document.getElementById("newProjectButton").addEventListener("click", () => { + if (currentRoleName() === "专业负责人") openClosedLoopAction("project"); + else configureFormModal("project"); + }); + document.getElementById("enterpriseDemandButton").addEventListener("click", () => { + if (currentRoleName() === "企业导师") openClosedLoopAction("demand"); + else configureFormModal("demand"); + }); + document.getElementById("actionForm").addEventListener("submit", (event) => { + event.preventDefault(); + const type = event.currentTarget.dataset.type; + const title = document.getElementById("formName").value.trim(); + const scope = document.getElementById("formScope").value; + const classification = document.getElementById("formPriority").value; + const goal = document.getElementById("formGoal").value.trim(); + const owner = document.getElementById("formOwner").value.trim(); + const due = document.getElementById("formDue").value; + if (type === "task") { + const task = { + id: `TSK-CUSTOM-${Date.now()}`, + title, + source: `手动创建 · ${classification}`, + profession: scope, + owner: owner.split("·")[0].trim(), + due, + progress: 0, + status: "progress", + statusText: "进行中", + }; + closedLoopState.custom.tasks.unshift(task); + addClosedLoopAudit("TASK_CREATED", task.id, `${title} · ${scope} · ${owner}`); + saveClosedLoopState(); + syncClosedLoopCollections(); + renderTasks(); + switchView("actions"); + } else if (type === "project") { + const project = { + id: `PRJ-CUSTOM-${Date.now()}`, + type: classification.includes("课程") ? "course" : "practice", + tone: "green", + title, + meta: `${scope} × 合作伙伴待确认`, + progress: 0, + partners: [owner.slice(0, 1), "企"], + }; + closedLoopState.custom.projects.unshift(project); + addClosedLoopAudit("PROJECT_CREATED", project.id, `${title} · ${scope} · ${owner}`); + saveClosedLoopState(); + syncClosedLoopCollections(); + renderProjects(); + switchView("collaboration"); + } else if (type === "demand") { + const demand = { + id: `DEM-CUSTOM-${Date.now()}`, + logo: document.getElementById("roleSelect").value === "企业导师" ? "企" : "调", + company: document.getElementById("roleSelect").value === "企业导师" ? "企业人才发展部" : "校企需求调研", + industry: classification, + title, + description: goal, + due: due ? `${due} 截止` : "待确认", + status: "已提交", + }; + closedLoopState.custom.demands.unshift(demand); + addClosedLoopAudit("DEMAND_CREATED", demand.id, `${title} · ${classification} · ${owner}`); + saveClosedLoopState(); + syncClosedLoopCollections(); + renderDemands(); + switchView("collaboration"); + } + closeModal(document.getElementById("formModal")); + const messages = { + task: "改进任务已创建,并通知专业负责人", + project: "协同项目草案已创建,可继续邀请企业伙伴", + demand: "企业需求调研已创建,共有126家在库企业可发送", + }; + showToast(messages[type] || "内容已保存"); + }); +} + +function setupFilters() { + document.getElementById("professionSearch").addEventListener("input", (event) => renderProfessionTable(event.target.value)); + document.getElementById("professionSelect").addEventListener("change", (event) => renderProfessionProfile(event.target.value)); + + document.querySelectorAll("#periodSwitch button").forEach((button) => { + button.addEventListener("click", () => { + document.querySelectorAll("#periodSwitch button").forEach((item) => item.classList.remove("active")); + button.classList.add("active"); + renderTrendChart(button.dataset.period); + }); + }); + + document.querySelectorAll("#professionTabs button").forEach((button) => { + button.addEventListener("click", () => { + document.querySelectorAll("#professionTabs button").forEach((item) => item.classList.remove("active")); + button.classList.add("active"); + professionTabState = button.dataset.tab; + const skillsView = document.getElementById("professionSkillsView"); + const detailView = document.getElementById("professionDetailView"); + const showSkills = professionTabState === "skills"; + skillsView.hidden = !showSkills; + detailView.hidden = showSkills; + if (!showSkills) renderProfessionDetailView(professionTabState); + }); + }); + + let taskFilter = "all"; + const taskSearch = document.getElementById("taskSearch"); + document.querySelectorAll("#taskFilters button").forEach((button) => { + button.addEventListener("click", () => { + taskFilter = button.dataset.filter; + document.querySelectorAll("#taskFilters button").forEach((item) => item.classList.remove("active")); + button.classList.add("active"); + renderTasks(taskFilter, taskSearch.value); + }); + }); + taskSearch.addEventListener("input", () => renderTasks(taskFilter, taskSearch.value)); + +} + +function validateClosedLoopSubmission(action, values) { + const e = closedLoopState.entities; + if (action === "receive") { + values.tenantId = values.tenantId.trim(); + values.packageId = values.packageId.trim(); + values.packageVersion = values.packageVersion.trim(); + values.sha256 = values.sha256.trim().toLowerCase(); + const checkedRecords = Number(values.checkedRecords); + const checks = [ + [values.tenantId === e.receipt.tenantId, `租户标识必须为 ${e.receipt.tenantId}`], + [values.packageId === e.receipt.packageId, `数据包编号必须为 ${e.receipt.packageId}`], + [values.packageVersion === e.receipt.packageVersion, `数据包版本必须为 ${e.receipt.packageVersion}`], + [Number.isInteger(checkedRecords) && checkedRecords === e.receipt.expectedRecords, `交付包记录数必须为 ${e.receipt.expectedRecords.toLocaleString("zh-CN")} 条`], + [/^[a-f0-9]{64}$/.test(values.sha256), "SHA-256 必须是完整的64位十六进制摘要"], + [values.sha256 === e.receipt.expectedSha256, "SHA-256 与厂商发布 Manifest 的数据文件摘要不一致"], + ]; + const failure = checks.find(([matched]) => !matched); + if (failure) { + return { + valid: false, + title: "技术接收校验失败", + message: `${failure[1]};回执与分析快照状态均未前进。`, + auditAction: "PACKAGE_RECEIPT_VALIDATION_FAILED", + auditDetail: `${values.tenantId || "空租户"} · ${values.packageId || "空包号"} · ${values.packageVersion || "空版本"} · ${Number.isFinite(checkedRecords) ? checkedRecords : "无效记录数"} 条 · SHA ${values.sha256 || "空"}`, + }; + } + values.checkedRecords = String(checkedRecords); + } + if (action === "evidence") { + const progress = Number(values.progress); + if (!Number.isFinite(progress) || progress < 0 || progress > 100) { + return { valid: false, title: "进度值无效", message: "阶段进度必须是0到100之间的数字。" }; + } + } + if (action === "reportReview" && values.approver === e.report?.submittedBy) { + return { + valid: false, + title: "报告审批职责未分离", + message: "本次报告提交人不能批准或退回自己的提交,请选择另一位校级管理者。", + auditAction: "REPORT_REVIEW_BLOCKED_SELF_APPROVAL", + auditDetail: `${e.report.id} · 提交人 ${e.report.submittedBy} · 拟审批人 ${values.approver}`, + }; + } + return { valid: true }; +} + +function setupClosedLoop() { + document.getElementById("view-loop").addEventListener("click", (event) => { + const button = event.target.closest("[data-loop-action]"); + if (button) openClosedLoopAction(button.dataset.loopAction); + }); + document.getElementById("reportApprovalToolbar").addEventListener("click", (event) => { + const button = event.target.closest("[data-loop-action]"); + if (button) openClosedLoopAction(button.dataset.loopAction); + }); + document.getElementById("closedLoopForm").addEventListener("submit", (event) => { + event.preventDefault(); + const action = event.currentTarget.dataset.action; + const values = Object.fromEntries(new FormData(event.currentTarget).entries()); + const availability = actionPrerequisite(action); + if (!availability.enabled) { + showToast(availability.reason, "权限或前置条件已变化"); + return; + } + const validation = validateClosedLoopSubmission(action, values); + if (!validation.valid) { + if (validation.auditAction) { + addClosedLoopAudit(validation.auditAction, action === "receive" ? closedLoopState.entities.receipt.id : closedLoopState.entities.report?.id || action, validation.auditDetail); + saveClosedLoopState(); + renderClosedLoop(); + } + showToast(validation.message, validation.title); + return; + } + closeModal(document.getElementById("closedLoopModal")); + applyClosedLoopAction(action, values); + const reader = document.getElementById("reportReader"); + if (reader.classList.contains("open")) { + const report = reports.find((item) => item.id === reader.dataset.reportId); + if (report) renderReportApprovalToolbar(report); + document.body.style.overflow = "hidden"; + } + }); + document.getElementById("resetClosedLoop").addEventListener("click", () => { + if (!window.confirm("确认重置校园闭环样板?本地持久化的闭环实体、自定义业务记录和审计事件将恢复为种子状态。")) return; + localStorage.removeItem(CLOSED_LOOP_STORAGE_KEY); + closedLoopState = closedLoopSeed(); + closedLoopState.auditEvents.unshift({ + id: `AUD-${Date.now()}`, + action: "SAMPLE_RESET", + objectId: CLOSED_LOOP_SHARED.tenantId, + operator: currentRoleUser(), + role: currentRoleName(), + at: nowText(), + detail: `按 schemaVersion ${CLOSED_LOOP_SCHEMA_VERSION} 重置样板。`, + }); + saveAndRenderClosedLoop("校园闭环样板已重置"); + renderProfessionProfile(document.getElementById("professionSelect").value); + }); +} + +function init() { + syncClosedLoopCollections(); + saveClosedLoopState(); + renderSparkline("sparkMatch", [65, 68, 67, 72, 74, 78.6]); + renderSparkline("sparkJobs", [38, 42, 41, 50, 57, 64], "#4978a8"); + renderSparkline("sparkGaps", [34, 31, 32, 29, 26, 23], "#d89527"); + renderTrendChart(); + renderProfessionTable(); + renderIndustryList(); + renderProfessionProfile("software"); + renderProjects(); + renderDemands(); + renderPartners(); + renderTasks(); + renderSources(); + setupGenericInteractions(); + setupRoleExperience(); + setupPlatformActions(); + setupAnalysis(); + setupReportGeneration(); + setupReportCenterInteractions(); + setupForms(); + setupFilters(); + setupSourceFilters(); + setupDataOperations(); + setupWorkspaceDetails(); + setupProductExperience(); + setupClosedLoop(); + renderClosedLoop(); +} + +document.addEventListener("DOMContentLoaded", init); diff --git a/demo/enterprise.css b/demo/enterprise.css new file mode 100644 index 0000000..b4e8104 --- /dev/null +++ b/demo/enterprise.css @@ -0,0 +1,3163 @@ +/* 企业版交互扩展:深层页面、数据运维、产品导览、大屏与可读性 */ + +.tour-launch { + display: inline-flex; + min-height: 40px; + align-items: center; + gap: 7px; + padding: 0 13px; + color: var(--green); + background: var(--green-soft); + border: 1px solid #d3e7dc; + border-radius: 10px; + font-size: 13px; + font-weight: 700; +} + +.tour-launch svg { + width: 17px; + height: 17px; +} + +.quality-icon { + color: white; + background: linear-gradient(135deg, var(--green), #2f9470); + box-shadow: 0 6px 16px rgba(23, 107, 79, 0.2); +} + +.quality-icon svg { + stroke-width: 2.2; +} + +/* 专业洞察深层视图 */ +.profession-tab-view { + min-width: 0; +} + +.profession-detail-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 14px; +} + +.profession-detail-panel { + min-width: 0; +} + +.profession-detail-panel.wide { + grid-column: 1 / -1; +} + +.job-flow-board { + display: grid; + min-height: 360px; + grid-template-columns: 150px minmax(80px, 0.4fr) minmax(285px, 1fr); + align-items: center; + gap: 12px; + margin-top: 18px; + padding: 22px; + overflow: hidden; + background: linear-gradient(110deg, #f5faf7, #fbfcfb); + border: 1px solid #e4ece7; + border-radius: 14px; +} + +.job-flow-source { + display: grid; + min-height: 150px; + place-items: center; + align-content: center; + color: white; + background: linear-gradient(145deg, #176b4f, #104735); + border-radius: 18px; + text-align: center; +} + +.job-flow-source span, +.job-flow-source strong, +.job-flow-source small { + display: block; +} + +.job-flow-source span { + font-size: 14px; +} + +.job-flow-source strong { + margin: 8px 0 2px; + color: var(--lime); + font-size: 34px; +} + +.job-flow-source small { + color: #adcbc0; + font-size: 13px; +} + +.job-flow-lines { + position: relative; + height: 300px; +} + +.job-flow-lines::before, +.job-flow-lines::after { + position: absolute; + top: 50%; + width: 14px; + height: 14px; + background: var(--green); + border-radius: 50%; + content: ""; + transform: translateY(-50%); +} + +.job-flow-lines::before { + left: -5px; +} + +.job-flow-lines::after { + right: -5px; + background: #72b893; +} + +.job-flow-lines i { + position: absolute; + top: var(--flow-top); + right: 0; + left: 0; + height: var(--flow-width); + background: linear-gradient(90deg, rgba(23, 107, 79, 0.82), rgba(114, 184, 147, 0.5)); + border-radius: 50%; +} + +.job-flow-targets { + display: flex; + flex-direction: column; + gap: 8px; +} + +.job-flow-targets > span { + display: grid; + grid-template-columns: 30px minmax(0, 1fr) auto; + align-items: center; + gap: 9px; + padding: 10px 12px; + background: white; + border: 1px solid #e2eae5; + border-radius: 10px; +} + +.job-flow-targets b { + color: var(--green); + font-size: 13px; +} + +.job-flow-targets strong { + font-size: 14px; +} + +.job-flow-targets small { + color: var(--muted); + font-size: 13px !important; +} + +.job-flow-targets i { + grid-column: 2 / -1; + display: block; + height: 6px; + overflow: hidden; + background: #edf2ee; + border-radius: 4px; +} + +.job-flow-targets i em, +.region-distribution-list i em { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #72b893); + border-radius: 4px; +} + +.region-distribution-list, +.salary-factor-list, +.course-gap-list { + display: flex; + flex-direction: column; + gap: 13px; + margin-top: 18px; +} + +.region-distribution-list > span { + display: grid; + grid-template-columns: 1fr auto; + gap: 6px 12px; +} + +.region-distribution-list strong, +.salary-factor-list strong, +.course-gap-list strong { + font-size: 14px; +} + +.region-distribution-list small, +.salary-factor-list small, +.course-gap-list small { + color: var(--muted); + font-size: 13px !important; +} + +.region-distribution-list i { + grid-column: 1 / -1; + display: block; + height: 8px; + overflow: hidden; + background: #edf2ee; + border-radius: 5px; +} + +.employer-structure { + display: flex; + min-height: 225px; + align-items: flex-end; + justify-content: space-around; + gap: 14px; + margin-top: 18px; +} + +.employer-structure > span { + display: flex; + min-width: 0; + flex: 1; + align-items: center; + flex-direction: column; + text-align: center; +} + +.employer-structure > span::before { + width: min(105px, 100%); + height: calc(var(--share) * 3.1px); + max-height: 135px; + margin-bottom: 10px; + background: linear-gradient(180deg, #72b893, var(--green)); + border-radius: 12px 12px 3px 3px; + content: ""; +} + +.employer-structure strong { + font-size: 14px; +} + +.employer-structure small { + margin-top: 5px; + color: var(--muted); + font-size: 13px !important; +} + +.profession-evidence-note { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 12px; + margin-top: 14px; + padding: 15px 17px; + color: #285041; + background: #edf7f1; + border: 1px solid #d8eade; + border-radius: 12px; +} + +.profession-evidence-note > span { + padding: 5px 8px; + color: white; + background: var(--green); + border-radius: 6px; + font-size: 13px; + font-weight: 800; +} + +.profession-evidence-note p { + margin: 0; + font-size: 14px !important; +} + +.profession-evidence-note button { + padding: 8px 10px; + color: var(--green); + background: white; + border: 1px solid #cfe2d6; + border-radius: 8px; + font-size: 13px !important; + font-weight: 700; +} + +.salary-index { + padding: 7px 10px; + color: var(--green); + background: var(--green-soft); + border-radius: 8px; + font-size: 13px; + font-weight: 700; +} + +.salary-index.warning { + color: #9a6818; + background: var(--amber-soft); +} + +.salary-comparison { + display: flex; + flex-direction: column; + gap: 18px; + margin-top: 24px; +} + +.salary-comparison > span { + display: grid; + grid-template-columns: 165px minmax(0, 1fr) 92px; + align-items: center; + gap: 13px; +} + +.salary-comparison strong { + font-size: 14px; +} + +.salary-comparison i { + height: 15px; + overflow: hidden; + background: #edf2ee; + border-radius: 8px; +} + +.salary-comparison i em { + display: block; + height: 100%; + background: var(--green); + border-radius: 8px; +} + +.salary-comparison i em.region { + background: #4d7fa8; +} + +.salary-comparison i em.peer { + background: #d39a35; +} + +.salary-comparison b { + font-size: 15px; + text-align: right; +} + +.salary-range { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 16px; + margin-top: 30px; + padding: 18px; + background: #f8faf8; + border-radius: 12px; +} + +.salary-range span small, +.salary-range span strong { + display: block; +} + +.salary-range span small { + color: var(--muted); + font-size: 13px !important; +} + +.salary-range span strong { + margin-top: 3px; + font-size: 15px; +} + +.salary-range > i { + position: relative; + height: 9px; + background: #dfe8e2; + border-radius: 5px; +} + +.salary-range > i b { + position: absolute; + inset: 0; + background: linear-gradient(90deg, #72b893, var(--green)); + border-radius: 5px; +} + +.salary-range > i em { + position: absolute; + top: 50%; + width: 17px; + height: 17px; + background: var(--lime); + border: 3px solid var(--green); + border-radius: 50%; + transform: translate(-50%, -50%); +} + +.salary-sample-card, +.coverage-summary { + display: flex; + min-height: 210px; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; +} + +.salary-sample-card > strong, +.coverage-summary > strong { + color: var(--green); + font-size: 44px; +} + +.salary-sample-card > span, +.coverage-summary > span { + font-size: 14px; + font-weight: 700; +} + +.salary-sample-card > small, +.coverage-summary > small { + max-width: 340px; + margin-top: 12px; + color: var(--muted); + font-size: 13px !important; + line-height: 1.7; +} + +.salary-factor-list span { + display: grid; + grid-template-columns: 70px minmax(0, 1fr); + align-items: center; + gap: 12px; + padding: 14px; + background: #f8faf8; + border-radius: 10px; +} + +.salary-factor-list b { + color: var(--green); + font-size: 20px; +} + +.matrix-legend { + display: flex; + flex-wrap: wrap; + gap: 8px; + color: var(--muted); + font-size: 13px; +} + +.matrix-legend i { + width: 9px; + height: 9px; + margin-left: 5px; + background: var(--green); + border-radius: 3px; +} + +.matrix-legend i:nth-of-type(2) { + background: var(--amber); +} + +.matrix-legend i:nth-of-type(3) { + background: var(--red); +} + +.course-matrix-wrap { + max-width: 100%; + margin-top: 18px; + overflow-x: auto; +} + +.course-matrix { + width: 100%; + min-width: 900px; + border-collapse: collapse; +} + +.course-matrix th, +.course-matrix td { + padding: 12px 10px; + border-bottom: 1px solid var(--line-soft); + font-size: 13px; + text-align: center; +} + +.course-matrix th:first-child, +.course-matrix td:first-child { + min-width: 145px; + text-align: left; +} + +.course-matrix td:first-child strong, +.course-matrix td:first-child small { + display: block; +} + +.course-matrix td:first-child small { + color: var(--muted); + font-size: 13px !important; +} + +.matrix-cell { + display: inline-grid; + width: 34px; + height: 34px; + place-items: center; + color: white; + background: var(--green); + border-radius: 8px; + font-size: 13px; + font-weight: 700; +} + +.matrix-cell.partial { + background: var(--amber); +} + +.matrix-cell.gap { + background: var(--red); +} + +.course-matrix button { + padding: 7px 9px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px !important; + font-weight: 700; +} + +.coverage-summary > i { + width: 80%; + height: 10px; + margin-top: 14px; + overflow: hidden; + background: #e8eee9; + border-radius: 6px; +} + +.coverage-summary > i b { + display: block; + height: 100%; + background: var(--green); +} + +.course-gap-list > span { + display: grid; + grid-template-columns: 30px 1fr; + gap: 3px 10px; + padding: 12px; + background: #f8faf8; + border-radius: 9px; +} + +.course-gap-list b { + grid-row: 1 / 3; + color: var(--red); +} + +/* 抽屉 */ +.data-ops-backdrop, +.workspace-detail-backdrop { + position: fixed; + z-index: 125; + inset: 0; + background: rgba(8, 25, 19, 0.54); + backdrop-filter: blur(4px); + opacity: 0; + pointer-events: none; + transition: opacity 0.22s ease; +} + +.data-ops-backdrop.open, +.workspace-detail-backdrop.open { + opacity: 1; + pointer-events: auto; +} + +.data-ops-drawer, +.workspace-detail-drawer { + position: absolute; + top: 0; + right: 0; + display: flex; + width: min(780px, 94vw); + height: 100%; + flex-direction: column; + overflow: hidden; + background: #f6f8f5; + box-shadow: -24px 0 70px rgba(10, 32, 23, 0.22); + transform: translateX(24px); + transition: transform 0.22s ease; +} + +.workspace-detail-drawer { + width: min(680px, 94vw); +} + +.data-ops-backdrop.open .data-ops-drawer, +.workspace-detail-backdrop.open .workspace-detail-drawer { + transform: translateX(0); +} + +.data-ops-header, +.workspace-detail-header { + display: flex; + flex: 0 0 auto; + align-items: flex-start; + justify-content: space-between; + gap: 20px; + padding: 25px 26px 20px; + background: white; + border-bottom: 1px solid var(--line); +} + +.data-ops-header > div > span, +.workspace-detail-header > div > span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.09em; +} + +.data-ops-header h2, +.workspace-detail-header h2 { + margin: 6px 0 5px; + font-size: 25px; +} + +.data-ops-header p, +.workspace-detail-header p { + margin: 0; + color: var(--muted); + font-size: 14px; +} + +.data-ops-header button, +.workspace-detail-header button, +.product-tour-close, +.showcase-header-actions button { + display: grid; + width: 38px; + height: 38px; + flex: 0 0 auto; + place-items: center; + color: var(--muted); + background: #f0f4f1; + border-radius: 10px; +} + +.data-ops-header button svg, +.workspace-detail-header button svg, +.product-tour-close svg, +.showcase-header-actions button svg { + width: 17px; + height: 17px; +} + +.data-ops-tabs { + display: flex; + flex: 0 0 auto; + gap: 5px; + padding: 10px 22px; + overflow-x: auto; + background: white; + border-bottom: 1px solid var(--line); +} + +.data-ops-tabs button { + flex: 0 0 auto; + padding: 8px 11px; + color: var(--muted); + background: transparent; + border-radius: 8px; + font-size: 13px; +} + +.data-ops-tabs button.active { + color: white; + background: var(--green); + font-weight: 700; +} + +.data-ops-content, +.workspace-detail-content { + min-height: 0; + flex: 1; + padding: 20px 24px 34px; + overflow-y: auto; +} + +.data-ops-footer, +.workspace-detail-footer { + display: flex; + flex: 0 0 auto; + justify-content: flex-end; + gap: 9px; + padding: 14px 22px; + background: white; + border-top: 1px solid var(--line); +} + +.data-ops-stat-grid, +.batch-update-summary, +.authorization-summary-grid, +.workspace-metric-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 9px; +} + +.batch-update-summary, +.authorization-summary-grid, +.workspace-metric-grid { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +.data-ops-stat-grid > span, +.batch-update-summary > span, +.authorization-summary-grid > span, +.workspace-metric-grid > span { + min-width: 0; + padding: 14px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.data-ops-stat-grid small, +.data-ops-stat-grid strong, +.data-ops-stat-grid em, +.batch-update-summary small, +.batch-update-summary strong, +.batch-update-summary em, +.authorization-summary-grid small, +.authorization-summary-grid strong, +.authorization-summary-grid em, +.workspace-metric-grid small, +.workspace-metric-grid strong, +.workspace-metric-grid em { + display: block; +} + +.data-ops-stat-grid small, +.batch-update-summary small, +.authorization-summary-grid small, +.workspace-metric-grid small { + color: var(--muted); + font-size: 13px; +} + +.data-ops-stat-grid strong, +.batch-update-summary strong, +.authorization-summary-grid strong, +.workspace-metric-grid strong { + margin: 7px 0 4px; + font-size: 17px; +} + +.data-ops-stat-grid em, +.batch-update-summary em, +.authorization-summary-grid em, +.workspace-metric-grid em { + color: var(--green-2); + font-size: 13px; + font-style: normal; +} + +.data-ops-highlight, +.data-issue-hero, +.data-authorization-card { + margin-top: 12px; + padding: 18px; + color: #eaf3ef; + background: linear-gradient(135deg, #174535, #102f26); + border-radius: 13px; +} + +.data-ops-highlight > span, +.data-issue-hero > span, +.data-authorization-card > span { + color: var(--lime); + font-size: 13px; + font-weight: 800; +} + +.data-ops-highlight > strong, +.data-issue-hero h3, +.data-authorization-card > strong { + display: block; + margin: 7px 0 6px; + color: white; + font-size: 17px; +} + +.data-ops-highlight p, +.data-issue-hero p, +.data-authorization-card p { + margin: 0; + color: #a8bdb5; + font-size: 14px; + line-height: 1.7; +} + +.data-authorization-card > div { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + margin-top: 14px; +} + +.data-authorization-card > div span { + padding: 10px; + color: #8fa99e; + background: rgba(255, 255, 255, 0.055); + border-radius: 8px; + font-size: 13px; +} + +.data-authorization-card > div strong { + display: block; + margin-top: 4px; + color: white; + font-size: 14px; + overflow-wrap: anywhere; +} + +.data-ops-two-column { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 11px; + margin-top: 12px; +} + +.data-ops-card, +.workspace-detail-card { + margin-top: 12px; + padding: 17px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.data-ops-card h3, +.workspace-detail-card h3 { + margin: 0 0 12px; + font-size: 16px; +} + +.data-ops-card p, +.workspace-detail-card p, +.data-ops-card li { + color: var(--muted); + font-size: 14px; + line-height: 1.75; +} + +.data-ops-card ul { + margin: 10px 0 0; + padding-left: 20px; +} + +.data-ops-card dl { + margin: 0; +} + +.data-ops-card dl > div { + display: grid; + grid-template-columns: 115px 1fr; + gap: 10px; + padding: 9px 0; + border-bottom: 1px solid var(--line-soft); +} + +.data-ops-card dl > div:last-child { + border-bottom: 0; +} + +.data-ops-card dt { + color: var(--muted); + font-size: 13px; +} + +.data-ops-card dd { + margin: 0; + font-size: 14px; + font-weight: 600; +} + +.data-ops-state { + display: inline-flex; + padding: 4px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 13px; +} + +.data-ops-state.warning { + color: #9a6818; + background: var(--amber-soft); +} + +.data-quality-meter { + display: grid; + grid-template-columns: 1fr auto; + align-items: center; + gap: 12px; +} + +.data-quality-meter > i { + height: 12px; + overflow: hidden; + background: #e7eee9; + border-radius: 7px; +} + +.data-quality-meter > i b { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #72b893); +} + +.data-quality-meter > strong { + color: var(--green); + font-size: 20px; +} + +.data-contract-hero { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 9px; +} + +.data-contract-hero > div { + padding: 16px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.data-contract-hero span, +.data-contract-hero strong, +.data-contract-hero small { + display: block; +} + +.data-contract-hero span, +.data-contract-hero small { + color: var(--muted); + font-size: 13px; +} + +.data-contract-hero strong { + margin: 7px 0 4px; + font-size: 15px; + word-break: break-word; +} + +.data-requirement-steps { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 8px; +} + +.data-requirement-steps > span { + padding: 12px; + background: #f7faf7; + border-radius: 9px; +} + +.data-requirement-steps b, +.data-requirement-steps strong, +.data-requirement-steps small { + display: block; +} + +.data-requirement-steps b { + color: var(--green); + font-size: 13px; +} + +.data-requirement-steps strong { + margin: 6px 0 5px; + font-size: 14px; +} + +.data-requirement-steps small { + color: var(--muted); + font-size: 13px; + line-height: 1.6; +} + +.data-field-tags, +.workspace-tag-row { + display: flex; + flex-wrap: wrap; + gap: 7px; +} + +.data-field-tags span, +.workspace-tag-row span { + padding: 7px 9px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 13px; + font-weight: 600; +} + +.data-ops-table { + width: 100%; + border-collapse: collapse; +} + +.data-ops-table th, +.data-ops-table td { + padding: 11px 9px; + border-bottom: 1px solid var(--line-soft); + font-size: 13px; + text-align: left; +} + +.data-ops-table th { + color: var(--muted); + background: #f5f8f5; +} + +.data-task-banner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 15px; + padding: 14px 16px; + color: var(--green); + background: var(--green-soft); + border: 1px solid #d4e7dc; + border-radius: 11px; +} + +.data-task-banner.warning { + color: #9b6816; + background: var(--amber-soft); +} + +.data-task-banner span { + display: flex; + align-items: center; + gap: 9px; +} + +.data-task-banner span i { + width: 8px; + height: 8px; + background: currentColor; + border-radius: 50%; +} + +.data-task-banner strong, +.data-task-banner em { + font-size: 14px; +} + +.data-task-banner em { + font-style: normal; + font-weight: 700; +} + +.data-version-timeline { + position: relative; + margin-top: 14px; + padding: 4px 0 4px 23px; +} + +.data-version-timeline::before { + position: absolute; + top: 10px; + bottom: 10px; + left: 8px; + width: 2px; + background: #dbe5df; + content: ""; +} + +.data-version-timeline article { + position: relative; + padding: 0 0 20px 15px; +} + +.data-version-timeline article > i { + position: absolute; + top: 5px; + left: -22px; + width: 13px; + height: 13px; + background: #b5c3ba; + border: 3px solid #f6f8f5; + border-radius: 50%; +} + +.data-version-timeline article.active > i { + background: var(--green); +} + +.data-version-timeline article.warning > i { + background: var(--amber); +} + +.data-version-timeline span, +.data-version-timeline strong, +.data-version-timeline small { + display: block; +} + +.data-version-timeline span { + color: var(--green); + font-size: 13px; + font-weight: 800; +} + +.data-version-timeline strong { + margin: 4px 0; + font-size: 14px; +} + +.data-version-timeline p { + margin: 4px 0; + color: var(--muted); + font-size: 14px; +} + +.data-version-timeline small { + color: #8a9690; + font-size: 13px; +} + +.data-audit-list, +.workspace-log-list { + display: flex; + flex-direction: column; +} + +.data-audit-list > span, +.workspace-log-list > span { + position: relative; + padding: 11px 0 11px 18px; + border-bottom: 1px solid var(--line-soft); +} + +.data-audit-list strong, +.data-audit-list small, +.workspace-log-list strong, +.workspace-log-list small { + display: block; +} + +.data-audit-list strong, +.workspace-log-list strong { + font-size: 14px; +} + +.data-audit-list small, +.workspace-log-list small { + margin-top: 4px; + color: var(--muted); + font-size: 13px; +} + +.data-wizard-progress { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + padding: 12px; + background: white; + border-radius: 11px; +} + +.data-wizard-progress span { + display: flex; + align-items: center; + gap: 6px; + color: var(--muted); + font-size: 13px; +} + +.data-wizard-progress span b { + display: grid; + width: 25px; + height: 25px; + place-items: center; + background: #edf2ee; + border-radius: 7px; +} + +.data-wizard-progress span.active { + color: var(--green); + font-weight: 700; +} + +.data-wizard-progress span.active b { + color: white; + background: var(--green); +} + +.data-wizard-progress > i { + width: 24px; + height: 1px; + background: #d7e0da; +} + +.data-source-methods { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; +} + +.data-source-methods button { + padding: 13px; + background: #f7f9f7; + border: 1px solid var(--line-soft); + border-radius: 9px; + text-align: left; +} + +.data-source-methods button.active { + background: var(--green-soft); + border-color: #bddcc9; +} + +.data-source-methods strong, +.data-source-methods small { + display: block; +} + +.data-source-methods strong { + font-size: 14px; +} + +.data-source-methods small { + margin-top: 4px; + color: var(--muted); + font-size: 13px; +} + +.data-form-grid, +.workspace-form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + margin-top: 16px; +} + +.data-form-grid label.full, +.workspace-form-grid label.full { + grid-column: 1 / -1; +} + +.data-form-grid label > span, +.workspace-form-grid label > span { + display: block; + margin-bottom: 6px; + color: var(--ink-soft); + font-size: 13px; + font-weight: 600; +} + +.data-form-grid input, +.data-form-grid select, +.data-form-grid textarea, +.workspace-form-grid input, +.workspace-form-grid select, +.workspace-form-grid textarea { + width: 100%; + padding: 10px 11px; + background: #fafbf9; + border: 1px solid var(--line); + border-radius: 8px; + font-size: 14px; +} + +.data-impact-grid, +.security-control-grid, +.workspace-evidence-list { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; +} + +.security-control-grid { + grid-template-columns: repeat(2, 1fr); +} + +.data-impact-grid span, +.security-control-grid span, +.workspace-evidence-list span { + padding: 11px; + color: var(--muted); + background: #f7f9f7; + border-radius: 8px; + font-size: 13px; +} + +.data-impact-grid strong, +.security-control-grid strong, +.workspace-evidence-list strong { + display: block; + margin-top: 5px; + color: var(--ink); + font-size: 14px; +} + +.batch-source-list { + display: flex; + flex-direction: column; +} + +.batch-source-list label { + display: grid; + grid-template-columns: 18px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 11px 0; + border-bottom: 1px solid var(--line-soft); +} + +.batch-source-list input { + width: 17px; + height: 17px; + accent-color: var(--green); +} + +.batch-source-list strong, +.batch-source-list small { + display: block; +} + +.batch-source-list strong { + font-size: 14px; +} + +.batch-source-list small, +.batch-source-list em { + color: var(--muted); + font-size: 13px; +} + +.batch-source-list em { + color: var(--green); + font-style: normal; + font-weight: 600; +} + +.batch-source-list em.warning { + color: #9b6816; +} + +.source-card-actions { + display: inline-flex !important; + align-items: center; + gap: 6px; +} + +.source-card-actions button:first-child { + color: var(--ink-soft); + background: white; + border: 1px solid var(--line); +} + +.platform-contract-summary { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; +} + +.platform-contract-summary span { + padding: 9px; + color: var(--muted); + background: white; + border-radius: 8px; + font-size: 13px; +} + +.platform-contract-summary strong { + display: block; + margin-top: 5px; + color: var(--ink); +} + +/* 业务详情 */ +.milestone-list { + position: relative; + padding-left: 22px; +} + +.milestone-list::before { + position: absolute; + top: 12px; + bottom: 12px; + left: 7px; + width: 2px; + background: #dfe7e1; + content: ""; +} + +.milestone-list > span { + position: relative; + display: block; + padding: 8px 0 14px; +} + +.milestone-list > span i { + position: absolute; + top: 12px; + left: -21px; + width: 12px; + height: 12px; + background: #bdc9c1; + border: 3px solid white; + border-radius: 50%; +} + +.milestone-list > span.done i { + background: var(--green); +} + +.milestone-list > span.active i { + background: var(--lime); +} + +.milestone-list strong, +.milestone-list small { + display: block; +} + +.milestone-list strong { + font-size: 14px; +} + +.milestone-list small { + margin-top: 4px; + color: var(--muted); + font-size: 13px; +} + +.notification-list, +.organization-list { + display: flex; + flex-direction: column; + gap: 9px; +} + +.notification-list button, +.organization-list button { + display: grid; + width: 100%; + grid-template-columns: 12px minmax(0, 1fr) auto; + align-items: center; + gap: 11px; + padding: 14px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 11px; + text-align: left; +} + +.organization-list button { + grid-template-columns: 42px minmax(0, 1fr) auto; +} + +.organization-list button.active { + background: var(--green-soft); +} + +.notification-list > button > i { + width: 9px; + height: 9px; + background: var(--green); + border-radius: 50%; +} + +.notification-list > button > i.red { + background: var(--red); +} + +.notification-list > button > i.amber { + background: var(--amber); +} + +.notification-list strong, +.notification-list small, +.organization-list strong, +.organization-list small { + display: block; +} + +.notification-list strong, +.organization-list strong { + font-size: 14px; +} + +.notification-list small, +.organization-list small { + margin-top: 4px; + color: var(--muted); + font-size: 13px; +} + +.notification-list em, +.organization-list em { + color: var(--green); + font-size: 13px; + font-style: normal; + font-weight: 700; +} + +.template-library { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +.template-library article { + padding: 17px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.template-library span, +.template-library strong, +.template-library small, +.template-library em { + display: block; +} + +.template-library span { + color: var(--green); + font-size: 13px; + font-weight: 800; +} + +.template-library strong { + margin: 8px 0; + font-size: 15px; +} + +.template-library small, +.template-library em { + color: var(--muted); + font-size: 13px; +} + +.template-library em { + margin-top: 12px; + color: var(--green-2); + font-style: normal; +} + +.compare-table-wrap { + overflow-x: auto; + background: white; + border-radius: 11px; +} + +.industry-detail-list { + display: flex; + flex-direction: column; + gap: 10px; +} + +.industry-detail-list > span { + display: grid; + grid-template-columns: 30px 155px minmax(0, 1fr) 50px 80px; + align-items: center; + gap: 9px; + padding: 12px 13px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.industry-detail-list b, +.industry-detail-list small { + color: var(--green); + font-size: 13px; +} + +.industry-detail-list strong { + font-size: 14px; +} + +.industry-detail-list > span > i { + height: 8px; + overflow: hidden; + background: #edf1ee; + border-radius: 5px; +} + +.industry-detail-list > span > i em { + display: block; + height: 100%; + background: var(--green); +} + +.industry-detail-list > span > em { + color: var(--muted); + font-size: 13px; + font-style: normal; +} + +.inline-empty-state { + display: grid; + min-height: 160px; + place-items: center; + align-content: center; + gap: 6px; + color: var(--muted); + text-align: center; +} + +.inline-empty-state strong { + color: var(--ink); + font-size: 15px; +} + +.inline-empty-state small { + font-size: 13px; +} + +/* 产品导览 */ +.product-tour-backdrop { + position: fixed; + z-index: 155; + inset: 0; + display: grid; + place-items: center; + padding: 24px; + background: rgba(7, 24, 17, 0.66); + backdrop-filter: blur(8px); + opacity: 0; + pointer-events: none; + transition: opacity 0.22s ease; +} + +.product-tour-backdrop.open { + opacity: 1; + pointer-events: auto; +} + +.product-tour-modal { + position: relative; + width: min(900px, 100%); + max-height: calc(100vh - 48px); + padding: 34px; + overflow-y: auto; + background: radial-gradient(circle at 94% 2%, rgba(198, 230, 111, 0.22), transparent 27%), white; + border-radius: 22px; + box-shadow: 0 28px 90px rgba(5, 25, 17, 0.28); +} + +.product-tour-close { + position: absolute; + top: 18px; + right: 18px; +} + +.product-tour-hero { + max-width: 690px; +} + +.product-tour-hero > span { + color: var(--green-2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.12em; +} + +.product-tour-hero h2 { + margin: 8px 0 10px; + font-size: 34px; +} + +.product-tour-hero p { + margin: 0; + color: var(--muted); + font-size: 16px; + line-height: 1.75; +} + +.tour-value-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 11px; + margin-top: 24px; +} + +.tour-value-grid article { + padding: 17px; + background: #f7faf7; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.tour-value-grid i, +.tour-value-grid strong, +.tour-value-grid span { + display: block; +} + +.tour-value-grid i { + color: var(--green); + font-size: 13px; + font-style: normal; + font-weight: 800; +} + +.tour-value-grid strong { + margin: 8px 0 5px; + font-size: 18px; +} + +.tour-value-grid span { + color: var(--muted); + font-size: 14px; + line-height: 1.6; +} + +.tour-route { + display: flex; + align-items: center; + justify-content: center; + gap: 9px; + margin-top: 22px; + padding: 16px; + color: #e7f2ec; + background: #143d31; + border-radius: 13px; +} + +.tour-route span { + display: flex; + align-items: center; + gap: 7px; + font-size: 14px; + font-weight: 700; +} + +.tour-route span b { + display: grid; + width: 26px; + height: 26px; + place-items: center; + color: #173c30; + background: var(--lime); + border-radius: 7px; + font-size: 13px; +} + +.tour-route > i { + width: 28px; + height: 1px; + background: #6b887d; +} + +.product-tour-actions { + display: flex; + justify-content: flex-end; + gap: 9px; + margin-top: 22px; +} + +.product-tour-modal > small { + display: block; + margin-top: 14px; + color: var(--muted); + font-size: 13px; + text-align: right; +} + +.product-tour-coach { + position: fixed; + z-index: 150; + right: 26px; + bottom: 26px; + width: min(390px, calc(100vw - 32px)); + padding: 20px; + color: white; + background: linear-gradient(145deg, #163f32, #0f2e25); + border: 1px solid rgba(198, 230, 111, 0.2); + border-radius: 16px; + box-shadow: 0 20px 60px rgba(6, 25, 17, 0.28); +} + +.tour-coach-head { + display: flex; + align-items: center; + justify-content: space-between; +} + +.tour-coach-head > span { + color: var(--lime); + font-size: 13px; + font-weight: 800; +} + +.tour-coach-head button { + display: grid; + width: 30px; + height: 30px; + place-items: center; + color: #a8beb5; + background: rgba(255, 255, 255, 0.06); + border-radius: 8px; +} + +.tour-coach-head svg { + width: 14px; + height: 14px; +} + +.product-tour-coach > strong { + display: block; + margin-top: 10px; + font-size: 19px; +} + +.product-tour-coach > p { + margin: 7px 0 15px; + color: #abc0b8; + font-size: 14px; + line-height: 1.7; +} + +.tour-coach-actions { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.tour-coach-actions button { + padding: 8px 12px; + color: #163d31; + background: var(--lime); + border-radius: 8px; + font-size: 13px; + font-weight: 700; +} + +.tour-coach-actions button:first-child { + color: #dce9e3; + background: rgba(255, 255, 255, 0.09); +} + +.tour-target { + position: relative; + z-index: 145; + outline: 4px solid var(--lime); + outline-offset: 5px; + box-shadow: 0 0 0 9999px rgba(7, 25, 17, 0.38), var(--shadow-high) !important; +} + +/* 展示大屏 */ +.showcase-screen { + position: fixed; + z-index: 180; + inset: 0; + min-width: 960px; + overflow: auto; + color: #e8f2ed; + background: radial-gradient(circle at 82% 8%, rgba(198, 230, 111, 0.1), transparent 30%), linear-gradient(155deg, #0e2b23, #071d18 72%); + opacity: 0; + pointer-events: none; + transform: scale(1.01); + transition: opacity 0.25s ease, transform 0.25s ease; +} + +.showcase-screen.open { + opacity: 1; + pointer-events: auto; + transform: scale(1); +} + +.showcase-header { + display: flex; + height: 86px; + align-items: center; + justify-content: space-between; + padding: 0 34px; + background: rgba(255, 255, 255, 0.025); + border-bottom: 1px solid rgba(255, 255, 255, 0.09); +} + +.showcase-brand, +.showcase-brand > span:last-child { + display: flex; + align-items: center; +} + +.showcase-brand { + gap: 14px; +} + +.showcase-brand > span:last-child { + align-items: flex-start; + flex-direction: column; +} + +.showcase-brand strong { + color: white; + font-size: 20px; +} + +.showcase-brand small { + margin-top: 4px; + color: #78968a; + font-size: 13px; +} + +.showcase-brand-mark { + position: relative; + width: 40px; + height: 40px; +} + +.showcase-brand-mark i { + position: absolute; + width: 24px; + height: 9px; + background: var(--lime); + border-radius: 3px 9px 3px 9px; + transform: skewX(-12deg); +} + +.showcase-brand-mark i:nth-child(1) { + top: 3px; +} + +.showcase-brand-mark i:nth-child(2) { + top: 15px; + left: 7px; + opacity: 0.75; +} + +.showcase-brand-mark i:nth-child(3) { + top: 27px; + left: 14px; + opacity: 0.5; +} + +.showcase-header-actions { + display: flex; + align-items: center; + gap: 16px; +} + +.showcase-header-actions > span { + display: flex; + align-items: center; + gap: 8px; + color: #8eaaa0; + font-size: 13px; +} + +.showcase-header-actions > span i { + width: 8px; + height: 8px; + background: var(--lime); + border-radius: 50%; +} + +.showcase-header-actions button { + color: #bad0c6; + background: rgba(255, 255, 255, 0.06); +} + +.showcase-content { + min-height: calc(100vh - 86px); + padding: 26px 34px 22px; +} + +.showcase-title { + display: flex; + align-items: center; + justify-content: space-between; + gap: 35px; +} + +.showcase-title > div:first-child > span { + color: var(--lime); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.15em; +} + +.showcase-title h2 { + margin: 7px 0 4px; + color: white; + font-size: clamp(26px, 2.5vw, 38px); +} + +.showcase-title p { + margin: 0; + color: #769387; + font-size: 14px; +} + +.showcase-score { + display: grid; + min-width: 225px; + grid-template-columns: auto 1fr; + align-items: center; + gap: 0 13px; + padding: 16px 20px; + background: rgba(255, 255, 255, 0.045); + border: 1px solid rgba(198, 230, 111, 0.15); + border-radius: 14px; +} + +.showcase-score strong { + grid-row: 1 / 3; + color: var(--lime); + font-size: 43px; +} + +.showcase-score span { + color: white; + font-size: 14px; + font-weight: 700; +} + +.showcase-score em { + color: #7fc39f; + font-size: 13px; + font-style: normal; +} + +.showcase-metrics { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; + margin-top: 20px; +} + +.showcase-metrics article, +.showcase-panel { + padding: 16px 18px; + background: rgba(255, 255, 255, 0.045); + border: 1px solid rgba(255, 255, 255, 0.08); + border-radius: 12px; +} + +.showcase-metrics span, +.showcase-metrics strong, +.showcase-metrics em { + display: block; +} + +.showcase-metrics span, +.showcase-metrics em { + color: #89a69a; + font-size: 13px; +} + +.showcase-metrics strong { + margin: 5px 0 2px; + color: white; + font-size: 27px; +} + +.showcase-metrics strong small { + margin-left: 4px; + color: #8ba69b; + font-size: 13px; +} + +.showcase-metrics em { + color: #7fc39f; + font-style: normal; +} + +.showcase-main-grid { + display: grid; + grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); + gap: 12px; + margin-top: 12px; +} + +.showcase-panel { + min-width: 0; + padding: 18px; +} + +.showcase-focus { + grid-column: 1 / -1; +} + +.showcase-panel-head { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 15px; +} + +.showcase-panel-head span { + color: white; + font-size: 16px; + font-weight: 700; +} + +.showcase-panel-head strong { + color: #617e72; + font-size: 13px; +} + +.showcase-rank-list, +.showcase-focus-list { + display: flex; + flex-direction: column; + gap: 8px; +} + +.showcase-rank-list > span { + display: grid; + grid-template-columns: 32px 150px minmax(0, 1fr) 43px; + align-items: center; + gap: 10px; +} + +.showcase-rank-list b, +.showcase-rank-list small { + color: var(--lime); + font-size: 13px; +} + +.showcase-rank-list strong { + font-size: 14px; +} + +.showcase-rank-list > span > i { + height: 9px; + overflow: hidden; + background: rgba(255, 255, 255, 0.08); + border-radius: 5px; +} + +.showcase-rank-list > span > i em { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--lime), #69bc92); +} + +.showcase-growth-chart { + display: flex; + min-height: 220px; + align-items: flex-end; + justify-content: space-around; + gap: 9px; +} + +.showcase-growth-chart > span { + display: flex; + min-width: 0; + flex: 1; + align-items: center; + flex-direction: column; +} + +.showcase-growth-chart > span::before { + width: min(55px, 80%); + height: calc(var(--value) * 1.7px); + max-height: 165px; + background: linear-gradient(180deg, var(--lime), #1f7a58); + border-radius: 9px 9px 2px 2px; + content: ""; +} + +.showcase-growth-chart i, +.showcase-growth-chart b { + margin-top: 7px; + color: #91ada1; + font-size: 13px; + font-style: normal; + text-align: center; +} + +.showcase-growth-chart b { + margin-top: 2px; + color: var(--lime); +} + +.showcase-focus-list { + display: grid; + grid-template-columns: repeat(3, 1fr); +} + +.showcase-focus-list > span { + display: grid; + grid-template-columns: 36px 1fr; + gap: 3px 10px; + padding: 13px; + background: rgba(255, 255, 255, 0.035); + border-radius: 9px; +} + +.showcase-focus-list b { + display: grid; + width: 34px; + height: 34px; + grid-row: 1 / 3; + place-items: center; + color: #173a2e; + background: var(--lime); + border-radius: 8px; + font-size: 13px; +} + +.showcase-focus-list strong { + color: white; + font-size: 14px; +} + +.showcase-focus-list small { + color: #7f9b90; + font-size: 13px; +} + +.showcase-footer { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 12px; + color: #668278; + font-size: 13px; +} + +.showcase-footer strong { + color: #9bb7ab; + font-size: 13px; +} + +/* 统一可读性:企业展示不使用小于13px的业务文字 */ +body small, +body button, +body input, +body select, +body textarea { + font-size: 13px !important; +} + +.app-shell .main-content span, +.app-shell .main-content em { + font-size: 13px !important; +} + +.app-shell .main-content .panel-kicker, +.app-shell .main-content .match-summary strong, +.app-shell .main-content .skill-gap strong, +.app-shell .main-content .project-progress strong, +.app-shell .main-content .health-score strong, +.app-shell .main-content .action-health strong, +.app-shell .main-content .lineage-flow span, +.app-shell .main-content .issue-list strong { + font-size: 13px !important; +} + +.app-shell .main-content .profile-banner span, +.app-shell .main-content .report-stat-grid span, +.app-shell .main-content .report-stat-grid em, +.app-shell .main-content .recommendation-evidence, +.app-shell .main-content #reportListSummary { + font-size: 14px !important; +} + +.app-shell .school-card strong, +.app-shell .role-avatar, +.app-shell .notification-button > span { + font-size: 13px !important; +} + +.app-shell .notification-button > span { + width: 20px; + height: 20px; +} + +.brand small, +.nav-label, +.school-card span, +.sync-line, +.meeting-pack small, +.meeting-pack strong, +.nav-count, +.breadcrumb, +.role-copy small, +.edition-badge, +.quality-main strong, +.quality-main span, +.metric-label, +.metric-foot, +.metric-tag, +.chart-legend, +.chart-labels, +.panel-kicker, +.status-badge, +.gap-badge, +.source-summary-foot, +.source-summary-metrics, +.source-filter-result, +.source-category-badge, +.source-commercial-badge, +.source-status, +.source-license-grid span, +.source-card-meta span, +.source-card-foot span, +.report-featured-label, +.report-type-badge, +.featured-report-meta, +.featured-report-cover small, +.featured-report-cover span, +.report-list-meta, +.report-list-side em, +.modal-kicker, +.modal small, +.toast small, +.tooltip { + font-size: 13px !important; +} + +.toast strong { + font-size: 14px !important; +} + +.toast small { + color: #c2d3cb; + line-height: 1.55; +} + +.main-content small, +.main-content .data-table th, +.main-content .data-table td, +.main-content .priority-mark, +.main-content .owner-avatar, +.main-content .partner-avatar, +.main-content .task-progress-cell span, +.modal label > span, +.modal button, +.modal input, +.modal select, +.modal textarea { + font-size: 13px !important; +} + +.recommendation-copy strong { + font-size: 15px !important; +} + +.recommendation-evidence { + font-size: 14px !important; +} + +.report-reader small, +.report-reader .report-toc-label, +.report-reader .report-toc button, +.report-reader .report-reader-meta span, +.report-reader .report-reader-meta strong, +.report-reader .report-standard-stamp, +.report-reader .report-cover-foot span, +.report-reader .report-section-heading small, +.report-reader .report-metric-grid span, +.report-reader .report-metric-grid small, +.report-reader .report-source-tag, +.report-reader .report-confidence, +.report-reader .report-action-priority, +.report-reader .report-action-card button, +.report-reader .report-evidence-code, +.report-reader .report-profile-code, +.report-reader .report-profile-label, +.report-reader .report-proof-chain small, +.report-reader .report-method-steps p, +.report-reader .report-action-cycle small { + font-size: 13px !important; +} + +.report-reader .report-finding small, +.report-reader .report-action-card small, +.report-reader .report-chart-card figcaption, +.report-reader .report-interpretation p, +.report-reader .report-table td { + font-size: 14px !important; +} + +.report-reader .report-table th { + font-size: 13px !important; +} + +.report-reader .reader-version, +.report-reader .report-document summary, +.report-reader .report-document .report-chart-head > span, +.report-reader .report-document .report-profile-kicker, +.report-reader .report-document .report-profile-attributes strong, +.report-reader .report-document .report-profile-stat-grid article > em, +.report-reader .report-document .report-profile-stat-grid details strong, +.report-reader .report-document .report-benchmark-strip em, +.report-reader .report-document .report-interpretation > span, +.report-reader .report-document .report-finding-validation strong, +.report-reader .report-document .report-finding-validation span, +.report-reader .report-document .report-finding-validation i, +.report-reader .report-document .report-proof-chain i, +.report-reader .report-document .report-proof-chain strong, +.report-reader .report-document .report-method-steps article > span, +.report-reader .report-document .report-method-steps strong, +.report-reader .report-document .report-action-cycle strong { + font-size: 13px !important; +} + +.report-reader .report-document .report-evidence-table td strong, +.report-reader .report-document .report-evidence-notice strong { + font-size: 13px !important; +} + +.report-reader .report-document svg text { + font-size: 13px !important; +} + +.report-reader .report-document p, +.report-reader .report-document li, +.report-reader .report-document .report-method-note, +.report-reader .report-document .report-evidence-notice p { + font-size: 14px !important; +} + +@media (max-width: 900px) { + .tour-launch span { + display: none; + } + + .tour-launch { + width: 40px; + padding: 0; + justify-content: center; + } + + .profession-detail-grid, + .data-ops-two-column, + .template-library { + grid-template-columns: 1fr; + } + + .profession-detail-panel.wide { + grid-column: auto; + } + + .job-flow-board { + grid-template-columns: 120px 65px minmax(260px, 1fr); + overflow-x: auto; + } + + .data-ops-stat-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .data-requirement-steps { + grid-template-columns: 1fr 1fr; + } + + .tour-value-grid { + grid-template-columns: 1fr; + } + + .tour-route { + align-items: stretch; + flex-direction: column; + } + + .tour-route > i { + width: 1px; + height: 13px; + margin-left: 13px; + } +} + +@media (max-width: 680px) { + .showcase-screen { + width: 100vw; + min-width: 0; + } + + .showcase-header { + min-height: 74px; + height: auto; + gap: 12px; + padding: 12px 15px; + } + + .showcase-brand { + min-width: 0; + gap: 9px; + } + + .showcase-brand strong { + font-size: 15px; + } + + .showcase-brand small, + .showcase-header-actions > span { + display: none; + } + + .showcase-content { + min-height: calc(100vh - 74px); + padding: 18px 14px 24px; + } + + .showcase-title { + align-items: stretch; + flex-direction: column; + gap: 15px; + } + + .showcase-title h2 { + font-size: 27px; + } + + .showcase-score { + width: 100%; + } + + .showcase-metrics { + grid-template-columns: 1fr 1fr; + } + + .showcase-main-grid { + grid-template-columns: 1fr; + } + + .showcase-focus { + grid-column: auto; + } + + .showcase-rank-list > span { + grid-template-columns: 25px 112px minmax(0, 1fr) 36px; + gap: 7px; + } + + .showcase-growth-chart { + min-height: 200px; + } + + .showcase-focus-list { + grid-template-columns: 1fr; + } + + .showcase-footer { + align-items: flex-start; + flex-direction: column; + gap: 7px; + } + + .data-ops-drawer, + .workspace-detail-drawer { + width: 100vw; + } + + .data-ops-header, + .workspace-detail-header { + padding: 20px 18px 16px; + } + + .data-ops-content, + .workspace-detail-content { + padding: 16px 15px 28px; + } + + .data-ops-stat-grid, + .batch-update-summary, + .authorization-summary-grid, + .workspace-metric-grid, + .data-contract-hero, + .data-authorization-card > div, + .data-impact-grid, + .security-control-grid, + .workspace-evidence-list { + grid-template-columns: 1fr 1fr; + } + + .data-requirement-steps, + .data-source-methods, + .data-form-grid, + .workspace-form-grid { + grid-template-columns: 1fr; + } + + .data-form-grid label.full, + .workspace-form-grid label.full { + grid-column: auto; + } + + .data-wizard-progress { + align-items: flex-start; + flex-direction: column; + } + + .data-wizard-progress > i { + width: 1px; + height: 10px; + margin-left: 12px; + } + + .profession-evidence-note { + grid-template-columns: 1fr; + } + + .profession-evidence-note > span, + .profession-evidence-note button { + justify-self: start; + } + + .salary-comparison > span { + grid-template-columns: 1fr 68px; + } + + .salary-comparison > span > i { + grid-column: 1 / -1; + grid-row: 2; + } + + .product-tour-backdrop { + padding: 10px; + } + + .product-tour-modal { + padding: 28px 20px 22px; + } + + .product-tour-hero h2 { + font-size: 28px; + } + + .product-tour-actions { + align-items: stretch; + flex-direction: column; + } + + .product-tour-actions .button { + width: 100%; + } + + .product-tour-coach { + right: 16px; + bottom: 16px; + } + + .industry-detail-list > span { + grid-template-columns: 28px 1fr 48px; + } + + .industry-detail-list > span > i, + .industry-detail-list > span > em { + grid-column: 2 / -1; + } +} + +/* 校园业务闭环 */ +.loop-identity-strip { + display: flex; + align-items: center; + gap: 9px; + flex-wrap: wrap; + margin-bottom: 16px; + padding: 14px 16px; + color: #dcebe4; + background: linear-gradient(135deg, #173f33, #102e26); + border-radius: 13px; +} + +.loop-identity-strip > strong { + color: var(--lime); + font-size: 14px; +} + +.loop-identity-strip > span { + padding: 5px 8px; + background: rgba(255, 255, 255, 0.07); + border-radius: 6px; + font-size: 13px; +} + +.loop-identity-strip b { + color: white; +} + +.loop-identity-strip > small { + width: 100%; + color: #a7beb4; + font-size: 13px; +} + +.loop-layout { + display: grid; + grid-template-columns: minmax(0, 1fr) 330px; + align-items: start; + gap: 16px; +} + +.loop-main { + display: flex; + min-width: 0; + flex-direction: column; + gap: 16px; +} + +.loop-action-panel { + position: sticky; + top: 86px; + min-width: 0; +} + +.loop-chain { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; +} + +.loop-stage { + display: grid; + min-width: 0; + grid-template-columns: 36px minmax(0, 1fr); + gap: 10px; + padding: 13px; + background: #f8faf8; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.loop-stage > i { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: var(--green); + background: #e7f3ed; + border-radius: 9px; + font-size: 13px; + font-style: normal; + font-weight: 800; +} + +.loop-stage.review > i { + color: #916217; + background: #fff6df; +} + +.loop-stage.risk > i { + color: #ad4e45; + background: #fff0ed; +} + +.loop-stage.done > i { + color: white; + background: var(--green); +} + +.loop-stage span, +.loop-stage small, +.loop-stage strong, +.loop-stage em { + display: block; + min-width: 0; +} + +.loop-stage small { + color: var(--muted); + font-size: 13px; +} + +.loop-stage strong { + margin: 3px 0; + overflow-wrap: anywhere; + font-size: 13px; +} + +.loop-stage em { + color: var(--green-2); + font-size: 13px; + font-style: normal; +} + +.loop-entity-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; +} + +.loop-entity-grid article { + min-width: 0; + padding: 15px; + background: #f9fbf9; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.loop-entity-grid span, +.loop-entity-grid strong, +.loop-entity-grid small { + display: block; + overflow-wrap: anywhere; +} + +.loop-entity-grid span { + color: var(--green); + font-size: 13px; + font-weight: 800; +} + +.loop-entity-grid strong { + margin: 8px 0; + font-size: 14px; +} + +.loop-entity-grid small { + margin-top: 5px; + color: var(--muted); + font-size: 13px; + line-height: 1.55; +} + +.loop-role-boundary { + margin-bottom: 12px; + padding: 13px; + color: #6e5423; + background: #fff9ec; + border: 1px solid #eee0bd; + border-radius: 10px; +} + +.loop-role-boundary strong, +.loop-role-boundary p { + font-size: 13px; +} + +.loop-role-boundary p { + margin: 5px 0 0; + line-height: 1.6; +} + +.loop-action-list { + display: flex; + flex-direction: column; + gap: 9px; +} + +.loop-action-list > button { + display: flex; + width: 100%; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 13px; + color: var(--ink); + background: white; + border: 1px solid var(--line-soft); + border-radius: 10px; + text-align: left; +} + +.loop-action-list button:disabled { + opacity: 0.58; + cursor: not-allowed; +} + +.loop-action-list span, +.loop-action-list strong, +.loop-action-list small { + display: block; +} + +.loop-action-list strong { + font-size: 14px; +} + +.loop-action-list small { + margin-top: 4px; + color: var(--muted); + font-size: 13px; + line-height: 1.45; +} + +.loop-action-list em { + flex: 0 0 auto; + color: var(--green); + font-size: 13px; + font-style: normal; + font-weight: 800; +} + +.loop-audit-list, +.report-approval-toolbar details > div { + display: flex; + max-height: 430px; + overflow-y: auto; + flex-direction: column; +} + +.loop-audit-list > span { + display: grid; + grid-template-columns: 12px 1fr; + gap: 3px 9px; + padding: 11px 0; + border-bottom: 1px solid var(--line-soft); +} + +.loop-audit-list i { + width: 8px; + height: 8px; + grid-row: 1 / 4; + margin-top: 5px; + background: var(--green); + border-radius: 50%; +} + +.loop-audit-list strong, +.loop-audit-list small, +.loop-audit-list em { + font-size: 13px; +} + +.loop-audit-list small { + color: var(--muted); +} + +.loop-audit-list em { + color: var(--green-2); + font-style: normal; +} + +.loop-modal { + width: min(680px, calc(100vw - 24px)); + max-height: calc(100vh - 36px); + overflow-y: auto; +} + +.loop-modal-fields { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + margin-top: 18px; +} + +.loop-modal-fields label { + display: flex; + min-width: 0; + flex-direction: column; + gap: 6px; +} + +.loop-modal-fields label:has(textarea) { + grid-column: 1 / -1; +} + +.loop-modal-fields span, +.loop-modal-fields input, +.loop-modal-fields select, +.loop-modal-fields textarea { + font-size: 13px; +} + +.loop-modal-fields input, +.loop-modal-fields select, +.loop-modal-fields textarea { + width: 100%; + padding: 10px 11px; + color: var(--ink); + background: white; + border: 1px solid var(--line); + border-radius: 8px; +} + +.loop-linked-id { + display: block; + margin: 5px 0; + color: var(--green-2); + font-size: 13px; + overflow-wrap: anywhere; +} + +.loop-inline-action { + margin-top: 13px; +} + +.loop-inline-actions { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin-top: 13px; +} + +.report-approval-toolbar { + position: relative; + z-index: 1; + display: flex; + min-height: 54px; + align-items: center; + gap: 12px; + flex-wrap: wrap; + padding: 9px 22px; + background: #f8faf8; + border-bottom: 1px solid var(--line); +} + +.report-approval-toolbar > span strong, +.report-approval-toolbar > span small { + display: block; + font-size: 13px; +} + +.report-flow-state.draft strong { + color: #9a651b; +} + +.report-flow-state.official strong { + color: var(--green); +} + +.report-approval-toolbar small, +.report-link-summary { + color: var(--muted); + font-size: 13px; +} + +.report-approval-toolbar details { + position: relative; + font-size: 13px; +} + +.report-approval-toolbar details > div { + position: absolute; + z-index: 3; + top: 28px; + right: 0; + width: min(420px, calc(100vw - 28px)); + max-height: 280px; + padding: 10px; + background: white; + border: 1px solid var(--line); + border-radius: 10px; + box-shadow: var(--shadow-high); +} + +.report-approval-toolbar details span { + display: block; + padding: 8px; + border-bottom: 1px solid var(--line-soft); +} + +.report-approval-toolbar details strong, +.report-approval-toolbar details small, +.report-approval-toolbar details em { + display: block; + font-size: 13px; +} + +.report-approval-toolbar details em { + color: var(--muted); + font-style: normal; +} + +.report-flow-actions { + display: flex; + gap: 8px; + margin-left: auto; +} + +@media (max-width: 1050px) { + .loop-layout { + grid-template-columns: 1fr; + } + + .loop-action-panel { + position: static; + } +} + +@media (max-width: 680px) { + .loop-chain, + .loop-entity-grid, + .loop-modal-fields { + grid-template-columns: 1fr; + } + + .loop-modal-fields label:has(textarea) { + grid-column: auto; + } + + .loop-identity-strip { + align-items: stretch; + flex-direction: column; + } + + .report-approval-toolbar { + align-items: stretch; + flex-direction: column; + padding: 9px 14px; + } + + .report-flow-actions { + width: 100%; + margin-left: 0; + } + + .report-flow-actions .button { + flex: 1; + } +} + +@media print { + body > .app-shell, + body > .toast-region, + body > .product-tour-backdrop, + body > .product-tour-coach, + body > .data-ops-backdrop, + body > .workspace-detail-backdrop, + body > .showcase-screen { + display: none !important; + } + + .report-reader { + position: static; + display: block; + opacity: 1; + pointer-events: auto; + transform: none; + } + + .report-reader-header, + .report-toc, + .report-flow-actions { + display: none; + } + + .report-approval-toolbar { + display: block; + padding: 8px; + } + + .report-reader-layout, + .report-document-wrap { + display: block; + overflow: visible; + } + + .report-document { + width: 100%; + margin: 0; + box-shadow: none; + } +} diff --git a/demo/favicon.svg b/demo/favicon.svg new file mode 100644 index 0000000..344d8bb --- /dev/null +++ b/demo/favicon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..868b364 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,1534 @@ + + + + + + + 产教融智 · 供需分析与协同平台 + + + + + +
+ + +
+
+
+ +
+ +

2025—2026 学年 · 第 2 学期

+
+
+
+ + 企业版 + + +
+
+ +
+ +
+
+
+
CAMPUS CLOSED LOOP
+

校园端业务闭环工作台

+

从企业需求到下一周期复核,一条样板链按角色推进、按实体留痕、刷新后继续。

+
+ +
+
+
+
+
+
+
实体状态链

样板闭环进度

+ SCHEMA V2 +
+
+
+
+
+
业务实体

关联对象与关键字段

+
+
+
+
+
+
AUDIT EVENTS

闭环审计事件

+ 0 条 +
+
+
+
+ +
+
+ + +
+
+
+
SCHOOL OVERVIEW
+

产教供需决策总览

+

把产业需求信号转化为专业建设任务,并用报告与改进证据形成决策闭环。

+
+
+ + +
+
+ +
+
+ + + +
+ 本期数据已通过质量校验 + 3 类数据资产 · 6 个数据源 · 128,642 条有效记录 · 岗位归一覆盖率 94.8% +
+
+ +
+ +
+
+
+ 全校供需匹配度 + +
+
78.6分
+
+ ↑ 4.2 + 较上期 +
+
+
+
+
+ 产业需求岗位 + 近90天 +
+
18,420个
+
+ ↑ 12.8% + 同比增速 +
+
+
+
+
+ 重点技能缺口 + 待响应 +
+
23项
+
+ 8 项高优先级 + 涉及 11 个专业 +
+
+
+
+
+ 协同改进完成率 + 本学期 +
+
68%
+
+ ↑ 16% + 21 / 31 项已完成 +
+
+
+
+ +
+
+
+
+ 核心指标 +

专业与产业需求匹配趋势

+
+
+ + + +
+
+
+
+ + + + +
+ 78.6 + 综合匹配度 +
+
+
+
+ 本校匹配度 + 区域院校基准 +
+ +
+
+
+
+ 18 个专业保持高匹配 + 9 个专业需要关注 + 5 个专业进入预警 +
+
+ +
+
+ + + +
+ AI DECISION BRIEF +

本期决策简报

+
+ 已生成 +
+

+ 智能制造与数字商贸需求显著上升,学校整体匹配度提高,但云原生、工业视觉和跨境运营仍存在结构性缺口。 +

+
+ + + +
+
+ + 结论综合基础数据包、校级数据与企业确认数据,所有引用均可追溯 +
+
+
+ +
+
+
+
+ 专业表现 +

32个专业供需表现

+
+
+ + +
+
+
+ + + + + + + + + + + + + +
专业名称所属学院匹配度市场需求技能缺口趋势
+
+
+ +
+
+
+ 产业信号 +

需求增长最快方向

+
+ +
+
+
+ 观察窗口 + 近 90 天 + 样本岗位 + 18,420 +
+
+
+
+ + +
+
+
+
PROGRAM INSIGHT
+
+

软件技术

+ +
+

信息工程学院 · 2026届毕业生 186 人

+
+
+ + +
+
+ +
+
+ 供需匹配度 + 84.2 + 高匹配 +
+
+
+ 对口岗位需求 + 2,864 + ↑ 18.6% +
+
+ 薪资竞争力 + 1.08 + 区域均值 = 1 +
+
+ 课程技能覆盖 + 76% + 31 / 41 项 +
+
+ 潜力合作企业 + 12 + 其中 4 家高意向 +
+
+ +
+ + + + +
+ +
+
+
+
+
+ 技能供需 +

产业技能需求与课程覆盖

+
+
+ 市场需求强度 + 课程覆盖度 +
+
+
+
+ +
+
+
+ 行动建议 +

课程改进建议

+
+ + + AI辅助 · 专家审核 + +
+
+
+
+ + +
+ +
+ + +
+
+
+
COLLABORATION HUB
+

校企协同中心

+

把产业需求转化为可执行的课程、项目与人才共育计划。

+
+
+ + +
+
+ +
+
在库合作企业126家↑ 18
+
本学期协同项目24个8 个进行中
+
企业导师68人覆盖 17 个专业
+
学生参与1,284人次满意度 92%
+
+ +
+
+
+
+ 协同进度 +

本学期重点项目

+
+
+ +
+
+
+
+ +
+
+
+ 企业声音 +

待响应企业需求

+
+ 6 项 +
+
+
+
+ +
+
+
+ 智能推荐 +

潜力合作伙伴

+
+
+ +
+
+
+
+
+ + +
+
+
+
ACTION TRACKER
+

改进任务闭环

+

从数据洞察到责任落实,持续追踪专业建设行动与实际成效。

+
+ +
+ +
+
+ + + + + 68%总体完成 +
+
全部任务31本学期
+
进行中72 项存在风险
+
待确认3需要校级审核
+
已完成21按期率 90%
+
+ 任务健康度 + 良好 +
+
+
+ +
+
+
+ + + + +
+ +
+
+ + + + + + + + + + + + + +
改进事项关联专业负责人截止日期进度状态
+
+
+
+ + +
+
+
+
DATA FOUNDATION
+

数据资产与质量

+

区分厂商基础数据包、学校自有数据与企业授权数据,所有分析结论均可追溯。

+
+ +
+ +
+
+
+ 数据健康度 + 92.6 + 优秀 +
+
+

三类数据资产已完成本期校验

+

厂商基础数据包处于有效服务期,校级数据已完成同步,企业数据均保留授权与确认记录。

+
+ 有效记录 128,642 + 最新入库 今天 08:30 + 质量规则 38 条 +
+
+
+
+
完整性94.8%
+
准确性91.2%
+
及时性96.5%
+
归一覆盖94.8%
+
+
+ +
+ + + + + +
+ +
+ + + + + 数据使用边界 + 基础数据包按订阅协议授权使用;校级数据权属归学校;企业数据仅用于约定的合作与人才培养场景。 + + +
+ +
+
+
+ 数据资产目录 +

数据源清单与授权状态

+
+ +
+
+
+ + + + +
+ 当前展示 6 个数据源 +
+
+
+ +
+
+
+
+ 处理链路 +

本期数据加工血缘

+
+ 分析版本 V2026.03 +
+
+
01原始接入142,318 条
+ +
02清洗去重移除 9,824 条
+ +
03岗位归一覆盖率 94.8%
+ +
04分析快照128,642 条
+
+
+
+
+
+ 质量事项 +

待处理问题

+
+ 4 项 +
+
+ + + +
+
+
+
+ + +
+
+
+
REPORT CENTER
+

分析报告中心

+

统一管理校级、学院、专业、产业与数据质量报告,支持在线阅读和版本追溯。

+
+
+ + +
+
+ +
+
可查看报告42份覆盖 32 个专业
+
本期新生成36份全部口径一致
+
待审核3份需要业务负责人确认
+
最近数据快照V2026.03质量评分 92.6
+
+ + + +
+
+
+ 报告资产库 +

全部分析报告

+
+
+ + +
+
+
+ + + + + + +
+
+
+ 显示 8 份报告 + +
+
+
+ + +
+
+
+
PLATFORM OPERATIONS
+

产教融智平台运营中心

+

面向所有学校租户管理数据服务、机构授权、系统保障与平台级审计。

+
+
+ + +
+
+ +
+ + + + + 平台运行正常 + 12 家学校租户在线,今日任务成功率 99.3%,有 2 个基础数据包将在 15 天内到期。 + + +
+ +
+
+ 服务学校 + 12家租户 + ↑ 本季度新增 2 家 +
+
+ 平台数据资产 + 2.84百万条 + 11 个在售数据包 +
+
+ 今日处理任务 + 428个 + 成功率 99.3% +
+
+ 平台可用性 + 99.96% + 连续稳定运行 46 天 +
+
+ +
+
+
+
+ 商业数据服务 +

基础数据包管理

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
数据包当前版本授权学校更新周期服务状态下次更新
区域招聘岗位基础包杭州及长三角 · 86.4万条V2026.0312 家每月正常服务2026-04-01
薪资与企业画像增强包重点产业企业 · 52.7万条V2026.Q18 家季度即将到期2026-04-15
产业政策与趋势数据包浙江省产业政策 · 3.2万条V2026.085 家每周正常服务2026-03-25
+
+
+ +
+
+
服务健康

核心服务状态

+ 全部正常 +
+
+ + + + +
+
+
+ +
+
+
多租户管理

学校机构与订阅状态

+ +
+
+ + + +
+
+ +
+ + +
+
+
容灾保障

备份与恢复

+ 策略正常 +
+
+ + 最近备份成功今天 02:00 · 全量备份 · 18.6 GB +
+
保留策略30 天异地副本2 份下次备份明天 02:00
+
+ + +
+
+ +
+
+
平台审计

最近关键操作

+ +
+
+ + + +
+
+
+
+
+
+
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/preview-campus-closed-loop-mobile.png b/demo/preview-campus-closed-loop-mobile.png new file mode 100644 index 0000000..75c6800 Binary files /dev/null and b/demo/preview-campus-closed-loop-mobile.png differ diff --git a/demo/preview-campus-closed-loop.png b/demo/preview-campus-closed-loop.png new file mode 100644 index 0000000..2b2e868 Binary files /dev/null and b/demo/preview-campus-closed-loop.png differ diff --git a/demo/preview-dashboard.png b/demo/preview-dashboard.png new file mode 100644 index 0000000..410eaba Binary files /dev/null and b/demo/preview-dashboard.png differ diff --git a/demo/preview-data-assets.png b/demo/preview-data-assets.png new file mode 100644 index 0000000..3ab506a Binary files /dev/null and b/demo/preview-data-assets.png differ diff --git a/demo/preview-data-evidence-workbench.png b/demo/preview-data-evidence-workbench.png new file mode 100644 index 0000000..79f02e3 Binary files /dev/null and b/demo/preview-data-evidence-workbench.png differ diff --git a/demo/preview-data-operations-center.png b/demo/preview-data-operations-center.png new file mode 100644 index 0000000..a827899 Binary files /dev/null and b/demo/preview-data-operations-center.png differ diff --git a/demo/preview-data-operations-mobile.png b/demo/preview-data-operations-mobile.png new file mode 100644 index 0000000..6734a6b Binary files /dev/null and b/demo/preview-data-operations-mobile.png differ diff --git a/demo/preview-enterprise-dashboard.png b/demo/preview-enterprise-dashboard.png new file mode 100644 index 0000000..36ded56 Binary files /dev/null and b/demo/preview-enterprise-dashboard.png differ diff --git a/demo/preview-enterprise-mobile-dashboard.png b/demo/preview-enterprise-mobile-dashboard.png new file mode 100644 index 0000000..7a98a6f Binary files /dev/null and b/demo/preview-enterprise-mobile-dashboard.png differ diff --git a/demo/preview-enterprise-showcase-mobile.png b/demo/preview-enterprise-showcase-mobile.png new file mode 100644 index 0000000..8533b03 Binary files /dev/null and b/demo/preview-enterprise-showcase-mobile.png differ diff --git a/demo/preview-enterprise-showcase-screen.png b/demo/preview-enterprise-showcase-screen.png new file mode 100644 index 0000000..2247b6a Binary files /dev/null and b/demo/preview-enterprise-showcase-screen.png differ diff --git a/demo/preview-mobile.png b/demo/preview-mobile.png new file mode 100644 index 0000000..42a21d6 Binary files /dev/null and b/demo/preview-mobile.png differ diff --git a/demo/preview-platform-admin.png b/demo/preview-platform-admin.png new file mode 100644 index 0000000..3dd738b Binary files /dev/null and b/demo/preview-platform-admin.png differ diff --git a/demo/preview-platform-mobile.png b/demo/preview-platform-mobile.png new file mode 100644 index 0000000..26edd21 Binary files /dev/null and b/demo/preview-platform-mobile.png differ diff --git a/demo/preview-product-tour.png b/demo/preview-product-tour.png new file mode 100644 index 0000000..1f6ca0c Binary files /dev/null and b/demo/preview-product-tour.png differ diff --git a/demo/preview-profession-course-mapping.png b/demo/preview-profession-course-mapping.png new file mode 100644 index 0000000..b47a60d Binary files /dev/null and b/demo/preview-profession-course-mapping.png differ diff --git a/demo/preview-profession.png b/demo/preview-profession.png new file mode 100644 index 0000000..0b62054 Binary files /dev/null and b/demo/preview-profession.png differ diff --git a/demo/preview-report-3d.png b/demo/preview-report-3d.png new file mode 100644 index 0000000..2cb8ef8 Binary files /dev/null and b/demo/preview-report-3d.png differ diff --git a/demo/preview-report-center-visual.png b/demo/preview-report-center-visual.png new file mode 100644 index 0000000..c7f180b Binary files /dev/null and b/demo/preview-report-center-visual.png differ diff --git a/demo/preview-report-center.png b/demo/preview-report-center.png new file mode 100644 index 0000000..19c5d4d Binary files /dev/null and b/demo/preview-report-center.png differ diff --git a/demo/preview-report-chart-mobile.png b/demo/preview-report-chart-mobile.png new file mode 100644 index 0000000..b38bca3 Binary files /dev/null and b/demo/preview-report-chart-mobile.png differ diff --git a/demo/preview-report-detail.png b/demo/preview-report-detail.png new file mode 100644 index 0000000..27694bb Binary files /dev/null and b/demo/preview-report-detail.png differ diff --git a/demo/preview-report-download-static.png b/demo/preview-report-download-static.png new file mode 100644 index 0000000..e6b5f00 Binary files /dev/null and b/demo/preview-report-download-static.png differ diff --git a/demo/preview-report-echarts.png b/demo/preview-report-echarts.png new file mode 100644 index 0000000..0d601e7 Binary files /dev/null and b/demo/preview-report-echarts.png differ diff --git a/demo/preview-report-enterprise-mobile.png b/demo/preview-report-enterprise-mobile.png new file mode 100644 index 0000000..7ec04aa Binary files /dev/null and b/demo/preview-report-enterprise-mobile.png differ diff --git a/demo/preview-report-evidence-chain.png b/demo/preview-report-evidence-chain.png new file mode 100644 index 0000000..cecc3fa Binary files /dev/null and b/demo/preview-report-evidence-chain.png differ diff --git a/demo/preview-report-evidence-detail.png b/demo/preview-report-evidence-detail.png new file mode 100644 index 0000000..985151c Binary files /dev/null and b/demo/preview-report-evidence-detail.png differ diff --git a/demo/preview-report-mobile.png b/demo/preview-report-mobile.png new file mode 100644 index 0000000..60c611a Binary files /dev/null and b/demo/preview-report-mobile.png differ diff --git a/demo/preview-report-school-evidence.png b/demo/preview-report-school-evidence.png new file mode 100644 index 0000000..d76aca9 Binary files /dev/null and b/demo/preview-report-school-evidence.png differ diff --git a/demo/preview-report-visual-mobile.png b/demo/preview-report-visual-mobile.png new file mode 100644 index 0000000..6cb2336 Binary files /dev/null and b/demo/preview-report-visual-mobile.png differ diff --git a/demo/preview-report-visual-summary.png b/demo/preview-report-visual-summary.png new file mode 100644 index 0000000..16ea7ae Binary files /dev/null and b/demo/preview-report-visual-summary.png differ diff --git a/demo/report-visuals.js b/demo/report-visuals.js new file mode 100644 index 0000000..7f5cd89 --- /dev/null +++ b/demo/report-visuals.js @@ -0,0 +1,1274 @@ +(function () { + "use strict"; + + const palette = { + green: "#176b4f", + green2: "#2f8f6b", + mint: "#72b893", + lime: "#c6e66f", + blue: "#4d7fa8", + amber: "#d39a35", + red: "#c65e51", + violet: "#7f6aaa", + ink: "#27362f", + muted: "#718078", + line: "#dfe7e1", + soft: "#f4f7f4", + }; + + const chartInstances = new Map(); + const resizeObserver = + typeof ResizeObserver === "function" + ? new ResizeObserver((entries) => { + entries.forEach((entry) => chartInstances.get(entry.target)?.resize()); + }) + : null; + + function clamp(value, min = 0, max = 100) { + return Math.max(min, Math.min(max, value)); + } + + function hashString(value) { + return [...String(value)].reduce((hash, char) => (hash * 31 + char.charCodeAt(0)) >>> 0, 2166136261); + } + + function firstNumber(value, fallback = 0) { + const match = String(value ?? "").replace(/,/g, "").match(/-?\d+(?:\.\d+)?/); + return match ? Number(match[0]) : fallback; + } + + function reportScore(report) { + if (report.type === "industry" && report.id === "gap-2026-03") return 76.8; + if (report.id === "salary-2026-03") return 98; + const metric = report.metrics.find((item) => /匹配度|质量评分|竞争力/.test(item.label)); + return clamp(firstNumber(metric?.value, 78.6)); + } + + function evidencePrefix(report) { + const prefixes = { + school: "SCH", + college: "COL", + profession: "PRO", + industry: "IND", + quality: "DQA", + }; + return prefixes[report.type] || "EVD"; + } + + function profileStats(report, seed) { + const commonSchoolStats = [ + { + code: "SCH-EDU-001", + label: "全日制在校生", + value: "12,860", + unit: "人", + note: "较上学年 +3.1%", + source: "教务管理系统 · 学籍库", + updated: "2026-03-20", + owner: "教务处", + definition: "统计学籍状态为“在籍”的全日制学生,休学学生单列、不重复计入。", + }, + { + code: "SCH-GRA-002", + label: "2026届毕业生", + value: "4,218", + unit: "人", + note: "覆盖 32 个专业", + source: "教务管理系统 · 毕业生库", + updated: "2026-03-20", + owner: "教务处", + definition: "按预计毕业年份为2026、通过学籍有效性校验的学生去重统计。", + }, + { + code: "SCH-MAJ-003", + label: "招生专业", + value: "32", + unit: "个", + note: "分属 6 个学院", + source: "专业设置与招生计划", + updated: "2026-03-18", + owner: "发展规划处", + definition: "统计本学年有在校生且处于有效状态的专业,不含停招无在校生专业。", + }, + { + code: "SCH-TEA-004", + label: "专任教师", + value: "812", + unit: "人", + note: "双师型占比 64.7%", + source: "人事系统 · 教师主数据", + updated: "2026-03-15", + owner: "人事处", + definition: "按在岗专任教师主数据去重;双师型依据校级认定结果计算。", + }, + { + code: "SCH-CRS-005", + label: "本学年课程", + value: "1,286", + unit: "门次", + note: "课程标准完整率 96.2%", + source: "教务管理系统 · 开课计划", + updated: "2026-03-20", + owner: "教务处", + definition: "按课程代码、教学班和学期统计开课门次;课程标准完整率按已归档标准计。", + }, + { + code: "SCH-ENT-006", + label: "有效合作企业", + value: "126", + unit: "家", + note: "近12个月新增 18 家", + source: "校企合作项目台账", + updated: "2026-03-21", + owner: "产教融合中心", + definition: "合作协议有效,且近12个月至少有需求确认、课程、项目、实习或就业记录之一。", + }, + { + code: "SCH-EMP-007", + label: "2025届去向落实率", + value: "93.2", + unit: "%", + note: "有效回执 3,864 份", + source: "就业管理系统 · 去向回执", + updated: "2025-12-31", + owner: "就业处", + definition: "按教育主管部门就业去向统计口径,分母排除经审核的暂不就业特殊样本。", + }, + { + code: "SCH-INT-008", + label: "岗位实习对口率", + value: "78.4", + unit: "%", + note: "较上届 +4.6pct", + source: "实习管理系统 · 岗位映射", + updated: "2026-03-19", + owner: "就业处", + definition: "实习岗位标准分类与学生所属专业方向达到二级或以上匹配的学生占比。", + }, + ]; + + if (report.type === "school" || report.type === "industry" || report.type === "quality") { + return commonSchoolStats; + } + + const isCollege = report.type === "college"; + const studentCount = isCollege ? 2860 + (seed % 520) : 438 + (seed % 310); + const graduateCount = isCollege ? 880 + (seed % 240) : 132 + (seed % 96); + const courseCount = isCollege ? 268 + (seed % 80) : 34 + (seed % 19); + const teacherCount = isCollege ? 146 + (seed % 45) : 24 + (seed % 14); + const enterpriseCount = firstNumber(report.metrics.find((item) => /企业/.test(item.label))?.value, 12); + const prefix = evidencePrefix(report); + return [ + { + code: `${prefix}-STU-001`, + label: "在校生规模", + value: studentCount.toLocaleString("zh-CN"), + unit: "人", + note: isCollege ? `${report.scope}在籍学生` : "三个年级全日制在籍", + source: "教务管理系统 · 学籍库", + updated: "2026-03-20", + owner: report.author, + definition: "按当前报告数据范围过滤后,对有效在籍学生学号去重统计。", + }, + { + code: `${prefix}-GRA-002`, + label: "2026届毕业生", + value: graduateCount.toLocaleString("zh-CN"), + unit: "人", + note: "已通过学籍一致性校验", + source: "教务管理系统 · 毕业生库", + updated: "2026-03-20", + owner: report.author, + definition: "预计毕业年份为2026且学籍有效的学生,跨专业调整以当前专业归属为准。", + }, + { + code: `${prefix}-CRS-003`, + label: "有效开课", + value: courseCount.toLocaleString("zh-CN"), + unit: "门次", + note: "含理论、实训与项目课程", + source: "教务管理系统 · 开课计划", + updated: "2026-03-20", + owner: "教务处", + definition: "本学年已经排课且有教学班的课程门次,取消或未开班课程不计入。", + }, + { + code: `${prefix}-TEA-004`, + label: "专任教师", + value: teacherCount.toLocaleString("zh-CN"), + unit: "人", + note: `企业兼职导师 ${Math.max(8, Math.round(teacherCount * 0.28))} 人`, + source: "教师主数据与导师台账", + updated: "2026-03-18", + owner: "人事处", + definition: "专任教师按在岗主数据统计,企业兼职导师须存在有效聘任或授课记录。", + }, + { + code: `${prefix}-ENT-005`, + label: "关联合作企业", + value: String(Math.max(enterpriseCount, isCollege ? 26 : 8)), + unit: "家", + note: `${Math.max(3, Math.round(enterpriseCount * 0.3))} 家有本学期项目`, + source: "校企合作项目台账", + updated: "2026-03-21", + owner: "产教融合中心", + definition: "与当前学院或专业存在有效课程、项目、实习、就业或导师关系的企业。", + }, + { + code: `${prefix}-PRJ-006`, + label: "真实项目实训", + value: String(isCollege ? 18 + (seed % 8) : 6 + (seed % 6)), + unit: "项", + note: "均有企业任务书或验收记录", + source: "项目实训与企业评价库", + updated: "2026-03-19", + owner: report.author, + definition: "纳入统计的项目须具备企业任务书、学生过程产物和至少一项验收证据。", + }, + ]; + } + + function buildEvidence(report) { + const seed = hashString(report.id); + const score = reportScore(report); + const prefix = evidencePrefix(report); + const dimensions = report.bars.slice(0, 5).map((bar, index) => { + const school = clamp(firstNumber(bar.value, 72)); + const regional = clamp(school - (3 + ((seed + index * 3) % 8))); + const peer = clamp(school - (1.4 + ((seed + index * 5) % 5))); + const coverageGap = 9 + ((seed + index * 7) % 24); + return { + name: bar.label, + school, + regional, + peer, + demand: school, + coverage: clamp(school - coverageGap), + attainment: clamp(school - Math.round(coverageGap * 0.68)), + confirmed: clamp(school - 5 + ((index * 4) % 11)), + }; + }); + + const benchmarkSchoolCount = report.type === "profession" ? 27 : 18; + const peerCount = report.type === "profession" ? 11 : 8; + const rank = Math.max(1, Math.min(benchmarkSchoolCount, Math.round((100 - score) / 4.8))); + const trendBase = clamp(score - 18, 45, 76); + const trendLabels = ["2025 Q2", "2025 Q3", "2025 Q4", "2026.01", "2026.02", "2026.03"]; + const demandTrend = trendLabels.map((_, index) => clamp(trendBase + index * 4 + ((seed + index) % 3))); + const responseTrend = trendLabels.map((_, index) => + clamp(trendBase - 7 + index * 3 + ((seed + index * 2) % 3)), + ); + const heatmap = []; + dimensions.forEach((item, row) => { + [item.demand, item.coverage, item.attainment, item.confirmed].forEach((value, column) => { + heatmap.push([column, row, value]); + }); + }); + const composition = [ + { name: "数字技术", value: 34 + (seed % 5) }, + { name: "智能制造", value: 28 + ((seed >> 2) % 5) }, + { name: "商贸服务", value: 24 + ((seed >> 4) % 5) }, + { name: "城建文创", value: 22 + ((seed >> 6) % 4) }, + { name: "教育服务", value: 18 + ((seed >> 8) % 4) }, + ]; + const quadrant = dimensions.map((item, index) => ({ + name: item.name, + coverage: item.coverage, + demand: item.demand, + sample: 280 + ((seed + index * 337) % 1720), + })); + + return { + score, + scoreLabel: + report.type === "quality" + ? "数据质量评分" + : report.id === "salary-2026-03" + ? "区域薪资竞争力" + : "供需匹配度", + benchmark: { + regional: clamp(score - 4.8), + peer: clamp(score - 2.7), + rank, + schoolCount: benchmarkSchoolCount, + peerCount, + sampleText: + report.type === "profession" + ? `区域 ${benchmarkSchoolCount} 所院校同名或相近专业、同类 ${peerCount} 个专业群` + : `区域 ${benchmarkSchoolCount} 所同层次院校、同类 ${peerCount} 所院校`, + }, + snapshot: { + id: "SNP-2026-03-22-0830", + records: "128,642", + quality: "92.6", + coverage: "94.8%", + generated: "2026-03-22 09:30", + }, + dimensions, + trend: { labels: trendLabels, demand: demandTrend, response: responseTrend }, + heatmap, + composition, + quadrant, + profile: { + name: + report.type === "school" || report.type === "industry" || report.type === "quality" + ? "杭州科技职业技术学院" + : `杭州科技职业技术学院 · ${report.scope}`, + attributes: [ + ["分析对象", report.scope], + ["统计周期", report.period], + ["数据快照", "2026-03-22 08:30"], + ["空间范围", "杭州都市圈 + 校企合作企业"], + ], + stats: profileStats(report, seed), + }, + sources: [ + { + code: `${prefix}-JOB-101`, + asset: "互联网基础数据包", + source: "区域招聘岗位与薪资基础包", + sample: "77,520 条", + updated: "2026-03-18", + owner: "平台厂商(订阅授权)", + confidence: "高", + limitation: "反映招聘需求信号,不等于实际录用人数", + }, + { + code: `${prefix}-EDU-102`, + asset: "校级数据", + source: "学籍、专业、课程与教师主数据", + sample: "17,176 条", + updated: "2026-03-20", + owner: "学校", + confidence: "高", + limitation: "跨系统统计以学号、专业代码和课程代码归一", + }, + { + code: `${prefix}-EMP-103`, + asset: "校级数据", + source: "实习、就业与薪资回执", + sample: "25,596 条", + updated: "2026-03-19", + owner: "学校", + confidence: "中高", + limitation: "薪资缺失或区间异常记录已降权", + }, + { + code: `${prefix}-ENT-104`, + asset: "企业数据", + source: "126家合作企业需求确认", + sample: "8,350 条", + updated: "2026-03-21", + owner: "合作企业(场景授权)", + confidence: "高", + limitation: "仅用于约定的专业建设和协同分析", + }, + ], + evidenceCodes: { + overall: `${prefix}-CAL-201`, + benchmark: `${prefix}-BAS-202`, + radar: `${prefix}-SKL-203`, + trend: `${prefix}-TRD-204`, + matrix: `${prefix}-MAT-205`, + composition: `${prefix}-ENT-206`, + quadrant: `${prefix}-GAP-207`, + threeD: `${prefix}-3DM-208`, + }, + }; + } + + function svgFrame(content, height = 300, label = "") { + return `${content}`; + } + + function gaugeSvg(evidence) { + const dash = clamp(evidence.score); + return svgFrame( + ` + + + + + + + + + + ${evidence.score.toFixed(1)} + ${evidence.scoreLabel} + + 区域排名 ${evidence.benchmark.rank}/${evidence.benchmark.schoolCount} + 低匹配 + 高匹配 + `, + 300, + `${evidence.scoreLabel}${evidence.score.toFixed(1)}分`, + ); + } + + function groupedBarSvg(evidence) { + const width = 680; + const labelWidth = 118; + const chartWidth = 470; + const rowHeight = 47; + const colors = [palette.green, palette.blue, palette.amber]; + const rows = evidence.dimensions + .map((item, index) => { + const y = 65 + index * rowHeight; + const bars = [item.school, item.regional, item.peer] + .map( + (value, seriesIndex) => + ` + ${value.toFixed(0)}`, + ) + .join(""); + return `${item.name.slice(0, 9)}${bars}`; + }) + .join(""); + return svgFrame( + ` + + 本校/本专业 + 区域均值 + 同类均值 + + ${[0, 25, 50, 75, 100] + .map( + (tick) => + ` + ${tick}`, + ) + .join("")} + ${rows} + `, + 325, + "学校值、区域均值与同类院校均值对比", + ); + } + + function radarPoints(values, radius = 103, centerX = 210, centerY = 145) { + return values + .map((value, index) => { + const angle = -Math.PI / 2 + (index * Math.PI * 2) / values.length; + const distance = (value / 100) * radius; + return `${centerX + Math.cos(angle) * distance},${centerY + Math.sin(angle) * distance}`; + }) + .join(" "); + } + + function radarSvg(evidence) { + const count = evidence.dimensions.length; + const labels = evidence.dimensions + .map((item, index) => { + const angle = -Math.PI / 2 + (index * Math.PI * 2) / count; + const x = 210 + Math.cos(angle) * 132; + const y = 145 + Math.sin(angle) * 124; + const anchor = x < 185 ? "end" : x > 235 ? "start" : "middle"; + return `${item.name.slice(0, 8)}`; + }) + .join(""); + const grids = [20, 40, 60, 80, 100] + .map((value) => ``) + .join(""); + const demand = evidence.dimensions.map((item) => item.demand); + const coverage = evidence.dimensions.map((item) => item.coverage); + return svgFrame( + ` + ${grids}${labels} + + + + 企业需求强度 + 课程技能覆盖 + + 最大结构性缺口 + ${Math.max( + ...evidence.dimensions.map((item) => item.demand - item.coverage), + ).toFixed(0)} pct + + `, + 300, + "企业需求与课程技能覆盖雷达对比", + ); + } + + function linePoints(values, width = 540, height = 190, startX = 75, startY = 32) { + return values + .map((value, index) => { + const x = startX + (index / (values.length - 1)) * width; + const y = startY + height - ((value - 40) / 60) * height; + return [x, y]; + }) + .map(([x, y]) => `${x},${y}`) + .join(" "); + } + + function trendSvg(evidence) { + const demandPoints = linePoints(evidence.trend.demand); + const responsePoints = linePoints(evidence.trend.response); + const demandArea = `${demandPoints} 615,242 75,242`; + return svgFrame( + ` + + ${[40, 55, 70, 85, 100] + .map((tick) => { + const y = 32 + 190 - ((tick - 40) / 60) * 190; + return `${tick}`; + }) + .join("")} + + + + ${evidence.trend.labels + .map( + (label, index) => + `${label}`, + ) + .join("")} + 产业需求 + 培养响应 + `, + 285, + "产业需求与学校培养响应趋势", + ); + } + + function heatColor(value) { + if (value >= 85) return "#176b4f"; + if (value >= 75) return "#4f9677"; + if (value >= 65) return "#9fc7ad"; + if (value >= 55) return "#ead09b"; + return "#dc897d"; + } + + function heatmapSvg(evidence) { + const columns = ["岗位需求", "课程覆盖", "学生达成", "企业确认"]; + const cellWidth = 105; + const cellHeight = 42; + const startX = 190; + const startY = 54; + const cells = evidence.heatmap + .map(([column, row, value]) => { + const x = startX + column * cellWidth; + const y = startY + row * cellHeight; + return ` + ${value.toFixed(0)}`; + }) + .join(""); + return svgFrame( + ` + ${columns + .map( + (label, index) => + `${label}`, + ) + .join("")} + ${evidence.dimensions + .map( + (item, index) => + `${item.name.slice(0, 10)}`, + ) + .join("")} + ${cells} + 低 + ${["#dc897d", "#ead09b", "#9fc7ad", "#4f9677", "#176b4f"] + .map((color, index) => ``) + .join("")} + 高 + `, + 300, + "技能供需证据热力图", + ); + } + + function donutSvg(evidence) { + const total = evidence.composition.reduce((sum, item) => sum + item.value, 0); + let offset = 0; + const colors = [palette.green, palette.blue, palette.amber, palette.violet, palette.mint]; + const rings = evidence.composition + .map((item, index) => { + const percent = (item.value / total) * 100; + const circle = ``; + offset += percent; + return circle; + }) + .join(""); + return svgFrame( + ` + ${rings} + + 126 + 有效合作企业 + ${evidence.composition + .map( + (item, index) => + ` + ${item.name} + ${item.value} 家`, + ) + .join("")} + `, + 300, + "合作企业产业结构", + ); + } + + function quadrantSvg(evidence) { + const x = (value) => 70 + ((value - 40) / 60) * 540; + const y = (value) => 245 - ((value - 40) / 60) * 200; + return svgFrame( + ` + + + + + ${[40, 55, 70, 85, 100] + .map( + (tick) => + ``, + ) + .join("")} + + + 优势巩固区 + 高优补强区 + ${evidence.quadrant + .map((item, index) => { + const radius = 11 + Math.sqrt(item.sample) / 8; + const color = item.coverage < 70 && item.demand >= 75 ? palette.red : palette.green2; + return ` + ${item.name.slice(0, 7)}`; + }) + .join("")} + 课程技能覆盖度 → + 企业需求强度 → + `, + 300, + "技能优势短板象限图", + ); + } + + function isometricSvg(evidence) { + const dims = evidence.dimensions.slice(0, 4); + const measures = ["需求", "课程", "达成", "确认"]; + const colors = [palette.green, palette.blue, palette.amber, palette.violet]; + const bars = []; + dims.forEach((item, xIndex) => { + [item.demand, item.coverage, item.attainment, item.confirmed].forEach((value, yIndex) => { + const x = 100 + xIndex * 125 + yIndex * 15; + const y = 238 - yIndex * 19; + const height = value * 1.55; + const color = colors[yIndex]; + bars.push(` + + + + `); + }); + }); + return svgFrame( + ` + + ${bars.join("")} + ${dims + .map( + (item, index) => + `${item.name.slice(0, 7)}`, + ) + .join("")} + ${measures + .map( + (item, index) => + ` + ${item}`, + ) + .join("")} + `, + 300, + "供需能力矩阵立体图", + ); + } + + function chartCard(report, key, figure, title, caption, fallback, options = {}) { + const evidence = buildEvidence(report); + const interactive = options.interactive !== false; + const wideClass = options.wide ? " wide" : ""; + return ` +
+
+ FIG ${figure} + ${title} +
+
+ ${interactive ? `` : ""} +
${fallback}
+
+
+ 证据 ${evidence.evidenceCodes[key]} + ${caption} +
+
+ `; + } + + function renderExecutiveCharts(report, options = {}) { + const evidence = buildEvidence(report); + return ` +
+ ${chartCard( + report, + "overall", + "1-1", + `${evidence.scoreLabel}与区域排名`, + `本期得分基于快照 ${evidence.snapshot.id} 的 ${evidence.snapshot.records} 条有效记录计算;区域排名采用 ${evidence.benchmark.sampleText}。`, + gaugeSvg(evidence), + options, + )} + ${chartCard( + report, + "benchmark", + "1-2", + "学校值、区域均值与同类均值", + `区域基准样本为 ${evidence.benchmark.schoolCount} 所院校,同类基准为 ${evidence.benchmark.peerCount} 所院校;仅比较口径一致且样本量达阈值的指标。`, + groupedBarSvg(evidence), + options, + )} +
+ `; + } + + function renderProfileEvidence(report, options = {}) { + const evidence = buildEvidence(report); + return ` +
+
+ INSTITUTION FACTS · 学校事实底座 +

${evidence.profile.name}

+

学校现状指标只使用校方自有业务数据;产业需求使用厂商订阅数据,企业确认使用合作授权数据。三类证据分开标识,不以招聘信号替代校内事实。

+
+
+ ${evidence.profile.attributes.map(([label, value]) => `${label}${value}`).join("")} +
+
+
+ ${evidence.profile.stats + .map( + (item) => ` +
+ ${item.code} + ${item.label} + ${item.value}${item.unit} + ${item.note} +
+ 查看证据口径 +
+ 来源${item.source} + 更新时间${item.updated} + 责任部门${item.owner} +

${item.definition}

+
+
+
+ `, + ) + .join("")} +
+
+ ${chartCard( + report, + "composition", + "2-1", + "学校合作企业产业结构", + "企业须同时具备有效协议和近12个月业务记录;126家合作企业均可追溯至协议、需求、课程、项目、实习或就业证据。", + donutSvg(evidence), + options, + )} + ${chartCard( + report, + "radar", + "2-2", + "企业需求与课程技能覆盖", + "需求强度来自77,520条去重岗位和8,350条企业确认记录;课程覆盖来自1,286门次课程标准的技能映射,映射覆盖率94.8%。", + radarSvg(evidence), + options, + )} +
+ `; + } + + function renderSupplyVisuals(report, options = {}) { + const evidence = buildEvidence(report); + return ` +
+ ${chartCard( + report, + "trend", + "4-1", + "产业需求与培养响应趋势", + "需求序列按月度新增岗位、企业确认和薪资变化综合计算;培养响应按课程覆盖、实训项目和学生达成证据计算,二者均以2025年二季度为可比基期。", + trendSvg(evidence), + options, + )} + ${chartCard( + report, + "matrix", + "4-2", + "技能供需证据热力矩阵", + "每个单元格均可回溯到岗位样本、课程标准、学生项目达成及企业确认四类证据;低于60分视为需要业务复核。", + heatmapSvg(evidence), + options, + )} + ${chartCard( + report, + "quadrant", + "4-3", + "技能优势与短板优先级", + "横轴为课程技能覆盖,纵轴为企业需求强度,气泡面积代表有效岗位样本量。左上象限为高需求、低覆盖的优先补强区。", + quadrantSvg(evidence), + options, + )} + ${chartCard( + report, + "threeD", + "4-4", + "供需能力立体证据矩阵", + "立体柱高同时呈现岗位需求、课程覆盖、学生达成和企业确认四个观察面。在线版支持拖拽旋转,下载版保留固定等距视图。", + isometricSvg(evidence), + { ...options, wide: false }, + )} +
+ `; + } + + function renderEvidenceLedger(report) { + const evidence = buildEvidence(report); + return ` +
+ 统一快照${evidence.snapshot.id} + 有效记录${evidence.snapshot.records} + 质量评分${evidence.snapshot.quality} + 技能映射覆盖${evidence.snapshot.coverage} +
+
+ 01原始事实保留来源、权属、时间戳 + + 02规则治理去重、归一、异常降权 + + 03指标计算样本阈值与基准校验 + + 04结论复核AI生成、业务负责人确认 +
+
+ + + + ${evidence.sources + .map( + (source) => ` + + + + + + + + + + `, + ) + .join("")} + +
证据编号数据资产 / 来源有效样本更新时间权属责任置信度已知限制
${source.code}${source.asset}${source.source}${source.sample}${source.updated}${source.owner}${source.confidence}${source.limitation}
+
+
+ 证据使用边界 +

校内学生、课程、教师、实习和就业事实以学校业务系统为准;互联网岗位仅用于判断外部需求趋势;企业数据只在协议授权范围内用于需求确认。任何单一来源都不直接触发专业撤并或招生调整。

+
+ `; + } + + function chartOption(kind, evidence) { + const baseText = { + color: palette.ink, + fontFamily: '"PingFang SC","Microsoft YaHei",sans-serif', + }; + const axisLine = { lineStyle: { color: "#dfe7e1" } }; + const axisLabel = { color: palette.muted, fontSize: 13 }; + const splitLine = { lineStyle: { color: "#e8eee9" } }; + + if (kind === "overall") { + return { + animationDuration: 800, + series: [ + { + type: "gauge", + startAngle: 210, + endAngle: -30, + min: 0, + max: 100, + splitNumber: 5, + center: ["50%", "58%"], + radius: "82%", + progress: { show: true, width: 18, roundCap: true, itemStyle: { color: palette.green } }, + axisLine: { + roundCap: true, + lineStyle: { + width: 18, + color: [ + [0.6, "#f2d7a5"], + [0.8, "#9bc8b0"], + [1, "#d9eba5"], + ], + }, + }, + pointer: { + show: true, + length: "56%", + width: 5, + itemStyle: { color: palette.ink }, + }, + anchor: { show: true, size: 12, itemStyle: { color: palette.ink } }, + axisTick: { distance: -25, splitNumber: 2, length: 5, lineStyle: { color: "#82948a" } }, + splitLine: { distance: -27, length: 10, lineStyle: { color: "#82948a", width: 1 } }, + axisLabel: { + distance: -43, + color: palette.muted, + fontSize: 13, + formatter: (value) => (value === 0 || value === 100 ? "" : value), + }, + title: { offsetCenter: [0, "71%"], color: palette.muted, fontSize: 13 }, + detail: { + valueAnimation: true, + offsetCenter: [0, "24%"], + fontSize: 42, + fontWeight: 800, + color: palette.ink, + formatter: "{value}", + }, + data: [{ value: evidence.score.toFixed(1), name: `${evidence.scoreLabel} · 排名 ${evidence.benchmark.rank}/${evidence.benchmark.schoolCount}` }], + }, + ], + }; + } + + if (kind === "benchmark") { + return { + animationDuration: 700, + color: [palette.green, palette.blue, palette.amber], + tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, + legend: { top: 2, textStyle: baseText, itemWidth: 12, itemHeight: 8 }, + grid: { left: 105, right: 25, top: 48, bottom: 24 }, + xAxis: { type: "value", max: 100, axisLine, axisLabel, splitLine }, + yAxis: { + type: "category", + inverse: true, + data: evidence.dimensions.map((item) => item.name), + axisLine, + axisTick: { show: false }, + axisLabel: { ...axisLabel, width: 88, overflow: "truncate" }, + }, + series: [ + { name: "本校/本专业", type: "bar", data: evidence.dimensions.map((item) => item.school), barMaxWidth: 9 }, + { name: "区域均值", type: "bar", data: evidence.dimensions.map((item) => item.regional), barMaxWidth: 9 }, + { name: "同类均值", type: "bar", data: evidence.dimensions.map((item) => item.peer), barMaxWidth: 9 }, + ], + }; + } + + if (kind === "composition") { + return { + animationDuration: 800, + color: [palette.green, palette.blue, palette.amber, palette.violet, palette.mint], + tooltip: { trigger: "item", formatter: "{b}
{c} 家 · {d}%" }, + legend: { type: "scroll", orient: "vertical", right: 12, top: "center", textStyle: baseText }, + graphic: [ + { type: "text", left: "28%", top: "42%", style: { text: "126", fill: palette.ink, font: "800 30px sans-serif", textAlign: "center" } }, + { type: "text", left: "25%", top: "55%", style: { text: "合作企业", fill: palette.muted, font: "12px sans-serif", textAlign: "center" } }, + ], + series: [ + { + type: "pie", + radius: ["45%", "70%"], + center: ["32%", "51%"], + roseType: "radius", + itemStyle: { borderColor: "#fff", borderWidth: 3, borderRadius: 5 }, + label: { show: false }, + data: evidence.composition, + }, + ], + }; + } + + if (kind === "radar") { + return { + animationDuration: 800, + color: [palette.green, palette.amber], + tooltip: { trigger: "item" }, + legend: { top: 3, textStyle: baseText }, + radar: { + center: ["50%", "55%"], + radius: "63%", + indicator: evidence.dimensions.map((item) => ({ name: item.name, max: 100 })), + axisName: { color: palette.muted, fontSize: 13 }, + splitNumber: 5, + splitArea: { areaStyle: { color: ["#fbfcfb", "#f4f8f5"] } }, + splitLine, + axisLine: { lineStyle: { color: "#dfe7e1" } }, + }, + series: [ + { + type: "radar", + symbolSize: 6, + lineStyle: { width: 2.5 }, + areaStyle: { opacity: 0.14 }, + data: [ + { name: "企业需求强度", value: evidence.dimensions.map((item) => item.demand) }, + { name: "课程技能覆盖", value: evidence.dimensions.map((item) => item.coverage) }, + ], + }, + ], + }; + } + + if (kind === "trend") { + return { + animationDuration: 800, + color: [palette.green, palette.amber], + tooltip: { trigger: "axis" }, + legend: { top: 2, textStyle: baseText }, + grid: { left: 44, right: 18, top: 45, bottom: 38 }, + xAxis: { type: "category", boundaryGap: false, data: evidence.trend.labels, axisLine, axisLabel }, + yAxis: { type: "value", min: 40, max: 100, axisLine, axisLabel, splitLine }, + dataZoom: [{ type: "inside" }], + series: [ + { + name: "产业需求", + type: "line", + smooth: true, + symbolSize: 7, + data: evidence.trend.demand, + lineStyle: { width: 3 }, + areaStyle: { + color: { + type: "linear", + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { offset: 0, color: "rgba(23,107,79,.28)" }, + { offset: 1, color: "rgba(23,107,79,.02)" }, + ], + }, + }, + }, + { + name: "培养响应", + type: "line", + smooth: true, + symbolSize: 7, + data: evidence.trend.response, + lineStyle: { width: 3, type: "dashed" }, + }, + ], + }; + } + + if (kind === "matrix") { + return { + animationDuration: 700, + tooltip: { + position: "top", + formatter: (params) => + `${evidence.dimensions[params.value[1]].name}
${["岗位需求", "课程覆盖", "学生达成", "企业确认"][params.value[0]]}:${params.value[2]}`, + }, + grid: { left: 105, right: 46, top: 26, bottom: 65 }, + xAxis: { + type: "category", + data: ["岗位需求", "课程覆盖", "学生达成", "企业确认"], + splitArea: { show: true }, + axisLine, + axisLabel: { ...axisLabel, interval: 0, rotate: 18 }, + }, + yAxis: { + type: "category", + data: evidence.dimensions.map((item) => item.name), + splitArea: { show: true }, + axisLine, + axisLabel: { ...axisLabel, width: 88, overflow: "truncate" }, + }, + visualMap: { + min: 40, + max: 100, + calculable: true, + orient: "horizontal", + left: "center", + bottom: 2, + inRange: { color: ["#dc897d", "#ead09b", "#9fc7ad", "#176b4f"] }, + textStyle: axisLabel, + itemWidth: 12, + itemHeight: 110, + }, + series: [ + { + type: "heatmap", + data: evidence.heatmap, + label: { show: true, color: palette.ink, fontWeight: 700 }, + itemStyle: { borderColor: "#fff", borderWidth: 3, borderRadius: 5 }, + emphasis: { itemStyle: { shadowBlur: 10, shadowColor: "rgba(0,0,0,.2)" } }, + }, + ], + }; + } + + if (kind === "quadrant") { + return { + animationDuration: 800, + tooltip: { + formatter: (params) => + `${params.data[3]}
课程覆盖:${params.data[0]}
需求强度:${params.data[1]}
岗位样本:${params.data[2]}条`, + }, + grid: { left: 48, right: 24, top: 25, bottom: 46 }, + xAxis: { name: "课程技能覆盖度", min: 40, max: 100, axisLine, axisLabel, splitLine }, + yAxis: { name: "企业需求强度", min: 40, max: 100, axisLine, axisLabel, splitLine }, + visualMap: { + show: false, + min: 200, + max: 2000, + dimension: 2, + inRange: { color: [palette.mint, palette.green], symbolSize: [16, 48] }, + }, + series: [ + { + type: "scatter", + data: evidence.quadrant.map((item) => [item.coverage, item.demand, item.sample, item.name]), + label: { show: true, position: "top", formatter: (params) => params.data[3], color: palette.ink, fontSize: 13 }, + itemStyle: { borderColor: "#fff", borderWidth: 2, opacity: 0.86 }, + markLine: { + silent: true, + symbol: "none", + lineStyle: { color: palette.amber, type: "dashed" }, + label: { color: palette.muted, fontSize: 13 }, + data: [{ xAxis: 70, name: "覆盖阈值" }, { yAxis: 75, name: "需求阈值" }], + }, + }, + ], + }; + } + + if (kind === "threeD") { + const axis3D = { + type: "category", + axisLabel: { color: palette.muted, fontSize: 13, interval: 0 }, + axisLine: { lineStyle: { color: "#bfcac3" } }, + splitLine: { lineStyle: { color: "#e2e9e4" } }, + }; + const values = []; + evidence.dimensions.slice(0, 5).forEach((item, xIndex) => { + [item.demand, item.coverage, item.attainment, item.confirmed].forEach((value, yIndex) => { + values.push([xIndex, yIndex, value]); + }); + }); + return { + animationDuration: 900, + tooltip: { + formatter: (params) => + `${evidence.dimensions[params.value[0]].name}
${["岗位需求", "课程覆盖", "学生达成", "企业确认"][params.value[1]]}:${params.value[2]}`, + }, + visualMap: { + min: 40, + max: 100, + calculable: true, + orient: "vertical", + right: 0, + top: "center", + inRange: { color: ["#e1a263", "#90bda2", "#176b4f", "#c6e66f"] }, + textStyle: axisLabel, + itemWidth: 12, + itemHeight: 110, + }, + xAxis3D: { ...axis3D, data: evidence.dimensions.slice(0, 5).map((item) => item.name) }, + yAxis3D: { ...axis3D, data: ["岗位需求", "课程覆盖", "学生达成", "企业确认"] }, + zAxis3D: { + type: "value", + min: 0, + max: 100, + axisLabel: { color: palette.muted, fontSize: 13 }, + axisLine: { lineStyle: { color: "#bfcac3" } }, + splitLine: { lineStyle: { color: "#e2e9e4" } }, + }, + grid3D: { + boxWidth: 125, + boxDepth: 72, + boxHeight: 72, + environment: "#fbfcfb", + light: { main: { intensity: 1.2, shadow: true }, ambient: { intensity: 0.55 } }, + viewControl: { alpha: 24, beta: 35, distance: 180, autoRotate: false, rotateSensitivity: 1 }, + }, + series: [ + { + type: "bar3D", + data: values, + shading: "lambert", + bevelSize: 0.3, + bevelSmoothness: 3, + itemStyle: { opacity: 0.94 }, + emphasis: { itemStyle: { color: palette.lime } }, + }, + ], + }; + } + + return {}; + } + + function dispose(root) { + const scope = root || document; + scope.querySelectorAll?.("[data-report-chart]").forEach((element) => { + const instance = chartInstances.get(element); + if (!instance) return; + resizeObserver?.unobserve(element); + instance.dispose(); + chartInstances.delete(element); + }); + } + + function init(report, root) { + if (!window.echarts || !root) return; + const evidence = buildEvidence(report); + root.querySelectorAll("[data-report-chart]").forEach((element) => { + const kind = element.dataset.reportChart; + let instance; + try { + instance = window.echarts.init(element, null, { + renderer: "canvas", + devicePixelRatio: Math.min(window.devicePixelRatio || 1, 2), + }); + instance.setOption(chartOption(kind, evidence), true); + chartInstances.set(element, instance); + resizeObserver?.observe(element); + element.closest(".report-chart-stage")?.classList.add("is-interactive"); + } catch (error) { + instance?.dispose(); + console.warn(`图表 ${kind} 使用静态降级视图`, error); + } + }); + } + + function resizeAll() { + chartInstances.forEach((instance) => instance.resize()); + } + + window.addEventListener("resize", resizeAll, { passive: true }); + + window.ReportVisuals = Object.freeze({ + buildEvidence, + renderExecutiveCharts, + renderProfileEvidence, + renderSupplyVisuals, + renderEvidenceLedger, + init, + dispose, + resizeAll, + }); +})(); diff --git a/demo/styles.css b/demo/styles.css new file mode 100644 index 0000000..186bada --- /dev/null +++ b/demo/styles.css @@ -0,0 +1,7045 @@ +:root { + --ink: #14241e; + --ink-soft: #33463e; + --muted: #718078; + --line: #dfe5df; + --line-soft: #ebefeb; + --surface: #ffffff; + --canvas: #f5f7f3; + --canvas-warm: #faf9f4; + --green: #176b4f; + --green-2: #238765; + --green-soft: #e8f4ee; + --lime: #c6e66f; + --lime-soft: #f1f8dc; + --amber: #d89527; + --amber-soft: #fff5df; + --red: #cb5548; + --red-soft: #fff0ed; + --blue: #4978a8; + --blue-soft: #edf4fa; + --shadow: 0 10px 35px rgba(27, 54, 43, 0.07); + --shadow-high: 0 22px 70px rgba(16, 39, 30, 0.18); + --radius: 18px; + --sidebar: 254px; + color-scheme: light; + font-family: + "Inter", "SF Pro Display", "PingFang SC", "Microsoft YaHei", + "Noto Sans CJK SC", sans-serif; +} + +* { + box-sizing: border-box; +} + +[hidden] { + display: none !important; +} + +html { + min-width: 320px; + background: var(--canvas); + scroll-behavior: smooth; +} + +body { + margin: 0; + color: var(--ink); + background: + radial-gradient(circle at 90% 0, rgba(198, 230, 111, 0.08), transparent 28%), + var(--canvas); + font-size: 14px; + -webkit-font-smoothing: antialiased; +} + +button, +input, +select, +textarea { + color: inherit; + font: inherit; +} + +button { + border: 0; + cursor: pointer; +} + +button:focus-visible, +input:focus-visible, +select:focus-visible, +textarea:focus-visible { + outline: 3px solid rgba(35, 135, 101, 0.24); + outline-offset: 2px; +} + +svg { + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 1.8; +} + +.app-shell { + min-height: 100vh; +} + +.sidebar { + position: fixed; + z-index: 30; + inset: 0 auto 0 0; + display: flex; + width: var(--sidebar); + flex-direction: column; + color: #dbe8e1; + background: + radial-gradient(circle at 15% 2%, rgba(198, 230, 111, 0.13), transparent 24%), + linear-gradient(180deg, #15382d 0%, #102c24 52%, #0d251e 100%); + border-right: 1px solid rgba(255, 255, 255, 0.06); + transition: transform 0.25s ease; +} + +.brand { + display: flex; + align-items: center; + gap: 12px; + height: 84px; + padding: 0 24px; +} + +.brand-mark { + position: relative; + width: 36px; + height: 36px; + transform: rotate(-6deg); +} + +.brand-mark span { + position: absolute; + display: block; + width: 21px; + height: 9px; + border-radius: 2px 8px 2px 8px; + background: var(--lime); + transform: skewX(-13deg); +} + +.brand-mark span:nth-child(1) { + top: 3px; + left: 1px; +} + +.brand-mark span:nth-child(2) { + top: 14px; + left: 8px; + opacity: 0.78; +} + +.brand-mark span:nth-child(3) { + top: 25px; + left: 15px; + opacity: 0.55; +} + +.brand strong { + display: block; + color: white; + font-size: 18px; + letter-spacing: 0.08em; +} + +.brand small { + display: block; + margin-top: 3px; + color: #88a398; + font-size: 8px; + letter-spacing: 0.16em; +} + +.school-card { + display: grid; + grid-template-columns: 34px minmax(0, 1fr) 24px; + align-items: center; + gap: 10px; + margin: 3px 14px 19px; + padding: 13px 12px; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 12px; + background: rgba(255, 255, 255, 0.045); +} + +.school-emblem { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: #173a2e; + background: var(--lime); + border-radius: 9px; + font-family: serif; + font-size: 16px; + font-weight: 800; +} + +.school-card > div:nth-child(2) { + min-width: 0; +} + +.school-card span, +.school-card strong { + display: block; +} + +.school-card span { + margin-bottom: 3px; + color: #779388; + font-size: 9px; +} + +.school-card strong { + overflow: hidden; + color: #eef6f1; + font-size: 11px; + font-weight: 500; + text-overflow: ellipsis; + white-space: nowrap; +} + +.icon-button { + display: inline-grid; + width: 40px; + height: 40px; + place-items: center; + padding: 0; + color: var(--ink-soft); + background: transparent; + border-radius: 10px; +} + +.icon-button:hover { + background: rgba(23, 107, 79, 0.08); +} + +.icon-button svg { + width: 19px; + height: 19px; +} + +.icon-button.subtle { + width: 24px; + height: 24px; + color: #7f9c90; +} + +.icon-button.subtle svg { + width: 14px; + height: 14px; +} + +.main-nav { + flex: 1; + min-height: 0; + padding: 0 14px; + overflow-y: auto; +} + +.nav-group { + display: block; +} + +.main-nav::-webkit-scrollbar { + width: 4px; +} + +.main-nav::-webkit-scrollbar-thumb { + background: rgba(255, 255, 255, 0.12); + border-radius: 3px; +} + +.nav-label { + display: block; + padding: 6px 12px 9px; + color: #66877a; + font-size: 9px; + font-weight: 700; + letter-spacing: 0.15em; + text-transform: uppercase; +} + +.nav-label-spaced { + margin-top: 20px; +} + +.nav-item { + position: relative; + display: flex; + width: 100%; + height: 44px; + align-items: center; + gap: 12px; + margin: 3px 0; + padding: 0 12px; + color: #a8beb5; + background: transparent; + border-radius: 11px; + text-align: left; + transition: + color 0.2s ease, + background 0.2s ease, + transform 0.2s ease; +} + +.nav-item::before { + position: absolute; + top: 10px; + bottom: 10px; + left: -14px; + width: 3px; + background: var(--lime); + border-radius: 0 4px 4px 0; + content: ""; + opacity: 0; + transition: opacity 0.2s ease; +} + +.nav-item:hover { + color: white; + background: rgba(255, 255, 255, 0.055); + transform: translateX(2px); +} + +.nav-item.active { + color: white; + background: rgba(198, 230, 111, 0.11); +} + +.nav-item.active::before { + opacity: 1; +} + +.nav-item svg { + width: 18px; + height: 18px; + flex: 0 0 auto; +} + +.nav-item span:nth-child(2) { + flex: 1; + font-size: 13px; +} + +.nav-count { + display: grid; + min-width: 24px; + height: 20px; + place-items: center; + color: #a4be67; + background: rgba(198, 230, 111, 0.1); + border-radius: 10px; + font-size: 10px; +} + +.nav-dot { + width: 6px; + height: 6px; + background: #ef9f58; + border-radius: 50%; + box-shadow: 0 0 0 4px rgba(239, 159, 88, 0.1); +} + +.sidebar-footer { + padding: 14px; +} + +.sync-line { + display: flex; + align-items: center; + gap: 8px; + padding: 0 8px 12px; + color: #6f8e81; + font-size: 10px; +} + +.live-dot { + width: 6px; + height: 6px; + background: #73bd8d; + border-radius: 50%; + box-shadow: 0 0 0 4px rgba(115, 189, 141, 0.09); +} + +.meeting-pack { + display: grid; + width: 100%; + grid-template-columns: 34px 1fr 16px; + align-items: center; + gap: 10px; + padding: 12px; + color: #eff8df; + background: + linear-gradient(135deg, rgba(198, 230, 111, 0.16), rgba(198, 230, 111, 0.04)); + border: 1px solid rgba(198, 230, 111, 0.16); + border-radius: 12px; + text-align: left; +} + +.meeting-pack:hover { + background: rgba(198, 230, 111, 0.17); +} + +.meeting-icon { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: #19392f; + background: var(--lime); + border-radius: 9px; +} + +.meeting-icon svg { + width: 17px; + height: 17px; +} + +.meeting-pack small, +.meeting-pack strong { + display: block; +} + +.meeting-pack small { + margin-bottom: 2px; + color: #8ca59b; + font-size: 9px; +} + +.meeting-pack strong { + font-size: 12px; + font-weight: 600; +} + +.meeting-arrow { + width: 14px; + height: 14px; + color: #68887b; +} + +.workspace { + min-height: 100vh; + margin-left: var(--sidebar); +} + +.topbar { + position: sticky; + z-index: 20; + top: 0; + display: flex; + height: 76px; + align-items: center; + justify-content: space-between; + padding: 0 30px; + background: rgba(245, 247, 243, 0.9); + border-bottom: 1px solid rgba(212, 220, 214, 0.8); + backdrop-filter: blur(16px); +} + +.topbar-left { + display: flex; + align-items: center; + gap: 10px; +} + +.breadcrumb { + display: flex; + align-items: center; + gap: 8px; + color: #87938d; + font-size: 11px; +} + +.breadcrumb strong { + color: var(--ink-soft); + font-weight: 600; +} + +.breadcrumb svg { + width: 12px; + height: 12px; +} + +.topbar-date { + margin: 5px 0 0; + color: var(--ink); + font-size: 12px; + font-weight: 600; +} + +.topbar-actions { + display: flex; + align-items: center; + gap: 10px; +} + +.edition-badge { + padding: 5px 9px; + color: #73591c; + background: #fff1be; + border: 1px solid #f2df9b; + border-radius: 7px; + font-size: 9px; + font-weight: 700; + letter-spacing: 0.08em; +} + +.role-switcher { + position: relative; + display: grid; + min-width: 172px; + height: 50px; + grid-template-columns: 34px 1fr 14px; + align-items: center; + gap: 9px; + padding: 0 12px; + background: rgba(255, 255, 255, 0.65); + border: 1px solid var(--line); + border-radius: 12px; +} + +.role-avatar { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: white; + background: var(--green); + border-radius: 10px; + font-size: 12px; + font-weight: 700; +} + +.role-copy strong, +.role-copy small { + display: block; +} + +.role-copy strong { + font-size: 11px; +} + +.role-copy small { + margin-top: 3px; + color: var(--muted); + font-size: 9px; +} + +.role-switcher > svg { + width: 13px; + height: 13px; + color: var(--muted); +} + +.role-switcher select { + position: absolute; + inset: 0; + width: 100%; + opacity: 0; + cursor: pointer; +} + +.notification-button { + position: relative; + background: rgba(255, 255, 255, 0.68); + border: 1px solid var(--line); +} + +.notification-button > span { + position: absolute; + top: -4px; + right: -3px; + display: grid; + width: 17px; + height: 17px; + place-items: center; + color: white; + background: var(--red); + border: 2px solid var(--canvas); + border-radius: 50%; + font-size: 8px; + font-weight: 700; +} + +.mobile-menu { + display: none; +} + +.main-content { + max-width: 1720px; + margin: 0 auto; + padding: 34px 30px 60px; +} + +.view { + display: none; + animation: viewIn 0.34s ease both; +} + +.view.active { + display: block; +} + +@keyframes viewIn { + from { + opacity: 0; + transform: translateY(6px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.page-heading { + margin-bottom: 28px; +} + +.heading-with-actions, +.profession-heading { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 24px; +} + +.eyebrow { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 8px; + color: var(--green-2); + font-size: 9px; + font-weight: 800; + letter-spacing: 0.16em; +} + +.eyebrow span { + display: inline-block; + width: 22px; + height: 2px; + background: var(--green-2); +} + +.page-heading h1 { + margin: 0; + color: #142920; + font-size: clamp(25px, 2.2vw, 36px); + font-weight: 700; + letter-spacing: -0.055em; +} + +.page-heading p { + margin: 9px 0 0; + color: var(--muted); + font-size: 12px; + line-height: 1.7; +} + +.heading-actions { + display: flex; + gap: 10px; + flex: 0 0 auto; +} + +.button { + display: inline-flex; + min-height: 42px; + align-items: center; + justify-content: center; + gap: 8px; + padding: 0 17px; + border: 1px solid transparent; + border-radius: 10px; + font-size: 12px; + font-weight: 600; + transition: + transform 0.18s ease, + box-shadow 0.18s ease, + background 0.18s ease; +} + +.button:hover { + transform: translateY(-1px); +} + +.button svg { + width: 16px; + height: 16px; +} + +.button.primary { + color: white; + background: var(--green); + box-shadow: 0 8px 18px rgba(23, 107, 79, 0.16); +} + +.button.primary:hover { + background: #125e45; + box-shadow: 0 11px 22px rgba(23, 107, 79, 0.22); +} + +.button.secondary { + color: var(--ink-soft); + background: white; + border-color: var(--line); +} + +.button.secondary:hover, +.button.tertiary:hover { + background: #f8faf8; +} + +.button.tertiary { + color: var(--green); + background: var(--green-soft); + border-color: #d2e9de; + box-shadow: none; +} + +.quality-strip { + display: flex; + min-height: 58px; + align-items: center; + justify-content: space-between; + gap: 20px; + margin-bottom: 18px; + padding: 10px 16px; + background: linear-gradient(90deg, #e8f3ec, #f4f8ed); + border: 1px solid #dceadd; + border-radius: 13px; +} + +.quality-main { + display: flex; + align-items: center; + gap: 12px; +} + +.quality-icon { + display: grid; + width: 35px; + height: 35px; + flex: 0 0 auto; + place-items: center; + color: var(--green); + background: white; + border-radius: 10px; + box-shadow: 0 3px 10px rgba(23, 107, 79, 0.08); +} + +.quality-icon svg { + width: 18px; + height: 18px; +} + +.quality-main strong, +.quality-main span { + display: block; +} + +.quality-main strong { + margin-bottom: 3px; + font-size: 11px; +} + +.quality-main span { + color: var(--muted); + font-size: 9px; +} + +.text-button { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 6px 4px; + color: var(--green); + background: transparent; + font-size: 10px; + font-weight: 600; + white-space: nowrap; +} + +.text-button:hover { + color: #0e543d; +} + +.text-button svg { + width: 13px; + height: 13px; +} + +.metric-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 14px; + margin-bottom: 14px; +} + +.metric-card, +.panel { + min-width: 0; + background: var(--surface); + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.metric-card { + position: relative; + min-height: 145px; + padding: 18px 20px; + overflow: hidden; +} + +.metric-card::after { + position: absolute; + right: -14px; + bottom: -36px; + width: 110px; + height: 90px; + background: radial-gradient(circle, rgba(198, 230, 111, 0.12), transparent 68%); + content: ""; +} + +.metric-top { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.metric-label { + color: var(--muted); + font-size: 10px; + font-weight: 600; +} + +.info-button { + display: grid; + width: 18px; + height: 18px; + place-items: center; + color: #87938d; + background: #f1f4f1; + border-radius: 50%; + font-family: Georgia, serif; + font-size: 10px; + font-weight: 700; +} + +.metric-tag { + padding: 4px 7px; + border-radius: 6px; + font-size: 8px; + font-weight: 700; +} + +.metric-tag.green { + color: var(--green); + background: var(--green-soft); +} + +.metric-tag.amber { + color: #946313; + background: var(--amber-soft); +} + +.metric-tag.blue { + color: #426d97; + background: var(--blue-soft); +} + +.metric-value { + display: flex; + align-items: baseline; + gap: 5px; + margin-top: 12px; +} + +.metric-value strong { + font-size: clamp(26px, 2.15vw, 34px); + font-weight: 700; + letter-spacing: -0.055em; +} + +.metric-value small { + color: var(--muted); + font-size: 10px; +} + +.metric-foot { + display: flex; + align-items: center; + gap: 8px; + margin-top: 7px; + font-size: 9px; +} + +.metric-foot span { + font-weight: 700; +} + +.metric-foot small { + color: #87938d; +} + +.metric-foot.positive span { + color: var(--green-2); +} + +.metric-foot.warning span { + color: #b27218; +} + +.metric-spark { + position: absolute; + right: 15px; + bottom: 14px; + width: 78px; + height: 30px; + opacity: 0.78; +} + +.metric-spark svg { + width: 100%; + height: 100%; + overflow: visible; +} + +.metric-spark path.area { + stroke: none; +} + +.metric-progress { + width: 100%; + height: 5px; + margin-top: 14px; + overflow: hidden; + background: #edf0ed; + border-radius: 4px; +} + +.metric-progress i { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #71b88c); + border-radius: 4px; +} + +.dashboard-grid { + display: grid; + grid-template-columns: minmax(0, 1.8fr) minmax(310px, 0.82fr); + gap: 14px; + margin-bottom: 14px; +} + +.panel { + padding: 22px; +} + +.panel-header { + display: flex; + min-height: 36px; + align-items: flex-start; + justify-content: space-between; + gap: 16px; +} + +.panel-kicker { + display: block; + margin-bottom: 5px; + color: #8a9790; + font-size: 8px; + font-weight: 700; + letter-spacing: 0.12em; +} + +.panel h2 { + margin: 0; + color: #1c3028; + font-size: 14px; + font-weight: 700; +} + +.segmented { + display: inline-flex; + padding: 3px; + background: #f2f5f2; + border-radius: 9px; +} + +.segmented button { + padding: 6px 10px; + color: #7d8983; + background: transparent; + border-radius: 7px; + font-size: 9px; +} + +.segmented button.active { + color: var(--ink); + background: white; + box-shadow: 0 2px 7px rgba(21, 53, 41, 0.08); + font-weight: 600; +} + +.match-content { + display: grid; + grid-template-columns: 170px minmax(0, 1fr); + align-items: center; + gap: 8px; + min-height: 226px; + padding-top: 6px; +} + +.score-dial { + position: relative; + display: grid; + width: 158px; + height: 158px; + place-items: center; +} + +.score-dial::after { + position: absolute; + width: 112px; + height: 112px; + border: 1px dashed #d9e4dc; + border-radius: 50%; + content: ""; +} + +.score-dial svg { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.score-dial circle { + fill: none; + stroke-width: 11; +} + +.dial-track { + stroke: #edf1ed; +} + +.dial-value { + stroke: var(--green); + stroke-dasharray: 389.6; + stroke-dashoffset: 83.4; + transition: stroke-dashoffset 0.5s ease; +} + +.score-dial > div { + position: relative; + z-index: 2; + text-align: center; +} + +.score-dial strong, +.score-dial span { + display: block; +} + +.score-dial strong { + font-size: 31px; + letter-spacing: -0.06em; +} + +.score-dial span { + margin-top: 2px; + color: var(--muted); + font-size: 9px; +} + +.trend-chart-wrap { + min-width: 0; +} + +.chart-legend { + display: flex; + justify-content: flex-end; + gap: 18px; + margin: 5px 8px 8px; + color: var(--muted); + font-size: 8px; +} + +.chart-legend span { + display: inline-flex; + align-items: center; + gap: 6px; +} + +.chart-legend i { + display: inline-block; + width: 15px; + height: 2px; +} + +.legend-current { + background: var(--green); +} + +.legend-benchmark { + background: #aebbb4; +} + +.line-chart { + display: block; + width: 100%; + height: 165px; + overflow: visible; +} + +.line-chart .grid-line { + stroke: #e7ece8; + stroke-width: 1; +} + +.line-chart .area-shape { + fill: url("#areaGradient"); + stroke: none; +} + +.line-chart .main-line { + fill: none; + stroke: var(--green); + stroke-width: 3.2; + vector-effect: non-scaling-stroke; +} + +.line-chart .benchmark-line { + fill: none; + stroke: #b4c0ba; + stroke-dasharray: 5 6; + stroke-width: 1.6; + vector-effect: non-scaling-stroke; +} + +.line-chart .data-point { + fill: white; + stroke: var(--green); + stroke-width: 2.6; + vector-effect: non-scaling-stroke; +} + +.line-chart .last-point { + fill: var(--lime); + stroke: var(--green); + stroke-width: 3; +} + +.line-chart .chart-value { + fill: var(--ink); + stroke: none; + font-size: 18px; + font-weight: 700; +} + +.chart-labels { + display: flex; + justify-content: space-between; + padding: 2px 0 0; + color: #94a098; + font-size: 8px; +} + +.match-summary { + display: flex; + min-height: 42px; + align-items: center; + justify-content: space-around; + gap: 14px; + margin: 2px -4px -5px; + padding-top: 12px; + border-top: 1px solid var(--line-soft); +} + +.match-summary span { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--muted); + font-size: 9px; +} + +.match-summary strong { + color: var(--ink); + font-size: 11px; +} + +.match-summary i { + width: 7px; + height: 7px; + border-radius: 50%; +} + +.summary-good { + background: var(--green-2); +} + +.summary-watch { + background: var(--amber); +} + +.summary-risk { + background: var(--red); +} + +.ai-panel { + position: relative; + color: #e7f1ec; + background: + radial-gradient(circle at 100% 0, rgba(198, 230, 111, 0.13), transparent 34%), + linear-gradient(160deg, #153f32, #102d25); + border-color: rgba(255, 255, 255, 0.06); + overflow: hidden; +} + +.ai-panel::after { + position: absolute; + right: -55px; + bottom: -65px; + width: 175px; + height: 175px; + border: 1px solid rgba(198, 230, 111, 0.09); + border-radius: 50%; + box-shadow: + 0 0 0 25px rgba(198, 230, 111, 0.025), + 0 0 0 50px rgba(198, 230, 111, 0.018); + content: ""; +} + +.ai-panel-head { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: 38px 1fr auto; + align-items: center; + gap: 10px; +} + +.ai-symbol { + display: grid; + width: 38px; + height: 38px; + place-items: center; + color: var(--lime); + background: rgba(198, 230, 111, 0.1); + border: 1px solid rgba(198, 230, 111, 0.12); + border-radius: 11px; +} + +.ai-symbol svg { + width: 20px; + height: 20px; +} + +.ai-panel-head small { + color: #79998c; + font-size: 7px; + font-weight: 700; + letter-spacing: 0.13em; +} + +.ai-panel-head h2 { + margin-top: 4px; + color: white; + font-size: 14px; +} + +.ai-state { + padding: 4px 7px; + color: #cce591; + background: rgba(198, 230, 111, 0.1); + border-radius: 5px; + font-size: 8px; +} + +.ai-lead { + position: relative; + z-index: 1; + margin: 18px 0 14px; + color: #bfd1c9; + font-size: 10px; + line-height: 1.8; +} + +.insight-list { + position: relative; + z-index: 1; +} + +.insight-item { + display: grid; + width: 100%; + grid-template-columns: 27px 1fr 14px; + align-items: center; + gap: 9px; + padding: 11px 0; + color: #edf6f1; + background: transparent; + border-top: 1px solid rgba(255, 255, 255, 0.08); + text-align: left; +} + +.insight-item:hover strong { + color: var(--lime); +} + +.insight-index { + color: #728f83; + font-size: 9px; + font-variant-numeric: tabular-nums; +} + +.insight-item strong, +.insight-item small { + display: block; +} + +.insight-item strong { + margin-bottom: 4px; + font-size: 10px; + font-weight: 600; + transition: color 0.2s ease; +} + +.insight-item small { + color: #78968a; + font-size: 8px; +} + +.insight-item > svg { + width: 13px; + height: 13px; + color: #67867a; +} + +.ai-source { + position: relative; + z-index: 1; + display: flex; + align-items: center; + gap: 6px; + margin-top: 12px; + color: #6d8c80; + font-size: 8px; +} + +.ai-source svg { + width: 13px; + height: 13px; +} + +.content-grid { + display: grid; + grid-template-columns: minmax(0, 1.75fr) minmax(300px, 0.65fr); + gap: 14px; +} + +.panel-tools { + display: flex; + align-items: center; + gap: 12px; +} + +.search-field { + display: flex; + width: 260px; + height: 40px; + align-items: center; + gap: 8px; + padding: 0 12px; + background: white; + border: 1px solid var(--line); + border-radius: 9px; +} + +.search-field.compact { + width: 150px; + height: 32px; + background: #f7f9f7; + border-color: transparent; +} + +.search-field svg { + width: 15px; + height: 15px; + flex: 0 0 auto; + color: #89958e; +} + +.search-field input { + width: 100%; + min-width: 0; + padding: 0; + background: transparent; + border: 0; + outline: 0; + font-size: 10px; +} + +.search-field input::placeholder { + color: #a1aaa5; +} + +.table-wrap { + width: 100%; + margin-top: 12px; + overflow-x: auto; +} + +.data-table { + width: 100%; + border-collapse: collapse; + white-space: nowrap; +} + +.data-table th { + padding: 10px 9px; + color: #88948d; + border-bottom: 1px solid var(--line-soft); + font-size: 8px; + font-weight: 600; + text-align: left; +} + +.data-table td { + padding: 12px 9px; + color: #617068; + border-bottom: 1px solid #eff2ef; + font-size: 9px; +} + +.data-table tbody tr { + transition: background 0.18s ease; +} + +.data-table tbody tr:hover { + background: #f8faf8; +} + +.data-table tbody tr:last-child td { + border-bottom: 0; +} + +.profession-cell { + display: flex; + align-items: center; + gap: 9px; +} + +.profession-icon { + display: grid; + width: 31px; + height: 31px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 9px; + font-size: 10px; + font-weight: 700; +} + +.profession-cell strong { + color: var(--ink); + font-size: 10px; +} + +.score-cell { + display: flex; + align-items: center; + gap: 8px; +} + +.score-cell strong { + width: 25px; + color: var(--ink); + font-size: 10px; +} + +.score-bar { + width: 52px; + height: 4px; + overflow: hidden; + background: #ecf0ec; + border-radius: 3px; +} + +.score-bar i { + display: block; + height: 100%; + background: var(--green-2); + border-radius: 3px; +} + +.score-bar.mid i { + background: var(--amber); +} + +.score-bar.low i { + background: var(--red); +} + +.gap-badge, +.status-badge { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 5px 7px; + border-radius: 6px; + font-size: 8px; + font-weight: 600; +} + +.gap-badge.high, +.status-badge.risk { + color: #a84137; + background: var(--red-soft); +} + +.gap-badge.mid, +.status-badge.progress { + color: #a16d16; + background: var(--amber-soft); +} + +.gap-badge.low, +.status-badge.done { + color: var(--green); + background: var(--green-soft); +} + +.status-badge.review { + color: #426d97; + background: var(--blue-soft); +} + +.trend-up { + color: var(--green-2); + font-weight: 700; +} + +.trend-down { + color: var(--red); + font-weight: 700; +} + +.row-action { + display: grid; + width: 25px; + height: 25px; + place-items: center; + color: #829088; + background: transparent; + border-radius: 7px; +} + +.row-action:hover { + color: var(--green); + background: var(--green-soft); +} + +.row-action svg { + width: 13px; + height: 13px; +} + +.more-button { + display: grid; + width: 28px; + height: 28px; + place-items: center; + color: var(--muted); + background: #f4f6f4; + border-radius: 8px; +} + +.more-button svg { + width: 15px; + height: 15px; +} + +.industry-list { + margin-top: 16px; +} + +.industry-item { + display: grid; + grid-template-columns: 31px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 10px 0; + border-bottom: 1px solid #eff2ef; +} + +.industry-item:last-child { + border-bottom: 0; +} + +.industry-rank { + display: grid; + width: 27px; + height: 27px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 8px; + font-size: 9px; + font-weight: 700; +} + +.industry-item:nth-child(1) .industry-rank { + color: #463d19; + background: var(--lime); +} + +.industry-copy strong, +.industry-copy small { + display: block; +} + +.industry-copy strong { + margin-bottom: 6px; + font-size: 9px; +} + +.industry-copy small { + position: relative; + width: 100%; + height: 3px; + overflow: hidden; + background: #edf0ed; + border-radius: 3px; +} + +.industry-copy i { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #83bf96); + border-radius: 3px; +} + +.industry-growth { + color: var(--green-2); + font-size: 10px; + font-weight: 700; +} + +.industry-note { + display: grid; + grid-template-columns: 1fr auto; + gap: 6px 10px; + margin-top: 12px; + padding: 12px; + color: #7d8983; + background: #f7f9f7; + border-radius: 10px; + font-size: 8px; +} + +.industry-note strong { + color: var(--ink-soft); + font-size: 9px; + text-align: right; +} + +/* 专业洞察 */ +.heading-inline { + display: flex; + align-items: center; + gap: 10px; +} + +.profession-select { + position: relative; + display: inline-flex; + width: 28px; + height: 28px; + align-items: center; + justify-content: center; + color: var(--green); + background: var(--green-soft); + border-radius: 8px; +} + +.profession-select select { + position: absolute; + inset: 0; + width: 100%; + opacity: 0; + cursor: pointer; +} + +.profession-select svg { + width: 14px; + height: 14px; +} + +.profile-banner { + display: grid; + grid-template-columns: 160px 1px repeat(4, minmax(0, 1fr)); + align-items: center; + gap: 25px; + margin-bottom: 16px; + padding: 22px 28px; + color: white; + background: + radial-gradient(circle at 85% 20%, rgba(198, 230, 111, 0.12), transparent 28%), + linear-gradient(110deg, #153d31, #102d25); + border-radius: 18px; + box-shadow: var(--shadow); +} + +.profile-score span, +.profile-score small, +.profile-metric span, +.profile-metric small { + display: block; +} + +.profile-score span, +.profile-metric span { + margin-bottom: 7px; + color: #88a69a; + font-size: 9px; +} + +.profile-score strong { + display: inline-block; + margin-right: 7px; + color: var(--lime); + font-size: 33px; + letter-spacing: -0.055em; +} + +.profile-score small { + display: inline-flex; + padding: 4px 7px; + color: #bed683; + background: rgba(198, 230, 111, 0.09); + border-radius: 5px; + font-size: 8px; +} + +.profile-divider { + width: 1px; + height: 48px; + background: rgba(255, 255, 255, 0.12); +} + +.profile-metric strong { + display: inline-block; + margin-right: 5px; + font-size: 20px; + letter-spacing: -0.04em; +} + +.profile-metric small { + margin-top: 6px; + color: #7d9c8f; + font-size: 8px; +} + +.profile-metric small.up { + display: inline; + color: #a7ca72; +} + +.tab-bar { + display: flex; + gap: 4px; + margin-bottom: 14px; + padding: 5px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 12px; + box-shadow: 0 5px 20px rgba(27, 54, 43, 0.04); +} + +.tab-bar button { + min-width: 90px; + padding: 9px 13px; + color: var(--muted); + background: transparent; + border-radius: 8px; + font-size: 10px; +} + +.tab-bar button.active { + color: white; + background: var(--green); + font-weight: 600; +} + +.profession-layout { + display: grid; + grid-template-columns: minmax(0, 1.6fr) minmax(300px, 0.72fr); + gap: 14px; +} + +.profession-main, +.profession-side { + display: flex; + min-width: 0; + flex-direction: column; + gap: 14px; +} + +.legend-row { + display: flex; + gap: 14px; + color: var(--muted); + font-size: 8px; +} + +.legend-row span { + display: inline-flex; + align-items: center; + gap: 5px; +} + +.legend-row i { + display: inline-block; + width: 12px; + height: 3px; + border-radius: 3px; +} + +.market-legend { + background: var(--green); +} + +.course-legend { + background: var(--lime); +} + +.skill-chart { + display: flex; + flex-direction: column; + gap: 13px; + margin-top: 20px; +} + +.skill-row { + display: grid; + grid-template-columns: 90px minmax(0, 1fr) 46px; + align-items: center; + gap: 13px; +} + +.skill-name strong, +.skill-name small { + display: block; +} + +.skill-name strong { + margin-bottom: 3px; + font-size: 9px; +} + +.skill-name small { + color: #919c96; + font-size: 7px; +} + +.skill-bars { + display: flex; + flex-direction: column; + gap: 4px; +} + +.skill-bars span { + display: block; + height: 5px; + overflow: hidden; + background: #edf0ed; + border-radius: 4px; +} + +.skill-bars i { + display: block; + height: 100%; + border-radius: 4px; + transition: width 0.45s ease; +} + +.skill-bars span:first-child i { + background: var(--green); +} + +.skill-bars span:last-child i { + background: var(--lime); +} + +.skill-gap { + text-align: right; +} + +.skill-gap strong { + display: block; + font-size: 9px; +} + +.skill-gap small { + display: block; + margin-top: 3px; + color: #929d97; + font-size: 7px; +} + +.skill-gap.high strong { + color: var(--red); +} + +.skill-gap.mid strong { + color: var(--amber); +} + +.skill-gap.low strong { + color: var(--green); +} + +.explainable-tag { + display: inline-flex; + align-items: center; + gap: 5px; + padding: 5px 8px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 8px; +} + +.explainable-tag svg { + width: 12px; + height: 12px; +} + +.recommendation-list { + display: flex; + flex-direction: column; + gap: 10px; + margin-top: 16px; +} + +.recommendation-card { + padding: 14px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 12px; + transition: + border-color 0.2s ease, + transform 0.2s ease; +} + +.recommendation-card:hover { + border-color: #cadbcf; + transform: translateY(-1px); +} + +.recommendation-card.accepted { + background: #f4f9f6; + border-color: #bad9c9; +} + +.recommendation-top { + display: flex; + align-items: flex-start; + gap: 10px; +} + +.priority-mark { + flex: 0 0 auto; + padding: 4px 6px; + color: #a14337; + background: var(--red-soft); + border-radius: 5px; + font-size: 7px; + font-weight: 700; +} + +.priority-mark.mid { + color: #956512; + background: var(--amber-soft); +} + +.recommendation-copy { + min-width: 0; + flex: 1; +} + +.recommendation-copy strong { + display: block; + margin-bottom: 6px; + font-size: 10px; +} + +.recommendation-copy p { + margin: 0; + color: var(--muted); + font-size: 8px; + line-height: 1.65; +} + +.recommendation-evidence { + display: flex; + align-items: center; + gap: 6px; + margin-top: 10px; + padding: 9px 11px; + color: var(--green); + background: #eef7f2; + border: 1px solid #dcece3; + border-radius: 8px; + font-size: 14px; + font-weight: 600; + line-height: 1.65; +} + +.recommendation-evidence svg { + width: 17px; + height: 17px; + flex: 0 0 auto; +} + +.recommendation-actions { + display: flex; + gap: 6px; + margin-top: 11px; +} + +.recommendation-actions button { + padding: 6px 10px; + color: #6c7972; + background: white; + border: 1px solid var(--line); + border-radius: 7px; + font-size: 8px; +} + +.recommendation-actions button:first-child { + color: var(--green); + background: var(--green-soft); + border-color: #d2e6dc; +} + +.time-caption { + color: #929c96; + font-size: 8px; +} + +.job-demand-list { + margin-top: 16px; +} + +.job-demand-item { + margin-bottom: 15px; +} + +.job-demand-copy { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 6px; +} + +.job-demand-copy strong { + font-size: 9px; +} + +.job-demand-copy span { + color: var(--muted); + font-size: 8px; +} + +.job-demand-copy em { + margin-left: 5px; + color: var(--green-2); + font-style: normal; + font-weight: 700; +} + +.job-demand-bar { + height: 5px; + overflow: hidden; + background: #edf0ed; + border-radius: 4px; +} + +.job-demand-bar i { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #76b78f); + border-radius: 4px; +} + +.company-shortlist { + margin-top: 10px; +} + +.company-short-item { + display: grid; + grid-template-columns: 35px 1fr auto; + align-items: center; + gap: 9px; + padding: 11px 0; + border-bottom: 1px solid var(--line-soft); +} + +.company-short-item:last-child { + border-bottom: 0; +} + +.company-logo { + display: grid; + width: 35px; + height: 35px; + place-items: center; + color: var(--green); + background: #eef5f1; + border-radius: 10px; + font-size: 9px; + font-weight: 800; +} + +.company-short-copy strong, +.company-short-copy small { + display: block; +} + +.company-short-copy strong { + margin-bottom: 4px; + font-size: 9px; +} + +.company-short-copy small { + color: var(--muted); + font-size: 7px; +} + +.match-chip { + padding: 5px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 8px; + font-weight: 700; +} + +/* 校企协同 */ +.collab-stats { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + margin-bottom: 14px; + background: white; + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.collab-stats > div { + position: relative; + padding: 19px 22px; +} + +.collab-stats > div:not(:last-child)::after { + position: absolute; + top: 17px; + right: 0; + bottom: 17px; + width: 1px; + background: var(--line-soft); + content: ""; +} + +.collab-stats span, +.collab-stats em { + display: block; +} + +.collab-stats span { + margin-bottom: 8px; + color: var(--muted); + font-size: 9px; +} + +.collab-stats strong { + font-size: 25px; + letter-spacing: -0.04em; +} + +.collab-stats small { + margin-left: 3px; + color: var(--muted); + font-size: 9px; +} + +.collab-stats em { + margin-top: 7px; + color: var(--green-2); + font-size: 8px; + font-style: normal; +} + +.collab-layout { + display: grid; + grid-template-columns: minmax(0, 1.4fr) minmax(310px, 0.75fr); + gap: 14px; + margin-bottom: 14px; +} + +.project-list, +.demand-list { + margin-top: 15px; +} + +.project-item { + display: grid; + grid-template-columns: 42px minmax(0, 1fr) 120px 90px 26px; + align-items: center; + gap: 12px; + padding: 13px 0; + border-bottom: 1px solid var(--line-soft); +} + +.project-item:last-child { + border-bottom: 0; +} + +.project-type { + display: grid; + width: 38px; + height: 38px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 10px; +} + +.project-type.amber { + color: #a06a13; + background: var(--amber-soft); +} + +.project-type.blue { + color: var(--blue); + background: var(--blue-soft); +} + +.project-type svg { + width: 18px; + height: 18px; +} + +.project-copy strong, +.project-copy small { + display: block; +} + +.project-copy strong { + margin-bottom: 5px; + font-size: 9px; +} + +.project-copy small { + color: var(--muted); + font-size: 7px; +} + +.project-partners { + display: flex; + align-items: center; +} + +.partner-avatar { + display: grid; + width: 27px; + height: 27px; + place-items: center; + margin-right: -5px; + color: white; + background: #477b68; + border: 2px solid white; + border-radius: 50%; + font-size: 7px; +} + +.partner-avatar:nth-child(2) { + background: #8d8062; +} + +.partner-avatar:nth-child(3) { + background: #587993; +} + +.project-progress span { + display: flex; + justify-content: space-between; + margin-bottom: 6px; + color: var(--muted); + font-size: 7px; +} + +.project-progress span strong { + color: var(--ink-soft); +} + +.project-progress i { + display: block; + height: 4px; + overflow: hidden; + background: #ebefeb; + border-radius: 4px; +} + +.project-progress b { + display: block; + height: 100%; + background: var(--green-2); + border-radius: 4px; +} + +.demand-item { + padding: 12px; + margin-bottom: 9px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.demand-item-top { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 8px; +} + +.demand-company { + display: flex; + align-items: center; + gap: 8px; +} + +.demand-company .company-logo { + width: 29px; + height: 29px; + font-size: 7px; +} + +.demand-company strong, +.demand-company small { + display: block; +} + +.demand-company strong { + margin-bottom: 3px; + font-size: 8px; +} + +.demand-company small { + color: var(--muted); + font-size: 7px; +} + +.demand-item > strong { + display: block; + margin-bottom: 6px; + font-size: 9px; +} + +.demand-item > p { + margin: 0; + color: var(--muted); + font-size: 8px; + line-height: 1.55; +} + +.demand-action { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 9px; + padding-top: 8px; + border-top: 1px dashed #e0e6e1; +} + +.demand-action span { + color: #929d97; + font-size: 7px; +} + +.demand-action button { + padding: 5px 8px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 7px; + font-weight: 600; +} + +.panel-count { + display: inline-grid; + min-width: 28px; + height: 24px; + place-items: center; + padding: 0 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 8px; + font-weight: 700; +} + +.amber-count { + color: #a36c12; + background: var(--amber-soft); +} + +.filter-pills { + display: flex; + gap: 6px; +} + +.filter-pills button { + padding: 7px 10px; + color: var(--muted); + background: #f4f6f4; + border-radius: 8px; + font-size: 8px; +} + +.filter-pills button.active { + color: white; + background: var(--green); +} + +.partner-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-top: 17px; +} + +.partner-card { + position: relative; + padding: 15px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 13px; + overflow: hidden; +} + +.partner-card::after { + position: absolute; + right: -18px; + top: -20px; + width: 65px; + height: 65px; + background: var(--green-soft); + border-radius: 50%; + content: ""; + opacity: 0.55; +} + +.partner-card-head { + position: relative; + z-index: 1; + display: flex; + align-items: center; + gap: 9px; +} + +.partner-card-head .company-logo { + width: 38px; + height: 38px; + color: white; + background: var(--green); +} + +.partner-card-head strong, +.partner-card-head small { + display: block; +} + +.partner-card-head strong { + margin-bottom: 4px; + font-size: 9px; +} + +.partner-card-head small { + color: var(--muted); + font-size: 7px; +} + +.partner-reason { + min-height: 42px; + margin: 13px 0; + color: var(--muted); + font-size: 8px; + line-height: 1.65; +} + +.partner-tags { + display: flex; + flex-wrap: wrap; + gap: 5px; +} + +.partner-tags span { + padding: 4px 6px; + color: #5c7167; + background: #eef2ef; + border-radius: 5px; + font-size: 7px; +} + +.partner-card-foot { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 13px; + padding-top: 11px; + border-top: 1px solid var(--line-soft); +} + +.partner-card-foot strong { + color: var(--green); + font-size: 9px; +} + +.partner-card-foot button { + padding: 6px 9px; + color: white; + background: var(--green); + border-radius: 7px; + font-size: 7px; +} + +/* 改进任务 */ +.action-overview { + display: grid; + grid-template-columns: 130px repeat(4, minmax(100px, 1fr)) minmax(130px, 1.2fr); + align-items: center; + gap: 12px; + margin-bottom: 14px; +} + +.action-ring { + position: relative; + display: grid; + width: 100px; + height: 100px; + place-items: center; +} + +.action-ring svg { + position: absolute; + width: 100%; + height: 100%; + transform: rotate(-90deg); +} + +.action-ring circle { + fill: none; + stroke: #edf1ed; + stroke-width: 8; +} + +.action-ring circle.complete { + stroke: var(--green); + stroke-dasharray: 295.3; + stroke-dashoffset: 94.5; +} + +.action-ring span { + position: relative; + text-align: center; +} + +.action-ring strong, +.action-ring small { + display: block; +} + +.action-ring strong { + font-size: 20px; +} + +.action-ring small { + margin-top: 3px; + color: var(--muted); + font-size: 7px; +} + +.action-stat { + padding: 8px 15px; + border-left: 1px solid var(--line-soft); +} + +.action-stat span, +.action-stat strong, +.action-stat small { + display: block; +} + +.action-stat span { + margin-bottom: 7px; + color: var(--muted); + font-size: 8px; +} + +.action-stat strong { + font-size: 23px; +} + +.action-stat small { + margin-top: 5px; + color: #8c9891; + font-size: 7px; +} + +.action-health { + padding: 14px; + background: #f6f9f6; + border-radius: 12px; +} + +.action-health span { + color: var(--muted); + font-size: 8px; +} + +.action-health strong { + float: right; + color: var(--green); + font-size: 9px; +} + +.action-health div { + height: 5px; + margin-top: 11px; + overflow: hidden; + background: #e6ebe7; + border-radius: 4px; +} + +.action-health i { + display: block; + height: 100%; + background: var(--green); + border-radius: 4px; +} + +.task-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; +} + +.task-table .task-title strong, +.task-table .task-title small { + display: block; +} + +.task-table .task-title strong { + margin-bottom: 4px; + color: var(--ink); + font-size: 9px; +} + +.task-table .task-title small { + color: #929c96; + font-size: 7px; +} + +.owner-cell { + display: flex; + align-items: center; + gap: 7px; +} + +.owner-avatar { + display: grid; + width: 25px; + height: 25px; + place-items: center; + color: white; + background: #557b6b; + border-radius: 8px; + font-size: 7px; +} + +.task-progress-cell { + display: flex; + align-items: center; + gap: 7px; +} + +.task-progress-cell i { + display: block; + width: 55px; + height: 4px; + overflow: hidden; + background: #ebefeb; + border-radius: 4px; +} + +.task-progress-cell b { + display: block; + height: 100%; + background: var(--green-2); + border-radius: 4px; +} + +.task-progress-cell span { + color: var(--ink-soft); + font-size: 8px; +} + +/* 数据资产 */ +.data-health { + display: grid; + grid-template-columns: minmax(0, 1.45fr) minmax(320px, 0.75fr); + gap: 14px; + margin-bottom: 14px; +} + +.data-health-main { + display: grid; + grid-template-columns: 130px 1fr; + align-items: center; + gap: 25px; + padding: 25px 28px; + color: white; + background: + radial-gradient(circle at 90% 10%, rgba(198, 230, 111, 0.13), transparent 29%), + linear-gradient(120deg, #153d31, #102c24); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.health-score { + padding-right: 25px; + border-right: 1px solid rgba(255, 255, 255, 0.12); +} + +.health-score span, +.health-score strong, +.health-score small { + display: block; +} + +.health-score span { + color: #89a69b; + font-size: 9px; +} + +.health-score strong { + margin: 6px 0 4px; + color: var(--lime); + font-size: 35px; + letter-spacing: -0.055em; +} + +.health-score small { + color: #bad381; + font-size: 8px; +} + +.health-copy h2 { + margin: 0 0 7px; + color: white; + font-size: 14px; +} + +.health-copy > p { + margin: 0; + color: #90aaa0; + font-size: 8px; + line-height: 1.65; +} + +.health-meta { + display: flex; + flex-wrap: wrap; + gap: 15px; + margin-top: 16px; +} + +.health-meta span { + display: inline-flex; + align-items: center; + gap: 5px; + color: #829e93; + font-size: 7px; +} + +.health-meta i { + width: 5px; + height: 5px; + background: var(--lime); + border-radius: 50%; +} + +.health-meta strong { + color: #d9e5df; + font-weight: 500; +} + +.quality-dimensions { + display: flex; + flex-direction: column; + justify-content: center; + gap: 14px; + padding: 22px; + background: white; + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.quality-dimensions > div { + display: grid; + grid-template-columns: 64px 1fr 42px; + align-items: center; + gap: 10px; +} + +.quality-dimensions span { + color: var(--muted); + font-size: 8px; +} + +.quality-dimensions strong { + grid-column: 3; + grid-row: 1; + font-size: 9px; + text-align: right; +} + +.quality-dimensions i { + grid-column: 2; + grid-row: 1; + display: block; + height: 5px; + overflow: hidden; + background: #edf0ed; + border-radius: 4px; +} + +.quality-dimensions b { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #79b58c); + border-radius: 4px; +} + +.source-panel { + margin-bottom: 14px; +} + +.source-summary-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 14px; + margin-bottom: 14px; +} + +.source-summary-card { + position: relative; + display: grid; + min-width: 0; + grid-template-columns: 46px minmax(0, 1fr) 18px; + align-items: start; + gap: 14px; + padding: 20px; + overflow: hidden; + background: white; + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: var(--shadow); + text-align: left; + transition: + transform 0.2s ease, + border-color 0.2s ease, + box-shadow 0.2s ease; +} + +.source-summary-card::after { + position: absolute; + right: -35px; + bottom: -50px; + width: 130px; + height: 130px; + background: currentColor; + border-radius: 50%; + content: ""; + opacity: 0.035; +} + +.source-summary-card:hover, +.source-summary-card.active { + transform: translateY(-2px); + box-shadow: 0 14px 38px rgba(27, 54, 43, 0.11); +} + +.source-summary-card.vendor { + color: var(--blue); +} + +.source-summary-card.vendor:hover, +.source-summary-card.vendor.active { + border-color: #b9d1e7; +} + +.source-summary-card.school { + color: var(--green); +} + +.source-summary-card.school:hover, +.source-summary-card.school.active { + border-color: #b9d9c9; +} + +.source-summary-card.enterprise { + color: #ad741d; +} + +.source-summary-card.enterprise:hover, +.source-summary-card.enterprise.active { + border-color: #e7cc9e; +} + +.source-summary-icon { + display: grid; + width: 46px; + height: 46px; + place-items: center; + background: currentColor; + border-radius: 13px; +} + +.source-summary-icon::before { + position: absolute; + width: 46px; + height: 46px; + background: white; + border-radius: 13px; + content: ""; + opacity: 0.88; +} + +.source-summary-icon svg { + position: relative; + z-index: 1; + width: 22px; + height: 22px; +} + +.source-summary-copy { + display: block; + min-width: 0; +} + +.source-summary-title { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + color: var(--ink); +} + +.source-summary-title strong { + font-size: 14px; +} + +.commercial-pill { + flex: 0 0 auto; + padding: 5px 8px; + border-radius: 7px; + font-size: 10px; + font-style: normal; + font-weight: 700; +} + +.commercial-pill.paid { + color: #376991; + background: var(--blue-soft); +} + +.commercial-pill.owned { + color: var(--green); + background: var(--green-soft); +} + +.commercial-pill.authorized { + color: #956313; + background: var(--amber-soft); +} + +.source-summary-copy > small { + display: block; + min-height: 38px; + margin-top: 8px; + color: var(--muted); + line-height: 1.6; +} + +.source-summary-metrics { + display: flex; + gap: 18px; + margin-top: 14px; + color: var(--muted); +} + +.source-summary-metrics > span { + display: inline-flex; + align-items: baseline; + gap: 4px; +} + +.source-summary-metrics strong { + color: var(--ink); + font-size: 18px; +} + +.source-summary-foot { + display: block; + margin-top: 13px; + padding-top: 11px; + color: var(--muted); + border-top: 1px solid var(--line-soft); +} + +.source-summary-arrow { + align-self: center; + width: 17px; + height: 17px; + color: #9aa59f; +} + +.data-usage-note { + display: grid; + grid-template-columns: 38px minmax(0, 1fr) auto; + align-items: center; + gap: 12px; + margin-bottom: 14px; + padding: 14px 16px; + color: #755312; + background: #fff9eb; + border: 1px solid #f0dfb9; + border-radius: 13px; +} + +.data-usage-icon { + display: grid; + width: 38px; + height: 38px; + place-items: center; + background: white; + border-radius: 10px; +} + +.data-usage-icon svg { + width: 19px; + height: 19px; +} + +.data-usage-note strong, +.data-usage-note small { + display: block; +} + +.data-usage-note strong { + margin-bottom: 4px; +} + +.data-usage-note small { + color: #8a7448; +} + +.data-usage-note button { + padding: 8px 10px; + color: #805b16; + background: white; + border: 1px solid #ead8ad; + border-radius: 8px; + font-weight: 600; +} + +.source-filter-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 14px; + margin-top: 18px; + padding: 10px; + background: #f6f8f6; + border-radius: 11px; +} + +.source-filters { + display: flex; + gap: 6px; +} + +.source-filters button { + padding: 8px 11px; + color: var(--muted); + background: transparent; + border-radius: 8px; +} + +.source-filters button strong { + margin-left: 4px; +} + +.source-filters button.active { + color: white; + background: var(--green); + font-weight: 600; +} + +.source-filter-result { + color: var(--muted); +} + +.source-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; + margin-top: 17px; +} + +.source-card { + position: relative; + padding: 14px; + overflow: hidden; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.source-card::before { + position: absolute; + inset: 0 auto 0 0; + width: 3px; + background: var(--green); + content: ""; +} + +.source-card.vendor::before { + background: var(--blue); +} + +.source-card.enterprise::before { + background: var(--amber); +} + +.source-card-tags { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-bottom: 12px; + padding-left: 3px; +} + +.source-category-badge, +.source-commercial-badge { + display: inline-flex; + padding: 5px 7px; + border-radius: 6px; + font-weight: 700; +} + +.source-category-badge.vendor { + color: #426f99; + background: var(--blue-soft); +} + +.source-category-badge.school { + color: var(--green); + background: var(--green-soft); +} + +.source-category-badge.enterprise { + color: #996617; + background: var(--amber-soft); +} + +.source-commercial-badge { + color: #65736c; + background: #edf1ee; +} + +.source-commercial-badge.paid { + color: #426f99; + background: #e7f0f8; +} + +.source-commercial-badge.authorized { + color: #956313; + background: #fff1d5; +} + +.source-card-head { + display: grid; + grid-template-columns: 36px 1fr auto; + align-items: center; + gap: 9px; +} + +.source-icon { + display: grid; + width: 36px; + height: 36px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 10px; +} + +.source-icon.vendor { + color: var(--blue); + background: var(--blue-soft); +} + +.source-icon.enterprise { + color: #996a1c; + background: var(--amber-soft); +} + +.source-icon svg { + width: 17px; + height: 17px; +} + +.source-name strong, +.source-name small { + display: block; +} + +.source-name strong { + margin-bottom: 4px; + font-size: 9px; +} + +.source-name small { + color: var(--muted); + font-size: 7px; +} + +.source-status { + display: inline-flex; + align-items: center; + gap: 5px; + color: var(--green); + font-size: 7px; +} + +.source-status::before { + width: 5px; + height: 5px; + background: #54a675; + border-radius: 50%; + content: ""; +} + +.source-status.warning { + color: #a06d18; +} + +.source-status.warning::before { + background: var(--amber); +} + +.source-license-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; + margin-top: 14px; + padding: 12px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.source-license-grid span { + color: #8b9690; +} + +.source-license-grid strong { + display: block; + margin-top: 4px; + color: var(--ink-soft); + font-weight: 600; +} + +.source-card-meta { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin-top: 13px; + padding-top: 11px; + border-top: 1px solid var(--line-soft); +} + +.source-card-meta span { + color: #929d97; + font-size: 7px; +} + +.source-card-meta strong { + display: block; + margin-top: 4px; + color: var(--ink-soft); + font-size: 8px; + font-weight: 600; +} + +.source-card-foot { + display: flex; + align-items: center; + justify-content: space-between; + margin-top: 11px; +} + +.source-card-foot span { + color: #929d97; + font-size: 7px; +} + +.source-card-foot button { + padding: 5px 8px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 7px; +} + +/* 可读性调整:正文、辅助说明、表格与控件不再使用超小字号 */ +.sidebar .school-card span, +.sidebar .sync-line, +.sidebar .meeting-pack small { + font-size: 11px; +} + +.sidebar .school-card strong, +.sidebar .meeting-pack strong, +.sidebar .nav-count { + font-size: 12px; +} + +.sidebar .nav-item span:nth-child(2) { + font-size: 14px; +} + +.topbar .breadcrumb, +.topbar .role-copy small, +.topbar .edition-badge { + font-size: 12px; +} + +.topbar .topbar-date, +.topbar .role-copy strong { + font-size: 14px; +} + +.main-content p, +.modal p { + font-size: 14px !important; + line-height: 1.7; +} + +.main-content small, +.modal small { + font-size: 12px !important; + line-height: 1.5; +} + +.main-content button, +.main-content input, +.main-content select, +.main-content textarea, +.modal button, +.modal input, +.modal select, +.modal textarea { + font-size: 13px !important; +} + +.main-content .eyebrow, +.main-content .panel-kicker, +.modal .modal-kicker { + font-size: 11px !important; +} + +.main-content .panel h2 { + font-size: 17px; +} + +.main-content .quality-main strong, +.main-content .insight-item strong, +.main-content .profession-cell strong, +.main-content .industry-copy strong, +.main-content .skill-name strong, +.main-content .recommendation-copy strong, +.main-content .job-demand-copy strong, +.main-content .company-short-copy strong, +.main-content .project-copy strong, +.main-content .demand-company strong, +.main-content .demand-item > strong, +.main-content .partner-card-head strong, +.main-content .partner-card-foot strong, +.main-content .task-title strong, +.main-content .source-name strong, +.main-content .source-license-grid strong, +.main-content .source-card-meta strong, +.main-content .health-meta strong, +.main-content .quality-dimensions strong, +.main-content .lineage-flow strong, +.main-content .issue-list strong { + font-size: 13px !important; +} + +.main-content .quality-main span, +.main-content .metric-label, +.main-content .metric-foot, +.main-content .metric-tag, +.main-content .chart-legend, +.main-content .chart-labels, +.main-content .match-summary span, +.main-content .ai-state, +.main-content .ai-source, +.main-content .industry-growth, +.main-content .profile-score span, +.main-content .profile-metric span, +.main-content .skill-gap strong, +.main-content .time-caption, +.main-content .collab-stats span, +.main-content .collab-stats em, +.main-content .gap-badge, +.main-content .status-badge, +.main-content .owner-cell, +.main-content .task-progress-cell span, +.main-content .health-score span, +.main-content .quality-dimensions span, +.main-content .source-summary-foot, +.main-content .source-summary-metrics, +.main-content .source-filter-result, +.main-content .source-category-badge, +.main-content .source-commercial-badge, +.main-content .source-status, +.main-content .source-license-grid span, +.main-content .source-card-meta span, +.main-content .source-card-foot span, +.main-content .issue-list strong { + font-size: 12px !important; +} + +.main-content .data-table th { + font-size: 12px; +} + +.main-content .data-table td { + font-size: 13px; +} + +.main-content .score-dial span, +.main-content .insight-index, +.main-content .profession-icon, +.main-content .industry-rank { + font-size: 12px !important; +} + +.main-content .score-cell strong { + font-size: 13px !important; +} + +.main-content .industry-note { + font-size: 12px; +} + +.main-content .industry-note strong { + font-size: 13px; +} + +.main-content .priority-mark, +.main-content .job-demand-copy em, +.main-content .company-logo, +.main-content .match-chip, +.main-content .panel-count, +.main-content .commercial-pill, +.main-content .version-badge, +.main-content .issue-level, +.main-content .lineage-flow > div span { + font-size: 12px !important; +} + +.main-content .partner-avatar, +.main-content .owner-avatar, +.main-content .project-progress span, +.main-content .project-progress span strong, +.main-content .demand-action span, +.main-content .partner-tags span { + font-size: 11px !important; +} + +.main-content .action-stat span, +.main-content .action-health span, +.main-content .action-health strong { + font-size: 12px !important; +} + +.modal h2 { + font-size: 24px; +} + +.modal label > span, +.modal .report-options strong, +.modal .snapshot-card strong { + font-size: 13px !important; +} + +.version-badge { + padding: 5px 8px; + color: #5e7067; + background: #eef2ef; + border-radius: 7px; + font-size: 8px; +} + +.data-bottom-grid { + display: grid; + grid-template-columns: minmax(0, 1.3fr) minmax(320px, 0.7fr); + gap: 14px; +} + +.lineage-flow { + display: flex; + align-items: stretch; + justify-content: space-between; + gap: 8px; + margin-top: 20px; +} + +.lineage-flow > div { + min-width: 105px; + flex: 1; + padding: 13px; + background: #f7f9f7; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.lineage-flow > div.active { + background: var(--green-soft); + border-color: #cce2d6; +} + +.lineage-flow > div span, +.lineage-flow > div strong, +.lineage-flow > div small { + display: block; +} + +.lineage-flow > div span { + color: var(--green-2); + font-size: 7px; + font-weight: 700; +} + +.lineage-flow > div strong { + margin: 7px 0 5px; + font-size: 9px; +} + +.lineage-flow > div small { + color: var(--muted); + font-size: 7px; +} + +.lineage-flow > i { + display: grid; + width: 17px; + flex: 0 0 auto; + place-items: center; + color: #a5afa9; +} + +.lineage-flow > i svg { + width: 13px; + height: 13px; +} + +.issue-list { + margin-top: 12px; +} + +.issue-list button { + display: grid; + width: 100%; + grid-template-columns: 26px 1fr 14px; + align-items: center; + gap: 9px; + padding: 11px 0; + background: transparent; + border-bottom: 1px solid var(--line-soft); + text-align: left; +} + +.issue-list button:last-child { + border-bottom: 0; +} + +.issue-level { + display: grid; + width: 24px; + height: 24px; + place-items: center; + border-radius: 7px; + font-size: 7px; + font-weight: 700; +} + +.issue-level.high { + color: var(--red); + background: var(--red-soft); +} + +.issue-level.mid { + color: #a16c13; + background: var(--amber-soft); +} + +.issue-level.low { + color: var(--blue); + background: var(--blue-soft); +} + +.issue-list strong, +.issue-list small { + display: block; +} + +.issue-list strong { + margin-bottom: 4px; + font-size: 8px; +} + +.issue-list small { + color: var(--muted); + font-size: 7px; +} + +.issue-list svg { + width: 13px; + height: 13px; + color: #9ba59f; +} + +/* 报告中心 */ +.report-stat-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 14px; + margin-bottom: 14px; +} + +.report-stat-grid article { + position: relative; + min-width: 0; + padding: 20px; + overflow: hidden; + background: white; + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.report-stat-grid article::after { + position: absolute; + right: -23px; + bottom: -38px; + width: 95px; + height: 95px; + background: var(--green); + border-radius: 50%; + content: ""; + opacity: 0.04; +} + +.report-stat-grid span, +.report-stat-grid em { + display: block; +} + +.report-stat-grid span { + margin-bottom: 8px; + color: var(--muted); +} + +.report-stat-grid strong { + font-size: 30px; + letter-spacing: -0.05em; +} + +.report-stat-grid small { + margin-left: 5px; + color: var(--muted); +} + +.report-stat-grid em { + margin-top: 8px; + color: var(--green-2); + font-style: normal; +} + +.report-stat-grid .report-version-value { + font-size: 23px; + letter-spacing: -0.03em; +} + +.featured-report-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 14px; + margin-bottom: 14px; +} + +.featured-report-card { + position: relative; + display: grid; + min-width: 0; + min-height: 230px; + grid-template-columns: minmax(0, 1fr) 152px; + gap: 24px; + padding: 24px; + overflow: hidden; + color: #e8f2ed; + background: + radial-gradient(circle at 85% 18%, rgba(198, 230, 111, 0.14), transparent 28%), + linear-gradient(145deg, #173f33, #102e26); + border: 1px solid rgba(255, 255, 255, 0.06); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.featured-report-card.secondary { + color: var(--ink); + background: + radial-gradient(circle at 90% 15%, rgba(73, 120, 168, 0.1), transparent 28%), + white; + border-color: var(--line-soft); +} + +.featured-report-copy { + display: flex; + min-width: 0; + flex-direction: column; + align-items: flex-start; +} + +.featured-report-copy > span:first-child { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 15px; +} + +.report-featured-label, +.report-type-badge { + display: inline-flex; + padding: 5px 8px; + color: #17392e; + background: var(--lime); + border-radius: 7px; + font-size: 11px; + font-weight: 700; +} + +.secondary .report-featured-label { + color: var(--green); + background: var(--green-soft); +} + +.featured-report-copy h2 { + margin: 0; + color: white; + font-size: 22px; + line-height: 1.35; + letter-spacing: -0.03em; +} + +.secondary .featured-report-copy h2 { + color: var(--ink); +} + +.featured-report-copy p { + margin: 10px 0 17px !important; + color: #a9c0b6; +} + +.secondary .featured-report-copy p { + color: var(--muted); +} + +.featured-report-meta { + display: flex; + flex-wrap: wrap; + gap: 12px; + margin-top: auto; + color: #89a69a; + font-size: 12px; +} + +.secondary .featured-report-meta { + color: var(--muted); +} + +.featured-report-actions { + display: flex; + gap: 8px; + margin-top: 16px; +} + +.featured-report-actions button { + padding: 8px 12px; + color: #17392e; + background: var(--lime); + border-radius: 8px; + font-weight: 700; +} + +.featured-report-actions button + button { + color: #d7e7df; + background: rgba(255, 255, 255, 0.08); + border: 1px solid rgba(255, 255, 255, 0.12); +} + +.secondary .featured-report-actions button { + color: white; + background: var(--green); +} + +.secondary .featured-report-actions button + button { + color: var(--green); + background: var(--green-soft); + border-color: #d2e6dc; +} + +.featured-report-cover { + position: relative; + align-self: center; + height: 180px; + padding: 20px 16px; + color: var(--ink); + background: #f7f7f0; + border: 1px solid rgba(255, 255, 255, 0.28); + border-radius: 4px 13px 13px 4px; + box-shadow: 0 18px 35px rgba(5, 22, 16, 0.2); + transform: rotate(2deg); +} + +.secondary .featured-report-cover { + background: #f3f7fa; + border-color: #dbe6ee; + box-shadow: 0 16px 32px rgba(31, 57, 76, 0.13); +} + +.featured-report-cover::before { + position: absolute; + inset: 0 auto 0 0; + width: 7px; + background: var(--green); + border-radius: 4px 0 0 4px; + content: ""; +} + +.featured-report-cover small, +.featured-report-cover strong, +.featured-report-cover span { + display: block; +} + +.featured-report-cover small { + color: var(--green); + font-size: 11px; + font-weight: 800; + letter-spacing: 0.12em; +} + +.featured-report-cover strong { + display: -webkit-box; + max-height: 50px; + margin-top: 14px; + overflow: hidden; + font-family: "Songti SC", "STSong", serif; + font-size: 16px; + line-height: 1.55; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; +} + +.featured-report-mini { + position: absolute; + right: 16px; + bottom: 51px; + left: 16px; + display: flex; + height: 34px; + align-items: flex-end; + gap: 6px; + padding: 4px 7px 0; + overflow: hidden; + background: + repeating-linear-gradient(to top, transparent 0 10px, rgba(39, 54, 47, 0.075) 10px 11px), + linear-gradient(90deg, #edf4ef, transparent); + border-radius: 5px; +} + +.featured-report-mini i { + position: relative; + z-index: 1; + width: 11px; + min-height: 7px; + background: var(--green); + border-radius: 3px 3px 0 0; +} + +.featured-report-mini i:nth-child(2) { + background: #4d7fa8; +} + +.featured-report-mini i:nth-child(3) { + background: #d39a35; +} + +.featured-report-mini i:nth-child(4) { + background: #7f6aaa; +} + +.featured-report-mini i:nth-child(5) { + background: #72b893; +} + +.featured-report-mini b { + position: absolute; + right: 6px; + bottom: 4px; + width: 55%; + height: 22px; + border-top: 2px solid var(--green); + border-radius: 60% 15% 0 0; + transform: rotate(-8deg); +} + +.featured-report-cover span { + position: absolute; + right: 16px; + bottom: 18px; + left: 16px; + color: var(--muted); + border-top: 1px solid #d9ded8; + padding-top: 9px; + font-size: 11px; +} + +.report-library-panel { + padding: 0; + overflow: hidden; +} + +.report-library-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 18px; + padding: 22px 22px 15px; +} + +.report-library-head h2 { + margin: 0; +} + +.report-library-tools { + display: flex; + align-items: center; + gap: 9px; +} + +.report-library-tools select { + height: 40px; + padding: 0 32px 0 12px; + color: var(--ink-soft); + background: white; + border: 1px solid var(--line); + border-radius: 9px; + outline: 0; +} + +.report-type-filters { + display: flex; + gap: 6px; + padding: 0 22px 15px; + overflow-x: auto; + border-bottom: 1px solid var(--line-soft); +} + +.report-type-filters button { + flex: 0 0 auto; + padding: 8px 12px; + color: var(--muted); + background: #f3f6f3; + border-radius: 8px; +} + +.report-type-filters button.active { + color: white; + background: var(--green); + font-weight: 700; +} + +.report-list-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 0 20px; + padding: 8px 22px; +} + +.report-list-item { + display: grid; + min-width: 0; + grid-template-columns: 44px minmax(0, 1fr) auto; + align-items: center; + gap: 12px; + padding: 16px 0; + background: transparent; + border-bottom: 1px solid var(--line-soft); + text-align: left; +} + +.report-list-icon { + display: grid; + width: 44px; + height: 52px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border: 1px solid #d9e9e0; + border-radius: 5px 10px 10px 5px; +} + +.report-list-icon.school { + color: var(--green); + background: var(--green-soft); +} + +.report-list-icon.college { + color: var(--blue); + background: var(--blue-soft); +} + +.report-list-icon.profession { + color: #8a6d21; + background: var(--amber-soft); +} + +.report-list-icon.industry { + color: #786098; + background: #f2edfa; +} + +.report-list-icon.quality { + color: #5d7067; + background: #eef2ef; +} + +.report-list-icon svg { + width: 21px; + height: 21px; +} + +.report-list-copy { + min-width: 0; +} + +.report-list-copy strong, +.report-list-copy small, +.report-list-copy span { + display: block; +} + +.report-list-copy strong { + overflow: hidden; + margin-bottom: 5px; + color: var(--ink); + font-size: 14px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-list-copy small { + color: var(--muted); +} + +.report-list-meta { + display: flex !important; + gap: 10px; + margin-top: 7px; + color: #859189; + font-size: 11px; +} + +.report-list-side { + text-align: right; +} + +.report-list-side em { + display: block; + padding: 5px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 11px; + font-style: normal; + font-weight: 700; +} + +.report-list-side em.review { + color: #9a6818; + background: var(--amber-soft); +} + +.report-list-side svg { + width: 15px; + height: 15px; + margin-top: 9px; + color: #9aa59f; +} + +.report-library-foot { + display: flex; + align-items: center; + justify-content: space-between; + padding: 13px 22px; + color: var(--muted); + background: #f7f9f7; + border-top: 1px solid var(--line-soft); +} + +.report-library-foot button { + padding: 7px 10px; + color: var(--green); + background: white; + border: 1px solid #d6e4dc; + border-radius: 8px; + font-weight: 600; +} + +.report-empty-state { + grid-column: 1 / -1; + display: grid; + min-height: 190px; + place-items: center; + align-content: center; + gap: 9px; + color: var(--muted); + text-align: center; +} + +.report-empty-state svg { + width: 30px; + height: 30px; + color: var(--green); +} + +.report-empty-state strong, +.report-empty-state small { + display: block; +} + +/* 报告正文阅读器 */ +.report-reader { + position: fixed; + z-index: 110; + inset: 0; + display: flex; + flex-direction: column; + background: #eef1ed; + opacity: 0; + pointer-events: none; + transform: translateY(10px); + transition: + opacity 0.22s ease, + transform 0.22s ease; +} + +.report-reader.open { + opacity: 1; + pointer-events: auto; + transform: translateY(0); +} + +.report-reader-header { + position: relative; + z-index: 2; + display: flex; + min-height: 72px; + align-items: center; + justify-content: space-between; + gap: 20px; + padding: 10px 22px; + background: white; + border-bottom: 1px solid var(--line); + box-shadow: 0 4px 18px rgba(22, 48, 37, 0.06); +} + +.report-reader-identity { + display: flex; + min-width: 0; + align-items: center; + gap: 10px; +} + +.report-reader-close { + flex: 0 0 auto; + background: #f0f4f1; +} + +.report-reader-identity small, +.report-reader-identity strong { + display: block; +} + +.report-reader-identity small { + margin-bottom: 4px; + color: var(--muted); + font-size: 12px; +} + +.report-reader-identity strong { + overflow: hidden; + max-width: 560px; + font-size: 15px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-reader-actions { + display: flex; + align-items: center; + gap: 9px; +} + +.reader-version { + padding: 7px 9px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 12px; + font-weight: 700; +} + +.report-reader-layout { + display: grid; + min-height: 0; + flex: 1; + grid-template-columns: 250px minmax(0, 1fr); +} + +.report-toc { + min-height: 0; + padding: 24px 18px; + overflow-y: auto; + background: #f8faf8; + border-right: 1px solid var(--line); +} + +.report-toc-label { + display: block; + margin: 0 10px 12px; + color: #89958e; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.1em; +} + +.report-toc nav { + display: flex; + flex-direction: column; + gap: 3px; +} + +.report-toc button { + display: flex; + width: 100%; + align-items: center; + gap: 10px; + padding: 10px; + color: var(--muted); + background: transparent; + border-radius: 8px; + font-size: 13px; + text-align: left; +} + +.report-toc button span { + color: #a3aca7; + font-variant-numeric: tabular-nums; +} + +.report-toc button.active, +.report-toc button:hover { + color: var(--green); + background: var(--green-soft); + font-weight: 700; +} + +.report-reader-meta { + margin-top: 24px; + padding: 12px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.report-reader-meta span, +.report-reader-meta strong { + display: block; +} + +.report-reader-meta span { + padding: 7px 0; + color: var(--muted); + border-bottom: 1px solid var(--line-soft); + font-size: 11px; +} + +.report-reader-meta span:last-child { + border-bottom: 0; +} + +.report-reader-meta strong { + margin-top: 4px; + color: var(--ink); + font-size: 12px; +} + +.report-document-wrap { + min-width: 0; + overflow: auto; + scroll-behavior: smooth; +} + +.report-document { + width: min(1040px, calc(100% - 48px)); + min-height: calc(100vh - 118px); + margin: 24px auto 48px; + color: #27362f; + background: white; + box-shadow: 0 18px 60px rgba(30, 52, 43, 0.12); +} + +.report-cover-page { + position: relative; + display: flex; + min-height: 570px; + flex-direction: column; + justify-content: space-between; + padding: 68px 70px 56px; + color: white; + background: + linear-gradient(140deg, rgba(198, 230, 111, 0.08), transparent 45%), + linear-gradient(155deg, #184638, #0f2c24); + overflow: hidden; +} + +.report-cover-page::after { + position: absolute; + right: -90px; + bottom: -120px; + width: 390px; + height: 390px; + border: 1px solid rgba(198, 230, 111, 0.13); + border-radius: 50%; + box-shadow: + 0 0 0 45px rgba(198, 230, 111, 0.025), + 0 0 0 90px rgba(198, 230, 111, 0.018); + content: ""; +} + +.report-cover-brand { + display: flex; + align-items: center; + gap: 12px; + color: var(--lime); + font-weight: 700; + letter-spacing: 0.1em; +} + +.report-cover-brand i { + width: 34px; + height: 4px; + background: var(--lime); +} + +.report-cover-main { + position: relative; + z-index: 1; +} + +.report-cover-main span { + display: block; + margin-bottom: 18px; + color: #9bb4a9; + font-size: 14px; + letter-spacing: 0.08em; +} + +.report-cover-main h1 { + max-width: 640px; + margin: 0; + font-family: "Songti SC", "STSong", serif; + font-size: 42px; + line-height: 1.35; + letter-spacing: 0.02em; +} + +.report-cover-main p { + max-width: 590px; + margin: 24px 0 0; + color: #aac0b7; + font-size: 16px; + line-height: 1.8; +} + +.report-standard-stamp { + display: inline-flex; + margin-top: 18px; + padding: 7px 10px; + color: #dce8b9; + background: rgba(198, 230, 111, 0.08); + border: 1px solid rgba(198, 230, 111, 0.25); + border-radius: 7px; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.04em; +} + +.report-cover-foot { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + padding-top: 24px; + border-top: 1px solid rgba(255, 255, 255, 0.13); +} + +.report-cover-foot span, +.report-cover-foot strong { + display: block; +} + +.report-cover-foot span { + color: #829f93; + font-size: 12px; +} + +.report-cover-foot strong { + margin-top: 6px; + color: #e8f1ed; + font-size: 14px; +} + +.report-section { + padding: 52px 64px; + border-bottom: 1px solid #e5eae6; + scroll-margin-top: 20px; +} + +.report-section:last-child { + border-bottom: 0; +} + +.report-section-heading { + display: flex; + align-items: flex-start; + gap: 16px; + margin-bottom: 24px; +} + +.report-section-heading > span { + display: grid; + width: 36px; + height: 36px; + flex: 0 0 auto; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 10px; + font-size: 13px; + font-weight: 800; +} + +.report-section-heading small, +.report-section-heading h2 { + display: block; +} + +.report-section-heading small { + margin-bottom: 5px; + color: var(--green-2); + font-size: 11px; + font-weight: 700; + letter-spacing: 0.1em; +} + +.report-section-heading h2 { + margin: 0; + font-size: 24px; + letter-spacing: -0.03em; +} + +.report-summary-callout { + padding: 20px; + color: #244036; + background: #eff7f2; + border-left: 4px solid var(--green); + border-radius: 0 12px 12px 0; + font-size: 15px; + line-height: 1.8; +} + +.report-metric-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-top: 20px; +} + +.report-metric-grid div { + padding: 16px; + background: #f8faf8; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.report-metric-grid span, +.report-metric-grid strong, +.report-metric-grid small { + display: block; +} + +.report-metric-grid span { + color: var(--muted); + font-size: 11px; +} + +.report-metric-grid strong { + margin: 8px 0 5px; + color: var(--ink); + font-size: 24px; +} + +.report-metric-grid small { + color: var(--green-2); + font-size: 11px; +} + +.report-finding-list { + display: flex; + flex-direction: column; + gap: 10px; +} + +.report-finding { + display: grid; + grid-template-columns: 34px minmax(0, 1fr) auto; + align-items: center; + gap: 12px; + padding: 15px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.report-finding > span:first-child { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 9px; + font-weight: 800; +} + +.report-finding strong, +.report-finding small { + display: block; +} + +.report-finding strong { + margin-bottom: 5px; + font-size: 14px; +} + +.report-finding small { + color: var(--muted); + font-size: 12px; + line-height: 1.5; +} + +.report-finding em { + color: var(--green); + font-style: normal; + font-weight: 800; +} + +.report-bar-list { + display: flex; + flex-direction: column; + gap: 17px; +} + +.report-bar-row { + display: grid; + grid-template-columns: 130px minmax(0, 1fr) 48px; + align-items: center; + gap: 13px; +} + +.report-bar-row > span:first-child { + font-size: 13px; + font-weight: 600; +} + +.report-bar-track { + height: 10px; + overflow: hidden; + background: #edf1ed; + border-radius: 6px; +} + +.report-bar-track i { + display: block; + height: 100%; + background: linear-gradient(90deg, var(--green), #6bb18a); + border-radius: 6px; +} + +.report-bar-row strong { + text-align: right; +} + +.report-table { + width: 100%; + border-collapse: collapse; +} + +.report-table th { + padding: 11px 10px; + color: var(--muted); + background: #f4f7f4; + border-bottom: 1px solid var(--line); + font-size: 12px; + text-align: left; +} + +.report-table td { + padding: 13px 10px; + border-bottom: 1px solid var(--line-soft); + font-size: 13px; + line-height: 1.5; +} + +.report-source-tag { + display: inline-flex; + padding: 4px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 11px; + font-weight: 700; +} + +.report-action-list { + display: flex; + flex-direction: column; + gap: 11px; +} + +.report-action-card { + display: grid; + grid-template-columns: 36px minmax(0, 1fr) auto; + align-items: start; + gap: 13px; + padding: 16px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 12px; +} + +.report-action-priority { + display: grid; + width: 36px; + height: 36px; + place-items: center; + color: #a14238; + background: var(--red-soft); + border-radius: 9px; + font-size: 11px; + font-weight: 800; +} + +.report-action-card strong, +.report-action-card small { + display: block; +} + +.report-action-card strong { + margin-bottom: 6px; + font-size: 14px; +} + +.report-action-card small { + color: var(--muted); + font-size: 12px; + line-height: 1.65; +} + +.report-action-card button { + padding: 7px 9px; + color: var(--green); + background: var(--green-soft); + border-radius: 7px; + font-size: 11px; + font-weight: 700; +} + +.report-method-note { + margin-top: 18px; + padding: 15px; + color: #627169; + background: #f7f8f5; + border: 1px dashed #ced8d1; + border-radius: 10px; + font-size: 12px; + line-height: 1.7; +} + +.report-benchmark-strip { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + margin-top: 12px; + overflow: hidden; + background: #153d31; + border-radius: 12px; +} + +.report-benchmark-strip > span { + position: relative; + min-width: 0; + padding: 15px 16px; + border-right: 1px solid rgba(255, 255, 255, 0.1); +} + +.report-benchmark-strip > span:last-child { + border-right: 0; +} + +.report-benchmark-strip small, +.report-benchmark-strip strong, +.report-benchmark-strip em { + display: block; +} + +.report-benchmark-strip small { + overflow: hidden; + color: #a9beb5; + font-size: 11px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-benchmark-strip strong { + margin: 7px 0 4px; + color: white; + font-size: 22px; +} + +.report-benchmark-strip em { + color: var(--lime); + font-size: 11px; + font-style: normal; +} + +.report-chart-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 14px; + margin-top: 22px; +} + +.report-chart-card { + min-width: 0; + margin: 0; + overflow: hidden; + background: white; + border: 1px solid #dfe7e1; + border-radius: 14px; + box-shadow: 0 7px 24px rgba(30, 60, 47, 0.06); +} + +.report-chart-card.wide { + grid-column: 1 / -1; +} + +.report-chart-head { + display: flex; + align-items: center; + gap: 9px; + padding: 14px 15px 11px; + border-bottom: 1px solid #edf1ee; +} + +.report-chart-head > span { + flex: 0 0 auto; + padding: 4px 6px; + color: var(--green); + background: var(--green-soft); + border-radius: 5px; + font-size: 11px; + font-weight: 800; + letter-spacing: 0.06em; +} + +.report-chart-head strong { + overflow: hidden; + font-size: 13px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-chart-stage { + position: relative; + min-height: 310px; + overflow: hidden; + background: + radial-gradient(circle at 50% 18%, rgba(23, 107, 79, 0.035), transparent 45%), + #fff; +} + +.report-echart { + width: 100%; + height: 310px; +} + +.report-chart-fallback { + position: absolute; + inset: 0; + display: grid; + place-items: center; + padding: 6px; + background: white; +} + +.report-chart-fallback svg { + display: block; + width: 100%; + height: 100%; +} + +.report-chart-stage.is-interactive .report-chart-fallback { + display: none; +} + +.report-chart-card figcaption { + min-height: 83px; + padding: 12px 15px 14px; + color: #65736c; + background: #f8faf8; + border-top: 1px solid #edf1ee; + font-size: 11px; + line-height: 1.65; +} + +.report-evidence-code { + display: inline-flex; + margin-right: 5px; + padding: 3px 6px; + color: var(--green); + background: #e8f4ee; + border-radius: 5px; + font-size: 11px; + font-weight: 800; + white-space: nowrap; +} + +.report-interpretation { + display: grid; + grid-template-columns: 84px minmax(0, 1fr); + gap: 15px; + margin-top: 16px; + padding: 17px 18px; + color: #29473c; + background: linear-gradient(100deg, #edf7f1, #f8fbf7); + border: 1px solid #dbeadf; + border-radius: 12px; +} + +.report-interpretation > span { + align-self: start; + padding: 5px 8px; + color: white; + background: var(--green); + border-radius: 6px; + font-size: 11px; + font-weight: 800; + text-align: center; +} + +.report-interpretation p { + margin: 0; + font-size: 13px; + line-height: 1.85; +} + +.report-interpretation strong { + color: var(--green); +} + +.report-profile-banner { + display: grid; + grid-template-columns: minmax(0, 1.2fr) minmax(260px, 0.8fr); + gap: 20px; + padding: 22px; + color: #e7f0ec; + background: + radial-gradient(circle at 90% 0, rgba(198, 230, 111, 0.14), transparent 35%), + linear-gradient(135deg, #173f33, #102e26); + border-radius: 15px; +} + +.report-profile-kicker { + color: var(--lime); + font-size: 11px; + font-weight: 800; + letter-spacing: 0.1em; +} + +.report-profile-banner h3 { + margin: 9px 0 8px; + color: white; + font-size: 19px; +} + +.report-profile-banner p { + margin: 0; + color: #a9bdb5; + font-size: 12px; + line-height: 1.75; +} + +.report-profile-attributes { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; +} + +.report-profile-attributes span { + min-width: 0; + padding: 10px; + color: #8da79c; + background: rgba(255, 255, 255, 0.055); + border: 1px solid rgba(255, 255, 255, 0.07); + border-radius: 9px; + font-size: 11px; +} + +.report-profile-attributes strong { + display: block; + overflow: hidden; + margin-top: 5px; + color: #eaf2ee; + font-size: 11px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-profile-stat-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + align-items: start; + gap: 10px; + margin-top: 13px; +} + +.report-profile-stat-grid article { + min-width: 0; + padding: 14px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.report-profile-code, +.report-profile-label, +.report-profile-stat-grid article > strong, +.report-profile-stat-grid article > em { + display: block; +} + +.report-profile-code { + overflow: hidden; + color: #84928a; + font-size: 11px; + font-weight: 700; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-profile-label { + margin-top: 9px; + color: var(--muted); + font-size: 11px; +} + +.report-profile-stat-grid article > strong { + margin: 5px 0 4px; + color: var(--ink); + font-size: 23px; + letter-spacing: -0.04em; +} + +.report-profile-stat-grid article > strong small { + margin-left: 3px; + color: var(--muted); + font-size: 11px; + font-weight: 500; +} + +.report-profile-stat-grid article > em { + min-height: 32px; + color: var(--green-2); + font-size: 11px; + font-style: normal; + line-height: 1.5; +} + +.report-profile-stat-grid details { + margin-top: 9px; + padding-top: 8px; + border-top: 1px solid #e8ede9; +} + +.report-profile-stat-grid summary { + color: var(--green); + font-size: 11px; + font-weight: 700; + cursor: pointer; +} + +.report-profile-stat-grid details > div { + margin-top: 8px; + padding: 9px; + color: var(--muted); + background: white; + border: 1px solid #e8ede9; + border-radius: 8px; + font-size: 11px; +} + +.report-profile-stat-grid details span, +.report-profile-stat-grid details strong { + display: block; +} + +.report-profile-stat-grid details span + span { + margin-top: 6px; +} + +.report-profile-stat-grid details strong { + margin-top: 2px; + color: var(--ink); + font-weight: 600; +} + +.report-profile-stat-grid details p { + margin: 8px 0 0; + padding-top: 8px; + border-top: 1px dashed #dce5de; + line-height: 1.6; +} + +.report-finding-proof, +.report-action-evidence { + margin-top: 7px; + color: var(--green-2) !important; + font-size: 11px !important; + font-weight: 600; +} + +.report-finding-validation { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + margin-top: 15px; + padding: 13px; + color: var(--muted); + background: #f5f8f5; + border: 1px dashed #d4ded7; + border-radius: 10px; + font-size: 11px; +} + +.report-finding-validation strong { + margin-right: 4px; + color: var(--ink); +} + +.report-finding-validation span { + padding: 5px 7px; + color: var(--green); + background: white; + border: 1px solid #dbe6df; + border-radius: 6px; + font-weight: 700; +} + +.report-finding-validation i { + color: #9aa69f; + font-style: normal; +} + +.report-subsection-title { + margin: 28px 0 12px; + font-size: 15px; +} + +.report-table-wrap { + max-width: 100%; + overflow-x: auto; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.report-table-wrap .report-table { + border: 0; +} + +.report-comparison-table { + min-width: 760px; +} + +.report-evidence-table { + min-width: 860px; +} + +.report-evidence-table td:first-child strong { + color: var(--green); + font-size: 11px; + white-space: nowrap; +} + +.report-evidence-table td:nth-child(2) small { + display: block; + min-width: 125px; + margin-top: 5px; + color: var(--muted); + font-size: 11px; +} + +.report-positive { + color: var(--green); + font-weight: 700; +} + +.report-negative { + color: #b45249; + font-weight: 700; +} + +.report-confidence { + display: inline-flex; + padding: 4px 7px; + color: var(--green); + background: var(--green-soft); + border-radius: 6px; + font-size: 11px; + font-weight: 700; + white-space: nowrap; +} + +.report-evidence-summary { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 14px; +} + +.report-evidence-summary span { + min-width: 0; + padding: 13px; + background: #f7faf7; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.report-evidence-summary small, +.report-evidence-summary strong { + display: block; +} + +.report-evidence-summary small { + color: var(--muted); + font-size: 11px; +} + +.report-evidence-summary strong { + overflow: hidden; + margin-top: 6px; + color: var(--ink); + font-size: 14px; + text-overflow: ellipsis; + white-space: nowrap; +} + +.report-proof-chain { + display: grid; + grid-template-columns: minmax(0, 1fr) 24px minmax(0, 1fr) 24px minmax(0, 1fr) 24px minmax(0, 1fr); + align-items: center; + gap: 4px; + margin-bottom: 15px; + padding: 14px; + background: #173e32; + border-radius: 12px; +} + +.report-proof-chain > span { + min-width: 0; + text-align: center; +} + +.report-proof-chain i, +.report-proof-chain strong, +.report-proof-chain small { + display: block; +} + +.report-proof-chain i { + width: 27px; + height: 27px; + margin: 0 auto 6px; + padding-top: 5px; + color: #173e32; + background: var(--lime); + border-radius: 8px; + font-size: 11px; + font-style: normal; + font-weight: 800; +} + +.report-proof-chain strong { + color: white; + font-size: 11px; +} + +.report-proof-chain small { + margin-top: 4px; + color: #92aaa0; + font-size: 11px; +} + +.report-proof-chain > b { + height: 1px; + background: #668078; +} + +.report-evidence-notice { + margin-top: 14px; + padding: 15px 17px; + color: #6f5220; + background: #fff9ed; + border: 1px solid #eee0bd; + border-radius: 10px; +} + +.report-evidence-notice strong { + display: block; + margin-bottom: 5px; + font-size: 12px; +} + +.report-evidence-notice p { + margin: 0; + font-size: 11px; + line-height: 1.7; +} + +.report-method-steps { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 16px; +} + +.report-method-steps article { + display: grid; + grid-template-columns: 34px minmax(0, 1fr); + gap: 3px 11px; + padding: 14px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.report-method-steps article > span { + display: grid; + width: 34px; + height: 34px; + grid-row: 1 / 3; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 9px; + font-size: 11px; + font-weight: 800; +} + +.report-method-steps strong { + font-size: 12px; +} + +.report-method-steps p { + margin: 2px 0 0; + color: var(--muted); + font-size: 11px; + line-height: 1.6; +} + +.report-action-cycle { + display: grid; + grid-template-columns: repeat(7, auto); + align-items: center; + justify-content: center; + gap: 10px; + margin-top: 17px; + padding: 15px; + color: #dcebe4; + background: #173e32; + border-radius: 11px; +} + +.report-action-cycle span, +.report-action-cycle strong, +.report-action-cycle small { + display: block; +} + +.report-action-cycle strong { + font-size: 11px; +} + +.report-action-cycle small { + margin-top: 3px; + color: #91aaa0; + font-size: 11px; +} + +.report-action-cycle i { + width: 28px; + height: 1px; + background: var(--lime); +} + +/* 厂商超级管理员 */ +.platform-view { + --platform-blue: #346f9f; + --platform-blue-soft: #eaf2f9; +} + +.platform-view [id] { + scroll-margin-top: 96px; +} + +.platform-alert { + display: grid; + grid-template-columns: 40px minmax(0, 1fr) auto; + align-items: center; + gap: 13px; + margin-bottom: 14px; + padding: 14px 16px; + color: #1b5945; + background: linear-gradient(90deg, #e7f4ed, #f3f8ec); + border: 1px solid #d3e9db; + border-radius: 13px; +} + +.platform-alert-icon { + display: grid; + width: 40px; + height: 40px; + place-items: center; + color: var(--green); + background: white; + border-radius: 11px; +} + +.platform-alert-icon svg { + width: 20px; + height: 20px; +} + +.platform-alert strong, +.platform-alert small { + display: block; +} + +.platform-alert strong { + margin-bottom: 4px; + font-size: 14px; +} + +.platform-alert button { + padding: 8px 11px; + color: var(--green); + background: white; + border: 1px solid #cce2d5; + border-radius: 8px; + font-weight: 600; +} + +.platform-metric-grid { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 14px; + margin-bottom: 14px; +} + +.platform-metric-grid article { + position: relative; + min-width: 0; + padding: 20px; + overflow: hidden; + background: white; + border: 1px solid var(--line-soft); + border-radius: var(--radius); + box-shadow: var(--shadow); +} + +.platform-metric-grid article::after { + position: absolute; + right: -25px; + bottom: -35px; + width: 95px; + height: 95px; + background: var(--platform-blue); + border-radius: 50%; + content: ""; + opacity: 0.04; +} + +.platform-metric-grid span, +.platform-metric-grid em { + display: block; +} + +.platform-metric-grid span { + margin-bottom: 9px; + color: var(--muted); +} + +.platform-metric-grid strong { + font-size: 30px; + letter-spacing: -0.05em; +} + +.platform-metric-grid small { + margin-left: 5px; + color: var(--muted); +} + +.platform-metric-grid em { + margin-top: 9px; + color: var(--green-2); + font-style: normal; +} + +.platform-grid { + display: grid; + grid-template-columns: minmax(0, 1.55fr) minmax(330px, 0.65fr); + gap: 14px; + margin-bottom: 14px; +} + +.platform-table-title strong, +.platform-table-title small { + display: block; +} + +.platform-table-title strong { + margin-bottom: 5px; + color: var(--ink); +} + +.platform-live { + display: inline-flex; + align-items: center; + gap: 6px; + color: var(--green); + font-weight: 600; +} + +.platform-live i { + width: 7px; + height: 7px; + background: #55ac78; + border-radius: 50%; + box-shadow: 0 0 0 4px rgba(85, 172, 120, 0.1); +} + +.platform-service-list { + margin-top: 14px; +} + +.platform-service-list button { + display: flex; + width: 100%; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 13px 0; + background: transparent; + border-bottom: 1px solid var(--line-soft); + text-align: left; +} + +.platform-service-list button:last-child { + border-bottom: 0; +} + +.platform-service-list button > span { + position: relative; + display: block; + padding-left: 17px; +} + +.platform-service-list i { + position: absolute; + top: 5px; + left: 0; + width: 7px; + height: 7px; + border-radius: 50%; +} + +.service-green { + background: #55ac78; +} + +.service-amber { + background: var(--amber); +} + +.platform-service-list strong, +.platform-service-list small { + display: block; +} + +.platform-service-list strong { + margin-bottom: 5px; + font-size: 13px; +} + +.platform-service-list em { + color: var(--green); + font-style: normal; + font-weight: 700; +} + +.platform-tenant-panel { + margin-bottom: 14px; +} + +.tenant-card-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; + margin-top: 17px; +} + +.tenant-card { + display: grid; + min-width: 0; + grid-template-columns: 42px minmax(0, 1fr) auto; + align-items: center; + gap: 11px; + padding: 14px; + background: #fafbf9; + border: 1px solid var(--line-soft); + border-radius: 12px; + text-align: left; + transition: + transform 0.2s ease, + border-color 0.2s ease; +} + +.tenant-card:hover { + border-color: #cbdad1; + transform: translateY(-1px); +} + +.tenant-logo { + display: grid; + width: 42px; + height: 42px; + place-items: center; + color: white; + background: var(--green); + border-radius: 11px; + font-weight: 700; +} + +.tenant-logo.blue { + background: var(--platform-blue); +} + +.tenant-logo.amber { + background: #b9822d; +} + +.tenant-card strong, +.tenant-card small { + display: block; +} + +.tenant-card strong { + margin-bottom: 5px; +} + +.tenant-card em { + font-style: normal; +} + +.platform-bottom-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 14px; +} + +.platform-quick-list, +.audit-list { + margin-top: 13px; +} + +.platform-quick-list button { + display: grid; + width: 100%; + grid-template-columns: 34px minmax(0, 1fr) auto; + align-items: center; + gap: 10px; + padding: 11px 0; + background: transparent; + border-bottom: 1px solid var(--line-soft); + text-align: left; +} + +.platform-quick-list button:last-child, +.audit-list button:last-child { + border-bottom: 0; +} + +.quick-icon { + display: grid; + width: 34px; + height: 34px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 9px; + font-weight: 700; +} + +.quick-icon.blue { + color: var(--platform-blue); + background: var(--platform-blue-soft); +} + +.quick-icon.amber { + color: #956313; + background: var(--amber-soft); +} + +.platform-quick-list strong, +.platform-quick-list small, +.audit-list strong, +.audit-list small { + display: block; +} + +.platform-quick-list strong, +.audit-list strong { + margin-bottom: 4px; +} + +.platform-quick-list em { + color: var(--green); + font-style: normal; + font-weight: 600; +} + +.backup-hero { + display: flex; + align-items: center; + gap: 12px; + margin-top: 16px; + padding: 14px; + color: #e5f1eb; + background: linear-gradient(135deg, #174132, #113027); + border-radius: 12px; +} + +.backup-icon { + display: grid; + width: 40px; + height: 40px; + flex: 0 0 auto; + place-items: center; + color: var(--lime); + background: rgba(198, 230, 111, 0.1); + border-radius: 10px; +} + +.backup-icon svg { + width: 19px; + height: 19px; +} + +.backup-hero strong, +.backup-hero small { + display: block; +} + +.backup-hero strong { + margin-bottom: 5px; +} + +.backup-hero small { + color: #8fa99e; +} + +.backup-meta { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + margin-top: 13px; +} + +.backup-meta span { + padding: 9px; + color: var(--muted); + background: #f6f8f6; + border-radius: 8px; +} + +.backup-meta strong { + display: block; + margin-top: 5px; + color: var(--ink); +} + +.backup-actions { + display: flex; + gap: 8px; + margin-top: 13px; +} + +.backup-actions .button { + min-height: 38px; + flex: 1; +} + +.audit-list button { + display: grid; + width: 100%; + grid-template-columns: 8px 1fr; + align-items: center; + gap: 10px; + padding: 12px 0; + background: transparent; + border-bottom: 1px solid var(--line-soft); + text-align: left; +} + +.audit-dot { + width: 7px; + height: 7px; + background: var(--green-2); + border-radius: 50%; +} + +.audit-dot.blue { + background: var(--platform-blue); +} + +.audit-dot.amber { + background: var(--amber); +} + +.platform-action-content { + margin-top: 20px; +} + +.platform-form-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 13px; +} + +.platform-action-content label { + display: block; +} + +.platform-action-content label.full { + grid-column: 1 / -1; +} + +.platform-action-content label > span, +.platform-action-content fieldset > legend { + display: block; + margin-bottom: 7px; + color: var(--ink-soft); + font-weight: 600; +} + +.platform-action-content input, +.platform-action-content select, +.platform-action-content textarea { + width: 100%; + padding: 11px 12px; + background: #fafbf9; + border: 1px solid var(--line); + border-radius: 9px; + outline: 0; +} + +.platform-action-content fieldset { + grid-column: 1 / -1; + padding: 13px; + background: #f7f9f7; + border: 1px solid var(--line-soft); + border-radius: 10px; +} + +.platform-check-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 9px; +} + +.platform-check-grid label { + display: flex; + align-items: center; + gap: 8px; + padding: 9px; + background: white; + border: 1px solid var(--line-soft); + border-radius: 8px; +} + +.platform-check-grid input { + width: 16px; + height: 16px; + accent-color: var(--green); +} + +.platform-detail-card { + padding: 14px; + background: #f6f9f7; + border: 1px solid var(--line-soft); + border-radius: 11px; +} + +.platform-detail-card + .platform-detail-card { + margin-top: 10px; +} + +.platform-detail-card strong, +.platform-detail-card small { + display: block; +} + +.platform-detail-card strong { + margin-bottom: 5px; +} + +/* 弹窗、提示 */ +.tooltip { + position: fixed; + z-index: 90; + max-width: 230px; + padding: 8px 10px; + color: white; + background: #102d25; + border-radius: 7px; + box-shadow: var(--shadow-high); + font-size: 9px; + line-height: 1.5; + pointer-events: none; + opacity: 0; + transform: translateY(3px); + transition: + opacity 0.15s ease, + transform 0.15s ease; +} + +.tooltip.show { + opacity: 1; + transform: translateY(0); +} + +.toast-region { + position: fixed; + z-index: 100; + right: 24px; + bottom: 24px; + display: flex; + width: min(360px, calc(100vw - 32px)); + flex-direction: column; + gap: 9px; + pointer-events: none; +} + +.toast { + display: grid; + grid-template-columns: 28px 1fr; + align-items: center; + gap: 10px; + padding: 12px 14px; + color: white; + background: #16372d; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 11px; + box-shadow: var(--shadow-high); + animation: toastIn 0.25s ease both; +} + +.toast.out { + animation: toastOut 0.22s ease both; +} + +.toast-icon { + display: grid; + width: 28px; + height: 28px; + place-items: center; + color: #19392e; + background: var(--lime); + border-radius: 8px; +} + +.toast-icon svg { + width: 15px; + height: 15px; +} + +.toast strong, +.toast small { + display: block; +} + +.toast strong { + margin-bottom: 3px; + font-size: 10px; +} + +.toast small { + color: #9bb1a8; + font-size: 8px; +} + +@keyframes toastIn { + from { + opacity: 0; + transform: translateX(18px); + } +} + +@keyframes toastOut { + to { + opacity: 0; + transform: translateX(18px); + } +} + +.modal-backdrop { + position: fixed; + z-index: 80; + inset: 0; + display: grid; + place-items: center; + padding: 20px; + background: rgba(8, 25, 19, 0.56); + backdrop-filter: blur(6px); + opacity: 0; + pointer-events: none; + transition: opacity 0.22s ease; +} + +.modal-backdrop.open { + opacity: 1; + pointer-events: auto; +} + +.modal { + position: relative; + width: min(590px, 100%); + max-height: calc(100vh - 40px); + padding: 28px; + overflow-y: auto; + background: white; + border-radius: 20px; + box-shadow: var(--shadow-high); + transform: translateY(12px) scale(0.985); + transition: transform 0.22s ease; +} + +.modal-backdrop.open .modal { + transform: translateY(0) scale(1); +} + +.modal-close { + position: absolute; + z-index: 2; + top: 17px; + right: 17px; + display: grid; + width: 31px; + height: 31px; + place-items: center; + color: var(--muted); + background: #f1f4f1; + border-radius: 9px; +} + +.modal-close svg { + width: 14px; + height: 14px; +} + +.modal-kicker { + margin-bottom: 6px; + color: var(--green-2); + font-size: 8px; + font-weight: 800; + letter-spacing: 0.15em; +} + +.modal h2 { + margin: 0; + font-size: 21px; + letter-spacing: -0.04em; +} + +.modal > p, +.report-modal-head p { + margin: 8px 0 20px; + color: var(--muted); + font-size: 9px; + line-height: 1.6; +} + +.form-modal form { + margin-top: 20px; +} + +.form-modal label { + display: block; + margin-bottom: 14px; +} + +.form-modal label > span { + display: block; + margin-bottom: 7px; + color: #5e6f67; + font-size: 9px; + font-weight: 600; +} + +.form-modal input, +.form-modal select, +.form-modal textarea { + width: 100%; + padding: 10px 11px; + background: #fafbf9; + border: 1px solid var(--line); + border-radius: 9px; + outline: 0; + font-size: 10px; +} + +.form-modal textarea { + line-height: 1.6; + resize: vertical; +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +} + +.modal-actions { + display: flex; + justify-content: flex-end; + gap: 9px; + margin-top: 22px; +} + +.report-modal { + width: min(620px, 100%); +} + +.report-modal-head { + display: grid; + grid-template-columns: 67px 1fr; + align-items: center; + gap: 14px; + padding-right: 35px; +} + +.report-modal-head p { + margin-bottom: 0; +} + +.report-graphic { + display: grid; + width: 62px; + height: 62px; + place-items: center; + color: var(--green); + background: var(--green-soft); + border-radius: 15px; +} + +.report-graphic svg { + width: 43px; + height: 43px; +} + +.snapshot-card { + margin: 20px 0; + padding: 13px 15px; + background: #f4f8f5; + border: 1px solid #dfeae3; + border-radius: 11px; +} + +.snapshot-card span, +.snapshot-card strong, +.snapshot-card small { + display: block; +} + +.snapshot-card span { + margin-bottom: 5px; + color: var(--green-2); + font-size: 7px; + font-weight: 700; +} + +.snapshot-card strong { + margin-bottom: 4px; + font-size: 9px; +} + +.snapshot-card small { + color: var(--muted); + font-size: 7px; +} + +.report-options { + padding: 0; + border: 0; +} + +.report-options legend { + margin-bottom: 9px; + font-size: 9px; + font-weight: 700; +} + +.report-options label { + display: grid; + grid-template-columns: 17px 1fr; + align-items: center; + gap: 10px; + padding: 10px 0; + border-bottom: 1px solid var(--line-soft); +} + +.report-options input { + width: 15px; + height: 15px; + accent-color: var(--green); +} + +.report-options strong, +.report-options small { + display: block; +} + +.report-options strong { + margin-bottom: 4px; + font-size: 9px; +} + +.report-options small { + color: var(--muted); + font-size: 7px; +} + +.report-progress { + margin-top: 16px; + padding: 13px; + background: #f7f9f7; + border-radius: 10px; +} + +.report-progress > div { + display: flex; + justify-content: space-between; + margin-bottom: 8px; + color: var(--muted); + font-size: 8px; +} + +.report-progress > i { + display: block; + height: 6px; + overflow: hidden; + background: #e6ebe7; + border-radius: 4px; +} + +.report-progress b { + display: block; + width: 0; + height: 100%; + background: var(--green); + border-radius: 4px; + transition: width 0.2s ease; +} + +.analysis-modal { + width: min(470px, 100%); + padding: 42px; + text-align: center; +} + +.analysis-orbit { + position: relative; + display: grid; + width: 92px; + height: 92px; + margin: 0 auto 22px; + place-items: center; +} + +.analysis-orbit span { + position: absolute; + inset: 0; + border: 1px solid #d8e5dd; + border-radius: 50%; + animation: orbit 3s linear infinite; +} + +.analysis-orbit span:nth-child(2) { + inset: 12px; + border-style: dashed; + animation-direction: reverse; + animation-duration: 2.2s; +} + +.analysis-orbit i { + position: absolute; + top: 4px; + width: 9px; + height: 9px; + background: var(--lime); + border: 2px solid var(--green); + border-radius: 50%; + transform-origin: 4px 42px; + animation: pointOrbit 2.1s linear infinite; +} + +.analysis-orbit svg { + width: 27px; + height: 27px; + color: var(--green); +} + +@keyframes orbit { + to { + transform: rotate(360deg); + } +} + +@keyframes pointOrbit { + to { + transform: rotate(360deg); + } +} + +.analysis-progress { + height: 6px; + margin: 23px 0 14px; + overflow: hidden; + background: #e8ece9; + border-radius: 5px; +} + +.analysis-progress i { + display: block; + width: 0; + height: 100%; + background: linear-gradient(90deg, var(--green), #79bd8f); + border-radius: 5px; + transition: width 0.25s ease; +} + +.analysis-steps { + display: flex; + justify-content: space-between; + color: #a0aaa4; + font-size: 7px; +} + +.analysis-steps span.active { + color: var(--green); + font-weight: 700; +} + +.sidebar-scrim { + position: fixed; + z-index: 29; + inset: 0; + display: none; + background: rgba(8, 24, 18, 0.5); + opacity: 0; + transition: opacity 0.2s ease; +} + +/* 响应式 */ +@media (max-width: 1260px) { + :root { + --sidebar: 226px; + } + + .main-content { + padding-right: 22px; + padding-left: 22px; + } + + .dashboard-grid, + .content-grid, + .profession-layout, + .collab-layout, + .data-health, + .data-bottom-grid { + grid-template-columns: 1fr; + } + + .metric-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .partner-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .action-overview { + grid-template-columns: 110px repeat(2, 1fr); + } + + .action-health { + grid-column: span 2; + } + + .source-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .source-summary-grid { + grid-template-columns: 1fr; + } + + .platform-metric-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .platform-grid { + grid-template-columns: 1fr; + } + + .platform-bottom-grid { + grid-template-columns: 1fr 1fr; + } + + .platform-audit-panel { + grid-column: span 2; + } + + .report-stat-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .featured-report-grid, + .report-list-grid { + grid-template-columns: 1fr; + } + + .report-reader-layout { + grid-template-columns: 210px minmax(0, 1fr); + } + + .report-section { + padding-right: 42px; + padding-left: 42px; + } +} + +@media (max-width: 900px) { + :root { + --sidebar: 254px; + } + + .sidebar { + transform: translateX(-100%); + } + + body.sidebar-open .sidebar { + transform: translateX(0); + } + + body.sidebar-open .sidebar-scrim { + display: block; + opacity: 1; + } + + .workspace { + margin-left: 0; + } + + .mobile-menu { + display: inline-grid; + } + + .profile-banner { + grid-template-columns: repeat(2, 1fr); + } + + .profile-score { + grid-column: span 2; + } + + .profile-divider { + display: none; + } + + .collab-stats { + grid-template-columns: repeat(2, 1fr); + } + + .collab-stats > div:nth-child(2)::after { + display: none; + } + + .source-grid { + grid-template-columns: 1fr; + } + + .source-filter-toolbar { + align-items: flex-start; + flex-direction: column; + } + + .tenant-card-grid { + grid-template-columns: 1fr; + } + + .source-filters { + width: 100%; + overflow-x: auto; + } + + .source-filters button { + flex: 0 0 auto; + } + + .project-item { + grid-template-columns: 42px minmax(0, 1fr) 90px 26px; + } + + .project-partners { + display: none; + } + + .report-library-head { + align-items: flex-start; + flex-direction: column; + } + + .report-library-tools { + width: 100%; + } + + .report-library-tools .search-field { + flex: 1; + } + + .report-reader-header { + padding: 9px 12px; + } + + .report-reader-actions .reader-version, + .report-reader-actions .button.secondary { + display: none; + } + + .report-reader-layout { + display: flex; + flex-direction: column; + } + + .report-toc { + position: relative; + z-index: 2; + min-height: 56px; + flex: 0 0 auto; + padding: 8px 12px; + overflow-x: auto; + overflow-y: hidden; + border-right: 0; + border-bottom: 1px solid var(--line); + scrollbar-width: none; + } + + .report-toc::-webkit-scrollbar { + display: none; + } + + .report-toc-label, + .report-reader-meta { + display: none; + } + + .report-toc nav { + min-height: 40px; + flex-direction: row; + align-items: center; + } + + .report-toc button { + width: auto; + flex: 0 0 auto; + white-space: nowrap; + } + + .report-document { + width: min(100% - 20px, 1040px); + margin-top: 10px; + } + + .report-document-wrap { + min-height: 0; + flex: 1; + } + + .report-cover-page { + min-height: 510px; + padding: 50px 32px 38px; + } + + .report-cover-main h1 { + font-size: 34px; + } + + .report-section { + padding: 38px 28px; + } + + .report-metric-grid { + grid-template-columns: repeat(2, 1fr); + } + + .report-chart-grid { + grid-template-columns: 1fr; + } + + .report-profile-stat-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@media (max-width: 680px) { + .topbar { + height: 68px; + padding: 0 15px; + } + + .breadcrumb { + display: none; + } + + .topbar-date { + margin: 0; + font-size: 10px; + } + + .role-switcher { + min-width: 42px; + width: 42px; + height: 42px; + grid-template-columns: 1fr; + padding: 3px; + border: 0; + background: transparent; + } + + .role-switcher .role-copy, + .role-switcher > svg, + .edition-badge { + display: none; + } + + .main-content { + padding: 24px 14px 45px; + } + + .heading-with-actions, + .profession-heading { + align-items: flex-start; + flex-direction: column; + } + + .heading-actions { + width: 100%; + } + + .heading-actions .button { + flex: 1; + } + + .quality-strip { + align-items: flex-start; + flex-direction: column; + gap: 4px; + } + + .metric-grid { + grid-template-columns: 1fr; + } + + .metric-card { + min-height: 132px; + } + + .match-content { + grid-template-columns: 1fr; + justify-items: center; + } + + .trend-chart-wrap { + width: 100%; + } + + .match-summary { + align-items: flex-start; + flex-direction: column; + padding: 12px 5px 3px; + } + + .panel { + padding: 17px; + } + + .panel-header { + align-items: flex-start; + flex-direction: column; + } + + .panel-tools { + width: 100%; + justify-content: space-between; + } + + .search-field { + width: 100%; + } + + .profession-rank .text-button { + display: none; + } + + .profile-banner { + grid-template-columns: 1fr 1fr; + gap: 19px; + padding: 21px; + } + + .tab-bar { + overflow-x: auto; + } + + .tab-bar button { + min-width: 84px; + } + + .skill-row { + grid-template-columns: 76px minmax(0, 1fr) 38px; + gap: 8px; + } + + .collab-stats { + grid-template-columns: 1fr 1fr; + } + + .collab-stats > div { + padding: 16px; + } + + .collab-stats > div::after { + display: none; + } + + .partner-grid { + grid-template-columns: 1fr; + } + + .project-item { + grid-template-columns: 38px minmax(0, 1fr) 24px; + } + + .project-progress, + .project-partners { + display: none; + } + + .action-overview { + grid-template-columns: 1fr 1fr; + } + + .action-ring { + grid-column: span 2; + margin: 0 auto; + } + + .action-stat { + border-left: 0; + border-top: 1px solid var(--line-soft); + } + + .action-health { + grid-column: span 2; + } + + .task-toolbar { + align-items: stretch; + flex-direction: column; + } + + .filter-pills { + overflow-x: auto; + } + + .filter-pills button { + flex: 0 0 auto; + } + + .data-health-main { + grid-template-columns: 1fr; + } + + .report-stat-grid { + grid-template-columns: 1fr; + } + + .featured-report-card { + min-height: auto; + grid-template-columns: 1fr; + } + + .featured-report-cover { + display: none; + } + + .report-library-tools { + align-items: stretch; + flex-direction: column; + } + + .report-library-tools select { + width: 100%; + } + + .report-list-grid { + padding-right: 16px; + padding-left: 16px; + } + + .report-reader-identity strong { + max-width: 155px; + font-size: 13px; + } + + .report-reader-actions .button { + min-height: 38px; + padding: 0 11px; + } + + .report-cover-page { + min-height: 460px; + padding: 42px 24px 32px; + } + + .report-cover-main h1 { + font-size: 29px; + } + + .report-cover-main p { + font-size: 14px; + } + + .report-cover-foot { + grid-template-columns: 1fr; + } + + .report-section { + padding: 32px 20px; + } + + .report-section-heading h2 { + font-size: 21px; + } + + .report-metric-grid { + grid-template-columns: 1fr 1fr; + } + + .report-benchmark-strip, + .report-evidence-summary, + .report-profile-stat-grid { + grid-template-columns: 1fr 1fr; + } + + .report-benchmark-strip > span:nth-child(2) { + border-right: 0; + } + + .report-benchmark-strip > span:nth-child(-n + 2) { + border-bottom: 1px solid rgba(255, 255, 255, 0.1); + } + + .report-profile-banner { + grid-template-columns: 1fr; + padding: 18px; + } + + .report-profile-attributes { + grid-template-columns: 1fr 1fr; + } + + .report-chart-grid { + grid-template-columns: 1fr; + } + + .report-chart-stage, + .report-echart { + min-height: 300px; + height: 300px; + } + + .report-chart-card figcaption { + min-height: auto; + } + + .report-interpretation { + grid-template-columns: 1fr; + gap: 10px; + } + + .report-interpretation > span { + justify-self: start; + } + + .report-finding-validation { + flex-wrap: wrap; + } + + .report-proof-chain { + grid-template-columns: 1fr; + gap: 8px; + } + + .report-proof-chain > b { + width: 1px; + height: 15px; + justify-self: center; + } + + .report-method-steps { + grid-template-columns: 1fr; + } + + .report-action-cycle { + grid-template-columns: 1fr; + text-align: center; + } + + .report-action-cycle i { + width: 1px; + height: 14px; + justify-self: center; + } + + .report-finding, + .report-action-card { + grid-template-columns: 34px minmax(0, 1fr); + } + + .report-finding em, + .report-action-card button { + grid-column: 2; + justify-self: start; + } + + .report-bar-row { + grid-template-columns: 95px minmax(0, 1fr) 42px; + } + + .report-document-wrap { + overflow-x: hidden; + } + + .platform-alert { + grid-template-columns: 40px 1fr; + } + + .platform-alert button { + grid-column: 1 / -1; + width: 100%; + } + + .platform-metric-grid, + .platform-bottom-grid { + grid-template-columns: 1fr; + } + + .platform-audit-panel { + grid-column: auto; + } + + .platform-form-grid, + .platform-check-grid { + grid-template-columns: 1fr; + } + + .data-usage-note { + grid-template-columns: 38px 1fr; + } + + .data-usage-note button { + grid-column: 1 / -1; + width: 100%; + } + + .source-license-grid { + grid-template-columns: 1fr; + } + + .health-score { + padding: 0 0 17px; + border-right: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.12); + } + + .health-meta { + align-items: flex-start; + flex-direction: column; + gap: 8px; + } + + .lineage-flow { + align-items: stretch; + flex-direction: column; + } + + .lineage-flow > i { + width: 100%; + height: 15px; + transform: rotate(90deg); + } + + .form-row { + grid-template-columns: 1fr; + gap: 0; + } + + .modal { + padding: 23px 19px; + } + + .report-modal-head { + grid-template-columns: 50px 1fr; + } + + .report-graphic { + width: 46px; + height: 46px; + } + + .report-graphic svg { + width: 31px; + height: 31px; + } + + .toast-region { + right: 16px; + bottom: 16px; + } +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + scroll-behavior: auto !important; + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} diff --git a/demo/vendor/ECHARTS-GL-LICENSE.txt b/demo/vendor/ECHARTS-GL-LICENSE.txt new file mode 100644 index 0000000..c3c3945 --- /dev/null +++ b/demo/vendor/ECHARTS-GL-LICENSE.txt @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, Baidu Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/demo/vendor/ECHARTS-LICENSE.txt b/demo/vendor/ECHARTS-LICENSE.txt new file mode 100644 index 0000000..c633765 --- /dev/null +++ b/demo/vendor/ECHARTS-LICENSE.txt @@ -0,0 +1,222 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + + + +======================================================================== +Apache ECharts Subcomponents: + +The Apache ECharts project contains subcomponents with separate copyright +notices and license terms. Your use of the source code for these +subcomponents is also subject to the terms and conditions of the following +licenses. + +BSD 3-Clause (d3.js): +The following files embed [d3.js](https://github.com/d3/d3) BSD 3-Clause: + `/src/chart/treemap/treemapLayout.ts`, + `/src/chart/tree/layoutHelper.ts`, + `/src/chart/graph/forceHelper.ts`, + `/src/util/number.ts` +See `/licenses/LICENSE-d3` for details of the license. diff --git a/demo/vendor/ECHARTS-NOTICE.txt b/demo/vendor/ECHARTS-NOTICE.txt new file mode 100644 index 0000000..6f73221 --- /dev/null +++ b/demo/vendor/ECHARTS-NOTICE.txt @@ -0,0 +1,5 @@ +Apache ECharts +Copyright 2017-2024 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (https://www.apache.org/). \ No newline at end of file diff --git a/demo/vendor/echarts-gl.min.js b/demo/vendor/echarts-gl.min.js new file mode 100644 index 0000000..adfb1f2 --- /dev/null +++ b/demo/vendor/echarts-gl.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("echarts")):"function"==typeof define&&define.amd?define(["echarts"],t):"object"==typeof exports?exports["echarts-gl"]=t(require("echarts")):e["echarts-gl"]=t(e.echarts)}(self,(function(e){return(()=>{"use strict";var t={468:(e,t,r)=>{r.r(t);var i=r(83);function n(e,t,r){"object"==typeof t&&(r=t,t=null);var i,n=this;if(!(e instanceof Function))for(var s in i=[],e)e.hasOwnProperty(s)&&i.push(s);var l=function(t){if(n.apply(this,arguments),e instanceof Function?a(this,e.call(this,t)):o(this,e,i),this.constructor===l)for(var r=l.__initializers__,s=0;s=400?e.onerror&&e.onerror():e.onload&&e.onload(t.response)},e.onerror&&(t.onerror=e.onerror),t.send(null)}};var F,z={supportWebGL:function(){if(null==F)try{var e=document.createElement("canvas");if(!e.getContext("webgl")&&!e.getContext("experimental-webgl"))throw new Error}catch(e){F=!1}return F}};z.Int8Array="undefined"==typeof Int8Array?Array:Int8Array,z.Uint8Array="undefined"==typeof Uint8Array?Array:Uint8Array,z.Uint16Array="undefined"==typeof Uint16Array?Array:Uint16Array,z.Uint32Array="undefined"==typeof Uint32Array?Array:Uint32Array,z.Int16Array="undefined"==typeof Int16Array?Array:Int16Array,z.Float32Array="undefined"==typeof Float32Array?Array:Float32Array,z.Float64Array="undefined"==typeof Float64Array?Array:Float64Array;var G={};"undefined"!=typeof window?G=window:void 0!==r.g&&(G=r.g),z.requestAnimationFrame=G.requestAnimationFrame||G.msRequestAnimationFrame||G.mozRequestAnimationFrame||G.webkitRequestAnimationFrame||function(e){setTimeout(e,16)},z.createCanvas=function(){return document.createElement("canvas")},z.createImage=function(){return new G.Image},z.request={get:B.get},z.addEventListener=function(e,t,r,i){e.addEventListener(t,r,i)},z.removeEventListener=function(e,t,r){e.removeEventListener(t,r)};const U=z;var k=function(){this.head=null,this.tail=null,this._length=0};k.prototype.insert=function(e){var t=new k.Entry(e);return this.insertEntry(t),t},k.prototype.insertAt=function(e,t){if(!(e<0)){for(var r=this.head,i=0;r&&i!=e;)r=r.next,i++;if(r){var n=new k.Entry(t),a=r.prev;a?(a.next=n,n.prev=a):this.head=n,n.next=r,r.prev=n}else this.insert(t)}},k.prototype.insertBeforeEntry=function(e,t){var r=new k.Entry(e),i=t.prev;i?(i.next=r,r.prev=i):this.head=r,r.next=t,t.prev=r,this._length++},k.prototype.insertEntry=function(e){this.head?(this.tail.next=e,e.prev=this.tail,this.tail=e):this.head=this.tail=e,this._length++},k.prototype.remove=function(e){var t=e.prev,r=e.next;t?t.next=r:this.head=r,r?r.prev=t:this.tail=t,e.next=e.prev=null,this._length--},k.prototype.removeAt=function(e){if(!(e<0)){for(var t=this.head,r=0;t&&r!=e;)t=t.next,r++;return t?(this.remove(t),t.value):void 0}},k.prototype.getHead=function(){if(this.head)return this.head.value},k.prototype.getTail=function(){if(this.tail)return this.tail.value},k.prototype.getAt=function(e){if(!(e<0)){for(var t=this.head,r=0;t&&r!=e;)t=t.next,r++;return t.value}},k.prototype.indexOf=function(e){for(var t=this.head,r=0;t;){if(t.value===e)return r;t=t.next,r++}},k.prototype.length=function(){return this._length},k.prototype.isEmpty=function(){return 0===this._length},k.prototype.forEach=function(e,t){for(var r=this.head,i=0,n=void 0!==t;r;)n?e.call(t,r.value,i):e(r.value,i),r=r.next,i++},k.prototype.clear=function(){this.tail=this.head=null,this._length=0},k.Entry=function(e){this.value=e,this.next=null,this.prev=null};const V=k;var H=function(e){this._list=new V,this._map={},this._maxSize=e||10};H.prototype.setMaxSize=function(e){this._maxSize=e},H.prototype.put=function(e,t){if(!this._map.hasOwnProperty(e)){var r=this._list.length();if(r>=this._maxSize&&r>0){var i=this._list.head;this._list.remove(i),delete this._map[i.key]}var n=this._list.insert(t);n.key=e,this._map[e]=n}},H.prototype.get=function(e){var t=this._map[e];if(this._map.hasOwnProperty(e))return t!==this._list.tail&&(this._list.remove(t),this._list.insertEntry(t)),t.value},H.prototype.remove=function(e){var t=this._map[e];void 0!==t&&(delete this._map[e],this._list.remove(t))},H.prototype.clear=function(){this._list.clear(),this._map={}};const W=H;var j={},X={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};function q(e){return(e=Math.round(e))<0?0:e>255?255:e}function Z(e){return e<0?0:e>1?1:e}function Y(e){return e.length&&"%"===e.charAt(e.length-1)?q(parseFloat(e)/100*255):q(parseInt(e,10))}function K(e){return e.length&&"%"===e.charAt(e.length-1)?Z(parseFloat(e)/100):Z(parseFloat(e))}function Q(e,t,r){return r<0?r+=1:r>1&&(r-=1),6*r<1?e+(t-e)*r*6:2*r<1?t:3*r<2?e+(t-e)*(2/3-r)*6:e}function J(e,t,r){return e+(t-e)*r}function $(e,t,r,i,n){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e}function ee(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}var te=new W(20),re=null;function ie(e,t){re&&ee(re,t),re=te.put(e,re||t.slice())}function ne(e,t){var r=(parseFloat(e[0])%360+360)%360/360,i=K(e[1]),n=K(e[2]),a=n<=.5?n*(i+1):n+i-n*i,o=2*n-a;return $(t=t||[],q(255*Q(o,a,r+1/3)),q(255*Q(o,a,r)),q(255*Q(o,a,r-1/3)),1),4===e.length&&(t[3]=e[3]),t}j.parse=function(e,t){if(e){t=t||[];var r=te.get(e);if(r)return ee(t,r);var i,n=(e+="").replace(/ /g,"").toLowerCase();if(n in X)return ee(t,X[n]),ie(e,t),t;if("#"===n.charAt(0))return 4===n.length?(i=parseInt(n.substr(1),16))>=0&&i<=4095?($(t,(3840&i)>>4|(3840&i)>>8,240&i|(240&i)>>4,15&i|(15&i)<<4,1),ie(e,t),t):void $(t,0,0,0,1):7===n.length?(i=parseInt(n.substr(1),16))>=0&&i<=16777215?($(t,(16711680&i)>>16,(65280&i)>>8,255&i,1),ie(e,t),t):void $(t,0,0,0,1):void 0;var a=n.indexOf("("),o=n.indexOf(")");if(-1!==a&&o+1===n.length){var s=n.substr(0,a),l=n.substr(a+1,o-(a+1)).split(","),h=1;switch(s){case"rgba":if(4!==l.length)return void $(t,0,0,0,1);h=K(l.pop());case"rgb":return 3!==l.length?void $(t,0,0,0,1):($(t,Y(l[0]),Y(l[1]),Y(l[2]),h),ie(e,t),t);case"hsla":return 4!==l.length?void $(t,0,0,0,1):(l[3]=K(l[3]),ne(l,t),ie(e,t),t);case"hsl":return 3!==l.length?void $(t,0,0,0,1):(ne(l,t),ie(e,t),t);default:return}}$(t,0,0,0,1)}},j.parseToFloat=function(e,t){if(t=j.parse(e,t))return t[0]/=255,t[1]/=255,t[2]/=255,t},j.lift=function(e,t){var r=j.parse(e);if(r){for(var i=0;i<3;i++)r[i]=t<0?r[i]*(1-t)|0:(255-r[i])*t+r[i]|0;return j.stringify(r,4===r.length?"rgba":"rgb")}},j.toHex=function(e){var t=j.parse(e);if(t)return((1<<24)+(t[0]<<16)+(t[1]<<8)+ +t[2]).toString(16).slice(1)},j.fastLerp=function(e,t,r){if(t&&t.length&&e>=0&&e<=1){r=r||[];var i=e*(t.length-1),n=Math.floor(i),a=Math.ceil(i),o=t[n],s=t[a],l=i-n;return r[0]=q(J(o[0],s[0],l)),r[1]=q(J(o[1],s[1],l)),r[2]=q(J(o[2],s[2],l)),r[3]=Z(J(o[3],s[3],l)),r}},j.fastMapToColor=j.fastLerp,j.lerp=function(e,t,r){if(t&&t.length&&e>=0&&e<=1){var i=e*(t.length-1),n=Math.floor(i),a=Math.ceil(i),o=j.parse(t[n]),s=j.parse(t[a]),l=i-n,h=j.stringify([q(J(o[0],s[0],l)),q(J(o[1],s[1],l)),q(J(o[2],s[2],l)),Z(J(o[3],s[3],l))],"rgba");return r?{color:h,leftIndex:n,rightIndex:a,value:i}:h}},j.mapToColor=j.lerp,j.modifyHSL=function(e,t,r,i){if(e=j.parse(e))return e=function(e){if(e){var t,r,i=e[0]/255,n=e[1]/255,a=e[2]/255,o=Math.min(i,n,a),s=Math.max(i,n,a),l=s-o,h=(s+o)/2;if(0===l)t=0,r=0;else{r=h<.5?l/(s+o):l/(2-s-o);var u=((s-i)/6+l/2)/l,c=((s-n)/6+l/2)/l,d=((s-a)/6+l/2)/l;i===s?t=d-c:n===s?t=1/3+u-d:a===s&&(t=2/3+c-u),t<0&&(t+=1),t>1&&(t-=1)}var f=[360*t,r,h];return null!=e[3]&&f.push(e[3]),f}}(e),null!=t&&(e[0]=(n=t,(n=Math.round(n))<0?0:n>360?360:n)),null!=r&&(e[1]=K(r)),null!=i&&(e[2]=K(i)),j.stringify(ne(e),"rgba");var n},j.modifyAlpha=function(e,t){if((e=j.parse(e))&&null!=t)return e[3]=Z(t),j.stringify(e,"rgba")},j.stringify=function(e,t){if(e&&e.length){var r=e[0]+","+e[1]+","+e[2];return"rgba"!==t&&"hsva"!==t&&"hsla"!==t||(r+=","+e[3]),t+"("+r+")"}};var ae=j.parseToFloat,oe={};function se(e){var t=Object.keys(e);t.sort();for(var r=[],i=0;i=0},getEnabledUniforms:function(){return this._enabledUniforms},getTextureUniforms:function(){return this._textureUniforms},set:function(e,t){if("object"==typeof e)for(var r in e){var i=e[r];this.setUniform(r,i)}else this.setUniform(e,t)},get:function(e){var t=this.uniforms[e];if(t)return t.value},attachShader:function(e,t){var r=this.uniforms;this.uniforms=e.createUniforms(),this.shader=e;var i=this.uniforms;this._enabledUniforms=Object.keys(i),this._enabledUniforms.sort(),this._textureUniforms=this._enabledUniforms.filter((function(e){var t=this.uniforms[e].type;return"t"===t||"tv"===t}),this);var n=this.vertexDefines,a=this.fragmentDefines;if(this.vertexDefines=f.clone(e.vertexDefines),this.fragmentDefines=f.clone(e.fragmentDefines),t){for(var o in r)i[o]&&(i[o].value=r[o].value);f.defaults(this.vertexDefines,n),f.defaults(this.fragmentDefines,a)}var s={};for(var l in e.textures)s[l]={shaderType:e.textures[l].shaderType,type:e.textures[l].type,enabled:!(!t||!this._textureStatus[l])&&this._textureStatus[l].enabled};this._textureStatus=s,this._programKey=""},clone:function(){var e=new this.constructor({name:this.name,shader:this.shader});for(var t in this.uniforms)e.uniforms[t].value=this.uniforms[t].value;return e.depthTest=this.depthTest,e.depthMask=this.depthMask,e.transparent=this.transparent,e.blend=this.blend,e.vertexDefines=f.clone(this.vertexDefines),e.fragmentDefines=f.clone(this.fragmentDefines),e.enableTexture(this.getEnabledTextures()),e.precision=this.precision,e},define:function(e,t,r){var i=this.vertexDefines,n=this.fragmentDefines;"vertex"!==e&&"fragment"!==e&&"both"!==e&&arguments.length<3&&(r=t,t=e,e="both"),r=null!=r?r:null,"vertex"!==e&&"both"!==e||i[t]!==r&&(i[t]=r,this._programKey=""),"fragment"!==e&&"both"!==e||n[t]!==r&&(n[t]=r,"both"!==e&&(this._programKey=""))},undefine:function(e,t){"vertex"!==e&&"fragment"!==e&&"both"!==e&&arguments.length<2&&(t=e,e="both"),"vertex"!==e&&"both"!==e||this.isDefined("vertex",t)&&(delete this.vertexDefines[t],this._programKey=""),"fragment"!==e&&"both"!==e||this.isDefined("fragment",t)&&(delete this.fragmentDefines[t],"both"!==e&&(this._programKey=""))},isDefined:function(e,t){switch(e){case"vertex":return void 0!==this.vertexDefines[t];case"fragment":return void 0!==this.fragmentDefines[t]}},getDefine:function(e,t){switch(e){case"vertex":return this.vertexDefines[t];case"fragment":return this.fragmentDefines[t]}},enableTexture:function(e){if(Array.isArray(e))for(var t=0;t0&&(n=1/Math.sqrt(n),e[0]=t[0]*n,e[1]=t[1]*n),e},fe.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]},fe.cross=function(e,t,r){var i=t[0]*r[1]-t[1]*r[0];return e[0]=e[1]=0,e[2]=i,e},fe.lerp=function(e,t,r,i){var n=t[0],a=t[1];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e},fe.random=function(e,t){t=t||1;var r=2*GLMAT_RANDOM()*Math.PI;return e[0]=Math.cos(r)*t,e[1]=Math.sin(r)*t,e},fe.transformMat2=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[2]*n,e[1]=r[1]*i+r[3]*n,e},fe.transformMat2d=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[2]*n+r[4],e[1]=r[1]*i+r[3]*n+r[5],e},fe.transformMat3=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[3]*n+r[6],e[1]=r[1]*i+r[4]*n+r[7],e},fe.transformMat4=function(e,t,r){var i=t[0],n=t[1];return e[0]=r[0]*i+r[4]*n+r[12],e[1]=r[1]*i+r[5]*n+r[13],e},fe.forEach=(he=fe.create(),function(e,t,r,i,n,a){var o,s;for(t||(t=2),r||(r=0),s=i?Math.min(i*t+r,e.length):e.length,o=r;o0&&i.push("#define "+n.toUpperCase()+"_COUNT "+a)}if(r)for(var o=0;ol.getMaxJointNumber()&&(d.USE_SKIN_MATRICES_TEXTURE=null),c+="\n"+Me(d)+"\n"}a&&(c+="\n#define INSTANCING\n");var f=c+Me(t.vertexDefines,s,u),p=c+Me(t.fragmentDefines,s,u),m=f+"\n"+t.shader.vertex,g=["OES_standard_derivatives","EXT_shader_texture_lod"].filter((function(e){return null!=l.getGLExtension(e)}));g.indexOf("EXT_shader_texture_lod")>=0&&(p+="\n#define SUPPORT_TEXTURE_LOD"),g.indexOf("OES_standard_derivatives")>=0&&(p+="\n#define SUPPORT_STANDARD_DERIVATIVES");var _,v,y=function(e){for(var t=[],r=0;r=0){if(1!==s&&4!==s){ke();break}s=2,h=[]}else if(1!==s)if(4!==s)u(c),s=0;else{var d=c;Ie.indexOf(d)>=0||Re.indexOf(d)>=0||Be.indexOf(d)>=0?l[o].semantic=d:"ignore"===d||"unconfigurable"===d?l[o].ignore=!0:l[o].value="bool"===e?"true"===d:parseFloat(d)}else l[o].value="bool"===e?"true"===c:parseFloat(c),h=null;else{if(2!==s){ke();break}if(!(h instanceof Array)){ke();break}h.push(+i[++a])}else l[o].value=new U.Float32Array(h),h=null,s=5;else if(2===s){if(!(h instanceof Array)){ke();break}h.push(+i[++a])}else s=5;else s=4;else{if(0!==s&&3!==s){ke();break}s=1}}return l}function He(e,t){"object"==typeof e&&(t=e.fragment,e=e.vertex),e=Ue(e),t=Ue(t),this._shaderID=function(e,t){var r="vertex:"+e+"fragment:"+t;if(ze[r])return ze[r];var i=f.genGUID();return ze[r]=i,Ge[i]={vertex:e,fragment:t},i}(e,t),this._vertexCode=He.parseImport(e),this._fragmentCode=He.parseImport(t),this.attributeSemantics={},this.matrixSemantics={},this.uniformSemantics={},this.matrixSemanticKeys=[],this.uniformTemplates={},this.attributes={},this.textures={},this.vertexDefines={},this.fragmentDefines={},this._parseAttributes(),this._parseUniforms(),this._parseDefines()}He.prototype={constructor:He,createUniforms:function(){var e={};for(var t in this.uniformTemplates){var r=this.uniformTemplates[t];e[t]={type:r.type,value:r.value()}}return e},_parseImport:function(){this._vertexCode=He.parseImport(this.vertex),this._fragmentCode=He.parseImport(this.fragment)},_addSemanticUniform:function(e,t,r){if(Ie.indexOf(r)>=0)this.attributeSemantics[r]={symbol:e,type:t};else if(Be.indexOf(r)>=0){var i=!1,n=r;r.match(/TRANSPOSE$/)&&(i=!0,n=r.slice(0,-9)),this.matrixSemantics[r]={symbol:e,type:t,isTranspose:i,semanticNoTranspose:n}}else Re.indexOf(r)>=0&&(this.uniformSemantics[r]={symbol:e,type:t})},_addMaterialUniform:function(e,t,r,i,n,a){a[e]={type:r,value:n?Ne.array:i||Ne[t],semantic:null}},_parseUniforms:function(){var e={},t=this;function r(e){return null!=e?function(){return e}:null}function i(i,n,a){var o=Ve(n,a),s=[];for(var l in o){var h=o[l],u=h.semantic,c=l,d=Pe[n],f=r(o[l].value);o[l].isArray&&(c+="["+o[l].arraySize+"]",d+="v"),s.push(c),t._uniformList.push(l),h.ignore||("sampler2D"!==n&&"samplerCube"!==n||(t.textures[l]={shaderType:"fragment",type:n}),u?t._addSemanticUniform(l,d,u):t._addMaterialUniform(l,n,d,f,o[l].isArray,e))}return s.length>0?"uniform "+n+" "+s.join(",")+";\n":""}this._uniformList=[],this._vertexCode=this._vertexCode.replace(Ce,i),this._fragmentCode=this._fragmentCode.replace(Ce,i),t.matrixSemanticKeys=Object.keys(this.matrixSemantics),this.uniformTemplates=e},_parseAttributes:function(){var e={},t=this;this._vertexCode=this._vertexCode.replace(De,(function(r,i,n){var a=Ve(i,n),o=Fe[i]||1,s=[];for(var l in a){var h=a[l].semantic;if(e[l]={type:"float",size:o,semantic:h||null},h){if(Ie.indexOf(h)<0)throw new Error('Unkown semantic "'+h+'"');t.attributeSemantics[h]={symbol:l,type:i}}s.push(l)}return"attribute "+i+" "+s.join(",")+";\n"})),this.attributes=e},_parseDefines:function(){var e=this;function t(t,r,i){var n=e.fragmentDefines;return n[r]||(n[r]="false"!==i&&("true"===i||(i?isNaN(parseFloat(i))?i.trim():parseFloat(i):null))),""}this._vertexCode=this._vertexCode.replace(Le,t),this._fragmentCode=this._fragmentCode.replace(Le,t)},clone:function(){var e=Ge[this._shaderID];return new He(e.vertex,e.fragment)}},Object.defineProperty&&(Object.defineProperty(He.prototype,"shaderID",{get:function(){return this._shaderID}}),Object.defineProperty(He.prototype,"vertex",{get:function(){return this._vertexCode}}),Object.defineProperty(He.prototype,"fragment",{get:function(){return this._fragmentCode}}),Object.defineProperty(He.prototype,"uniforms",{get:function(){return this._uniformList}}));var We=/(@import)\s*([0-9a-zA-Z_\-\.]*)/g;He.parseImport=function(e){return e.replace(We,(function(e,t,r){return(e=He.source(r))?He.parseImport(e):(console.error('Shader chunk "'+r+'" not existed in library'),"")}))};var je=/(@export)\s*([0-9a-zA-Z_\-\.]*)\s*\n([\s\S]*?)@end/g;He.import=function(e){e.replace(je,(function(e,t,r,i){if(i=i.replace(/(^[\s\t\xa0\u3000]+)|([\u3000\xa0\s\t]+\x24)/g,"")){for(var n,a=r.split("."),o=He.codes,s=0;s 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n gl_FragColor = vec4(0.0,0.0,0.0,1.0);\n}\n@end";var Ze={create:function(){var e=new ce(16);return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},clone:function(e){var t=new ce(16);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t},copy:function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e},identity:function(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},transpose:function(e,t){if(e===t){var r=t[1],i=t[2],n=t[3],a=t[6],o=t[7],s=t[11];e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=r,e[6]=t[9],e[7]=t[13],e[8]=i,e[9]=a,e[11]=t[14],e[12]=n,e[13]=o,e[14]=s}else e[0]=t[0],e[1]=t[4],e[2]=t[8],e[3]=t[12],e[4]=t[1],e[5]=t[5],e[6]=t[9],e[7]=t[13],e[8]=t[2],e[9]=t[6],e[10]=t[10],e[11]=t[14],e[12]=t[3],e[13]=t[7],e[14]=t[11],e[15]=t[15];return e},invert:function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],l=t[6],h=t[7],u=t[8],c=t[9],d=t[10],f=t[11],p=t[12],m=t[13],g=t[14],_=t[15],v=r*s-i*o,y=r*l-n*o,x=r*h-a*o,b=i*l-n*s,w=i*h-a*s,T=n*h-a*l,S=u*m-c*p,M=u*g-d*p,A=u*_-f*p,E=c*g-d*m,C=c*_-f*m,D=d*_-f*g,L=v*D-y*C+x*E+b*A-w*M+T*S;return L?(L=1/L,e[0]=(s*D-l*C+h*E)*L,e[1]=(n*C-i*D-a*E)*L,e[2]=(m*T-g*w+_*b)*L,e[3]=(d*w-c*T-f*b)*L,e[4]=(l*A-o*D-h*M)*L,e[5]=(r*D-n*A+a*M)*L,e[6]=(g*x-p*T-_*y)*L,e[7]=(u*T-d*x+f*y)*L,e[8]=(o*C-s*A+h*S)*L,e[9]=(i*A-r*C-a*S)*L,e[10]=(p*w-m*x+_*v)*L,e[11]=(c*x-u*w-f*v)*L,e[12]=(s*M-o*E-l*S)*L,e[13]=(r*E-i*M+n*S)*L,e[14]=(m*y-p*b-g*v)*L,e[15]=(u*b-c*y+d*v)*L,e):null},adjoint:function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=t[4],s=t[5],l=t[6],h=t[7],u=t[8],c=t[9],d=t[10],f=t[11],p=t[12],m=t[13],g=t[14],_=t[15];return e[0]=s*(d*_-f*g)-c*(l*_-h*g)+m*(l*f-h*d),e[1]=-(i*(d*_-f*g)-c*(n*_-a*g)+m*(n*f-a*d)),e[2]=i*(l*_-h*g)-s*(n*_-a*g)+m*(n*h-a*l),e[3]=-(i*(l*f-h*d)-s*(n*f-a*d)+c*(n*h-a*l)),e[4]=-(o*(d*_-f*g)-u*(l*_-h*g)+p*(l*f-h*d)),e[5]=r*(d*_-f*g)-u*(n*_-a*g)+p*(n*f-a*d),e[6]=-(r*(l*_-h*g)-o*(n*_-a*g)+p*(n*h-a*l)),e[7]=r*(l*f-h*d)-o*(n*f-a*d)+u*(n*h-a*l),e[8]=o*(c*_-f*m)-u*(s*_-h*m)+p*(s*f-h*c),e[9]=-(r*(c*_-f*m)-u*(i*_-a*m)+p*(i*f-a*c)),e[10]=r*(s*_-h*m)-o*(i*_-a*m)+p*(i*h-a*s),e[11]=-(r*(s*f-h*c)-o*(i*f-a*c)+u*(i*h-a*s)),e[12]=-(o*(c*g-d*m)-u*(s*g-l*m)+p*(s*d-l*c)),e[13]=r*(c*g-d*m)-u*(i*g-n*m)+p*(i*d-n*c),e[14]=-(r*(s*g-l*m)-o*(i*g-n*m)+p*(i*l-n*s)),e[15]=r*(s*d-l*c)-o*(i*d-n*c)+u*(i*l-n*s),e},determinant:function(e){var t=e[0],r=e[1],i=e[2],n=e[3],a=e[4],o=e[5],s=e[6],l=e[7],h=e[8],u=e[9],c=e[10],d=e[11],f=e[12],p=e[13],m=e[14],g=e[15];return(t*o-r*a)*(c*g-d*m)-(t*s-i*a)*(u*g-d*p)+(t*l-n*a)*(u*m-c*p)+(r*s-i*o)*(h*g-d*f)-(r*l-n*o)*(h*m-c*f)+(i*l-n*s)*(h*p-u*f)},multiply:function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],l=t[5],h=t[6],u=t[7],c=t[8],d=t[9],f=t[10],p=t[11],m=t[12],g=t[13],_=t[14],v=t[15],y=r[0],x=r[1],b=r[2],w=r[3];return e[0]=y*i+x*s+b*c+w*m,e[1]=y*n+x*l+b*d+w*g,e[2]=y*a+x*h+b*f+w*_,e[3]=y*o+x*u+b*p+w*v,y=r[4],x=r[5],b=r[6],w=r[7],e[4]=y*i+x*s+b*c+w*m,e[5]=y*n+x*l+b*d+w*g,e[6]=y*a+x*h+b*f+w*_,e[7]=y*o+x*u+b*p+w*v,y=r[8],x=r[9],b=r[10],w=r[11],e[8]=y*i+x*s+b*c+w*m,e[9]=y*n+x*l+b*d+w*g,e[10]=y*a+x*h+b*f+w*_,e[11]=y*o+x*u+b*p+w*v,y=r[12],x=r[13],b=r[14],w=r[15],e[12]=y*i+x*s+b*c+w*m,e[13]=y*n+x*l+b*d+w*g,e[14]=y*a+x*h+b*f+w*_,e[15]=y*o+x*u+b*p+w*v,e},multiplyAffine:function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[4],s=t[5],l=t[6],h=t[8],u=t[9],c=t[10],d=t[12],f=t[13],p=t[14],m=r[0],g=r[1],_=r[2];return e[0]=m*i+g*o+_*h,e[1]=m*n+g*s+_*u,e[2]=m*a+g*l+_*c,m=r[4],g=r[5],_=r[6],e[4]=m*i+g*o+_*h,e[5]=m*n+g*s+_*u,e[6]=m*a+g*l+_*c,m=r[8],g=r[9],_=r[10],e[8]=m*i+g*o+_*h,e[9]=m*n+g*s+_*u,e[10]=m*a+g*l+_*c,m=r[12],g=r[13],_=r[14],e[12]=m*i+g*o+_*h+d,e[13]=m*n+g*s+_*u+f,e[14]=m*a+g*l+_*c+p,e}};Ze.mul=Ze.multiply,Ze.mulAffine=Ze.multiplyAffine,Ze.translate=function(e,t,r){var i,n,a,o,s,l,h,u,c,d,f,p,m=r[0],g=r[1],_=r[2];return t===e?(e[12]=t[0]*m+t[4]*g+t[8]*_+t[12],e[13]=t[1]*m+t[5]*g+t[9]*_+t[13],e[14]=t[2]*m+t[6]*g+t[10]*_+t[14],e[15]=t[3]*m+t[7]*g+t[11]*_+t[15]):(i=t[0],n=t[1],a=t[2],o=t[3],s=t[4],l=t[5],h=t[6],u=t[7],c=t[8],d=t[9],f=t[10],p=t[11],e[0]=i,e[1]=n,e[2]=a,e[3]=o,e[4]=s,e[5]=l,e[6]=h,e[7]=u,e[8]=c,e[9]=d,e[10]=f,e[11]=p,e[12]=i*m+s*g+c*_+t[12],e[13]=n*m+l*g+d*_+t[13],e[14]=a*m+h*g+f*_+t[14],e[15]=o*m+u*g+p*_+t[15]),e},Ze.scale=function(e,t,r){var i=r[0],n=r[1],a=r[2];return e[0]=t[0]*i,e[1]=t[1]*i,e[2]=t[2]*i,e[3]=t[3]*i,e[4]=t[4]*n,e[5]=t[5]*n,e[6]=t[6]*n,e[7]=t[7]*n,e[8]=t[8]*a,e[9]=t[9]*a,e[10]=t[10]*a,e[11]=t[11]*a,e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e},Ze.rotate=function(e,t,r,i){var n,a,o,s,l,h,u,c,d,f,p,m,g,_,v,y,x,b,w,T,S,M,A,E,C=i[0],D=i[1],L=i[2],P=Math.sqrt(C*C+D*D+L*L);return Math.abs(P)0&&(a=1/Math.sqrt(a),e[0]=t[0]*a,e[1]=t[1]*a,e[2]=t[2]*a),e},Ke.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]},Ke.cross=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],l=r[2];return e[0]=n*l-a*s,e[1]=a*o-i*l,e[2]=i*s-n*o,e},Ke.lerp=function(e,t,r,i){var n=t[0],a=t[1],o=t[2];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e[2]=o+i*(r[2]-o),e},Ke.random=function(e,t){t=t||1;var r=2*de()*Math.PI,i=2*de()-1,n=Math.sqrt(1-i*i)*t;return e[0]=Math.cos(r)*n,e[1]=Math.sin(r)*n,e[2]=i*t,e},Ke.transformMat4=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[3]*i+r[7]*n+r[11]*a+r[15];return o=o||1,e[0]=(r[0]*i+r[4]*n+r[8]*a+r[12])/o,e[1]=(r[1]*i+r[5]*n+r[9]*a+r[13])/o,e[2]=(r[2]*i+r[6]*n+r[10]*a+r[14])/o,e},Ke.transformMat3=function(e,t,r){var i=t[0],n=t[1],a=t[2];return e[0]=i*r[0]+n*r[3]+a*r[6],e[1]=i*r[1]+n*r[4]+a*r[7],e[2]=i*r[2]+n*r[5]+a*r[8],e},Ke.transformQuat=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],l=r[2],h=r[3],u=h*i+s*a-l*n,c=h*n+l*i-o*a,d=h*a+o*n-s*i,f=-o*i-s*n-l*a;return e[0]=u*h+f*-o+c*-l-d*-s,e[1]=c*h+f*-s+d*-o-u*-l,e[2]=d*h+f*-l+u*-s-c*-o,e},Ke.rotateX=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[0],a[1]=n[1]*Math.cos(i)-n[2]*Math.sin(i),a[2]=n[1]*Math.sin(i)+n[2]*Math.cos(i),e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},Ke.rotateY=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[2]*Math.sin(i)+n[0]*Math.cos(i),a[1]=n[1],a[2]=n[2]*Math.cos(i)-n[0]*Math.sin(i),e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},Ke.rotateZ=function(e,t,r,i){var n=[],a=[];return n[0]=t[0]-r[0],n[1]=t[1]-r[1],n[2]=t[2]-r[2],a[0]=n[0]*Math.cos(i)-n[1]*Math.sin(i),a[1]=n[0]*Math.sin(i)+n[1]*Math.cos(i),a[2]=n[2],e[0]=a[0]+r[0],e[1]=a[1]+r[1],e[2]=a[2]+r[2],e},Ke.forEach=function(){var e=Ke.create();return function(t,r,i,n,a,o){var s,l;for(r||(r=3),i||(i=0),l=n?Math.min(n*r+i,t.length):t.length,s=i;s1?0:Math.acos(n)};const Qe=Ke;Xe.import(qe);var Je=Ye.create,$e={};function et(e){return e.material}function tt(e,t,r){return t.uniforms[r].value}function rt(e,t,r,i){return r!==i}function it(e){return!0}function nt(){}var at={float:S,byte:5120,ubyte:T,short:5122,ushort:5123};function ot(e,t,r){this.availableAttributes=e,this.availableAttributeSymbols=t,this.indicesBuffer=r,this.vao=null}function st(e){var t,r;this.bind=function(e){t||((t=U.createCanvas()).width=t.height=1,t.getContext("2d"));var i=e.gl,n=!r;n&&(r=i.createTexture()),i.bindTexture(i.TEXTURE_2D,r),n&&i.texImage2D(i.TEXTURE_2D,0,i.RGBA,i.RGBA,i.UNSIGNED_BYTE,t)},this.unbind=function(e){e.gl.bindTexture(e.gl.TEXTURE_2D,null)},this.isRenderable=function(){return!0}}var lt=m.extend((function(){return{canvas:null,_width:100,_height:100,devicePixelRatio:"undefined"!=typeof window&&window.devicePixelRatio||1,clearColor:[0,0,0,0],clearBit:17664,alpha:!0,depth:!0,stencil:!1,antialias:!0,premultipliedAlpha:!0,preserveDrawingBuffer:!1,throwError:!0,gl:null,viewport:{},maxJointNumber:20,__currentFrameBuffer:null,_viewportStack:[],_clearStack:[],_sceneRendering:null}}),(function(){this.canvas||(this.canvas=U.createCanvas());var e=this.canvas;try{var t={alpha:this.alpha,depth:this.depth,stencil:this.stencil,antialias:this.antialias,premultipliedAlpha:this.premultipliedAlpha,preserveDrawingBuffer:this.preserveDrawingBuffer};if(this.gl=e.getContext("webgl",t)||e.getContext("experimental-webgl",t),!this.gl)throw new Error;this._glinfo=new v(this.gl),this.gl.targetRenderer&&console.error("Already created a renderer"),this.gl.targetRenderer=this,this.resize()}catch(e){throw"Error creating WebGL Context "+e}this._programMgr=new Ee(this),this._placeholderTexture=new st(this)}),{resize:function(e,t){var r=this.canvas,i=this.devicePixelRatio;null!=e?(r.style&&(r.style.width=e+"px",r.style.height=t+"px"),r.width=e*i,r.height=t*i,this._width=e,this._height=t):(this._width=r.width/i,this._height=r.height/i),this.setViewport(0,0,this._width,this._height)},getWidth:function(){return this._width},getHeight:function(){return this._height},getViewportAspect:function(){var e=this.viewport;return e.width/e.height},setDevicePixelRatio:function(e){this.devicePixelRatio=e,this.resize(this._width,this._height)},getDevicePixelRatio:function(){return this.devicePixelRatio},getGLExtension:function(e){return this._glinfo.getExtension(e)},getGLParameter:function(e){return this._glinfo.getParameter(e)},setViewport:function(e,t,r,i,n){if("object"==typeof e){var a=e;e=a.x,t=a.y,r=a.width,i=a.height,n=a.devicePixelRatio}n=n||this.devicePixelRatio,this.gl.viewport(e*n,t*n,r*n,i*n),this.viewport={x:e,y:t,width:r,height:i,devicePixelRatio:n}},saveViewport:function(){this._viewportStack.push(this.viewport)},restoreViewport:function(){this._viewportStack.length>0&&this.setViewport(this._viewportStack.pop())},saveClear:function(){this._clearStack.push({clearBit:this.clearBit,clearColor:this.clearColor})},restoreClear:function(){if(this._clearStack.length>0){var e=this._clearStack.pop();this.clearColor=e.clearColor,this.clearBit=e.clearBit}},bindSceneRendering:function(e){this._sceneRendering=e},render:function(e,t,r,i){var n=this.gl,a=this.clearColor;if(this.clearBit){n.colorMask(!0,!0,!0,!0),n.depthMask(!0);var o=this.viewport,s=!1,l=o.devicePixelRatio;(o.width!==this._width||o.height!==this._height||l&&l!==this.devicePixelRatio||o.x||o.y)&&(s=!0,n.enable(n.SCISSOR_TEST),n.scissor(o.x*l,o.y*l,o.width*l,o.height*l)),n.clearColor(a[0],a[1],a[2],a[3]),n.clear(this.clearBit),s&&n.disable(n.SCISSOR_TEST)}if(r||e.update(!1),e.updateLights(),t=t||e.getMainCamera()){t.update();var h=e.updateRenderList(t,!0);this._sceneRendering=e;var u=h.opaque,c=h.transparent,d=e.material;e.trigger("beforerender",this,e,t,h),i?(this.renderPreZ(u,e,t),n.depthFunc(n.LEQUAL)):n.depthFunc(n.LESS);for(var f=Je(),p=Qe.create(),m=0;m0){var s=e[n-1],l=s.joints?s.joints.length:0;if((a.joints?a.joints.length:0)===l&&a.material===s.material&&a.lightGroup===s.lightGroup){a.__program=s.__program;continue}}var h=this._programMgr.getProgram(a,o,t);this.validateProgram(h),a.__program=h}},renderPass:function(e,t,r){this.trigger("beforerenderpass",this,e,t,r),(r=r||{}).getMaterial=r.getMaterial||et,r.getUniform=r.getUniform||tt,r.isMaterialChanged=r.isMaterialChanged||rt,r.beforeRender=r.beforeRender||nt,r.afterRender=r.afterRender||nt;var i=r.ifRender||it;this.updatePrograms(e,this._sceneRendering,r),r.sortCompare&&e.sort(r.sortCompare);var n=this.viewport,a=n.devicePixelRatio,o=[n.x*a,n.y*a,n.width*a,n.height*a],s=this.devicePixelRatio,l=this.__currentFrameBuffer?[this.__currentFrameBuffer.getTextureWidth(),this.__currentFrameBuffer.getTextureHeight()]:[this._width*s,this._height*s],h=[o[2],o[3]],u=Date.now();t?(Ye.copy(ht.VIEW,t.viewMatrix.array),Ye.copy(ht.PROJECTION,t.projectionMatrix.array),Ye.copy(ht.VIEWINVERSE,t.worldTransform.array)):(Ye.identity(ht.VIEW),Ye.identity(ht.PROJECTION),Ye.identity(ht.VIEWINVERSE)),Ye.multiply(ht.VIEWPROJECTION,ht.PROJECTION,ht.VIEW),Ye.invert(ht.PROJECTIONINVERSE,ht.PROJECTION),Ye.invert(ht.VIEWPROJECTIONINVERSE,ht.VIEWPROJECTION);for(var c,d,f,p,m,g,_,v,y,x,b,w,T=this.gl,S=this._sceneRendering,M=0;Mthis.getMaxJointNumber()){var a=n.getSubSkinMatricesTexture(e.__uid__,e.joints);t.useTextureSlot(this,a,r),t.setUniform(i,"1i","skinMatricesTexture",r),t.setUniform(i,"1f","skinMatricesTextureSize",a.width)}else{var o=n.getSubSkinMatrices(e.__uid__,e.joints);t.setUniformOfSemantic(i,"SKIN_MATRIX",o)}},_renderObject:function(e,t,r){var i=this.gl,n=e.geometry,a=e.mode;null==a&&(a=4);var o=null,s=e.isInstancedMesh&&e.isInstancedMesh();if(!s||(o=this.getGLExtension("ANGLE_instanced_arrays"))){var l;if(s&&(l=this._bindInstancedAttributes(e,r,o)),t.indicesBuffer){var h=this.getGLExtension("OES_element_index_uint")&&n.indices instanceof Uint32Array?i.UNSIGNED_INT:i.UNSIGNED_SHORT;s?o.drawElementsInstancedANGLE(a,t.indicesBuffer.count,h,0,e.getInstanceCount()):i.drawElements(a,t.indicesBuffer.count,h,0)}else s?o.drawArraysInstancedANGLE(a,0,n.vertexCount,e.getInstanceCount()):i.drawArrays(a,0,n.vertexCount);if(s)for(var u=0;ur?r:e}ct.add=function(e,t,r){return Qe.add(e.array,t.array,r.array),e._dirty=!0,e},ct.set=function(e,t,r,i){Qe.set(e.array,t,r,i),e._dirty=!0},ct.copy=function(e,t){return Qe.copy(e.array,t.array),e._dirty=!0,e},ct.cross=function(e,t,r){return Qe.cross(e.array,t.array,r.array),e._dirty=!0,e},ct.distance=ct.dist=function(e,t){return Qe.distance(e.array,t.array)},ct.divide=ct.div=function(e,t,r){return Qe.divide(e.array,t.array,r.array),e._dirty=!0,e},ct.dot=function(e,t){return Qe.dot(e.array,t.array)},ct.len=function(e){return Qe.length(e.array)},ct.lerp=function(e,t,r,i){return Qe.lerp(e.array,t.array,r.array,i),e._dirty=!0,e},ct.min=function(e,t,r){return Qe.min(e.array,t.array,r.array),e._dirty=!0,e},ct.max=function(e,t,r){return Qe.max(e.array,t.array,r.array),e._dirty=!0,e},ct.multiply=ct.mul=function(e,t,r){return Qe.multiply(e.array,t.array,r.array),e._dirty=!0,e},ct.negate=function(e,t){return Qe.negate(e.array,t.array),e._dirty=!0,e},ct.normalize=function(e,t){return Qe.normalize(e.array,t.array),e._dirty=!0,e},ct.random=function(e,t){return Qe.random(e.array,t),e._dirty=!0,e},ct.scale=function(e,t,r){return Qe.scale(e.array,t.array,r),e._dirty=!0,e},ct.scaleAndAdd=function(e,t,r,i){return Qe.scaleAndAdd(e.array,t.array,r.array,i),e._dirty=!0,e},ct.squaredDistance=ct.sqrDist=function(e,t){return Qe.sqrDist(e.array,t.array)},ct.squaredLength=ct.sqrLen=function(e){return Qe.sqrLen(e.array)},ct.subtract=ct.sub=function(e,t,r){return Qe.subtract(e.array,t.array,r.array),e._dirty=!0,e},ct.transformMat3=function(e,t,r){return Qe.transformMat3(e.array,t.array,r.array),e._dirty=!0,e},ct.transformMat4=function(e,t,r){return Qe.transformMat4(e.array,t.array,r.array),e._dirty=!0,e},ct.transformQuat=function(e,t,r){return Qe.transformQuat(e.array,t.array,r.array),e._dirty=!0,e};var mt=Math.atan2,gt=Math.asin,_t=Math.abs;ct.eulerFromQuat=function(e,t,r){e._dirty=!0,t=t.array;var i=e.array,n=t[0],a=t[1],o=t[2],s=t[3],l=n*n,h=a*a,u=o*o,c=s*s;switch(r=(r||"XYZ").toUpperCase()){case"XYZ":i[0]=mt(2*(n*s-a*o),c-l-h+u),i[1]=gt(pt(2*(n*o+a*s),-1,1)),i[2]=mt(2*(o*s-n*a),c+l-h-u);break;case"YXZ":i[0]=gt(pt(2*(n*s-a*o),-1,1)),i[1]=mt(2*(n*o+a*s),c-l-h+u),i[2]=mt(2*(n*a+o*s),c-l+h-u);break;case"ZXY":i[0]=gt(pt(2*(n*s+a*o),-1,1)),i[1]=mt(2*(a*s-o*n),c-l-h+u),i[2]=mt(2*(o*s-n*a),c-l+h-u);break;case"ZYX":i[0]=mt(2*(n*s+o*a),c-l-h+u),i[1]=gt(pt(2*(a*s-n*o),-1,1)),i[2]=mt(2*(n*a+o*s),c+l-h-u);break;case"YZX":i[0]=mt(2*(n*s-o*a),c-l+h-u),i[1]=mt(2*(a*s-n*o),c+l-h-u),i[2]=gt(pt(2*(n*a+o*s),-1,1));break;case"XZY":i[0]=mt(2*(n*s+a*o),c-l+h-u),i[1]=mt(2*(n*o+a*s),c+l-h-u),i[2]=gt(pt(2*(o*s-n*a),-1,1));break;default:console.warn("Unkown order: "+r)}return e},ct.eulerFromMat3=function(e,t,r){var i=t.array,n=i[0],a=i[3],o=i[6],s=i[1],l=i[4],h=i[7],u=i[2],c=i[5],d=i[8],f=e.array;switch(r=(r||"XYZ").toUpperCase()){case"XYZ":f[1]=gt(pt(o,-1,1)),_t(o)<.99999?(f[0]=mt(-h,d),f[2]=mt(-a,n)):(f[0]=mt(c,l),f[2]=0);break;case"YXZ":f[0]=gt(-pt(h,-1,1)),_t(h)<.99999?(f[1]=mt(o,d),f[2]=mt(s,l)):(f[1]=mt(-u,n),f[2]=0);break;case"ZXY":f[0]=gt(pt(c,-1,1)),_t(c)<.99999?(f[1]=mt(-u,d),f[2]=mt(-a,l)):(f[1]=0,f[2]=mt(s,n));break;case"ZYX":f[1]=gt(-pt(u,-1,1)),_t(u)<.99999?(f[0]=mt(c,d),f[2]=mt(s,n)):(f[0]=0,f[2]=mt(-a,l));break;case"YZX":f[2]=gt(pt(s,-1,1)),_t(s)<.99999?(f[0]=mt(-h,l),f[1]=mt(-u,n)):(f[0]=0,f[1]=mt(o,d));break;case"XZY":f[2]=gt(-pt(a,-1,1)),_t(a)<.99999?(f[0]=mt(c,l),f[1]=mt(o,n)):(f[0]=mt(-h,d),f[1]=0);break;default:console.warn("Unkown order: "+r)}return e._dirty=!0,e},Object.defineProperties(ct,{POSITIVE_X:{get:function(){return new ct(1,0,0)}},NEGATIVE_X:{get:function(){return new ct(-1,0,0)}},POSITIVE_Y:{get:function(){return new ct(0,1,0)}},NEGATIVE_Y:{get:function(){return new ct(0,-1,0)}},POSITIVE_Z:{get:function(){return new ct(0,0,1)}},NEGATIVE_Z:{get:function(){return new ct(0,0,-1)}},UP:{get:function(){return new ct(0,1,0)}},ZERO:{get:function(){return new ct}}});const vt=ct;var yt,xt,bt,wt,Tt,St=function(e,t){this.origin=e||new vt,this.direction=t||new vt};St.prototype={constructor:St,intersectPlane:function(e,t){var r=e.normal.array,i=e.distance,n=this.origin.array,a=this.direction.array,o=Qe.dot(r,a);if(0===o)return null;t||(t=new vt);var s=(Qe.dot(r,n)-i)/o;return Qe.scaleAndAdd(t.array,n,a,-s),t._dirty=!0,t},mirrorAgainstPlane:function(e){var t=Qe.dot(e.normal.array,this.direction.array);Qe.scaleAndAdd(this.direction.array,this.direction.array,e.normal.array,2*-t),this.direction._dirty=!0},distanceToPoint:(Tt=Qe.create(),function(e){Qe.sub(Tt,e,this.origin.array);var t=Qe.dot(Tt,this.direction.array);if(t<0)return Qe.distance(this.origin.array,e);var r=Qe.lenSquared(Tt);return Math.sqrt(r-t*t)}),intersectSphere:function(){var e=Qe.create();return function(t,r,i){var n=this.origin.array,a=this.direction.array;t=t.array,Qe.sub(e,t,n);var o=Qe.dot(e,a),s=Qe.squaredLength(e)-o*o,l=r*r;if(!(s>l)){var h=Math.sqrt(l-s),u=o-h,c=o+h;return i||(i=new vt),u<0?c<0?null:(Qe.scaleAndAdd(i.array,n,a,c),i):(Qe.scaleAndAdd(i.array,n,a,u),i)}}}(),intersectBoundingBox:function(e,t){var r,i,n,a,o,s,l=this.direction.array,h=this.origin.array,u=e.min.array,c=e.max.array,d=1/l[0],f=1/l[1],p=1/l[2];if(d>=0?(r=(u[0]-h[0])*d,i=(c[0]-h[0])*d):(i=(u[0]-h[0])*d,r=(c[0]-h[0])*d),f>=0?(n=(u[1]-h[1])*f,a=(c[1]-h[1])*f):(a=(u[1]-h[1])*f,n=(c[1]-h[1])*f),r>a||n>i)return null;if((n>r||r!=r)&&(r=n),(a=0?(o=(u[2]-h[2])*p,s=(c[2]-h[2])*p):(s=(u[2]-h[2])*p,o=(c[2]-h[2])*p),r>s||o>i)return null;if((o>r||r!=r)&&(r=o),(s=0?r:i;return t||(t=new vt),Qe.scaleAndAdd(t.array,h,l,m),t},intersectTriangle:(yt=Qe.create(),xt=Qe.create(),bt=Qe.create(),wt=Qe.create(),function(e,t,r,i,n,a){var o=this.direction.array,s=this.origin.array;e=e.array,t=t.array,r=r.array,Qe.sub(yt,t,e),Qe.sub(xt,r,e),Qe.cross(wt,xt,o);var l=Qe.dot(yt,wt);if(i){if(l>-1e-5)return null}else if(l>-1e-5&&l<1e-5)return null;Qe.sub(bt,s,e);var h=Qe.dot(wt,bt)/l;if(h<0||h>1)return null;Qe.cross(wt,yt,bt);var u=Qe.dot(o,wt)/l;if(u<0||u>1||h+u>1)return null;Qe.cross(wt,yt,xt);var c=-Qe.dot(bt,wt)/l;return c<0?null:(n||(n=new vt),a&&vt.set(a,1-h-u,h,u),Qe.scaleAndAdd(n.array,s,o,c),n)}),applyTransform:function(e){vt.add(this.direction,this.direction,this.origin),vt.transformMat4(this.origin,this.origin,e),vt.transformMat4(this.direction,this.direction,e),vt.sub(this.direction,this.direction,this.origin),vt.normalize(this.direction,this.direction)},copy:function(e){vt.copy(this.origin,e.origin),vt.copy(this.direction,e.direction)},clone:function(){var e=new St;return e.copy(this),e}};const Mt=St;var At={create:function(){var e=new ce(4);return e[0]=0,e[1]=0,e[2]=0,e[3]=0,e},clone:function(e){var t=new ce(4);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t},fromValues:function(e,t,r,i){var n=new ce(4);return n[0]=e,n[1]=t,n[2]=r,n[3]=i,n},copy:function(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e},set:function(e,t,r,i,n){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e},add:function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e[2]=t[2]+r[2],e[3]=t[3]+r[3],e},subtract:function(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e[2]=t[2]-r[2],e[3]=t[3]-r[3],e}};At.sub=At.subtract,At.multiply=function(e,t,r){return e[0]=t[0]*r[0],e[1]=t[1]*r[1],e[2]=t[2]*r[2],e[3]=t[3]*r[3],e},At.mul=At.multiply,At.divide=function(e,t,r){return e[0]=t[0]/r[0],e[1]=t[1]/r[1],e[2]=t[2]/r[2],e[3]=t[3]/r[3],e},At.div=At.divide,At.min=function(e,t,r){return e[0]=Math.min(t[0],r[0]),e[1]=Math.min(t[1],r[1]),e[2]=Math.min(t[2],r[2]),e[3]=Math.min(t[3],r[3]),e},At.max=function(e,t,r){return e[0]=Math.max(t[0],r[0]),e[1]=Math.max(t[1],r[1]),e[2]=Math.max(t[2],r[2]),e[3]=Math.max(t[3],r[3]),e},At.scale=function(e,t,r){return e[0]=t[0]*r,e[1]=t[1]*r,e[2]=t[2]*r,e[3]=t[3]*r,e},At.scaleAndAdd=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e[2]=t[2]+r[2]*i,e[3]=t[3]+r[3]*i,e},At.distance=function(e,t){var r=t[0]-e[0],i=t[1]-e[1],n=t[2]-e[2],a=t[3]-e[3];return Math.sqrt(r*r+i*i+n*n+a*a)},At.dist=At.distance,At.squaredDistance=function(e,t){var r=t[0]-e[0],i=t[1]-e[1],n=t[2]-e[2],a=t[3]-e[3];return r*r+i*i+n*n+a*a},At.sqrDist=At.squaredDistance,At.length=function(e){var t=e[0],r=e[1],i=e[2],n=e[3];return Math.sqrt(t*t+r*r+i*i+n*n)},At.len=At.length,At.squaredLength=function(e){var t=e[0],r=e[1],i=e[2],n=e[3];return t*t+r*r+i*i+n*n},At.sqrLen=At.squaredLength,At.negate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=-t[3],e},At.inverse=function(e,t){return e[0]=1/t[0],e[1]=1/t[1],e[2]=1/t[2],e[3]=1/t[3],e},At.normalize=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r*r+i*i+n*n+a*a;return o>0&&(o=1/Math.sqrt(o),e[0]=t[0]*o,e[1]=t[1]*o,e[2]=t[2]*o,e[3]=t[3]*o),e},At.dot=function(e,t){return e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]*t[3]},At.lerp=function(e,t,r,i){var n=t[0],a=t[1],o=t[2],s=t[3];return e[0]=n+i*(r[0]-n),e[1]=a+i*(r[1]-a),e[2]=o+i*(r[2]-o),e[3]=s+i*(r[3]-s),e},At.random=function(e,t){return t=t||1,e[0]=de(),e[1]=de(),e[2]=de(),e[3]=de(),At.normalize(e,e),At.scale(e,e,t),e},At.transformMat4=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3];return e[0]=r[0]*i+r[4]*n+r[8]*a+r[12]*o,e[1]=r[1]*i+r[5]*n+r[9]*a+r[13]*o,e[2]=r[2]*i+r[6]*n+r[10]*a+r[14]*o,e[3]=r[3]*i+r[7]*n+r[11]*a+r[15]*o,e},At.transformQuat=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=r[0],s=r[1],l=r[2],h=r[3],u=h*i+s*a-l*n,c=h*n+l*i-o*a,d=h*a+o*n-s*i,f=-o*i-s*n-l*a;return e[0]=u*h+f*-o+c*-l-d*-s,e[1]=c*h+f*-s+d*-o-u*-l,e[2]=d*h+f*-l+u*-s-c*-o,e},At.forEach=function(){var e=At.create();return function(t,r,i,n,a,o){var s,l;for(r||(r=4),i||(i=0),l=n?Math.min(n*r+i,t.length):t.length,s=i;s.999999?(e[0]=0,e[1]=0,e[2]=0,e[3]=1,e):(Qe.cross(Lt,t,r),e[0]=Lt[0],e[1]=Lt[1],e[2]=Lt[2],e[3]=1+i,It.normalize(e,e))}),It.setAxes=(Nt=Dt.create(),function(e,t,r,i){return Nt[0]=r[0],Nt[3]=r[1],Nt[6]=r[2],Nt[1]=i[0],Nt[4]=i[1],Nt[7]=i[2],Nt[2]=-t[0],Nt[5]=-t[1],Nt[8]=-t[2],It.normalize(e,It.fromMat3(e,Nt))}),It.clone=Et.clone,It.fromValues=Et.fromValues,It.copy=Et.copy,It.set=Et.set,It.identity=function(e){return e[0]=0,e[1]=0,e[2]=0,e[3]=1,e},It.setAxisAngle=function(e,t,r){r*=.5;var i=Math.sin(r);return e[0]=i*t[0],e[1]=i*t[1],e[2]=i*t[2],e[3]=Math.cos(r),e},It.add=Et.add,It.multiply=function(e,t,r){var i=t[0],n=t[1],a=t[2],o=t[3],s=r[0],l=r[1],h=r[2],u=r[3];return e[0]=i*u+o*s+n*h-a*l,e[1]=n*u+o*l+a*s-i*h,e[2]=a*u+o*h+i*l-n*s,e[3]=o*u-i*s-n*l-a*h,e},It.mul=It.multiply,It.scale=Et.scale,It.rotateX=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),l=Math.cos(r);return e[0]=i*l+o*s,e[1]=n*l+a*s,e[2]=a*l-n*s,e[3]=o*l-i*s,e},It.rotateY=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),l=Math.cos(r);return e[0]=i*l-a*s,e[1]=n*l+o*s,e[2]=a*l+i*s,e[3]=o*l-n*s,e},It.rotateZ=function(e,t,r){r*=.5;var i=t[0],n=t[1],a=t[2],o=t[3],s=Math.sin(r),l=Math.cos(r);return e[0]=i*l+n*s,e[1]=n*l-i*s,e[2]=a*l+o*s,e[3]=o*l-a*s,e},It.calculateW=function(e,t){var r=t[0],i=t[1],n=t[2];return e[0]=r,e[1]=i,e[2]=n,e[3]=Math.sqrt(Math.abs(1-r*r-i*i-n*n)),e},It.dot=Et.dot,It.lerp=Et.lerp,It.slerp=function(e,t,r,i){var n,a,o,s,l,h=t[0],u=t[1],c=t[2],d=t[3],f=r[0],p=r[1],m=r[2],g=r[3];return(a=h*f+u*p+c*m+d*g)<0&&(a=-a,f=-f,p=-p,m=-m,g=-g),1-a>1e-6?(n=Math.acos(a),o=Math.sin(n),s=Math.sin((1-i)*n)/o,l=Math.sin(i*n)/o):(s=1-i,l=i),e[0]=s*h+l*f,e[1]=s*u+l*p,e[2]=s*c+l*m,e[3]=s*d+l*g,e},It.invert=function(e,t){var r=t[0],i=t[1],n=t[2],a=t[3],o=r*r+i*i+n*n+a*a,s=o?1/o:0;return e[0]=-r*s,e[1]=-i*s,e[2]=-n*s,e[3]=a*s,e},It.conjugate=function(e,t){return e[0]=-t[0],e[1]=-t[1],e[2]=-t[2],e[3]=t[3],e},It.length=Et.length,It.len=It.length,It.squaredLength=Et.squaredLength,It.sqrLen=It.squaredLength,It.normalize=Et.normalize,It.fromMat3=function(e,t){var r,i=t[0]+t[4]+t[8];if(i>0)r=Math.sqrt(i+1),e[3]=.5*r,r=.5/r,e[0]=(t[5]-t[7])*r,e[1]=(t[6]-t[2])*r,e[2]=(t[1]-t[3])*r;else{var n=0;t[4]>t[0]&&(n=1),t[8]>t[3*n+n]&&(n=2);var a=(n+1)%3,o=(n+2)%3;r=Math.sqrt(t[3*n+n]-t[3*a+a]-t[3*o+o]+1),e[n]=.5*r,r=.5/r,e[3]=(t[3*a+o]-t[3*o+a])*r,e[a]=(t[3*a+n]+t[3*n+a])*r,e[o]=(t[3*o+n]+t[3*n+o])*r}return e};const Rt=It;var Bt,Ft,zt,Gt,Ut=function(){this._axisX=new vt,this._axisY=new vt,this._axisZ=new vt,this.array=Ye.create(),this._dirty=!0};Ut.prototype={constructor:Ut,setArray:function(e){for(var t=0;t0){var t=this.min,r=this.max,i=t.array,n=r.array;tr(i,e[0]),tr(n,e[0]);for(var a=1;an[0]&&(n[0]=o[0]),o[1]>n[1]&&(n[1]=o[1]),o[2]>n[2]&&(n[2]=o[2])}t._dirty=!0,r._dirty=!0}},union:function(e){var t=this.min,r=this.max;return Qe.min(t.array,t.array,e.min.array),Qe.max(r.array,r.array,e.max.array),t._dirty=!0,r._dirty=!0,this},intersection:function(e){var t=this.min,r=this.max;return Qe.max(t.array,t.array,e.min.array),Qe.min(r.array,r.array,e.max.array),t._dirty=!0,r._dirty=!0,this},intersectBoundingBox:function(e){var t=this.min.array,r=this.max.array,i=e.min.array,n=e.max.array;return!(t[0]>n[0]||t[1]>n[1]||t[2]>n[2]||r[0]=n[0]&&r[1]>=n[1]&&r[2]>=n[2]},containPoint:function(e){var t=this.min.array,r=this.max.array,i=e.array;return t[0]<=i[0]&&t[1]<=i[1]&&t[2]<=i[2]&&r[0]>=i[0]&&r[1]>=i[1]&&r[2]>=i[2]},isFinite:function(){var e=this.min.array,t=this.max.array;return isFinite(e[0])&&isFinite(e[1])&&isFinite(e[2])&&isFinite(t[0])&&isFinite(t[1])&&isFinite(t[2])},applyTransform:function(e){this.transformFrom(this,e)},transformFrom:(Zt=Qe.create(),Yt=Qe.create(),Kt=Qe.create(),Qt=Qe.create(),Jt=Qe.create(),$t=Qe.create(),function(e,t){var r=e.min.array,i=e.max.array,n=t.array;return Zt[0]=n[0]*r[0],Zt[1]=n[1]*r[0],Zt[2]=n[2]*r[0],Yt[0]=n[0]*i[0],Yt[1]=n[1]*i[0],Yt[2]=n[2]*i[0],Kt[0]=n[4]*r[1],Kt[1]=n[5]*r[1],Kt[2]=n[6]*r[1],Qt[0]=n[4]*i[1],Qt[1]=n[5]*i[1],Qt[2]=n[6]*i[1],Jt[0]=n[8]*r[2],Jt[1]=n[9]*r[2],Jt[2]=n[10]*r[2],$t[0]=n[8]*i[2],$t[1]=n[9]*i[2],$t[2]=n[10]*i[2],r=this.min.array,i=this.max.array,r[0]=Math.min(Zt[0],Yt[0])+Math.min(Kt[0],Qt[0])+Math.min(Jt[0],$t[0])+n[12],r[1]=Math.min(Zt[1],Yt[1])+Math.min(Kt[1],Qt[1])+Math.min(Jt[1],$t[1])+n[13],r[2]=Math.min(Zt[2],Yt[2])+Math.min(Kt[2],Qt[2])+Math.min(Jt[2],$t[2])+n[14],i[0]=Math.max(Zt[0],Yt[0])+Math.max(Kt[0],Qt[0])+Math.max(Jt[0],$t[0])+n[12],i[1]=Math.max(Zt[1],Yt[1])+Math.max(Kt[1],Qt[1])+Math.max(Jt[1],$t[1])+n[13],i[2]=Math.max(Zt[2],Yt[2])+Math.max(Kt[2],Qt[2])+Math.max(Jt[2],$t[2])+n[14],this.min._dirty=!0,this.max._dirty=!0,this}),applyProjection:function(e){var t=this.min.array,r=this.max.array,i=e.array,n=t[0],a=t[1],o=t[2],s=r[0],l=r[1],h=t[2],u=r[0],c=r[1],d=r[2];if(1===i[15])t[0]=i[0]*n+i[12],t[1]=i[5]*a+i[13],r[2]=i[10]*o+i[14],r[0]=i[0]*u+i[12],r[1]=i[5]*c+i[13],t[2]=i[10]*d+i[14];else{var f=-1/o;t[0]=i[0]*n*f,t[1]=i[5]*a*f,r[2]=(i[10]*o+i[14])*f,f=-1/h,r[0]=i[0]*s*f,r[1]=i[5]*l*f,f=-1/d,t[2]=(i[10]*d+i[14])*f}return this.min._dirty=!0,this.max._dirty=!0,this},updateVertices:function(){var e=this.vertices;if(!e){e=[];for(var t=0;t<8;t++)e[t]=Qe.fromValues(0,0,0);this.vertices=e}var r=this.min.array,i=this.max.array;return er(e[0],r[0],r[1],r[2]),er(e[1],r[0],i[1],r[2]),er(e[2],i[0],r[1],r[2]),er(e[3],i[0],i[1],r[2]),er(e[4],r[0],r[1],i[2]),er(e[5],r[0],i[1],i[2]),er(e[6],i[0],r[1],i[2]),er(e[7],i[0],i[1],i[2]),this},copy:function(e){var t=this.min,r=this.max;return tr(t.array,e.min.array),tr(r.array,e.max.array),t._dirty=!0,r._dirty=!0,this},clone:function(){var e=new rr;return e.copy(this),e}};const ir=rr;var nr,ar,or=0;const sr=m.extend({name:"",position:null,rotation:null,scale:null,worldTransform:null,localTransform:null,autoUpdateLocalTransform:!0,_parent:null,_scene:null,_needsUpdateWorldTransform:!0,_inIterating:!1,__depth:0},(function(){this.name||(this.name=(this.type||"NODE")+"_"+or++),this.position||(this.position=new vt),this.rotation||(this.rotation=new qt),this.scale||(this.scale=new vt(1,1,1)),this.worldTransform=new Ht,this.localTransform=new Ht,this._children=[]}),{target:null,invisible:!1,isSkinnedMesh:function(){return!1},isRenderable:function(){return!1},setName:function(e){var t=this._scene;if(t){var r=t._nodeRepository;delete r[this.name],r[e]=this}this.name=e},add:function(e){var t=e._parent;if(t!==this){t&&t.remove(e),e._parent=this,this._children.push(e);var r=this._scene;r&&r!==e.scene&&e.traverse(this._addSelfToScene,this),e._needsUpdateWorldTransform=!0}},remove:function(e){var t=this._children,r=t.indexOf(e);r<0||(t.splice(r,1),e._parent=null,this._scene&&e.traverse(this._removeSelfFromScene,this))},removeAll:function(){for(var e=this._children,t=0;t0},beforeRender:function(e){},afterRender:function(e,t){},getBoundingBox:function(e,t){return t=sr.prototype.getBoundingBox.call(this,e,t),this.geometry&&this.geometry.boundingBox&&t.union(this.geometry.boundingBox),t},clone:(lr=["castShadow","receiveShadow","mode","culling","cullFace","frontFace","frustumCulling","renderOrder","lineWidth","ignorePicking","ignorePreZ","ignoreGBuffer"],function(){var e=sr.prototype.clone.call(this);e.geometry=this.geometry,e.material=this.material;for(var t=0;t=0&&g[p]>1e-4&&(Qe.transformMat4(T,m,d[_[p]]),Qe.scaleAndAdd(v,v,T,g[p]));S.set(f,v)}}for(f=0;f>t;return e+1},dispose:function(e){var t=this._cache;t.use(e.__uid__);var r=t.get("webgl_texture");r&&e.gl.deleteTexture(r),t.deleteContext(e.__uid__)},isRenderable:function(){},isPowerOfTwo:function(){}});Object.defineProperty(br.prototype,"width",{get:function(){return this._width},set:function(e){this._width=e}}),Object.defineProperty(br.prototype,"height",{get:function(){return this._height},set:function(e){this._height=e}}),br.BYTE=5120,br.UNSIGNED_BYTE=T,br.SHORT=5122,br.UNSIGNED_SHORT=5123,br.INT=5124,br.UNSIGNED_INT=5125,br.FLOAT=S,br.HALF_FLOAT=36193,br.UNSIGNED_INT_24_8_WEBGL=34042,br.DEPTH_COMPONENT=M,br.DEPTH_STENCIL=34041,br.ALPHA=6406,br.RGB=6407,br.RGBA=A,br.LUMINANCE=6409,br.LUMINANCE_ALPHA=6410,br.SRGB=35904,br.SRGB_ALPHA=35906,br.COMPRESSED_RGB_S3TC_DXT1_EXT=33776,br.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777,br.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778,br.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779,br.NEAREST=E,br.LINEAR=C,br.NEAREST_MIPMAP_NEAREST=D,br.LINEAR_MIPMAP_NEAREST=L,br.NEAREST_MIPMAP_LINEAR=P,br.LINEAR_MIPMAP_LINEAR=O,br.REPEAT=N,br.CLAMP_TO_EDGE=I,br.MIRRORED_REPEAT=33648;const wr=br;var Tr=ur.extend({skeleton:null,joints:null},(function(){this.joints||(this.joints=[])}),{offsetMatrix:null,isInstancedMesh:function(){return!1},isSkinnedMesh:function(){return!!(this.skeleton&&this.joints&&this.joints.length>0)},clone:function(){var e=ur.prototype.clone.call(this);return e.skeleton=this.skeleton,this.joints&&(e.joints=this.joints.slice()),e}});Tr.POINTS=0,Tr.LINES=1,Tr.LINE_LOOP=2,Tr.LINE_STRIP=3,Tr.TRIANGLES=4,Tr.TRIANGLE_STRIP=5,Tr.TRIANGLE_FAN=6,Tr.BACK=x,Tr.FRONT=y,Tr.FRONT_AND_BACK=1032,Tr.CW=b,Tr.CCW=w;const Sr=Tr;const Mr={isPowerOfTwo:function(e){return 0==(e&e-1)},nextPowerOfTwo:function(e){return e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e},nearestPowerOfTwo:function(e){return Math.pow(2,Math.round(Math.log(e)/Math.LN2))}};var Ar=Mr.isPowerOfTwo;function Er(e){return Math.pow(2,Math.round(Math.log(e)/Math.LN2))}var Cr=wr.extend((function(){return{image:null,pixels:null,mipmaps:[],convertToPOT:!1}}),{textureType:"texture2D",update:function(e){var t=e.gl;t.bindTexture(t.TEXTURE_2D,this._cache.get("webgl_texture")),this.updateCommon(e);var r=this.format,i=this.type,n=!(!this.convertToPOT||this.mipmaps.length||!this.image||this.wrapS!==wr.REPEAT&&this.wrapT!==wr.REPEAT||!this.NPOT);t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,n?this.wrapS:this.getAvailableWrapS()),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,n?this.wrapT:this.getAvailableWrapT()),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,n?this.magFilter:this.getAvailableMagFilter()),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,n?this.minFilter:this.getAvailableMinFilter());var a=e.getGLExtension("EXT_texture_filter_anisotropic");if(a&&this.anisotropic>1&&t.texParameterf(t.TEXTURE_2D,a.TEXTURE_MAX_ANISOTROPY_EXT,this.anisotropic),36193===i&&(e.getGLExtension("OES_texture_half_float")||(i=S)),this.mipmaps.length)for(var o=this.width,s=this.height,l=0;l=wr.COMPRESSED_RGB_S3TC_DXT1_EXT?e.compressedTexImage2D(e.TEXTURE_2D,r,a,i,n,0,t.pixels):e.texImage2D(e.TEXTURE_2D,r,a,i,n,0,a,o,t.pixels)},generateMipmap:function(e){var t=e.gl;this.useMipmap&&!this.NPOT&&(t.bindTexture(t.TEXTURE_2D,this._cache.get("webgl_texture")),t.generateMipmap(t.TEXTURE_2D))},isPowerOfTwo:function(){return Ar(this.width)&&Ar(this.height)},isRenderable:function(){return this.image?this.image.width>0&&this.image.height>0:!(!this.width||!this.height)},bind:function(e){e.gl.bindTexture(e.gl.TEXTURE_2D,this.getWebGLTexture(e))},unbind:function(e){e.gl.bindTexture(e.gl.TEXTURE_2D,null)},load:function(e,t){var r=U.createImage();t&&(r.crossOrigin=t);var i=this;return r.onload=function(){i.dirty(),i.trigger("success",i)},r.onerror=function(){i.trigger("error",i)},r.src=e,this.image=r,this}});Object.defineProperty(Cr.prototype,"width",{get:function(){return this.image?this.image.width:this._width},set:function(e){this.image?console.warn("Texture from image can't set width"):(this._width!==e&&this.dirty(),this._width=e)}}),Object.defineProperty(Cr.prototype,"height",{get:function(){return this.image?this.image.height:this._height},set:function(e){this.image?console.warn("Texture from image can't set height"):(this._height!==e&&this.dirty(),this._height=e)}});const Dr=Cr;function Lr(e){return{byte:U.Int8Array,ubyte:U.Uint8Array,short:U.Int16Array,ushort:U.Uint16Array}[e]||U.Float32Array}function Pr(e){return"attr_"+e}function Or(e,t,r,i){switch(this.name=e,this.type=t,this.size=r,this.semantic=i||"",this.value=null,r){case 1:this.get=function(e){return this.value[e]},this.set=function(e,t){this.value[e]=t},this.copy=function(e,t){this.value[e]=this.value[e]};break;case 2:this.get=function(e,t){var r=this.value;return t[0]=r[2*e],t[1]=r[2*e+1],t},this.set=function(e,t){var r=this.value;r[2*e]=t[0],r[2*e+1]=t[1]},this.copy=function(e,t){var r=this.value;t*=2,r[e*=2]=r[t],r[e+1]=r[t+1]};break;case 3:this.get=function(e,t){var r=3*e,i=this.value;return t[0]=i[r],t[1]=i[r+1],t[2]=i[r+2],t},this.set=function(e,t){var r=3*e,i=this.value;i[r]=t[0],i[r+1]=t[1],i[r+2]=t[2]},this.copy=function(e,t){var r=this.value;t*=3,r[e*=3]=r[t],r[e+1]=r[t+1],r[e+2]=r[t+2]};break;case 4:this.get=function(e,t){var r=this.value,i=4*e;return t[0]=r[i],t[1]=r[i+1],t[2]=r[i+2],t[3]=r[i+3],t},this.set=function(e,t){var r=this.value,i=4*e;r[i]=t[0],r[i+1]=t[1],r[i+2]=t[2],r[i+3]=t[3]},this.copy=function(e,t){var r=this.value;t*=4,r[e*=4]=r[t],r[e+1]=r[t+1],r[e+2]=r[t+2],r[e+3]=r[t+3]}}}function Nr(e,t,r,i,n){this.name=e,this.type=t,this.buffer=r,this.size=i,this.semantic=n,this.symbol="",this.needsRemove=!1}function Ir(e){this.buffer=e,this.count=0}Or.prototype.init=function(e){if(!this.value||this.value.length!==e*this.size){var t=Lr(this.type);this.value=new t(e*this.size)}},Or.prototype.fromArray=function(e){var t,r=Lr(this.type);if(e[0]&&e[0].length){var i=0,n=this.size;t=new r(e.length*n);for(var a=0;a=0){t||(t=[]);var r=this.indices;return t[0]=r[3*e],t[1]=r[3*e+1],t[2]=r[3*e+2],t}},setTriangleIndices:function(e,t){var r=this.indices;r[3*e]=t[0],r[3*e+1]=t[1],r[3*e+2]=t[2]},isUseIndices:function(){return!!this.indices},initIndicesFromArray:function(e){var t,r=this.vertexCount>65535?U.Uint32Array:U.Uint16Array;if(e[0]&&e[0].length){var i=0;t=new r(3*e.length);for(var n=0;n=0&&(t.splice(r,1),delete this.attributes[e],!0)},getAttribute:function(e){return this.attributes[e]},getEnabledAttributes:function(){var e=this._enabledAttributes,t=this._attributeList;if(e)return e;for(var r=[],i=this.vertexCount,n=0;na[0]&&(a[0]=s),l>a[1]&&(a[1]=l),h>a[2]&&(a[2]=h)}r._dirty=!0,i._dirty=!0}},generateVertexNormals:function(){if(this.vertexCount){var e=this.indices,t=this.attributes,r=t.position.value,i=t.normal.value;if(i&&i.length===r.length)for(var n=0;n65535&&(this.indices=new U.Uint32Array(this.indices));for(var e=this.attributes,t=this.indices,r=this.getEnabledAttributes(),i={},n=0;nthis.distance,n=1;n<8;n++)if(Qe.dot(t[n].array,r)>this.distance!=i)return!0},intersectLine:(Qr=Qe.create(),function(e,t,r){var i=this.distanceToPoint(e),n=this.distanceToPoint(t);if(i>0&&n>0||i<0&&n<0)return null;var a=this.normal.array,o=this.distance,s=e.array;Qe.sub(Qr,t.array,e.array),Qe.normalize(Qr,Qr);var l=Qe.dot(a,Qr);if(0===l)return null;r||(r=new vt);var h=(Qe.dot(a,s)-o)/l;return Qe.scaleAndAdd(r.array,s,Qr,-h),r._dirty=!0,r}),applyTransform:(Zr=Ye.create(),Yr=Et.create(),Kr=Et.create(),Kr[3]=1,function(e){e=e.array,Qe.scale(Kr,this.normal.array,this.distance),Et.transformMat4(Kr,Kr,e),this.distance=Qe.dot(Kr,this.normal.array),Ye.invert(Zr,e),Ye.transpose(Zr,Zr),Yr[3]=0,Qe.copy(Yr,this.normal.array),Et.transformMat4(Yr,Yr,Zr),Qe.copy(this.normal.array,Yr)}),copy:function(e){Qe.copy(this.normal.array,e.normal.array),this.normal._dirty=!0,this.distance=e.distance},clone:function(){var e=new Jr;return e.copy(this),e}};const $r=Jr;var ei,ti=Qe.set,ri=Qe.copy,ii=Qe.transformMat4,ni=Math.min,ai=Math.max,oi=function(){this.planes=[];for(var e=0;e<6;e++)this.planes.push(new $r);for(this.boundingBox=new ir,this.vertices=[],e=0;e<8;e++)this.vertices[e]=Qe.fromValues(0,0,0)};oi.prototype={setFromProjection:function(e){var t=this.planes,r=e.array,i=r[0],n=r[1],a=r[2],o=r[3],s=r[4],l=r[5],h=r[6],u=r[7],c=r[8],d=r[9],f=r[10],p=r[11],m=r[12],g=r[13],_=r[14],v=r[15];ti(t[0].normal.array,o-i,u-s,p-c),t[0].distance=-(v-m),t[0].normalize(),ti(t[1].normal.array,o+i,u+s,p+c),t[1].distance=-(v+m),t[1].normalize(),ti(t[2].normal.array,o+n,u+l,p+d),t[2].distance=-(v+g),t[2].normalize(),ti(t[3].normal.array,o-n,u-l,p-d),t[3].distance=-(v-g),t[3].normalize(),ti(t[4].normal.array,o-a,u-h,p-f),t[4].distance=-(v-_),t[4].normalize(),ti(t[5].normal.array,o+a,u+h,p+f),t[5].distance=-(v+_),t[5].normalize();var y=this.boundingBox,x=this.vertices;if(0===v){var b=l/i,w=-_/(f-1),T=-_/(f+1),S=-T/l,M=-w/l;y.min.set(-S*b,-S,T),y.max.set(S*b,S,w),ti(x[0],-S*b,-S,T),ti(x[1],-S*b,S,T),ti(x[2],S*b,-S,T),ti(x[3],S*b,S,T),ti(x[4],-M*b,-M,w),ti(x[5],-M*b,M,w),ti(x[6],M*b,-M,w),ti(x[7],M*b,M,w)}else{var A=(-1-m)/i,E=(1-m)/i,C=(1-g)/l,D=(-1-g)/l,L=(-1-_)/f,P=(1-_)/f;y.min.set(Math.min(A,E),Math.min(D,C),Math.min(P,L)),y.max.set(Math.max(E,A),Math.max(C,D),Math.max(L,P));var O=y.min.array,N=y.max.array;ti(x[0],O[0],O[1],O[2]),ti(x[1],O[0],N[1],O[2]),ti(x[2],N[0],O[1],O[2]),ti(x[3],N[0],N[1],O[2]),ti(x[4],O[0],O[1],N[2]),ti(x[5],O[0],N[1],N[2]),ti(x[6],N[0],O[1],N[2]),ti(x[7],N[0],N[1],N[2])}},getTransformedBoundingBox:(ei=Qe.create(),function(e,t){var r=this.vertices,i=t.array,n=e.min,a=e.max,o=n.array,s=a.array,l=r[0];ii(ei,l,i),ri(o,ei),ri(s,ei);for(var h=1;h<8;h++)l=r[h],ii(ei,l,i),o[0]=ni(ei[0],o[0]),o[1]=ni(ei[1],o[1]),o[2]=ni(ei[2],o[2]),s[0]=ai(ei[0],s[0]),s[1]=ai(ei[1],s[1]),s[2]=ai(ei[2],s[2]);return n._dirty=!0,a._dirty=!0,e})};const si=oi;var li;const hi=sr.extend((function(){return{projectionMatrix:new Ht,invProjectionMatrix:new Ht,viewMatrix:new Ht,frustum:new si}}),(function(){this.update(!0)}),{update:function(e){sr.prototype.update.call(this,e),Ht.invert(this.viewMatrix,this.worldTransform),this.updateProjectionMatrix(),Ht.invert(this.invProjectionMatrix,this.projectionMatrix),this.frustum.setFromProjection(this.projectionMatrix)},setViewMatrix:function(e){Ht.copy(this.viewMatrix,e),Ht.invert(this.worldTransform,e),this.decomposeWorldTransform()},decomposeProjectionMatrix:function(){},setProjectionMatrix:function(e){Ht.copy(this.projectionMatrix,e),Ht.invert(this.invProjectionMatrix,e),this.decomposeProjectionMatrix()},updateProjectionMatrix:function(){},castRay:(li=Et.create(),function(e,t){var r=void 0!==t?t:new Mt,i=e.array[0],n=e.array[1];return Et.set(li,i,n,-1,1),Et.transformMat4(li,li,this.invProjectionMatrix.array),Et.transformMat4(li,li,this.worldTransform.array),Qe.scale(r.origin.array,li,1/li[3]),Et.set(li,i,n,1,1),Et.transformMat4(li,li,this.invProjectionMatrix.array),Et.transformMat4(li,li,this.worldTransform.array),Qe.scale(li,li,1/li[3]),Qe.sub(r.direction.array,li,r.origin.array),Qe.normalize(r.direction.array,r.direction.array),r.direction._dirty=!0,r.origin._dirty=!0,r})});var ui,ci,di=Ye.create(),fi=Ye.create(),pi={};function mi(e){var t=[],r=Object.keys(e);r.sort();for(var i=0;i0&&console.warn("Found multiple camera in one scene. Use the fist one."),this._cameraList.push(e)):e instanceof qr&&this.lights.push(e),e.name&&(this._nodeRepository[e.name]=e)},removeFromScene:function(e){var t;e instanceof hi?(t=this._cameraList.indexOf(e))>=0&&this._cameraList.splice(t,1):e instanceof qr&&(t=this.lights.indexOf(e))>=0&&this.lights.splice(t,1),e.name&&delete this._nodeRepository[e.name]},getNode:function(e){return this._nodeRepository[e]},setMainCamera:function(e){var t=this._cameraList.indexOf(e);t>=0&&this._cameraList.splice(t,1),this._cameraList.unshift(e)},getMainCamera:function(){return this._cameraList[0]},getLights:function(){return this.lights},updateLights:function(){var e=this.lights;this._previousLightNumber=this._lightNumber;for(var t={},r=0;r0&&this._doUpdateRenderList(o,t,r,i,n)}},isFrustumCulled:(ui=new ir,ci=new Ht,function(e,t,r){var i=e.boundingBox;if(i||(i=e.skeleton&&e.skeleton.boundingBox?e.skeleton.boundingBox:e.geometry.boundingBox),!i)return!1;if(ci.array=r,ui.transformFrom(i,ci),e.castShadow&&this.viewBoundingBoxLastFrame.union(ui),e.frustumCulling){if(!ui.intersectBoundingBox(t.frustum.boundingBox))return!0;ci.array=t.projectionMatrix.array,ui.max.array[2]>0&&ui.min.array[2]<0&&(ui.max.array[2]=-1e-20),ui.applyProjection(ci);var n=ui.min.array,a=ui.max.array;if(a[0]<-1||n[0]>1||a[1]<-1||n[1]>1||a[2]<-1||n[2]>1)return!0}return!1}),_updateLightUniforms:function(){var e=this.lights;e.sort(_i);var t=this._lightUniforms;for(var r in t)for(var i in t[r])t[r][i].value.length=0;for(var n=0;n=this._maxSize&&a>0){var s=r.head;r.remove(s),delete i[s.key],n=s.value,this._lastRemovedEntry=s}o?o.value=t:o=new yi(t),o.key=e,r.insertEntry(o),i[e]=o}return n},e.prototype.get=function(e){var t=this._map[e],r=this._list;if(null!=t)return t!==r.tail&&(r.remove(t),r.insertEntry(t)),t.value},e.prototype.clear=function(){this._list.clear(),this._map={}},e.prototype.len=function(){return this._list.len()},e}();var wi=Mr.isPowerOfTwo,Ti=["px","nx","py","ny","pz","nz"],Si=wr.extend((function(){return{image:{px:null,nx:null,py:null,ny:null,pz:null,nz:null},pixels:{px:null,nx:null,py:null,ny:null,pz:null,nz:null},mipmaps:[]}}),{textureType:"textureCube",update:function(e){var t=e.gl;t.bindTexture(t.TEXTURE_CUBE_MAP,this._cache.get("webgl_texture")),this.updateCommon(e);var r=this.format,i=this.type;t.texParameteri(t.TEXTURE_CUBE_MAP,t.TEXTURE_WRAP_S,this.getAvailableWrapS()),t.texParameteri(t.TEXTURE_CUBE_MAP,t.TEXTURE_WRAP_T,this.getAvailableWrapT()),t.texParameteri(t.TEXTURE_CUBE_MAP,t.TEXTURE_MAG_FILTER,this.getAvailableMagFilter()),t.texParameteri(t.TEXTURE_CUBE_MAP,t.TEXTURE_MIN_FILTER,this.getAvailableMinFilter());var n=e.getGLExtension("EXT_texture_filter_anisotropic");if(n&&this.anisotropic>1&&t.texParameterf(t.TEXTURE_CUBE_MAP,n.TEXTURE_MAX_ANISOTROPY_EXT,this.anisotropic),36193===i&&(e.getGLExtension("OES_texture_half_float")||(i=S)),this.mipmaps.length)for(var a=this.width,o=this.height,s=0;s0&&e.height>0}Object.defineProperty(Si.prototype,"width",{get:function(){return this.image&&this.image.px?this.image.px.width:this._width},set:function(e){this.image&&this.image.px?console.warn("Texture from image can't set width"):(this._width!==e&&this.dirty(),this._width=e)}}),Object.defineProperty(Si.prototype,"height",{get:function(){return this.image&&this.image.px?this.image.px.height:this._height},set:function(e){this.image&&this.image.px?console.warn("Texture from image can't set height"):(this._height!==e&&this.dirty(),this._height=e)}});const Ai=Si,Ei=hi.extend({fov:50,aspect:1,near:.1,far:2e3},{updateProjectionMatrix:function(){var e=this.fov/180*Math.PI;this.projectionMatrix.perspective(e,this.aspect,this.near,this.far)},decomposeProjectionMatrix:function(){var e=this.projectionMatrix.array,t=2*Math.atan(1/e[5]);this.fov=t/Math.PI*180,this.aspect=e[5]/e[0],this.near=e[14]/(e[10]-1),this.far=e[14]/(e[10]+1)},clone:function(){var e=hi.prototype.clone.call(this);return e.fov=this.fov,e.aspect=this.aspect,e.near=this.near,e.far=this.far,e}});var Ci="framebuffer",Di="renderbuffer",Li="renderbuffer_width",Pi="renderbuffer_height",Oi="renderbuffer_attached",Ni="depthtexture_attached",Ii=36160,Ri=36161,Bi=36096,Fi=m.extend({depthBuffer:!0,viewport:null,_width:0,_height:0,_textures:null,_boundRenderer:null},(function(){this._cache=new xr,this._textures={}}),{getTextureWidth:function(){return this._width},getTextureHeight:function(){return this._height},bind:function(e){if(e.__currentFrameBuffer){if(e.__currentFrameBuffer===this)return;console.warn("Renderer already bound with another framebuffer. Unbind it first")}e.__currentFrameBuffer=this;var t=e.gl;t.bindFramebuffer(Ii,this._getFrameBufferGL(e)),this._boundRenderer=e;var r=this._cache;r.put("viewport",e.viewport);var i,n,a=!1;for(var o in this._textures){a=!0;var s=this._textures[o];s&&(i=s.texture.width,n=s.texture.height,this._doAttach(e,s.texture,o,s.target))}this._width=i,this._height=n,!a&&this.depthBuffer&&console.error("Must attach texture before bind, or renderbuffer may have incorrect width and height."),this.viewport?e.setViewport(this.viewport):e.setViewport(0,0,i,n,1);var l=r.get("attached_textures");if(l)for(var o in l)if(!this._textures[o]){var h=l[o];this._doDetach(t,o,h)}if(!r.get(Ni)&&this.depthBuffer){r.miss(Di)&&r.put(Di,t.createRenderbuffer());var u=r.get(Di);i===r.get(Li)&&n===r.get(Pi)||(t.bindRenderbuffer(Ri,u),t.renderbufferStorage(Ri,t.DEPTH_COMPONENT16,i,n),r.put(Li,i),r.put(Pi,n),t.bindRenderbuffer(Ri,null)),r.get(Oi)||(t.framebufferRenderbuffer(Ii,Bi,Ri,u),r.put(Oi,!0))}},unbind:function(e){e.__currentFrameBuffer=null,e.gl.bindFramebuffer(Ii,null),this._boundRenderer=null,this._cache.use(e.__uid__);var t=this._cache.get("viewport");t&&e.setViewport(t),this.updateMipmap(e)},updateMipmap:function(e){var t=e.gl;for(var r in this._textures){var i=this._textures[r];if(i){var n=i.texture;if(!n.NPOT&&n.useMipmap&&n.minFilter===wr.LINEAR_MIPMAP_LINEAR){var a="textureCube"===n.textureType?34067:3553;t.bindTexture(a,n.getWebGLTexture(e)),t.generateMipmap(a),t.bindTexture(a,null)}}}},checkStatus:function(e){return e.checkFramebufferStatus(Ii)},_getFrameBufferGL:function(e){var t=this._cache;return t.use(e.__uid__),t.miss(Ci)&&t.put(Ci,e.gl.createFramebuffer()),t.get(Ci)},attach:function(e,t,r){if(!e.width)throw new Error("The texture attached to color buffer is not a valid.");t=t||36064,r=r||3553;var i,n=this._boundRenderer;if(n&&n.gl){var a=this._cache;a.use(n.__uid__),i=a.get("attached_textures")}var o=this._textures[t];if(!o||o.target!==r||o.texture!==e||!i||null==i[t]){var s=!0;n&&(s=this._doAttach(n,e,t,r),this.viewport||n.setViewport(0,0,e.width,e.height,1)),s&&(this._textures[t]=this._textures[t]||{},this._textures[t].texture=e,this._textures[t].target=r)}},_doAttach:function(e,t,r,i){var n=e.gl,a=t.getWebGLTexture(e),o=this._cache.get("attached_textures");if(o&&o[r]){var s=o[r];if(s.texture===t&&s.target===i)return}var l=!0;if(((r=+r)===Bi||r===R)&&(e.getGLExtension("WEBGL_depth_texture")||(console.error("Depth texture is not supported by the browser"),l=!1),t.format!==M&&34041!==t.format&&(console.error("The texture attached to depth buffer is not a valid."),l=!1),l)){var h=this._cache.get(Di);h&&(n.framebufferRenderbuffer(Ii,Bi,Ri,null),n.deleteRenderbuffer(h),this._cache.put(Di,!1)),this._cache.put(Oi,!1),this._cache.put(Ni,!0)}return n.framebufferTexture2D(Ii,r,i,a,0),o||(o={},this._cache.put("attached_textures",o)),o[r]=o[r]||{},o[r].texture=t,o[r].target=i,l},_doDetach:function(e,t,r){e.framebufferTexture2D(Ii,t,r,null,0);var i=this._cache.get("attached_textures");i&&i[t]&&(i[t]=null),t!==Bi&&t!==R||this._cache.put(Ni,!1)},detach:function(e,t){this._textures[e]=null,this._boundRenderer&&(this._cache.use(this._boundRenderer.__uid__),this._doDetach(this._boundRenderer.gl,e,t))},dispose:function(e){var t=e.gl,r=this._cache;r.use(e.__uid__);var i=r.get(Di);i&&t.deleteRenderbuffer(i);var n=r.get(Ci);n&&t.deleteFramebuffer(n),r.deleteContext(e.__uid__),this._textures={}}});Fi.DEPTH_ATTACHMENT=Bi,Fi.COLOR_ATTACHMENT0=36064,Fi.STENCIL_ATTACHMENT=36128,Fi.DEPTH_STENCIL_ATTACHMENT=R;const zi=Fi;var Gi=["px","nx","py","ny","pz","nz"];const Ui=m.extend((function(){var e={position:new vt,far:1e3,near:.1,texture:null,shadowMapPass:null},t=e._cameras={px:new Ei({fov:90}),nx:new Ei({fov:90}),py:new Ei({fov:90}),ny:new Ei({fov:90}),pz:new Ei({fov:90}),nz:new Ei({fov:90})};return t.px.lookAt(vt.POSITIVE_X,vt.NEGATIVE_Y),t.nx.lookAt(vt.NEGATIVE_X,vt.NEGATIVE_Y),t.py.lookAt(vt.POSITIVE_Y,vt.POSITIVE_Z),t.ny.lookAt(vt.NEGATIVE_Y,vt.NEGATIVE_Z),t.pz.lookAt(vt.POSITIVE_Z,vt.NEGATIVE_Y),t.nz.lookAt(vt.NEGATIVE_Z,vt.NEGATIVE_Y),e._frameBuffer=new zi,e}),{getCamera:function(e){return this._cameras[e]},render:function(e,t,r){var i=e.gl;r||t.update();for(var n=this.texture.width,a=2*Math.atan(n/(n-.5))/Math.PI*180,o=0;o<6;o++){var s=Gi[o],l=this._cameras[s];if(vt.copy(l.position,this.position),l.far=this.far,l.near=this.near,l.fov=a,this.shadowMapPass){l.update();var h=t.getBoundingBox();h.applyTransform(l.viewMatrix),t.viewBoundingBoxLastFrame.copy(h),this.shadowMapPass.render(e,t,l,!0)}this._frameBuffer.attach(this.texture,i.COLOR_ATTACHMENT0,i.TEXTURE_CUBE_MAP_POSITIVE_X+o),this._frameBuffer.bind(e),e.render(t,l,!0),this._frameBuffer.unbind(e)}},dispose:function(e){this._frameBuffer.dispose(e)}}),ki=Vr.extend({dynamic:!1,widthSegments:1,heightSegments:1},(function(){this.build()}),{build:function(){for(var e=this.heightSegments,t=this.widthSegments,r=this.attributes,i=[],n=[],a=[],o=[],s=0;s<=e;s++)for(var l=s/e,h=0;h<=t;h++){var u=h/t;if(i.push([2*u-1,2*l-1,0]),n&&n.push([u,l]),a&&a.push([0,0,1]),h0?this.material.define("fragment","LOD"):this.material.undefine("fragment","LOD"),e.renderPass([this],r)}}),Xi=ji;function qi(e){return e.charCodeAt(0)+(e.charCodeAt(1)<<8)+(e.charCodeAt(2)<<16)+(e.charCodeAt(3)<<24)}var Zi=qi("DXT1"),Yi=qi("DXT3"),Ki=qi("DXT5");const Qi=function(e,t){var r=new Int32Array(e,0,31);if(542327876!==r[0])return null;if(4&!r(20))return null;var i,n,a=r(21),o=r[4],s=r[3],l=512&r[28],h=131072&r[2];switch(a){case Zi:i=8,n=wr.COMPRESSED_RGB_S3TC_DXT1_EXT;break;case Yi:i=16,n=wr.COMPRESSED_RGBA_S3TC_DXT3_EXT;break;case Ki:i=16,n=wr.COMPRESSED_RGBA_S3TC_DXT5_EXT;break;default:return null}var u=r[1]+4,c=l?6:1,d=1;h&&(d=Math.max(1,r[7]));for(var f=[],p=0;p0){var n=Math.pow(2,e[3]-128-8+i);t[r+0]=e[0]*n,t[r+1]=e[1]*n,t[r+2]=e[2]*n}else t[r+0]=0,t[r+1]=0,t[r+2]=0;return t[r+3]=1,t}function en(e,t,r,i){for(var n,a,o=0,s=0,l=i;l>0;)if(e[s][0]=t[r++],e[s][1]=t[r++],e[s][2]=t[r++],e[s][3]=t[r++],1===e[s][0]&&1===e[s][1]&&1===e[s][2]){for(var h=e[s][3]<>>0;h>0;h--)n=e[s-1],(a=e[s])[0]=n[0],a[1]=n[1],a[2]=n[2],a[3]=n[3],s++,l--;o+=8}else s++,l--,o=0;return r}function tn(e,t,r,i){if(i<8|i>32767)return en(e,t,r,i);if(2!=(n=t[r++]))return en(e,t,r-1,i);if(e[0][1]=t[r++],e[0][2]=t[r++],n=t[r++],(e[0][2]<<8>>>0|n)>>>0!==i)return null;for(var n=0;n<4;n++)for(var a=0;a128){o=(127&o)>>>0;for(var s=t[r++];o--;)e[a++][n]=s}else for(;o--;)e[a++][n]=t[r++]}return r}const rn=function(e,t,r){null==r&&(r=0);var i=new Uint8Array(e),n=i.length;if("#?"===function(e,t,r){for(var i="",n=0;n<2;n++)i+=Ji(e[n]);return i}(i)){for(var a=2;a=n)){a+=2;for(var o="";a20)return console.warn("Given image is not a height map"),e}var d,f,p,m;l%(4*i)==0?(d=o.data[l],p=o.data[l+4]):l%(4*i)==4*(i-1)?(d=o.data[l-4],p=o.data[l]):(d=o.data[l-4],p=o.data[l+4]),l<4*i?(f=o.data[l],m=o.data[l+4*i]):l>i*(n-1)*4?(f=o.data[l-4*i],m=o.data[l]):(f=o.data[l-4*i],m=o.data[l+4*i]),s.data[l]=d-p+127,s.data[l+1]=f-m+127,s.data[l+2]=255,s.data[l+3]=255}return a.putImageData(s,0,0),r},isHeightImage:function(e,t,r){if(!e||!e.width||!e.height)return!1;var i=document.createElement("canvas"),n=i.getContext("2d"),a=t||32;r=r||20,i.width=i.height=a,n.drawImage(e,0,0,a,a);for(var o=n.getImageData(0,0,a,a),s=0;sr)return!1}return!0},_fetchTexture:function(e,t,r){U.request.get({url:e,responseType:"arraybuffer",onload:t,onerror:r})},createChessboard:function(e,t,r,i){e=e||512,t=t||64,r=r||"black",i=i||"white";var n=Math.ceil(e/t),a=document.createElement("canvas");a.width=e,a.height=e;var o=a.getContext("2d");o.fillStyle=i,o.fillRect(0,0,e,e),o.fillStyle=r;for(var s=0;s=0||(on.forEach((function(t){e.on(t,this[sn(t)],this)}),this),this._meshes.push(e))},detachFromMesh:function(e){var t=this._meshes.indexOf(e);t>=0&&this._meshes.splice(t,1),on.forEach((function(t){e.off(t,this[sn(t)])}),this)},dispose:function(){this._meshes.forEach((function(e){this.detachFromMesh(e)}),this)}};const hn=ln,un=hi.extend({left:-1,right:1,near:-1,far:1,top:1,bottom:-1},{updateProjectionMatrix:function(){this.projectionMatrix.ortho(this.left,this.right,this.bottom,this.top,this.near,this.far)},decomposeProjectionMatrix:function(){var e=this.projectionMatrix.array;this.left=(-1-e[12])/e[0],this.right=(1-e[12])/e[0],this.top=(1-e[13])/e[5],this.bottom=(-1-e[13])/e[5],this.near=-(-1-e[14])/e[10],this.far=-(1-e[14])/e[10]},clone:function(){var e=hi.prototype.clone.call(this);return e.left=this.left,e.right=this.right,e.near=this.near,e.far=this.far,e.top=this.top,e.bottom=this.bottom,e}});Xe.import("\n@export clay.compositor.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nvarying vec2 v_Texcoord;\nvoid main()\n{\n v_Texcoord = texcoord;\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end");var cn=new ki,dn=new Sr({geometry:cn,frustumCulling:!1}),fn=new un;const pn=m.extend((function(){return{fragment:"",outputs:null,material:null,blendWithPrevious:!1,clearColor:!1,clearDepth:!0}}),(function(){var e=new Xe(Xe.source("clay.compositor.vertex"),this.fragment),t=new le({shader:e});t.enableTexturesAll(),this.material=t}),{setUniform:function(e,t){this.material.setUniform(e,t)},getUniform:function(e){var t=this.material.uniforms[e];if(t)return t.value},attachOutput:function(e,t){this.outputs||(this.outputs={}),t=t||36064,this.outputs[t]=e},detachOutput:function(e){for(var t in this.outputs)this.outputs[t]===e&&(this.outputs[t]=null)},bind:function(e,t){if(this.outputs)for(var r in this.outputs){var i=this.outputs[r];i&&t.attach(i,r)}t&&t.bind(e)},unbind:function(e,t){t.unbind(e)},render:function(e,t){var r=e.gl;if(t){this.bind(e,t);var i=e.getGLExtension("EXT_draw_buffers");if(i&&this.outputs){var n=[];for(var a in this.outputs)(a=+a)>=r.COLOR_ATTACHMENT0&&a<=r.COLOR_ATTACHMENT0+8&&n.push(a);i.drawBuffersEXT(n)}}this.trigger("beforerender",this,e);var o=this.clearDepth?r.DEPTH_BUFFER_BIT:0;if(r.depthMask(!0),this.clearColor){o|=r.COLOR_BUFFER_BIT,r.colorMask(!0,!0,!0,!0);var s=this.clearColor;Array.isArray(s)&&r.clearColor(s[0],s[1],s[2],s[3])}r.clear(o),this.blendWithPrevious?(r.enable(r.BLEND),this.material.transparent=!0):(r.disable(r.BLEND),this.material.transparent=!1),this.renderQuad(e),this.trigger("afterrender",this,e),t&&this.unbind(e,t)},renderQuad:function(e){dn.material=this.material,e.renderPass([dn],fn)},dispose:function(e){}});var mn={},gn=["px","nx","py","ny","pz","nz"];mn.prefilterEnvironmentMap=function(e,t,r,i,n){n&&i||(i=mn.generateNormalDistribution(),n=mn.integrateBRDF(e,i));var a=(r=r||{}).width||64,o=r.height||64,s=r.type||t.type,l=new Ai({width:a,height:o,type:s,flipY:!1,mipmaps:[]});l.isPowerOfTwo()||console.warn("Width and height must be power of two to enable mipmap.");var h=Math.min(a,o),u=Math.log(h)/Math.log(2)+1,c=new le({shader:new Xe({vertex:Xe.source("clay.skybox.vertex"),fragment:"#define SHADER_NAME prefilter\n#define SAMPLE_NUMBER 1024\n#define PI 3.14159265358979\nuniform mat4 viewInverse : VIEWINVERSE;\nuniform samplerCube environmentMap;\nuniform sampler2D normalDistribution;\nuniform float roughness : 0.5;\nvarying vec2 v_Texcoord;\nvarying vec3 v_WorldPosition;\n@import clay.util.rgbm\nvec3 importanceSampleNormal(float i, float roughness, vec3 N) {\n vec3 H = texture2D(normalDistribution, vec2(roughness, i)).rgb;\n vec3 upVector = abs(N.y) > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvoid main() {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(v_WorldPosition - eyePos);\n vec3 N = V;\n vec3 prefilteredColor = vec3(0.0);\n float totalWeight = 0.0;\n float fMaxSampleNumber = float(SAMPLE_NUMBER);\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fMaxSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(dot(N, L), 0.0, 1.0);\n if (NoL > 0.0) {\n prefilteredColor += decodeHDR(textureCube(environmentMap, L)).rgb * NoL;\n totalWeight += NoL;\n }\n }\n gl_FragColor = encodeHDR(vec4(prefilteredColor / totalWeight, 1.0));\n}\n"})});c.set("normalDistribution",i),r.encodeRGBM&&c.define("fragment","RGBM_ENCODE"),r.decodeRGBM&&c.define("fragment","RGBM_DECODE");var d,f=new vi;if("texture2D"===t.textureType){var p=new Ai({width:a,height:o,type:s===wr.FLOAT?wr.HALF_FLOAT:s});an.panoramaToCubeMap(e,t,p,{encodeRGBM:r.decodeRGBM}),t=p}(d=new ji({scene:f,material:c})).material.set("environmentMap",t);var m=new Ui({texture:l});r.encodeRGBM&&(s=l.type=wr.UNSIGNED_BYTE);for(var g=new Dr({width:a,height:o,type:s}),_=new zi({depthBuffer:!1}),v=U[s===wr.UNSIGNED_BYTE?"Uint8Array":"Float32Array"],y=0;y 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nfloat G_Smith(float roughness, float NoV, float NoL) {\n float k = roughness * roughness / 2.0;\n float G1V = NoV / (NoV * (1.0 - k) + k);\n float G1L = NoL / (NoL * (1.0 - k) + k);\n return G1L * G1V;\n}\nvoid main() {\n vec2 uv = gl_FragCoord.xy / viewportSize;\n float NoV = uv.x;\n float roughness = uv.y;\n vec3 V;\n V.x = sqrt(1.0 - NoV * NoV);\n V.y = 0.0;\n V.z = NoV;\n float A = 0.0;\n float B = 0.0;\n for (int i = 0; i < SAMPLE_NUMBER; i++) {\n vec3 H = importanceSampleNormal(float(i) / fSampleNumber, roughness, N);\n vec3 L = reflect(-V, H);\n float NoL = clamp(L.z, 0.0, 1.0);\n float NoH = clamp(H.z, 0.0, 1.0);\n float VoH = clamp(dot(V, H), 0.0, 1.0);\n if (NoL > 0.0) {\n float G = G_Smith(roughness, NoV, NoL);\n float G_Vis = G * VoH / (NoH * NoV);\n float Fc = pow(1.0 - VoH, 5.0);\n A += (1.0 - Fc) * G_Vis;\n B += Fc * G_Vis;\n }\n }\n gl_FragColor = vec4(vec2(A, B) / fSampleNumber, 0.0, 1.0);\n}\n"}),n=new Dr({width:512,height:256,type:wr.HALF_FLOAT,wrapS:wr.CLAMP_TO_EDGE,wrapT:wr.CLAMP_TO_EDGE,minFilter:wr.NEAREST,magFilter:wr.NEAREST,useMipmap:!1});return i.setUniform("normalDistribution",t),i.setUniform("viewportSize",[512,256]),i.attachOutput(n),i.render(e,r),r.dispose(e),n},mn.generateNormalDistribution=function(e,t){for(var r=new Dr({width:e=e||256,height:t=t||1024,type:wr.FLOAT,minFilter:wr.NEAREST,magFilter:wr.NEAREST,wrapS:wr.CLAMP_TO_EDGE,wrapT:wr.CLAMP_TO_EDGE,useMipmap:!1}),i=new Float32Array(t*e*4),n=[],a=0;a>>16)>>>0;h=(((16711935&(h=((252645135&(h=((858993459&(h=((1431655765&h)<<1|(2863311530&h)>>>1)>>>0))<<2|(3435973836&h)>>>2)>>>0))<<4|(4042322160&h)>>>4)>>>0))<<8|(4278255360&h)>>>8)>>>0)/4294967296;var u=Math.sqrt((1-h)/(1+(s*s-1)*h));n[l]=u}for(l=0;l65535?Uint32Array:Uint16Array,v=this.indices=new _(t*e*6),y=this.radius,x=this.phiStart,b=this.phiLength,w=this.thetaStart,T=this.thetaLength,S=[],M=[],A=0,E=1/(y=this.radius);for(d=0;d<=e;d++)for(c=0;c<=t;c++)h=c/t,u=d/e,o=-y*Math.cos(x+h*b)*Math.sin(w+u*T),s=y*Math.cos(w+u*T),l=y*Math.sin(x+h*b)*Math.sin(w+u*T),S[0]=o,S[1]=s,S[2]=l,M[0]=h,M[1]=u,r.set(A,S),i.set(A,M),S[0]*=E,S[1]*=E,S[2]*=E,n.set(A,S),A++;var C=t+1,D=0;for(d=0;d255?255:e}function Qn(e){return e<0?0:e>1?1:e}function Jn(e){var t=e;return t.length&&"%"===t.charAt(t.length-1)?Kn(parseFloat(t)/100*255):Kn(parseInt(t,10))}function $n(e){var t=e;return t.length&&"%"===t.charAt(t.length-1)?Qn(parseFloat(t)/100):Qn(parseFloat(t))}function ea(e,t,r){return r<0?r+=1:r>1&&(r-=1),6*r<1?e+(t-e)*r*6:2*r<1?t:3*r<2?e+(t-e)*(2/3-r)*6:e}function ta(e,t,r,i,n){return e[0]=t,e[1]=r,e[2]=i,e[3]=n,e}function ra(e,t){return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e}var ia=new bi(20),na=null;function aa(e,t){na&&ra(na,t),na=ia.put(e,na||t.slice())}function oa(e,t){if(e){t=t||[];var r=ia.get(e);if(r)return ra(t,r);var i=(e+="").replace(/ /g,"").toLowerCase();if(i in Yn)return ra(t,Yn[i]),aa(e,t),t;var n,a=i.length;if("#"===i.charAt(0))return 4===a||5===a?(n=parseInt(i.slice(1,4),16))>=0&&n<=4095?(ta(t,(3840&n)>>4|(3840&n)>>8,240&n|(240&n)>>4,15&n|(15&n)<<4,5===a?parseInt(i.slice(4),16)/15:1),aa(e,t),t):void ta(t,0,0,0,1):7===a||9===a?(n=parseInt(i.slice(1,7),16))>=0&&n<=16777215?(ta(t,(16711680&n)>>16,(65280&n)>>8,255&n,9===a?parseInt(i.slice(7),16)/255:1),aa(e,t),t):void ta(t,0,0,0,1):void 0;var o=i.indexOf("("),s=i.indexOf(")");if(-1!==o&&s+1===a){var l=i.substr(0,o),h=i.substr(o+1,s-(o+1)).split(","),u=1;switch(l){case"rgba":if(4!==h.length)return 3===h.length?ta(t,+h[0],+h[1],+h[2],1):ta(t,0,0,0,1);u=$n(h.pop());case"rgb":return 3!==h.length?void ta(t,0,0,0,1):(ta(t,Jn(h[0]),Jn(h[1]),Jn(h[2]),u),aa(e,t),t);case"hsla":return 4!==h.length?void ta(t,0,0,0,1):(h[3]=$n(h[3]),sa(h,t),aa(e,t),t);case"hsl":return 3!==h.length?void ta(t,0,0,0,1):(sa(h,t),aa(e,t),t);default:return}}ta(t,0,0,0,1)}}function sa(e,t){var r=(parseFloat(e[0])%360+360)%360/360,i=$n(e[1]),n=$n(e[2]),a=n<=.5?n*(i+1):n+i-n*i,o=2*n-a;return ta(t=t||[],Kn(255*ea(o,a,r+1/3)),Kn(255*ea(o,a,r)),Kn(255*ea(o,a,r-1/3)),1),4===e.length&&(t[3]=e[3]),t}var la=Object.prototype.toString,ha=Array.prototype,ua=ha.forEach,ca=ha.filter,da=ha.slice,fa=ha.map,pa=function(){}.constructor,ma=pa?pa.prototype:null;function ga(e,t){if(Object.assign)Object.assign(e,t);else for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e}function _a(e,t,r){if(e="prototype"in e?e.prototype:e,t="prototype"in t?t.prototype:t,Object.getOwnPropertyNames)for(var i=Object.getOwnPropertyNames(t),n=0;no)i.length=o;else for(var s=a;s=2&&this.interpolable},e.prototype.getAdditiveTrack=function(){return this._additiveTrack},e.prototype.addKeyframe=function(e,t){e>=this.maxTime?this.maxTime=e:this._needsSort=!0;var r=this.keyframes,i=r.length;if(this.interpolable)if(va(t)){var n=function(e){return va(e&&e[0])?2:1}(t);if(i>0&&this.arrDim!==n)return void(this.interpolable=!1);if(1===n&&"number"!=typeof t[0]||2===n&&"number"!=typeof t[0][0])return void(this.interpolable=!1);if(i>0){var a=r[i-1];this._isAllValueEqual&&(1===n&&Na(t,a.value)||(this._isAllValueEqual=!1))}this.arrDim=n}else{if(this.arrDim>0)return void(this.interpolable=!1);if("string"==typeof t){var o=oa(t);o?(t=o,this.isValueColor=!0):this.interpolable=!1}else if("number"!=typeof t||isNaN(t))return void(this.interpolable=!1);this._isAllValueEqual&&i>0&&(a=r[i-1],(this.isValueColor&&!Na(a.value,t)||a.value!==t)&&(this._isAllValueEqual=!1))}var s={time:e,value:t,percent:0};return this.keyframes.push(s),s},e.prototype.prepare=function(e){var t=this.keyframes;this._needsSort&&t.sort((function(e,t){return e.time-t.time}));for(var r=this.arrDim,i=t.length,n=t[i-1],a=0;a0&&a!==i-1&&Oa(t[a].value,n.value,r);if(e&&this.needsAnimate()&&e.needsAnimate()&&r===e.arrDim&&this.isValueColor===e.isValueColor&&!e._finished){this._additiveTrack=e;var o=t[0].value;for(a=0;a=0&&!(a[r].percent<=t);r--);r=Math.min(r,o-2)}else{for(r=this._lastFrame;rt);r++);r=Math.min(r-1,o-2)}var u=a[r+1],c=a[r];if(c&&u){this._lastFrame=r,this._lastFramePercent=t;var d=u.percent-c.percent;if(0!==d){var f=(t-c.percent)/d,p=i?this._additiveValue:h?za:e[s];if((l>0||h)&&!p&&(p=this._additiveValue=[]),this.useSpline){var m=a[r][n],g=a[0===r?r:r-1][n],_=a[r>o-2?o-1:r+1][n],v=a[r>o-3?o-1:r+2][n];if(l>0)1===l?Ra(p,g,m,_,v,f,f*f,f*f*f):function(e,t,r,i,n,a,o,s){for(var l=t.length,h=t[0].length,u=0;u0?1===l?Da(p,c[n],u[n],f):function(e,t,r,i){for(var n=t.length,a=n&&t[0].length,o=0;o.5?t:e}(c[n],u[n],f),i?this._additiveValue=y:e[s]=y);i&&this._addToTarget(e)}}}},e.prototype._addToTarget=function(e){var t=this.arrDim,r=this.propName,i=this._additiveValue;0===t?this.isValueColor?(oa(e[r],za),La(za,za,i,1),e[r]=Fa(za)):e[r]=e[r]+i:1===t?La(e[r],e[r],i,1):2===t&&Pa(e[r],e[r],i,1)},e}();const Ua=function(){function e(e,t,r){this._tracks={},this._trackKeys=[],this._delay=0,this._maxTime=0,this._paused=!1,this._started=0,this._clip=null,this._target=e,this._loop=t,t&&r?function(){for(var e=[],t=0;t0)){this._started=1;for(var r=this,i=[],n=0;n1){var o=a.pop();n.addKeyframe(o.time,e[i]),n.prepare(n.getAdditiveTrack())}}}},e}(),ka={_animators:null,getAnimators:function(){return this._animators=this._animators||[],this._animators},animate:function(e,t){var r;if(this._animators=this._animators||[],e){for(var i=e.split("."),n=this,a=0,o=i.length;a=0&&s.splice(e,1)})),s.push(l),this.__zr&&this.__zr.animation.addAnimator(l),l},stopAnimation:function(e){this._animators=this._animators||[];for(var t=this._animators,r=t.length,i=0;i 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.y) * weight.y;\n}\nif (weight.z > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.z) * weight.z;\n}\nfloat weightW = 1.0-weight.x-weight.y-weight.z;\nif (weightW > 1e-4)\n{\n skinMatrixWS += getSkinMatrix(joint.w) * weightW;\n}\n@end\n@export clay.chunk.instancing_header\n#ifdef INSTANCING\nattribute vec4 instanceMat1;\nattribute vec4 instanceMat2;\nattribute vec4 instanceMat3;\n#endif\n@end\n@export clay.chunk.instancing_matrix\nmat4 instanceMat = mat4(\n vec4(instanceMat1.xyz, 0.0),\n vec4(instanceMat2.xyz, 0.0),\n vec4(instanceMat3.xyz, 0.0),\n vec4(instanceMat1.w, instanceMat2.w, instanceMat3.w, 1.0)\n);\n@end\n@export clay.util.parallax_correct\nvec3 parallaxCorrect(in vec3 dir, in vec3 pos, in vec3 boxMin, in vec3 boxMax) {\n vec3 first = (boxMax - pos) / dir;\n vec3 second = (boxMin - pos) / dir;\n vec3 further = max(first, second);\n float dist = min(further.x, min(further.y, further.z));\n vec3 fixedPos = pos + dir * dist;\n vec3 boxCenter = (boxMax + boxMin) * 0.5;\n return normalize(fixedPos - boxCenter);\n}\n@end\n@export clay.util.clamp_sample\nvec4 clampSample(const in sampler2D texture, const in vec2 coord)\n{\n#ifdef STEREO\n float eye = step(0.5, coord.x) * 0.5;\n vec2 coordClamped = clamp(coord, vec2(eye, 0.0), vec2(0.5 + eye, 1.0));\n#else\n vec2 coordClamped = clamp(coord, vec2(0.0), vec2(1.0));\n#endif\n return texture2D(texture, coordClamped);\n}\n@end\n@export clay.util.ACES\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\n@end";function Ha(e){return e instanceof HTMLCanvasElement||e instanceof HTMLImageElement||e instanceof Image}Object.assign(sr.prototype,ka),Xe.import(Va),Xe.import(qe),Xe.import("\n@export ecgl.common.transformUniforms\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nuniform mat4 world : WORLD;\n@end\n\n@export ecgl.common.attributes\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 normal : NORMAL;\n@end\n\n@export ecgl.common.uv.header\nuniform vec2 uvRepeat : [1.0, 1.0];\nuniform vec2 uvOffset : [0.0, 0.0];\nuniform vec2 detailUvRepeat : [1.0, 1.0];\nuniform vec2 detailUvOffset : [0.0, 0.0];\n\nvarying vec2 v_Texcoord;\nvarying vec2 v_DetailTexcoord;\n@end\n\n@export ecgl.common.uv.main\nv_Texcoord = texcoord * uvRepeat + uvOffset;\nv_DetailTexcoord = texcoord * detailUvRepeat + detailUvOffset;\n@end\n\n@export ecgl.common.uv.fragmentHeader\nvarying vec2 v_Texcoord;\nvarying vec2 v_DetailTexcoord;\n@end\n\n\n@export ecgl.common.albedo.main\n\n vec4 albedoTexel = vec4(1.0);\n#ifdef DIFFUSEMAP_ENABLED\n albedoTexel = texture2D(diffuseMap, v_Texcoord);\n #ifdef SRGB_DECODE\n albedoTexel = sRGBToLinear(albedoTexel);\n #endif\n#endif\n\n#ifdef DETAILMAP_ENABLED\n vec4 detailTexel = texture2D(detailMap, v_DetailTexcoord);\n #ifdef SRGB_DECODE\n detailTexel = sRGBToLinear(detailTexel);\n #endif\n albedoTexel.rgb = mix(albedoTexel.rgb, detailTexel.rgb, detailTexel.a);\n albedoTexel.a = detailTexel.a + (1.0 - detailTexel.a) * albedoTexel.a;\n#endif\n\n@end\n\n@export ecgl.common.wireframe.vertexHeader\n\n#ifdef WIREFRAME_QUAD\nattribute vec4 barycentric;\nvarying vec4 v_Barycentric;\n#elif defined(WIREFRAME_TRIANGLE)\nattribute vec3 barycentric;\nvarying vec3 v_Barycentric;\n#endif\n\n@end\n\n@export ecgl.common.wireframe.vertexMain\n\n#if defined(WIREFRAME_QUAD) || defined(WIREFRAME_TRIANGLE)\n v_Barycentric = barycentric;\n#endif\n\n@end\n\n\n@export ecgl.common.wireframe.fragmentHeader\n\nuniform float wireframeLineWidth : 1;\nuniform vec4 wireframeLineColor: [0, 0, 0, 0.5];\n\n#ifdef WIREFRAME_QUAD\nvarying vec4 v_Barycentric;\nfloat edgeFactor () {\n vec4 d = fwidth(v_Barycentric);\n vec4 a4 = smoothstep(vec4(0.0), d * wireframeLineWidth, v_Barycentric);\n return min(min(min(a4.x, a4.y), a4.z), a4.w);\n}\n#elif defined(WIREFRAME_TRIANGLE)\nvarying vec3 v_Barycentric;\nfloat edgeFactor () {\n vec3 d = fwidth(v_Barycentric);\n vec3 a3 = smoothstep(vec3(0.0), d * wireframeLineWidth, v_Barycentric);\n return min(min(a3.x, a3.y), a3.z);\n}\n#endif\n\n@end\n\n\n@export ecgl.common.wireframe.fragmentMain\n\n#if defined(WIREFRAME_QUAD) || defined(WIREFRAME_TRIANGLE)\n if (wireframeLineWidth > 0.) {\n vec4 lineColor = wireframeLineColor;\n#ifdef SRGB_DECODE\n lineColor = sRGBToLinear(lineColor);\n#endif\n\n gl_FragColor.rgb = mix(gl_FragColor.rgb, lineColor.rgb, (1.0 - edgeFactor()) * lineColor.a);\n }\n#endif\n@end\n\n\n\n\n@export ecgl.common.bumpMap.header\n\n#ifdef BUMPMAP_ENABLED\nuniform sampler2D bumpMap;\nuniform float bumpScale : 1.0;\n\n\nvec3 bumpNormal(vec3 surfPos, vec3 surfNormal, vec3 baseNormal)\n{\n vec2 dSTdx = dFdx(v_Texcoord);\n vec2 dSTdy = dFdy(v_Texcoord);\n\n float Hll = bumpScale * texture2D(bumpMap, v_Texcoord).x;\n float dHx = bumpScale * texture2D(bumpMap, v_Texcoord + dSTdx).x - Hll;\n float dHy = bumpScale * texture2D(bumpMap, v_Texcoord + dSTdy).x - Hll;\n\n vec3 vSigmaX = dFdx(surfPos);\n vec3 vSigmaY = dFdy(surfPos);\n vec3 vN = surfNormal;\n\n vec3 R1 = cross(vSigmaY, vN);\n vec3 R2 = cross(vN, vSigmaX);\n\n float fDet = dot(vSigmaX, R1);\n\n vec3 vGrad = sign(fDet) * (dHx * R1 + dHy * R2);\n return normalize(abs(fDet) * baseNormal - vGrad);\n\n}\n#endif\n\n@end\n\n@export ecgl.common.normalMap.vertexHeader\n\n#ifdef NORMALMAP_ENABLED\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@end\n\n@export ecgl.common.normalMap.vertexMain\n\n#ifdef NORMALMAP_ENABLED\n if (dot(tangent, tangent) > 0.0) {\n v_Tangent = normalize((worldInverseTranspose * vec4(tangent.xyz, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n }\n#endif\n\n@end\n\n\n@export ecgl.common.normalMap.fragmentHeader\n\n#ifdef NORMALMAP_ENABLED\nuniform sampler2D normalMap;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@end\n\n@export ecgl.common.normalMap.fragmentMain\n#ifdef NORMALMAP_ENABLED\n if (dot(v_Tangent, v_Tangent) > 0.0) {\n vec3 normalTexel = texture2D(normalMap, v_DetailTexcoord).xyz;\n if (dot(normalTexel, normalTexel) > 0.0) { N = normalTexel * 2.0 - 1.0;\n mat3 tbn = mat3(v_Tangent, v_Bitangent, v_Normal);\n N = normalize(tbn * N);\n }\n }\n#endif\n@end\n\n\n\n@export ecgl.common.vertexAnimation.header\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute vec3 prevNormal;\nuniform float percent;\n#endif\n\n@end\n\n@export ecgl.common.vertexAnimation.main\n\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n vec3 norm = mix(prevNormal, normal, percent);\n#else\n vec3 pos = position;\n vec3 norm = normal;\n#endif\n\n@end\n\n\n@export ecgl.common.ssaoMap.header\n#ifdef SSAOMAP_ENABLED\nuniform sampler2D ssaoMap;\nuniform vec4 viewport : VIEWPORT;\n#endif\n@end\n\n@export ecgl.common.ssaoMap.main\n float ao = 1.0;\n#ifdef SSAOMAP_ENABLED\n ao = texture2D(ssaoMap, (gl_FragCoord.xy - viewport.xy) / viewport.zw).r;\n#endif\n@end\n\n\n\n\n@export ecgl.common.diffuseLayer.header\n\n#if (LAYER_DIFFUSEMAP_COUNT > 0)\nuniform float layerDiffuseIntensity[LAYER_DIFFUSEMAP_COUNT];\nuniform sampler2D layerDiffuseMap[LAYER_DIFFUSEMAP_COUNT];\n#endif\n\n@end\n\n@export ecgl.common.emissiveLayer.header\n\n#if (LAYER_EMISSIVEMAP_COUNT > 0)\nuniform float layerEmissionIntensity[LAYER_EMISSIVEMAP_COUNT];\nuniform sampler2D layerEmissiveMap[LAYER_EMISSIVEMAP_COUNT];\n#endif\n\n@end\n\n@export ecgl.common.layers.header\n@import ecgl.common.diffuseLayer.header\n@import ecgl.common.emissiveLayer.header\n@end\n\n@export ecgl.common.diffuseLayer.main\n\n#if (LAYER_DIFFUSEMAP_COUNT > 0)\n for (int _idx_ = 0; _idx_ < LAYER_DIFFUSEMAP_COUNT; _idx_++) {{\n float intensity = layerDiffuseIntensity[_idx_];\n vec4 texel2 = texture2D(layerDiffuseMap[_idx_], v_Texcoord);\n #ifdef SRGB_DECODE\n texel2 = sRGBToLinear(texel2);\n #endif\n albedoTexel.rgb = mix(albedoTexel.rgb, texel2.rgb * intensity, texel2.a);\n albedoTexel.a = texel2.a + (1.0 - texel2.a) * albedoTexel.a;\n }}\n#endif\n\n@end\n\n@export ecgl.common.emissiveLayer.main\n\n#if (LAYER_EMISSIVEMAP_COUNT > 0)\n for (int _idx_ = 0; _idx_ < LAYER_EMISSIVEMAP_COUNT; _idx_++)\n {{\n vec4 texel2 = texture2D(layerEmissiveMap[_idx_], v_Texcoord) * layerEmissionIntensity[_idx_];\n #ifdef SRGB_DECODE\n texel2 = sRGBToLinear(texel2);\n #endif\n float intensity = layerEmissionIntensity[_idx_];\n gl_FragColor.rgb += texel2.rgb * texel2.a * intensity;\n }}\n#endif\n\n@end\n"),Xe.import("@export ecgl.color.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\n@import ecgl.common.uv.header\n\nattribute vec2 texcoord : TEXCOORD_0;\nattribute vec3 position: POSITION;\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nuniform float percent : 1.0;\n#endif\n\n#ifdef ATMOSPHERE_ENABLED\nattribute vec3 normal: NORMAL;\nuniform mat4 worldInverseTranspose : WORLDINVERSETRANSPOSE;\nvarying vec3 v_Normal;\n#endif\n\nvoid main()\n{\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n#else\n vec3 pos = position;\n#endif\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n @import ecgl.common.uv.main\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n#ifdef ATMOSPHERE_ENABLED\n v_Normal = normalize((worldInverseTranspose * vec4(normal, 0.0)).xyz);\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n\n}\n\n@end\n\n@export ecgl.color.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n\nuniform sampler2D diffuseMap;\nuniform sampler2D detailMap;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\n#ifdef ATMOSPHERE_ENABLED\nuniform mat4 viewTranspose: VIEWTRANSPOSE;\nuniform vec3 glowColor;\nuniform float glowPower;\nvarying vec3 v_Normal;\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n@import ecgl.common.layers.header\n\n@import ecgl.common.uv.fragmentHeader\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color);\n#else\n gl_FragColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n gl_FragColor *= albedoTexel;\n\n#ifdef ATMOSPHERE_ENABLED\n float atmoIntensity = pow(1.0 - dot(v_Normal, (viewTranspose * vec4(0.0, 0.0, 1.0, 0.0)).xyz), glowPower);\n gl_FragColor.rgb += glowColor * atmoIntensity;\n#endif\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n\n}\n@end"),Xe.import("/**\n * http: */\n\n@export ecgl.lambert.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n\n@import ecgl.common.attributes\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.vertexAnimation.header\n\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nvoid main()\n{\n @import ecgl.common.uv.main\n\n @import ecgl.common.vertexAnimation.main\n\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n v_Normal = normalize((worldInverseTranspose * vec4(norm, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n}\n\n@end\n\n\n@export ecgl.lambert.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform sampler2D diffuseMap;\nuniform sampler2D detailMap;\n\n@import ecgl.common.layers.header\n\nuniform float emissionIntensity: 1.0;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef ATMOSPHERE_ENABLED\nuniform mat4 viewTranspose: VIEWTRANSPOSE;\nuniform vec3 glowColor;\nuniform float glowPower;\n#endif\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color);\n#else\n gl_FragColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n gl_FragColor *= sRGBToLinear(v_Color);\n #else\n gl_FragColor *= v_Color;\n #endif\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n gl_FragColor *= albedoTexel;\n\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n vec3 diffuseColor = vec3(0.0, 0.0, 0.0);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int i = 0; i < AMBIENT_LIGHT_COUNT; i++)\n {\n diffuseColor += ambientLightColor[i] * ambientFactor * ao;\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseColor += calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_] * ao;\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n vec3 lightColor = directionalLightColor[i];\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n\n float ndl = dot(N, normalize(lightDirection)) * shadowContrib;\n\n diffuseColor += lightColor * clamp(ndl, 0.0, 1.0);\n }\n#endif\n\n gl_FragColor.rgb *= diffuseColor;\n\n#ifdef ATMOSPHERE_ENABLED\n float atmoIntensity = pow(1.0 - dot(v_Normal, (viewTranspose * vec4(0.0, 0.0, 1.0, 0.0)).xyz), glowPower);\n gl_FragColor.rgb += glowColor * atmoIntensity;\n#endif\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end"),Xe.import("@export ecgl.realistic.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\n\n@import ecgl.common.wireframe.vertexHeader\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef NORMALMAP_ENABLED\nattribute vec4 tangent : TANGENT;\nvarying vec3 v_Tangent;\nvarying vec3 v_Bitangent;\n#endif\n\n@import ecgl.common.vertexAnimation.header\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nvoid main()\n{\n\n @import ecgl.common.uv.main\n\n @import ecgl.common.vertexAnimation.main\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n v_Normal = normalize((worldInverseTranspose * vec4(norm, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n#ifdef VERTEX_COLOR\n v_Color = a_Color;\n#endif\n\n#ifdef NORMALMAP_ENABLED\n v_Tangent = normalize((worldInverseTranspose * vec4(tangent.xyz, 0.0)).xyz);\n v_Bitangent = normalize(cross(v_Normal, v_Tangent) * tangent.w);\n#endif\n\n @import ecgl.common.wireframe.vertexMain\n\n}\n\n@end\n\n\n\n@export ecgl.realistic.fragment\n\n#define LAYER_DIFFUSEMAP_COUNT 0\n#define LAYER_EMISSIVEMAP_COUNT 0\n#define PI 3.14159265358979\n#define ROUGHNESS_CHANEL 0\n#define METALNESS_CHANEL 1\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform sampler2D diffuseMap;\n\nuniform sampler2D detailMap;\nuniform sampler2D metalnessMap;\nuniform sampler2D roughnessMap;\n\n@import ecgl.common.layers.header\n\nuniform float emissionIntensity: 1.0;\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nuniform float metalness : 0.0;\nuniform float roughness : 0.5;\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef ATMOSPHERE_ENABLED\nuniform mat4 viewTranspose: VIEWTRANSPOSE;\nuniform vec3 glowColor;\nuniform float glowPower;\n#endif\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n@import clay.header.ambient_cubemap_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n@import ecgl.common.normalMap.fragmentHeader\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import clay.util.rgbm\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n\nfloat D_Phong(float g, float ndh) {\n float a = pow(8192.0, g);\n return (a + 2.0) / 8.0 * pow(ndh, a);\n}\n\nvoid main()\n{\n vec4 albedoColor = color;\n\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n albedoColor *= sRGBToLinear(v_Color);\n #else\n albedoColor *= v_Color;\n #endif\n#endif\n\n @import ecgl.common.albedo.main\n\n @import ecgl.common.diffuseLayer.main\n\n albedoColor *= albedoTexel;\n\n float m = metalness;\n\n#ifdef METALNESSMAP_ENABLED\n float m2 = texture2D(metalnessMap, v_DetailTexcoord)[METALNESS_CHANEL];\n m = clamp(m2 + (m - 0.5) * 2.0, 0.0, 1.0);\n#endif\n\n vec3 baseColor = albedoColor.rgb;\n albedoColor.rgb = baseColor * (1.0 - m);\n vec3 specFactor = mix(vec3(0.04), baseColor, m);\n\n float g = 1.0 - roughness;\n\n#ifdef ROUGHNESSMAP_ENABLED\n float g2 = 1.0 - texture2D(roughnessMap, v_DetailTexcoord)[ROUGHNESS_CHANEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n#endif\n\n vec3 N = v_Normal;\n\n#ifdef DOUBLE_SIDED\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n@import ecgl.common.normalMap.fragmentMain\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n vec3 diffuseTerm = vec3(0.0);\n vec3 specularTerm = vec3(0.0);\n\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n vec3 fresnelTerm = F_Schlick(ndv, specFactor);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += ambientLightColor[_idx_] * ambientFactor * ao;\n }}\n#endif\n\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n diffuseTerm += calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_] * ao;\n }}\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++)\n {{\n vec3 L = -directionalLightDirection[_idx_];\n vec3 lc = directionalLightColor[_idx_];\n\n vec3 H = normalize(L + V);\n float ndl = clamp(dot(N, normalize(L)), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[_idx_];\n }\n#endif\n\n vec3 li = lc * ndl * shadowContrib;\n\n diffuseTerm += li;\n specularTerm += li * fresnelTerm * D_Phong(g, ndh);\n }}\n#endif\n\n\n#ifdef AMBIENT_CUBEMAP_LIGHT_COUNT\n vec3 L = reflect(-V, N);\n L = vec3(L.x, L[NORMAL_UP_AXIS], L[NORMAL_FRONT_AXIS]);\n float rough2 = clamp(1.0 - g, 0.0, 1.0);\n float bias2 = rough2 * 5.0;\n vec2 brdfParam2 = texture2D(ambientCubemapLightBRDFLookup[0], vec2(rough2, ndv)).xy;\n vec3 envWeight2 = specFactor * brdfParam2.x + brdfParam2.y;\n vec3 envTexel2;\n for(int _idx_ = 0; _idx_ < AMBIENT_CUBEMAP_LIGHT_COUNT; _idx_++)\n {{\n envTexel2 = RGBMDecode(textureCubeLodEXT(ambientCubemapLightCubemap[_idx_], L, bias2), 8.12);\n specularTerm += ambientCubemapLightColor[_idx_] * envTexel2 * envWeight2 * ao;\n }}\n#endif\n\n gl_FragColor.rgb = albedoColor.rgb * diffuseTerm + specularTerm;\n gl_FragColor.a = albedoColor.a;\n\n#ifdef ATMOSPHERE_ENABLED\n float atmoIntensity = pow(1.0 - dot(v_Normal, (viewTranspose * vec4(0.0, 0.0, 1.0, 0.0)).xyz), glowPower);\n gl_FragColor.rgb += glowColor * atmoIntensity;\n#endif\n\n#ifdef SRGB_ENCODE\n gl_FragColor = linearTosRGB(gl_FragColor);\n#endif\n\n @import ecgl.common.emissiveLayer.main\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end"),Xe.import("@export ecgl.hatching.vertex\n\n@import ecgl.realistic.vertex\n\n@end\n\n\n@export ecgl.hatching.fragment\n\n#define NORMAL_UP_AXIS 1\n#define NORMAL_FRONT_AXIS 2\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform vec4 color : [0.0, 0.0, 0.0, 1.0];\nuniform vec4 paperColor : [1.0, 1.0, 1.0, 1.0];\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n#ifdef AMBIENT_LIGHT_COUNT\n@import clay.header.ambient_light\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n@import clay.header.ambient_sh_light\n#endif\n\n#ifdef DIRECTIONAL_LIGHT_COUNT\n@import clay.header.directional_light\n#endif\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\n\n@import ecgl.common.ssaoMap.header\n\n@import ecgl.common.bumpMap.header\n\n@import clay.util.srgb\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.plugin.compute_shadow_map\n\nuniform sampler2D hatch1;\nuniform sampler2D hatch2;\nuniform sampler2D hatch3;\nuniform sampler2D hatch4;\nuniform sampler2D hatch5;\nuniform sampler2D hatch6;\n\nfloat shade(in float tone) {\n vec4 c = vec4(1. ,1., 1., 1.);\n float step = 1. / 6.;\n vec2 uv = v_DetailTexcoord;\n if (tone <= step / 2.0) {\n c = mix(vec4(0.), texture2D(hatch6, uv), 12. * tone);\n }\n else if (tone <= step) {\n c = mix(texture2D(hatch6, uv), texture2D(hatch5, uv), 6. * tone);\n }\n if(tone > step && tone <= 2. * step){\n c = mix(texture2D(hatch5, uv), texture2D(hatch4, uv) , 6. * (tone - step));\n }\n if(tone > 2. * step && tone <= 3. * step){\n c = mix(texture2D(hatch4, uv), texture2D(hatch3, uv), 6. * (tone - 2. * step));\n }\n if(tone > 3. * step && tone <= 4. * step){\n c = mix(texture2D(hatch3, uv), texture2D(hatch2, uv), 6. * (tone - 3. * step));\n }\n if(tone > 4. * step && tone <= 5. * step){\n c = mix(texture2D(hatch2, uv), texture2D(hatch1, uv), 6. * (tone - 4. * step));\n }\n if(tone > 5. * step){\n c = mix(texture2D(hatch1, uv), vec4(1.), 6. * (tone - 5. * step));\n }\n\n return c.r;\n}\n\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n vec4 inkColor = sRGBToLinear(color);\n#else\n vec4 inkColor = color;\n#endif\n\n#ifdef VERTEX_COLOR\n #ifdef SRGB_DECODE\n inkColor *= sRGBToLinear(v_Color);\n #else\n inkColor *= v_Color;\n #endif\n#endif\n\n vec3 N = v_Normal;\n#ifdef DOUBLE_SIDED\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n N = -N;\n }\n#endif\n\n float tone = 0.0;\n\n float ambientFactor = 1.0;\n\n#ifdef BUMPMAP_ENABLED\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n ambientFactor = dot(v_Normal, N);\n#endif\n\n vec3 N2 = vec3(N.x, N[NORMAL_UP_AXIS], N[NORMAL_FRONT_AXIS]);\n\n @import ecgl.common.ssaoMap.main\n\n#ifdef AMBIENT_LIGHT_COUNT\n for(int i = 0; i < AMBIENT_LIGHT_COUNT; i++)\n {\n tone += dot(ambientLightColor[i], w) * ambientFactor * ao;\n }\n#endif\n#ifdef AMBIENT_SH_LIGHT_COUNT\n for(int _idx_ = 0; _idx_ < AMBIENT_SH_LIGHT_COUNT; _idx_++)\n {{\n tone += dot(calcAmbientSHLight(_idx_, N2) * ambientSHLightColor[_idx_], w) * ao;\n }}\n#endif\n#ifdef DIRECTIONAL_LIGHT_COUNT\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n float shadowContribsDir[DIRECTIONAL_LIGHT_COUNT];\n if(shadowEnabled)\n {\n computeShadowOfDirectionalLights(v_WorldPosition, shadowContribsDir);\n }\n#endif\n for(int i = 0; i < DIRECTIONAL_LIGHT_COUNT; i++)\n {\n vec3 lightDirection = -directionalLightDirection[i];\n float lightTone = dot(directionalLightColor[i], w);\n\n float shadowContrib = 1.0;\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n if (shadowEnabled)\n {\n shadowContrib = shadowContribsDir[i];\n }\n#endif\n\n float ndl = dot(N, normalize(lightDirection)) * shadowContrib;\n\n tone += lightTone * clamp(ndl, 0.0, 1.0);\n }\n#endif\n\n gl_FragColor = mix(inkColor, paperColor, shade(clamp(tone, 0.0, 1.0)));\n }\n@end\n"),Xe.import("@export ecgl.sm.depth.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec3 position : POSITION;\nattribute vec2 texcoord : TEXCOORD_0;\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nuniform float percent : 1.0;\n#endif\n\nvarying vec4 v_ViewPosition;\nvarying vec2 v_Texcoord;\n\nvoid main(){\n\n#ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n#else\n vec3 pos = position;\n#endif\n\n v_ViewPosition = worldViewProjection * vec4(pos, 1.0);\n gl_Position = v_ViewPosition;\n\n v_Texcoord = texcoord;\n\n}\n@end\n\n\n\n@export ecgl.sm.depth.fragment\n\n@import clay.sm.depth.fragment\n\n@end");var Wa=vi.prototype.addToScene,ja=vi.prototype.removeFromScene;vi.prototype.addToScene=function(e){if(Wa.call(this,e),this.__zr){var t=this.__zr;e.traverse((function(e){e.__zr=t,e.addAnimatorsToZr&&e.addAnimatorsToZr(t)}))}},vi.prototype.removeFromScene=function(e){ja.call(this,e),e.traverse((function(e){var t=e.__zr;e.__zr=null,t&&e.removeAnimatorsFromZr&&e.removeAnimatorsFromZr(t)}))},le.prototype.setTextureImage=function(e,t,r,i){if(this.shader){var n,a=r.getZr(),o=this;return o.autoUpdateTextureStatus=!1,o.disableTexture(e),!(s=t)||"none"===s||(n=Xa.loadTexture(t,r,i,(function(t){o.enableTexture(e),a&&a.refresh()})),o.set(e,n)),n}var s};var Xa={};Xa.Renderer=ut,Xa.Node=sr,Xa.Mesh=Sr,Xa.Shader=Xe,Xa.Material=le,Xa.Texture=wr,Xa.Texture2D=Dr,Xa.Geometry=Vr,Xa.SphereGeometry=En,Xa.PlaneGeometry=ki,Xa.CubeGeometry=Wi,Xa.AmbientLight=Cn,Xa.DirectionalLight=Dn,Xa.PointLight=Ln,Xa.SpotLight=Pn,Xa.PerspectiveCamera=Ei,Xa.OrthographicCamera=un,Xa.Vector2=_e,Xa.Vector3=vt,Xa.Vector4=Rn,Xa.Quaternion=qt,Xa.Matrix2=Gn,Xa.Matrix2d=Hn,Xa.Matrix3=jn,Xa.Matrix4=Ht,Xa.Plane=$r,Xa.Ray=Mt,Xa.BoundingBox=ir,Xa.Frustum=si;var qa=null;function Za(e){return Math.pow(2,Math.round(Math.log(e)/Math.LN2))}function Ya(e){if((e.wrapS===wr.REPEAT||e.wrapT===wr.REPEAT)&&e.image){var t=Za(e.width),r=Za(e.height);if(t!==e.width||r!==e.height){var i=document.createElement("canvas");i.width=t,i.height=r,i.getContext("2d").drawImage(e.image,0,0,t,r),e.image=i}}}Xa.loadTexture=function(e,t,r,i){"function"==typeof r&&(i=r,r={}),r=r||{};for(var n=Object.keys(r).sort(),a="",o=0;o3?t[3]=e[3]:t[3]=1,t):((t=i.color.parse(e||"#000",t)||[0,0,0,0])[0]/=255,t[1]/=255,t[2]/=255,t)},Xa.directionFromAlphaBeta=function(e,t){var r=e/180*Math.PI+Math.PI/2,i=-t/180*Math.PI+Math.PI/2,n=[],a=Math.sin(r);return n[0]=a*Math.cos(i),n[1]=-Math.cos(r),n[2]=a*Math.sin(i),n},Xa.getShadowResolution=function(e){var t=1024;switch(e){case"low":t=512;break;case"medium":break;case"high":t=2048;break;case"ultra":t=4096}return t},Xa.COMMON_SHADERS=["lambert","color","realistic","hatching","shadow"],Xa.createShader=function(e){"ecgl.shadow"===e&&(e="ecgl.displayShadow");var t=Xe.source(e+".vertex"),r=Xe.source(e+".fragment");t||console.error("Vertex shader of '%s' not exits",e),r||console.error("Fragment shader of '%s' not exits",e);var i=new Xe(t,r);return i.name=e,i},Xa.createMaterial=function(e,t){t instanceof Array||(t=[t]);var r=Xa.createShader(e),i=new le({shader:r});return t.forEach((function(e){"string"==typeof e&&i.define(e)})),i},Xa.setMaterialFromModel=function(e,t,r,i){t.autoUpdateTextureStatus=!1;var n=r.getModel(e+"Material"),a=n.get("detailTexture"),o=Mn(n.get("textureTiling"),1),s=Mn(n.get("textureOffset"),0);"number"==typeof o&&(o=[o,o]),"number"==typeof s&&(s=[s,s]);var l=o[0]>1||o[1]>1?Xa.Texture.REPEAT:Xa.Texture.CLAMP_TO_EDGE,h={anisotropic:8,wrapS:l,wrapT:l};if("realistic"===e){var u=n.get("roughness"),c=n.get("metalness");null!=c?isNaN(c)&&(t.setTextureImage("metalnessMap",c,i,h),c=Mn(n.get("metalnessAdjust"),.5)):c=0,null!=u?isNaN(u)&&(t.setTextureImage("roughnessMap",u,i,h),u=Mn(n.get("roughnessAdjust"),.5)):u=.5;var d=n.get("normalTexture");t.setTextureImage("detailMap",a,i,h),t.setTextureImage("normalMap",d,i,h),t.set({roughness:u,metalness:c,detailUvRepeat:o,detailUvOffset:s})}else if("lambert"===e)t.setTextureImage("detailMap",a,i,h),t.set({detailUvRepeat:o,detailUvOffset:s});else if("color"===e)t.setTextureImage("detailMap",a,i,h),t.set({detailUvRepeat:o,detailUvOffset:s});else if("hatching"===e){var f=n.get("hatchingTextures")||[];f.length;for(var p=0;p<6;p++)t.setTextureImage("hatch"+(p+1),f[p],i,{anisotropic:8,wrapS:Xa.Texture.REPEAT,wrapT:Xa.Texture.REPEAT});t.set({detailUvRepeat:o,detailUvOffset:s})}},Xa.updateVertexAnimation=function(e,t,r,i){var n=i.get("animation"),a=i.get("animationDurationUpdate"),o=i.get("animationEasingUpdate"),s=r.shadowDepthMaterial;if(n&&t&&a>0&&t.geometry.vertexCount===r.geometry.vertexCount){r.material.define("vertex","VERTEX_ANIMATION"),r.ignorePreZ=!0,s&&s.define("vertex","VERTEX_ANIMATION");for(var l=0;l=0&&this._viewsToDispose.splice(t,1),this.views.push(e),e.layer=this;var r=this.zr;e.scene.traverse((function(e){e.__zr=r,e.addAnimatorsToZr&&e.addAnimatorsToZr(r)}))}},Ja.prototype.removeView=function(e){if(e.layer===this){var t=this.views.indexOf(e);t>=0&&(this.views.splice(t,1),e.scene.traverse($a,this),e.layer=null,this._viewsToDispose.push(e))}},Ja.prototype.removeViewsAll=function(){this.views.forEach((function(e){e.scene.traverse($a,this),e.layer=null,this._viewsToDispose.push(e)}),this),this.views.length=0},Ja.prototype.resize=function(e,t){this.renderer.resize(e,t)},Ja.prototype.clear=function(){var e=this.renderer.gl,t=this._backgroundColor||[0,0,0,0];e.clearColor(t[0],t[1],t[2],t[3]),e.depthMask(!0),e.colorMask(!0,!0,!0,!0),e.clear(e.DEPTH_BUFFER_BIT|e.COLOR_BUFFER_BIT)},Ja.prototype.clearDepth=function(){var e=this.renderer.gl;e.clear(e.DEPTH_BUFFER_BIT)},Ja.prototype.clearColor=function(){var e=this.renderer.gl;e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT)},Ja.prototype.needsRefresh=function(){this.zr.refresh()},Ja.prototype.refresh=function(e){this._backgroundColor=e?Ka.parseColor(e):[0,0,0,0],this.renderer.clearColor=this._backgroundColor;for(var t=0;t20)){e=e.event;var i=this.pickObject(e.offsetX,e.offsetY);i&&(this._dispatchEvent(e.type,e,i),this._dispatchDataEvent(e.type,e,i));var n=this._clickToSetFocusPoint(e);n&&n.view.setDOFFocusOnPoint(n.distance)&&this.zr.refresh()}}},Ja.prototype._clickToSetFocusPoint=function(e){for(var t=this.renderer,r=t.viewport,i=this.views.length-1;i>=0;i--){var n=this.views[i];if(n.hasDOF()&&n.containPoint(e.offsetX,e.offsetY)){this._picking.scene=n.scene,this._picking.camera=n.camera,t.viewport=n.viewport;var a=this._picking.pick(e.offsetX,e.offsetY,!0);if(a)return a.view=n,a}}t.viewport=r},Ja.prototype.onglobalout=function(e){var t=this._hovered;t&&this._dispatchEvent("mouseout",e,{target:t.target})},Ja.prototype.pickObject=function(e,t){for(var r=[],i=this.renderer,n=i.viewport,a=0;a=0&&(c.dataIndex=this._lastDataIndex,c.seriesIndex=this._lastSeriesIndex,this.zr.handler.dispatchToElement(u,"mouseout",t)),l=!0):null!=s&&s!==this._lastEventData&&(null!=this._lastEventData&&(c.eventData=this._lastEventData,this.zr.handler.dispatchToElement(u,"mouseout",t)),l=!0),this._lastEventData=s,this._lastDataIndex=a,this._lastSeriesIndex=o),c.eventData=s,c.dataIndex=a,c.seriesIndex=o,(null!=s||parseInt(a,10)>=0&&parseInt(o,10)>=0)&&(this.zr.handler.dispatchToElement(u,e,t),l&&this.zr.handler.dispatchToElement(u,"mouseover",t))},Ja.prototype._dispatchToView=function(e,t){for(var r=0;re&&o=0&&(function(e){so(e,"itemStyle"),so(e,"lineStyle"),so(e,"areaStyle"),so(e,"label")}(t),"mapbox"===t.coordinateSystem&&(t.coordinateSystem="mapbox3D",e.mapbox3D=e.mapbox))})),lo(e.xAxis3D),lo(e.yAxis3D),lo(e.zAxis3D),lo(e.grid3D),so(e.geo3D)}));const uo={defaultOption:{viewControl:{projection:"perspective",autoRotate:!1,autoRotateDirection:"cw",autoRotateSpeed:10,autoRotateAfterStill:3,damping:.8,rotateSensitivity:1,zoomSensitivity:1,panSensitivity:1,panMouseButton:"middle",rotateMouseButton:"left",distance:150,minDistance:40,maxDistance:400,orthographicSize:150,maxOrthographicSize:400,minOrthographicSize:20,center:[0,0,0],alpha:0,beta:0,minAlpha:-90,maxAlpha:90}},setView:function(e){e=e||{},this.option.viewControl=this.option.viewControl||{},null!=e.alpha&&(this.option.viewControl.alpha=e.alpha),null!=e.beta&&(this.option.viewControl.beta=e.beta),null!=e.distance&&(this.option.viewControl.distance=e.distance),null!=e.center&&(this.option.viewControl.center=e.center)}},co={defaultOption:{postEffect:{enable:!1,bloom:{enable:!0,intensity:.1},depthOfField:{enable:!1,focalRange:20,focalDistance:50,blurRadius:10,fstop:2.8,quality:"medium"},screenSpaceAmbientOcclusion:{enable:!1,radius:2,quality:"medium",intensity:1},screenSpaceReflection:{enable:!1,quality:"medium",maxRoughness:.8},colorCorrection:{enable:!0,exposure:0,brightness:0,contrast:1,saturation:1,lookupTexture:""},edge:{enable:!1},FXAA:{enable:!1}},temporalSuperSampling:{enable:"auto"}}},fo={defaultOption:{light:{main:{shadow:!1,shadowQuality:"high",color:"#fff",intensity:1,alpha:0,beta:0},ambient:{color:"#fff",intensity:.2},ambientCubemap:{texture:null,exposure:1,diffuseIntensity:.5,specularIntensity:.5}}}};var po=i.ComponentModel.extend({type:"grid3D",dependencies:["xAxis3D","yAxis3D","zAxis3D"],defaultOption:{show:!0,zlevel:-10,left:0,top:0,width:"100%",height:"100%",environment:"auto",boxWidth:100,boxHeight:100,boxDepth:100,axisPointer:{show:!0,lineStyle:{color:"rgba(0, 0, 0, 0.8)",width:1},label:{show:!0,formatter:null,margin:8,textStyle:{fontSize:14,color:"#fff",backgroundColor:"rgba(0,0,0,0.5)",padding:3,borderRadius:3}}},axisLine:{show:!0,lineStyle:{color:"#333",width:2,type:"solid"}},axisTick:{show:!0,inside:!1,length:3,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,margin:8,textStyle:{fontSize:12}},splitLine:{show:!0,lineStyle:{color:["#ccc"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.3)","rgba(200,200,200,0.3)"]}},light:{main:{alpha:30,beta:40},ambient:{intensity:.4}},viewControl:{alpha:20,beta:40,autoRotate:!1,distance:200,minDistance:40,maxDistance:400}}});i.util.merge(po.prototype,uo),i.util.merge(po.prototype,co),i.util.merge(po.prototype,fo);const mo=po;function go(e,t){switch(e){case"center":case"middle":e="50%";break;case"left":case"top":e="0%";break;case"right":case"bottom":e="100%"}return"string"==typeof e?(r=e,r.replace(/^\s+|\s+$/g,"")).match(/%$/)?parseFloat(e)/100*t:parseFloat(e):null==e?NaN:+e;var r}function _o(){var e="__ec_inner_"+vo++;return function(t){return t[e]||(t[e]={})}}var vo=Math.round(9*Math.random()),yo={};function xo(e,t,r,i,n){var a={};return function(e,t,r,i,n){r=r||yo;var a,o=t.ecModel,s=o&&o.option.textStyle,l=function(e){for(var t;e&&e!==e.ecModel;){var r=(e.option||yo).rich;if(r){t=t||{};for(var i=ba(r),n=0;n0&&this._notFirst?this.animateTo({alpha:h,beta:u,center:c,distance:a,orthographicSize:o,easing:l.animationEasingUpdate,duration:l.animationDurationUpdate}):(this.setDistance(a),this.setAlpha(h),this.setBeta(u),this.setCenter(c),this.setOrthographicSize(o)),this._notFirst=!0,this._validateProperties()},_validateProperties:function(){},animateTo:function(e){var t=this.zr,r=this,i={},n={};return null!=e.distance&&(i.distance=this.getDistance(),n.distance=e.distance),null!=e.orthographicSize&&(i.orthographicSize=this.getOrthographicSize(),n.orthographicSize=e.orthographicSize),null!=e.alpha&&(i.alpha=this.getAlpha(),n.alpha=e.alpha),null!=e.beta&&(i.beta=this.getBeta(),n.beta=e.beta),null!=e.center&&(i.center=this.getCenter(),n.center=e.center),this._addAnimator(t.animation.animate(i).when(e.duration||1e3,n).during((function(){null!=i.alpha&&r.setAlpha(i.alpha),null!=i.beta&&r.setBeta(i.beta),null!=i.distance&&r.setDistance(i.distance),null!=i.center&&r.setCenter(i.center),null!=i.orthographicSize&&r.setOrthographicSize(i.orthographicSize),r._needsUpdate=!0}))).start(e.easing||"linear")},stopAllAnimation:function(){for(var e=0;e0},_update:function(e){if(this._rotating){var t=("cw"===this.autoRotateDirection?1:-1)*this.autoRotateSpeed/180*Math.PI;this._phi-=t*e/1e3,this._needsUpdate=!0}else this._rotateVelocity.len()>0&&(this._needsUpdate=!0);(Math.abs(this._zoomSpeed)>.1||this._panVelocity.len()>0)&&(this._needsUpdate=!0),this._needsUpdate&&(e=Math.min(e,50),this._updateDistanceOrSize(e),this._updatePan(e),this._updateRotate(e),this._updateTransform(),this.getCamera().update(),this.zr&&this.zr.refresh(),this.trigger("update"),this._needsUpdate=!1)},_updateRotate:function(e){var t=this._rotateVelocity;this._phi=t.y*e/20+this._phi,this._theta=t.x*e/20+this._theta,this.setAlpha(this.getAlpha()),this.setBeta(this.getBeta()),this._vectorDamping(t,Math.pow(this.damping,e/16))},_updateDistanceOrSize:function(e){"perspective"===this._projection?this._setDistance(this._distance+this._zoomSpeed*e/20):this._setOrthoSize(this._orthoSize+this._zoomSpeed*e/20),this._zoomSpeed*=Math.pow(this.damping,e/16)},_setDistance:function(e){this._distance=Math.max(Math.min(e,this.maxDistance),this.minDistance)},_setOrthoSize:function(e){this._orthoSize=Math.max(Math.min(e,this.maxOrthographicSize),this.minOrthographicSize);var t=this.getCamera(),r=this._orthoSize,i=r/this.viewGL.viewport.height*this.viewGL.viewport.width;t.left=-i/2,t.right=i/2,t.top=r/2,t.bottom=-r/2},_updatePan:function(e){var t=this._panVelocity,r=this._distance,i=this.getCamera(),n=i.worldTransform.y,a=i.worldTransform.x;this._center.scaleAndAdd(a,-t.x*r/200).scaleAndAdd(n,-t.y*r/200),this._vectorDamping(t,0)},_updateTransform:function(){var e=this.getCamera(),t=new vt,r=this._theta+Math.PI/2,i=this._phi+Math.PI/2,n=Math.sin(r);t.x=n*Math.cos(i),t.y=-Math.cos(r),t.z=n*Math.sin(i),e.position.copy(this._center).scaleAndAdd(t,this._distance),e.rotation.identity().rotateY(-this._phi).rotateX(-this._theta)},_startCountingStill:function(){clearTimeout(this._stillTimeout);var e=this.autoRotateAfterStill,t=this;!isNaN(e)&&e>0&&(this._stillTimeout=setTimeout((function(){t._rotating=!0}),1e3*e))},_vectorDamping:function(e,t){var r=e.len();(r*=t)<1e-4&&(r=0),e.normalize().scale(r)},_decomposeTransform:function(){if(this.getCamera()){this.getCamera().updateWorldTransform();var e=this.getCamera().worldTransform.z,t=Math.asin(e.y),r=Math.atan2(e.x,e.z);this._theta=t,this._phi=-r,this.setBeta(this.getBeta()),this.setAlpha(this.getAlpha()),this.getCamera().aspect?this._setDistance(this.getCamera().position.dist(this._center)):this._setOrthoSize(this.getCamera().top-this.getCamera().bottom)}},_mouseDownHandler:function(e){if(!e.target&&!this._isAnimating()){var t=e.offsetX,r=e.offsetY;this.viewGL&&!this.viewGL.containPoint(t,r)||(this.zr.on("mousemove",this._mouseMoveHandler),this.zr.on("mouseup",this._mouseUpHandler),e.event.targetTouches?1===e.event.targetTouches.length&&(this._mode="rotate"):e.event.button===Ao[this.rotateMouseButton]?this._mode="rotate":e.event.button===Ao[this.panMouseButton]?this._mode="pan":this._mode="",this._rotateVelocity.set(0,0),this._rotating=!1,this.autoRotate&&this._startCountingStill(),this._mouseX=e.offsetX,this._mouseY=e.offsetY)}},_mouseMoveHandler:function(e){if(!(e.target&&e.target.__isGLToZRProxy||this._isAnimating())){var t=Eo(this.panSensitivity),r=Eo(this.rotateSensitivity);"rotate"===this._mode?(this._rotateVelocity.y=(e.offsetX-this._mouseX)/this.zr.getHeight()*2*r[0],this._rotateVelocity.x=(e.offsetY-this._mouseY)/this.zr.getWidth()*2*r[1]):"pan"===this._mode&&(this._panVelocity.x=(e.offsetX-this._mouseX)/this.zr.getWidth()*t[0]*400,this._panVelocity.y=(-e.offsetY+this._mouseY)/this.zr.getHeight()*t[1]*400),this._mouseX=e.offsetX,this._mouseY=e.offsetY,e.event.preventDefault()}},_mouseWheelHandler:function(e){if(!this._isAnimating()){var t=e.event.wheelDelta||-e.event.detail;this._zoomHandler(e,t)}},_pinchHandler:function(e){this._isAnimating()||(this._zoomHandler(e,e.pinchScale>1?1:-1),this._mode="")},_zoomHandler:function(e,t){if(0!==t){var r,i=e.offsetX,n=e.offsetY;this.viewGL&&!this.viewGL.containPoint(i,n)||(r="perspective"===this._projection?Math.max(Math.max(Math.min(this._distance-this.minDistance,this.maxDistance-this._distance))/20,.5):Math.max(Math.max(Math.min(this._orthoSize-this.minOrthographicSize,this.maxOrthographicSize-this._orthoSize))/20,.5),this._zoomSpeed=(t>0?-1:1)*r*this.zoomSensitivity,this._rotating=!1,this.autoRotate&&"rotate"===this._mode&&this._startCountingStill(),e.event.preventDefault())}},_mouseUpHandler:function(){this.zr.off("mousemove",this._mouseMoveHandler),this.zr.off("mouseup",this._mouseUpHandler)},_isRightMouseButtonUsed:function(){return"right"===this.rotateMouseButton||"right"===this.panMouseButton},_contextMenuHandler:function(e){this._isRightMouseButtonUsed()&&e.preventDefault()},_addAnimator:function(e){var t=this._animators;return t.push(e),e.done((function(){var r=t.indexOf(e);r>=0&&t.splice(r,1)})),e}});Object.defineProperty(Co.prototype,"autoRotate",{get:function(e){return this._autoRotate},set:function(e){this._autoRotate=e,this._rotating=e}});const Do=Co,Lo={convertToDynamicArray:function(e){e&&this.resetOffset();var t=this.attributes;for(var r in t)e||!t[r].value?t[r].value=[]:t[r].value=Array.prototype.slice.call(t[r].value);e||!this.indices?this.indices=[]:this.indices=Array.prototype.slice.call(this.indices)},convertToTypedArray:function(){var e=this.attributes;for(var t in e)e[t].value&&e[t].value.length>0?e[t].value=new Float32Array(e[t].value):e[t].value=null;this.indices&&this.indices.length>0&&(this.indices=this.vertexCount>65535?new Uint32Array(this.indices):new Uint16Array(this.indices)),this.dirty()}},Po={vec2:pe,vec3:Qe,vec4:Et,mat2:Fn,mat2d:kn,mat3:Dt,mat4:Ye,quat:Rt};var Oo=Po.vec3,No=[[0,0],[1,1]],Io=Vr.extend((function(){return{segmentScale:1,dynamic:!0,useNativeLine:!0,attributes:{position:new Vr.Attribute("position","float",3,"POSITION"),positionPrev:new Vr.Attribute("positionPrev","float",3),positionNext:new Vr.Attribute("positionNext","float",3),prevPositionPrev:new Vr.Attribute("prevPositionPrev","float",3),prevPosition:new Vr.Attribute("prevPosition","float",3),prevPositionNext:new Vr.Attribute("prevPositionNext","float",3),offset:new Vr.Attribute("offset","float",1),color:new Vr.Attribute("color","float",4,"COLOR")}}}),{resetOffset:function(){this._vertexOffset=0,this._triangleOffset=0,this._itemVertexOffsets=[]},setVertexCount:function(e){var t=this.attributes;this.vertexCount!==e&&(t.position.init(e),t.color.init(e),this.useNativeLine||(t.positionPrev.init(e),t.positionNext.init(e),t.offset.init(e)),e>65535?this.indices instanceof Uint16Array&&(this.indices=new Uint32Array(this.indices)):this.indices instanceof Uint32Array&&(this.indices=new Uint16Array(this.indices)))},setTriangleCount:function(e){this.triangleCount!==e&&(this.indices=0===e?null:this.vertexCount>65535?new Uint32Array(3*e):new Uint16Array(3*e))},_getCubicCurveApproxStep:function(e,t,r,i){return 1/(Oo.dist(e,t)+Oo.dist(r,t)+Oo.dist(i,r)+1)*this.segmentScale},getCubicCurveVertexCount:function(e,t,r,i){var n=this._getCubicCurveApproxStep(e,t,r,i),a=Math.ceil(1/n);return this.useNativeLine?2*a:2*a+2},getCubicCurveTriangleCount:function(e,t,r,i){var n=this._getCubicCurveApproxStep(e,t,r,i),a=Math.ceil(1/n);return this.useNativeLine?0:2*a},getLineVertexCount:function(){return this.getPolylineVertexCount(No)},getLineTriangleCount:function(){return this.getPolylineTriangleCount(No)},getPolylineVertexCount:function(e){var t;return t="number"==typeof e?e:"number"!=typeof e[0]?e.length:e.length/3,this.useNativeLine?2*(t-1):2*(t-1)+2},getPolylineTriangleCount:function(e){var t;return t="number"==typeof e?e:"number"!=typeof e[0]?e.length:e.length/3,this.useNativeLine?0:2*Math.max(t-1,0)},addCubicCurve:function(e,t,r,i,n,a){null==a&&(a=1);var o=e[0],s=e[1],l=e[2],h=t[0],u=t[1],c=t[2],d=r[0],f=r[1],p=r[2],m=i[0],g=i[1],_=i[2],v=this._getCubicCurveApproxStep(e,t,r,i),y=v*v,x=y*v,b=3*v,w=3*y,T=6*y,S=6*x,M=o-2*h+d,A=s-2*u+f,E=l-2*c+p,C=3*(h-d)-o+m,D=3*(u-f)-s+g,L=3*(c-p)-l+_,P=o,O=s,N=l,I=(h-o)*b+M*w+C*x,R=(u-s)*b+A*w+D*x,B=(c-l)*b+E*w+L*x,F=M*T+C*S,z=A*T+D*S,G=E*T+L*S,U=C*S,k=D*S,V=L*S,H=0,W=0,j=Math.ceil(1/v),X=new Float32Array(3*(j+1)),q=(X=[],0);for(W=0;W1&&(P=I>0?Math.min(P,m):Math.max(P,m),O=R>0?Math.min(O,g):Math.max(O,g),N=B>0?Math.min(N,_):Math.max(N,_));return this.addPolyline(X,n,a)},addLine:function(e,t,r,i){return this.addPolyline([e,t],r,i)},addPolyline:function(e,t,r,i,n){if(e.length){var a="number"!=typeof e[0];if(null==n&&(n=a?e.length:e.length/3),!(n<2)){null==i&&(i=0),null==r&&(r=1),this._itemVertexOffsets.push(this._vertexOffset);var o,s,l=(a="number"!=typeof e[0])?"number"!=typeof t[0]:t.length/4===n,h=this.attributes.position,u=this.attributes.positionPrev,c=this.attributes.positionNext,d=this.attributes.color,f=this.attributes.offset,p=this.indices,m=this._vertexOffset;r=Math.max(r,.01);for(var g=i;g1&&(h.copy(m,m-1),d.copy(m,m-1),m++):(g0&&(c.set(m-2,o),c.set(m-1,o)),h.set(m,o),h.set(m+1,o),d.set(m,s),d.set(m+1,s),f.set(m,r/2),f.set(m+1,-r/2),m+=2),this.useNativeLine)d.set(m,s),h.set(m,o),m++;else if(g>0){var y=3*this._triangleOffset;(p=this.indices)[y]=m-4,p[y+1]=m-3,p[y+2]=m-2,p[y+3]=m-3,p[y+4]=m-1,p[y+5]=m-2,this._triangleOffset+=2}}if(!this.useNativeLine){var x=this._vertexOffset,b=this._vertexOffset+2*n;u.copy(x,x+2),u.copy(x+1,x+3),c.copy(b-1,b-3),c.copy(b-2,b-4)}return this._vertexOffset=m,this._vertexOffset}}},setItemColor:function(e,t){for(var r=this._itemVertexOffsets[e],i=eo&&(n=this._x=0,a+=this._rowHeight+l,this._y=a,this._rowHeight=0),this._x+=t+l,this._rowHeight=Math.max(this._rowHeight,r),a+r+l>s)return null;e.x+=this.offsetX*this.dpr+n,e.y+=this.offsetY*this.dpr+a,this._zr.add(e);var h=[this.offsetX/this.width,this.offsetY/this.height];return[[n/o+h[0],a/s+h[1]],[(n+t)/o+h[0],(a+r)/s+h[1]]]},_fitElement:function(e,t,r){var i=e.getBoundingRect(),n=t/i.width,a=r/i.height;e.x=-i.x*n,e.y=-i.y*a,e.scaleX=n,e.scaleY=a,e.update()}},Fo.prototype={clear:function(){for(var e=0;e=e)){var n=(r+this._nodeWidth)*this._dpr,a=(i+this._nodeHeight)*this._dpr;try{this._zr.resize({width:n,height:a})}catch(e){this._canvas.width=n,this._canvas.height=a}var o=new Bo(this._zr,r,i,this._nodeWidth,this._nodeHeight,this._gap,this._dpr);return this._textureAtlasNodes.push(o),o}},add:function(e,t,r){if(this._coords[e.id])return this._coords[e.id];var i=this._getCurrentNode().add(e,t,r);if(!i){var n=this._expand();if(!n)return;i=n.add(e,t,r)}return this._coords[e.id]=i,i},getCoordsScale:function(){var e=this._dpr;return[this._nodeWidth/this._canvas.width*e,this._nodeHeight/this._canvas.height*e]},getCoords:function(e){return this._coords[e]},dispose:function(){this._zr.dispose()}};const zo=Fo;function Go(){}Go.prototype={constructor:Go,setScene:function(e){this._scene=e,this._skybox&&this._skybox.attachScene(this._scene)},initLight:function(e){this._lightRoot=e,this.mainLight=new Ka.DirectionalLight({shadowBias:.005}),this.ambientLight=new Ka.AmbientLight,e.add(this.mainLight),e.add(this.ambientLight)},dispose:function(){this._lightRoot&&(this._lightRoot.remove(this.mainLight),this._lightRoot.remove(this.ambientLight))},updateLight:function(e){var t=this.mainLight,r=this.ambientLight,i=e.getModel("light"),n=i.getModel("main"),a=i.getModel("ambient");t.intensity=n.get("intensity"),r.intensity=a.get("intensity"),t.color=Ka.parseColor(n.get("color")).slice(0,3),r.color=Ka.parseColor(a.get("color")).slice(0,3);var o=n.get("alpha")||0,s=n.get("beta")||0;t.position.setArray(Ka.directionFromAlphaBeta(o,s)),t.lookAt(Ka.Vector3.ZERO),t.castShadow=n.get("shadow"),t.shadowResolution=Ka.getShadowResolution(n.get("shadowQuality"))},updateAmbientCubemap:function(e,t,r){var i=t.getModel("light.ambientCubemap"),n=i.get("texture");if(n){this._cubemapLightsCache=this._cubemapLightsCache||{};var a=this._cubemapLightsCache[n];if(!a){var o=this;a=this._cubemapLightsCache[n]=Ka.createAmbientCubemap(i.option,e,r,(function(){o._isSkyboxFromAmbientCubemap&&o._skybox.setEnvironmentMap(a.specular.cubemap),r.getZr().refresh()}))}this._lightRoot.add(a.diffuse),this._lightRoot.add(a.specular),this._currentCubemapLights=a}else this._currentCubemapLights&&(this._lightRoot.remove(this._currentCubemapLights.diffuse),this._lightRoot.remove(this._currentCubemapLights.specular),this._currentCubemapLights=null)},updateSkybox:function(e,t,r){var n=t.get("environment"),a=this,o=(a._skybox=a._skybox||new ji,a._skybox);if(n&&"none"!==n)if("auto"===n)if(this._isSkyboxFromAmbientCubemap=!0,this._currentCubemapLights){var s=this._currentCubemapLights.specular.cubemap;o.setEnvironmentMap(s),this._scene&&o.attachScene(this._scene),o.material.set("lod",3)}else this._skybox&&this._skybox.detachScene();else if("object"==typeof n&&n.colorStops||"string"==typeof n&&i.color.parse(n)){this._isSkyboxFromAmbientCubemap=!1;var l=new Ka.Texture2D({anisotropic:8,flipY:!1});o.setEnvironmentMap(l);var h=l.image=document.createElement("canvas");h.width=h.height=16;var u=h.getContext("2d"),c=new i.graphic.Rect({shape:{x:0,y:0,width:16,height:16},style:{fill:n}});i.innerDrawElementOnCanvas(u,c),o.attachScene(this._scene)}else this._isSkyboxFromAmbientCubemap=!1,l=Ka.loadTexture(n,r,{anisotropic:8,flipY:!1}),o.setEnvironmentMap(l),o.attachScene(this._scene);else this._skybox&&this._skybox.detachScene(this._scene),this._skybox=null;var d=t.coordinateSystem;if(this._skybox)if(!d||!d.viewGL||"auto"===n||n.match&&n.match(/.hdr$/))this._skybox.material.undefine("fragment","SRGB_DECODE");else{var f=d.viewGL.isLinearSpace()?"define":"undefine";this._skybox.material[f]("fragment","SRGB_DECODE")}}};const Uo=Go;var ko=Po.vec3,Vo=Vr.extend((function(){return{segmentScale:1,useNativeLine:!0,attributes:{position:new Vr.Attribute("position","float",3,"POSITION"),normal:new Vr.Attribute("normal","float",3,"NORMAL"),color:new Vr.Attribute("color","float",4,"COLOR")}}}),{resetOffset:function(){this._vertexOffset=0,this._faceOffset=0},setQuadCount:function(e){var t=this.attributes,r=this.getQuadVertexCount()*e,i=this.getQuadTriangleCount()*e;this.vertexCount!==r&&(t.position.init(r),t.normal.init(r),t.color.init(r)),this.triangleCount!==i&&(this.indices=r>65535?new Uint32Array(3*i):new Uint16Array(3*i))},getQuadVertexCount:function(){return 4},getQuadTriangleCount:function(){return 2},addQuad:function(){var e=ko.create(),t=ko.create(),r=ko.create(),i=[0,3,1,3,2,1];return function(n,a){var o=this.attributes.position,s=this.attributes.normal,l=this.attributes.color;ko.sub(e,n[1],n[0]),ko.sub(t,n[2],n[1]),ko.cross(r,e,t),ko.normalize(r,r);for(var h=0;h<4;h++)o.set(this._vertexOffset+h,n[h]),l.set(this._vertexOffset+h,a),s.set(this._vertexOffset+h,r);var u=3*this._faceOffset;for(h=0;h<6;h++)this.indices[u+h]=i[h]+this._vertexOffset;this._vertexOffset+=4,this._faceOffset+=2}}()});i.util.defaults(Vo.prototype,Lo);const Ho=Vo;var Wo=Mn,jo={x:0,y:2,z:1};function Xo(e,t,r){this.rootNode=new Ka.Node;var i=new Ka.Mesh({geometry:new Ro({useNativeLine:!1}),material:t,castShadow:!1,ignorePicking:!0,$ignorePicking:!0,renderOrder:1}),n=new Ka.Mesh({geometry:new Ho,material:r,castShadow:!1,culling:!1,ignorePicking:!0,$ignorePicking:!0,renderOrder:0});this.rootNode.add(n),this.rootNode.add(i),this.faceInfo=e,this.plane=new Ka.Plane,this.linesMesh=i,this.quadsMesh=n}Xo.prototype.update=function(e,t,r){var i=e.coordinateSystem,n=[i.getAxis(this.faceInfo[0]),i.getAxis(this.faceInfo[1])],a=this.linesMesh.geometry,o=this.quadsMesh.geometry;a.convertToDynamicArray(!0),o.convertToDynamicArray(!0),this._updateSplitLines(a,n,e,r),this._udpateSplitAreas(o,n,e,r),a.convertToTypedArray(),o.convertToTypedArray();var s=i.getAxis(this.faceInfo[2]);!function(e,t,r,i){var n=[0,0,0],a=i<0?r.getExtentMin():r.getExtentMax();n[jo[r.dim]]=a,e.position.setArray(n),e.rotation.identity(),t.distance=-Math.abs(a),t.normal.set(0,0,0),"x"===r.dim?(e.rotation.rotateY(i*Math.PI/2),t.normal.x=-i):"z"===r.dim?(e.rotation.rotateX(-i*Math.PI/2),t.normal.y=-i):(i>0&&e.rotation.rotateY(Math.PI),t.normal.z=-i)}(this.rootNode,this.plane,s,this.faceInfo[3])},Xo.prototype._updateSplitLines=function(e,t,r,n){var a=n.getDevicePixelRatio();t.forEach((function(n,o){var s=n.model,l=t[1-o].getExtent();if(!n.scale.isBlank()){var h=s.getModel("splitLine",r.getModel("splitLine"));if(h.get("show")){var u=h.getModel("lineStyle"),c=u.get("color"),d=Wo(u.get("opacity"),1),f=Wo(u.get("width"),1);c=i.util.isArray(c)?c:[c];for(var p=n.getTicksCoords({tickModel:h}),m=0,g=0;g65535?new Uint32Array(3*r):new Uint16Array(3*r))},setSpriteAlign:function(e,t,r,i,n){var a,o,s,l;switch(null==r&&(r="left"),null==i&&(i="top"),n=n||0,r){case"left":a=n,s=t[0]+n;break;case"center":case"middle":a=-t[0]/2,s=t[0]/2;break;case"right":a=-t[0]-n,s=-n}switch(i){case"bottom":o=n,l=t[1]+n;break;case"middle":o=-t[1]/2,l=t[1]/2;break;case"top":o=-t[1]-n,l=-n}var h=4*e,u=this.attributes.offset;u.set(h,[a,l]),u.set(h+1,[s,l]),u.set(h+2,[s,o]),u.set(h+3,[a,o])},addSprite:function(e,t,r,i,n,a){var o=this._vertexOffset;this.setSprite(this._vertexOffset/4,e,t,r,i,n,a);for(var s=0;s 0.0) {\n currProj = clipNear(currProj, nextProj);\n }\n else if (prevProj.w > 0.0) {\n currProj = clipNear(currProj, prevProj);\n }\n }\n\n vec2 prevScreen = (prevProj.xy / abs(prevProj.w) + 1.0) * 0.5 * viewport.zw;\n vec2 currScreen = (currProj.xy / abs(currProj.w) + 1.0) * 0.5 * viewport.zw;\n vec2 nextScreen = (nextProj.xy / abs(nextProj.w) + 1.0) * 0.5 * viewport.zw;\n\n vec2 dir;\n float len = offset;\n if (position == positionPrev) {\n dir = normalize(nextScreen - currScreen);\n }\n else if (position == positionNext) {\n dir = normalize(currScreen - prevScreen);\n }\n else {\n vec2 dirA = normalize(currScreen - prevScreen);\n vec2 dirB = normalize(nextScreen - currScreen);\n\n vec2 tanget = normalize(dirA + dirB);\n\n float miter = 1.0 / max(dot(tanget, dirA), 0.5);\n len *= miter;\n dir = tanget;\n }\n\n dir = vec2(-dir.y, dir.x) * len;\n currScreen += dir;\n\n currProj.xy = (currScreen / viewport.zw - 0.5) * 2.0 * abs(currProj.w);\n@end\n\n\n@export ecgl.meshLines3D.vertex\n\nattribute vec3 position: POSITION;\nattribute vec3 positionPrev;\nattribute vec3 positionNext;\nattribute float offset;\nattribute vec4 a_Color : COLOR;\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute vec3 prevPositionPrev;\nattribute vec3 prevPositionNext;\nuniform float percent : 1.0;\n#endif\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\nuniform float near : NEAR;\n\nvarying vec4 v_Color;\n\n@import ecgl.common.wireframe.vertexHeader\n\n@import ecgl.lines3D.clipNear\n\nvoid main()\n{\n @import ecgl.lines3D.expandLine\n\n gl_Position = currProj;\n\n v_Color = a_Color;\n\n @import ecgl.common.wireframe.vertexMain\n}\n@end\n\n\n@export ecgl.meshLines3D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\n@import ecgl.common.wireframe.fragmentHeader\n\n@import clay.util.srgb\n\nvoid main()\n{\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n\n @import ecgl.common.wireframe.fragmentMain\n}\n\n@end";var ns=Mn;Ka.Shader.import(is);var as={x:0,y:2,z:1};const os=i.ComponentView.extend({type:"grid3D",__ecgl__:!0,init:function(e,t){var r=new Ka.Material({shader:Ka.createShader("ecgl.color"),depthMask:!1,transparent:!0}),i=new Ka.Material({shader:Ka.createShader("ecgl.meshLines3D"),depthMask:!1,transparent:!0});r.define("fragment","DOUBLE_SIDED"),r.define("both","VERTEX_COLOR"),this.groupGL=new Ka.Node,this._control=new Do({zr:t.getZr()}),this._control.init(),this._faces=[["y","z","x",-1,"left"],["y","z","x",1,"right"],["x","y","z",-1,"bottom"],["x","y","z",1,"top"],["x","z","y",-1,"far"],["x","z","y",1,"near"]].map((function(e){var t=new qo(e,i,r);return this.groupGL.add(t.rootNode),t}),this),this._axes=["x","y","z"].map((function(e){var t=new rs(e,i);return this.groupGL.add(t.rootNode),t}),this);var n=t.getDevicePixelRatio();this._axisLabelSurface=new zo({width:256,height:256,devicePixelRatio:n}),this._axisLabelSurface.onupdate=function(){t.getZr().refresh()},this._axisPointerLineMesh=new Ka.Mesh({geometry:new Ro({useNativeLine:!1}),material:i,castShadow:!1,ignorePicking:!0,renderOrder:3}),this.groupGL.add(this._axisPointerLineMesh),this._axisPointerLabelsSurface=new zo({width:128,height:128,devicePixelRatio:n}),this._axisPointerLabelsMesh=new Qo({ignorePicking:!0,renderOrder:4,castShadow:!1}),this._axisPointerLabelsMesh.material.set("textureAtlas",this._axisPointerLabelsSurface.getTexture()),this.groupGL.add(this._axisPointerLabelsMesh),this._lightRoot=new Ka.Node,this._sceneHelper=new Uo,this._sceneHelper.initLight(this._lightRoot)},render:function(e,t,r){this._model=e,this._api=r;var i=e.coordinateSystem;i.viewGL.add(this._lightRoot),e.get("show")?i.viewGL.add(this.groupGL):i.viewGL.remove(this.groupGL);var n=this._control;n.setViewGL(i.viewGL);var a=e.getModel("viewControl");n.setFromViewControlModel(a,0),this._axisLabelSurface.clear(),n.off("update"),e.get("show")&&(this._faces.forEach((function(i){i.update(e,t,r)}),this),this._axes.forEach((function(t){t.update(e,this._axisLabelSurface,r)}),this)),n.on("update",this._onCameraChange.bind(this,e,r),this),this._sceneHelper.setScene(i.viewGL.scene),this._sceneHelper.updateLight(e),i.viewGL.setPostEffect(e.getModel("postEffect"),r),i.viewGL.setTemporalSuperSampling(e.getModel("temporalSuperSampling")),this._initMouseHandler(e)},afterRender:function(e,t,r,i){var n=i.renderer;this._sceneHelper.updateAmbientCubemap(n,e,r),this._sceneHelper.updateSkybox(n,e,r)},showAxisPointer:function(e,t,r,i){this._doShowAxisPointer(),this._updateAxisPointer(i.value)},hideAxisPointer:function(e,t,r,i){this._doHideAxisPointer()},_initMouseHandler:function(e){var t=e.coordinateSystem.viewGL;e.get("show")&&e.get("axisPointer.show")?t.on("mousemove",this._updateAxisPointerOnMousePosition,this):t.off("mousemove",this._updateAxisPointerOnMousePosition)},_updateAxisPointerOnMousePosition:function(e){if(!e.target){for(var t,r=this._model.coordinateSystem,i=r.viewGL,n=i.castRay(e.offsetX,e.offsetY,new Ka.Ray),a=0;ai[1]?0:1,o=this._faces[2*r+a],s=this._faces[2*r+1-a];o.rootNode.invisible=!0,s.rootNode.invisible=!1}},_updateAxisLinePosition:function(){var e=this._model.coordinateSystem,t=e.getAxis("x"),r=e.getAxis("y"),i=e.getAxis("z"),n=i.getExtentMax(),a=i.getExtentMin(),o=t.getExtentMin(),s=t.getExtentMax(),l=r.getExtentMax(),h=r.getExtentMin(),u=this._axes[0].rootNode,c=this._axes[1].rootNode,d=this._axes[2].rootNode,f=this._faces,p=f[4].rootNode.invisible?h:l,m=f[2].rootNode.invisible?n:a,g=f[0].rootNode.invisible?o:s,_=f[2].rootNode.invisible?n:a,v=f[0].rootNode.invisible?s:o,y=f[4].rootNode.invisible?h:l;u.rotation.identity(),c.rotation.identity(),d.rotation.identity(),f[4].rootNode.invisible&&(this._axes[0].flipped=!0,u.rotation.rotateX(Math.PI)),f[0].rootNode.invisible&&(this._axes[1].flipped=!0,c.rotation.rotateZ(Math.PI)),f[4].rootNode.invisible&&(this._axes[2].flipped=!0,d.rotation.rotateY(Math.PI)),u.position.set(0,m,p),c.position.set(g,_,0),d.position.set(v,0,y),u.update(),c.update(),d.update(),this._updateAxisLabelAlign()},_updateAxisLabelAlign:function(){var e=this._control.getCamera(),t=[new Ka.Vector4,new Ka.Vector4],r=new Ka.Vector4;this.groupGL.getWorldPosition(r),r.w=1,r.transformMat4(e.viewMatrix).transformMat4(e.projectionMatrix),r.x/=r.w,r.y/=r.w,this._axes.forEach((function(i){for(var n=i.axisLineCoords,a=(i.labelsMesh.geometry,0);ar.y?"bottom":"top"):(s="middle",o=u>r.x?"left":"right"),i.setSpriteAlign(o,s,this._api)}),this)},_doShowAxisPointer:function(){this._axisPointerLineMesh.invisible&&(this._axisPointerLineMesh.invisible=!1,this._axisPointerLabelsMesh.invisible=!1,this._api.getZr().refresh())},_doHideAxisPointer:function(){this._axisPointerLineMesh.invisible||(this._axisPointerLineMesh.invisible=!0,this._axisPointerLabelsMesh.invisible=!0,this._api.getZr().refresh())},_updateAxisPointer:function(e){var t=this._model.coordinateSystem,r=t.dataToPoint(e),i=this._axisPointerLineMesh.geometry,n=this._model.getModel("axisPointer"),a=this._api.getDevicePixelRatio();function o(e){return Mn(e.model.get("axisPointer.show"),n.get("show"))}function s(e){var t=e.model.getModel("axisPointer",n).getModel("lineStyle"),r=Ka.parseColor(t.get("color")),i=ns(t.get("width"),1),a=ns(t.get("opacity"),1);return r[3]*=a,{color:r,lineWidth:i}}i.convertToDynamicArray(!0);for(var l=0;lp&&(p=y,mp&&(p=x,_=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e.prototype.copy=function(t){e.copy(this,t)},e.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},e.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},e.prototype.isZero=function(){return 0===this.width||0===this.height},e.create=function(t){return new e(t.x,t.y,t.width,t.height)},e.copy=function(e,t){e.x=t.x,e.y=t.y,e.width=t.width,e.height=t.height},e.applyTransform=function(t,r,i){if(i){if(i[1]<1e-5&&i[1]>-1e-5&&i[2]<1e-5&&i[2]>-1e-5){var n=i[0],a=i[3],o=i[4],s=i[5];return t.x=r.x*n+o,t.y=r.y*a+s,t.width=r.width*n,t.height=r.height*a,t.width<0&&(t.x+=t.width,t.width=-t.width),void(t.height<0&&(t.y+=t.height,t.height=-t.height))}gs.x=vs.x=r.x,gs.y=ys.y=r.y,_s.x=ys.x=r.x+r.width,_s.y=vs.y=r.y+r.height,gs.transform(i),ys.transform(i),_s.transform(i),vs.transform(i),t.x=ps(gs.x,_s.x,vs.x,ys.x),t.y=ps(gs.y,_s.y,vs.y,ys.y);var l=ms(gs.x,_s.x,vs.x,ys.x),h=ms(gs.y,_s.y,vs.y,ys.y);t.width=l-t.x,t.height=h-t.y}else t!==r&&e.copy(t,r)},e}();function Ts(e,t,r,i,n){var a=0,o=0;null==i&&(i=1/0),null==n&&(n=1/0);var s=0;t.eachChild((function(l,h){var u,c,d=l.getBoundingRect(),f=t.childAt(h+1),p=f&&f.getBoundingRect();if("horizontal"===e){var m=d.width+(p?-p.x+d.x:0);(u=a+m)>i||l.newline?(a=0,u=m,o+=s+r,s=d.height):s=Math.max(s,d.height)}else{var g=d.height+(p?-p.y+d.y:0);(c=o+g)>n||l.newline?(a+=s+r,o=0,c=g,s=d.width):s=Math.max(s,d.width)}l.newline||(l.x=a,l.y=o,l.markRedraw(),"horizontal"===e?a=u+r:o=c+r)}))}function Ss(e,t,r){r=function(e){if("number"==typeof e)return[e,e,e,e];var t=e.length;return 2===t?[e[0],e[1],e[0],e[1]]:3===t?[e[0],e[1],e[2],e[1]]:e}(r||0);var i=t.width,n=t.height,a=go(e.left,i),o=go(e.top,n),s=go(e.right,i),l=go(e.bottom,n),h=go(e.width,i),u=go(e.height,n),c=r[2]+r[0],d=r[1]+r[3],f=e.aspect;switch(isNaN(h)&&(h=i-s-d-a),isNaN(u)&&(u=n-l-c-o),null!=f&&(isNaN(h)&&isNaN(u)&&(f>i/n?h=.8*i:u=.8*n),isNaN(h)&&(h=f*u),isNaN(u)&&(u=h/f)),isNaN(a)&&(a=i-s-h-d),isNaN(o)&&(o=n-l-u-c),e.left||e.right){case"center":a=i/2-h/2-r[3];break;case"right":a=i-h-d}switch(e.top||e.bottom){case"middle":case"center":o=n/2-u/2-r[0];break;case"bottom":o=n-u-c}a=a||0,o=o||0,isNaN(h)&&(h=i-d-a-(s||0)),isNaN(u)&&(u=n-c-o-(l||0));var p=new ws(a+r[3],o+r[0],h,u);return p.margin=r,p}wa(Ts,"vertical"),wa(Ts,"horizontal");var Ms=function(){this._pool={},this._allocatedTextures=[]};Ms.prototype={constructor:Ms,get:function(e){var t=Cs(e);this._pool.hasOwnProperty(t)||(this._pool[t]=[]);var r=this._pool[t];if(!r.length){var i=new Dr(e);return this._allocatedTextures.push(i),i}return r.pop()},put:function(e){var t=Cs(e);this._pool.hasOwnProperty(t)||(this._pool[t]=[]),this._pool[t].push(e)},clear:function(e){for(var t=0;t 0.0) {\n if (texture2D(alphaMap, v_Texcoord).a <= alphaCutoff) {\n discard;\n }\n }\n#ifdef USE_VSM\n depth = depth * 0.5 + 0.5;\n float moment1 = depth;\n float moment2 = depth * depth;\n #ifdef SUPPORT_STANDARD_DERIVATIVES\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n moment2 += 0.25*(dx*dx+dy*dy);\n #endif\n gl_FragColor = vec4(moment1, moment2, 0.0, 1.0);\n#else\n #ifdef SUPPORT_STANDARD_DERIVATIVES\n float dx = dFdx(depth);\n float dy = dFdy(depth);\n depth += sqrt(dx*dx + dy*dy) * slopeScale + bias;\n #else\n depth += bias;\n #endif\n gl_FragColor = encodeFloat(depth * 0.5 + 0.5);\n#endif\n}\n@end\n@export clay.sm.debug_depth\nuniform sampler2D depthMap;\nvarying vec2 v_Texcoord;\n@import clay.util.decode_float\nvoid main() {\n vec4 tex = texture2D(depthMap, v_Texcoord);\n#ifdef USE_VSM\n gl_FragColor = vec4(tex.rgb, 1.0);\n#else\n float depth = decodeFloat(tex);\n gl_FragColor = vec4(depth, depth, depth, 1.0);\n#endif\n}\n@end\n@export clay.sm.distance.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 world : WORLD;\nattribute vec3 position : POSITION;\n@import clay.chunk.skinning_header\nvarying vec3 v_WorldPosition;\nvoid main (){\n vec4 P = vec4(position, 1.0);\n#ifdef SKINNING\n @import clay.chunk.skin_matrix\n P = skinMatrixWS * P;\n#endif\n#ifdef INSTANCING\n @import clay.chunk.instancing_matrix\n P = instanceMat * P;\n#endif\n gl_Position = worldViewProjection * P;\n v_WorldPosition = (world * P).xyz;\n}\n@end\n@export clay.sm.distance.fragment\nuniform vec3 lightPosition;\nuniform float range : 100;\nvarying vec3 v_WorldPosition;\n@import clay.util.encode_float\nvoid main(){\n float dist = distance(lightPosition, v_WorldPosition);\n#ifdef USE_VSM\n gl_FragColor = vec4(dist, dist * dist, 0.0, 0.0);\n#else\n dist = dist / range;\n gl_FragColor = encodeFloat(dist);\n#endif\n}\n@end\n@export clay.plugin.shadow_map_common\n@import clay.util.decode_float\nfloat tapShadowMap(sampler2D map, vec2 uv, float z){\n vec4 tex = texture2D(map, uv);\n return step(z, decodeFloat(tex) * 2.0 - 1.0);\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize, vec2 scale) {\n float shadowContrib = tapShadowMap(map, uv, z);\n vec2 offset = vec2(1.0 / textureSize) * scale;\n#ifdef PCF_KERNEL_SIZE\n for (int _idx_ = 0; _idx_ < PCF_KERNEL_SIZE; _idx_++) {{\n shadowContrib += tapShadowMap(map, uv + offset * pcfKernel[_idx_], z);\n }}\n return shadowContrib / float(PCF_KERNEL_SIZE + 1);\n#else\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, 0.0), z);\n shadowContrib += tapShadowMap(map, uv+vec2(-offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(offset.x, -offset.y), z);\n shadowContrib += tapShadowMap(map, uv+vec2(0.0, -offset.y), z);\n return shadowContrib / 9.0;\n#endif\n}\nfloat pcf(sampler2D map, vec2 uv, float z, float textureSize) {\n return pcf(map, uv, z, textureSize, vec2(1.0));\n}\nfloat chebyshevUpperBound(vec2 moments, float z){\n float p = 0.0;\n z = z * 0.5 + 0.5;\n if (z <= moments.x) {\n p = 1.0;\n }\n float variance = moments.y - moments.x * moments.x;\n variance = max(variance, 0.0000001);\n float mD = moments.x - z;\n float pMax = variance / (variance + mD * mD);\n pMax = clamp((pMax-0.4)/(1.0-0.4), 0.0, 1.0);\n return max(p, pMax);\n}\nfloat computeShadowContrib(\n sampler2D map, mat4 lightVPM, vec3 position, float textureSize, vec2 scale, vec2 offset\n) {\n vec4 posInLightSpace = lightVPM * vec4(position, 1.0);\n posInLightSpace.xyz /= posInLightSpace.w;\n float z = posInLightSpace.z;\n if(all(greaterThan(posInLightSpace.xyz, vec3(-0.99, -0.99, -1.0))) &&\n all(lessThan(posInLightSpace.xyz, vec3(0.99, 0.99, 1.0)))){\n vec2 uv = (posInLightSpace.xy+1.0) / 2.0;\n #ifdef USE_VSM\n vec2 moments = texture2D(map, uv * scale + offset).xy;\n return chebyshevUpperBound(moments, z);\n #else\n return pcf(map, uv * scale + offset, z, textureSize, scale);\n #endif\n }\n return 1.0;\n}\nfloat computeShadowContrib(sampler2D map, mat4 lightVPM, vec3 position, float textureSize) {\n return computeShadowContrib(map, lightVPM, position, textureSize, vec2(1.0), vec2(0.0));\n}\nfloat computeShadowContribOmni(samplerCube map, vec3 direction, float range)\n{\n float dist = length(direction);\n vec4 shadowTex = textureCube(map, direction);\n#ifdef USE_VSM\n vec2 moments = shadowTex.xy;\n float variance = moments.y - moments.x * moments.x;\n float mD = moments.x - dist;\n float p = variance / (variance + mD * mD);\n if(moments.x + 0.001 < dist){\n return clamp(p, 0.0, 1.0);\n }else{\n return 1.0;\n }\n#else\n return step(dist, (decodeFloat(shadowTex) + 0.0002) * range);\n#endif\n}\n@end\n@export clay.plugin.compute_shadow_map\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT) || defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT) || defined(POINT_LIGHT_SHADOWMAP_COUNT)\n#ifdef SPOT_LIGHT_SHADOWMAP_COUNT\nuniform sampler2D spotLightShadowMaps[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 spotLightMatrices[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float spotLightShadowMapSizes[SPOT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#ifdef DIRECTIONAL_LIGHT_SHADOWMAP_COUNT\n#if defined(SHADOW_CASCADE)\nuniform sampler2D directionalLightShadowMaps[1]:unconfigurable;\nuniform mat4 directionalLightMatrices[SHADOW_CASCADE]:unconfigurable;\nuniform float directionalLightShadowMapSizes[1]:unconfigurable;\nuniform float shadowCascadeClipsNear[SHADOW_CASCADE]:unconfigurable;\nuniform float shadowCascadeClipsFar[SHADOW_CASCADE]:unconfigurable;\n#else\nuniform sampler2D directionalLightShadowMaps[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform mat4 directionalLightMatrices[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\nuniform float directionalLightShadowMapSizes[DIRECTIONAL_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\n#endif\n#ifdef POINT_LIGHT_SHADOWMAP_COUNT\nuniform samplerCube pointLightShadowMaps[POINT_LIGHT_SHADOWMAP_COUNT]:unconfigurable;\n#endif\nuniform bool shadowEnabled : true;\n#ifdef PCF_KERNEL_SIZE\nuniform vec2 pcfKernel[PCF_KERNEL_SIZE];\n#endif\n@import clay.plugin.shadow_map_common\n#if defined(SPOT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfSpotLights(vec3 position, inout float shadowContribs[SPOT_LIGHT_COUNT] ) {\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < SPOT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n spotLightShadowMaps[_idx_], spotLightMatrices[_idx_], position,\n spotLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = SPOT_LIGHT_SHADOWMAP_COUNT; _idx_ < SPOT_LIGHT_COUNT; _idx_++){{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#if defined(DIRECTIONAL_LIGHT_SHADOWMAP_COUNT)\n#ifdef SHADOW_CASCADE\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float depth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far)\n / (gl_DepthRange.far - gl_DepthRange.near);\n float shadowContrib;\n shadowContribs[0] = 1.0;\n for (int _idx_ = 0; _idx_ < SHADOW_CASCADE; _idx_++) {{\n if (\n depth >= shadowCascadeClipsNear[_idx_] &&\n depth <= shadowCascadeClipsFar[_idx_]\n ) {\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[0], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[0],\n vec2(1.0 / float(SHADOW_CASCADE), 1.0),\n vec2(float(_idx_) / float(SHADOW_CASCADE), 0.0)\n );\n shadowContribs[0] = shadowContrib;\n }\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#else\nvoid computeShadowOfDirectionalLights(vec3 position, inout float shadowContribs[DIRECTIONAL_LIGHT_COUNT]){\n float shadowContrib;\n for(int _idx_ = 0; _idx_ < DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n shadowContrib = computeShadowContrib(\n directionalLightShadowMaps[_idx_], directionalLightMatrices[_idx_], position,\n directionalLightShadowMapSizes[_idx_]\n );\n shadowContribs[_idx_] = shadowContrib;\n }}\n for(int _idx_ = DIRECTIONAL_LIGHT_SHADOWMAP_COUNT; _idx_ < DIRECTIONAL_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n#if defined(POINT_LIGHT_SHADOWMAP_COUNT)\nvoid computeShadowOfPointLights(vec3 position, inout float shadowContribs[POINT_LIGHT_COUNT] ){\n vec3 lightPosition;\n vec3 direction;\n for(int _idx_ = 0; _idx_ < POINT_LIGHT_SHADOWMAP_COUNT; _idx_++) {{\n lightPosition = pointLightPosition[_idx_];\n direction = position - lightPosition;\n shadowContribs[_idx_] = computeShadowContribOmni(pointLightShadowMaps[_idx_], direction, pointLightRange[_idx_]);\n }}\n for(int _idx_ = POINT_LIGHT_SHADOWMAP_COUNT; _idx_ < POINT_LIGHT_COUNT; _idx_++) {{\n shadowContribs[_idx_] = 1.0;\n }}\n}\n#endif\n#endif\n@end");var Ns,Is,Rs,Bs,Fs,zs,Gs,Us=m.extend((function(){return{softShadow:Us.PCF,shadowBlur:1,lightFrustumBias:"auto",kernelPCF:new Float32Array([1,0,1,1,-1,1,0,1,-1,0,-1,-1,1,-1,0,-1]),precision:"highp",_lastRenderNotCastShadow:!1,_frameBuffer:new zi,_textures:{},_shadowMapNumber:{POINT_LIGHT:0,DIRECTIONAL_LIGHT:0,SPOT_LIGHT:0},_depthMaterials:{},_distanceMaterials:{},_receivers:[],_lightsCastShadow:[],_lightCameras:{},_lightMaterials:{},_texturePool:new Ds}}),(function(){this._gaussianPassH=new pn({fragment:Xe.source("clay.compositor.gaussian_blur")}),this._gaussianPassV=new pn({fragment:Xe.source("clay.compositor.gaussian_blur")}),this._gaussianPassH.setUniform("blurSize",this.shadowBlur),this._gaussianPassH.setUniform("blurDir",0),this._gaussianPassV.setUniform("blurSize",this.shadowBlur),this._gaussianPassV.setUniform("blurDir",1),this._outputDepthPass=new pn({fragment:Xe.source("clay.sm.debug_depth")})}),{render:function(e,t,r,i){r||(r=t.getMainCamera()),this.trigger("beforerender",this,e,t,r),this._renderShadowPass(e,t,r,i),this.trigger("afterrender",this,e,t,r)},renderDebug:function(e,t){e.saveClear();var r=e.viewport,i=0,n=t||r.width/4,a=n;for(var o in this.softShadow===Us.VSM?this._outputDepthPass.material.define("fragment","USE_VSM"):this._outputDepthPass.material.undefine("fragment","USE_VSM"),this._textures){var s=this._textures[o];e.setViewport(i,0,n*s.width/s.height,a),this._outputDepthPass.setUniform("depthMap",s),this._outputDepthPass.render(e),i+=n*s.width/s.height}e.setViewport(r),e.restoreClear()},_updateReceivers:function(e,t){if(t.receiveShadow?(this._receivers.push(t),t.material.set("shadowEnabled",1),t.material.set("pcfKernel",this.kernelPCF)):t.material.set("shadowEnabled",0),this.softShadow===Us.VSM)t.material.define("fragment","USE_VSM"),t.material.undefine("fragment","PCF_KERNEL_SIZE");else{t.material.undefine("fragment","USE_VSM");var r=this.kernelPCF;r&&r.length?t.material.define("fragment","PCF_KERNEL_SIZE",r.length/2):t.material.undefine("fragment","PCF_KERNEL_SIZE")}},_update:function(e,t){var r=this;t.traverse((function(t){t.isRenderable()&&r._updateReceivers(e,t)}));for(var i=0;i4){console.warn("Support at most 4 cascade");continue}p.shadowCascade>1&&(o=p),this.renderDirectionalLightShadow(e,t,r,p,c,u,h)}else"SPOT_LIGHT"===p.type?this.renderSpotLightShadow(e,t,p,l,s):"POINT_LIGHT"===p.type&&this.renderPointLightShadow(e,t,p,d);this._shadowMapNumber[p.type]++}for(var m in this._shadowMapNumber){var g=this._shadowMapNumber[m],_=m+"_SHADOWMAP_COUNT";for(f=0;f0?v.define("fragment",_,g):v.isDefined("fragment",_)&&v.undefine("fragment",_))}for(f=0;f0){var x=h.map(S);if(y.directionalLightShadowMaps={value:h,type:"tv"},y.directionalLightMatrices={value:u,type:"m4v"},y.directionalLightShadowMapSizes={value:x,type:"1fv"},o){var b=c.slice(),w=c.slice();b.pop(),w.shift(),b.reverse(),w.reverse(),u.reverse(),y.shadowCascadeClipsNear={value:b,type:"1fv"},y.shadowCascadeClipsFar={value:w,type:"1fv"}}}if(s.length>0){var T=s.map(S);(y=t.shadowUniforms).spotLightShadowMaps={value:s,type:"tv"},y.spotLightMatrices={value:l,type:"m4v"},y.spotLightShadowMapSizes={value:T,type:"1fv"}}d.length>0&&(y.pointLightShadowMaps={value:d,type:"tv"})}function S(e){return e.height}},renderDirectionalLightShadow:(Ns=new si,Is=new Ht,Rs=new ir,Bs=new Ht,Fs=new Ht,zs=new Ht,Gs=new Ht,function(e,t,r,i,n,a,o){var s=this._getDepthMaterial(i),l={getMaterial:function(e){return e.shadowDepthMaterial||s},isMaterialChanged:Os,getUniform:Ps,ifRender:function(e){return e.castShadow},sortCompare:ut.opaqueSortCompare};if(!t.viewBoundingBoxLastFrame.isFinite()){var h=t.getBoundingBox();t.viewBoundingBoxLastFrame.copy(h).applyTransform(r.viewMatrix)}var u=Math.min(-t.viewBoundingBoxLastFrame.min.z,r.far),c=Math.max(-t.viewBoundingBoxLastFrame.max.z,r.near),d=this._getDirectionalLightCamera(i,t,r),f=zs.array;Gs.copy(d.projectionMatrix),Ye.invert(Fs.array,d.worldTransform.array),Ye.multiply(Fs.array,Fs.array,r.worldTransform.array),Ye.multiply(f,Gs.array,Fs.array);for(var p=[],m=r instanceof Ei,g=(r.near+r.far)/(r.near-r.far),_=2*r.near*r.far/(r.near-r.far),v=0;v<=i.shadowCascade;v++){var y=c*Math.pow(u/c,v/i.shadowCascade),x=c+(u-c)*v/i.shadowCascade,b=y*i.cascadeSplitLogFactor+x*(1-i.cascadeSplitLogFactor);p.push(b),n.push(-(-b*g+_)/-b)}var w=this._getTexture(i,i.shadowCascade);o.push(w);var T=e.viewport,S=e.gl;for(this._frameBuffer.attach(w),this._frameBuffer.bind(e),S.clear(S.COLOR_BUFFER_BIT|S.DEPTH_BUFFER_BIT),v=0;vd?s>f?p[n>0?"px":"nx"]=!0:p[o>0?"pz":"nz"]=!0:d>f?p[a>0?"py":"ny"]=!0:p[o>0?"pz":"nz"]=!0}for(r=0;r0&&(this.outputs[e].keepLastFrame?(this._prevOutputTextures[e]&&this._compositor.releaseTexture(this._prevOutputTextures[e]),this._prevOutputTextures[e]=this._outputTextures[e]):this._compositor.releaseTexture(this._outputTextures[e]))}}),Hs=m.extend((function(){return{nodes:[]}}),{dirty:function(){this._dirty=!0},addNode:function(e){this.nodes.indexOf(e)>=0||(this.nodes.push(e),this._dirty=!0)},removeNode:function(e){"string"==typeof e&&(e=this.getNodeByName(e));var t=this.nodes.indexOf(e);t>=0&&(this.nodes.splice(t,1),this._dirty=!0)},getNodeByName:function(e){for(var t=0;t=r.COLOR_ATTACHMENT0&&u<=r.COLOR_ATTACHMENT0+8&&h.push(u);l.drawBuffersEXT(h)}e.saveClear(),e.clearBit=16640,t=e.render(this.scene,this.camera,!this.autoUpdateScene,this.preZ),e.restoreClear(),i.unbind(e)}else t=e.render(this.scene,this.camera,!this.autoUpdateScene,this.preZ);this.trigger("afterrender",t),this._rendering=!1,this._rendered=!0}}),Xs=Vs.extend((function(){return{texture:null,outputs:{color:{}}}}),(function(){}),{getOutput:function(e,t){return this.texture},beforeFrame:function(){},afterFrame:function(){}}),qs=Vs.extend((function(){return{name:"",inputs:{},outputs:null,shader:"",inputLinks:{},outputLinks:{},pass:null,_prevOutputTextures:{},_outputTextures:{},_outputReferences:{},_rendering:!1,_rendered:!1,_compositor:null}}),(function(){var e=new pn({fragment:this.shader});this.pass=e}),{render:function(e,t){this.trigger("beforerender",e),this._rendering=!0;var r=e.gl;for(var i in this.inputLinks){var n=(c=this.inputLinks[i]).node.getOutput(e,c.pin);this.pass.setUniform(i,n)}if(this.outputs){this.pass.outputs={};var a={};for(var o in this.outputs){var s=this.updateParameter(o,e);isNaN(s.width)&&this.updateParameter(o,e);var l=this.outputs[o],h=this._compositor.allocateTexture(s);this._outputTextures[o]=h,"string"==typeof(u=l.attachment||r.COLOR_ATTACHMENT0)&&(u=r[u]),a[u]=h}for(var u in this._compositor.getFrameBuffer().bind(e),a)this._compositor.getFrameBuffer().attach(a[u],u);this.pass.render(e),this._compositor.getFrameBuffer().updateMipmap(e)}else this.pass.outputs=null,this._compositor.getFrameBuffer().unbind(e),this.pass.render(e,t);for(var i in this.inputLinks){var c;(c=this.inputLinks[i]).node.removeReference(c.pin)}this._rendering=!1,this._rendered=!0,this.trigger("afterrender",e)},updateParameter:function(e,t){var r,i,n=this.outputs[e],a=n.parameters,o=n._parametersCopy;if(o||(o=n._parametersCopy={}),a)for(var s in a)"width"!==s&&"height"!==s&&(o[s]=a[s]);return r="function"==typeof a.width?a.width.call(this,t):a.width,i="function"==typeof a.height?a.height.call(this,t):a.height,r=Math.ceil(r),i=Math.ceil(i),o.width===r&&o.height===i||this._outputTextures[e]&&this._outputTextures[e].dispose(t),o.width=r,o.height=i,o},setParameter:function(e,t){this.pass.setUniform(e,t)},getParameter:function(e){return this.pass.getUniform(e)},setParameters:function(e){for(var t in e)this.setParameter(t,e[t])},define:function(e,t){this.pass.material.define("fragment",e,t)},undefine:function(e){this.pass.material.undefine("fragment",e)},removeReference:function(e){this._outputReferences[e]--,0===this._outputReferences[e]&&(this.outputs[e].keepLastFrame?(this._prevOutputTextures[e]&&this._compositor.releaseTexture(this._prevOutputTextures[e]),this._prevOutputTextures[e]=this._outputTextures[e]):this._compositor.releaseTexture(this._outputTextures[e]))},clear:function(){Vs.prototype.clear.call(this),this.pass.material.disableTexturesAll()}}),Zs="@export clay.compositor.kernel.gaussian_9\nfloat gaussianKernel[9];\ngaussianKernel[0] = 0.07;\ngaussianKernel[1] = 0.09;\ngaussianKernel[2] = 0.12;\ngaussianKernel[3] = 0.14;\ngaussianKernel[4] = 0.16;\ngaussianKernel[5] = 0.14;\ngaussianKernel[6] = 0.12;\ngaussianKernel[7] = 0.09;\ngaussianKernel[8] = 0.07;\n@end\n@export clay.compositor.kernel.gaussian_13\nfloat gaussianKernel[13];\ngaussianKernel[0] = 0.02;\ngaussianKernel[1] = 0.03;\ngaussianKernel[2] = 0.06;\ngaussianKernel[3] = 0.08;\ngaussianKernel[4] = 0.11;\ngaussianKernel[5] = 0.13;\ngaussianKernel[6] = 0.14;\ngaussianKernel[7] = 0.13;\ngaussianKernel[8] = 0.11;\ngaussianKernel[9] = 0.08;\ngaussianKernel[10] = 0.06;\ngaussianKernel[11] = 0.03;\ngaussianKernel[12] = 0.02;\n@end\n@export clay.compositor.gaussian_blur\n#define SHADER_NAME gaussian_blur\nuniform sampler2D texture;varying vec2 v_Texcoord;\nuniform float blurSize : 2.0;\nuniform vec2 textureSize : [512.0, 512.0];\nuniform float blurDir : 0.0;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main (void)\n{\n @import clay.compositor.kernel.gaussian_9\n vec2 off = blurSize / textureSize;\n off *= vec2(1.0 - blurDir, blurDir);\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n for (int i = 0; i < 9; i++) {\n float w = gaussianKernel[i];\n vec4 texel = decodeHDR(clampSample(texture, v_Texcoord + float(i - 4) * off));\n sum += texel * w;\n weightAll += w;\n }\n gl_FragColor = encodeHDR(sum / max(weightAll, 0.01));\n}\n@end\n",Ys="\n@export clay.compositor.lut\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform sampler2D lookup;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n float blueColor = tex.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * tex.g);\n vec4 newColor1 = texture2D(lookup, texPos1);\n vec4 newColor2 = texture2D(lookup, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n gl_FragColor = vec4(newColor.rgb, tex.w);\n}\n@end",Ks="@export clay.compositor.output\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = tex.rgb;\n#ifdef OUTPUT_ALPHA\n gl_FragColor.a = tex.a;\n#else\n gl_FragColor.a = 1.0;\n#endif\n gl_FragColor = encodeHDR(gl_FragColor);\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end",Qs="@export clay.compositor.bright\nuniform sampler2D texture;\nuniform float threshold : 1;\nuniform float scale : 1.0;\nuniform vec2 textureSize: [512, 512];\nvarying vec2 v_Texcoord;\nconst vec3 lumWeight = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvec4 median(vec4 a, vec4 b, vec4 c)\n{\n return a + b + c - min(min(a, b), c) - max(max(a, b), c);\n}\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n#ifdef ANTI_FLICKER\n vec3 d = 1.0 / textureSize.xyx * vec3(1.0, 1.0, 0.0);\n vec4 s1 = decodeHDR(texture2D(texture, v_Texcoord - d.xz));\n vec4 s2 = decodeHDR(texture2D(texture, v_Texcoord + d.xz));\n vec4 s3 = decodeHDR(texture2D(texture, v_Texcoord - d.zy));\n vec4 s4 = decodeHDR(texture2D(texture, v_Texcoord + d.zy));\n texel = median(median(texel, s1, s2), s3, s4);\n#endif\n float lum = dot(texel.rgb , lumWeight);\n vec4 color;\n if (lum > threshold && texel.a > 0.0)\n {\n color = vec4(texel.rgb * scale, texel.a * scale);\n }\n else\n {\n color = vec4(0.0);\n }\n gl_FragColor = encodeHDR(color);\n}\n@end\n",Js="@export clay.compositor.downsample\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nfloat brightness(vec3 c)\n{\n return max(max(c.r, c.g), c.b);\n}\n@import clay.util.clamp_sample\nvoid main()\n{\n vec4 d = vec4(-1.0, -1.0, 1.0, 1.0) / textureSize.xyxy;\n#ifdef ANTI_FLICKER\n vec3 s1 = decodeHDR(clampSample(texture, v_Texcoord + d.xy)).rgb;\n vec3 s2 = decodeHDR(clampSample(texture, v_Texcoord + d.zy)).rgb;\n vec3 s3 = decodeHDR(clampSample(texture, v_Texcoord + d.xw)).rgb;\n vec3 s4 = decodeHDR(clampSample(texture, v_Texcoord + d.zw)).rgb;\n float s1w = 1.0 / (brightness(s1) + 1.0);\n float s2w = 1.0 / (brightness(s2) + 1.0);\n float s3w = 1.0 / (brightness(s3) + 1.0);\n float s4w = 1.0 / (brightness(s4) + 1.0);\n float oneDivideSum = 1.0 / (s1w + s2w + s3w + s4w);\n vec4 color = vec4(\n (s1 * s1w + s2 * s2w + s3 * s3w + s4 * s4w) * oneDivideSum,\n 1.0\n );\n#else\n vec4 color = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n color += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n color *= 0.25;\n#endif\n gl_FragColor = encodeHDR(color);\n}\n@end",$s="\n@export clay.compositor.upsample\n#define HIGH_QUALITY\nuniform sampler2D texture;\nuniform vec2 textureSize : [512, 512];\nuniform float sampleScale: 0.5;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\n@import clay.util.clamp_sample\nvoid main()\n{\n#ifdef HIGH_QUALITY\n vec4 d = vec4(1.0, 1.0, -1.0, 0.0) / textureSize.xyxy * sampleScale;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord - d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord - d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord - d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord )) * 4.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.wy)) * 2.0;\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n gl_FragColor = encodeHDR(s / 16.0);\n#else\n vec4 d = vec4(-1.0, -1.0, +1.0, +1.0) / textureSize.xyxy;\n vec4 s;\n s = decodeHDR(clampSample(texture, v_Texcoord + d.xy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zy));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.xw));\n s += decodeHDR(clampSample(texture, v_Texcoord + d.zw));\n gl_FragColor = encodeHDR(s / 4.0);\n#endif\n}\n@end",el="@export clay.compositor.hdr.composite\n#define TONEMAPPING\nuniform sampler2D texture;\n#ifdef BLOOM_ENABLED\nuniform sampler2D bloom;\n#endif\n#ifdef LENSFLARE_ENABLED\nuniform sampler2D lensflare;\nuniform sampler2D lensdirt;\n#endif\n#ifdef LUM_ENABLED\nuniform sampler2D lum;\n#endif\n#ifdef LUT_ENABLED\nuniform sampler2D lut;\n#endif\n#ifdef COLOR_CORRECTION\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float saturation : 1.0;\n#endif\n#ifdef VIGNETTE\nuniform float vignetteDarkness: 1.0;\nuniform float vignetteOffset: 1.0;\n#endif\nuniform float exposure : 1.0;\nuniform float bloomIntensity : 0.25;\nuniform float lensflareIntensity : 1;\nvarying vec2 v_Texcoord;\n@import clay.util.srgb\nvec3 ACESToneMapping(vec3 color)\n{\n const float A = 2.51;\n const float B = 0.03;\n const float C = 2.43;\n const float D = 0.59;\n const float E = 0.14;\n return (color * (A * color + B)) / (color * (C * color + D) + E);\n}\nfloat eyeAdaption(float fLum)\n{\n return mix(0.2, fLum, 0.5);\n}\n#ifdef LUT_ENABLED\nvec3 lutTransform(vec3 color) {\n float blueColor = color.b * 63.0;\n vec2 quad1;\n quad1.y = floor(floor(blueColor) / 8.0);\n quad1.x = floor(blueColor) - (quad1.y * 8.0);\n vec2 quad2;\n quad2.y = floor(ceil(blueColor) / 8.0);\n quad2.x = ceil(blueColor) - (quad2.y * 8.0);\n vec2 texPos1;\n texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec2 texPos2;\n texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.r);\n texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * color.g);\n vec4 newColor1 = texture2D(lut, texPos1);\n vec4 newColor2 = texture2D(lut, texPos2);\n vec4 newColor = mix(newColor1, newColor2, fract(blueColor));\n return newColor.rgb;\n}\n#endif\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = vec4(0.0);\n vec4 originalTexel = vec4(0.0);\n#ifdef TEXTURE_ENABLED\n texel = decodeHDR(texture2D(texture, v_Texcoord));\n originalTexel = texel;\n#endif\n#ifdef BLOOM_ENABLED\n vec4 bloomTexel = decodeHDR(texture2D(bloom, v_Texcoord));\n texel.rgb += bloomTexel.rgb * bloomIntensity;\n texel.a += bloomTexel.a * bloomIntensity;\n#endif\n#ifdef LENSFLARE_ENABLED\n texel += decodeHDR(texture2D(lensflare, v_Texcoord)) * texture2D(lensdirt, v_Texcoord) * lensflareIntensity;\n#endif\n texel.a = min(texel.a, 1.0);\n#ifdef LUM_ENABLED\n float fLum = texture2D(lum, vec2(0.5, 0.5)).r;\n float adaptedLumDest = 3.0 / (max(0.1, 1.0 + 10.0*eyeAdaption(fLum)));\n float exposureBias = adaptedLumDest * exposure;\n#else\n float exposureBias = exposure;\n#endif\n#ifdef TONEMAPPING\n texel.rgb *= exposureBias;\n texel.rgb = ACESToneMapping(texel.rgb);\n#endif\n texel = linearTosRGB(texel);\n#ifdef LUT_ENABLED\n texel.rgb = lutTransform(clamp(texel.rgb,vec3(0.0),vec3(1.0)));\n#endif\n#ifdef COLOR_CORRECTION\n texel.rgb = clamp(texel.rgb + vec3(brightness), 0.0, 1.0);\n texel.rgb = clamp((texel.rgb - vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n float lum = dot(texel.rgb, vec3(0.2125, 0.7154, 0.0721));\n texel.rgb = mix(vec3(lum), texel.rgb, saturation);\n#endif\n#ifdef VIGNETTE\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(vignetteOffset);\n texel.rgb = mix(texel.rgb, vec3(1.0 - vignetteDarkness), dot(uv, uv));\n#endif\n gl_FragColor = encodeHDR(texel);\n#ifdef DEBUG\n #if DEBUG == 1\n gl_FragColor = encodeHDR(decodeHDR(texture2D(texture, v_Texcoord)));\n #elif DEBUG == 2\n gl_FragColor = encodeHDR(decodeHDR(texture2D(bloom, v_Texcoord)) * bloomIntensity);\n #elif DEBUG == 3\n gl_FragColor = encodeHDR(decodeHDR(texture2D(lensflare, v_Texcoord) * lensflareIntensity));\n #endif\n#endif\n if (originalTexel.a <= 0.01 && gl_FragColor.a > 1e-5) {\n gl_FragColor.a = dot(gl_FragColor.rgb, vec3(0.2125, 0.7154, 0.0721));\n }\n#ifdef PREMULTIPLY_ALPHA\n gl_FragColor.rgb *= gl_FragColor.a;\n#endif\n}\n@end",tl="@export clay.compositor.blend\n#define SHADER_NAME blend\n#ifdef TEXTURE1_ENABLED\nuniform sampler2D texture1;\nuniform float weight1 : 1.0;\n#endif\n#ifdef TEXTURE2_ENABLED\nuniform sampler2D texture2;\nuniform float weight2 : 1.0;\n#endif\n#ifdef TEXTURE3_ENABLED\nuniform sampler2D texture3;\nuniform float weight3 : 1.0;\n#endif\n#ifdef TEXTURE4_ENABLED\nuniform sampler2D texture4;\nuniform float weight4 : 1.0;\n#endif\n#ifdef TEXTURE5_ENABLED\nuniform sampler2D texture5;\nuniform float weight5 : 1.0;\n#endif\n#ifdef TEXTURE6_ENABLED\nuniform sampler2D texture6;\nuniform float weight6 : 1.0;\n#endif\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = vec4(0.0);\n#ifdef TEXTURE1_ENABLED\n tex += decodeHDR(texture2D(texture1, v_Texcoord)) * weight1;\n#endif\n#ifdef TEXTURE2_ENABLED\n tex += decodeHDR(texture2D(texture2, v_Texcoord)) * weight2;\n#endif\n#ifdef TEXTURE3_ENABLED\n tex += decodeHDR(texture2D(texture3, v_Texcoord)) * weight3;\n#endif\n#ifdef TEXTURE4_ENABLED\n tex += decodeHDR(texture2D(texture4, v_Texcoord)) * weight4;\n#endif\n#ifdef TEXTURE5_ENABLED\n tex += decodeHDR(texture2D(texture5, v_Texcoord)) * weight5;\n#endif\n#ifdef TEXTURE6_ENABLED\n tex += decodeHDR(texture2D(texture6, v_Texcoord)) * weight6;\n#endif\n gl_FragColor = encodeHDR(tex);\n}\n@end",rl="@export clay.compositor.fxaa\nuniform sampler2D texture;\nuniform vec4 viewport : VIEWPORT;\nvarying vec2 v_Texcoord;\n#define FXAA_REDUCE_MIN (1.0/128.0)\n#define FXAA_REDUCE_MUL (1.0/8.0)\n#define FXAA_SPAN_MAX 8.0\n@import clay.util.rgbm\nvoid main()\n{\n vec2 resolution = 1.0 / viewport.zw;\n vec3 rgbNW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbNE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSW = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ) ).xyz;\n vec3 rgbSE = decodeHDR( texture2D( texture, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ) ).xyz;\n vec4 rgbaM = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution ) );\n vec3 rgbM = rgbaM.xyz;\n float opacity = rgbaM.w;\n vec3 luma = vec3( 0.299, 0.587, 0.114 );\n float lumaNW = dot( rgbNW, luma );\n float lumaNE = dot( rgbNE, luma );\n float lumaSW = dot( rgbSW, luma );\n float lumaSE = dot( rgbSE, luma );\n float lumaM = dot( rgbM, luma );\n float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\n float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\n vec2 dir;\n dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\n dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\n float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\n float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\n dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\n max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\n dir * rcpDirMin)) * resolution;\n vec3 rgbA = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ) ).xyz;\n rgbA *= 0.5;\n vec3 rgbB = decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * -0.5 ) ).xyz;\n rgbB += decodeHDR( texture2D( texture, gl_FragCoord.xy * resolution + dir * 0.5 ) ).xyz;\n rgbB *= 0.25;\n rgbB += rgbA * 0.5;\n float lumaB = dot( rgbB, luma );\n if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) )\n {\n gl_FragColor = vec4( rgbA, opacity );\n }\n else {\n gl_FragColor = vec4( rgbB, opacity );\n }\n}\n@end";!function(e){e.import("@export clay.compositor.coloradjust\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nuniform float contrast : 1.0;\nuniform float exposure : 0.0;\nuniform float gamma : 1.0;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = clamp(tex.rgb + vec3(brightness), 0.0, 1.0);\n color = clamp( (color-vec3(0.5))*contrast+vec3(0.5), 0.0, 1.0);\n color = clamp( color * pow(2.0, exposure), 0.0, 1.0);\n color = clamp( pow(color, vec3(gamma)), 0.0, 1.0);\n float luminance = dot( color, w );\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.brightness\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float brightness : 0.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = tex.rgb + vec3(brightness);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.contrast\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float contrast : 1.0;\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord);\n vec3 color = (tex.rgb-vec3(0.5))*contrast+vec3(0.5);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.exposure\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float exposure : 0.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb * pow(2.0, exposure);\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.gamma\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float gamma : 1.0;\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = pow(tex.rgb, vec3(gamma));\n gl_FragColor = vec4(color, tex.a);\n}\n@end\n@export clay.compositor.saturation\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float saturation : 1.0;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D(texture, v_Texcoord);\n vec3 color = tex.rgb;\n float luminance = dot(color, w);\n color = mix(vec3(luminance), color, saturation);\n gl_FragColor = vec4(color, tex.a);\n}\n@end"),e.import(Zs),e.import("@export clay.compositor.hdr.log_lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\n@import clay.util.rgbm\nvoid main()\n{\n vec4 tex = decodeHDR(texture2D(texture, v_Texcoord));\n float luminance = dot(tex.rgb, w);\n luminance = log(luminance + 0.001);\n gl_FragColor = encodeHDR(vec4(vec3(luminance), 1.0));\n}\n@end\n@export clay.compositor.hdr.lum_adaption\nvarying vec2 v_Texcoord;\nuniform sampler2D adaptedLum;\nuniform sampler2D currentLum;\nuniform float frameTime : 0.02;\n@import clay.util.rgbm\nvoid main()\n{\n float fAdaptedLum = decodeHDR(texture2D(adaptedLum, vec2(0.5, 0.5))).r;\n float fCurrentLum = exp(encodeHDR(texture2D(currentLum, vec2(0.5, 0.5))).r);\n fAdaptedLum += (fCurrentLum - fAdaptedLum) * (1.0 - pow(0.98, 30.0 * frameTime));\n gl_FragColor = encodeHDR(vec4(vec3(fAdaptedLum), 1.0));\n}\n@end\n@export clay.compositor.lum\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nconst vec3 w = vec3(0.2125, 0.7154, 0.0721);\nvoid main()\n{\n vec4 tex = texture2D( texture, v_Texcoord );\n float luminance = dot(tex.rgb, w);\n gl_FragColor = vec4(vec3(luminance), 1.0);\n}\n@end"),e.import(Ys),e.import("@export clay.compositor.vignette\n#define OUTPUT_ALPHA\nvarying vec2 v_Texcoord;\nuniform sampler2D texture;\nuniform float darkness: 1;\nuniform float offset: 1;\n@import clay.util.rgbm\nvoid main()\n{\n vec4 texel = decodeHDR(texture2D(texture, v_Texcoord));\n gl_FragColor.rgb = texel.rgb;\n vec2 uv = (v_Texcoord - vec2(0.5)) * vec2(offset);\n gl_FragColor = encodeHDR(vec4(mix(texel.rgb, vec3(1.0 - darkness), dot(uv, uv)), texel.a));\n}\n@end"),e.import(Ks),e.import(Qs),e.import(Js),e.import($s),e.import(el),e.import("@export clay.compositor.lensflare\n#define SAMPLE_NUMBER 8\nuniform sampler2D texture;\nuniform sampler2D lenscolor;\nuniform vec2 textureSize : [512, 512];\nuniform float dispersal : 0.3;\nuniform float haloWidth : 0.4;\nuniform float distortion : 1.0;\nvarying vec2 v_Texcoord;\n@import clay.util.rgbm\nvec4 textureDistorted(\n in vec2 texcoord,\n in vec2 direction,\n in vec3 distortion\n) {\n return vec4(\n decodeHDR(texture2D(texture, texcoord + direction * distortion.r)).r,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.g)).g,\n decodeHDR(texture2D(texture, texcoord + direction * distortion.b)).b,\n 1.0\n );\n}\nvoid main()\n{\n vec2 texcoord = -v_Texcoord + vec2(1.0); vec2 textureOffset = 1.0 / textureSize;\n vec2 ghostVec = (vec2(0.5) - texcoord) * dispersal;\n vec2 haloVec = normalize(ghostVec) * haloWidth;\n vec3 distortion = vec3(-textureOffset.x * distortion, 0.0, textureOffset.x * distortion);\n vec4 result = vec4(0.0);\n for (int i = 0; i < SAMPLE_NUMBER; i++)\n {\n vec2 offset = fract(texcoord + ghostVec * float(i));\n float weight = length(vec2(0.5) - offset) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n }\n result *= texture2D(lenscolor, vec2(length(vec2(0.5) - texcoord)) / length(vec2(0.5)));\n float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5));\n weight = pow(1.0 - weight, 10.0);\n vec2 offset = fract(texcoord + haloVec);\n result += textureDistorted(offset, normalize(ghostVec), distortion) * weight;\n gl_FragColor = result;\n}\n@end"),e.import(tl),e.import(rl)}(Xe);var il=/^#source\((.*?)\)/;function nl(e,t,r){var i,n,a,o,s=e.type||"filter";if("filter"===s){var l=e.shader.trim(),h=il.exec(l);if(h?i=Xe.source(h[1].trim()):"#"===l.charAt(0)&&(i=t.shaders[l.substr(1)]),i||(i=l),!i)return}if(e.inputs)for(var u in n={},e.inputs)"string"==typeof e.inputs[u]?n[u]=e.inputs[u]:n[u]={node:e.inputs[u].node,pin:e.inputs[u].pin};if(e.outputs)for(var u in a={},e.outputs){var c=e.outputs[u];a[u]={},null!=c.attachment&&(a[u].attachment=c.attachment),null!=c.keepLastFrame&&(a[u].keepLastFrame=c.keepLastFrame),null!=c.outputLastFrame&&(a[u].outputLastFrame=c.outputLastFrame),c.parameters&&(a[u].parameters=sl(c.parameters))}if(o="scene"===s?new js({name:e.name,scene:r.scene,camera:r.camera,outputs:a}):"texture"===s?new Xs({name:e.name,outputs:a}):new qs({name:e.name,shader:i,inputs:n,outputs:a})){if(e.parameters)for(var u in e.parameters)"string"==typeof(d=e.parameters[u])?"#"===(d=d.trim()).charAt(0)?d=t.textures[d.substr(1)]:o.on("beforerender",ll(u,hl(d))):"function"==typeof d&&o.on("beforerender",d),o.setParameter(u,d);if(e.defines&&o.pass)for(var u in e.defines){var d=e.defines[u];o.pass.material.define("fragment",u,d)}}return o}function al(e,t){return e}function ol(e,t){return t}function sl(e){var t={};if(!e)return t;["type","minFilter","magFilter","wrapS","wrapT","flipY","useMipmap"].forEach((function(r){var i=e[r];null!=i&&("string"==typeof i&&(i=wr[i]),t[r]=i)}));var r=e.scale||1;return["width","height"].forEach((function(i){if(null!=e[i]){var n=e[i];"string"==typeof n?(n=n.trim(),t[i]=(a=hl(n),o=(o=r)||1,function(e){var t=e.getDevicePixelRatio(),r=e.getWidth()*o,i=e.getHeight()*o;return a(r,i,t)})):t[i]=n}var a,o})),t.width||(t.width=al),t.height||(t.height=ol),null!=e.useMipmap&&(t.useMipmap=e.useMipmap),t}function ll(e,t){return function(r){var i=r.getDevicePixelRatio(),n=r.getWidth(),a=r.getHeight(),o=t(n,a,i);this.setParameter(e,o)}}function hl(e){var t=/^expr\((.*)\)$/.exec(e);if(t)try{var r=new Function("width","height","dpr","return "+t[1]);return r(1,1),r}catch(e){throw new Error("Invalid expression.")}}const ul=function(e,t){for(var r=0,i=1/t,n=e;n>0;)r+=i*(n%t),n=Math.floor(n/t),i/=t;return r};function cl(e){for(var t=new Uint8Array(e*e*4),r=0,i=new vt,n=0;n 0.99999) {\n gl_FragColor = vec4(1.0);\n return;\n }\n mat3 kernelBasis;\n#endif\n\n float z = depthTexel.r * 2.0 - 1.0;\n\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * projectedPos;\n\n vec3 position = p4.xyz / p4.w;\n\n float ao = ssaoEstimator(position, kernelBasis);\n ao = clamp(1.0 - (1.0 - ao) * intensity, 0.0, 1.0);\n gl_FragColor = vec4(vec3(ao), 1.0);\n}\n\n@end\n\n\n@export ecgl.ssao.blur\n#define SHADER_NAME SSAO_BLUR\n\nuniform sampler2D ssaoTexture;\n\n#ifdef NORMALTEX_ENABLED\nuniform sampler2D normalTex;\n#endif\n\nvarying vec2 v_Texcoord;\n\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n\nuniform int direction: 0.0;\n\n#ifdef DEPTHTEX_ENABLED\nuniform sampler2D depthTex;\nuniform mat4 projection;\nuniform float depthRange : 0.5;\n\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(depthTex, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n#endif\n\nvoid main()\n{\n float kernel[5];\n kernel[0] = 0.122581;\n kernel[1] = 0.233062;\n kernel[2] = 0.288713;\n kernel[3] = 0.233062;\n kernel[4] = 0.122581;\n\n vec2 off = vec2(0.0);\n if (direction == 0) {\n off[0] = blurSize / textureSize.x;\n }\n else {\n off[1] = blurSize / textureSize.y;\n }\n\n vec2 coord = v_Texcoord;\n\n float sum = 0.0;\n float weightAll = 0.0;\n\n#ifdef NORMALTEX_ENABLED\n vec3 centerNormal = texture2D(normalTex, v_Texcoord).rgb * 2.0 - 1.0;\n#endif\n#if defined(DEPTHTEX_ENABLED)\n float centerDepth = getLinearDepth(v_Texcoord);\n#endif\n\n for (int i = 0; i < 5; i++) {\n vec2 coord = clamp(v_Texcoord + vec2(float(i) - 2.0) * off, vec2(0.0), vec2(1.0));\n\n float w = kernel[i];\n#ifdef NORMALTEX_ENABLED\n vec3 normal = texture2D(normalTex, coord).rgb * 2.0 - 1.0;\n w *= clamp(dot(normal, centerNormal), 0.0, 1.0);\n#endif\n#ifdef DEPTHTEX_ENABLED\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(centerDepth - d) / depthRange, 0.0, 1.0));\n#endif\n\n weightAll += w;\n sum += texture2D(ssaoTexture, coord).r * w;\n }\n\n gl_FragColor = vec4(vec3(sum / weightAll), 1.0);\n}\n\n@end\n"),pl.prototype.setDepthTexture=function(e){this._depthTex=e},pl.prototype.setNormalTexture=function(e){this._normalTex=e,this._ssaoPass.material[e?"enableTexture":"disableTexture"]("normalTex"),this.setKernelSize(this._kernelSize)},pl.prototype.update=function(e,t,r){var i=e.getWidth(),n=e.getHeight(),a=this._ssaoPass,o=this._blurPass;a.setUniform("kernel",this._kernels[r%this._kernels.length]),a.setUniform("depthTex",this._depthTex),null!=this._normalTex&&a.setUniform("normalTex",this._normalTex),a.setUniform("depthTexSize",[this._depthTex.width,this._depthTex.height]);var s=new Ht;Ht.transpose(s,t.worldTransform),a.setUniform("projection",t.projectionMatrix.array),a.setUniform("projectionInv",t.invProjectionMatrix.array),a.setUniform("viewInverseTranspose",s.array);var l=this._ssaoTexture,h=this._blurTexture,u=this._blurTexture2;l.width=i/2,l.height=n/2,h.width=i,h.height=n,u.width=i,u.height=n,this._framebuffer.attach(l),this._framebuffer.bind(e),e.gl.clearColor(1,1,1,1),e.gl.clear(e.gl.COLOR_BUFFER_BIT),a.render(e),o.setUniform("textureSize",[i/2,n/2]),o.setUniform("projection",t.projectionMatrix.array),this._framebuffer.attach(h),o.setUniform("direction",0),o.setUniform("ssaoTexture",l),o.render(e),this._framebuffer.attach(u),o.setUniform("textureSize",[i,n]),o.setUniform("direction",1),o.setUniform("ssaoTexture",h),o.render(e),this._framebuffer.unbind(e);var c=e.clearColor;e.gl.clearColor(c[0],c[1],c[2],c[3])},pl.prototype.getTargetTexture=function(){return this._blurTexture2},pl.prototype.setParameter=function(e,t){"noiseTexSize"===e?this.setNoiseSize(t):"kernelSize"===e?this.setKernelSize(t):"intensity"===e?this._ssaoPass.material.set("intensity",t):this._ssaoPass.setUniform(e,t)},pl.prototype.setKernelSize=function(e){this._kernelSize=e,this._ssaoPass.material.define("fragment","KERNEL_SIZE",e),this._kernels=this._kernels||[];for(var t=0;t<30;t++)this._kernels[t]=fl(e,t*e,!!this._normalTex)},pl.prototype.setNoiseSize=function(e){var t=this._ssaoPass.getUniform("noiseTex");t?(t.data=cl(e),t.width=t.height=e,t.dirty()):(t=dl(e),this._ssaoPass.setUniform("noiseTex",dl(e))),this._ssaoPass.setUniform("noiseTexSize",[e,e])},pl.prototype.dispose=function(e){this._blurTexture.dispose(e),this._ssaoTexture.dispose(e),this._blurTexture2.dispose(e)};const ml=pl;function gl(e){e=e||{},this._ssrPass=new pn({fragment:Xe.source("ecgl.ssr.main"),clearColor:[0,0,0,0]}),this._blurPass1=new pn({fragment:Xe.source("ecgl.ssr.blur"),clearColor:[0,0,0,0]}),this._blurPass2=new pn({fragment:Xe.source("ecgl.ssr.blur"),clearColor:[0,0,0,0]}),this._blendPass=new pn({fragment:Xe.source("clay.compositor.blend")}),this._blendPass.material.disableTexturesAll(),this._blendPass.material.enableTexture(["texture1","texture2"]),this._ssrPass.setUniform("gBufferTexture1",e.normalTexture),this._ssrPass.setUniform("gBufferTexture2",e.depthTexture),this._blurPass1.setUniform("gBufferTexture1",e.normalTexture),this._blurPass1.setUniform("gBufferTexture2",e.depthTexture),this._blurPass2.setUniform("gBufferTexture1",e.normalTexture),this._blurPass2.setUniform("gBufferTexture2",e.depthTexture),this._blurPass2.material.define("fragment","VERTICAL"),this._blurPass2.material.define("fragment","BLEND"),this._ssrTexture=new Dr({type:wr.HALF_FLOAT}),this._texture2=new Dr({type:wr.HALF_FLOAT}),this._texture3=new Dr({type:wr.HALF_FLOAT}),this._prevTexture=new Dr({type:wr.HALF_FLOAT}),this._currentTexture=new Dr({type:wr.HALF_FLOAT}),this._frameBuffer=new zi({depthBuffer:!1}),this._normalDistribution=null,this._totalSamples=256,this._samplePerFrame=4,this._ssrPass.material.define("fragment","SAMPLE_PER_FRAME",this._samplePerFrame),this._ssrPass.material.define("fragment","TOTAL_SAMPLES",this._totalSamples),this._downScale=1}Xe.import("@export ecgl.ssr.main\n\n#define SHADER_NAME SSR\n#define MAX_ITERATION 20;\n#define SAMPLE_PER_FRAME 5;\n#define TOTAL_SAMPLES 128;\n\nuniform sampler2D sourceTexture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform sampler2D gBufferTexture3;\nuniform samplerCube specularCubemap;\nuniform float specularIntensity: 1;\n\nuniform mat4 projection;\nuniform mat4 projectionInv;\nuniform mat4 toViewSpace;\nuniform mat4 toWorldSpace;\n\nuniform float maxRayDistance: 200;\n\nuniform float pixelStride: 16;\nuniform float pixelStrideZCutoff: 50; \nuniform float screenEdgeFadeStart: 0.9; \nuniform float eyeFadeStart : 0.2; uniform float eyeFadeEnd: 0.8; \nuniform float minGlossiness: 0.2; uniform float zThicknessThreshold: 1;\n\nuniform float nearZ;\nuniform vec2 viewportSize : VIEWPORT_SIZE;\n\nuniform float jitterOffset: 0;\n\nvarying vec2 v_Texcoord;\n\n#ifdef DEPTH_DECODE\n@import clay.util.decode_float\n#endif\n\n#ifdef PHYSICALLY_CORRECT\nuniform sampler2D normalDistribution;\nuniform float sampleOffset: 0;\nuniform vec2 normalDistributionSize;\n\nvec3 transformNormal(vec3 H, vec3 N) {\n vec3 upVector = N.y > 0.999 ? vec3(1.0, 0.0, 0.0) : vec3(0.0, 1.0, 0.0);\n vec3 tangentX = normalize(cross(N, upVector));\n vec3 tangentZ = cross(N, tangentX);\n return normalize(tangentX * H.x + N * H.y + tangentZ * H.z);\n}\nvec3 importanceSampleNormalGGX(float i, float roughness, vec3 N) {\n float p = fract((i + sampleOffset) / float(TOTAL_SAMPLES));\n vec3 H = texture2D(normalDistribution,vec2(roughness, p)).rgb;\n return transformNormal(H, N);\n}\nfloat G_Smith(float g, float ndv, float ndl) {\n float roughness = 1.0 - g;\n float k = roughness * roughness / 2.0;\n float G1V = ndv / (ndv * (1.0 - k) + k);\n float G1L = ndl / (ndl * (1.0 - k) + k);\n return G1L * G1V;\n}\nvec3 F_Schlick(float ndv, vec3 spec) {\n return spec + (1.0 - spec) * pow(1.0 - ndv, 5.0);\n}\n#endif\n\nfloat fetchDepth(sampler2D depthTexture, vec2 uv)\n{\n vec4 depthTexel = texture2D(depthTexture, uv);\n return depthTexel.r * 2.0 - 1.0;\n}\n\nfloat linearDepth(float depth)\n{\n if (projection[3][3] == 0.0) {\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n }\n else {\n return (depth - projection[3][2]) / projection[2][2];\n }\n}\n\nbool rayIntersectDepth(float rayZNear, float rayZFar, vec2 hitPixel)\n{\n if (rayZFar > rayZNear)\n {\n float t = rayZFar; rayZFar = rayZNear; rayZNear = t;\n }\n float cameraZ = linearDepth(fetchDepth(gBufferTexture2, hitPixel));\n return rayZFar <= cameraZ && rayZNear >= cameraZ - zThicknessThreshold;\n}\n\n\nbool traceScreenSpaceRay(\n vec3 rayOrigin, vec3 rayDir, float jitter,\n out vec2 hitPixel, out vec3 hitPoint, out float iterationCount\n)\n{\n float rayLength = ((rayOrigin.z + rayDir.z * maxRayDistance) > -nearZ)\n ? (-nearZ - rayOrigin.z) / rayDir.z : maxRayDistance;\n\n vec3 rayEnd = rayOrigin + rayDir * rayLength;\n\n vec4 H0 = projection * vec4(rayOrigin, 1.0);\n vec4 H1 = projection * vec4(rayEnd, 1.0);\n\n float k0 = 1.0 / H0.w, k1 = 1.0 / H1.w;\n\n vec3 Q0 = rayOrigin * k0, Q1 = rayEnd * k1;\n\n vec2 P0 = (H0.xy * k0 * 0.5 + 0.5) * viewportSize;\n vec2 P1 = (H1.xy * k1 * 0.5 + 0.5) * viewportSize;\n\n P1 += dot(P1 - P0, P1 - P0) < 0.0001 ? 0.01 : 0.0;\n vec2 delta = P1 - P0;\n\n bool permute = false;\n if (abs(delta.x) < abs(delta.y)) {\n permute = true;\n delta = delta.yx;\n P0 = P0.yx;\n P1 = P1.yx;\n }\n float stepDir = sign(delta.x);\n float invdx = stepDir / delta.x;\n\n vec3 dQ = (Q1 - Q0) * invdx;\n float dk = (k1 - k0) * invdx;\n\n vec2 dP = vec2(stepDir, delta.y * invdx);\n\n float strideScaler = 1.0 - min(1.0, -rayOrigin.z / pixelStrideZCutoff);\n float pixStride = 1.0 + strideScaler * pixelStride;\n\n dP *= pixStride; dQ *= pixStride; dk *= pixStride;\n\n vec4 pqk = vec4(P0, Q0.z, k0);\n vec4 dPQK = vec4(dP, dQ.z, dk);\n\n pqk += dPQK * jitter;\n float rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n float rayZNear;\n\n bool intersect = false;\n\n vec2 texelSize = 1.0 / viewportSize;\n\n iterationCount = 0.0;\n\n for (int i = 0; i < MAX_ITERATION; i++)\n {\n pqk += dPQK;\n\n rayZNear = rayZFar;\n rayZFar = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);\n\n hitPixel = permute ? pqk.yx : pqk.xy;\n hitPixel *= texelSize;\n\n intersect = rayIntersectDepth(rayZNear, rayZFar, hitPixel);\n\n iterationCount += 1.0;\n\n dPQK *= 1.2;\n\n if (intersect) {\n break;\n }\n }\n\n Q0.xy += dQ.xy * iterationCount;\n Q0.z = pqk.z;\n hitPoint = Q0 / pqk.w;\n\n return intersect;\n}\n\nfloat calculateAlpha(\n float iterationCount, float reflectivity,\n vec2 hitPixel, vec3 hitPoint, float dist, vec3 rayDir\n)\n{\n float alpha = clamp(reflectivity, 0.0, 1.0);\n alpha *= 1.0 - (iterationCount / float(MAX_ITERATION));\n vec2 hitPixelNDC = hitPixel * 2.0 - 1.0;\n float maxDimension = min(1.0, max(abs(hitPixelNDC.x), abs(hitPixelNDC.y)));\n alpha *= 1.0 - max(0.0, maxDimension - screenEdgeFadeStart) / (1.0 - screenEdgeFadeStart);\n\n float _eyeFadeStart = eyeFadeStart;\n float _eyeFadeEnd = eyeFadeEnd;\n if (_eyeFadeStart > _eyeFadeEnd) {\n float tmp = _eyeFadeEnd;\n _eyeFadeEnd = _eyeFadeStart;\n _eyeFadeStart = tmp;\n }\n\n float eyeDir = clamp(rayDir.z, _eyeFadeStart, _eyeFadeEnd);\n alpha *= 1.0 - (eyeDir - _eyeFadeStart) / (_eyeFadeEnd - _eyeFadeStart);\n\n alpha *= 1.0 - clamp(dist / maxRayDistance, 0.0, 1.0);\n\n return alpha;\n}\n\n@import clay.util.rand\n\n@import clay.util.rgbm\n\nvoid main()\n{\n vec4 normalAndGloss = texture2D(gBufferTexture1, v_Texcoord);\n\n if (dot(normalAndGloss.rgb, vec3(1.0)) == 0.0) {\n discard;\n }\n\n float g = normalAndGloss.a;\n#if !defined(PHYSICALLY_CORRECT)\n if (g <= minGlossiness) {\n discard;\n }\n#endif\n\n float reflectivity = (g - minGlossiness) / (1.0 - minGlossiness);\n\n vec3 N = normalize(normalAndGloss.rgb * 2.0 - 1.0);\n N = normalize((toViewSpace * vec4(N, 0.0)).xyz);\n\n vec4 projectedPos = vec4(v_Texcoord * 2.0 - 1.0, fetchDepth(gBufferTexture2, v_Texcoord), 1.0);\n vec4 pos = projectionInv * projectedPos;\n vec3 rayOrigin = pos.xyz / pos.w;\n vec3 V = -normalize(rayOrigin);\n\n float ndv = clamp(dot(N, V), 0.0, 1.0);\n float iterationCount;\n float jitter = rand(fract(v_Texcoord + jitterOffset));\n\n#ifdef PHYSICALLY_CORRECT\n vec4 color = vec4(vec3(0.0), 1.0);\n vec4 albedoMetalness = texture2D(gBufferTexture3, v_Texcoord);\n vec3 albedo = albedoMetalness.rgb;\n float m = albedoMetalness.a;\n vec3 diffuseColor = albedo * (1.0 - m);\n vec3 spec = mix(vec3(0.04), albedo, m);\n\n float jitter2 = rand(fract(v_Texcoord)) * float(TOTAL_SAMPLES);\n\n for (int i = 0; i < SAMPLE_PER_FRAME; i++) {\n vec3 H = importanceSampleNormalGGX(float(i) + jitter2, 1.0 - g, N);\n vec3 rayDir = normalize(reflect(-V, H));\n#else\n vec3 rayDir = normalize(reflect(-V, N));\n#endif\n vec2 hitPixel;\n vec3 hitPoint;\n\n bool intersect = traceScreenSpaceRay(rayOrigin, rayDir, jitter, hitPixel, hitPoint, iterationCount);\n\n float dist = distance(rayOrigin, hitPoint);\n\n vec3 hitNormal = texture2D(gBufferTexture1, hitPixel).rgb * 2.0 - 1.0;\n hitNormal = normalize((toViewSpace * vec4(hitNormal, 0.0)).xyz);\n#ifdef PHYSICALLY_CORRECT\n float ndl = clamp(dot(N, rayDir), 0.0, 1.0);\n float vdh = clamp(dot(V, H), 0.0, 1.0);\n float ndh = clamp(dot(N, H), 0.0, 1.0);\n vec3 litTexel = vec3(0.0);\n if (dot(hitNormal, rayDir) < 0.0 && intersect) {\n litTexel = texture2D(sourceTexture, hitPixel).rgb;\n litTexel *= pow(clamp(1.0 - dist / 200.0, 0.0, 1.0), 3.0);\n\n }\n else {\n #ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n litTexel = RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, 0.0), 8.12).rgb * specularIntensity;\n#endif\n }\n color.rgb += ndl * litTexel * (\n F_Schlick(ndl, spec) * G_Smith(g, ndv, ndl) * vdh / (ndh * ndv + 0.001)\n );\n }\n color.rgb /= float(SAMPLE_PER_FRAME);\n#else\n #if !defined(SPECULARCUBEMAP_ENABLED)\n if (dot(hitNormal, rayDir) >= 0.0) {\n discard;\n }\n if (!intersect) {\n discard;\n }\n#endif\n float alpha = clamp(calculateAlpha(iterationCount, reflectivity, hitPixel, hitPoint, dist, rayDir), 0.0, 1.0);\n vec4 color = texture2D(sourceTexture, hitPixel);\n color.rgb *= alpha;\n\n#ifdef SPECULARCUBEMAP_ENABLED\n vec3 rayDirW = normalize(toWorldSpace * vec4(rayDir, 0.0)).rgb;\n alpha = alpha * (intersect ? 1.0 : 0.0);\n float bias = (1.0 -g) * 5.0;\n color.rgb += (1.0 - alpha)\n * RGBMDecode(textureCubeLodEXT(specularCubemap, rayDirW, bias), 8.12).rgb\n * specularIntensity;\n#endif\n\n#endif\n\n gl_FragColor = encodeHDR(color);\n}\n@end\n\n@export ecgl.ssr.blur\n\nuniform sampler2D texture;\nuniform sampler2D gBufferTexture1;\nuniform sampler2D gBufferTexture2;\nuniform mat4 projection;\nuniform float depthRange : 0.05;\n\nvarying vec2 v_Texcoord;\n\nuniform vec2 textureSize;\nuniform float blurSize : 1.0;\n\n#ifdef BLEND\n #ifdef SSAOTEX_ENABLED\nuniform sampler2D ssaoTex;\n #endif\nuniform sampler2D sourceTexture;\n#endif\n\nfloat getLinearDepth(vec2 coord)\n{\n float depth = texture2D(gBufferTexture2, coord).r * 2.0 - 1.0;\n return projection[3][2] / (depth * projection[2][3] - projection[2][2]);\n}\n\n@import clay.util.rgbm\n\n\nvoid main()\n{\n @import clay.compositor.kernel.gaussian_9\n\n vec4 centerNTexel = texture2D(gBufferTexture1, v_Texcoord);\n float g = centerNTexel.a;\n float maxBlurSize = clamp(1.0 - g, 0.0, 1.0) * blurSize;\n#ifdef VERTICAL\n vec2 off = vec2(0.0, maxBlurSize / textureSize.y);\n#else\n vec2 off = vec2(maxBlurSize / textureSize.x, 0.0);\n#endif\n\n vec2 coord = v_Texcoord;\n\n vec4 sum = vec4(0.0);\n float weightAll = 0.0;\n\n vec3 cN = centerNTexel.rgb * 2.0 - 1.0;\n float cD = getLinearDepth(v_Texcoord);\n for (int i = 0; i < 9; i++) {\n vec2 coord = clamp((float(i) - 4.0) * off + v_Texcoord, vec2(0.0), vec2(1.0));\n float w = gaussianKernel[i]\n * clamp(dot(cN, texture2D(gBufferTexture1, coord).rgb * 2.0 - 1.0), 0.0, 1.0);\n float d = getLinearDepth(coord);\n w *= (1.0 - smoothstep(abs(cD - d) / depthRange, 0.0, 1.0));\n\n weightAll += w;\n sum += decodeHDR(texture2D(texture, coord)) * w;\n }\n\n#ifdef BLEND\n float aoFactor = 1.0;\n #ifdef SSAOTEX_ENABLED\n aoFactor = texture2D(ssaoTex, v_Texcoord).r;\n #endif\n gl_FragColor = encodeHDR(\n sum / weightAll * aoFactor + decodeHDR(texture2D(sourceTexture, v_Texcoord))\n );\n#else\n gl_FragColor = encodeHDR(sum / weightAll);\n#endif\n}\n\n@end"),gl.prototype.setAmbientCubemap=function(e,t){this._ssrPass.material.set("specularCubemap",e),this._ssrPass.material.set("specularIntensity",t);var r=e&&t;this._ssrPass.material[r?"enableTexture":"disableTexture"]("specularCubemap")},gl.prototype.update=function(e,t,r,i){var n=e.getWidth(),a=e.getHeight(),o=this._ssrTexture,s=this._texture2,l=this._texture3;o.width=this._prevTexture.width=this._currentTexture.width=n/this._downScale,o.height=this._prevTexture.height=this._currentTexture.height=a/this._downScale,s.width=l.width=n,s.height=l.height=a;var h=this._frameBuffer,u=this._ssrPass,c=this._blurPass1,d=this._blurPass2,f=this._blendPass,p=new Ht,m=new Ht;Ht.transpose(p,t.worldTransform),Ht.transpose(m,t.viewMatrix),u.setUniform("sourceTexture",r),u.setUniform("projection",t.projectionMatrix.array),u.setUniform("projectionInv",t.invProjectionMatrix.array),u.setUniform("toViewSpace",p.array),u.setUniform("toWorldSpace",m.array),u.setUniform("nearZ",t.near);var g=i/this._totalSamples*this._samplePerFrame;if(u.setUniform("jitterOffset",g),u.setUniform("sampleOffset",i*this._samplePerFrame),c.setUniform("textureSize",[o.width,o.height]),d.setUniform("textureSize",[n,a]),d.setUniform("sourceTexture",r),c.setUniform("projection",t.projectionMatrix.array),d.setUniform("projection",t.projectionMatrix.array),h.attach(o),h.bind(e),u.render(e),this._physicallyCorrect&&(h.attach(this._currentTexture),f.setUniform("texture1",this._prevTexture),f.setUniform("texture2",o),f.material.set({weight1:i>=1?.95:0,weight2:i>=1?.05:1}),f.render(e)),h.attach(s),c.setUniform("texture",this._physicallyCorrect?this._currentTexture:o),c.render(e),h.attach(l),d.setUniform("texture",s),d.render(e),h.unbind(e),this._physicallyCorrect){var _=this._prevTexture;this._prevTexture=this._currentTexture,this._currentTexture=_}},gl.prototype.getTargetTexture=function(){return this._texture3},gl.prototype.setParameter=function(e,t){"maxIteration"===e?this._ssrPass.material.define("fragment","MAX_ITERATION",t):this._ssrPass.setUniform(e,t)},gl.prototype.setPhysicallyCorrect=function(e){e?(this._normalDistribution||(this._normalDistribution=_n.generateNormalDistribution(64,this._totalSamples)),this._ssrPass.material.define("fragment","PHYSICALLY_CORRECT"),this._ssrPass.material.set("normalDistribution",this._normalDistribution),this._ssrPass.material.set("normalDistributionSize",[64,this._totalSamples])):this._ssrPass.material.undefine("fragment","PHYSICALLY_CORRECT"),this._physicallyCorrect=e},gl.prototype.setSSAOTexture=function(e){var t=this._blurPass2;e?(t.material.enableTexture("ssaoTex"),t.material.set("ssaoTex",e)):t.material.disableTexture("ssaoTex")},gl.prototype.isFinished=function(e){return!this._physicallyCorrect||e>this._totalSamples/this._samplePerFrame},gl.prototype.dispose=function(e){this._ssrTexture.dispose(e),this._texture2.dispose(e),this._texture3.dispose(e),this._prevTexture.dispose(e),this._currentTexture.dispose(e),this._frameBuffer.dispose(e)};const _l=gl,vl=[0,0,-.321585265978,-.154972575841,.458126042375,.188473391593,.842080129861,.527766490688,.147304551086,-.659453822776,-.331943915203,-.940619700594,.0479226680259,.54812163202,.701581552186,-.709825561388,-.295436780218,.940589268233,-.901489676764,.237713156085,.973570876096,-.109899459384,-.866792314779,-.451805525005,.330975007087,.800048655954,-.344275183665,.381779221166,-.386139432542,-.437418421534,-.576478634965,-.0148463392551,.385798197415,-.262426961053,-.666302061145,.682427250835,-.628010632582,-.732836215494,.10163141741,-.987658134403,.711995289051,-.320024291314,.0296005138058,.950296523438,.0130612307608,-.351024443122,-.879596633704,-.10478487883,.435712737232,.504254490347,.779203817497,.206477676721,.388264289969,-.896736162545,-.153106280781,-.629203242522,-.245517550697,.657969239148,.126830499058,.26862328493,-.634888119007,-.302301223431,.617074219636,.779817204925];function yl(e,t,r,i,n){var a=e.gl;t.setUniform(a,"1i",r,n),a.activeTexture(a.TEXTURE0+n),i.isRenderable()?i.bind(e):i.unbind(e)}function xl(e,t,r,i,n){var a,o,s,l,h=e.gl;return function(n,u,c){if(!l||l.material!==n.material){var d=n.material,f=n.__program,p=d.get("roughness");null==p&&(p=1);var m=d.get("normalMap")||t,g=d.get("roughnessMap"),_=d.get("bumpMap"),v=d.get("uvRepeat"),y=d.get("uvOffset"),x=d.get("detailUvRepeat"),b=d.get("detailUvOffset"),w=!!_&&d.isTextureEnabled("bumpMap"),T=!!g&&d.isTextureEnabled("roughnessMap"),S=d.isDefined("fragment","DOUBLE_SIDED");_=_||r,g=g||i,c!==u?(u.set("normalMap",m),u.set("bumpMap",_),u.set("roughnessMap",g),u.set("useBumpMap",w),u.set("useRoughnessMap",T),u.set("doubleSide",S),null!=v&&u.set("uvRepeat",v),null!=y&&u.set("uvOffset",y),null!=x&&u.set("detailUvRepeat",x),null!=b&&u.set("detailUvOffset",b),u.set("roughness",p)):(f.setUniform(h,"1f","roughness",p),a!==m&&yl(e,f,"normalMap",m,0),o!==_&&_&&yl(e,f,"bumpMap",_,1),s!==g&&g&&yl(e,f,"roughnessMap",g,2),null!=v&&f.setUniform(h,"2f","uvRepeat",v),null!=y&&f.setUniform(h,"2f","uvOffset",y),null!=x&&f.setUniform(h,"2f","detailUvRepeat",x),null!=b&&f.setUniform(h,"2f","detailUvOffset",b),f.setUniform(h,"1i","useBumpMap",+w),f.setUniform(h,"1i","useRoughnessMap",+T),f.setUniform(h,"1i","doubleSide",+S)),a=m,o=_,s=g,l=n}}}function bl(e){e=e||{},this._depthTex=new Dr({format:wr.DEPTH_COMPONENT,type:wr.UNSIGNED_INT}),this._normalTex=new Dr({type:wr.HALF_FLOAT}),this._framebuffer=new zi,this._framebuffer.attach(this._normalTex),this._framebuffer.attach(this._depthTex,zi.DEPTH_ATTACHMENT),this._normalMaterial=new le({shader:new Xe(Xe.source("ecgl.normal.vertex"),Xe.source("ecgl.normal.fragment"))}),this._normalMaterial.enableTexture(["normalMap","bumpMap","roughnessMap"]),this._defaultNormalMap=an.createBlank("#000"),this._defaultBumpMap=an.createBlank("#000"),this._defaultRoughessMap=an.createBlank("#000"),this._debugPass=new pn({fragment:Xe.source("clay.compositor.output")}),this._debugPass.setUniform("texture",this._normalTex),this._debugPass.material.undefine("fragment","OUTPUT_ALPHA")}Xe.import("@export ecgl.normal.vertex\n\n@import ecgl.common.transformUniforms\n\n@import ecgl.common.uv.header\n\n@import ecgl.common.attributes\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\n@import ecgl.common.normalMap.vertexHeader\n\n@import ecgl.common.vertexAnimation.header\n\nvoid main()\n{\n\n @import ecgl.common.vertexAnimation.main\n\n @import ecgl.common.uv.main\n\n v_Normal = normalize((worldInverseTranspose * vec4(normal, 0.0)).xyz);\n v_WorldPosition = (world * vec4(pos, 1.0)).xyz;\n\n @import ecgl.common.normalMap.vertexMain\n\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n\n}\n\n\n@end\n\n\n@export ecgl.normal.fragment\n\n#define ROUGHNESS_CHANEL 0\n\nuniform bool useBumpMap;\nuniform bool useRoughnessMap;\nuniform bool doubleSide;\nuniform float roughness;\n\n@import ecgl.common.uv.fragmentHeader\n\nvarying vec3 v_Normal;\nvarying vec3 v_WorldPosition;\n\nuniform mat4 viewInverse : VIEWINVERSE;\n\n@import ecgl.common.normalMap.fragmentHeader\n@import ecgl.common.bumpMap.header\n\nuniform sampler2D roughnessMap;\n\nvoid main()\n{\n vec3 N = v_Normal;\n \n bool flipNormal = false;\n if (doubleSide) {\n vec3 eyePos = viewInverse[3].xyz;\n vec3 V = normalize(eyePos - v_WorldPosition);\n\n if (dot(N, V) < 0.0) {\n flipNormal = true;\n }\n }\n\n @import ecgl.common.normalMap.fragmentMain\n\n if (useBumpMap) {\n N = bumpNormal(v_WorldPosition, v_Normal, N);\n }\n\n float g = 1.0 - roughness;\n\n if (useRoughnessMap) {\n float g2 = 1.0 - texture2D(roughnessMap, v_DetailTexcoord)[ROUGHNESS_CHANEL];\n g = clamp(g2 + (g - 0.5) * 2.0, 0.0, 1.0);\n }\n\n if (flipNormal) {\n N = -N;\n }\n\n gl_FragColor.rgb = (N.xyz + 1.0) * 0.5;\n gl_FragColor.a = g;\n}\n@end"),bl.prototype.getDepthTexture=function(){return this._depthTex},bl.prototype.getNormalTexture=function(){return this._normalTex},bl.prototype.update=function(e,t,r){var i=e.getWidth(),n=e.getHeight(),a=this._depthTex,o=this._normalTex,s=this._normalMaterial;a.width=i,a.height=n,o.width=i,o.height=n;var l=t.getRenderList(r).opaque;this._framebuffer.bind(e),e.gl.clearColor(0,0,0,0),e.gl.clear(e.gl.COLOR_BUFFER_BIT|e.gl.DEPTH_BUFFER_BIT),e.gl.disable(e.gl.BLEND),e.renderPass(l,r,{getMaterial:function(){return s},ifRender:function(e){return e.renderNormal},beforeRender:xl(e,this._defaultNormalMap,this._defaultBumpMap,this._defaultRoughessMap,this._normalMaterial),sort:e.opaqueSortCompare}),this._framebuffer.unbind(e)},bl.prototype.renderDebug=function(e){this._debugPass.render(e)},bl.prototype.dispose=function(e){this._depthTex.dispose(e),this._normalTex.dispose(e)};const wl=bl;function Tl(e){e=e||{},this._edgePass=new pn({fragment:Xe.source("ecgl.edge")}),this._edgePass.setUniform("normalTexture",e.normalTexture),this._edgePass.setUniform("depthTexture",e.depthTexture),this._targetTexture=new Dr({type:wr.HALF_FLOAT}),this._frameBuffer=new zi,this._frameBuffer.attach(this._targetTexture)}Tl.prototype.update=function(e,t,r,i){var n=e.getWidth(),a=e.getHeight(),o=this._targetTexture;o.width=n,o.height=a;var s=this._frameBuffer;s.bind(e),this._edgePass.setUniform("projectionInv",t.invProjectionMatrix.array),this._edgePass.setUniform("textureSize",[n,a]),this._edgePass.setUniform("texture",r),this._edgePass.render(e),s.unbind(e)},Tl.prototype.getTargetTexture=function(){return this._targetTexture},Tl.prototype.setParameter=function(e,t){this._edgePass.setUniform(e,t)},Tl.prototype.dispose=function(e){this._targetTexture.dispose(e),this._frameBuffer.dispose(e)};const Sl=Tl,Ml={type:"compositor",nodes:[{name:"source",type:"texture",outputs:{color:{}}},{name:"source_half",shader:"#source(clay.compositor.downsample)",inputs:{texture:"source"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 2)",height:"expr(height * 1.0 / 2)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0, height * 1.0] )"}},{name:"bright",shader:"#source(clay.compositor.bright)",inputs:{texture:"source_half"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 2)",height:"expr(height * 1.0 / 2)",type:"HALF_FLOAT"}}},parameters:{threshold:2,scale:4,textureSize:"expr([width * 1.0 / 2, height / 2])"}},{name:"bright_downsample_4",shader:"#source(clay.compositor.downsample)",inputs:{texture:"bright"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 4)",height:"expr(height * 1.0 / 4)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0 / 2, height / 2] )"}},{name:"bright_downsample_8",shader:"#source(clay.compositor.downsample)",inputs:{texture:"bright_downsample_4"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 8)",height:"expr(height * 1.0 / 8)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0 / 4, height / 4] )"}},{name:"bright_downsample_16",shader:"#source(clay.compositor.downsample)",inputs:{texture:"bright_downsample_8"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 16)",height:"expr(height * 1.0 / 16)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0 / 8, height / 8] )"}},{name:"bright_downsample_32",shader:"#source(clay.compositor.downsample)",inputs:{texture:"bright_downsample_16"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 32)",height:"expr(height * 1.0 / 32)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0 / 16, height / 16] )"}},{name:"bright_upsample_16_blur_h",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_downsample_32"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 16)",height:"expr(height * 1.0 / 16)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:0,textureSize:"expr( [width * 1.0 / 32, height / 32] )"}},{name:"bright_upsample_16_blur_v",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_upsample_16_blur_h"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 16)",height:"expr(height * 1.0 / 16)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:1,textureSize:"expr( [width * 1.0 / 16, height * 1.0 / 16] )"}},{name:"bright_upsample_8_blur_h",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_downsample_16"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 8)",height:"expr(height * 1.0 / 8)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:0,textureSize:"expr( [width * 1.0 / 16, height * 1.0 / 16] )"}},{name:"bright_upsample_8_blur_v",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_upsample_8_blur_h"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 8)",height:"expr(height * 1.0 / 8)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:1,textureSize:"expr( [width * 1.0 / 8, height * 1.0 / 8] )"}},{name:"bright_upsample_8_blend",shader:"#source(clay.compositor.blend)",inputs:{texture1:"bright_upsample_8_blur_v",texture2:"bright_upsample_16_blur_v"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 8)",height:"expr(height * 1.0 / 8)",type:"HALF_FLOAT"}}},parameters:{weight1:.3,weight2:.7}},{name:"bright_upsample_4_blur_h",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_downsample_8"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 4)",height:"expr(height * 1.0 / 4)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:0,textureSize:"expr( [width * 1.0 / 8, height * 1.0 / 8] )"}},{name:"bright_upsample_4_blur_v",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_upsample_4_blur_h"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 4)",height:"expr(height * 1.0 / 4)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:1,textureSize:"expr( [width * 1.0 / 4, height * 1.0 / 4] )"}},{name:"bright_upsample_4_blend",shader:"#source(clay.compositor.blend)",inputs:{texture1:"bright_upsample_4_blur_v",texture2:"bright_upsample_8_blend"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 4)",height:"expr(height * 1.0 / 4)",type:"HALF_FLOAT"}}},parameters:{weight1:.3,weight2:.7}},{name:"bright_upsample_2_blur_h",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_downsample_4"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 2)",height:"expr(height * 1.0 / 2)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:0,textureSize:"expr( [width * 1.0 / 4, height * 1.0 / 4] )"}},{name:"bright_upsample_2_blur_v",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_upsample_2_blur_h"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 2)",height:"expr(height * 1.0 / 2)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:1,textureSize:"expr( [width * 1.0 / 2, height * 1.0 / 2] )"}},{name:"bright_upsample_2_blend",shader:"#source(clay.compositor.blend)",inputs:{texture1:"bright_upsample_2_blur_v",texture2:"bright_upsample_4_blend"},outputs:{color:{parameters:{width:"expr(width * 1.0 / 2)",height:"expr(height * 1.0 / 2)",type:"HALF_FLOAT"}}},parameters:{weight1:.3,weight2:.7}},{name:"bright_upsample_full_blur_h",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:0,textureSize:"expr( [width * 1.0 / 2, height * 1.0 / 2] )"}},{name:"bright_upsample_full_blur_v",shader:"#source(clay.compositor.gaussian_blur)",inputs:{texture:"bright_upsample_full_blur_h"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)",type:"HALF_FLOAT"}}},parameters:{blurSize:1,blurDir:1,textureSize:"expr( [width * 1.0, height * 1.0] )"}},{name:"bloom_composite",shader:"#source(clay.compositor.blend)",inputs:{texture1:"bright_upsample_full_blur_v",texture2:"bright_upsample_2_blend"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)",type:"HALF_FLOAT"}}},parameters:{weight1:.3,weight2:.7}},{name:"coc",shader:"#source(ecgl.dof.coc)",outputs:{color:{parameters:{minFilter:"NEAREST",magFilter:"NEAREST",width:"expr(width * 1.0)",height:"expr(height * 1.0)"}}},parameters:{focalDist:50,focalRange:30}},{name:"dof_far_blur",shader:"#source(ecgl.dof.diskBlur)",inputs:{texture:"source",coc:"coc"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0, height * 1.0] )"}},{name:"dof_near_blur",shader:"#source(ecgl.dof.diskBlur)",inputs:{texture:"source",coc:"coc"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)",type:"HALF_FLOAT"}}},parameters:{textureSize:"expr( [width * 1.0, height * 1.0] )"},defines:{BLUR_NEARFIELD:null}},{name:"dof_coc_blur",shader:"#source(ecgl.dof.diskBlur)",inputs:{texture:"coc"},outputs:{color:{parameters:{minFilter:"NEAREST",magFilter:"NEAREST",width:"expr(width * 1.0)",height:"expr(height * 1.0)"}}},parameters:{textureSize:"expr( [width * 1.0, height * 1.0] )"},defines:{BLUR_COC:null}},{name:"dof_composite",shader:"#source(ecgl.dof.composite)",inputs:{original:"source",blurred:"dof_far_blur",nearfield:"dof_near_blur",coc:"coc",nearcoc:"dof_coc_blur"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)",type:"HALF_FLOAT"}}}},{name:"composite",shader:"#source(clay.compositor.hdr.composite)",inputs:{texture:"source",bloom:"bloom_composite"},outputs:{color:{parameters:{width:"expr(width * 1.0)",height:"expr(height * 1.0)"}}},defines:{}},{name:"FXAA",shader:"#source(clay.compositor.fxaa)",inputs:{texture:"composite"}}]};function Al(e,t){return{color:{parameters:{width:e,height:t}}}}Xe.import(Zs),Xe.import(Ys),Xe.import(Ks),Xe.import(Qs),Xe.import(Js),Xe.import($s),Xe.import(el),Xe.import(tl),Xe.import(rl),Xe.import("@export ecgl.dof.coc\n\nuniform sampler2D depth;\n\nuniform float zNear: 0.1;\nuniform float zFar: 2000;\n\nuniform float focalDistance: 3;\nuniform float focalRange: 1;\nuniform float focalLength: 30;\nuniform float fstop: 2.8;\n\nvarying vec2 v_Texcoord;\n\n@import clay.util.encode_float\n\nvoid main()\n{\n float z = texture2D(depth, v_Texcoord).r * 2.0 - 1.0;\n\n float dist = 2.0 * zNear * zFar / (zFar + zNear - z * (zFar - zNear));\n\n float aperture = focalLength / fstop;\n\n float coc;\n\n float uppper = focalDistance + focalRange;\n float lower = focalDistance - focalRange;\n if (dist <= uppper && dist >= lower) {\n coc = 0.5;\n }\n else {\n float focalAdjusted = dist > uppper ? uppper : lower;\n\n coc = abs(aperture * (focalLength * (dist - focalAdjusted)) / (dist * (focalAdjusted - focalLength)));\n coc = clamp(coc, 0.0, 2.0) / 2.00001;\n\n if (dist < lower) {\n coc = -coc;\n }\n coc = coc * 0.5 + 0.5;\n }\n\n gl_FragColor = encodeFloat(coc);\n}\n@end\n\n\n@export ecgl.dof.composite\n\n#define DEBUG 0\n\nuniform sampler2D original;\nuniform sampler2D blurred;\nuniform sampler2D nearfield;\nuniform sampler2D coc;\nuniform sampler2D nearcoc;\nvarying vec2 v_Texcoord;\n\n@import clay.util.rgbm\n@import clay.util.float\n\nvoid main()\n{\n vec4 blurredColor = texture2D(blurred, v_Texcoord);\n vec4 originalColor = texture2D(original, v_Texcoord);\n\n float fCoc = decodeFloat(texture2D(coc, v_Texcoord));\n\n fCoc = abs(fCoc * 2.0 - 1.0);\n\n float weight = smoothstep(0.0, 1.0, fCoc);\n \n#ifdef NEARFIELD_ENABLED\n vec4 nearfieldColor = texture2D(nearfield, v_Texcoord);\n float fNearCoc = decodeFloat(texture2D(nearcoc, v_Texcoord));\n fNearCoc = abs(fNearCoc * 2.0 - 1.0);\n\n gl_FragColor = encodeHDR(\n mix(\n nearfieldColor, mix(originalColor, blurredColor, weight),\n pow(1.0 - fNearCoc, 4.0)\n )\n );\n#else\n gl_FragColor = encodeHDR(mix(originalColor, blurredColor, weight));\n#endif\n\n}\n\n@end\n\n\n\n@export ecgl.dof.diskBlur\n\n#define POISSON_KERNEL_SIZE 16;\n\nuniform sampler2D texture;\nuniform sampler2D coc;\nvarying vec2 v_Texcoord;\n\nuniform float blurRadius : 10.0;\nuniform vec2 textureSize : [512.0, 512.0];\n\nuniform vec2 poissonKernel[POISSON_KERNEL_SIZE];\n\nuniform float percent;\n\nfloat nrand(const in vec2 n) {\n return fract(sin(dot(n.xy ,vec2(12.9898,78.233))) * 43758.5453);\n}\n\n@import clay.util.rgbm\n@import clay.util.float\n\n\nvoid main()\n{\n vec2 offset = blurRadius / textureSize;\n\n float rnd = 6.28318 * nrand(v_Texcoord + 0.07 * percent );\n float cosa = cos(rnd);\n float sina = sin(rnd);\n vec4 basis = vec4(cosa, -sina, sina, cosa);\n\n#if !defined(BLUR_NEARFIELD) && !defined(BLUR_COC)\n offset *= abs(decodeFloat(texture2D(coc, v_Texcoord)) * 2.0 - 1.0);\n#endif\n\n#ifdef BLUR_COC\n float cocSum = 0.0;\n#else\n vec4 color = vec4(0.0);\n#endif\n\n\n float weightSum = 0.0;\n\n for (int i = 0; i < POISSON_KERNEL_SIZE; i++) {\n vec2 ofs = poissonKernel[i];\n\n ofs = vec2(dot(ofs, basis.xy), dot(ofs, basis.zw));\n\n vec2 uv = v_Texcoord + ofs * offset;\n vec4 texel = texture2D(texture, uv);\n\n float w = 1.0;\n#ifdef BLUR_COC\n float fCoc = decodeFloat(texel) * 2.0 - 1.0;\n cocSum += clamp(fCoc, -1.0, 0.0) * w;\n#else\n texel = texel;\n #if !defined(BLUR_NEARFIELD)\n float fCoc = decodeFloat(texture2D(coc, uv)) * 2.0 - 1.0;\n w *= abs(fCoc);\n #endif\n texel.rgb *= texel.a;\n color += texel * w;\n#endif\n\n weightSum += w;\n }\n\n#ifdef BLUR_COC\n gl_FragColor = encodeFloat(clamp(cocSum / weightSum, -1.0, 0.0) * 0.5 + 0.5);\n#else\n color /= weightSum;\n color.rgb /= (color.a + 0.0001);\n gl_FragColor = color;\n#endif\n}\n\n@end"),Xe.import("@export ecgl.edge\n\nuniform sampler2D texture;\n\nuniform sampler2D normalTexture;\nuniform sampler2D depthTexture;\n\nuniform mat4 projectionInv;\n\nuniform vec2 textureSize;\n\nuniform vec4 edgeColor: [0,0,0,0.8];\n\nvarying vec2 v_Texcoord;\n\nvec3 packColor(vec2 coord) {\n float z = texture2D(depthTexture, coord).r * 2.0 - 1.0;\n vec4 p = vec4(v_Texcoord * 2.0 - 1.0, z, 1.0);\n vec4 p4 = projectionInv * p;\n\n return vec3(\n texture2D(normalTexture, coord).rg,\n -p4.z / p4.w / 5.0\n );\n}\n\nvoid main() {\n vec2 cc = v_Texcoord;\n vec3 center = packColor(cc);\n\n float size = clamp(1.0 - (center.z - 10.0) / 100.0, 0.0, 1.0) * 0.5;\n float dx = size / textureSize.x;\n float dy = size / textureSize.y;\n\n vec2 coord;\n vec3 topLeft = packColor(cc+vec2(-dx, -dy));\n vec3 top = packColor(cc+vec2(0.0, -dy));\n vec3 topRight = packColor(cc+vec2(dx, -dy));\n vec3 left = packColor(cc+vec2(-dx, 0.0));\n vec3 right = packColor(cc+vec2(dx, 0.0));\n vec3 bottomLeft = packColor(cc+vec2(-dx, dy));\n vec3 bottom = packColor(cc+vec2(0.0, dy));\n vec3 bottomRight = packColor(cc+vec2(dx, dy));\n\n vec3 v = -topLeft-2.0*top-topRight+bottomLeft+2.0*bottom+bottomRight;\n vec3 h = -bottomLeft-2.0*left-topLeft+bottomRight+2.0*right+topRight;\n\n float edge = sqrt(dot(h, h) + dot(v, v));\n\n edge = smoothstep(0.8, 1.0, edge);\n\n gl_FragColor = mix(texture2D(texture, v_Texcoord), vec4(edgeColor.rgb, 1.0), edgeColor.a * edge);\n}\n@end");var El=["composite","FXAA"];function Cl(){this._width,this._height,this._dpr,this._sourceTexture=new Dr({type:wr.HALF_FLOAT}),this._depthTexture=new Dr({format:wr.DEPTH_COMPONENT,type:wr.UNSIGNED_INT}),this._framebuffer=new zi,this._framebuffer.attach(this._sourceTexture),this._framebuffer.attach(this._depthTexture,zi.DEPTH_ATTACHMENT),this._normalPass=new wl,this._compositor=function(e,t){var r=new Ws;t=t||{};var i={textures:{},parameters:{}};for(var n in e.parameters){var a=e.parameters[n];i.parameters[n]=sl(a)}return function(e,t,r,i){if(e.textures){var n={},a=0,o=!1,s=r.textureRootPath;f.each(e.textures,(function(e,t){var r,l=e.path,h=sl(e.parameters);if(Array.isArray(l)&&6===l.length)s&&(l=l.map((function(e){return f.relative2absolute(e,s)}))),r=new Ai(h);else{if("string"!=typeof l)return;s&&(l=f.relative2absolute(l,s)),r=new Dr(h)}r.load(l),a++,r.once("success",(function(){n[t]=r,0==--a&&(i(n),o=!0)}))})),0!==a||o||i(n)}else i({})}(e,0,t,(function(n){i.textures=n,function(n,a){for(var o=0;o=this._haltonSequence.length},render:function(e,t,r){var i=this._blendPass;0===this._frame?(i.setUniform("weight1",0),i.setUniform("weight2",1)):(i.setUniform("weight1",.9),i.setUniform("weight2",.1)),i.setUniform("texture1",this._prevFrameTex),i.setUniform("texture2",t||this._sourceTex),this._blendFb.attach(this._outputTex),this._blendFb.bind(e),i.render(e),this._blendFb.unbind(e),r||(this._outputPass.setUniform("texture",this._outputTex),this._outputPass.render(e));var n=this._prevFrameTex;this._prevFrameTex=this._outputTex,this._outputTex=n,this._frame++},dispose:function(e){this._sourceFb.dispose(e),this._blendFb.dispose(e),this._prevFrameTex.dispose(e),this._outputTex.dispose(e),this._sourceTex.dispose(e),this._outputPass.dispose(e),this._blendPass.dispose(e)}};const Pl=Ll;function Ol(e){e=e||"perspective",this.layer=null,this.scene=new vi,this.rootNode=this.scene,this.viewport={x:0,y:0,width:0,height:0},this.setProjection(e),this._compositor=new Dl,this._temporalSS=new Pl,this._shadowMapPass=new ks;for(var t=[],r=0,i=0;i<30;i++){for(var n=[],a=0;a<6;a++)n.push(4*ul(r,2)-2),n.push(4*ul(r,3)-2),r++;t.push(n)}this._pcfKernels=t,this.scene.on("beforerender",(function(e,t,r){this.needsTemporalSS()&&this._temporalSS.jitterProjection(e,r)}),this)}Ol.prototype.setProjection=function(e){var t=this.camera;t&&t.update(),"perspective"===e?this.camera instanceof Ei||(this.camera=new Ei,t&&this.camera.setLocalTransform(t.localTransform)):this.camera instanceof un||(this.camera=new un,t&&this.camera.setLocalTransform(t.localTransform)),this.camera.near=.1,this.camera.far=2e3},Ol.prototype.setViewport=function(e,t,r,i,n){this.camera instanceof Ei&&(this.camera.aspect=r/i),n=n||1,this.viewport.x=e,this.viewport.y=t,this.viewport.width=r,this.viewport.height=i,this.viewport.devicePixelRatio=n,this._compositor.resize(r*n,i*n),this._temporalSS.resize(r*n,i*n)},Ol.prototype.containPoint=function(e,t){var r=this.viewport;return t=this.layer.renderer.getHeight()-t,e>=r.x&&t>=r.y&&e<=r.x+r.width&&t<=r.y+r.height};var Nl=new _e;Ol.prototype.castRay=function(e,t,r){var i=this.layer.renderer,n=i.viewport;return i.viewport=this.viewport,i.screenToNDC(e,t,Nl),this.camera.castRay(Nl,r),i.viewport=n,r},Ol.prototype.prepareRender=function(){this.scene.update(),this.camera.update(),this.scene.updateLights();var e=this.scene.updateRenderList(this.camera);this._needsSortProgressively=!1;for(var t=0;t30},Ol.prototype._doRender=function(e,t,r){var i=this.scene,n=this.camera;r=r||0,this._updateTransparent(e,i,n,r),t||(this._shadowMapPass.kernelPCF=this._pcfKernels[0],this._shadowMapPass.render(e,i,n,!0)),this._updateShadowPCFKernel(r);var a,o=e.clearColor;e.gl.clearColor(o[0],o[1],o[2],o[3]),this._enablePostEffect&&(this.needsTemporalSS()&&this._temporalSS.jitterProjection(e,n),this._compositor.updateNormal(e,i,n,this._temporalSS.getFrame())),this._updateSSAO(e,i,n,this._temporalSS.getFrame()),this._enablePostEffect?((a=this._compositor.getSourceFrameBuffer()).bind(e),e.gl.clear(e.gl.DEPTH_BUFFER_BIT|e.gl.COLOR_BUFFER_BIT),e.render(i,n,!0,!0),a.unbind(e),this.needsTemporalSS()&&t?(this._compositor.composite(e,i,n,this._temporalSS.getSourceFrameBuffer(),this._temporalSS.getFrame()),e.setViewport(this.viewport),this._temporalSS.render(e)):(e.setViewport(this.viewport),this._compositor.composite(e,i,n,null,0))):this.needsTemporalSS()&&t?((a=this._temporalSS.getSourceFrameBuffer()).bind(e),e.saveClear(),e.clearBit=e.gl.DEPTH_BUFFER_BIT|e.gl.COLOR_BUFFER_BIT,e.render(i,n,!0,!0),e.restoreClear(),a.unbind(e),e.setViewport(this.viewport),this._temporalSS.render(e)):(e.setViewport(this.viewport),e.render(i,n,!0,!0))},Ol.prototype._updateTransparent=function(e,t,r,i){for(var n=new vt,a=new Ht,o=r.getWorldPosition(),s=t.getRenderList(r).transparent,l=0;lthis.camera.far||e80*r){i=a=e[0],n=o=e[1];for(var p=r;pa&&(a=s),l>o&&(o=l);h=Math.max(a-i,o-n)}return nh(d,f,r,i,n,h),f}function rh(e,t,r,i,n){var a,o;if(n===Th(e,t,r,i)>0)for(a=t;a=t;a-=i)o=xh(a,e[a],e[a+1],o);return o&&gh(o,o.next)&&(bh(o),o=o.next),o}function ih(e,t){if(!e)return e;t||(t=e);var r,i=e;do{if(r=!1,i.steiner||!gh(i,i.next)&&0!==mh(i.prev,i,i.next))i=i.next;else{if(bh(i),(i=t=i.prev)===i.next)return null;r=!0}}while(r||i!==t);return t}function nh(e,t,r,i,n,a,o){if(e){!o&&a&&function(e,t,r,i){var n=e;do{null===n.z&&(n.z=ch(n.x,n.y,t,r,i)),n.prevZ=n.prev,n.nextZ=n.next,n=n.next}while(n!==e);n.prevZ.nextZ=null,n.prevZ=null,function(e){var t,r,i,n,a,o,s,l,h=1;do{for(r=e,e=null,a=null,o=0;r;){for(o++,i=r,s=0,t=0;t0||l>0&&i;)0!==s&&(0===l||!i||r.z<=i.z)?(n=r,r=r.nextZ,s--):(n=i,i=i.nextZ,l--),a?a.nextZ=n:e=n,n.prevZ=a,a=n;r=i}a.nextZ=null,h*=2}while(o>1)}(n)}(e,i,n,a);for(var s,l,h=e;e.prev!==e.next;)if(s=e.prev,l=e.next,a?oh(e,i,n,a):ah(e))t.push(s.i/r),t.push(e.i/r),t.push(l.i/r),bh(e),e=l.next,h=l.next;else if((e=l)===h){o?1===o?nh(e=sh(e,t,r),t,r,i,n,a,2):2===o&&lh(e,t,r,i,n,a):nh(ih(e),t,r,i,n,a,1);break}}}function ah(e){var t=e.prev,r=e,i=e.next;if(mh(t,r,i)>=0)return!1;for(var n=e.next.next;n!==e.prev;){if(fh(t.x,t.y,r.x,r.y,i.x,i.y,n.x,n.y)&&mh(n.prev,n,n.next)>=0)return!1;n=n.next}return!0}function oh(e,t,r,i){var n=e.prev,a=e,o=e.next;if(mh(n,a,o)>=0)return!1;for(var s=n.xa.x?n.x>o.x?n.x:o.x:a.x>o.x?a.x:o.x,u=n.y>a.y?n.y>o.y?n.y:o.y:a.y>o.y?a.y:o.y,c=ch(s,l,t,r,i),d=ch(h,u,t,r,i),f=e.nextZ;f&&f.z<=d;){if(f!==e.prev&&f!==e.next&&fh(n.x,n.y,a.x,a.y,o.x,o.y,f.x,f.y)&&mh(f.prev,f,f.next)>=0)return!1;f=f.nextZ}for(f=e.prevZ;f&&f.z>=c;){if(f!==e.prev&&f!==e.next&&fh(n.x,n.y,a.x,a.y,o.x,o.y,f.x,f.y)&&mh(f.prev,f,f.next)>=0)return!1;f=f.prevZ}return!0}function sh(e,t,r){var i=e;do{var n=i.prev,a=i.next.next;!gh(n,a)&&_h(n,i,i.next,a)&&vh(n,a)&&vh(a,n)&&(t.push(n.i/r),t.push(i.i/r),t.push(a.i/r),bh(i),bh(i.next),i=e=a),i=i.next}while(i!==e);return i}function lh(e,t,r,i,n,a){var o=e;do{for(var s=o.next.next;s!==o.prev;){if(o.i!==s.i&&ph(o,s)){var l=yh(o,s);return o=ih(o,o.next),l=ih(l,l.next),nh(o,t,r,i,n,a),void nh(l,t,r,i,n,a)}s=s.next}o=o.next}while(o!==e)}function hh(e,t){return e.x-t.x}function uh(e,t){if(t=function(e,t){var r,i=t,n=e.x,a=e.y,o=-1/0;do{if(a<=i.y&&a>=i.next.y&&i.next.y!==i.y){var s=i.x+(a-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(s<=n&&s>o){if(o=s,s===n){if(a===i.y)return i;if(a===i.next.y)return i.next}r=i.x=i.x&&i.x>=u&&n!==i.x&&fh(ar.x)&&vh(i,e)&&(r=i,d=l),i=i.next;return r}(e,t)){var r=yh(t,e);ih(r,r.next)}}function ch(e,t,r,i,n){return(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=32767*(e-r)/n)|e<<8))|e<<4))|e<<2))|e<<1))|(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=32767*(t-i)/n)|t<<8))|t<<4))|t<<2))|t<<1))<<1}function dh(e){var t=e,r=e;do{t.x=0&&(e-o)*(i-s)-(r-o)*(t-s)>=0&&(r-o)*(a-s)-(n-o)*(i-s)>=0}function ph(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!function(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&_h(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}(e,t)&&vh(e,t)&&vh(t,e)&&function(e,t){var r=e,i=!1,n=(e.x+t.x)/2,a=(e.y+t.y)/2;do{r.y>a!=r.next.y>a&&r.next.y!==r.y&&n<(r.next.x-r.x)*(a-r.y)/(r.next.y-r.y)+r.x&&(i=!i),r=r.next}while(r!==e);return i}(e,t)}function mh(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function gh(e,t){return e.x===t.x&&e.y===t.y}function _h(e,t,r,i){return!!(gh(e,t)&&gh(r,i)||gh(e,i)&&gh(r,t))||mh(e,t,r)>0!=mh(e,t,i)>0&&mh(r,i,e)>0!=mh(r,i,t)>0}function vh(e,t){return mh(e.prev,e,e.next)<0?mh(e,t,e.next)>=0&&mh(e,e.prev,t)>=0:mh(e,t,e.prev)<0||mh(e,e.next,t)<0}function yh(e,t){var r=new wh(e.i,e.x,e.y),i=new wh(t.i,t.x,t.y),n=e.next,a=t.prev;return e.next=t,t.prev=e,r.next=n,n.prev=r,i.next=r,r.prev=i,a.next=i,i.prev=a,i}function xh(e,t,r,i){var n=new wh(e,t,r);return i?(n.next=i.next,n.prev=i,i.next.prev=n,i.next=n):(n.prev=n,n.next=n),n}function bh(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function wh(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function Th(e,t,r,i){for(var n=0,a=t,o=r-i;ah&&s.push({pivot:Math.floor((l+h)/2),left:h,right:l}),h=a[o].pivot+1,(l=a[o].right)>h&&s.push({pivot:Math.floor((l+h)/2),left:h,right:l})}a=this._parts=s}else for(o=0;o=2e4},doSortTriangles:function(e,t){var r=this.indices;if(0===t){var i=this.attributes.position;e=e.array,this._triangleZList&&this._triangleZList.length===this.triangleCount||(this._triangleZList=new Float32Array(this.triangleCount),this._sortedTriangleIndices=new Uint32Array(this.triangleCount),this._indicesTmp=new r.constructor(r.length),this._triangleZListTmp=new Float32Array(this.triangleCount));for(var n,a=0,o=0;o0,r={},n=0;n65535?new Uint32Array(3*o):new Uint16Array(3*o),d.material.shader!==t&&d.material.attachShader(t,!0),Ka.setMaterialFromModel(t.__shading,d.material,e,r),s>0&&(this._linesMesh.geometry.resetOffset(),this._linesMesh.geometry.setVertexCount(s),this._linesMesh.geometry.setTriangleCount(l)),this._dataIndexOfVertex=new Uint32Array(a),this._vertexRangeOfDataIndex=new Uint32Array(2*(n-i))},_updateRegionMesh:function(e,t,r,i){for(var n=e.getData(),a=0,o=0,s=!1,l=this._polygonMesh,h=this._linesMesh,u=r;u0;w&&(b*=t.getDevicePixelRatio(),this._updateLinesGeometry(h.geometry,e,u,v,b,e.coordinateSystem.transform)),h.invisible=!w,h.material.set({color:g})}(l=this._polygonMesh).material.transparent=s,l.material.depthMask=!s,l.geometry.updateBoundingBox(),l.frontFace=this.extrudeY?Ka.Mesh.CCW:Ka.Mesh.CW,l.material.get("normalMap")&&l.geometry.generateTangents(),l.seriesIndex=e.seriesIndex,l.on("mousemove",this._onmousemove,this),l.on("mouseout",this._onmouseout,this)},_updateDebugWireframe:function(e){var t=e.getModel("debug.wireframe");if(t.get("show")){var r=Ka.parseColor(t.get("lineStyle.color")||"rgba(0,0,0,0.5)"),i=Mn(t.get("lineStyle.width"),1),n=this._polygonMesh;n.geometry.generateBarycentric(),n.material.define("both","WIREFRAME_TRIANGLE"),n.material.set("wireframeLineColor",r),n.material.set("wireframeLineWidth",i)}},_onmousemove:function(e){var t=this._dataIndexOfVertex[e.triangle[0]];null==t&&(t=-1),t!==this._lastHoverDataIndex&&(this.downplay(this._lastHoverDataIndex),this.highlight(t),this._labelsBuilder.updateLabels([t])),this._lastHoverDataIndex=t,this._polygonMesh.dataIndex=t},_onmouseout:function(e){e.target&&(this.downplay(this._lastHoverDataIndex),this._lastHoverDataIndex=-1,this._polygonMesh.dataIndex=-1),this._labelsBuilder.updateLabels([])},_updateGroundPlane:function(e,t,r){var i=e.getModel("groundPlane",e);if(this._groundMesh.invisible=!i.get("show",!0),!this._groundMesh.invisible){var n=e.get("shading"),a=this._groundMaterials[n];a||(a=this._groundMaterials.lambert),Ka.setMaterialFromModel(n,a,i,r),a.get("normalMap")&&this._groundMesh.geometry.generateTangents(),this._groundMesh.material=a,this._groundMesh.material.set("color",Ka.parseColor(i.get("color"))),this._groundMesh.scale.set(t.size[0],t.size[2],1)}},_triangulation:function(e,t,r){this._triangulationResults=[];for(var i=[1/0,1/0,1/0],n=[-1/0,-1/0,-1/0],a=e.coordinateSystem,o=t;o1?i:0,L[U][g]=A.points[V+2],l.set(n+U,L[U]),s?(I[0]=(A.points[V]*_[0]-v[0])/x,I[1]=(A.points[V+2]*_[g]-v[g])/x):(I[0]=(k?R:R+G)/x,I[1]=(L[U][m]*_[m]-v[m])/x),u.set(n+U,I)}for(zh.sub(P,L[1],L[0]),zh.sub(O,L[3],L[0]),zh.cross(N,P,O),zh.normalize(N,N),U=0;U<4;U++)h.set(n+U,N),f&&c.set(n+U,o);for(U=0;U<6;U++)p[3*a+U]=D[U]+n;n+=4,a+=2,R+=G}}return t.dirty(),{vertexOffset:n,triangleOffset:a}},_getRegionLinesInfo:function(e,t,r){var i=0,n=0;return t.getRegionModel(e).getModel("itemStyle").get("borderWidth")>0&&t.getRegionPolygonCoords(e).forEach((function(e){var t=e.exterior,a=e.interiors;i+=r.getPolylineVertexCount(t),n+=r.getPolylineTriangleCount(t);for(var o=0;othis._endIndex)){t-=this._startIndex;for(var i=this._vertexRangeOfDataIndex[2*t];i0},_displacementChanged:!0,_displacementScale:0,updateDisplacementHash:function(){var e=this.getDisplacementTexture(),t=this.getDisplacemenScale();this._displacementChanged=this._displacementTexture!==e||this._displacementScale!==t,this._displacementTexture=e,this._displacementScale=t},isDisplacementChanged:function(){return this._displacementChanged}});i.util.merge(ru.prototype,uo),i.util.merge(ru.prototype,co),i.util.merge(ru.prototype,fo),i.util.merge(ru.prototype,Kl);const iu=ru;var nu=Math.PI,au=Math.sin,ou=Math.cos,su=Math.tan,lu=Math.asin,hu=Math.atan2,uu=nu/180,cu=23.4397*uu;function du(e,t){return hu(au(e)*ou(cu)-su(t)*au(cu),ou(e))}function fu(e,t,r){return hu(au(e),ou(e)*au(t)-su(r)*ou(t))}function pu(e,t,r){return lu(au(t)*au(r)+ou(t)*ou(r)*ou(e))}var mu={};mu.getPosition=function(e,t,r){var i=uu*-r,n=uu*t,a=function(e){return function(e){return e.valueOf()/864e5-.5+2440588}(e)-2451545}(e),o=function(e){var t,r,i=(r=function(e){return uu*(357.5291+.98560028*e)}(e))+uu*(1.9148*au(r)+.02*au(2*r)+3e-4*au(3*r))+102.9372*uu+nu;return{dec:(t=i,lu(au(0)*ou(cu)+ou(0)*au(cu)*au(t))),ra:du(i,0)}}(a),s=function(e,t){return uu*(280.16+360.9856235*e)-t}(a,i)-o.ra;return{azimuth:fu(s,n,o.dec),altitude:pu(s,n,o.dec)}};const gu=mu;Ka.Shader.import(Va),Ka.Shader.import("@export ecgl.atmosphere.vertex\nattribute vec3 position: POSITION;\nattribute vec3 normal : NORMAL;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform mat4 normalMatrix : WORLDINVERSETRANSPOSE;\n\nvarying vec3 v_Normal;\n\nvoid main() {\n v_Normal = normalize((normalMatrix * vec4(normal, 0.0)).xyz);\n gl_Position = worldViewProjection * vec4(position, 1.0);\n}\n@end\n\n\n@export ecgl.atmosphere.fragment\nuniform mat4 viewTranspose: VIEWTRANSPOSE;\nuniform float glowPower;\nuniform vec3 glowColor;\n\nvarying vec3 v_Normal;\n\nvoid main() {\n float intensity = pow(1.0 - dot(v_Normal, (viewTranspose * vec4(0.0, 0.0, 1.0, 0.0)).xyz), glowPower);\n gl_FragColor = vec4(glowColor, intensity * intensity);\n}\n@end");const _u=i.ComponentView.extend({type:"globe",__ecgl__:!0,_displacementScale:0,init:function(e,t){this.groupGL=new Ka.Node,this._sphereGeometry=new Ka.SphereGeometry({widthSegments:200,heightSegments:100,dynamic:!0}),this._overlayGeometry=new Ka.SphereGeometry({widthSegments:80,heightSegments:40}),this._planeGeometry=new Ka.PlaneGeometry,this._earthMesh=new Ka.Mesh({renderNormal:!0}),this._atmosphereMesh=new Ka.Mesh,this._atmosphereGeometry=new Ka.SphereGeometry({widthSegments:80,heightSegments:40}),this._atmosphereMaterial=new Ka.Material({shader:new Ka.Shader(Ka.Shader.source("ecgl.atmosphere.vertex"),Ka.Shader.source("ecgl.atmosphere.fragment")),transparent:!0}),this._atmosphereMesh.geometry=this._atmosphereGeometry,this._atmosphereMesh.material=this._atmosphereMaterial,this._atmosphereMesh.frontFace=Ka.Mesh.CW,this._lightRoot=new Ka.Node,this._sceneHelper=new Uo,this._sceneHelper.initLight(this._lightRoot),this.groupGL.add(this._atmosphereMesh),this.groupGL.add(this._earthMesh),this._control=new Do({zr:t.getZr()}),this._control.init(),this._layerMeshes={}},render:function(e,t,r){var i=e.coordinateSystem,n=e.get("shading");i.viewGL.add(this._lightRoot),e.get("show")?i.viewGL.add(this.groupGL):i.viewGL.remove(this.groupGL),this._sceneHelper.setScene(i.viewGL.scene),i.viewGL.setPostEffect(e.getModel("postEffect"),r),i.viewGL.setTemporalSuperSampling(e.getModel("temporalSuperSampling"));var a=this._earthMesh;a.geometry=this._sphereGeometry;var o="ecgl."+n;a.material&&a.material.shader.name===o||(a.material=Ka.createMaterial(o)),Ka.setMaterialFromModel(n,a.material,e,r),["roughnessMap","metalnessMap","detailMap","normalMap"].forEach((function(e){var t=a.material.get(e);t&&(t.flipY=!1)})),a.material.set("color",Ka.parseColor(e.get("baseColor")));var s=.99*i.radius;if(a.scale.set(s,s,s),e.get("atmosphere.show")){a.material.define("both","ATMOSPHERE_ENABLED"),this._atmosphereMesh.invisible=!1,this._atmosphereMaterial.setUniforms({glowPower:e.get("atmosphere.glowPower")||6,glowColor:e.get("atmosphere.color")||"#ffffff"}),a.material.setUniforms({glowPower:e.get("atmosphere.innerGlowPower")||2,glowColor:e.get("atmosphere.color")||"#ffffff"});var l=e.get("atmosphere.offset")||5;this._atmosphereMesh.scale.set(s+l,s+l,s+l)}else a.material.undefine("both","ATMOSPHERE_ENABLED"),this._atmosphereMesh.invisible=!0;var h=a.material.setTextureImage("diffuseMap",e.get("baseTexture"),r,{flipY:!1,anisotropic:8});h&&h.surface&&h.surface.attachToMesh(a);var u=a.material.setTextureImage("bumpMap",e.get("heightTexture"),r,{flipY:!1,anisotropic:8});u&&u.surface&&u.surface.attachToMesh(a),a.material[e.get("postEffect.enable")?"define":"undefine"]("fragment","SRGB_DECODE"),this._updateLight(e,r),this._displaceVertices(e,r),this._updateViewControl(e,r),this._updateLayers(e,r)},afterRender:function(e,t,r,i){var n=i.renderer;this._sceneHelper.updateAmbientCubemap(n,e,r),this._sceneHelper.updateSkybox(n,e,r)},_updateLayers:function(e,t){var r=e.coordinateSystem,n=e.get("layers"),a=r.radius,o=[],s=[],l=[],h=[];i.util.each(n,(function(e){var n=new i.Model(e),u=n.get("type"),c=Ka.loadTexture(n.get("texture"),t,{flipY:!1,anisotropic:8});if(c.surface&&c.surface.attachToMesh(this._earthMesh),"blend"===u){var d=n.get("blendTo"),f=Mn(n.get("intensity"),1);"emission"===d?(l.push(c),h.push(f)):(o.push(c),s.push(f))}else{var p=n.get("id"),m=this._layerMeshes[p];m||(m=this._layerMeshes[p]=new Ka.Mesh({geometry:this._overlayGeometry,castShadow:!1,ignorePicking:!0})),"lambert"===n.get("shading")?(m.material=m.__lambertMaterial||new Ka.Material({autoUpdateTextureStatus:!1,shader:Ka.createShader("ecgl.lambert"),transparent:!0,depthMask:!1}),m.__lambertMaterial=m.material):(m.material=m.__colorMaterial||new Ka.Material({autoUpdateTextureStatus:!1,shader:Ka.createShader("ecgl.color"),transparent:!0,depthMask:!1}),m.__colorMaterial=m.material),m.material.enableTexture("diffuseMap");var g=n.get("distance"),_=a+(null==g?r.radius/100:g);m.scale.set(_,_,_),a=_;var v=this._blankTexture||(this._blankTexture=Ka.createBlankTexture("rgba(255, 255, 255, 0)"));m.material.set("diffuseMap",v),Ka.loadTexture(n.get("texture"),t,{flipY:!1,anisotropic:8},(function(e){e.surface&&e.surface.attachToMesh(m),m.material.set("diffuseMap",e),t.getZr().refresh()})),n.get("show")?this.groupGL.add(m):this.groupGL.remove(m)}}),this);var u=this._earthMesh.material;u.define("fragment","LAYER_DIFFUSEMAP_COUNT",o.length),u.define("fragment","LAYER_EMISSIVEMAP_COUNT",l.length),u.set("layerDiffuseMap",o),u.set("layerDiffuseIntensity",s),u.set("layerEmissiveMap",l),u.set("layerEmissionIntensity",h);var c=e.getModel("debug.wireframe");if(c.get("show")){u.define("both","WIREFRAME_TRIANGLE");var d=Ka.parseColor(c.get("lineStyle.color")||"rgba(0,0,0,0.5)"),f=Mn(c.get("lineStyle.width"),1);u.set("wireframeLineWidth",f),u.set("wireframeLineColor",d)}else u.undefine("both","WIREFRAME_TRIANGLE")},_updateViewControl:function(e,t){var r=e.coordinateSystem,i=e.getModel("viewControl"),n=(r.viewGL.camera,this),a=this._control;a.setViewGL(r.viewGL);var o,s,l=i.get("targetCoord");null!=l&&(s=l[0]+90,o=l[1]),a.setFromViewControlModel(i,{baseDistance:r.radius,alpha:o,beta:s}),a.off("update"),a.on("update",(function(){t.dispatchAction({type:"globeChangeCamera",alpha:a.getAlpha(),beta:a.getBeta(),distance:a.getDistance()-r.radius,center:a.getCenter(),from:n.uid,globeId:e.id})}))},_displaceVertices:function(e,t){var r=e.get("displacementQuality"),i=e.get("debug.wireframe.show"),n=e.coordinateSystem;if(e.isDisplacementChanged()||r!==this._displacementQuality||i!==this._showDebugWireframe){this._displacementQuality=r,this._showDebugWireframe=i;var a=this._sphereGeometry,o={low:100,medium:200,high:400,ultra:800}[r]||200,s=o/2;(a.widthSegments!==o||i)&&(a.widthSegments=o,a.heightSegments=s,a.build()),this._doDisplaceVertices(a,n),i&&a.generateBarycentric()}},_doDisplaceVertices:function(e,t){var r=e.attributes.position.value,i=e.attributes.texcoord0.value,n=e.__originalPosition;n&&n.length===r.length||((n=new Float32Array(r.length)).set(r),e.__originalPosition=n);for(var a=t.displacementWidth,o=t.displacementHeight,s=t.displacementData,l=0;l50&&(a=1e3);var o=[];Ou.perspective(o,Iu,this.width/this.height,1,a),this.viewGL.camera.projectionMatrix.setArray(o),this.viewGL.camera.decomposeProjectionMatrix(),o=Ou.identity([]);var s=this.dataToPoint(this.center);Ou.scale(o,o,[1,-1,1]),Ou.translate(o,o,[0,0,-e]),Ou.rotateX(o,o,t),Ou.rotateZ(o,o,-this.bearing/180*Math.PI),Ou.translate(o,o,[-s[0]*this.getScale()*Bu,-s[1]*this.getScale()*Bu,0]),this.viewGL.camera.viewMatrix.array=o;var l=[];Ou.invert(l,o),this.viewGL.camera.worldTransform.array=l,this.viewGL.camera.decomposeWorldTransform();var h,u=Nu*this.getScale();if(this.altitudeExtent&&!isNaN(this.boxHeight)){var c=this.altitudeExtent[1]-this.altitudeExtent[0];h=this.boxHeight/c*this.getScale()/Math.pow(2,this._initialZoom-this.zoomOffset)}else h=u/(2*Math.PI*6378e3*Math.abs(Math.cos(this.center[1]*(Math.PI/180))))*this.altitudeScale*Bu;this.viewGL.rootNode.scale.set(this.getScale()*Bu,this.getScale()*Bu,h)}},getScale:function(){return Math.pow(2,this.zoom-this.zoomOffset)},projectOnTile:function(e,t){return this.projectOnTileWithScale(e,this.getScale()*Nu,t)},projectOnTileWithScale:function(e,t,r){var i=e[0],n=e[1]*Ru/180,a=t*(i*Ru/180+Ru)/(2*Ru),o=t*(Ru-Math.log(Math.tan(Ru/4+.5*n)))/(2*Ru);return(r=r||[])[0]=a,r[1]=o,r},unprojectFromTile:function(e,t){return this.unprojectOnTileWithScale(e,this.getScale()*Nu,t)},unprojectOnTileWithScale:function(e,t,r){var i=e[0],n=e[1],a=i/t*(2*Ru)-Ru,o=2*(Math.atan(Math.exp(Ru-n/t*(2*Ru)))-Ru/4);return(r=r||[])[0]=180*a/Ru,r[1]=180*o/Ru,r},dataToPoint:function(e,t){return(t=this.projectOnTileWithScale(e,Nu,t))[0]-=this._origin[0],t[1]-=this._origin[1],t[2]=isNaN(e[2])?0:e[2],isNaN(e[2])||(t[2]=e[2],this.altitudeExtent&&(t[2]-=this.altitudeExtent[0])),t}};const zu=Fu;function Gu(){zu.apply(this,arguments)}function Uu(e,t,r){function i(e,t){var r=t.getWidth(),i=t.getHeight(),n=t.getDevicePixelRatio();this.viewGL.setViewport(0,0,r,i,n),this.width=r,this.height=i,this.altitudeScale=e.get("altitudeScale"),this.boxHeight=e.get("boxHeight")}function n(e,t){if("auto"!==this.model.get("boxHeight")){var r=[1/0,-1/0];e.eachSeries((function(e){if(e.coordinateSystem===this){var t=e.getData(),i=e.coordDimToDataDim("alt")[0];if(i){var n=t.getDataExtent(i,!0);r[0]=Math.min(r[0],n[0]),r[1]=Math.max(r[1],n[1])}}}),this),r&&isFinite(r[1]-r[0])&&(this.altitudeExtent=r)}}return{dimensions:t.prototype.dimensions,create:function(a,o){var s=[];return a.eachComponent(e,(function(e){var r=e.__viewGL;r||(r=e.__viewGL=new Il).setRootNode(new Ka.Node);var a=new t;a.viewGL=e.__viewGL,a.resize=i,a.resize(e,o),s.push(a),e.coordinateSystem=a,a.model=e,a.update=n})),a.eachSeries((function(t){if(t.get("coordinateSystem")===e){var r=t.getReferringComponents(e).models[0];if(r||(r=a.getComponent(e)),!r)throw new Error(e+' "'+Mn(t.get(e+"Index"),t.get(e+"Id"),0)+'" not found');t.coordinateSystem=r.coordinateSystem}})),r&&r(s,a,o),s}}}Gu.prototype=new zu,Gu.prototype.constructor=Gu,Gu.prototype.type="mapbox3D";const ku=Uu("mapbox3D",Gu,(function(e){e.forEach((function(e){e.setCameraOption(e.model.getMapboxCameraOption())}))}));(0,i.use)((function(e){e.registerComponentModel(Au),e.registerComponentView(Pu),e.registerCoordinateSystem("mapbox3D",ku),e.registerAction({type:"mapbox3DChangeCamera",event:"mapbox3dcamerachanged",update:"mapbox3D:updateCamera"},(function(e,t){t.eachComponent({mainType:"mapbox3D",query:e},(function(t){t.setMapboxCameraOption(e)}))}))}));var Vu=["zoom","center","pitch","bearing"],Hu=i.ComponentModel.extend({type:"maptalks3D",layoutMode:"box",coordinateSystem:null,defaultOption:{zlevel:-10,urlTemplate:"http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",attribution:'© OpenStreetMap contributors, © CARTO',center:[0,0],zoom:0,pitch:0,bearing:0,light:{main:{alpha:20,beta:30}},altitudeScale:1,boxHeight:"auto"},getMaptalksCameraOption:function(){var e=this;return Vu.reduce((function(t,r){return t[r]=e.get(r),t}),{})},setMaptalksCameraOption:function(e){null!=e&&Vu.forEach((function(t){null!=e[t]&&(this.option[t]=e[t])}),this)},getMaptalks:function(){return this._maptalks},setMaptalks:function(e){this._maptalks=e}});i.util.merge(Hu.prototype,co),i.util.merge(Hu.prototype,fo);const Wu=Hu;function ju(e,t,r,i){if(this.id=e,this.zr=t,this.dom=document.createElement("div"),this.dom.style.cssText="position:absolute;left:0;right:0;top:0;bottom:0;",!maptalks)throw new Error("Maptalks library must be included. See https://maptalks.org");this._maptalks=new maptalks.Map(this.dom,{center:r,zoom:i,doubleClickZoom:!1,fog:!1}),this._initEvents()}ju.prototype.setUnpainted=function(){},ju.prototype.resize=function(){this._maptalks.checkSize()},ju.prototype.getMaptalks=function(){return this._maptalks},ju.prototype.clear=function(){},ju.prototype.refresh=function(){this._maptalks.checkSize()};var Xu=["mousedown","mouseup","click","dblclick","mousemove","mousewheel","DOMMouseScroll","touchstart","touchend","touchmove","touchcancel"];ju.prototype._initEvents=function(){var e=this.dom;this._handlers=this._handlers||{contextmenu:function(e){return e.preventDefault(),!1}},Xu.forEach((function(t){this._handlers[t]=function(r){var i={};for(var n in r)i[n]=r[n];i.bubbles=!1;var a=new r.constructor(r.type,i);"mousewheel"===t||"DOMMouseScroll"===t?e.dispatchEvent(a):e.firstElementChild.dispatchEvent(a)},this.zr.dom.addEventListener(t,this._handlers[t])}),this),this.zr.dom.addEventListener("contextmenu",this._handlers.contextmenu)},ju.prototype.dispose=function(){Xu.forEach((function(e){this.zr.dom.removeEventListener(e,this._handlers[e])}),this),this._maptalks.remove()};const qu=ju;Ka.Shader.import(Lu);const Zu=i.ComponentView.extend({type:"maptalks3D",__ecgl__:!0,init:function(e,t){this._groundMesh=new Ka.Mesh({geometry:new Ka.PlaneGeometry,material:new Ka.Material({shader:new Ka.Shader({vertex:Ka.Shader.source("ecgl.displayShadow.vertex"),fragment:Ka.Shader.source("ecgl.displayShadow.fragment")}),depthMask:!1}),renderOrder:-100,culling:!1,castShadow:!1,$ignorePicking:!0,renderNormal:!0})},_initMaptalksLayer:function(e,t){var r=t.getZr();this._zrLayer=new qu("maptalks3D",r,e.get("center"),e.get("zoom")),r.painter.insertLayer(-1e3,this._zrLayer),this._lightRoot=new Ka.Node,this._sceneHelper=new Uo(this._lightRoot),this._sceneHelper.initLight(this._lightRoot);var i=this._zrLayer.getMaptalks(),n=this._dispatchInteractAction.bind(this,t,i);["zoomend","zooming","zoomstart","dragrotating","pitch","pitchend","movestart","moving","moveend","resize","touchstart","touchmove","touchend","animating"].forEach((function(e){i.on(e,n)}))},render:function(e,t,r){this._zrLayer||this._initMaptalksLayer(e,r);var i=this._zrLayer.getMaptalks(),n=e.get("urlTemplate"),a=i.getBaseLayer();n!==this._oldUrlTemplate&&(a?a.setOptions({urlTemplate:n,attribution:e.get("attribution")}):(a=new maptalks.TileLayer("maptalks-echarts-gl-baselayer",{urlTemplate:n,subdomains:["a","b","c"],attribution:e.get("attribution")}),i.setBaseLayer(a))),this._oldUrlTemplate=n,i.setCenter(e.get("center")),i.setZoom(e.get("zoom"),{animation:!1}),i.setPitch(e.get("pitch")),i.setBearing(e.get("bearing")),e.setMaptalks(i);var o=e.coordinateSystem;o.viewGL.scene.add(this._lightRoot),o.viewGL.add(this._groundMesh),this._updateGroundMesh(),this._sceneHelper.setScene(o.viewGL.scene),this._sceneHelper.updateLight(e),o.viewGL.setPostEffect(e.getModel("postEffect"),r),o.viewGL.setTemporalSuperSampling(e.getModel("temporalSuperSampling")),this._maptalks3DModel=e},afterRender:function(e,t,r,i){var n=i.renderer;this._sceneHelper.updateAmbientCubemap(n,e,r),this._sceneHelper.updateSkybox(n,e,r),e.coordinateSystem.viewGL.scene.traverse((function(e){e.material&&(e.material.define("fragment","NORMAL_UP_AXIS",2),e.material.define("fragment","NORMAL_FRONT_AXIS",1))}))},updateCamera:function(e,t,r,i){e.coordinateSystem.setCameraOption(i),this._updateGroundMesh(),r.getZr().refresh()},_dispatchInteractAction:function(e,t,r){var i;e.dispatchAction({type:"maptalks3DChangeCamera",pitch:t.getPitch(),zoom:(i=t.getResolution(),19-Math.log(i/Yu)/Math.LN2+1),center:t.getCenter().toArray(),bearing:t.getBearing(),maptalks3DId:this._maptalks3DModel&&this._maptalks3DModel.id})},_updateGroundMesh:function(){if(this._maptalks3DModel){var e=this._maptalks3DModel.coordinateSystem,t=e.dataToPoint(e.center);this._groundMesh.position.set(t[0],t[1],-.001);var r=new Ka.Plane(new Ka.Vector3(0,0,1),0),i=e.viewGL.camera.castRay(new Ka.Vector2(-1,-1)),n=e.viewGL.camera.castRay(new Ka.Vector2(1,1)),a=i.intersectPlane(r),o=n.intersectPlane(r),s=a.dist(o)/e.viewGL.rootNode.scale.x;this._groundMesh.scale.set(s,s,1)}},dispose:function(e,t){this._zrLayer&&this._zrLayer.dispose(),t.getZr().painter.delLayer(-1e3)}}),Yu=12756274*Math.PI/(256*Math.pow(2,20));function Ku(){zu.apply(this,arguments),this.maxPitch=85,this.zoomOffset=1}Ku.prototype=new zu,Ku.prototype.constructor=Ku,Ku.prototype.type="maptalks3D";const Qu=Uu("maptalks3D",Ku,(function(e){e.forEach((function(e){e.setCameraOption(e.model.getMaptalksCameraOption())}))}));(0,i.use)((function(e){e.registerComponentModel(Wu),e.registerComponentView(Zu),e.registerCoordinateSystem("maptalks3D",Qu),e.registerAction({type:"maptalks3DChangeCamera",event:"maptalks3dcamerachanged",update:"maptalks3D:updateCamera"},(function(e,t){t.eachComponent({mainType:"maptalks3D",query:e},(function(t){t.setMaptalksCameraOption(e)}))}))}));var Ju=Po.vec3,$u=i.helper.dataStack.isDimensionStacked;function ec(e,t,r){for(var i=e.getDataExtent(t),n=e.getDataExtent(r),a=i[1]-i[0]||i[0],o=n[1]-n[0]||n[0],s=new Uint8Array(2500),l=0;l0&&d>0||c<0&&d<0)),m=["x","y","z"].map((function(t){return e.coordDimToDataDim(t)[0]})),g=$u(r,m[2]),_=g?r.getCalculationInfo("stackResultDimension"):m[2];r.each(m,(function(e,i,a,o){var s=r.get(_,o),l=g?s-a:p?0:f[0],h=t.dataToPoint([e,i,l]),u=t.dataToPoint([e,i,s]),c=Ju.dist(h,u),d=[0,u[1]"+a.join("
")}(a):i.format.encodeHTML(i.format.addCommas(a)),s=n.getName(t),l=Ih(n,t);i.util.isObject(l)&&l.colorStops&&(l=(l.colorStops[0]||{}).color),l=l||"transparent";var h=i.format.getTooltipMarker(l),u=e.name;return"\0-"===u&&(u=""),u=u?i.format.encodeHTML(u)+(r?": ":"
"):"",r?h+u+o:u+h+(s?i.format.encodeHTML(s)+": "+o:o)}function sc(e,t,r){r=r||e.getSource();var n=t||i.getCoordinateSystemDimensions(e.get("coordinateSystem"))||["x","y","z"],a=i.helper.createDimensions(r,{dimensionsDefine:r.dimensionsDefine||e.get("dimensions"),encodeDefine:r.encodeDefine||e.get("encode"),coordDimensions:n.map((function(t){var r=e.getReferringComponents(t+"Axis3D").models[0];return{type:r&&"category"===r.get("type")?"ordinal":"float",name:t}}))});"cartesian3D"===e.get("coordinateSystem")&&a.forEach((function(t){if(n.indexOf(t.coordDim)>=0){var r=e.getReferringComponents(t.coordDim+"Axis3D").models[0];r&&"category"===r.get("type")&&(t.ordinalMeta=r.getOrdinalMeta())}}));var o=i.helper.dataStack.enableDataStack(e,a,{byIndex:!0,stackedCoordDimension:"z"}),s=new i.List(a,e);return s.setCalculationInfo(o),s.initData(r),s}var lc=i.SeriesModel.extend({type:"series.bar3D",dependencies:["globe"],visualStyleAccessPathvisu:"itemStyle",getInitialData:function(e,t){return sc(this)},getFormattedLabel:function(e,t,r,i){var n=ac.getFormattedLabel(this,e,t,r,i);return null==n&&(n=this.getData().get("z",e)),n},formatTooltip:function(e){return oc(this,e)},defaultOption:{coordinateSystem:"cartesian3D",globeIndex:0,grid3DIndex:0,zlevel:-10,bevelSize:0,bevelSmoothness:2,onGridPlane:"xy",shading:"color",minHeight:0,itemStyle:{opacity:1},label:{show:!1,distance:2,textStyle:{fontSize:14,color:"#000",backgroundColor:"rgba(255,255,255,0.7)",padding:3,borderRadius:3}},emphasis:{label:{show:!0}},animationDurationUpdate:500}});i.util.merge(lc.prototype,Kl);const hc=lc;var uc,cc,dc,fc,pc,mc,gc,_c,vc=Po.vec3,yc=Po.mat3,xc=Vr.extend((function(){return{attributes:{position:new Vr.Attribute("position","float",3,"POSITION"),normal:new Vr.Attribute("normal","float",3,"NORMAL"),color:new Vr.Attribute("color","float",4,"COLOR"),prevPosition:new Vr.Attribute("prevPosition","float",3),prevNormal:new Vr.Attribute("prevNormal","float",3)},dynamic:!0,enableNormal:!1,bevelSize:1,bevelSegments:0,_dataIndices:null,_vertexOffset:0,_triangleOffset:0}}),{resetOffset:function(){this._vertexOffset=0,this._triangleOffset=0},setBarCount:function(e){var t=this.enableNormal,r=this.getBarVertexCount()*e,i=this.getBarTriangleCount()*e;this.vertexCount!==r&&(this.attributes.position.init(r),t?this.attributes.normal.init(r):this.attributes.normal.value=null,this.attributes.color.init(r)),this.triangleCount!==i&&(this.indices=r>65535?new Uint32Array(3*i):new Uint16Array(3*i),this._dataIndices=new Uint32Array(r))},getBarVertexCount:function(){var e=this.bevelSize>0?this.bevelSegments:0;return e>0?this._getBevelBarVertexCount(e):this.enableNormal?24:8},getBarTriangleCount:function(){var e=this.bevelSize>0?this.bevelSegments:0;return e>0?this._getBevelBarTriangleCount(e):12},_getBevelBarVertexCount:function(e){return 4*(e+1)*(e+1)*2},_getBevelBarTriangleCount:function(e){return(4*e+3+1)*(2*e+1)*2+4},setColor:function(e,t){for(var r=this.getBarVertexCount(),i=r*(e+1),n=r*e;n0&&this.bevelSegments>0)this._addBevelBar(e,c,m,g,this.bevelSize,this.bevelSegments,_);else{vc.copy(n,c),vc.normalize(n,n),vc.cross(a,m,n),vc.normalize(a,a),vc.cross(i,n,a),vc.normalize(a,a),vc.negate(o,i),vc.negate(s,n),vc.negate(l,a),t(h[0],e,i,g[0]/2),t(h[0],h[0],a,g[2]/2),t(h[1],e,i,g[0]/2),t(h[1],h[1],l,g[2]/2),t(h[2],e,o,g[0]/2),t(h[2],h[2],l,g[2]/2),t(h[3],e,o,g[0]/2),t(h[3],h[3],a,g[2]/2),t(r,e,n,g[1]),t(h[4],r,i,g[0]/2),t(h[4],h[4],a,g[2]/2),t(h[5],r,i,g[0]/2),t(h[5],h[5],l,g[2]/2),t(h[6],r,o,g[0]/2),t(h[6],h[6],l,g[2]/2),t(h[7],r,o,g[0]/2),t(h[7],h[7],a,g[2]/2);var x=this.attributes;if(this.enableNormal){u[0]=i,u[1]=o,u[2]=n,u[3]=s,u[4]=a,u[5]=l;for(var b=this._vertexOffset,w=0;w0&&(f++,u[3]<.99&&(p=!0))}})),o.geometry.setBarCount(f);var m=r.getLayout("orient"),g=this._barIndexOfData=new Int32Array(r.count());f=0,r.each((function(e){if(r.hasValue(e)){var t=r.getItemLayout(e),i=t[0],n=t[1],o=t[2],s=4*e;u[0]=c[s++],u[1]=c[s++],u[2]=c[s++],u[3]=c[s++],u[3]>0&&(a._barMesh.geometry.addBar(i,n,m,o,u,e),g[e]=f++)}else g[e]=-1})),o.geometry.dirty(),o.geometry.updateBoundingBox();var _=o.material;_.transparent=p,_.depthMask=!p,o.geometry.sortTriangles=p,this._initHandler(e,t)},_initHandler:function(e,t){var r=e.getData(),i=this._barMesh,n="cartesian3D"===e.coordinateSystem.type;i.seriesIndex=e.seriesIndex;var a=-1;i.off("mousemove"),i.off("mouseout"),i.on("mousemove",(function(e){var o=i.geometry.getDataIndexOfVertex(e.triangle[0]);o!==a&&(this._downplay(a),this._highlight(o),this._labelsBuilder.updateLabels([o]),n&&t.dispatchAction({type:"grid3DShowAxisPointer",value:[r.get("x",o),r.get("y",o),r.get("z",o,!0)]})),a=o,i.dataIndex=o}),this),i.on("mouseout",(function(e){this._downplay(a),this._labelsBuilder.updateLabels(),a=-1,i.dataIndex=-1,n&&t.dispatchAction({type:"grid3DHideAxisPointer"})}),this)},_highlight:function(e){var t=this._data;if(t){var r=this._barIndexOfData[e];if(!(r<0)){var n=t.getItemModel(e).getModel("emphasis.itemStyle"),a=n.get("color"),o=n.get("opacity");if(null==a){var s=Ih(t,e);a=i.color.lift(s,-.4)}null==o&&(o=Rh(t,e));var l=Ka.parseColor(a);l[3]*=o,this._barMesh.geometry.setColor(r,l),this._api.getZr().refresh()}}},_downplay:function(e){var t=this._data;if(t){var r=this._barIndexOfData[e];if(!(r<0)){var i=Ih(t,e),n=Rh(t,e),a=Ka.parseColor(i);a[3]*=n,this._barMesh.geometry.setColor(r,a),this._api.getZr().refresh()}}},highlight:function(e,t,r,i){this._toggleStatus("highlight",e,t,r,i)},downplay:function(e,t,r,i){this._toggleStatus("downplay",e,t,r,i)},_toggleStatus:function(e,t,r,n,a){var o=t.getData(),s=An(o,a),l=this;null!=s?i.util.each(ac.normalizeToArray(s),(function(t){"highlight"===e?this._highlight(t):this._downplay(t)}),this):o.each((function(t){"highlight"===e?l._highlight(t):l._downplay(t)}))},remove:function(){this.groupGL.removeAll()},dispose:function(){this._labelsBuilder.dispose(),this.groupGL.removeAll()}});(0,i.use)((function(e){e.registerChartView(Tc),e.registerSeriesModel(hc),nc(e),e.registerProcessor((function(e,t){e.eachSeriesByType("bar3d",(function(e){var t=e.getData();t.filterSelf((function(e){return t.hasValue(e)}))}))}))}));const Sc=i.SeriesModel.extend({type:"series.line3D",dependencies:["grid3D"],visualStyleAccessPath:"lineStyle",visualDrawType:"stroke",getInitialData:function(e,t){return sc(this)},formatTooltip:function(e){return oc(this,e)},defaultOption:{coordinateSystem:"cartesian3D",zlevel:-10,grid3DIndex:0,lineStyle:{width:2},animationDurationUpdate:500}});function Mc(e,t,r,i,n,a,o){if(0===n)return!1;var s,l=n;if(o>t+l&&o>i+l||oe+l&&a>r+l||a=0){var g=3*l,_=new vt(this._points[g],this._points[g+1],this._points[g+2]);a.push({dataIndex:l,point:_,pointWorld:_.clone(),target:this._line3DMesh,distance:this._camera.getWorldPosition().dist(_)})}},remove:function(){this.groupGL.removeAll()},dispose:function(){this.groupGL.removeAll()}});(0,i.use)((function(e){e.registerChartView(Ec),e.registerSeriesModel(Sc),e.registerLayout((function(e,t){e.eachSeriesByType("line3D",(function(e){var t=e.getData(),r=e.coordinateSystem;if(r){if("cartesian3D"!==r.type)return;var i=new Float32Array(3*t.count()),n=[],a=[],o=r.dimensions.map((function(t){return e.coordDimToDataDim(t)[0]}));r&&t.each(o,(function(e,t,o,s){n[0]=e,n[1]=t,n[2]=o,r.dataToPoint(n,a),i[3*s]=a[0],i[3*s+1]=a[1],i[3*s+2]=a[2]})),t.setLayout("points",i)}}))}))}));const Cc=i.SeriesModel.extend({type:"series.scatter3D",dependencies:["globe","grid3D","geo3D"],visualStyleAccessPath:"itemStyle",hasSymbolVisual:!0,getInitialData:function(e,t){return sc(this)},getFormattedLabel:function(e,t,r,i){var n=ac.getFormattedLabel(this,e,t,r,i);if(null==n){var a=this.getData(),o=a.dimensions[a.dimensions.length-1];n=a.get(o,e)}return n},formatTooltip:function(e){return oc(this,e)},defaultOption:{coordinateSystem:"cartesian3D",zlevel:-10,progressive:1e5,progressiveThreshold:1e5,grid3DIndex:0,globeIndex:0,symbol:"circle",symbolSize:10,blendMode:"source-over",label:{show:!1,position:"right",distance:5,textStyle:{fontSize:14,color:"#000",backgroundColor:"rgba(255,255,255,0.7)",padding:3,borderRadius:3}},itemStyle:{opacity:.8},emphasis:{label:{show:!0}},animationDurationUpdate:500}});function Dc(e,t,r){(t=t||document.createElement("canvas")).width=e,t.height=e;var i=t.getContext("2d");return r&&r(i),t}var Lc={getMarginByStyle:function(e){var t=e.minMargin||0,r=0;e.stroke&&"none"!==e.stroke&&(r=null==e.lineWidth?1:e.lineWidth);var i=e.shadowBlur||0,n=e.shadowOffsetX||0,a=e.shadowOffsetY||0,o={};return o.left=Math.max(r/2,-n+i,t),o.right=Math.max(r/2,n+i,t),o.top=Math.max(r/2,-a+i,t),o.bottom=Math.max(r/2,a+i,t),o},createSymbolSprite:function(e,t,r,n){var a=function(e,t,r,n){i.util.isArray(t)||(t=[t,t]);var a=Lc.getMarginByStyle(r,void 0),o=t[0]+a.left+a.right,s=t[1]+a.top+a.bottom,l=i.helper.createSymbol(e,0,0,t[0],t[1]),h=Math.max(o,s);l.x=a.left,l.y=a.top,o>s?l.y+=(h-s)/2:l.x+=(h-o)/2;var u=l.getBoundingRect();return l.x-=u.x,l.y-=u.y,l.setStyle(r),l.update(),l.__size=h,l}(e,t,r),o=Lc.getMarginByStyle(r);return{image:Dc(a.__size,n,(function(e){i.innerDrawElementOnCanvas(e,a)})),margin:o}},createSDFFromCanvas:function(e,t,r,i){return Dc(t,i,(function(t){var i=e.getContext("2d").getImageData(0,0,e.width,e.height);t.putImageData(function(e,t,r){var i=t.width,n=t.height,a=e.canvas.width,o=e.canvas.height,s=i/a,l=n/o;function h(e){return e<128?1:-1}function u(e,a){var o=1/0;e=Math.floor(e*s);for(var u=(a=Math.floor(a*l))*i+e,c=h(t.data[4*u]),d=Math.max(a-r,0);d=2e4},doSortVertices:function(e,t){var r=this.indices,i=Oc.create();if(!r){r=this.indices=this.vertexCount>65535?new Uint32Array(this.vertexCount):new Uint16Array(this.vertexCount);for(var n=0;n.05);else for(n=0;n<3;n++)this._progressiveQuickSort(3*t+n);this.dirtyIndices()},_simpleSort:function(e){var t=this._zList,r=this.indices;function i(e,r){return t[r]-t[e]}e?Array.prototype.sort.call(r,i):Ch.sort(r,i,0,r.length-1)},_progressiveQuickSort:function(e){var t=this._zList,r=this.indices;this._quickSort=this._quickSort||new Ch,this._quickSort.step(r,(function(e,r){return t[r]-t[e]}),e)}};var Ic=Po.vec4;Ka.Shader.import("@export ecgl.sdfSprite.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform float elapsedTime : 0;\n\nattribute vec3 position : POSITION;\n\n#ifdef VERTEX_SIZE\nattribute float size;\n#else\nuniform float u_Size;\n#endif\n\n#ifdef VERTEX_COLOR\nattribute vec4 a_FillColor: COLOR;\nvarying vec4 v_Color;\n#endif\n\n#ifdef VERTEX_ANIMATION\nattribute vec3 prevPosition;\nattribute float prevSize;\nuniform float percent : 1.0;\n#endif\n\n\n#ifdef POSITIONTEXTURE_ENABLED\nuniform sampler2D positionTexture;\n#endif\n\nvarying float v_Size;\n\nvoid main()\n{\n\n#ifdef POSITIONTEXTURE_ENABLED\n gl_Position = worldViewProjection * vec4(texture2D(positionTexture, position.xy).xy, -10.0, 1.0);\n#else\n\n #ifdef VERTEX_ANIMATION\n vec3 pos = mix(prevPosition, position, percent);\n #else\n vec3 pos = position;\n #endif\n gl_Position = worldViewProjection * vec4(pos, 1.0);\n#endif\n\n#ifdef VERTEX_SIZE\n#ifdef VERTEX_ANIMATION\n v_Size = mix(prevSize, size, percent);\n#else\n v_Size = size;\n#endif\n#else\n v_Size = u_Size;\n#endif\n\n#ifdef VERTEX_COLOR\n v_Color = a_FillColor;\n #endif\n\n gl_PointSize = v_Size;\n}\n\n@end\n\n@export ecgl.sdfSprite.fragment\n\nuniform vec4 color: [1, 1, 1, 1];\nuniform vec4 strokeColor: [1, 1, 1, 1];\nuniform float smoothing: 0.07;\n\nuniform float lineWidth: 0.0;\n\n#ifdef VERTEX_COLOR\nvarying vec4 v_Color;\n#endif\n\nvarying float v_Size;\n\nuniform sampler2D sprite;\n\n@import clay.util.srgb\n\nvoid main()\n{\n gl_FragColor = color;\n\n vec4 _strokeColor = strokeColor;\n\n#ifdef VERTEX_COLOR\n gl_FragColor *= v_Color;\n #endif\n\n#ifdef SPRITE_ENABLED\n float d = texture2D(sprite, gl_PointCoord).r;\n gl_FragColor.a *= smoothstep(0.5 - smoothing, 0.5 + smoothing, d);\n\n if (lineWidth > 0.0) {\n float sLineWidth = lineWidth / 2.0;\n\n float outlineMaxValue0 = 0.5 + sLineWidth;\n float outlineMaxValue1 = 0.5 + sLineWidth + smoothing;\n float outlineMinValue0 = 0.5 - sLineWidth - smoothing;\n float outlineMinValue1 = 0.5 - sLineWidth;\n\n if (d <= outlineMaxValue1 && d >= outlineMinValue0) {\n float a = _strokeColor.a;\n if (d <= outlineMinValue1) {\n a = a * smoothstep(outlineMinValue0, outlineMinValue1, d);\n }\n else {\n a = a * smoothstep(outlineMaxValue1, outlineMaxValue0, d);\n }\n gl_FragColor.rgb = mix(gl_FragColor.rgb * gl_FragColor.a, _strokeColor.rgb, a);\n gl_FragColor.a = gl_FragColor.a * (1.0 - a) + a;\n }\n }\n#endif\n\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(gl_FragColor);\n#endif\n}\n@end");const Rc=Ka.Mesh.extend((function(){var e=new Ka.Geometry({dynamic:!0,attributes:{color:new Ka.Geometry.Attribute("color","float",4,"COLOR"),position:new Ka.Geometry.Attribute("position","float",3,"POSITION"),size:new Ka.Geometry.Attribute("size","float",1),prevPosition:new Ka.Geometry.Attribute("prevPosition","float",3),prevSize:new Ka.Geometry.Attribute("prevSize","float",1)}});Object.assign(e,Nc);var t=new Ka.Material({shader:Ka.createShader("ecgl.sdfSprite"),transparent:!0,depthMask:!1});t.enableTexture("sprite"),t.define("both","VERTEX_COLOR"),t.define("both","VERTEX_SIZE");var r=new Ka.Texture2D({image:document.createElement("canvas"),flipY:!1});return t.set("sprite",r),e.pick=this._pick.bind(this),{geometry:e,material:t,mode:Ka.Mesh.POINTS,sizeScale:1}}),{_pick:function(e,t,r,i,n,a){var o=this._positionNDC;if(o)for(var s=r.viewport,l=2/s.width,h=2/s.height,u=this.geometry.vertexCount-1;u>=0;u--){var c,d=o[2*(c=this.geometry.indices?this.geometry.indices[u]:u)],f=o[2*c+1],p=this.geometry.attributes.size.get(c)/this.sizeScale/2;if(e>d-p*l&&ef-p*h&&t2?(p=this._updateSymbolSprite(e,d,u,c),s.enableTexture("sprite")):s.disableTexture("sprite"),h.position.init(n-i);var m=[];if(f){s.undefine("VERTEX_SIZE"),s.undefine("VERTEX_COLOR");var g=function(e){const t=e.getVisual("style");if(t)return t[e.getVisual("drawType")]}(o),_=function(e){return e.getVisual("style").opacity}(o);Ka.parseColor(g,m),m[3]*=_,s.set({color:m,u_Size:u.maxSize*this._sizeScale})}else s.set({color:[1,1,1,1]}),s.define("VERTEX_SIZE"),s.define("VERTEX_COLOR"),h.size.init(n-i),h.color.init(n-i),this._originalOpacity=new Float32Array(n-i);for(var v=o.getLayout("points"),y=h.position.value,x=0;x1?(o[0]=r.maxSize,o[1]=r.maxSize/r.aspect):(o[1]=r.maxSize,o[0]=r.maxSize*r.aspect),o[0]=o[0]||1,o[1]=o[1]||1,this._symbolType===r.type&&(a=o,(n=this._symbolSize)&&a&&n[0]===a[0]&&n[1]===a[1])&&this._lineWidth===t.lineWidth||(Pc.createSymbolSprite(r.type,o,{fill:"#fff",lineWidth:t.lineWidth,stroke:"transparent",shadowColor:"transparent",minMargin:Math.min(o[0]/2,10)},this._spriteImageCanvas),Pc.createSDFFromCanvas(this._spriteImageCanvas,Math.min(this._spriteImageCanvas.width,32),20,this._mesh.material.get("sprite").image),this._symbolType=r.type,this._symbolSize=o,this._lineWidth=t.lineWidth),this._spriteImageCanvas.width/r.maxSize*i},_updateMaterial:function(e,t){var r="lighter"===e.get("blendMode")?Ka.additiveBlend:null,i=this._mesh.material;i.blend=r,i.set("lineWidth",t.lineWidth/20);var n=Ka.parseColor(t.stroke);i.set("strokeColor",n),i.transparent=!0,i.depthMask=!1,i.depthTest=!this.is2D,i.sortVertices=!this.is2D},_updateLabelBuilder:function(e,t,r){var i=e.getData(),n=this._mesh.geometry,a=n.attributes.position.value,o=(t=this._startDataIndex,this._mesh.sizeScale);this._labelsBuilder.updateData(i,t,r),this._labelsBuilder.getLabelPosition=function(e,r,i){var n=3*(e-t);return[a[n],a[n+1],a[n+2]]},this._labelsBuilder.getLabelDistance=function(e,r,i){return n.attributes.size.get(e-t)/o/2+i},this._labelsBuilder.updateLabels()},_updateAnimation:function(e){Ka.updateVertexAnimation([["prevPosition","position"],["prevSize","size"]],this._prevMesh,this._mesh,e)},_updateHandler:function(e,t,r){var i,n=e.getData(),a=this._mesh,o=this,s=-1,l=e.coordinateSystem&&"cartesian3D"===e.coordinateSystem.type;l&&(i=e.coordinateSystem.model),a.seriesIndex=e.seriesIndex,a.off("mousemove"),a.off("mouseout"),a.on("mousemove",(function(t){var h=t.vertexIndex+o._startDataIndex;h!==s&&(this.highlightOnMouseover&&(this.downplay(n,s),this.highlight(n,h),this._labelsBuilder.updateLabels([h])),l&&r.dispatchAction({type:"grid3DShowAxisPointer",value:[n.get(e.coordDimToDataDim("x")[0],h),n.get(e.coordDimToDataDim("y")[0],h),n.get(e.coordDimToDataDim("z")[0],h)],grid3DIndex:i.componentIndex})),a.dataIndex=h,s=h}),this),a.on("mouseout",(function(e){var t=e.vertexIndex+o._startDataIndex;this.highlightOnMouseover&&(this.downplay(n,t),this._labelsBuilder.updateLabels()),s=-1,a.dataIndex=-1,l&&r.dispatchAction({type:"grid3DHideAxisPointer",grid3DIndex:i.componentIndex})}),this)},updateLayout:function(e,t,r){var i=e.getData();if(this._mesh){var n=this._mesh.geometry.attributes.position.value,a=i.getLayout("points");if(this.is2D)for(var o=0;othis._endDataIndex||tthis._endDataIndex||t 1.0 || v_Percent < 0.0) {\n discard;\n }\n\n float fade = v_Percent;\n\n#ifdef SRGB_DECODE\n gl_FragColor = sRGBToLinear(color * v_Color);\n#else\n gl_FragColor = color * v_Color;\n#endif\n\n @import ecgl.common.wireframe.fragmentMain\n\n if (v_Percent > (1.0 - v_SpotPercent)) {\n gl_FragColor.rgb *= spotIntensity;\n }\n\n gl_FragColor.a *= fade;\n}\n\n@end");const ad=Ka.Mesh.extend((function(){var e=new Ka.Material({shader:new Ka.Shader(Ka.Shader.source("ecgl.trail2.vertex"),Ka.Shader.source("ecgl.trail2.fragment")),transparent:!0,depthMask:!1}),t=new Ro({dynamic:!0});return t.createAttribute("dist","float",1),t.createAttribute("distAll","float",1),t.createAttribute("start","float",1),{geometry:t,material:e,culling:!1,$ignorePicking:!0}}),{updateData:function(e,t,r){var i=e.hostModel,n=this.geometry,a=i.getModel("effect"),o=a.get("trailWidth")*t.getDevicePixelRatio(),s=a.get("trailLength"),l=i.get("effect.constantSpeed"),h=1e3*i.get("effect.period"),u=null!=l;u?this.material.set("speed",l/1e3):this.material.set("period",h),this.material[u?"define":"undefine"]("vertex","CONSTANT_SPEED");var c=i.get("polyline");n.trailLength=s,this.material.set("trailLength",s),n.resetOffset(),["position","positionPrev","positionNext"].forEach((function(e){n.attributes[e].value=r.attributes[e].value})),["dist","distAll","start","offset","color"].forEach((function(e){n.attributes[e].init(n.vertexCount)})),n.indices=r.indices;var d=[],f=a.get("trailColor"),p=a.get("trailOpacity"),m=null!=f,g=null!=p;this.updateWorldTransform();var _=this.worldTransform.x.len(),v=this.worldTransform.y.len(),y=this.worldTransform.z.len(),x=0,b=0;e.each((function(t){var i=e.getItemLayout(t),a=g?p:Rh(e,t),s=Ih(e,t);null==a&&(a=1),(d=Ka.parseColor(m?f:s,d))[3]*=a;for(var l=c?r.getPolylineVertexCount(i):r.getCubicCurveVertexCount(i[0],i[1],i[2],i[3]),w=0,T=[],S=[],M=x;Mx&&(w+=nd.dist(T,S)),n.attributes.dist.set(M,w),nd.copy(S,T);b=Math.max(b,w);var A=Math.random()*(u?w:h);for(M=x;M0?1:-1)*o/2),n.attributes.color.set(M,d);x+=l})),this.material.set("spotSize",.1*b*s),this.material.set("spotIntensity",a.get("spotIntensity")),n.dirty()},setAnimationTime:function(e){this.material.set("time",e)}});Ka.Shader.import(is);const od=i.ChartView.extend({type:"lines3D",__ecgl__:!0,init:function(e,t){this.groupGL=new Ka.Node,this._meshLinesMaterial=new Ka.Material({shader:Ka.createShader("ecgl.meshLines3D"),transparent:!0,depthMask:!1}),this._linesMesh=new Ka.Mesh({geometry:new Ro,material:this._meshLinesMaterial,$ignorePicking:!0}),this._trailMesh=new ad},render:function(e,t,r){this.groupGL.add(this._linesMesh);var i=e.coordinateSystem,n=e.getData();if(i&&i.viewGL){i.viewGL.add(this.groupGL),this._updateLines(e,t,r);var a=i.viewGL.isLinearSpace()?"define":"undefine";this._linesMesh.material[a]("fragment","SRGB_DECODE"),this._trailMesh.material[a]("fragment","SRGB_DECODE")}var o=this._trailMesh;if(o.stopAnimation(),e.get("effect.show")){this.groupGL.add(o),o.updateData(n,r,this._linesMesh.geometry),o.__time=o.__time||0;var s=36e5;this._curveEffectsAnimator=o.animate("",{loop:!0}).when(s,{__time:s}).during((function(){o.setAnimationTime(o.__time)})).start()}else this.groupGL.remove(o),this._curveEffectsAnimator=null;this._linesMesh.material.blend=this._trailMesh.material.blend="lighter"===e.get("blendMode")?Ka.additiveBlend:null},pauseEffect:function(){this._curveEffectsAnimator&&this._curveEffectsAnimator.pause()},resumeEffect:function(){this._curveEffectsAnimator&&this._curveEffectsAnimator.resume()},toggleEffect:function(){var e=this._curveEffectsAnimator;e&&(e.isPaused()?e.resume():e.pause())},_updateLines:function(e,t,r){var i=e.getData(),n=e.coordinateSystem,a=this._linesMesh.geometry,o=e.get("polyline");a.expandLine=!0;var s=function(e){return null!=e.radius?e.radius:null!=e.size?Math.max(e.size[0],e.size[1],e.size[2]):100}(n);a.segmentScale=s/20;var l="lineStyle.width".split("."),h=r.getDevicePixelRatio(),u=0;i.each((function(e){var t=i.getItemModel(e).get(l);null==t&&(t=1),i.setItemVisual(e,"lineWidth",t),u=Math.max(t,u)})),a.useNativeLine=!1;var c=0,d=0;i.each((function(e){var t=i.getItemLayout(e);o?(c+=a.getPolylineVertexCount(t),d+=a.getPolylineTriangleCount(t)):(c+=a.getCubicCurveVertexCount(t[0],t[1],t[2],t[3]),d+=a.getCubicCurveTriangleCount(t[0],t[1],t[2],t[3]))})),a.setVertexCount(c),a.setTriangleCount(d),a.resetOffset();var f=[];i.each((function(e){var t=i.getItemLayout(e),r=Ih(i,e),n=Rh(i,e),s=i.getItemVisual(e,"lineWidth")*h;null==n&&(n=1),(f=Ka.parseColor(r,f))[3]*=n,o?a.addPolyline(t,f,s):a.addCubicCurve(t[0],t[1],t[2],t[3],f,s)})),a.dirty()},remove:function(){this.groupGL.removeAll()},dispose:function(){this.groupGL.removeAll()}});function sd(e,t){for(var r=[],i=0;i0;this._updateSurfaceMesh(this._surfaceMesh,e,u,f);var p=this._surfaceMesh.material;f?(p.define("WIREFRAME_QUAD"),p.set("wireframeLineWidth",d),p.set("wireframeLineColor",Ka.parseColor(c.get("lineStyle.color")))):p.undefine("WIREFRAME_QUAD"),this._initHandler(e,r),this._updateAnimation(e)},_updateAnimation:function(e){Ka.updateVertexAnimation([["prevPosition","position"],["prevNormal","normal"]],this._prevSurfaceMesh,this._surfaceMesh,e)},_createSurfaceMesh:function(){var e=new Ka.Mesh({geometry:new Ka.Geometry({dynamic:!0,sortTriangles:!0}),shadowDepthMaterial:new Ka.Material({shader:new Ka.Shader(Ka.Shader.source("ecgl.sm.depth.vertex"),Ka.Shader.source("ecgl.sm.depth.fragment"))}),culling:!1,renderOrder:10,renderNormal:!0});return e.geometry.createAttribute("barycentric","float",4),e.geometry.createAttribute("prevPosition","float",3),e.geometry.createAttribute("prevNormal","float",3),Object.assign(e.geometry,Nh),e},_initHandler:function(e,t){var r=e.getData(),i=this._surfaceMesh,n=e.coordinateSystem;i.seriesIndex=e.seriesIndex;var a=-1;i.off("mousemove"),i.off("mouseout"),i.on("mousemove",(function(e){var o=function(e,t){for(var r=1/0,n=-1,a=[],o=0;o=0){var s=[];i.geometry.attributes.position.get(o,s);for(var l=n.pointToData(s),h=1/0,u=-1,c=[],d=0;d65535?Uint32Array:Uint16Array)((p-1)*(m-1)*6),w=function(e,t,r){r[1]=e*m+t,r[0]=e*m+t+1,r[3]=(e+1)*m+t+1,r[2]=(e+1)*m+t},T=!1;if(l){var S=[],M=[],A=0;g?u.init(n.vertexCount):u.value=null;for(var E=[[],[],[]],C=[],D=[],L=fd.create(),P=function(e,t,r){var i=3*t;return r[0]=e[i],r[1]=e[i+1],r[2]=e[i+2],r},O=new Float32Array(o.length),N=new Float32Array(o.length/3*4),I=0;I0;){if(Math.floor(s/u)===s/u)return[u,s/u];u--}return[u=Math.floor(Math.sqrt(s)),u]},dispose:function(){this.groupGL.removeAll()},remove:function(){this.groupGL.removeAll()}});function md(e,t){for(var r=[],i=0;i=0&&e.call(t,r[n],n)},e.prototype.eachEdge=function(e,t){for(var r=this.edges,i=r.length,n=0;n=0&&r[n].node1.dataIndex>=0&&r[n].node2.dataIndex>=0&&e.call(t,r[n],n)},e.prototype.breadthFirstTraverse=function(e,t,r,i){if(t instanceof Ad||(t=this._nodesMap[Sd(t)]),t){for(var n="out"===r?"outEdges":"in"===r?"inEdges":"edges",a=0;a=0&&r.node2.dataIndex>=0})),n=0,a=i.length;n=0&&this[e][t].setItemVisual(this.dataIndex,r,i)},getVisual:function(r){return this[e][t].getItemVisual(this.dataIndex,r)},setLayout:function(r,i){this.dataIndex>=0&&this[e][t].setItemLayout(this.dataIndex,r,i)},getLayout:function(){return this[e][t].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[e][t].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[e][t].getRawIndex(this.dataIndex)}}}_a(Ad,Cd("hostGraph","data")),_a(Ed,Cd("hostGraph","edgeData"));const Dd=Md;var Ld=_o();function Pd(e,t){if(Ld(this).mainData===this){var r=ga({},Ld(this).datas);r[this.dataType]=t,Bd(t,r,e)}else Fd(t,this.dataType,Ld(this).mainData,e);return t}function Od(e,t){return e.struct&&e.struct.update(),t}function Nd(e,t){return ya(Ld(t).datas,(function(r,i){r!==t&&Fd(r.cloneShallow(),i,t,e)})),t}function Id(e){var t=Ld(this).mainData;return null==e||null==t?t:Ld(t).datas[e]}function Rd(){var e=Ld(this).mainData;return null==e?[{data:e}]:xa(ba(Ld(e).datas),(function(t){return{type:t,data:Ld(e).datas[t]}}))}function Bd(e,t,r){Ld(e).datas={},ya(t,(function(t,i){Fd(t,i,e,r)}))}function Fd(e,t,r,i){Ld(r).datas[t]=e,Ld(e).mainData=r,e.dataType=t,i.struct&&(e[i.structAttr]=i.struct,i.struct[i.datasAttr[t]]=e),e.getLinkedData=Id,e.getLinkedDataAll=Rd}var zd=i.SeriesModel.extend({type:"series.graphGL",visualStyleAccessPath:"itemStyle",hasSymbolVisual:!0,init:function(e){zd.superApply(this,"init",arguments),this.legendDataProvider=function(){return this._categoriesData},this._updateCategoriesData()},mergeOption:function(e){zd.superApply(this,"mergeOption",arguments),this._updateCategoriesData()},getFormattedLabel:function(e,t,r,i){var n=ac.getFormattedLabel(this,e,t,r,i);if(null==n){var a=this.getData(),o=a.dimensions[a.dimensions.length-1];n=a.get(o,e)}return n},getInitialData:function(e,t){var r=e.edges||e.links||[],n=e.data||e.nodes||[],a=this;if(n&&r)return function(e,t,r,n,a){for(var o=new Dd(!0),s=0;s "+p)),c++)}var m=i.helper.createDimensions(e,{coordDimensions:["value"]});(l=new i.List(m,r)).initData(e);var g,_,v,y=new i.List(["value"],r);return y.initData(u,h),a&&a(l,y),_=(g={mainData:l,struct:o,structAttr:"graph",datas:{node:l,edge:y},datasAttr:{node:"data",edge:"edgeData"}}).mainData,(v=g.datas)||(v={main:_},g.datasAttr={main:"data"}),g.datas=g.mainData=null,Bd(_,v,g),ya(v,(function(e){ya(_.TRANSFERABLE_METHODS,(function(t){e.wrapMethod(t,wa(Pd,g))}))})),_.wrapMethod("cloneShallow",wa(Nd,g)),ya(_.CHANGABLE_METHODS,(function(e){_.wrapMethod(e,wa(Od,g))})),function(e,t){if(!e)throw new Error(void 0)}(v[_.dataType]===_),o.update(),o}(n,r,this,0,(function(e,r){e.wrapMethod("getItemModel",(function(e){const t=a._categoriesModels[e.getShallow("category")];return t&&(t.parentModel=e.parentModel,e.parentModel=t),e}));const i=t.getModel([]).getModel;function n(e,t){const r=i.call(this,e,t);return r.resolveParentPath=o,r}function o(e){if(e&&("label"===e[0]||"label"===e[1])){const t=e.slice();return"label"===e[0]?t[0]="edgeLabel":"label"===e[1]&&(t[1]="edgeLabel"),t}return e}r.wrapMethod("getItemModel",(function(e){return e.resolveParentPath=o,e.getModel=n,e}))})).data},getGraph:function(){return this.getData().graph},getEdgeData:function(){return this.getGraph().edgeData},getCategoriesData:function(){return this._categoriesData},formatTooltip:function(e,t,r){if("edge"===r){var n=this.getData(),a=this.getDataParams(e,r),o=n.graph.getEdgeByIndex(e),s=n.getName(o.node1.dataIndex),l=n.getName(o.node2.dataIndex),h=[];return null!=s&&h.push(s),null!=l&&h.push(l),h=i.format.encodeHTML(h.join(" > ")),a.value&&(h+=" : "+i.format.encodeHTML(a.value)),h}return zd.superApply(this,"formatTooltip",arguments)},_updateCategoriesData:function(){var e=(this.option.categories||[]).map((function(e){return null!=e.value?e:Object.assign({value:0},e)})),t=new i.List(["value"],this);t.initData(e),this._categoriesData=t,this._categoriesModels=t.mapArray((function(e){return t.getItemModel(e,!0)}))},setView:function(e){null!=e.zoom&&(this.option.zoom=e.zoom),null!=e.offset&&(this.option.offset=e.offset)},setNodePosition:function(e){for(var t=0;t65535?this.indices instanceof Uint16Array&&(this.indices=new Uint32Array(this.indices)):this.indices instanceof Uint32Array&&(this.indices=new Uint16Array(this.indices)))},setTriangleCount:function(e){this.triangleCount!==e&&(this.indices=0===e?null:this.vertexCount>65535?new Uint32Array(3*e):new Uint16Array(3*e))},_getCubicCurveApproxStep:function(e,t,r,i){return 1/(Ud.dist(e,t)+Ud.dist(r,t)+Ud.dist(i,r)+1)*this.segmentScale},getCubicCurveVertexCount:function(e,t,r,i){var n=this._getCubicCurveApproxStep(e,t,r,i),a=Math.ceil(1/n);return this.useNativeLine?2*a:2*a+2},getCubicCurveTriangleCount:function(e,t,r,i){var n=this._getCubicCurveApproxStep(e,t,r,i),a=Math.ceil(1/n);return this.useNativeLine?0:2*a},getLineVertexCount:function(){return this.getPolylineVertexCount(kd)},getLineTriangleCount:function(){return this.getPolylineTriangleCount(kd)},getPolylineVertexCount:function(e){var t;return t="number"==typeof e?e:"number"!=typeof e[0]?e.length:e.length/2,this.useNativeLine?2*(t-1):2*(t-1)+2},getPolylineTriangleCount:function(e){var t;return t="number"==typeof e?e:"number"!=typeof e[0]?e.length:e.length/2,this.useNativeLine?0:2*(t-1)},addCubicCurve:function(e,t,r,i,n,a){null==a&&(a=1);var o=e[0],s=e[1],l=t[0],h=t[1],u=r[0],c=r[1],d=i[0],f=i[1],p=this._getCubicCurveApproxStep(e,t,r,i),m=p*p,g=m*p,_=3*p,v=3*m,y=6*m,x=6*g,b=o-2*l+u,w=s-2*h+c,T=3*(l-u)-o+d,S=3*(h-c)-s+f,M=o,A=s,E=(l-o)*_+b*v+T*g,C=(h-s)*_+w*v+S*g,D=b*y+T*x,L=w*y+S*x,P=T*x,O=S*x,N=0,I=0,R=Math.ceil(1/p),B=new Float32Array(3*(R+1)),F=(B=[],0);for(I=0;I1&&(M=E>0?Math.min(M,d):Math.max(M,d),A=C>0?Math.min(A,f):Math.max(A,f));this.addPolyline(B,n,a)},addLine:function(e,t,r,i){this.addPolyline([e,t],r,i)},addPolyline:function(){var e=Ud.create(),t=Ud.create(),r=Ud.create(),i=Ud.create(),n=[],a=[],o=[];return function(s,l,h,u,c){if(s.length){var d="number"!=typeof s[0];if(null==c&&(c=d?s.length:s.length/2),!(c<2)){null==u&&(u=0),null==h&&(h=1),this._itemVertexOffsets.push(this._vertexOffset);for(var f,p=d?"number"!=typeof l[0]:l.length/4===c,m=this.attributes.position,g=this.attributes.color,_=this.attributes.offset,v=this.attributes.normal,y=this.indices,x=this._vertexOffset,b=0;b1&&(m.copy(x,x-1),g.copy(x,x-1),x++);else{var S;if(b0){Ud.sub(e,n,o),Ud.sub(t,a,n),Ud.normalize(e,e),Ud.normalize(t,t),Ud.add(i,e,t),Ud.normalize(i,i);var M=h/2*Math.min(1/Ud.dot(e,i),2);r[0]=-i[1],r[1]=i[0],S=M}else Ud.sub(e,a,n),Ud.normalize(e,e),r[0]=-e[1],r[1]=e[0],S=h/2;else Ud.sub(e,n,o),Ud.normalize(e,e),r[0]=-e[1],r[1]=e[0],S=h/2;v.set(x,r),v.set(x+1,r),_.set(x,S),_.set(x+1,-S),Ud.copy(o,n),m.set(x,n),m.set(x+1,n),g.set(x,f),g.set(x+1,f),x+=2}if(this.useNativeLine)g.set(x,f),m.set(x,n),x++;else if(b>0){var A=3*this._faceOffset;(y=this.indices)[A]=x-4,y[A+1]=x-3,y[A+2]=x-2,y[A+3]=x-3,y[A+4]=x-1,y[A+5]=x-2,this._faceOffset+=2}}this._vertexOffset=x}}}}(),setItemColor:function(e,t){for(var r=this._itemVertexOffsets[e],i=e 0.0) {\n float factor = 0.0;\n if (preventOverlap) {\n float d = sqrt(d2);\n d = d - n0.w - n1.w;\n if (d > 0.0) {\n factor = scaling * n0.z * n1.z / (d * d);\n }\n else if (d < 0.0) {\n factor = scaling * 100.0 * n0.z * n1.z;\n }\n }\n else {\n factor = scaling * n0.z * n1.z / d2;\n }\n force += dir * factor;\n }\n }\n\n vec2 dir = gravityCenter - n0.xy;\n float d = 1.0;\n if (!strongGravityMode) {\n d = length(dir);\n }\n\n force += dir * n0.z * gravity / (d + 1.0);\n\n gl_FragColor = vec4(force, 0.0, 1.0);\n}\n@end\n\n@export ecgl.forceAtlas2.updateEdgeAttraction.vertex\n\nattribute vec2 node1;\nattribute vec2 node2;\nattribute float weight;\n\nuniform sampler2D positionTex;\nuniform float edgeWeightInfluence;\nuniform bool preventOverlap;\nuniform bool linLogMode;\n\nuniform vec2 windowSize: WINDOW_SIZE;\n\nvarying vec2 v_Force;\n\nvoid main() {\n\n vec4 n0 = texture2D(positionTex, node1);\n vec4 n1 = texture2D(positionTex, node2);\n\n vec2 dir = n1.xy - n0.xy;\n float d = length(dir);\n float w;\n if (edgeWeightInfluence == 0.0) {\n w = 1.0;\n }\n else if (edgeWeightInfluence == 1.0) {\n w = weight;\n }\n else {\n w = pow(weight, edgeWeightInfluence);\n }\n vec2 offset = vec2(1.0 / windowSize.x, 1.0 / windowSize.y);\n vec2 scale = vec2((windowSize.x - 1.0) / windowSize.x, (windowSize.y - 1.0) / windowSize.y);\n vec2 pos = node1 * scale * 2.0 - 1.0;\n gl_Position = vec4(pos + offset, 0.0, 1.0);\n gl_PointSize = 1.0;\n\n float factor;\n if (preventOverlap) {\n d = d - n1.w - n0.w;\n }\n if (d <= 0.0) {\n v_Force = vec2(0.0);\n return;\n }\n\n if (linLogMode) {\n factor = w * log(d) / d;\n }\n else {\n factor = w;\n }\n v_Force = dir * factor;\n}\n@end\n\n@export ecgl.forceAtlas2.updateEdgeAttraction.fragment\n\nvarying vec2 v_Force;\n\nvoid main() {\n gl_FragColor = vec4(v_Force, 0.0, 0.0);\n}\n@end\n\n@export ecgl.forceAtlas2.calcWeightedSum.vertex\n\nattribute vec2 node;\n\nvarying vec2 v_NodeUv;\n\nvoid main() {\n\n v_NodeUv = node;\n gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n gl_PointSize = 1.0;\n}\n@end\n\n@export ecgl.forceAtlas2.calcWeightedSum.fragment\n\nvarying vec2 v_NodeUv;\n\nuniform sampler2D positionTex;\nuniform sampler2D forceTex;\nuniform sampler2D forcePrevTex;\n\nvoid main() {\n vec2 force = texture2D(forceTex, v_NodeUv).rg;\n vec2 forcePrev = texture2D(forcePrevTex, v_NodeUv).rg;\n\n float mass = texture2D(positionTex, v_NodeUv).z;\n float swing = length(force - forcePrev) * mass;\n float traction = length(force + forcePrev) * 0.5 * mass;\n\n gl_FragColor = vec4(swing, traction, 0.0, 0.0);\n}\n@end\n\n@export ecgl.forceAtlas2.calcGlobalSpeed\n\nuniform sampler2D globalSpeedPrevTex;\nuniform sampler2D weightedSumTex;\nuniform float jitterTolerence;\n\nvoid main() {\n vec2 weightedSum = texture2D(weightedSumTex, vec2(0.5)).xy;\n float prevGlobalSpeed = texture2D(globalSpeedPrevTex, vec2(0.5)).x;\n float globalSpeed = jitterTolerence * jitterTolerence\n * weightedSum.y / weightedSum.x;\n if (prevGlobalSpeed > 0.0) {\n globalSpeed = min(globalSpeed / prevGlobalSpeed, 1.5) * prevGlobalSpeed;\n }\n gl_FragColor = vec4(globalSpeed, 0.0, 0.0, 1.0);\n}\n@end\n\n@export ecgl.forceAtlas2.updatePosition\n\nuniform sampler2D forceTex;\nuniform sampler2D forcePrevTex;\nuniform sampler2D positionTex;\nuniform sampler2D globalSpeedTex;\n\nvarying vec2 v_Texcoord;\n\nvoid main() {\n vec2 force = texture2D(forceTex, v_Texcoord).xy;\n vec2 forcePrev = texture2D(forcePrevTex, v_Texcoord).xy;\n vec4 node = texture2D(positionTex, v_Texcoord);\n\n float globalSpeed = texture2D(globalSpeedTex, vec2(0.5)).r;\n float swing = length(force - forcePrev);\n float speed = 0.1 * globalSpeed / (0.1 + globalSpeed * sqrt(swing));\n\n float df = length(force);\n if (df > 0.0) {\n speed = min(df * speed, 10.0) / df;\n\n gl_FragColor = vec4(node.xy + speed * force, node.zw);\n }\n else {\n gl_FragColor = node;\n }\n}\n@end\n\n@export ecgl.forceAtlas2.edges.vertex\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec2 node;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\nuniform sampler2D positionTex;\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(\n texture2D(positionTex, node).xy, -10.0, 1.0\n );\n v_Color = a_Color;\n}\n@end\n\n@export ecgl.forceAtlas2.edges.fragment\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nvarying vec4 v_Color;\nvoid main() {\n gl_FragColor = color * v_Color;\n}\n@end");var Wd={repulsionByDegree:!0,linLogMode:!1,strongGravityMode:!1,gravity:1,scaling:1,edgeWeightInfluence:1,jitterTolerence:.1,preventOverlap:!1,dissuadeHubs:!1,gravityCenter:null};function jd(e){var t={type:Ka.Texture.FLOAT,minFilter:Ka.Texture.NEAREST,magFilter:Ka.Texture.NEAREST};this._positionSourceTex=new Ka.Texture2D(t),this._positionSourceTex.flipY=!1,this._positionTex=new Ka.Texture2D(t),this._positionPrevTex=new Ka.Texture2D(t),this._forceTex=new Ka.Texture2D(t),this._forcePrevTex=new Ka.Texture2D(t),this._weightedSumTex=new Ka.Texture2D(t),this._weightedSumTex.width=this._weightedSumTex.height=1,this._globalSpeedTex=new Ka.Texture2D(t),this._globalSpeedPrevTex=new Ka.Texture2D(t),this._globalSpeedTex.width=this._globalSpeedTex.height=1,this._globalSpeedPrevTex.width=this._globalSpeedPrevTex.height=1,this._nodeRepulsionPass=new pn({fragment:Ka.Shader.source("ecgl.forceAtlas2.updateNodeRepulsion")}),this._positionPass=new pn({fragment:Ka.Shader.source("ecgl.forceAtlas2.updatePosition")}),this._globalSpeedPass=new pn({fragment:Ka.Shader.source("ecgl.forceAtlas2.calcGlobalSpeed")}),this._copyPass=new pn({fragment:Ka.Shader.source("clay.compositor.output")});var r=function(e){e.blendEquation(e.FUNC_ADD),e.blendFunc(e.ONE,e.ONE)};this._edgeForceMesh=new Ka.Mesh({geometry:new Ka.Geometry({attributes:{node1:new Ka.Geometry.Attribute("node1","float",2),node2:new Ka.Geometry.Attribute("node2","float",2),weight:new Ka.Geometry.Attribute("weight","float",1)},dynamic:!0,mainAttribute:"node1"}),material:new Ka.Material({transparent:!0,shader:Ka.createShader("ecgl.forceAtlas2.updateEdgeAttraction"),blend:r,depthMask:!1,depthText:!1}),mode:Ka.Mesh.POINTS}),this._weightedSumMesh=new Ka.Mesh({geometry:new Ka.Geometry({attributes:{node:new Ka.Geometry.Attribute("node","float",2)},dynamic:!0,mainAttribute:"node"}),material:new Ka.Material({transparent:!0,shader:Ka.createShader("ecgl.forceAtlas2.calcWeightedSum"),blend:r,depthMask:!1,depthText:!1}),mode:Ka.Mesh.POINTS}),this._framebuffer=new zi({depthBuffer:!1}),this._dummyCamera=new Ka.OrthographicCamera({left:-1,right:1,top:1,bottom:-1,near:0,far:100}),this._globalSpeed=0}jd.prototype.updateOption=function(e){for(var t in Wd)this[t]=Wd[t];var r=this._nodes.length;if(this.jitterTolerence=r>5e4?10:r>5e3?1:.1,this.scaling=r>100?2:10,e)for(var t in Wd)null!=e[t]&&(this[t]=e[t]);if(this.repulsionByDegree)for(var i=this._positionSourceTex.pixels,n=0;ne},jd.prototype._swapTexture=function(){var e=this._positionPrevTex;this._positionPrevTex=this._positionTex,this._positionTex=e,e=this._forcePrevTex,this._forcePrevTex=this._forceTex,this._forceTex=e,e=this._globalSpeedPrevTex,this._globalSpeedPrevTex=this._globalSpeedTex,this._globalSpeedTex=e},jd.prototype._initFromSource=function(e){this._framebuffer.attach(this._positionPrevTex),this._framebuffer.bind(e),this._copyPass.setUniform("texture",this._positionSourceTex),this._copyPass.render(e),e.gl.clearColor(0,0,0,0),this._framebuffer.attach(this._forcePrevTex),e.gl.clear(e.gl.COLOR_BUFFER_BIT),this._framebuffer.attach(this._globalSpeedPrevTex),e.gl.clear(e.gl.COLOR_BUFFER_BIT),this._framebuffer.unbind(e)},jd.prototype._resize=function(e,t){["_positionSourceTex","_positionTex","_positionPrevTex","_forceTex","_forcePrevTex"].forEach((function(r){this[r].width=e,this[r].height=t,this[r].dirty()}),this)},jd.prototype.dispose=function(e){this._framebuffer.dispose(e),this._copyPass.dispose(e),this._nodeRepulsionPass.dispose(e),this._positionPass.dispose(e),this._globalSpeedPass.dispose(e),this._edgeForceMesh.geometry.dispose(e),this._weightedSumMesh.geometry.dispose(e),this._positionSourceTex.dispose(e),this._positionTex.dispose(e),this._positionPrevTex.dispose(e),this._forceTex.dispose(e),this._forcePrevTex.dispose(e),this._weightedSumTex.dispose(e),this._globalSpeedTex.dispose(e),this._globalSpeedPrevTex.dispose(e)};const Xd=jd;var qd=function(){var e=function(){return new Float32Array(2)},t=function(e,t){var r=t[0]-e[0],i=t[1]-e[1];return Math.sqrt(r*r+i*i)},r=function(e){var t=e[0],r=e[1];return Math.sqrt(t*t+r*r)},i=function(e,t,r,i){return e[0]=t[0]+r[0]*i,e[1]=t[1]+r[1]*i,e},n=function(e,t,r){return e[0]=t[0]+r[0],e[1]=t[1]+r[1],e},a=function(e,t,r){return e[0]=t[0]-r[0],e[1]=t[1]-r[1],e},o=function(e,t,r){return e[0]=t,e[1]=r,e};function s(){this.subRegions=[],this.nSubRegions=0,this.node=null,this.mass=0,this.centerOfMass=null,this.bbox=new Float32Array(4),this.size=0}var l=s.prototype;function h(){this.position=new Float32Array(2),this.force=e(),this.forcePrev=e(),this.mass=1,this.inDegree=0,this.outDegree=0}function u(e,t){this.source=e,this.target=t,this.weight=1}function c(){this.autoSettings=!0,this.barnesHutOptimize=!0,this.barnesHutTheta=1.5,this.repulsionByDegree=!0,this.linLogMode=!1,this.strongGravityMode=!1,this.gravity=1,this.scaling=1,this.edgeWeightInfluence=1,this.jitterTolerence=.1,this.preventOverlap=!1,this.dissuadeHubs=!1,this.rootRegion=new s,this.rootRegion.centerOfMass=e(),this.nodes=[],this.edges=[],this.bbox=new Float32Array(4),this.gravityCenter=null,this._massArr=null,this._swingingArr=null,this._sizeArr=null,this._globalSpeed=0}l.beforeUpdate=function(){for(var e=0;e=e&&this.bbox[1]<=t&&this.bbox[3]>=t},l.setBBox=function(e,t,r,i){this.bbox[0]=e,this.bbox[1]=t,this.bbox[2]=r,this.bbox[3]=i,this.size=(r-e+i-t)/2},l._newSubRegion=function(){var e=this.subRegions[this.nSubRegions];return e||(e=new s,this.subRegions[this.nSubRegions]=e),this.nSubRegions++,e},l._addNodeToSubRegion=function(e){var t=this.findSubRegion(e.position[0],e.position[1]),r=this.bbox;if(!t){var i=(r[0]+r[2])/2,n=(r[1]+r[3])/2,a=(r[2]-r[0])/2,o=(r[3]-r[1])/2,s=e.position[0]>=i?1:0,l=e.position[1]>=n?1:0;(t=this._newSubRegion()).setBBox(s*a+r[0],l*o+r[1],(s+1)*a+r[0],(l+1)*o+r[1])}t.addNode(e)},l._updateCenterOfMass=function(e){null==this.centerOfMass&&(this.centerOfMass=new Float32Array(2));var t=this.centerOfMass[0]*this.mass,r=this.centerOfMass[1]*this.mass;t+=e.position[0]*e.mass,r+=e.position[1]*e.mass,this.mass+=e.mass,this.centerOfMass[0]=t/this.mass,this.centerOfMass[1]=r/this.mass};var d=c.prototype;d.initNodes=function(e,t,r){var i=t.length;this.nodes.length=0;for(var n=void 0!==r,a=0;a0&&(this.strongGravityMode?this.applyNodeStrongGravity(c):this.applyNodeGravity(c))}for(h=0;h0&&(_=Math.min(_/this._globalSpeed,1.5)*this._globalSpeed),this._globalSpeed=_,h=0;h0&&(y=Math.min(x*y,10)/x,i(u.position,u.position,u.force,y))}},d.applyRegionToNodeRepulsion=function(){var t=e();return function(e,r){if(e.node)this.applyNodeToNodeRepulsion(e.node,r,!0);else{a(t,r.position,e.centerOfMass);var n=t[0]*t[0]+t[1]*t[1];if(n>this.barnesHutTheta*e.size*e.size){var o=this.scaling*r.mass*e.mass/n;i(r.force,r.force,t,o)}else for(var s=0;s0)s=this.scaling*e.mass*r.mass/(l*l);else{if(!(l<0))return;s=100*this.scaling*e.mass*r.mass}}else s=this.scaling*e.mass*r.mass/o;i(e.force,e.force,t,s),i(r.force,r.force,t,-s)}}}}(),d.applyEdgeAttraction=function(){var t=e();return function(e){var n=e.source,o=e.target;a(t,n.position,o.position);var s,l,h=r(t);s=0===this.edgeWeightInfluence?1:1===this.edgeWeightInfluence?e.weight:Math.pow(e.weight,this.edgeWeightInfluence),this.preventOverlap&&(h=h-n.size-o.size)<=0||(l=this.linLogMode?-s*Math.log(h+1)/(h+1):-s,i(n.force,n.force,t,l),i(o.force,o.force,t,-l))}}(),d.applyNodeGravity=function(){var t=e();return function(e){a(t,this.gravityCenter,e.position);var n=r(t);i(e.force,e.force,t,this.gravity*e.mass/(n+1))}}(),d.applyNodeStrongGravity=function(){var t=e();return function(e){a(t,this.gravityCenter,e.position),i(e.force,e.force,t,this.gravity*e.mass)}}(),d.updateBBox=function(){for(var e=1/0,t=1/0,r=-1/0,i=-1/0,n=0;n5e4?10:a>5e3?1:.1,t.scaling=a>100?2:10,t.barnesHutOptimize=a>1e3,e)for(var r in Zd)null!=e[r]&&(t[r]=e[r]);if(!t.gravityCenter){for(var o=[1/0,1/0],s=[-1/0,-1/0],l=0;le},Yd.prototype.getNodePosition=function(e,t){if(t||(t=new Float32Array(2*this._nodes.length)),this._positionArr)for(var r=0;r0?1.1:.9,a=Math.max(Math.min(this._zoom*n,this.maxZoom),this.minZoom);n=a/this._zoom;var o=this._convertPos(r,i),s=(o.x-this._dx)*(n-1),l=(o.y-this._dy)*(n-1);this._dx-=s,this._dy-=l,this._zoom=a,this._needsUpdate=!0}}},dispose:function(){var e=this.zr;e.off("mousedown",this._mouseDownHandler),e.off("mousemove",this._mouseMoveHandler),e.off("mouseup",this._mouseUpHandler),e.off("mousewheel",this._mouseWheelHandler),e.off("globalout",this._mouseUpHandler),e.animation.off("frame",this._update)}});var Jd=Po.vec2;Ka.Shader.import("@export ecgl.lines2D.vertex\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nattribute vec2 position: POSITION;\nattribute vec4 a_Color : COLOR;\nvarying vec4 v_Color;\n\n#ifdef POSITIONTEXTURE_ENABLED\nuniform sampler2D positionTexture;\n#endif\n\nvoid main()\n{\n gl_Position = worldViewProjection * vec4(position, -10.0, 1.0);\n\n v_Color = a_Color;\n}\n\n@end\n\n@export ecgl.lines2D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\n\nvoid main()\n{\n gl_FragColor = color * v_Color;\n}\n@end\n\n\n@export ecgl.meshLines2D.vertex\n\nattribute vec2 position: POSITION;\nattribute vec2 normal;\nattribute float offset;\nattribute vec4 a_Color : COLOR;\n\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\nuniform vec4 viewport : VIEWPORT;\n\nvarying vec4 v_Color;\nvarying float v_Miter;\n\nvoid main()\n{\n vec4 p2 = worldViewProjection * vec4(position + normal, -10.0, 1.0);\n gl_Position = worldViewProjection * vec4(position, -10.0, 1.0);\n\n p2.xy /= p2.w;\n gl_Position.xy /= gl_Position.w;\n\n vec2 N = normalize(p2.xy - gl_Position.xy);\n gl_Position.xy += N * offset / viewport.zw * 2.0;\n\n gl_Position.xy *= gl_Position.w;\n\n v_Color = a_Color;\n}\n@end\n\n\n@export ecgl.meshLines2D.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\n\nvarying vec4 v_Color;\nvarying float v_Miter;\n\nvoid main()\n{\n gl_FragColor = color * v_Color;\n}\n\n@end");var $d=1;const ef=i.ChartView.extend({type:"graphGL",__ecgl__:!0,init:function(e,t){this.groupGL=new Ka.Node,this.viewGL=new Il("orthographic"),this.viewGL.camera.left=this.viewGL.camera.right=0,this.viewGL.add(this.groupGL),this._pointsBuilder=new Fc(!0,t),this._forceEdgesMesh=new Ka.Mesh({material:new Ka.Material({shader:Ka.createShader("ecgl.forceAtlas2.edges"),transparent:!0,depthMask:!1,depthTest:!1}),$ignorePicking:!0,geometry:new Ka.Geometry({attributes:{node:new Ka.Geometry.Attribute("node","float",2),color:new Ka.Geometry.Attribute("color","float",4,"COLOR")},dynamic:!0,mainAttribute:"node"}),renderOrder:-1,mode:Ka.Mesh.LINES}),this._edgesMesh=new Ka.Mesh({material:new Ka.Material({shader:Ka.createShader("ecgl.meshLines2D"),transparent:!0,depthMask:!1,depthTest:!1}),$ignorePicking:!0,geometry:new Hd({useNativeLine:!1,dynamic:!0}),renderOrder:-1,culling:!1}),this._layoutId=0,this._control=new Qd({zr:t.getZr(),viewGL:this.viewGL}),this._control.setTarget(this.groupGL),this._control.init(),this._clickHandler=this._clickHandler.bind(this)},render:function(e,t,r){this.groupGL.add(this._pointsBuilder.rootNode),this._model=e,this._api=r,this._initLayout(e,t,r),this._pointsBuilder.update(e,t,r),this._forceLayoutInstance instanceof Xd||this.groupGL.remove(this._forceEdgesMesh),this._updateCamera(e,r),this._control.off("update"),this._control.on("update",(function(){r.dispatchAction({type:"graphGLRoam",seriesId:e.id,zoom:this._control.getZoom(),offset:this._control.getOffset()}),this._pointsBuilder.updateView(this.viewGL.camera)}),this),this._control.setZoom(Mn(e.get("zoom"),1)),this._control.setOffset(e.get("offset")||[0,0]);var i=this._pointsBuilder.getPointsMesh();if(i.off("mousemove",this._mousemoveHandler),i.off("mouseout",this._mouseOutHandler,this),r.getZr().off("click",this._clickHandler),this._pointsBuilder.highlightOnMouseover=!0,e.get("focusNodeAdjacency")){var n=e.get("focusNodeAdjacencyOn");"click"===n?r.getZr().on("click",this._clickHandler):"mouseover"===n&&(i.on("mousemove",this._mousemoveHandler,this),i.on("mouseout",this._mouseOutHandler,this),this._pointsBuilder.highlightOnMouseover=!1)}this._lastMouseOverDataIndex=-1},_clickHandler:function(e){if(!this._layouting){var t=this._pointsBuilder.getPointsMesh().dataIndex;t>=0?this._api.dispatchAction({type:"graphGLFocusNodeAdjacency",seriesId:this._model.id,dataIndex:t}):this._api.dispatchAction({type:"graphGLUnfocusNodeAdjacency",seriesId:this._model.id})}},_mousemoveHandler:function(e){if(!this._layouting){var t=this._pointsBuilder.getPointsMesh().dataIndex;t>=0?t!==this._lastMouseOverDataIndex&&this._api.dispatchAction({type:"graphGLFocusNodeAdjacency",seriesId:this._model.id,dataIndex:t}):this._mouseOutHandler(e),this._lastMouseOverDataIndex=t}},_mouseOutHandler:function(e){this._layouting||(this._api.dispatchAction({type:"graphGLUnfocusNodeAdjacency",seriesId:this._model.id}),this._lastMouseOverDataIndex=-1)},_updateForceEdgesGeometry:function(e,t){var r=this._forceEdgesMesh.geometry,i=t.getEdgeData(),n=0,a=this._forceLayoutInstance,o=2*i.count();r.attributes.node.init(o),r.attributes.color.init(o),i.each((function(t){var o=e[t];r.attributes.node.set(n,a.getNodeUV(o.node1)),r.attributes.node.set(n+1,a.getNodeUV(o.node2));var s=Ih(i,o.dataIndex),l=Ka.parseColor(s);l[3]*=Mn(Rh(i,o.dataIndex),1),r.attributes.color.set(n,l),r.attributes.color.set(n+1,l),n+=2})),r.dirty()},_updateMeshLinesGeometry:function(){var e=this._model.getEdgeData(),t=this._edgesMesh.geometry,r=(e=this._model.getEdgeData(),this._model.getData().getLayout("points"));t.resetOffset(),t.setVertexCount(e.count()*t.getLineVertexCount()),t.setTriangleCount(e.count()*t.getLineTriangleCount());var i=[],n=[],a=["lineStyle","width"];this._originalEdgeColors=new Float32Array(4*e.count()),this._edgeIndicesMap=new Float32Array(e.count()),e.each((function(o){var s=e.graph.getEdgeByIndex(o),l=2*s.node1.dataIndex,h=2*s.node2.dataIndex;i[0]=r[l],i[1]=r[l+1],n[0]=r[h],n[1]=r[h+1];var u=Ih(e,s.dataIndex),c=Ka.parseColor(u);c[3]*=Mn(Rh(e,s.dataIndex),1);var d=e.getItemModel(s.dataIndex),f=Mn(d.get(a),1)*this._api.getDevicePixelRatio();t.addLine(i,n,c,f);for(var p=0;p<4;p++)this._originalEdgeColors[4*s.dataIndex+p]=c[p];this._edgeIndicesMap[s.dataIndex]=o}),this),t.dirty()},_updateForceNodesGeometry:function(e){for(var t=this._pointsBuilder.getPointsMesh(),r=[],i=0;i=f&&(l._syncNodePosition(e),d=0),r.getZr().refresh(),Qa((function(){p(t)}))}))};Qa((function(){l._forceLayoutInstanceToDispose&&(l._forceLayoutInstanceToDispose.dispose(n.layer.renderer),l._forceLayoutInstanceToDispose=null),p(h)})),this._layouting=!0}}},stopLayout:function(e,t,r,i){i&&null!=i.from&&i.from!==this.uid||(this._layoutId=0,this.groupGL.remove(this._forceEdgesMesh),this.groupGL.add(this._edgesMesh),this._forceLayoutInstance&&this.viewGL.layer&&(i&&i.beforeLayout||(this._syncNodePosition(e),this._updateAfterLayout(e,t,r)),this._api.getZr().refresh(),this._layouting=!1))},_syncNodePosition:function(e){var t=this._forceLayoutInstance.getNodePosition(this.viewGL.layer.renderer);e.getData().setLayout("points",t),e.setNodePosition(t)},_updateAfterLayout:function(e,t,r){this._updateMeshLinesGeometry(),this._pointsBuilder.removePositionTexture(),this._pointsBuilder.updateLayout(e,t,r),this._pointsBuilder.updateView(this.viewGL.camera),this._pointsBuilder.updateLabels(),this._pointsBuilder.showLabels()},focusNodeAdjacency:function(e,t,r,i){var n=this._model.getData();this._downplayAll();var a=i.dataIndex,o=n.graph,s=[],l=o.getNodeByIndex(a);s.push(l),l.edges.forEach((function(e){e.dataIndex<0||(e.node1!==l&&s.push(e.node1),e.node2!==l&&s.push(e.node2))}),this),this._pointsBuilder.fadeOutAll(.05),this._fadeOutEdgesAll(.05),s.forEach((function(e){this._pointsBuilder.highlight(n,e.dataIndex)}),this),this._pointsBuilder.updateLabels(s.map((function(e){return e.dataIndex})));var h=[];l.edges.forEach((function(e){e.dataIndex>=0&&(this._highlightEdge(e.dataIndex),h.push(e))}),this),this._focusNodes=s,this._focusEdges=h},unfocusNodeAdjacency:function(e,t,r,i){this._downplayAll(),this._pointsBuilder.fadeInAll(),this._fadeInEdgesAll(),this._pointsBuilder.updateLabels()},_highlightEdge:function(e){var t=this._model.getEdgeData().getItemModel(e),r=Ka.parseColor(t.get("emphasis.lineStyle.color")||t.get("lineStyle.color")),i=Mn(t.get("emphasis.lineStyle.opacity"),t.get("lineStyle.opacity"),1);r[3]*=i,this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[e],r)},_downplayAll:function(){this._focusNodes&&this._focusNodes.forEach((function(e){this._pointsBuilder.downplay(this._model.getData(),e.dataIndex)}),this),this._focusEdges&&this._focusEdges.forEach((function(e){this._downplayEdge(e.dataIndex)}),this)},_downplayEdge:function(e){var t=this._getColor(e,[]);this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[e],t)},_setEdgeFade:(tf=[],function(e,t){this._getColor(e,tf),tf[3]*=t,this._edgesMesh.geometry.setItemColor(this._edgeIndicesMap[e],tf)}),_getColor:function(e,t){for(var r=0;r<4;r++)t[r]=this._originalEdgeColors[4*e+r];return t},_fadeOutEdgesAll:function(e){this._model.getData().graph.eachEdge((function(t){this._setEdgeFade(t.dataIndex,e)}),this)},_fadeInEdgesAll:function(){this._fadeOutEdgesAll(1)},_updateCamera:function(e,t){this.viewGL.setViewport(0,0,t.getWidth(),t.getHeight(),t.getDevicePixelRatio());for(var r=this.viewGL.camera,i=e.getData().getLayout("points"),n=Jd.create(1/0,1/0),a=Jd.create(-1/0,-1/0),o=[],s=0;sr.left&&hr.top)){var u=Math.max(a[0]-n[0],10),c=u/t.getWidth()*t.getHeight();u*=1.4,c*=1.4,n[0]-=.2*u,r.left=n[0],r.top=l-c/2,r.bottom=l+c/2,r.right=u+n[0],r.near=0,r.far=100}},dispose:function(){var e=this.viewGL.layer.renderer;this._forceLayoutInstance&&this._forceLayoutInstance.dispose(e),this.groupGL.removeAll(),this._layoutId=-1,this._pointsBuilder.dispose()},remove:function(){this.groupGL.removeAll(),this._control.dispose()}});var tf;function rf(e){return e instanceof Array||(e=[e,e]),e}(0,i.use)((function(e){function t(){}e.registerChartView(ef),e.registerSeriesModel(Gd),e.registerVisual((function(e){const t={};e.eachSeriesByType("graphGL",(function(e){var r=e.getCategoriesData(),n=e.getData(),a={};r.each((function(i){var n=r.getName(i);a["ec-"+n]=i;var o=r.getItemModel(i),s=o.getModel("itemStyle").getItemStyle();s.fill||(s.fill=e.getColorFromPalette(n,t)),r.setItemVisual(i,"style",s);var l=["symbol","symbolSize","symbolKeepAspect"];for(let e=0;e65535?new Uint32Array(3*i):new Uint16Array(3*i))},addLine:function(e){var t=this._vertexOffset;this.attributes.position.set(t,[e[0],e[1],1]),this.attributes.position.set(t+1,[e[0],e[1],-1]),this.attributes.position.set(t+2,[e[0],e[1],2]),this.attributes.position.set(t+3,[e[0],e[1],-2]),this.setTriangleIndices(this._faceOffset++,[t,t+1,t+2]),this.setTriangleIndices(this._faceOffset++,[t+1,t+2,t+3]),this._vertexOffset+=4}});Xe.import("@export ecgl.vfParticle.particle.fragment\n\nuniform sampler2D particleTexture;\nuniform sampler2D spawnTexture;\nuniform sampler2D velocityTexture;\n\nuniform float deltaTime;\nuniform float elapsedTime;\n\nuniform float speedScaling : 1.0;\n\nuniform vec2 textureSize;\nuniform vec4 region : [0, 0, 1, 1];\nuniform float firstFrameTime;\n\nvarying vec2 v_Texcoord;\n\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, v_Texcoord);\n bool spawn = false;\n if (p.w <= 0.0) {\n p = texture2D(spawnTexture, fract(v_Texcoord + elapsedTime / 10.0));\n p.w -= firstFrameTime;\n spawn = true;\n }\n vec2 v = texture2D(velocityTexture, fract(p.xy * region.zw + region.xy)).xy;\n v = (v - 0.5) * 2.0;\n p.z = length(v);\n p.xy += v * deltaTime / 10.0 * speedScaling;\n p.w -= deltaTime;\n\n if (spawn || p.xy != fract(p.xy)) {\n p.z = 0.0;\n }\n p.xy = fract(p.xy);\n\n gl_FragColor = p;\n}\n@end\n\n@export ecgl.vfParticle.renderPoints.vertex\n\n#define PI 3.1415926\n\nattribute vec2 texcoord : TEXCOORD_0;\n\nuniform sampler2D particleTexture;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nuniform float size : 1.0;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, texcoord);\n\n if (p.w > 0.0 && p.z > 1e-5) {\n gl_Position = worldViewProjection * vec4(p.xy * 2.0 - 1.0, 0.0, 1.0);\n }\n else {\n gl_Position = vec4(100000.0, 100000.0, 100000.0, 1.0);\n }\n\n v_Mag = p.z;\n v_Uv = p.xy;\n\n gl_PointSize = size;\n}\n\n@end\n\n@export ecgl.vfParticle.renderPoints.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform sampler2D gradientTexture;\nuniform sampler2D colorTexture;\nuniform sampler2D spriteTexture;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n gl_FragColor = color;\n#ifdef SPRITETEXTURE_ENABLED\n gl_FragColor *= texture2D(spriteTexture, gl_PointCoord);\n if (color.a == 0.0) {\n discard;\n }\n#endif\n#ifdef GRADIENTTEXTURE_ENABLED\n gl_FragColor *= texture2D(gradientTexture, vec2(v_Mag, 0.5));\n#endif\n#ifdef COLORTEXTURE_ENABLED\n gl_FragColor *= texture2D(colorTexture, v_Uv);\n#endif\n}\n\n@end\n\n@export ecgl.vfParticle.renderLines.vertex\n\n#define PI 3.1415926\n\nattribute vec3 position : POSITION;\n\nuniform sampler2D particleTexture;\nuniform sampler2D prevParticleTexture;\n\nuniform float size : 1.0;\nuniform vec4 vp: VIEWPORT;\nuniform mat4 worldViewProjection : WORLDVIEWPROJECTION;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\n@import clay.util.rand\n\nvoid main()\n{\n vec4 p = texture2D(particleTexture, position.xy);\n vec4 p2 = texture2D(prevParticleTexture, position.xy);\n\n p.xy = p.xy * 2.0 - 1.0;\n p2.xy = p2.xy * 2.0 - 1.0;\n\n if (p.w > 0.0 && p.z > 1e-5) {\n vec2 dir = normalize(p.xy - p2.xy);\n vec2 norm = vec2(dir.y / vp.z, -dir.x / vp.w) * sign(position.z) * size;\n if (abs(position.z) == 2.0) {\n gl_Position = vec4(p.xy + norm, 0.0, 1.0);\n v_Uv = p.xy;\n v_Mag = p.z;\n }\n else {\n gl_Position = vec4(p2.xy + norm, 0.0, 1.0);\n v_Mag = p2.z;\n v_Uv = p2.xy;\n }\n gl_Position = worldViewProjection * gl_Position;\n }\n else {\n gl_Position = vec4(100000.0, 100000.0, 100000.0, 1.0);\n }\n}\n\n@end\n\n@export ecgl.vfParticle.renderLines.fragment\n\nuniform vec4 color : [1.0, 1.0, 1.0, 1.0];\nuniform sampler2D gradientTexture;\nuniform sampler2D colorTexture;\n\nvarying float v_Mag;\nvarying vec2 v_Uv;\n\nvoid main()\n{\n gl_FragColor = color;\n #ifdef GRADIENTTEXTURE_ENABLED\n gl_FragColor *= texture2D(gradientTexture, vec2(v_Mag, 0.5));\n#endif\n#ifdef COLORTEXTURE_ENABLED\n gl_FragColor *= texture2D(colorTexture, v_Uv);\n#endif\n}\n\n@end\n");var of=function(){this.motionBlurFactor=.99,this.vectorFieldTexture=new Dr({type:wr.FLOAT,flipY:!1}),this.particleLife=[5,20],this._particleType="point",this._particleSize=1,this.particleColor=[1,1,1,1],this.particleSpeedScaling=1,this._thisFrameTexture=null,this._particlePass=null,this._spawnTexture=null,this._particleTexture0=null,this._particleTexture1=null,this._particlePointsMesh=null,this._surfaceFrameBuffer=null,this._elapsedTime=0,this._scene=null,this._camera=null,this._lastFrameTexture=null,this._supersampling=1,this._downsampleTextures=[],this._width=512,this._height=512,this.init()};of.prototype={constructor:of,init:function(){var e={type:wr.FLOAT,minFilter:wr.NEAREST,magFilter:wr.NEAREST,useMipmap:!1};this._spawnTexture=new Dr(e),this._particleTexture0=new Dr(e),this._particleTexture1=new Dr(e),this._frameBuffer=new zi({depthBuffer:!1}),this._particlePass=new pn({fragment:Xe.source("ecgl.vfParticle.particle.fragment")}),this._particlePass.setUniform("velocityTexture",this.vectorFieldTexture),this._particlePass.setUniform("spawnTexture",this._spawnTexture),this._downsamplePass=new pn({fragment:Xe.source("clay.compositor.downsample")});var t=new Sr({renderOrder:10,material:new le({shader:new Xe(Xe.source("ecgl.vfParticle.renderPoints.vertex"),Xe.source("ecgl.vfParticle.renderPoints.fragment"))}),mode:Sr.POINTS,geometry:new Vr({dynamic:!0,mainAttribute:"texcoord0"})}),r=new Sr({renderOrder:10,material:new le({shader:new Xe(Xe.source("ecgl.vfParticle.renderLines.vertex"),Xe.source("ecgl.vfParticle.renderLines.fragment"))}),geometry:new af,culling:!1}),i=new Sr({material:new le({shader:new Xe(Xe.source("ecgl.color.vertex"),Xe.source("ecgl.color.fragment"))}),geometry:new ki});i.material.enableTexture("diffuseMap"),this._particlePointsMesh=t,this._particleLinesMesh=r,this._lastFrameFullQuadMesh=i,this._camera=new un,this._thisFrameTexture=new Dr,this._lastFrameTexture=new Dr},setParticleDensity:function(e,t){for(var r=new Float32Array(e*t*4),i=0,n=this.particleLife,a=0;a0?e[e.length-1]:this._lastFrameTexture},setRegion:function(e){this._particlePass.setUniform("region",e)},resize:function(e,t){this._lastFrameTexture.width=e*this._supersampling,this._lastFrameTexture.height=t*this._supersampling,this._thisFrameTexture.width=e*this._supersampling,this._thisFrameTexture.height=t*this._supersampling,this._width=e,this._height=t},setParticleSize:function(e){var t=this._getParticleMesh();if(e<=2)return t.material.disableTexture("spriteTexture"),void(t.material.transparent=!1);this._spriteTexture||(this._spriteTexture=new Dr),this._spriteTexture.image&&this._spriteTexture.image.width===e||(this._spriteTexture.image=function(e){var t=document.createElement("canvas");t.width=t.height=e;var r=t.getContext("2d");return r.fillStyle="#fff",r.arc(e/2,e/2,e/2,0,2*Math.PI),r.fill(),t}(e),this._spriteTexture.dirty()),t.material.transparent=!0,t.material.enableTexture("spriteTexture"),t.material.set("spriteTexture",this._spriteTexture),this._particleSize=e},setGradientTexture:function(e){var t=this._getParticleMesh().material;t[e?"enableTexture":"disableTexture"]("gradientTexture"),t.setUniform("gradientTexture",e)},setColorTextureImage:function(e,t){this._getParticleMesh().material.setTextureImage("colorTexture",e,t,{flipY:!0})},setParticleType:function(e){this._particleType=e},clearFrame:function(e){var t=this._frameBuffer;t.attach(this._lastFrameTexture),t.bind(e),e.gl.clear(e.gl.DEPTH_BUFFER_BIT|e.gl.COLOR_BUFFER_BIT),t.unbind(e)},setSupersampling:function(e){this._supersampling=e,this.resize(this._width,this._height)},_updateDownsampleTextures:function(e,t){for(var r=this._downsampleTextures,i=Math.max(Math.floor(Math.log(this._supersampling/t.getDevicePixelRatio())/Math.log(2)),0),n=2,a=this._width*this._supersampling,o=this._height*this._supersampling,s=0;s=359&&(n[0]>0&&(n[0]=0),a[0]1?(t.material.shader!==this._meshLinesShader&&t.material.attachShader(this._meshLinesShader),t.mode=Ka.Mesh.TRIANGLES):(t.material.shader!==this._nativeLinesShader&&t.material.attachShader(this._nativeLinesShader),t.mode=Ka.Mesh.LINES),r=r||0,i=i||n.count(),s.resetOffset();var u=0,c=0,d=[],f=[],p=[],m=[],g=[],_=.3,v=.7;function y(){f[0]=d[0]*v+m[0]*_-(d[1]-m[1])*a,f[1]=d[1]*v+m[1]*_-(m[0]-d[0])*a,p[0]=d[0]*_+m[0]*v-(d[1]-m[1])*a,p[1]=d[1]*_+m[1]*v-(m[0]-d[0])*a}if(o||0!==a)for(var x=r;x{t.exports=e}},r={};function i(e){if(r[e])return r[e].exports;var n=r[e]={exports:{}};return t[e](n,n.exports,i),n.exports}return i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i(468)})()})); \ No newline at end of file diff --git a/demo/vendor/echarts.min.js b/demo/vendor/echarts.min.js new file mode 100644 index 0000000..a3e9805 --- /dev/null +++ b/demo/vendor/echarts.min.js @@ -0,0 +1,45 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).echarts={})}(this,(function(t){"use strict"; +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},e(t,n)};function n(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}var i=function(){this.firefox=!1,this.ie=!1,this.edge=!1,this.newEdge=!1,this.weChat=!1},r=new function(){this.browser=new i,this.node=!1,this.wxa=!1,this.worker=!1,this.svgSupported=!1,this.touchEventsSupported=!1,this.pointerEventsSupported=!1,this.domSupported=!1,this.transformSupported=!1,this.transform3dSupported=!1,this.hasGlobalWindow="undefined"!=typeof window};"object"==typeof wx&&"function"==typeof wx.getSystemInfoSync?(r.wxa=!0,r.touchEventsSupported=!0):"undefined"==typeof document&&"undefined"!=typeof self?r.worker=!0:!r.hasGlobalWindow||"Deno"in window?(r.node=!0,r.svgSupported=!0):function(t,e){var n=e.browser,i=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),o=t.match(/Edge?\/([\d.]+)/),a=/micromessenger/i.test(t);i&&(n.firefox=!0,n.version=i[1]);r&&(n.ie=!0,n.version=r[1]);o&&(n.edge=!0,n.version=o[1],n.newEdge=+o[1].split(".")[0]>18);a&&(n.weChat=!0);e.svgSupported="undefined"!=typeof SVGRect,e.touchEventsSupported="ontouchstart"in window&&!n.ie&&!n.edge,e.pointerEventsSupported="onpointerdown"in window&&(n.edge||n.ie&&+n.version>=11),e.domSupported="undefined"!=typeof document;var s=document.documentElement.style;e.transform3dSupported=(n.ie&&"transition"in s||n.edge||"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix||"MozPerspective"in s)&&!("OTransition"in s),e.transformSupported=e.transform3dSupported||n.ie&&+n.version>=9}(navigator.userAgent,r);var o="sans-serif",a="12px "+o;var s,l,u=function(t){var e={};if("undefined"==typeof JSON)return e;for(var n=0;n=0)o=r*t.length;else for(var c=0;c>1)%2;a.style.cssText=["position: absolute","visibility: hidden","padding: 0","margin: 0","border-width: 0","user-select: none","width:0","height:0",i[s]+":0",r[l]+":0",i[1-s]+":auto",r[1-l]+":auto",""].join("!important;"),t.appendChild(a),n.push(a)}return n}(e,a),l=function(t,e,n){for(var i=n?"invTrans":"trans",r=e[i],o=e.srcCoords,a=[],s=[],l=!0,u=0;u<4;u++){var h=t[u].getBoundingClientRect(),c=2*u,p=h.left,d=h.top;a.push(p,d),l=l&&o&&p===o[c]&&d===o[c+1],s.push(t[u].offsetLeft,t[u].offsetTop)}return l&&r?r:(e.srcCoords=a,e[i]=n?$t(s,a):$t(a,s))}(s,a,o);if(l)return l(t,n,i),!0}return!1}function ee(t){return"CANVAS"===t.nodeName.toUpperCase()}var ne=/([&<>"'])/g,ie={"&":"&","<":"<",">":">",'"':""","'":"'"};function re(t){return null==t?"":(t+"").replace(ne,(function(t,e){return ie[e]}))}var oe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ae=[],se=r.browser.firefox&&+r.browser.version.split(".")[0]<39;function le(t,e,n,i){return n=n||{},i?ue(t,e,n):se&&null!=e.layerX&&e.layerX!==e.offsetX?(n.zrX=e.layerX,n.zrY=e.layerY):null!=e.offsetX?(n.zrX=e.offsetX,n.zrY=e.offsetY):ue(t,e,n),n}function ue(t,e,n){if(r.domSupported&&t.getBoundingClientRect){var i=e.clientX,o=e.clientY;if(ee(t)){var a=t.getBoundingClientRect();return n.zrX=i-a.left,void(n.zrY=o-a.top)}if(te(ae,t,i,o))return n.zrX=ae[0],void(n.zrY=ae[1])}n.zrX=n.zrY=0}function he(t){return t||window.event}function ce(t,e,n){if(null!=(e=he(e)).zrX)return e;var i=e.type;if(i&&i.indexOf("touch")>=0){var r="touchend"!==i?e.targetTouches[0]:e.changedTouches[0];r&&le(t,r,e,n)}else{le(t,e,e,n);var o=function(t){var e=t.wheelDelta;if(e)return e;var n=t.deltaX,i=t.deltaY;if(null==n||null==i)return e;return 3*(0!==i?Math.abs(i):Math.abs(n))*(i>0?-1:i<0?1:n>0?-1:1)}(e);e.zrDelta=o?o/120:-(e.detail||0)/3}var a=e.button;return null==e.which&&void 0!==a&&oe.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function pe(t,e,n,i){t.addEventListener(e,n,i)}var de=function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0};function fe(t){return 2===t.which||3===t.which}var ge=function(){function t(){this._track=[]}return t.prototype.recognize=function(t,e,n){return this._doTrack(t,e,n),this._recognize(t)},t.prototype.clear=function(){return this._track.length=0,this},t.prototype._doTrack=function(t,e,n){var i=t.touches;if(i){for(var r={points:[],touches:[],target:e,event:t},o=0,a=i.length;o1&&r&&r.length>1){var a=ye(r)/ye(o);!isFinite(a)&&(a=1),e.pinchScale=a;var s=[((i=r)[0][0]+i[1][0])/2,(i[0][1]+i[1][1])/2];return e.pinchX=s[0],e.pinchY=s[1],{type:"pinch",target:t[0].target,event:e}}}}};function me(){return[1,0,0,1,0,0]}function xe(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function _e(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function be(t,e,n){var i=e[0]*n[0]+e[2]*n[1],r=e[1]*n[0]+e[3]*n[1],o=e[0]*n[2]+e[2]*n[3],a=e[1]*n[2]+e[3]*n[3],s=e[0]*n[4]+e[2]*n[5]+e[4],l=e[1]*n[4]+e[3]*n[5]+e[5];return t[0]=i,t[1]=r,t[2]=o,t[3]=a,t[4]=s,t[5]=l,t}function we(t,e,n){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+n[0],t[5]=e[5]+n[1],t}function Se(t,e,n,i){void 0===i&&(i=[0,0]);var r=e[0],o=e[2],a=e[4],s=e[1],l=e[3],u=e[5],h=Math.sin(n),c=Math.cos(n);return t[0]=r*c+s*h,t[1]=-r*h+s*c,t[2]=o*c+l*h,t[3]=-o*h+c*l,t[4]=c*(a-i[0])+h*(u-i[1])+i[0],t[5]=c*(u-i[1])-h*(a-i[0])+i[1],t}function Me(t,e,n){var i=n[0],r=n[1];return t[0]=e[0]*i,t[1]=e[1]*r,t[2]=e[2]*i,t[3]=e[3]*r,t[4]=e[4]*i,t[5]=e[5]*r,t}function Ie(t,e){var n=e[0],i=e[2],r=e[4],o=e[1],a=e[3],s=e[5],l=n*a-o*i;return l?(l=1/l,t[0]=a*l,t[1]=-o*l,t[2]=-i*l,t[3]=n*l,t[4]=(i*s-a*r)*l,t[5]=(o*r-n*s)*l,t):null}function Te(t){var e=[1,0,0,1,0,0];return _e(e,t),e}var Ce=Object.freeze({__proto__:null,create:me,identity:xe,copy:_e,mul:be,translate:we,rotate:Se,scale:Me,invert:Ie,clone:Te}),De=function(){function t(t,e){this.x=t||0,this.y=e||0}return t.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this},t.prototype.clone=function(){return new t(this.x,this.y)},t.prototype.set=function(t,e){return this.x=t,this.y=e,this},t.prototype.equal=function(t){return t.x===this.x&&t.y===this.y},t.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},t.prototype.scale=function(t){this.x*=t,this.y*=t},t.prototype.scaleAndAdd=function(t,e){this.x+=t.x*e,this.y+=t.y*e},t.prototype.sub=function(t){return this.x-=t.x,this.y-=t.y,this},t.prototype.dot=function(t){return this.x*t.x+this.y*t.y},t.prototype.len=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},t.prototype.lenSquare=function(){return this.x*this.x+this.y*this.y},t.prototype.normalize=function(){var t=this.len();return this.x/=t,this.y/=t,this},t.prototype.distance=function(t){var e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)},t.prototype.distanceSquare=function(t){var e=this.x-t.x,n=this.y-t.y;return e*e+n*n},t.prototype.negate=function(){return this.x=-this.x,this.y=-this.y,this},t.prototype.transform=function(t){if(t){var e=this.x,n=this.y;return this.x=t[0]*e+t[2]*n+t[4],this.y=t[1]*e+t[3]*n+t[5],this}},t.prototype.toArray=function(t){return t[0]=this.x,t[1]=this.y,t},t.prototype.fromArray=function(t){this.x=t[0],this.y=t[1]},t.set=function(t,e,n){t.x=e,t.y=n},t.copy=function(t,e){t.x=e.x,t.y=e.y},t.len=function(t){return Math.sqrt(t.x*t.x+t.y*t.y)},t.lenSquare=function(t){return t.x*t.x+t.y*t.y},t.dot=function(t,e){return t.x*e.x+t.y*e.y},t.add=function(t,e,n){t.x=e.x+n.x,t.y=e.y+n.y},t.sub=function(t,e,n){t.x=e.x-n.x,t.y=e.y-n.y},t.scale=function(t,e,n){t.x=e.x*n,t.y=e.y*n},t.scaleAndAdd=function(t,e,n,i){t.x=e.x+n.x*i,t.y=e.y+n.y*i},t.lerp=function(t,e,n,i){var r=1-i;t.x=r*e.x+i*n.x,t.y=r*e.y+i*n.y},t}(),Ae=Math.min,ke=Math.max,Le=new De,Pe=new De,Oe=new De,Re=new De,Ne=new De,Ee=new De,ze=function(){function t(t,e,n,i){n<0&&(t+=n,n=-n),i<0&&(e+=i,i=-i),this.x=t,this.y=e,this.width=n,this.height=i}return t.prototype.union=function(t){var e=Ae(t.x,this.x),n=Ae(t.y,this.y);isFinite(this.x)&&isFinite(this.width)?this.width=ke(t.x+t.width,this.x+this.width)-e:this.width=t.width,isFinite(this.y)&&isFinite(this.height)?this.height=ke(t.y+t.height,this.y+this.height)-n:this.height=t.height,this.x=e,this.y=n},t.prototype.applyTransform=function(e){t.applyTransform(this,this,e)},t.prototype.calculateTransform=function(t){var e=this,n=t.width/e.width,i=t.height/e.height,r=[1,0,0,1,0,0];return we(r,r,[-e.x,-e.y]),Me(r,r,[n,i]),we(r,r,[t.x,t.y]),r},t.prototype.intersect=function(e,n){if(!e)return!1;e instanceof t||(e=t.create(e));var i=this,r=i.x,o=i.x+i.width,a=i.y,s=i.y+i.height,l=e.x,u=e.x+e.width,h=e.y,c=e.y+e.height,p=!(of&&(f=x,gf&&(f=_,v=n.x&&t<=n.x+n.width&&e>=n.y&&e<=n.y+n.height},t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.copy=function(e){t.copy(this,e)},t.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},t.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},t.prototype.isZero=function(){return 0===this.width||0===this.height},t.create=function(e){return new t(e.x,e.y,e.width,e.height)},t.copy=function(t,e){t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height},t.applyTransform=function(e,n,i){if(i){if(i[1]<1e-5&&i[1]>-1e-5&&i[2]<1e-5&&i[2]>-1e-5){var r=i[0],o=i[3],a=i[4],s=i[5];return e.x=n.x*r+a,e.y=n.y*o+s,e.width=n.width*r,e.height=n.height*o,e.width<0&&(e.x+=e.width,e.width=-e.width),void(e.height<0&&(e.y+=e.height,e.height=-e.height))}Le.x=Oe.x=n.x,Le.y=Re.y=n.y,Pe.x=Re.x=n.x+n.width,Pe.y=Oe.y=n.y+n.height,Le.transform(i),Re.transform(i),Pe.transform(i),Oe.transform(i),e.x=Ae(Le.x,Pe.x,Oe.x,Re.x),e.y=Ae(Le.y,Pe.y,Oe.y,Re.y);var l=ke(Le.x,Pe.x,Oe.x,Re.x),u=ke(Le.y,Pe.y,Oe.y,Re.y);e.width=l-e.x,e.height=u-e.y}else e!==n&&t.copy(e,n)},t}(),Ve="silent";function Be(){de(this.event)}var Fe=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.handler=null,e}return n(e,t),e.prototype.dispose=function(){},e.prototype.setCursor=function(){},e}(jt),Ge=function(t,e){this.x=t,this.y=e},We=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],He=new ze(0,0,0,0),Ye=function(t){function e(e,n,i,r,o){var a=t.call(this)||this;return a._hovered=new Ge(0,0),a.storage=e,a.painter=n,a.painterRoot=r,a._pointerSize=o,i=i||new Fe,a.proxy=null,a.setHandlerProxy(i),a._draggingMgr=new Zt(a),a}return n(e,t),e.prototype.setHandlerProxy=function(t){this.proxy&&this.proxy.dispose(),t&&(E(We,(function(e){t.on&&t.on(e,this[e],this)}),this),t.handler=this),this.proxy=t},e.prototype.mousemove=function(t){var e=t.zrX,n=t.zrY,i=Ze(this,e,n),r=this._hovered,o=r.target;o&&!o.__zr&&(o=(r=this.findHover(r.x,r.y)).target);var a=this._hovered=i?new Ge(e,n):this.findHover(e,n),s=a.target,l=this.proxy;l.setCursor&&l.setCursor(s?s.cursor:"default"),o&&s!==o&&this.dispatchToElement(r,"mouseout",t),this.dispatchToElement(a,"mousemove",t),s&&s!==o&&this.dispatchToElement(a,"mouseover",t)},e.prototype.mouseout=function(t){var e=t.zrEventControl;"only_globalout"!==e&&this.dispatchToElement(this._hovered,"mouseout",t),"no_globalout"!==e&&this.trigger("globalout",{type:"globalout",event:t})},e.prototype.resize=function(){this._hovered=new Ge(0,0)},e.prototype.dispatch=function(t,e){var n=this[t];n&&n.call(this,e)},e.prototype.dispose=function(){this.proxy.dispose(),this.storage=null,this.proxy=null,this.painter=null},e.prototype.setCursorStyle=function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},e.prototype.dispatchToElement=function(t,e,n){var i=(t=t||{}).target;if(!i||!i.silent){for(var r="on"+e,o=function(t,e,n){return{type:t,event:n,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:n.zrX,offsetY:n.zrY,gestureEvent:n.gestureEvent,pinchX:n.pinchX,pinchY:n.pinchY,pinchScale:n.pinchScale,wheelDelta:n.zrDelta,zrByTouch:n.zrByTouch,which:n.which,stop:Be}}(e,t,n);i&&(i[r]&&(o.cancelBubble=!!i[r].call(i,o)),i.trigger(e,o),i=i.__hostTarget?i.__hostTarget:i.parent,!o.cancelBubble););o.cancelBubble||(this.trigger(e,o),this.painter&&this.painter.eachOtherLayer&&this.painter.eachOtherLayer((function(t){"function"==typeof t[r]&&t[r].call(t,o),t.trigger&&t.trigger(e,o)})))}},e.prototype.findHover=function(t,e,n){var i=this.storage.getDisplayList(),r=new Ge(t,e);if(Ue(i,r,t,e,n),this._pointerSize&&!r.target){for(var o=[],a=this._pointerSize,s=a/2,l=new ze(t-s,e-s,a,a),u=i.length-1;u>=0;u--){var h=i[u];h===n||h.ignore||h.ignoreCoarsePointer||h.parent&&h.parent.ignoreCoarsePointer||(He.copy(h.getBoundingRect()),h.transform&&He.applyTransform(h.transform),He.intersect(l)&&o.push(h))}if(o.length)for(var c=Math.PI/12,p=2*Math.PI,d=0;d=0;o--){var a=t[o],s=void 0;if(a!==r&&!a.ignore&&(s=Xe(a,n,i))&&(!e.topTarget&&(e.topTarget=a),s!==Ve)){e.target=a;break}}}function Ze(t,e,n){var i=t.painter;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}E(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],(function(t){Ye.prototype[t]=function(e){var n,i,r=e.zrX,o=e.zrY,a=Ze(this,r,o);if("mouseup"===t&&a||(i=(n=this.findHover(r,o)).target),"mousedown"===t)this._downEl=i,this._downPoint=[e.zrX,e.zrY],this._upEl=i;else if("mouseup"===t)this._upEl=i;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||Vt(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(n,t,e)}}));function je(t,e,n,i){var r=e+1;if(r===n)return 1;if(i(t[r++],t[e])<0){for(;r=0;)r++;return r-e}function qe(t,e,n,i,r){for(i===e&&i++;i>>1])<0?l=o:s=o+1;var u=i-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=a}}function Ke(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])>0){for(s=i-r;l0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}else{for(s=r+1;ls&&(l=s);var u=a;a=r-l,l=r-u}for(a++;a>>1);o(t,e[n+h])>0?a=h+1:l=h}return l}function $e(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])<0){for(s=r+1;ls&&(l=s);var u=a;a=r-l,l=r-u}else{for(s=i-r;l=0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}for(a++;a>>1);o(t,e[n+h])<0?l=h:a=h+1}return l}function Je(t,e){var n,i,r=7,o=0,a=[];function s(s){var l=n[s],u=i[s],h=n[s+1],c=i[s+1];i[s]=u+c,s===o-3&&(n[s+1]=n[s+2],i[s+1]=i[s+2]),o--;var p=$e(t[h],t,l,u,0,e);l+=p,0!==(u-=p)&&0!==(c=Ke(t[l+u-1],t,h,c,c-1,e))&&(u<=c?function(n,i,o,s){var l=0;for(l=0;l=7||d>=7);if(f)break;g<0&&(g=0),g+=2}if((r=g)<1&&(r=1),1===i){for(l=0;l=0;l--)t[d+l]=t[p+l];return void(t[c]=a[h])}var f=r;for(;;){var g=0,y=0,v=!1;do{if(e(a[h],t[u])<0){if(t[c--]=t[u--],g++,y=0,0==--i){v=!0;break}}else if(t[c--]=a[h--],y++,g=0,1==--s){v=!0;break}}while((g|y)=0;l--)t[d+l]=t[p+l];if(0===i){v=!0;break}}if(t[c--]=a[h--],1==--s){v=!0;break}if(0!==(y=s-Ke(t[u],a,0,s,s-1,e))){for(s-=y,d=(c-=y)+1,p=(h-=y)+1,l=0;l=7||y>=7);if(v)break;f<0&&(f=0),f+=2}(r=f)<1&&(r=1);if(1===s){for(d=(c-=i)+1,p=(u-=i)+1,l=i-1;l>=0;l--)t[d+l]=t[p+l];t[c]=a[h]}else{if(0===s)throw new Error;for(p=c-(s-1),l=0;l1;){var t=o-2;if(t>=1&&i[t-1]<=i[t]+i[t+1]||t>=2&&i[t-2]<=i[t]+i[t-1])i[t-1]i[t+1])break;s(t)}},forceMergeRuns:function(){for(;o>1;){var t=o-2;t>0&&i[t-1]=32;)e|=1&t,t>>=1;return t+e}(r);do{if((o=je(t,n,i,e))s&&(l=s),qe(t,n,n+l,n+o,e),o=l}a.pushRun(n,o),a.mergeRuns(),r-=o,n+=o}while(0!==r);a.forceMergeRuns()}}}var tn=!1;function en(){tn||(tn=!0,console.warn("z / z2 / zlevel of displayable is invalid, which may cause unexpected errors"))}function nn(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}var rn=function(){function t(){this._roots=[],this._displayList=[],this._displayListLen=0,this.displayableSortFunc=nn}return t.prototype.traverse=function(t,e){for(var n=0;n0&&(u.__clipPaths=[]),isNaN(u.z)&&(en(),u.z=0),isNaN(u.z2)&&(en(),u.z2=0),isNaN(u.zlevel)&&(en(),u.zlevel=0),this._displayList[this._displayListLen++]=u}var h=t.getDecalElement&&t.getDecalElement();h&&this._updateAndAddDisplayable(h,e,n);var c=t.getTextGuideLine();c&&this._updateAndAddDisplayable(c,e,n);var p=t.getTextContent();p&&this._updateAndAddDisplayable(p,e,n)}},t.prototype.addRoot=function(t){t.__zr&&t.__zr.storage===this||this._roots.push(t)},t.prototype.delRoot=function(t){if(t instanceof Array)for(var e=0,n=t.length;e=0&&this._roots.splice(i,1)}},t.prototype.delAllRoots=function(){this._roots=[],this._displayList=[],this._displayListLen=0},t.prototype.getRoots=function(){return this._roots},t.prototype.dispose=function(){this._displayList=null,this._roots=null},t}(),on=r.hasGlobalWindow&&(window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.msRequestAnimationFrame&&window.msRequestAnimationFrame.bind(window)||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame)||function(t){return setTimeout(t,16)},an={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,n=.1,i=.4;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=i*Math.asin(1/n)/(2*Math.PI),(t*=2)<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-an.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*an.bounceIn(2*t):.5*an.bounceOut(2*t-1)+.5}},sn=Math.pow,ln=Math.sqrt,un=1e-8,hn=1e-4,cn=ln(3),pn=1/3,dn=Mt(),fn=Mt(),gn=Mt();function yn(t){return t>-1e-8&&tun||t<-1e-8}function mn(t,e,n,i,r){var o=1-r;return o*o*(o*t+3*r*e)+r*r*(r*i+3*o*n)}function xn(t,e,n,i,r){var o=1-r;return 3*(((e-t)*o+2*(n-e)*r)*o+(i-n)*r*r)}function _n(t,e,n,i,r,o){var a=i+3*(e-n)-t,s=3*(n-2*e+t),l=3*(e-t),u=t-r,h=s*s-3*a*l,c=s*l-9*a*u,p=l*l-3*s*u,d=0;if(yn(h)&&yn(c)){if(yn(s))o[0]=0;else(M=-l/s)>=0&&M<=1&&(o[d++]=M)}else{var f=c*c-4*h*p;if(yn(f)){var g=c/h,y=-g/2;(M=-s/a+g)>=0&&M<=1&&(o[d++]=M),y>=0&&y<=1&&(o[d++]=y)}else if(f>0){var v=ln(f),m=h*s+1.5*a*(-c+v),x=h*s+1.5*a*(-c-v);(M=(-s-((m=m<0?-sn(-m,pn):sn(m,pn))+(x=x<0?-sn(-x,pn):sn(x,pn))))/(3*a))>=0&&M<=1&&(o[d++]=M)}else{var _=(2*h*s-3*a*c)/(2*ln(h*h*h)),b=Math.acos(_)/3,w=ln(h),S=Math.cos(b),M=(-s-2*w*S)/(3*a),I=(y=(-s+w*(S+cn*Math.sin(b)))/(3*a),(-s+w*(S-cn*Math.sin(b)))/(3*a));M>=0&&M<=1&&(o[d++]=M),y>=0&&y<=1&&(o[d++]=y),I>=0&&I<=1&&(o[d++]=I)}}return d}function bn(t,e,n,i,r){var o=6*n-12*e+6*t,a=9*e+3*i-3*t-9*n,s=3*e-3*t,l=0;if(yn(a)){if(vn(o))(h=-s/o)>=0&&h<=1&&(r[l++]=h)}else{var u=o*o-4*a*s;if(yn(u))r[0]=-o/(2*a);else if(u>0){var h,c=ln(u),p=(-o-c)/(2*a);(h=(-o+c)/(2*a))>=0&&h<=1&&(r[l++]=h),p>=0&&p<=1&&(r[l++]=p)}}return l}function wn(t,e,n,i,r,o){var a=(e-t)*r+t,s=(n-e)*r+e,l=(i-n)*r+n,u=(s-a)*r+a,h=(l-s)*r+s,c=(h-u)*r+u;o[0]=t,o[1]=a,o[2]=u,o[3]=c,o[4]=c,o[5]=h,o[6]=l,o[7]=i}function Sn(t,e,n,i,r,o,a,s,l,u,h){var c,p,d,f,g,y=.005,v=1/0;dn[0]=l,dn[1]=u;for(var m=0;m<1;m+=.05)fn[0]=mn(t,n,r,a,m),fn[1]=mn(e,i,o,s,m),(f=Ft(dn,fn))=0&&f=0&&y=1?1:_n(0,i,o,1,t,s)&&mn(0,r,a,1,s[0])}}}var On=function(){function t(t){this._inited=!1,this._startTime=0,this._pausedTime=0,this._paused=!1,this._life=t.life||1e3,this._delay=t.delay||0,this.loop=t.loop||!1,this.onframe=t.onframe||bt,this.ondestroy=t.ondestroy||bt,this.onrestart=t.onrestart||bt,t.easing&&this.setEasing(t.easing)}return t.prototype.step=function(t,e){if(this._inited||(this._startTime=t+this._delay,this._inited=!0),!this._paused){var n=this._life,i=t-this._startTime-this._pausedTime,r=i/n;r<0&&(r=0),r=Math.min(r,1);var o=this.easingFunc,a=o?o(r):r;if(this.onframe(a),1===r){if(!this.loop)return!0;var s=i%n;this._startTime=t-s,this._pausedTime=0,this.onrestart()}return!1}this._pausedTime+=e},t.prototype.pause=function(){this._paused=!0},t.prototype.resume=function(){this._paused=!1},t.prototype.setEasing=function(t){this.easing=t,this.easingFunc=X(t)?t:an[t]||Pn(t)},t}(),Rn=function(t){this.value=t},Nn=function(){function t(){this._len=0}return t.prototype.insert=function(t){var e=new Rn(t);return this.insertEntry(e),e},t.prototype.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},t.prototype.remove=function(t){var e=t.prev,n=t.next;e?e.next=n:this.head=n,n?n.prev=e:this.tail=e,t.next=t.prev=null,this._len--},t.prototype.len=function(){return this._len},t.prototype.clear=function(){this.head=this.tail=null,this._len=0},t}(),En=function(){function t(t){this._list=new Nn,this._maxSize=10,this._map={},this._maxSize=t}return t.prototype.put=function(t,e){var n=this._list,i=this._map,r=null;if(null==i[t]){var o=n.len(),a=this._lastRemovedEntry;if(o>=this._maxSize&&o>0){var s=n.head;n.remove(s),delete i[s.key],r=s.value,this._lastRemovedEntry=s}a?a.value=e:a=new Rn(e),a.key=t,n.insertEntry(a),i[t]=a}return r},t.prototype.get=function(t){var e=this._map[t],n=this._list;if(null!=e)return e!==n.tail&&(n.remove(e),n.insertEntry(e)),e.value},t.prototype.clear=function(){this._list.clear(),this._map={}},t.prototype.len=function(){return this._list.len()},t}(),zn={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};function Vn(t){return(t=Math.round(t))<0?0:t>255?255:t}function Bn(t){return t<0?0:t>1?1:t}function Fn(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?Vn(parseFloat(e)/100*255):Vn(parseInt(e,10))}function Gn(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?Bn(parseFloat(e)/100):Bn(parseFloat(e))}function Wn(t,e,n){return n<0?n+=1:n>1&&(n-=1),6*n<1?t+(e-t)*n*6:2*n<1?e:3*n<2?t+(e-t)*(2/3-n)*6:t}function Hn(t,e,n){return t+(e-t)*n}function Yn(t,e,n,i,r){return t[0]=e,t[1]=n,t[2]=i,t[3]=r,t}function Xn(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}var Un=new En(20),Zn=null;function jn(t,e){Zn&&Xn(Zn,e),Zn=Un.put(t,Zn||e.slice())}function qn(t,e){if(t){e=e||[];var n=Un.get(t);if(n)return Xn(e,n);var i=(t+="").replace(/ /g,"").toLowerCase();if(i in zn)return Xn(e,zn[i]),jn(t,e),e;var r,o=i.length;if("#"===i.charAt(0))return 4===o||5===o?(r=parseInt(i.slice(1,4),16))>=0&&r<=4095?(Yn(e,(3840&r)>>4|(3840&r)>>8,240&r|(240&r)>>4,15&r|(15&r)<<4,5===o?parseInt(i.slice(4),16)/15:1),jn(t,e),e):void Yn(e,0,0,0,1):7===o||9===o?(r=parseInt(i.slice(1,7),16))>=0&&r<=16777215?(Yn(e,(16711680&r)>>16,(65280&r)>>8,255&r,9===o?parseInt(i.slice(7),16)/255:1),jn(t,e),e):void Yn(e,0,0,0,1):void 0;var a=i.indexOf("("),s=i.indexOf(")");if(-1!==a&&s+1===o){var l=i.substr(0,a),u=i.substr(a+1,s-(a+1)).split(","),h=1;switch(l){case"rgba":if(4!==u.length)return 3===u.length?Yn(e,+u[0],+u[1],+u[2],1):Yn(e,0,0,0,1);h=Gn(u.pop());case"rgb":return u.length>=3?(Yn(e,Fn(u[0]),Fn(u[1]),Fn(u[2]),3===u.length?h:Gn(u[3])),jn(t,e),e):void Yn(e,0,0,0,1);case"hsla":return 4!==u.length?void Yn(e,0,0,0,1):(u[3]=Gn(u[3]),Kn(u,e),jn(t,e),e);case"hsl":return 3!==u.length?void Yn(e,0,0,0,1):(Kn(u,e),jn(t,e),e);default:return}}Yn(e,0,0,0,1)}}function Kn(t,e){var n=(parseFloat(t[0])%360+360)%360/360,i=Gn(t[1]),r=Gn(t[2]),o=r<=.5?r*(i+1):r+i-r*i,a=2*r-o;return Yn(e=e||[],Vn(255*Wn(a,o,n+1/3)),Vn(255*Wn(a,o,n)),Vn(255*Wn(a,o,n-1/3)),1),4===t.length&&(e[3]=t[3]),e}function $n(t,e){var n=qn(t);if(n){for(var i=0;i<3;i++)n[i]=e<0?n[i]*(1-e)|0:(255-n[i])*e+n[i]|0,n[i]>255?n[i]=255:n[i]<0&&(n[i]=0);return ri(n,4===n.length?"rgba":"rgb")}}function Jn(t,e,n){if(e&&e.length&&t>=0&&t<=1){n=n||[];var i=t*(e.length-1),r=Math.floor(i),o=Math.ceil(i),a=e[r],s=e[o],l=i-r;return n[0]=Vn(Hn(a[0],s[0],l)),n[1]=Vn(Hn(a[1],s[1],l)),n[2]=Vn(Hn(a[2],s[2],l)),n[3]=Bn(Hn(a[3],s[3],l)),n}}var Qn=Jn;function ti(t,e,n){if(e&&e.length&&t>=0&&t<=1){var i=t*(e.length-1),r=Math.floor(i),o=Math.ceil(i),a=qn(e[r]),s=qn(e[o]),l=i-r,u=ri([Vn(Hn(a[0],s[0],l)),Vn(Hn(a[1],s[1],l)),Vn(Hn(a[2],s[2],l)),Bn(Hn(a[3],s[3],l))],"rgba");return n?{color:u,leftIndex:r,rightIndex:o,value:i}:u}}var ei=ti;function ni(t,e,n,i){var r=qn(t);if(t)return r=function(t){if(t){var e,n,i=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(i,r,o),s=Math.max(i,r,o),l=s-a,u=(s+a)/2;if(0===l)e=0,n=0;else{n=u<.5?l/(s+a):l/(2-s-a);var h=((s-i)/6+l/2)/l,c=((s-r)/6+l/2)/l,p=((s-o)/6+l/2)/l;i===s?e=p-c:r===s?e=1/3+h-p:o===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var d=[360*e,n,u];return null!=t[3]&&d.push(t[3]),d}}(r),null!=e&&(r[0]=function(t){return(t=Math.round(t))<0?0:t>360?360:t}(e)),null!=n&&(r[1]=Gn(n)),null!=i&&(r[2]=Gn(i)),ri(Kn(r),"rgba")}function ii(t,e){var n=qn(t);if(n&&null!=e)return n[3]=Bn(e),ri(n,"rgba")}function ri(t,e){if(t&&t.length){var n=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(n+=","+t[3]),e+"("+n+")"}}function oi(t,e){var n=qn(t);return n?(.299*n[0]+.587*n[1]+.114*n[2])*n[3]/255+(1-n[3])*e:0}var ai=new En(100);function si(t){if(U(t)){var e=ai.get(t);return e||(e=$n(t,-.1),ai.put(t,e)),e}if(Q(t)){var n=A({},t);return n.colorStops=z(t.colorStops,(function(t){return{offset:t.offset,color:$n(t.color,-.1)}})),n}return t}var li=Object.freeze({__proto__:null,parse:qn,lift:$n,toHex:function(t){var e=qn(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)},fastLerp:Jn,fastMapToColor:Qn,lerp:ti,mapToColor:ei,modifyHSL:ni,modifyAlpha:ii,stringify:ri,lum:oi,random:function(){return ri([Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())],"rgb")},liftColor:si}),ui=Math.round;function hi(t){var e;if(t&&"transparent"!==t){if("string"==typeof t&&t.indexOf("rgba")>-1){var n=qn(t);n&&(t="rgb("+n[0]+","+n[1]+","+n[2]+")",e=n[3])}}else t="none";return{color:t,opacity:null==e?1:e}}var ci=1e-4;function pi(t){return t-1e-4}function di(t){return ui(1e3*t)/1e3}function fi(t){return ui(1e4*t)/1e4}var gi={left:"start",right:"end",center:"middle",middle:"middle"};function yi(t){return t&&!!t.image}function vi(t){return yi(t)||function(t){return t&&!!t.svgElement}(t)}function mi(t){return"linear"===t.type}function xi(t){return"radial"===t.type}function _i(t){return t&&("linear"===t.type||"radial"===t.type)}function bi(t){return"url(#"+t+")"}function wi(t){var e=t.getGlobalScale(),n=Math.max(e[0],e[1]);return Math.max(Math.ceil(Math.log(n)/Math.log(10)),1)}function Si(t){var e=t.x||0,n=t.y||0,i=(t.rotation||0)*wt,r=rt(t.scaleX,1),o=rt(t.scaleY,1),a=t.skewX||0,s=t.skewY||0,l=[];return(e||n)&&l.push("translate("+e+"px,"+n+"px)"),i&&l.push("rotate("+i+")"),1===r&&1===o||l.push("scale("+r+","+o+")"),(a||s)&&l.push("skew("+ui(a*wt)+"deg, "+ui(s*wt)+"deg)"),l.join(" ")}var Mi=r.hasGlobalWindow&&X(window.btoa)?function(t){return window.btoa(unescape(encodeURIComponent(t)))}:"undefined"!=typeof Buffer?function(t){return Buffer.from(t).toString("base64")}:function(t){return null},Ii=Array.prototype.slice;function Ti(t,e,n){return(e-t)*n+t}function Ci(t,e,n,i){for(var r=e.length,o=0;oi?e:t,o=Math.min(n,i),a=r[o-1]||{color:[0,0,0,0],offset:0},s=o;sa)i.length=a;else for(var s=o;s=1},t.prototype.getAdditiveTrack=function(){return this._additiveTrack},t.prototype.addKeyframe=function(t,e,n){this._needsSort=!0;var i=this.keyframes,r=i.length,o=!1,a=6,s=e;if(N(e)){var l=function(t){return N(t&&t[0])?2:1}(e);a=l,(1===l&&!j(e[0])||2===l&&!j(e[0][0]))&&(o=!0)}else if(j(e)&&!nt(e))a=0;else if(U(e))if(isNaN(+e)){var u=qn(e);u&&(s=u,a=3)}else a=0;else if(Q(e)){var h=A({},s);h.colorStops=z(e.colorStops,(function(t){return{offset:t.offset,color:qn(t.color)}})),mi(e)?a=4:xi(e)&&(a=5),s=h}0===r?this.valType=a:a===this.valType&&6!==a||(o=!0),this.discrete=this.discrete||o;var c={time:t,value:s,rawValue:e,percent:0};return n&&(c.easing=n,c.easingFunc=X(n)?n:an[n]||Pn(n)),i.push(c),c},t.prototype.prepare=function(t,e){var n=this.keyframes;this._needsSort&&n.sort((function(t,e){return t.time-e.time}));for(var i=this.valType,r=n.length,o=n[r-1],a=this.discrete,s=Ni(i),l=Ri(i),u=0;u=0&&!(l[n].percent<=e);n--);n=d(n,u-2)}else{for(n=p;ne);n++);n=d(n-1,u-2)}r=l[n+1],i=l[n]}if(i&&r){this._lastFr=n,this._lastFrP=e;var f=r.percent-i.percent,g=0===f?1:d((e-i.percent)/f,1);r.easingFunc&&(g=r.easingFunc(g));var y=o?this._additiveValue:c?Ei:t[h];if(!Ni(s)&&!c||y||(y=this._additiveValue=[]),this.discrete)t[h]=g<1?i.rawValue:r.rawValue;else if(Ni(s))1===s?Ci(y,i[a],r[a],g):function(t,e,n,i){for(var r=e.length,o=r&&e[0].length,a=0;a0&&s.addKeyframe(0,Pi(l),i),this._trackKeys.push(a)}s.addKeyframe(t,Pi(e[a]),i)}return this._maxTime=Math.max(this._maxTime,t),this},t.prototype.pause=function(){this._clip.pause(),this._paused=!0},t.prototype.resume=function(){this._clip.resume(),this._paused=!1},t.prototype.isPaused=function(){return!!this._paused},t.prototype.duration=function(t){return this._maxTime=t,this._force=!0,this},t.prototype._doneCallback=function(){this._setTracksFinished(),this._clip=null;var t=this._doneCbs;if(t)for(var e=t.length,n=0;n0)){this._started=1;for(var e=this,n=[],i=this._maxTime||0,r=0;r1){var a=o.pop();r.addKeyframe(a.time,t[i]),r.prepare(this._maxTime,r.getAdditiveTrack())}}}},t}();function Bi(){return(new Date).getTime()}var Fi,Gi,Wi=function(t){function e(e){var n=t.call(this)||this;return n._running=!1,n._time=0,n._pausedTime=0,n._pauseStart=0,n._paused=!1,e=e||{},n.stage=e.stage||{},n}return n(e,t),e.prototype.addClip=function(t){t.animation&&this.removeClip(t),this._head?(this._tail.next=t,t.prev=this._tail,t.next=null,this._tail=t):this._head=this._tail=t,t.animation=this},e.prototype.addAnimator=function(t){t.animation=this;var e=t.getClip();e&&this.addClip(e)},e.prototype.removeClip=function(t){if(t.animation){var e=t.prev,n=t.next;e?e.next=n:this._head=n,n?n.prev=e:this._tail=e,t.next=t.prev=t.animation=null}},e.prototype.removeAnimator=function(t){var e=t.getClip();e&&this.removeClip(e),t.animation=null},e.prototype.update=function(t){for(var e=Bi()-this._pausedTime,n=e-this._time,i=this._head;i;){var r=i.next;i.step(e,n)?(i.ondestroy(),this.removeClip(i),i=r):i=r}this._time=e,t||(this.trigger("frame",n),this.stage.update&&this.stage.update())},e.prototype._startLoop=function(){var t=this;this._running=!0,on((function e(){t._running&&(on(e),!t._paused&&t.update())}))},e.prototype.start=function(){this._running||(this._time=Bi(),this._pausedTime=0,this._startLoop())},e.prototype.stop=function(){this._running=!1},e.prototype.pause=function(){this._paused||(this._pauseStart=Bi(),this._paused=!0)},e.prototype.resume=function(){this._paused&&(this._pausedTime+=Bi()-this._pauseStart,this._paused=!1)},e.prototype.clear=function(){for(var t=this._head;t;){var e=t.next;t.prev=t.next=t.animation=null,t=e}this._head=this._tail=null},e.prototype.isFinished=function(){return null==this._head},e.prototype.animate=function(t,e){e=e||{},this.start();var n=new Vi(t,e.loop);return this.addAnimator(n),n},e}(jt),Hi=r.domSupported,Yi=(Gi={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},{mouse:Fi=["click","dblclick","mousewheel","wheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],touch:["touchstart","touchend","touchmove"],pointer:z(Fi,(function(t){var e=t.replace("mouse","pointer");return Gi.hasOwnProperty(e)?e:t}))}),Xi=["mousemove","mouseup"],Ui=["pointermove","pointerup"],Zi=!1;function ji(t){var e=t.pointerType;return"pen"===e||"touch"===e}function qi(t){t&&(t.zrByTouch=!0)}function Ki(t,e){for(var n=e,i=!1;n&&9!==n.nodeType&&!(i=n.domBelongToZr||n!==e&&n===t.painterRoot);)n=n.parentNode;return i}var $i=function(t,e){this.stopPropagation=bt,this.stopImmediatePropagation=bt,this.preventDefault=bt,this.type=e.type,this.target=this.currentTarget=t.dom,this.pointerType=e.pointerType,this.clientX=e.clientX,this.clientY=e.clientY},Ji={mousedown:function(t){t=ce(this.dom,t),this.__mayPointerCapture=[t.zrX,t.zrY],this.trigger("mousedown",t)},mousemove:function(t){t=ce(this.dom,t);var e=this.__mayPointerCapture;!e||t.zrX===e[0]&&t.zrY===e[1]||this.__togglePointerCapture(!0),this.trigger("mousemove",t)},mouseup:function(t){t=ce(this.dom,t),this.__togglePointerCapture(!1),this.trigger("mouseup",t)},mouseout:function(t){Ki(this,(t=ce(this.dom,t)).toElement||t.relatedTarget)||(this.__pointerCapturing&&(t.zrEventControl="no_globalout"),this.trigger("mouseout",t))},wheel:function(t){Zi=!0,t=ce(this.dom,t),this.trigger("mousewheel",t)},mousewheel:function(t){Zi||(t=ce(this.dom,t),this.trigger("mousewheel",t))},touchstart:function(t){qi(t=ce(this.dom,t)),this.__lastTouchMoment=new Date,this.handler.processGesture(t,"start"),Ji.mousemove.call(this,t),Ji.mousedown.call(this,t)},touchmove:function(t){qi(t=ce(this.dom,t)),this.handler.processGesture(t,"change"),Ji.mousemove.call(this,t)},touchend:function(t){qi(t=ce(this.dom,t)),this.handler.processGesture(t,"end"),Ji.mouseup.call(this,t),+new Date-+this.__lastTouchMoment<300&&Ji.click.call(this,t)},pointerdown:function(t){Ji.mousedown.call(this,t)},pointermove:function(t){ji(t)||Ji.mousemove.call(this,t)},pointerup:function(t){Ji.mouseup.call(this,t)},pointerout:function(t){ji(t)||Ji.mouseout.call(this,t)}};E(["click","dblclick","contextmenu"],(function(t){Ji[t]=function(e){e=ce(this.dom,e),this.trigger(t,e)}}));var Qi={pointermove:function(t){ji(t)||Qi.mousemove.call(this,t)},pointerup:function(t){Qi.mouseup.call(this,t)},mousemove:function(t){this.trigger("mousemove",t)},mouseup:function(t){var e=this.__pointerCapturing;this.__togglePointerCapture(!1),this.trigger("mouseup",t),e&&(t.zrEventControl="only_globalout",this.trigger("mouseout",t))}};function tr(t,e){var n=e.domHandlers;r.pointerEventsSupported?E(Yi.pointer,(function(i){nr(e,i,(function(e){n[i].call(t,e)}))})):(r.touchEventsSupported&&E(Yi.touch,(function(i){nr(e,i,(function(r){n[i].call(t,r),function(t){t.touching=!0,null!=t.touchTimer&&(clearTimeout(t.touchTimer),t.touchTimer=null),t.touchTimer=setTimeout((function(){t.touching=!1,t.touchTimer=null}),700)}(e)}))})),E(Yi.mouse,(function(i){nr(e,i,(function(r){r=he(r),e.touching||n[i].call(t,r)}))})))}function er(t,e){function n(n){nr(e,n,(function(i){i=he(i),Ki(t,i.target)||(i=function(t,e){return ce(t.dom,new $i(t,e),!0)}(t,i),e.domHandlers[n].call(t,i))}),{capture:!0})}r.pointerEventsSupported?E(Ui,n):r.touchEventsSupported||E(Xi,n)}function nr(t,e,n,i){t.mounted[e]=n,t.listenerOpts[e]=i,pe(t.domTarget,e,n,i)}function ir(t){var e,n,i,r,o=t.mounted;for(var a in o)o.hasOwnProperty(a)&&(e=t.domTarget,n=a,i=o[a],r=t.listenerOpts[a],e.removeEventListener(n,i,r));t.mounted={}}var rr=function(t,e){this.mounted={},this.listenerOpts={},this.touching=!1,this.domTarget=t,this.domHandlers=e},or=function(t){function e(e,n){var i=t.call(this)||this;return i.__pointerCapturing=!1,i.dom=e,i.painterRoot=n,i._localHandlerScope=new rr(e,Ji),Hi&&(i._globalHandlerScope=new rr(document,Qi)),tr(i,i._localHandlerScope),i}return n(e,t),e.prototype.dispose=function(){ir(this._localHandlerScope),Hi&&ir(this._globalHandlerScope)},e.prototype.setCursor=function(t){this.dom.style&&(this.dom.style.cursor=t||"default")},e.prototype.__togglePointerCapture=function(t){if(this.__mayPointerCapture=null,Hi&&+this.__pointerCapturing^+t){this.__pointerCapturing=t;var e=this._globalHandlerScope;t?er(this,e):ir(e)}},e}(jt),ar=1;r.hasGlobalWindow&&(ar=Math.max(window.devicePixelRatio||window.screen&&window.screen.deviceXDPI/window.screen.logicalXDPI||1,1));var sr=ar,lr="#333",ur="#ccc",hr=xe,cr=5e-5;function pr(t){return t>cr||t<-5e-5}var dr=[],fr=[],gr=[1,0,0,1,0,0],yr=Math.abs,vr=function(){function t(){}return t.prototype.getLocalTransform=function(e){return t.getLocalTransform(this,e)},t.prototype.setPosition=function(t){this.x=t[0],this.y=t[1]},t.prototype.setScale=function(t){this.scaleX=t[0],this.scaleY=t[1]},t.prototype.setSkew=function(t){this.skewX=t[0],this.skewY=t[1]},t.prototype.setOrigin=function(t){this.originX=t[0],this.originY=t[1]},t.prototype.needLocalTransform=function(){return pr(this.rotation)||pr(this.x)||pr(this.y)||pr(this.scaleX-1)||pr(this.scaleY-1)||pr(this.skewX)||pr(this.skewY)},t.prototype.updateTransform=function(){var t=this.parent&&this.parent.transform,e=this.needLocalTransform(),n=this.transform;e||t?(n=n||[1,0,0,1,0,0],e?this.getLocalTransform(n):hr(n),t&&(e?be(n,t,n):_e(n,t)),this.transform=n,this._resolveGlobalScaleRatio(n)):n&&(hr(n),this.invTransform=null)},t.prototype._resolveGlobalScaleRatio=function(t){var e=this.globalScaleRatio;if(null!=e&&1!==e){this.getGlobalScale(dr);var n=dr[0]<0?-1:1,i=dr[1]<0?-1:1,r=((dr[0]-n)*e+n)/dr[0]||0,o=((dr[1]-i)*e+i)/dr[1]||0;t[0]*=r,t[1]*=r,t[2]*=o,t[3]*=o}this.invTransform=this.invTransform||[1,0,0,1,0,0],Ie(this.invTransform,t)},t.prototype.getComputedTransform=function(){for(var t=this,e=[];t;)e.push(t),t=t.parent;for(;t=e.pop();)t.updateTransform();return this.transform},t.prototype.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],n=t[2]*t[2]+t[3]*t[3],i=Math.atan2(t[1],t[0]),r=Math.PI/2+i-Math.atan2(t[3],t[2]);n=Math.sqrt(n)*Math.cos(r),e=Math.sqrt(e),this.skewX=r,this.skewY=0,this.rotation=-i,this.x=+t[4],this.y=+t[5],this.scaleX=e,this.scaleY=n,this.originX=0,this.originY=0}},t.prototype.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(t.invTransform=t.invTransform||[1,0,0,1,0,0],be(fr,t.invTransform,e),e=fr);var n=this.originX,i=this.originY;(n||i)&&(gr[4]=n,gr[5]=i,be(fr,e,gr),fr[4]-=n,fr[5]-=i,e=fr),this.setLocalTransform(e)}},t.prototype.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},t.prototype.transformCoordToLocal=function(t,e){var n=[t,e],i=this.invTransform;return i&&Wt(n,n,i),n},t.prototype.transformCoordToGlobal=function(t,e){var n=[t,e],i=this.transform;return i&&Wt(n,n,i),n},t.prototype.getLineScale=function(){var t=this.transform;return t&&yr(t[0]-1)>1e-10&&yr(t[3]-1)>1e-10?Math.sqrt(yr(t[0]*t[3]-t[2]*t[1])):1},t.prototype.copyTransform=function(t){xr(this,t)},t.getLocalTransform=function(t,e){e=e||[];var n=t.originX||0,i=t.originY||0,r=t.scaleX,o=t.scaleY,a=t.anchorX,s=t.anchorY,l=t.rotation||0,u=t.x,h=t.y,c=t.skewX?Math.tan(t.skewX):0,p=t.skewY?Math.tan(-t.skewY):0;if(n||i||a||s){var d=n+a,f=i+s;e[4]=-d*r-c*f*o,e[5]=-f*o-p*d*r}else e[4]=e[5]=0;return e[0]=r,e[3]=o,e[1]=p*r,e[2]=c*o,l&&Se(e,e,l),e[4]+=n+u,e[5]+=i+h,e},t.initDefaultProps=function(){var e=t.prototype;e.scaleX=e.scaleY=e.globalScaleRatio=1,e.x=e.y=e.originX=e.originY=e.skewX=e.skewY=e.rotation=e.anchorX=e.anchorY=0}(),t}(),mr=["x","y","originX","originY","anchorX","anchorY","rotation","scaleX","scaleY","skewX","skewY"];function xr(t,e){for(var n=0;n=0?parseFloat(t)/100*e:parseFloat(t):t}function Dr(t,e,n){var i=e.position||"inside",r=null!=e.distance?e.distance:5,o=n.height,a=n.width,s=o/2,l=n.x,u=n.y,h="left",c="top";if(i instanceof Array)l+=Cr(i[0],n.width),u+=Cr(i[1],n.height),h=null,c=null;else switch(i){case"left":l-=r,u+=s,h="right",c="middle";break;case"right":l+=r+a,u+=s,c="middle";break;case"top":l+=a/2,u-=r,h="center",c="bottom";break;case"bottom":l+=a/2,u+=o+r,h="center";break;case"inside":l+=a/2,u+=s,h="center",c="middle";break;case"insideLeft":l+=r,u+=s,c="middle";break;case"insideRight":l+=a-r,u+=s,h="right",c="middle";break;case"insideTop":l+=a/2,u+=r,h="center";break;case"insideBottom":l+=a/2,u+=o-r,h="center",c="bottom";break;case"insideTopLeft":l+=r,u+=r;break;case"insideTopRight":l+=a-r,u+=r,h="right";break;case"insideBottomLeft":l+=r,u+=o-r,c="bottom";break;case"insideBottomRight":l+=a-r,u+=o-r,h="right",c="bottom"}return(t=t||{}).x=l,t.y=u,t.align=h,t.verticalAlign=c,t}var Ar="__zr_normal__",kr=mr.concat(["ignore"]),Lr=V(mr,(function(t,e){return t[e]=!0,t}),{ignore:!1}),Pr={},Or=new ze(0,0,0,0),Rr=function(){function t(t){this.id=M(),this.animators=[],this.currentStates=[],this.states={},this._init(t)}return t.prototype._init=function(t){this.attr(t)},t.prototype.drift=function(t,e,n){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this.transform;i||(i=this.transform=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.markRedraw()},t.prototype.beforeUpdate=function(){},t.prototype.afterUpdate=function(){},t.prototype.update=function(){this.updateTransform(),this.__dirty&&this.updateInnerText()},t.prototype.updateInnerText=function(t){var e=this._textContent;if(e&&(!e.ignore||t)){this.textConfig||(this.textConfig={});var n=this.textConfig,i=n.local,r=e.innerTransformable,o=void 0,a=void 0,s=!1;r.parent=i?this:null;var l=!1;if(r.copyTransform(e),null!=n.position){var u=Or;n.layoutRect?u.copy(n.layoutRect):u.copy(this.getBoundingRect()),i||u.applyTransform(this.transform),this.calculateTextPosition?this.calculateTextPosition(Pr,n,u):Dr(Pr,n,u),r.x=Pr.x,r.y=Pr.y,o=Pr.align,a=Pr.verticalAlign;var h=n.origin;if(h&&null!=n.rotation){var c=void 0,p=void 0;"center"===h?(c=.5*u.width,p=.5*u.height):(c=Cr(h[0],u.width),p=Cr(h[1],u.height)),l=!0,r.originX=-r.x+c+(i?0:u.x),r.originY=-r.y+p+(i?0:u.y)}}null!=n.rotation&&(r.rotation=n.rotation);var d=n.offset;d&&(r.x+=d[0],r.y+=d[1],l||(r.originX=-d[0],r.originY=-d[1]));var f=null==n.inside?"string"==typeof n.position&&n.position.indexOf("inside")>=0:n.inside,g=this._innerTextDefaultStyle||(this._innerTextDefaultStyle={}),y=void 0,v=void 0,m=void 0;f&&this.canBeInsideText()?(y=n.insideFill,v=n.insideStroke,null!=y&&"auto"!==y||(y=this.getInsideTextFill()),null!=v&&"auto"!==v||(v=this.getInsideTextStroke(y),m=!0)):(y=n.outsideFill,v=n.outsideStroke,null!=y&&"auto"!==y||(y=this.getOutsideFill()),null!=v&&"auto"!==v||(v=this.getOutsideStroke(y),m=!0)),(y=y||"#000")===g.fill&&v===g.stroke&&m===g.autoStroke&&o===g.align&&a===g.verticalAlign||(s=!0,g.fill=y,g.stroke=v,g.autoStroke=m,g.align=o,g.verticalAlign=a,e.setDefaultTextStyle(g)),e.__dirty|=1,s&&e.dirtyStyle(!0)}},t.prototype.canBeInsideText=function(){return!0},t.prototype.getInsideTextFill=function(){return"#fff"},t.prototype.getInsideTextStroke=function(t){return"#000"},t.prototype.getOutsideFill=function(){return this.__zr&&this.__zr.isDarkMode()?ur:lr},t.prototype.getOutsideStroke=function(t){var e=this.__zr&&this.__zr.getBackgroundColor(),n="string"==typeof e&&qn(e);n||(n=[255,255,255,1]);for(var i=n[3],r=this.__zr.isDarkMode(),o=0;o<3;o++)n[o]=n[o]*i+(r?0:255)*(1-i);return n[3]=1,ri(n,"rgba")},t.prototype.traverse=function(t,e){},t.prototype.attrKV=function(t,e){"textConfig"===t?this.setTextConfig(e):"textContent"===t?this.setTextContent(e):"clipPath"===t?this.setClipPath(e):"extra"===t?(this.extra=this.extra||{},A(this.extra,e)):this[t]=e},t.prototype.hide=function(){this.ignore=!0,this.markRedraw()},t.prototype.show=function(){this.ignore=!1,this.markRedraw()},t.prototype.attr=function(t,e){if("string"==typeof t)this.attrKV(t,e);else if(q(t))for(var n=G(t),i=0;i0},t.prototype.getState=function(t){return this.states[t]},t.prototype.ensureState=function(t){var e=this.states;return e[t]||(e[t]={}),e[t]},t.prototype.clearStates=function(t){this.useState(Ar,!1,t)},t.prototype.useState=function(t,e,n,i){var r=t===Ar;if(this.hasState()||!r){var o=this.currentStates,a=this.stateTransition;if(!(P(o,t)>=0)||!e&&1!==o.length){var s;if(this.stateProxy&&!r&&(s=this.stateProxy(t)),s||(s=this.states&&this.states[t]),s||r){r||this.saveCurrentToNormalState(s);var l=!!(s&&s.hoverLayer||i);l&&this._toggleHoverLayerFlag(!0),this._applyStateObj(t,s,this._normalState,e,!n&&!this.__inHover&&a&&a.duration>0,a);var u=this._textContent,h=this._textGuide;return u&&u.useState(t,e,n,l),h&&h.useState(t,e,n,l),r?(this.currentStates=[],this._normalState={}):e?this.currentStates.push(t):this.currentStates=[t],this._updateAnimationTargets(),this.markRedraw(),!l&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2),s}I("State "+t+" not exists.")}}},t.prototype.useStates=function(t,e,n){if(t.length){var i=[],r=this.currentStates,o=t.length,a=o===r.length;if(a)for(var s=0;s0,d);var f=this._textContent,g=this._textGuide;f&&f.useStates(t,e,c),g&&g.useStates(t,e,c),this._updateAnimationTargets(),this.currentStates=t.slice(),this.markRedraw(),!c&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2)}else this.clearStates()},t.prototype.isSilent=function(){for(var t=this.silent,e=this.parent;!t&&e;){if(e.silent){t=!0;break}e=e.parent}return t},t.prototype._updateAnimationTargets=function(){for(var t=0;t=0){var n=this.currentStates.slice();n.splice(e,1),this.useStates(n)}},t.prototype.replaceState=function(t,e,n){var i=this.currentStates.slice(),r=P(i,t),o=P(i,e)>=0;r>=0?o?i.splice(r,1):i[r]=e:n&&!o&&i.push(e),this.useStates(i)},t.prototype.toggleState=function(t,e){e?this.useState(t,!0):this.removeState(t)},t.prototype._mergeStates=function(t){for(var e,n={},i=0;i=0&&e.splice(n,1)})),this.animators.push(t),n&&n.animation.addAnimator(t),n&&n.wakeUp()},t.prototype.updateDuringAnimation=function(t){this.markRedraw()},t.prototype.stopAnimation=function(t,e){for(var n=this.animators,i=n.length,r=[],o=0;o0&&n.during&&o[0].during((function(t,e){n.during(e)}));for(var p=0;p0||r.force&&!a.length){var w,S=void 0,M=void 0,I=void 0;if(s){M={},p&&(S={});for(_=0;_=0&&(n.splice(i,0,t),this._doAdd(t))}return this},e.prototype.replace=function(t,e){var n=P(this._children,t);return n>=0&&this.replaceAt(e,n),this},e.prototype.replaceAt=function(t,e){var n=this._children,i=n[e];if(t&&t!==this&&t.parent!==this&&t!==i){n[e]=t,i.parent=null;var r=this.__zr;r&&i.removeSelfFromZr(r),this._doAdd(t)}return this},e.prototype._doAdd=function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__zr;e&&e!==t.__zr&&t.addSelfToZr(e),e&&e.refresh()},e.prototype.remove=function(t){var e=this.__zr,n=this._children,i=P(n,t);return i<0||(n.splice(i,1),t.parent=null,e&&t.removeSelfFromZr(e),e&&e.refresh()),this},e.prototype.removeAll=function(){for(var t=this._children,e=this.__zr,n=0;n0&&(this._stillFrameAccum++,this._stillFrameAccum>this._sleepAfterStill&&this.animation.stop())},t.prototype.setSleepAfterStill=function(t){this._sleepAfterStill=t},t.prototype.wakeUp=function(){this._disposed||(this.animation.start(),this._stillFrameAccum=0)},t.prototype.refreshHover=function(){this._needsRefreshHover=!0},t.prototype.refreshHoverImmediately=function(){this._disposed||(this._needsRefreshHover=!1,this.painter.refreshHover&&"canvas"===this.painter.getType()&&this.painter.refreshHover())},t.prototype.resize=function(t){this._disposed||(t=t||{},this.painter.resize(t.width,t.height),this.handler.resize())},t.prototype.clearAnimation=function(){this._disposed||this.animation.clear()},t.prototype.getWidth=function(){if(!this._disposed)return this.painter.getWidth()},t.prototype.getHeight=function(){if(!this._disposed)return this.painter.getHeight()},t.prototype.setCursorStyle=function(t){this._disposed||this.handler.setCursorStyle(t)},t.prototype.findHover=function(t,e){if(!this._disposed)return this.handler.findHover(t,e)},t.prototype.on=function(t,e,n){return this._disposed||this.handler.on(t,e,n),this},t.prototype.off=function(t,e){this._disposed||this.handler.off(t,e)},t.prototype.trigger=function(t,e){this._disposed||this.handler.trigger(t,e)},t.prototype.clear=function(){if(!this._disposed){for(var t=this.storage.getRoots(),e=0;e0){if(t<=r)return a;if(t>=o)return s}else{if(t>=r)return a;if(t<=o)return s}else{if(t===r)return a;if(t===o)return s}return(t-r)/l*u+a}function $r(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return U(t)?(n=t,n.replace(/^\s+|\s+$/g,"")).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t;var n}function Jr(t,e,n){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),n?t:+t}function Qr(t){return t.sort((function(t,e){return t-e})),t}function to(t){if(t=+t,isNaN(t))return 0;if(t>1e-14)for(var e=1,n=0;n<15;n++,e*=10)if(Math.round(t*e)/e===t)return n;return eo(t)}function eo(t){var e=t.toString().toLowerCase(),n=e.indexOf("e"),i=n>0?+e.slice(n+1):0,r=n>0?n:e.length,o=e.indexOf("."),a=o<0?0:r-1-o;return Math.max(0,a-i)}function no(t,e){var n=Math.log,i=Math.LN10,r=Math.floor(n(t[1]-t[0])/i),o=Math.round(n(Math.abs(e[1]-e[0]))/i),a=Math.min(Math.max(-r+o,0),20);return isFinite(a)?a:20}function io(t,e){var n=V(t,(function(t,e){return t+(isNaN(e)?0:e)}),0);if(0===n)return[];for(var i=Math.pow(10,e),r=z(t,(function(t){return(isNaN(t)?0:t)/n*i*100})),o=100*i,a=z(r,(function(t){return Math.floor(t)})),s=V(a,(function(t,e){return t+e}),0),l=z(r,(function(t,e){return t-a[e]}));su&&(u=l[c],h=c);++a[h],l[h]=0,++s}return z(a,(function(t){return t/i}))}function ro(t,e){var n=Math.max(to(t),to(e)),i=t+e;return n>20?i:Jr(i,n)}var oo=9007199254740991;function ao(t){var e=2*Math.PI;return(t%e+e)%e}function so(t){return t>-1e-4&&t=10&&e++,e}function po(t,e){var n=co(t),i=Math.pow(10,n),r=t/i;return t=(e?r<1.5?1:r<2.5?2:r<4?3:r<7?5:10:r<1?1:r<2?2:r<3?3:r<5?5:10)*i,n>=-20?+t.toFixed(n<0?-n:0):t}function fo(t,e){var n=(t.length-1)*e+1,i=Math.floor(n),r=+t[i-1],o=n-i;return o?r+o*(t[i]-r):r}function go(t){t.sort((function(t,e){return s(t,e,0)?-1:1}));for(var e=-1/0,n=1,i=0;i=0||r&&P(r,s)<0)){var l=n.getShallow(s,e);null!=l&&(o[t[a][0]]=l)}}return o}}var ra=ia([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),oa=function(){function t(){}return t.prototype.getAreaStyle=function(t,e){return ra(this,t,e)},t}(),aa=new En(50);function sa(t){if("string"==typeof t){var e=aa.get(t);return e&&e.image}return t}function la(t,e,n,i,r){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!n)return e;var o=aa.get(t),a={hostEl:n,cb:i,cbPayload:r};return o?!ha(e=o.image)&&o.pending.push(a):((e=h.loadImage(t,ua,ua)).__zrImageSrc=t,aa.put(t,e.__cachedImgObj={image:e,pending:[a]})),e}return t}return e}function ua(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;e=a;l++)s-=a;var u=br(n,e);return u>s&&(n="",u=0),s=t-u,r.ellipsis=n,r.ellipsisWidth=u,r.contentWidth=s,r.containerWidth=t,r}function fa(t,e,n){var i=n.containerWidth,r=n.font,o=n.contentWidth;if(!i)return t.textLine="",void(t.isTruncated=!1);var a=br(e,r);if(a<=i)return t.textLine=e,void(t.isTruncated=!1);for(var s=0;;s++){if(a<=o||s>=n.maxIterations){e+=n.ellipsis;break}var l=0===s?ga(e,o,n.ascCharWidth,n.cnCharWidth):a>0?Math.floor(e.length*o/a):0;a=br(e=e.substr(0,l),r)}""===e&&(e=n.placeholder),t.textLine=e,t.isTruncated=!0}function ga(t,e,n,i){for(var r=0,o=0,a=t.length;o0&&f+i.accumWidth>i.width&&(o=e.split("\n"),c=!0),i.accumWidth=f}else{var g=wa(e,h,i.width,i.breakAll,i.accumWidth);i.accumWidth=g.accumWidth+d,a=g.linesWidths,o=g.lines}}else o=e.split("\n");for(var y=0;y=32&&e<=591||e>=880&&e<=4351||e>=4608&&e<=5119||e>=7680&&e<=8303}(t)||!!_a[t]}function wa(t,e,n,i,r){for(var o=[],a=[],s="",l="",u=0,h=0,c=0;cn:r+h+d>n)?h?(s||l)&&(f?(s||(s=l,l="",h=u=0),o.push(s),a.push(h-u),l+=p,s="",h=u+=d):(l&&(s+=l,l="",u=0),o.push(s),a.push(h),s=p,h=d)):f?(o.push(l),a.push(u),l=p,u=d):(o.push(p),a.push(d)):(h+=d,f?(l+=p,u+=d):(l&&(s+=l,l="",u=0),s+=p))}else l&&(s+=l,h+=u),o.push(s),a.push(h),s="",l="",u=0,h=0}return o.length||s||(s=t,l="",u=0),l&&(s+=l),s&&(o.push(s),a.push(h)),1===o.length&&(h+=r),{accumWidth:h,lines:o,linesWidths:a}}var Sa="__zr_style_"+Math.round(10*Math.random()),Ma={shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,shadowColor:"#000",opacity:1,blend:"source-over"},Ia={style:{shadowBlur:!0,shadowOffsetX:!0,shadowOffsetY:!0,shadowColor:!0,opacity:!0}};Ma[Sa]=!0;var Ta=["z","z2","invisible"],Ca=["invisible"],Da=function(t){function e(e){return t.call(this,e)||this}var i;return n(e,t),e.prototype._init=function(e){for(var n=G(e),i=0;i1e-4)return s[0]=t-n,s[1]=e-i,l[0]=t+n,void(l[1]=e+i);if(Ea[0]=Ra(r)*n+t,Ea[1]=Oa(r)*i+e,za[0]=Ra(o)*n+t,za[1]=Oa(o)*i+e,u(s,Ea,za),h(l,Ea,za),(r%=Na)<0&&(r+=Na),(o%=Na)<0&&(o+=Na),r>o&&!a?o+=Na:rr&&(Va[0]=Ra(d)*n+t,Va[1]=Oa(d)*i+e,u(s,Va,s),h(l,Va,l))}var Ua={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},Za=[],ja=[],qa=[],Ka=[],$a=[],Ja=[],Qa=Math.min,ts=Math.max,es=Math.cos,ns=Math.sin,is=Math.abs,rs=Math.PI,os=2*rs,as="undefined"!=typeof Float32Array,ss=[];function ls(t){return Math.round(t/rs*1e8)/1e8%2*rs}function us(t,e){var n=ls(t[0]);n<0&&(n+=os);var i=n-t[0],r=t[1];r+=i,!e&&r-n>=os?r=n+os:e&&n-r>=os?r=n-os:!e&&n>r?r=n+(os-ls(n-r)):e&&n0&&(this._ux=is(n/sr/t)||0,this._uy=is(n/sr/e)||0)},t.prototype.setDPR=function(t){this.dpr=t},t.prototype.setContext=function(t){this._ctx=t},t.prototype.getContext=function(){return this._ctx},t.prototype.beginPath=function(){return this._ctx&&this._ctx.beginPath(),this.reset(),this},t.prototype.reset=function(){this._saveData&&(this._len=0),this._pathSegLen&&(this._pathSegLen=null,this._pathLen=0),this._version++},t.prototype.moveTo=function(t,e){return this._drawPendingPt(),this.addData(Ua.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},t.prototype.lineTo=function(t,e){var n=is(t-this._xi),i=is(e-this._yi),r=n>this._ux||i>this._uy;if(this.addData(Ua.L,t,e),this._ctx&&r&&this._ctx.lineTo(t,e),r)this._xi=t,this._yi=e,this._pendingPtDist=0;else{var o=n*n+i*i;o>this._pendingPtDist&&(this._pendingPtX=t,this._pendingPtY=e,this._pendingPtDist=o)}return this},t.prototype.bezierCurveTo=function(t,e,n,i,r,o){return this._drawPendingPt(),this.addData(Ua.C,t,e,n,i,r,o),this._ctx&&this._ctx.bezierCurveTo(t,e,n,i,r,o),this._xi=r,this._yi=o,this},t.prototype.quadraticCurveTo=function(t,e,n,i){return this._drawPendingPt(),this.addData(Ua.Q,t,e,n,i),this._ctx&&this._ctx.quadraticCurveTo(t,e,n,i),this._xi=n,this._yi=i,this},t.prototype.arc=function(t,e,n,i,r,o){this._drawPendingPt(),ss[0]=i,ss[1]=r,us(ss,o),i=ss[0];var a=(r=ss[1])-i;return this.addData(Ua.A,t,e,n,n,i,a,0,o?0:1),this._ctx&&this._ctx.arc(t,e,n,i,r,o),this._xi=es(r)*n+t,this._yi=ns(r)*n+e,this},t.prototype.arcTo=function(t,e,n,i,r){return this._drawPendingPt(),this._ctx&&this._ctx.arcTo(t,e,n,i,r),this},t.prototype.rect=function(t,e,n,i){return this._drawPendingPt(),this._ctx&&this._ctx.rect(t,e,n,i),this.addData(Ua.R,t,e,n,i),this},t.prototype.closePath=function(){this._drawPendingPt(),this.addData(Ua.Z);var t=this._ctx,e=this._x0,n=this._y0;return t&&t.closePath(),this._xi=e,this._yi=n,this},t.prototype.fill=function(t){t&&t.fill(),this.toStatic()},t.prototype.stroke=function(t){t&&t.stroke(),this.toStatic()},t.prototype.len=function(){return this._len},t.prototype.setData=function(t){var e=t.length;this.data&&this.data.length===e||!as||(this.data=new Float32Array(e));for(var n=0;nu.length&&(this._expandData(),u=this.data);for(var h=0;h0&&(this._ctx&&this._ctx.lineTo(this._pendingPtX,this._pendingPtY),this._pendingPtDist=0)},t.prototype._expandData=function(){if(!(this.data instanceof Array)){for(var t=[],e=0;e11&&(this.data=new Float32Array(t)))}},t.prototype.getBoundingRect=function(){qa[0]=qa[1]=$a[0]=$a[1]=Number.MAX_VALUE,Ka[0]=Ka[1]=Ja[0]=Ja[1]=-Number.MAX_VALUE;var t,e=this.data,n=0,i=0,r=0,o=0;for(t=0;tn||is(y)>i||c===e-1)&&(f=Math.sqrt(A*A+y*y),r=g,o=x);break;case Ua.C:var v=t[c++],m=t[c++],x=(g=t[c++],t[c++]),_=t[c++],b=t[c++];f=Mn(r,o,v,m,g,x,_,b,10),r=_,o=b;break;case Ua.Q:f=kn(r,o,v=t[c++],m=t[c++],g=t[c++],x=t[c++],10),r=g,o=x;break;case Ua.A:var w=t[c++],S=t[c++],M=t[c++],I=t[c++],T=t[c++],C=t[c++],D=C+T;c+=1,d&&(a=es(T)*M+w,s=ns(T)*I+S),f=ts(M,I)*Qa(os,Math.abs(C)),r=es(D)*M+w,o=ns(D)*I+S;break;case Ua.R:a=r=t[c++],s=o=t[c++],f=2*t[c++]+2*t[c++];break;case Ua.Z:var A=a-r;y=s-o;f=Math.sqrt(A*A+y*y),r=a,o=s}f>=0&&(l[h++]=f,u+=f)}return this._pathLen=u,u},t.prototype.rebuildPath=function(t,e){var n,i,r,o,a,s,l,u,h,c,p=this.data,d=this._ux,f=this._uy,g=this._len,y=e<1,v=0,m=0,x=0;if(!y||(this._pathSegLen||this._calculateLength(),l=this._pathSegLen,u=e*this._pathLen))t:for(var _=0;_0&&(t.lineTo(h,c),x=0),b){case Ua.M:n=r=p[_++],i=o=p[_++],t.moveTo(r,o);break;case Ua.L:a=p[_++],s=p[_++];var S=is(a-r),M=is(s-o);if(S>d||M>f){if(y){if(v+(j=l[m++])>u){var I=(u-v)/j;t.lineTo(r*(1-I)+a*I,o*(1-I)+s*I);break t}v+=j}t.lineTo(a,s),r=a,o=s,x=0}else{var T=S*S+M*M;T>x&&(h=a,c=s,x=T)}break;case Ua.C:var C=p[_++],D=p[_++],A=p[_++],k=p[_++],L=p[_++],P=p[_++];if(y){if(v+(j=l[m++])>u){wn(r,C,A,L,I=(u-v)/j,Za),wn(o,D,k,P,I,ja),t.bezierCurveTo(Za[1],ja[1],Za[2],ja[2],Za[3],ja[3]);break t}v+=j}t.bezierCurveTo(C,D,A,k,L,P),r=L,o=P;break;case Ua.Q:C=p[_++],D=p[_++],A=p[_++],k=p[_++];if(y){if(v+(j=l[m++])>u){Dn(r,C,A,I=(u-v)/j,Za),Dn(o,D,k,I,ja),t.quadraticCurveTo(Za[1],ja[1],Za[2],ja[2]);break t}v+=j}t.quadraticCurveTo(C,D,A,k),r=A,o=k;break;case Ua.A:var O=p[_++],R=p[_++],N=p[_++],E=p[_++],z=p[_++],V=p[_++],B=p[_++],F=!p[_++],G=N>E?N:E,W=is(N-E)>.001,H=z+V,Y=!1;if(y)v+(j=l[m++])>u&&(H=z+V*(u-v)/j,Y=!0),v+=j;if(W&&t.ellipse?t.ellipse(O,R,N,E,B,z,H,F):t.arc(O,R,G,z,H,F),Y)break t;w&&(n=es(z)*N+O,i=ns(z)*E+R),r=es(H)*N+O,o=ns(H)*E+R;break;case Ua.R:n=r=p[_],i=o=p[_+1],a=p[_++],s=p[_++];var X=p[_++],U=p[_++];if(y){if(v+(j=l[m++])>u){var Z=u-v;t.moveTo(a,s),t.lineTo(a+Qa(Z,X),s),(Z-=X)>0&&t.lineTo(a+X,s+Qa(Z,U)),(Z-=U)>0&&t.lineTo(a+ts(X-Z,0),s+U),(Z-=X)>0&&t.lineTo(a,s+ts(U-Z,0));break t}v+=j}t.rect(a,s,X,U);break;case Ua.Z:if(y){var j;if(v+(j=l[m++])>u){I=(u-v)/j;t.lineTo(r*(1-I)+n*I,o*(1-I)+i*I);break t}v+=j}t.closePath(),r=n,o=i}}},t.prototype.clone=function(){var e=new t,n=this.data;return e.data=n.slice?n.slice():Array.prototype.slice.call(n),e._len=this._len,e},t.CMD=Ua,t.initDefaultProps=function(){var e=t.prototype;e._saveData=!0,e._ux=0,e._uy=0,e._pendingPtDist=0,e._version=0}(),t}();function cs(t,e,n,i,r,o,a){if(0===r)return!1;var s=r,l=0;if(a>e+s&&a>i+s||at+s&&o>n+s||oe+c&&h>i+c&&h>o+c&&h>s+c||ht+c&&u>n+c&&u>r+c&&u>a+c||ue+u&&l>i+u&&l>o+u||lt+u&&s>n+u&&s>r+u||sn||h+ur&&(r+=ys);var p=Math.atan2(l,s);return p<0&&(p+=ys),p>=i&&p<=r||p+ys>=i&&p+ys<=r}function ms(t,e,n,i,r,o){if(o>e&&o>i||or?s:0}var xs=hs.CMD,_s=2*Math.PI;var bs=[-1,-1,-1],ws=[-1,-1];function Ss(t,e,n,i,r,o,a,s,l,u){if(u>e&&u>i&&u>o&&u>s||u1&&(h=void 0,h=ws[0],ws[0]=ws[1],ws[1]=h),f=mn(e,i,o,s,ws[0]),d>1&&(g=mn(e,i,o,s,ws[1]))),2===d?ve&&s>i&&s>o||s=0&&h<=1&&(r[l++]=h);else{var u=a*a-4*o*s;if(yn(u))(h=-a/(2*o))>=0&&h<=1&&(r[l++]=h);else if(u>0){var h,c=ln(u),p=(-a-c)/(2*o);(h=(-a+c)/(2*o))>=0&&h<=1&&(r[l++]=h),p>=0&&p<=1&&(r[l++]=p)}}return l}(e,i,o,s,bs);if(0===l)return 0;var u=Cn(e,i,o);if(u>=0&&u<=1){for(var h=0,c=In(e,i,o,u),p=0;pn||s<-n)return 0;var l=Math.sqrt(n*n-s*s);bs[0]=-l,bs[1]=l;var u=Math.abs(i-r);if(u<1e-4)return 0;if(u>=_s-1e-4){i=0,r=_s;var h=o?1:-1;return a>=bs[0]+t&&a<=bs[1]+t?h:0}if(i>r){var c=i;i=r,r=c}i<0&&(i+=_s,r+=_s);for(var p=0,d=0;d<2;d++){var f=bs[d];if(f+t>a){var g=Math.atan2(s,f);h=o?1:-1;g<0&&(g=_s+g),(g>=i&&g<=r||g+_s>=i&&g+_s<=r)&&(g>Math.PI/2&&g<1.5*Math.PI&&(h=-h),p+=h)}}return p}function Ts(t,e,n,i,r){for(var o,a,s,l,u=t.data,h=t.len(),c=0,p=0,d=0,f=0,g=0,y=0;y1&&(n||(c+=ms(p,d,f,g,i,r))),m&&(f=p=u[y],g=d=u[y+1]),v){case xs.M:p=f=u[y++],d=g=u[y++];break;case xs.L:if(n){if(cs(p,d,u[y],u[y+1],e,i,r))return!0}else c+=ms(p,d,u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case xs.C:if(n){if(ps(p,d,u[y++],u[y++],u[y++],u[y++],u[y],u[y+1],e,i,r))return!0}else c+=Ss(p,d,u[y++],u[y++],u[y++],u[y++],u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case xs.Q:if(n){if(ds(p,d,u[y++],u[y++],u[y],u[y+1],e,i,r))return!0}else c+=Ms(p,d,u[y++],u[y++],u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case xs.A:var x=u[y++],_=u[y++],b=u[y++],w=u[y++],S=u[y++],M=u[y++];y+=1;var I=!!(1-u[y++]);o=Math.cos(S)*b+x,a=Math.sin(S)*w+_,m?(f=o,g=a):c+=ms(p,d,o,a,i,r);var T=(i-x)*w/b+x;if(n){if(vs(x,_,w,S,S+M,I,e,T,r))return!0}else c+=Is(x,_,w,S,S+M,I,T,r);p=Math.cos(S+M)*b+x,d=Math.sin(S+M)*w+_;break;case xs.R:if(f=p=u[y++],g=d=u[y++],o=f+u[y++],a=g+u[y++],n){if(cs(f,g,o,g,e,i,r)||cs(o,g,o,a,e,i,r)||cs(o,a,f,a,e,i,r)||cs(f,a,f,g,e,i,r))return!0}else c+=ms(o,g,o,a,i,r),c+=ms(f,a,f,g,i,r);break;case xs.Z:if(n){if(cs(p,d,f,g,e,i,r))return!0}else c+=ms(p,d,f,g,i,r);p=f,d=g}}return n||(s=d,l=g,Math.abs(s-l)<1e-4)||(c+=ms(p,d,f,g,i,r)||0),0!==c}var Cs=k({fill:"#000",stroke:null,strokePercent:1,fillOpacity:1,strokeOpacity:1,lineDashOffset:0,lineWidth:1,lineCap:"butt",miterLimit:10,strokeNoScale:!1,strokeFirst:!1},Ma),Ds={style:k({fill:!0,stroke:!0,strokePercent:!0,fillOpacity:!0,strokeOpacity:!0,lineDashOffset:!0,lineWidth:!0,miterLimit:!0},Ia.style)},As=mr.concat(["invisible","culling","z","z2","zlevel","parent"]),ks=function(t){function e(e){return t.call(this,e)||this}var i;return n(e,t),e.prototype.update=function(){var n=this;t.prototype.update.call(this);var i=this.style;if(i.decal){var r=this._decalEl=this._decalEl||new e;r.buildPath===e.prototype.buildPath&&(r.buildPath=function(t){n.buildPath(t,n.shape)}),r.silent=!0;var o=r.style;for(var a in i)o[a]!==i[a]&&(o[a]=i[a]);o.fill=i.fill?i.decal:null,o.decal=null,o.shadowColor=null,i.strokeFirst&&(o.stroke=null);for(var s=0;s.5?lr:e>.2?"#eee":ur}if(t)return ur}return lr},e.prototype.getInsideTextStroke=function(t){var e=this.style.fill;if(U(e)){var n=this.__zr;if(!(!n||!n.isDarkMode())===oi(t,0)<.4)return e}},e.prototype.buildPath=function(t,e,n){},e.prototype.pathUpdated=function(){this.__dirty&=-5},e.prototype.getUpdatedPathProxy=function(t){return!this.path&&this.createPathProxy(),this.path.beginPath(),this.buildPath(this.path,this.shape,t),this.path},e.prototype.createPathProxy=function(){this.path=new hs(!1)},e.prototype.hasStroke=function(){var t=this.style,e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))},e.prototype.hasFill=function(){var t=this.style.fill;return null!=t&&"none"!==t},e.prototype.getBoundingRect=function(){var t=this._rect,e=this.style,n=!t;if(n){var i=!1;this.path||(i=!0,this.createPathProxy());var r=this.path;(i||4&this.__dirty)&&(r.beginPath(),this.buildPath(r,this.shape,!1),this.pathUpdated()),t=r.getBoundingRect()}if(this._rect=t,this.hasStroke()&&this.path&&this.path.len()>0){var o=this._rectStroke||(this._rectStroke=t.clone());if(this.__dirty||n){o.copy(t);var a=e.strokeNoScale?this.getLineScale():1,s=e.lineWidth;if(!this.hasFill()){var l=this.strokeContainThreshold;s=Math.max(s,null==l?4:l)}a>1e-10&&(o.width+=s/a,o.height+=s/a,o.x-=s/a/2,o.y-=s/a/2)}return o}return t},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect(),r=this.style;if(t=n[0],e=n[1],i.contain(t,e)){var o=this.path;if(this.hasStroke()){var a=r.lineWidth,s=r.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(this.hasFill()||(a=Math.max(a,this.strokeContainThreshold)),function(t,e,n,i){return Ts(t,e,!0,n,i)}(o,a/s,t,e)))return!0}if(this.hasFill())return function(t,e,n){return Ts(t,0,!1,e,n)}(o,t,e)}return!1},e.prototype.dirtyShape=function(){this.__dirty|=4,this._rect&&(this._rect=null),this._decalEl&&this._decalEl.dirtyShape(),this.markRedraw()},e.prototype.dirty=function(){this.dirtyStyle(),this.dirtyShape()},e.prototype.animateShape=function(t){return this.animate("shape",t)},e.prototype.updateDuringAnimation=function(t){"style"===t?this.dirtyStyle():"shape"===t?this.dirtyShape():this.markRedraw()},e.prototype.attrKV=function(e,n){"shape"===e?this.setShape(n):t.prototype.attrKV.call(this,e,n)},e.prototype.setShape=function(t,e){var n=this.shape;return n||(n=this.shape={}),"string"==typeof t?n[t]=e:A(n,t),this.dirtyShape(),this},e.prototype.shapeChanged=function(){return!!(4&this.__dirty)},e.prototype.createStyle=function(t){return mt(Cs,t)},e.prototype._innerSaveToNormal=function(e){t.prototype._innerSaveToNormal.call(this,e);var n=this._normalState;e.shape&&!n.shape&&(n.shape=A({},this.shape))},e.prototype._applyStateObj=function(e,n,i,r,o,a){t.prototype._applyStateObj.call(this,e,n,i,r,o,a);var s,l=!(n&&r);if(n&&n.shape?o?r?s=n.shape:(s=A({},i.shape),A(s,n.shape)):(s=A({},r?this.shape:i.shape),A(s,n.shape)):l&&(s=i.shape),s)if(o){this.shape=A({},this.shape);for(var u={},h=G(s),c=0;c0},e.prototype.hasFill=function(){var t=this.style.fill;return null!=t&&"none"!==t},e.prototype.createStyle=function(t){return mt(Ls,t)},e.prototype.setBoundingRect=function(t){this._rect=t},e.prototype.getBoundingRect=function(){var t=this.style;if(!this._rect){var e=t.text;null!=e?e+="":e="";var n=Sr(e,t.font,t.textAlign,t.textBaseline);if(n.x+=t.x||0,n.y+=t.y||0,this.hasStroke()){var i=t.lineWidth;n.x-=i/2,n.y-=i/2,n.width+=i,n.height+=i}this._rect=n}return this._rect},e.initDefaultProps=void(e.prototype.dirtyRectTolerance=10),e}(Da);Ps.prototype.type="tspan";var Os=k({x:0,y:0},Ma),Rs={style:k({x:!0,y:!0,width:!0,height:!0,sx:!0,sy:!0,sWidth:!0,sHeight:!0},Ia.style)};var Ns=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.createStyle=function(t){return mt(Os,t)},e.prototype._getSize=function(t){var e=this.style,n=e[t];if(null!=n)return n;var i,r=(i=e.image)&&"string"!=typeof i&&i.width&&i.height?e.image:this.__image;if(!r)return 0;var o="width"===t?"height":"width",a=e[o];return null==a?r[t]:r[t]/r[o]*a},e.prototype.getWidth=function(){return this._getSize("width")},e.prototype.getHeight=function(){return this._getSize("height")},e.prototype.getAnimationStyleProps=function(){return Rs},e.prototype.getBoundingRect=function(){var t=this.style;return this._rect||(this._rect=new ze(t.x||0,t.y||0,this.getWidth(),this.getHeight())),this._rect},e}(Da);Ns.prototype.type="image";var Es=Math.round;function zs(t,e,n){if(e){var i=e.x1,r=e.x2,o=e.y1,a=e.y2;t.x1=i,t.x2=r,t.y1=o,t.y2=a;var s=n&&n.lineWidth;return s?(Es(2*i)===Es(2*r)&&(t.x1=t.x2=Bs(i,s,!0)),Es(2*o)===Es(2*a)&&(t.y1=t.y2=Bs(o,s,!0)),t):t}}function Vs(t,e,n){if(e){var i=e.x,r=e.y,o=e.width,a=e.height;t.x=i,t.y=r,t.width=o,t.height=a;var s=n&&n.lineWidth;return s?(t.x=Bs(i,s,!0),t.y=Bs(r,s,!0),t.width=Math.max(Bs(i+o,s,!1)-t.x,0===o?0:1),t.height=Math.max(Bs(r+a,s,!1)-t.y,0===a?0:1),t):t}}function Bs(t,e,n){if(!e)return t;var i=Es(2*t);return(i+Es(e))%2==0?i/2:(i+(n?1:-1))/2}var Fs=function(){this.x=0,this.y=0,this.width=0,this.height=0},Gs={},Ws=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Fs},e.prototype.buildPath=function(t,e){var n,i,r,o;if(this.subPixelOptimize){var a=Vs(Gs,e,this.style);n=a.x,i=a.y,r=a.width,o=a.height,a.r=e.r,e=a}else n=e.x,i=e.y,r=e.width,o=e.height;e.r?function(t,e){var n,i,r,o,a,s=e.x,l=e.y,u=e.width,h=e.height,c=e.r;u<0&&(s+=u,u=-u),h<0&&(l+=h,h=-h),"number"==typeof c?n=i=r=o=c:c instanceof Array?1===c.length?n=i=r=o=c[0]:2===c.length?(n=r=c[0],i=o=c[1]):3===c.length?(n=c[0],i=o=c[1],r=c[2]):(n=c[0],i=c[1],r=c[2],o=c[3]):n=i=r=o=0,n+i>u&&(n*=u/(a=n+i),i*=u/a),r+o>u&&(r*=u/(a=r+o),o*=u/a),i+r>h&&(i*=h/(a=i+r),r*=h/a),n+o>h&&(n*=h/(a=n+o),o*=h/a),t.moveTo(s+n,l),t.lineTo(s+u-i,l),0!==i&&t.arc(s+u-i,l+i,i,-Math.PI/2,0),t.lineTo(s+u,l+h-r),0!==r&&t.arc(s+u-r,l+h-r,r,0,Math.PI/2),t.lineTo(s+o,l+h),0!==o&&t.arc(s+o,l+h-o,o,Math.PI/2,Math.PI),t.lineTo(s,l+n),0!==n&&t.arc(s+n,l+n,n,Math.PI,1.5*Math.PI)}(t,e):t.rect(n,i,r,o)},e.prototype.isZeroArea=function(){return!this.shape.width||!this.shape.height},e}(ks);Ws.prototype.type="rect";var Hs={fill:"#000"},Ys={style:k({fill:!0,stroke:!0,fillOpacity:!0,strokeOpacity:!0,lineWidth:!0,fontSize:!0,lineHeight:!0,width:!0,height:!0,textShadowColor:!0,textShadowBlur:!0,textShadowOffsetX:!0,textShadowOffsetY:!0,backgroundColor:!0,padding:!0,borderColor:!0,borderWidth:!0,borderRadius:!0},Ia.style)},Xs=function(t){function e(e){var n=t.call(this)||this;return n.type="text",n._children=[],n._defaultStyle=Hs,n.attr(e),n}return n(e,t),e.prototype.childrenRef=function(){return this._children},e.prototype.update=function(){t.prototype.update.call(this),this.styleChanged()&&this._updateSubTexts();for(var e=0;ef&&h){var g=Math.floor(f/l);c=c||n.length>g,n=n.slice(0,g)}if(t&&a&&null!=p)for(var y=da(p,o,e.ellipsis,{minChar:e.truncateMinChar,placeholder:e.placeholder}),v={},m=0;m0,T=null!=t.width&&("truncate"===t.overflow||"break"===t.overflow||"breakAll"===t.overflow),C=i.calculatedLineHeight,D=0;Dl&&xa(n,t.substring(l,u),e,s),xa(n,i[2],e,s,i[1]),l=ca.lastIndex}lo){var D=n.lines.length;w>0?(x.tokens=x.tokens.slice(0,w),v(x,b,_),n.lines=n.lines.slice(0,m+1)):n.lines=n.lines.slice(0,m),n.isTruncated=n.isTruncated||n.lines.length=0&&"right"===(C=x[T]).align;)this._placeToken(C,t,b,f,I,"right",y),w-=C.width,I-=C.width,T--;for(M+=(n-(M-d)-(g-I)-w)/2;S<=T;)C=x[S],this._placeToken(C,t,b,f,M+C.width/2,"center",y),M+=C.width,S++;f+=b}},e.prototype._placeToken=function(t,e,n,i,r,o,s){var l=e.rich[t.styleName]||{};l.text=t.text;var u=t.verticalAlign,h=i+n/2;"top"===u?h=i+t.height/2:"bottom"===u&&(h=i+n-t.height/2),!t.isLineHolder&&il(l)&&this._renderBackground(l,e,"right"===o?r-t.width:"center"===o?r-t.width/2:r,h-t.height/2,t.width,t.height);var c=!!l.backgroundColor,p=t.textPadding;p&&(r=el(r,o,p),h-=t.height/2-p[0]-t.innerHeight/2);var d=this._getOrCreateChild(Ps),f=d.createStyle();d.useStyle(f);var g=this._defaultStyle,y=!1,v=0,m=tl("fill"in l?l.fill:"fill"in e?e.fill:(y=!0,g.fill)),x=Qs("stroke"in l?l.stroke:"stroke"in e?e.stroke:c||s||g.autoStroke&&!y?null:(v=2,g.stroke)),_=l.textShadowBlur>0||e.textShadowBlur>0;f.text=t.text,f.x=r,f.y=h,_&&(f.shadowBlur=l.textShadowBlur||e.textShadowBlur||0,f.shadowColor=l.textShadowColor||e.textShadowColor||"transparent",f.shadowOffsetX=l.textShadowOffsetX||e.textShadowOffsetX||0,f.shadowOffsetY=l.textShadowOffsetY||e.textShadowOffsetY||0),f.textAlign=o,f.textBaseline="middle",f.font=t.font||a,f.opacity=ot(l.opacity,e.opacity,1),Ks(f,l),x&&(f.lineWidth=ot(l.lineWidth,e.lineWidth,v),f.lineDash=rt(l.lineDash,e.lineDash),f.lineDashOffset=e.lineDashOffset||0,f.stroke=x),m&&(f.fill=m);var b=t.contentWidth,w=t.contentHeight;d.setBoundingRect(new ze(Mr(f.x,b,f.textAlign),Ir(f.y,w,f.textBaseline),b,w))},e.prototype._renderBackground=function(t,e,n,i,r,o){var a,s,l,u=t.backgroundColor,h=t.borderWidth,c=t.borderColor,p=u&&u.image,d=u&&!p,f=t.borderRadius,g=this;if(d||t.lineHeight||h&&c){(a=this._getOrCreateChild(Ws)).useStyle(a.createStyle()),a.style.fill=null;var y=a.shape;y.x=n,y.y=i,y.width=r,y.height=o,y.r=f,a.dirtyShape()}if(d)(l=a.style).fill=u||null,l.fillOpacity=rt(t.fillOpacity,1);else if(p){(s=this._getOrCreateChild(Ns)).onload=function(){g.dirtyStyle()};var v=s.style;v.image=u.image,v.x=n,v.y=i,v.width=r,v.height=o}h&&c&&((l=a.style).lineWidth=h,l.stroke=c,l.strokeOpacity=rt(t.strokeOpacity,1),l.lineDash=t.borderDash,l.lineDashOffset=t.borderDashOffset||0,a.strokeContainThreshold=0,a.hasFill()&&a.hasStroke()&&(l.strokeFirst=!0,l.lineWidth*=2));var m=(a||s).style;m.shadowBlur=t.shadowBlur||0,m.shadowColor=t.shadowColor||"transparent",m.shadowOffsetX=t.shadowOffsetX||0,m.shadowOffsetY=t.shadowOffsetY||0,m.opacity=ot(t.opacity,e.opacity,1)},e.makeFont=function(t){var e="";return $s(t)&&(e=[t.fontStyle,t.fontWeight,qs(t.fontSize),t.fontFamily||"sans-serif"].join(" ")),e&&ut(e)||t.textFont||t.font},e}(Da),Us={left:!0,right:1,center:1},Zs={top:1,bottom:1,middle:1},js=["fontStyle","fontWeight","fontSize","fontFamily"];function qs(t){return"string"!=typeof t||-1===t.indexOf("px")&&-1===t.indexOf("rem")&&-1===t.indexOf("em")?isNaN(+t)?"12px":t+"px":t}function Ks(t,e){for(var n=0;n=0,o=!1;if(t instanceof ks){var a=ll(t),s=r&&a.selectFill||a.normalFill,l=r&&a.selectStroke||a.normalStroke;if(ml(s)||ml(l)){var u=(i=i||{}).style||{};"inherit"===u.fill?(o=!0,i=A({},i),(u=A({},u)).fill=s):!ml(u.fill)&&ml(s)?(o=!0,i=A({},i),(u=A({},u)).fill=si(s)):!ml(u.stroke)&&ml(l)&&(o||(i=A({},i),u=A({},u)),u.stroke=si(l)),i.style=u}}if(i&&null==i.z2){o||(i=A({},i));var h=t.z2EmphasisLift;i.z2=t.z2+(null!=h?h:pl)}return i}(this,0,e,n);if("blur"===t)return function(t,e,n){var i=P(t.currentStates,e)>=0,r=t.style.opacity,o=i?null:function(t,e,n,i){for(var r=t.style,o={},a=0;a0){var o={dataIndex:r,seriesIndex:t.seriesIndex};null!=i&&(o.dataType=i),e.push(o)}}))})),e}function Ul(t,e,n){Jl(t,!0),Cl(t,kl),jl(t,e,n)}function Zl(t,e,n,i){i?function(t){Jl(t,!1)}(t):Ul(t,e,n)}function jl(t,e,n){var i=rl(t);null!=e?(i.focus=e,i.blurScope=n):i.focus&&(i.focus=null)}var ql=["emphasis","blur","select"],Kl={itemStyle:"getItemStyle",lineStyle:"getLineStyle",areaStyle:"getAreaStyle"};function $l(t,e,n,i){n=n||"itemStyle";for(var r=0;r1&&(a*=su(f),s*=su(f));var g=(r===o?-1:1)*su((a*a*(s*s)-a*a*(d*d)-s*s*(p*p))/(a*a*(d*d)+s*s*(p*p)))||0,y=g*a*d/s,v=g*-s*p/a,m=(t+n)/2+uu(c)*y-lu(c)*v,x=(e+i)/2+lu(c)*y+uu(c)*v,_=du([1,0],[(p-y)/a,(d-v)/s]),b=[(p-y)/a,(d-v)/s],w=[(-1*p-y)/a,(-1*d-v)/s],S=du(b,w);if(pu(b,w)<=-1&&(S=hu),pu(b,w)>=1&&(S=0),S<0){var M=Math.round(S/hu*1e6)/1e6;S=2*hu+M%2*hu}h.addData(u,m,x,a,s,_,S,c,o)}var gu=/([mlvhzcqtsa])([^mlvhzcqtsa]*)/gi,yu=/-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;var vu=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.applyTransform=function(t){},e}(ks);function mu(t){return null!=t.setData}function xu(t,e){var n=function(t){var e=new hs;if(!t)return e;var n,i=0,r=0,o=i,a=r,s=hs.CMD,l=t.match(gu);if(!l)return e;for(var u=0;uk*k+L*L&&(M=T,I=C),{cx:M,cy:I,x0:-h,y0:-c,x1:M*(r/b-1),y1:I*(r/b-1)}}function Vu(t,e){var n,i=Ru(e.r,0),r=Ru(e.r0||0,0),o=i>0;if(o||r>0){if(o||(i=r,r=0),r>i){var a=i;i=r,r=a}var s=e.startAngle,l=e.endAngle;if(!isNaN(s)&&!isNaN(l)){var u=e.cx,h=e.cy,c=!!e.clockwise,p=Pu(l-s),d=p>Cu&&p%Cu;if(d>Eu&&(p=d),i>Eu)if(p>Cu-Eu)t.moveTo(u+i*Au(s),h+i*Du(s)),t.arc(u,h,i,s,l,!c),r>Eu&&(t.moveTo(u+r*Au(l),h+r*Du(l)),t.arc(u,h,r,l,s,c));else{var f=void 0,g=void 0,y=void 0,v=void 0,m=void 0,x=void 0,_=void 0,b=void 0,w=void 0,S=void 0,M=void 0,I=void 0,T=void 0,C=void 0,D=void 0,A=void 0,k=i*Au(s),L=i*Du(s),P=r*Au(l),O=r*Du(l),R=p>Eu;if(R){var N=e.cornerRadius;N&&(n=function(t){var e;if(Y(t)){var n=t.length;if(!n)return t;e=1===n?[t[0],t[0],0,0]:2===n?[t[0],t[0],t[1],t[1]]:3===n?t.concat(t[2]):t}else e=[t,t,t,t];return e}(N),f=n[0],g=n[1],y=n[2],v=n[3]);var E=Pu(i-r)/2;if(m=Nu(E,y),x=Nu(E,v),_=Nu(E,f),b=Nu(E,g),M=w=Ru(m,x),I=S=Ru(_,b),(w>Eu||S>Eu)&&(T=i*Au(l),C=i*Du(l),D=r*Au(s),A=r*Du(s),pEu){var X=Nu(y,M),U=Nu(v,M),Z=zu(D,A,k,L,i,X,c),j=zu(T,C,P,O,i,U,c);t.moveTo(u+Z.cx+Z.x0,h+Z.cy+Z.y0),M0&&t.arc(u+Z.cx,h+Z.cy,X,Lu(Z.y0,Z.x0),Lu(Z.y1,Z.x1),!c),t.arc(u,h,i,Lu(Z.cy+Z.y1,Z.cx+Z.x1),Lu(j.cy+j.y1,j.cx+j.x1),!c),U>0&&t.arc(u+j.cx,h+j.cy,U,Lu(j.y1,j.x1),Lu(j.y0,j.x0),!c))}else t.moveTo(u+k,h+L),t.arc(u,h,i,s,l,!c);else t.moveTo(u+k,h+L);if(r>Eu&&R)if(I>Eu){X=Nu(f,I),Z=zu(P,O,T,C,r,-(U=Nu(g,I)),c),j=zu(k,L,D,A,r,-X,c);t.lineTo(u+Z.cx+Z.x0,h+Z.cy+Z.y0),I0&&t.arc(u+Z.cx,h+Z.cy,U,Lu(Z.y0,Z.x0),Lu(Z.y1,Z.x1),!c),t.arc(u,h,r,Lu(Z.cy+Z.y1,Z.cx+Z.x1),Lu(j.cy+j.y1,j.cx+j.x1),c),X>0&&t.arc(u+j.cx,h+j.cy,X,Lu(j.y1,j.x1),Lu(j.y0,j.x0),!c))}else t.lineTo(u+P,h+O),t.arc(u,h,r,l,s,c);else t.lineTo(u+P,h+O)}else t.moveTo(u,h);t.closePath()}}}var Bu=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0,this.cornerRadius=0},Fu=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Bu},e.prototype.buildPath=function(t,e){Vu(t,e)},e.prototype.isZeroArea=function(){return this.shape.startAngle===this.shape.endAngle||this.shape.r===this.shape.r0},e}(ks);Fu.prototype.type="sector";var Gu=function(){this.cx=0,this.cy=0,this.r=0,this.r0=0},Wu=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Gu},e.prototype.buildPath=function(t,e){var n=e.cx,i=e.cy,r=2*Math.PI;t.moveTo(n+e.r,i),t.arc(n,i,e.r,0,r,!1),t.moveTo(n+e.r0,i),t.arc(n,i,e.r0,0,r,!0)},e}(ks);function Hu(t,e,n){var i=e.smooth,r=e.points;if(r&&r.length>=2){if(i){var o=function(t,e,n,i){var r,o,a,s,l=[],u=[],h=[],c=[];if(i){a=[1/0,1/0],s=[-1/0,-1/0];for(var p=0,d=t.length;plh[1]){if(a=!1,r)return a;var u=Math.abs(lh[0]-sh[1]),h=Math.abs(sh[0]-lh[1]);Math.min(u,h)>i.len()&&(u0){var c={duration:h.duration,delay:h.delay||0,easing:h.easing,done:o,force:!!o||!!a,setToFinal:!u,scope:t,during:a};l?e.animateFrom(n,c):e.animateTo(n,c)}else e.stopAnimation(),!l&&e.attr(n),a&&a(1),o&&o()}function vh(t,e,n,i,r,o){yh("update",t,e,n,i,r,o)}function mh(t,e,n,i,r,o){yh("enter",t,e,n,i,r,o)}function xh(t){if(!t.__zr)return!0;for(var e=0;eMath.abs(o[1])?o[0]>0?"right":"left":o[1]>0?"bottom":"top"}function Wh(t){return!t.isGroup}function Hh(t,e,n){if(t&&e){var i,r=(i={},t.traverse((function(t){Wh(t)&&t.anid&&(i[t.anid]=t)})),i);e.traverse((function(t){if(Wh(t)&&t.anid){var e=r[t.anid];if(e){var i=o(t);t.attr(o(e)),vh(t,i,n,rl(t).dataIndex)}}}))}function o(t){var e={x:t.x,y:t.y,rotation:t.rotation};return function(t){return null!=t.shape}(t)&&(e.shape=A({},t.shape)),e}}function Yh(t,e){return z(t,(function(t){var n=t[0];n=Mh(n,e.x),n=Ih(n,e.x+e.width);var i=t[1];return i=Mh(i,e.y),[n,i=Ih(i,e.y+e.height)]}))}function Xh(t,e){var n=Mh(t.x,e.x),i=Ih(t.x+t.width,e.x+e.width),r=Mh(t.y,e.y),o=Ih(t.y+t.height,e.y+e.height);if(i>=n&&o>=r)return{x:n,y:r,width:i-n,height:o-r}}function Uh(t,e,n){var i=A({rectHover:!0},e),r=i.style={strokeNoScale:!0};if(n=n||{x:-1,y:-1,width:2,height:2},t)return 0===t.indexOf("image://")?(r.image=t.slice(8),k(r,n),new Ns(i)):Ph(t.replace("path://",""),i,n,"center")}function Zh(t,e,n,i,r){for(var o=0,a=r[r.length-1];o=-1e-6)return!1;var f=t-r,g=e-o,y=qh(f,g,u,h)/d;if(y<0||y>1)return!1;var v=qh(f,g,c,p)/d;return!(v<0||v>1)}function qh(t,e,n,i){return t*i-n*e}function Kh(t){var e=t.itemTooltipOption,n=t.componentModel,i=t.itemName,r=U(e)?{formatter:e}:e,o=n.mainType,a=n.componentIndex,s={componentType:o,name:i,$vars:["name"]};s[o+"Index"]=a;var l=t.formatterParamsExtra;l&&E(G(l),(function(t){_t(s,t)||(s[t]=l[t],s.$vars.push(t))}));var u=rl(t.el);u.componentMainType=o,u.componentIndex=a,u.tooltipConfig={name:i,option:k({content:i,encodeHTMLContent:!0,formatterParams:s},r)}}function $h(t,e){var n;t.isGroup&&(n=e(t)),n||t.traverse(e)}function Jh(t,e){if(t)if(Y(t))for(var n=0;n-1?Lc:Oc;function zc(t,e){t=t.toUpperCase(),Nc[t]=new Cc(e),Rc[t]=e}function Vc(t){return Nc[t]}zc(Pc,{time:{month:["January","February","March","April","May","June","July","August","September","October","November","December"],monthAbbr:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayOfWeek:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayOfWeekAbbr:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},legend:{selector:{all:"All",inverse:"Inv"}},toolbox:{brush:{title:{rect:"Box Select",polygon:"Lasso Select",lineX:"Horizontally Select",lineY:"Vertically Select",keep:"Keep Selections",clear:"Clear Selections"}},dataView:{title:"Data View",lang:["Data View","Close","Refresh"]},dataZoom:{title:{zoom:"Zoom",back:"Zoom Reset"}},magicType:{title:{line:"Switch to Line Chart",bar:"Switch to Bar Chart",stack:"Stack",tiled:"Tile"}},restore:{title:"Restore"},saveAsImage:{title:"Save as Image",lang:["Right Click to Save Image"]}},series:{typeNames:{pie:"Pie chart",bar:"Bar chart",line:"Line chart",scatter:"Scatter plot",effectScatter:"Ripple scatter plot",radar:"Radar chart",tree:"Tree",treemap:"Treemap",boxplot:"Boxplot",candlestick:"Candlestick",k:"K line chart",heatmap:"Heat map",map:"Map",parallel:"Parallel coordinate map",lines:"Line graph",graph:"Relationship graph",sankey:"Sankey diagram",funnel:"Funnel chart",gauge:"Gauge",pictorialBar:"Pictorial bar",themeRiver:"Theme River Map",sunburst:"Sunburst",custom:"Custom chart",chart:"Chart"}},aria:{general:{withTitle:'This is a chart about "{title}"',withoutTitle:"This is a chart"},series:{single:{prefix:"",withName:" with type {seriesType} named {seriesName}.",withoutName:" with type {seriesType}."},multiple:{prefix:". It consists of {seriesCount} series count.",withName:" The {seriesId} series is a {seriesType} representing {seriesName}.",withoutName:" The {seriesId} series is a {seriesType}.",separator:{middle:"",end:""}}},data:{allData:"The data is as follows: ",partialData:"The first {displayCnt} items are: ",withName:"the data for {name} is {value}",withoutName:"{value}",separator:{middle:", ",end:". "}}}}),zc(Lc,{time:{month:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthAbbr:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayOfWeek:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayOfWeekAbbr:["日","一","二","三","四","五","六"]},legend:{selector:{all:"全选",inverse:"反选"}},toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图",custom:"自定义图表",chart:"图表"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}});var Bc=1e3,Fc=6e4,Gc=36e5,Wc=864e5,Hc=31536e6,Yc={year:"{yyyy}",month:"{MMM}",day:"{d}",hour:"{HH}:{mm}",minute:"{HH}:{mm}",second:"{HH}:{mm}:{ss}",millisecond:"{HH}:{mm}:{ss} {SSS}",none:"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}"},Xc="{yyyy}-{MM}-{dd}",Uc={year:"{yyyy}",month:"{yyyy}-{MM}",day:Xc,hour:Xc+" "+Yc.hour,minute:Xc+" "+Yc.minute,second:Xc+" "+Yc.second,millisecond:Yc.none},Zc=["year","month","day","hour","minute","second","millisecond"],jc=["year","half-year","quarter","month","week","half-week","day","half-day","quarter-day","hour","minute","second","millisecond"];function qc(t,e){return"0000".substr(0,e-(t+="").length)+t}function Kc(t){switch(t){case"half-year":case"quarter":return"month";case"week":case"half-week":return"day";case"half-day":case"quarter-day":return"hour";default:return t}}function $c(t){return t===Kc(t)}function Jc(t,e,n,i){var r=uo(t),o=r[ep(n)](),a=r[np(n)]()+1,s=Math.floor((a-1)/3)+1,l=r[ip(n)](),u=r["get"+(n?"UTC":"")+"Day"](),h=r[rp(n)](),c=(h-1)%12+1,p=r[op(n)](),d=r[ap(n)](),f=r[sp(n)](),g=h>=12?"pm":"am",y=g.toUpperCase(),v=(i instanceof Cc?i:Vc(i||Ec)||Nc[Oc]).getModel("time"),m=v.get("month"),x=v.get("monthAbbr"),_=v.get("dayOfWeek"),b=v.get("dayOfWeekAbbr");return(e||"").replace(/{a}/g,g+"").replace(/{A}/g,y+"").replace(/{yyyy}/g,o+"").replace(/{yy}/g,qc(o%100+"",2)).replace(/{Q}/g,s+"").replace(/{MMMM}/g,m[a-1]).replace(/{MMM}/g,x[a-1]).replace(/{MM}/g,qc(a,2)).replace(/{M}/g,a+"").replace(/{dd}/g,qc(l,2)).replace(/{d}/g,l+"").replace(/{eeee}/g,_[u]).replace(/{ee}/g,b[u]).replace(/{e}/g,u+"").replace(/{HH}/g,qc(h,2)).replace(/{H}/g,h+"").replace(/{hh}/g,qc(c+"",2)).replace(/{h}/g,c+"").replace(/{mm}/g,qc(p,2)).replace(/{m}/g,p+"").replace(/{ss}/g,qc(d,2)).replace(/{s}/g,d+"").replace(/{SSS}/g,qc(f,3)).replace(/{S}/g,f+"")}function Qc(t,e){var n=uo(t),i=n[np(e)]()+1,r=n[ip(e)](),o=n[rp(e)](),a=n[op(e)](),s=n[ap(e)](),l=0===n[sp(e)](),u=l&&0===s,h=u&&0===a,c=h&&0===o,p=c&&1===r;return p&&1===i?"year":p?"month":c?"day":h?"hour":u?"minute":l?"second":"millisecond"}function tp(t,e,n){var i=j(t)?uo(t):t;switch(e=e||Qc(t,n)){case"year":return i[ep(n)]();case"half-year":return i[np(n)]()>=6?1:0;case"quarter":return Math.floor((i[np(n)]()+1)/4);case"month":return i[np(n)]();case"day":return i[ip(n)]();case"half-day":return i[rp(n)]()/24;case"hour":return i[rp(n)]();case"minute":return i[op(n)]();case"second":return i[ap(n)]();case"millisecond":return i[sp(n)]()}}function ep(t){return t?"getUTCFullYear":"getFullYear"}function np(t){return t?"getUTCMonth":"getMonth"}function ip(t){return t?"getUTCDate":"getDate"}function rp(t){return t?"getUTCHours":"getHours"}function op(t){return t?"getUTCMinutes":"getMinutes"}function ap(t){return t?"getUTCSeconds":"getSeconds"}function sp(t){return t?"getUTCMilliseconds":"getMilliseconds"}function lp(t){return t?"setUTCFullYear":"setFullYear"}function up(t){return t?"setUTCMonth":"setMonth"}function hp(t){return t?"setUTCDate":"setDate"}function cp(t){return t?"setUTCHours":"setHours"}function pp(t){return t?"setUTCMinutes":"setMinutes"}function dp(t){return t?"setUTCSeconds":"setSeconds"}function fp(t){return t?"setUTCMilliseconds":"setMilliseconds"}function gp(t){if(!vo(t))return U(t)?t:"-";var e=(t+"").split(".");return e[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(e.length>1?"."+e[1]:"")}function yp(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,(function(t,e){return e.toUpperCase()})),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}var vp=st;function mp(t,e,n){function i(t){return t&&ut(t)?t:"-"}function r(t){return!(null==t||isNaN(t)||!isFinite(t))}var o="time"===e,a=t instanceof Date;if(o||a){var s=o?uo(t):t;if(!isNaN(+s))return Jc(s,"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}",n);if(a)return"-"}if("ordinal"===e)return Z(t)?i(t):j(t)&&r(t)?t+"":"-";var l=yo(t);return r(l)?gp(l):Z(t)?i(t):"boolean"==typeof t?t+"":"-"}var xp=["a","b","c","d","e","f","g"],_p=function(t,e){return"{"+t+(null==e?"":e)+"}"};function bp(t,e,n){Y(e)||(e=[e]);var i=e.length;if(!i)return"";for(var r=e[0].$vars||[],o=0;o':'':{renderMode:o,content:"{"+(n.markerId||"markerX")+"|} ",style:"subItem"===r?{width:4,height:4,borderRadius:2,backgroundColor:i}:{width:10,height:10,borderRadius:5,backgroundColor:i}}:""}function Sp(t,e){return e=e||"transparent",U(t)?t:q(t)&&t.colorStops&&(t.colorStops[0]||{}).color||e}function Mp(t,e){if("_blank"===e||"blank"===e){var n=window.open();n.opener=null,n.location.href=t}else window.open(t,e)}var Ip=E,Tp=["left","right","top","bottom","width","height"],Cp=[["width","left","right"],["height","top","bottom"]];function Dp(t,e,n,i,r){var o=0,a=0;null==i&&(i=1/0),null==r&&(r=1/0);var s=0;e.eachChild((function(l,u){var h,c,p=l.getBoundingRect(),d=e.childAt(u+1),f=d&&d.getBoundingRect();if("horizontal"===t){var g=p.width+(f?-f.x+p.x:0);(h=o+g)>i||l.newline?(o=0,h=g,a+=s+n,s=p.height):s=Math.max(s,p.height)}else{var y=p.height+(f?-f.y+p.y:0);(c=a+y)>r||l.newline?(o+=s+n,a=0,c=y,s=p.width):s=Math.max(s,p.width)}l.newline||(l.x=o,l.y=a,l.markRedraw(),"horizontal"===t?o=h+n:a=c+n)}))}var Ap=Dp;H(Dp,"vertical"),H(Dp,"horizontal");function kp(t,e,n){n=vp(n||0);var i=e.width,r=e.height,o=$r(t.left,i),a=$r(t.top,r),s=$r(t.right,i),l=$r(t.bottom,r),u=$r(t.width,i),h=$r(t.height,r),c=n[2]+n[0],p=n[1]+n[3],d=t.aspect;switch(isNaN(u)&&(u=i-s-p-o),isNaN(h)&&(h=r-l-c-a),null!=d&&(isNaN(u)&&isNaN(h)&&(d>i/r?u=.8*i:h=.8*r),isNaN(u)&&(u=d*h),isNaN(h)&&(h=u/d)),isNaN(o)&&(o=i-s-u-p),isNaN(a)&&(a=r-l-h-c),t.left||t.right){case"center":o=i/2-u/2-n[3];break;case"right":o=i-u-p}switch(t.top||t.bottom){case"middle":case"center":a=r/2-h/2-n[0];break;case"bottom":a=r-h-c}o=o||0,a=a||0,isNaN(u)&&(u=i-p-o-(s||0)),isNaN(h)&&(h=r-c-a-(l||0));var f=new ze(o+n[3],a+n[0],u,h);return f.margin=n,f}function Lp(t,e,n,i,r,o){var a,s=!r||!r.hv||r.hv[0],l=!r||!r.hv||r.hv[1],u=r&&r.boundingMode||"all";if((o=o||t).x=t.x,o.y=t.y,!s&&!l)return!1;if("raw"===u)a="group"===t.type?new ze(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(a=t.getBoundingRect(),t.needLocalTransform()){var h=t.getLocalTransform();(a=a.clone()).applyTransform(h)}var c=kp(k({width:a.width,height:a.height},e),n,i),p=s?c.x-a.x:0,d=l?c.y-a.y:0;return"raw"===u?(o.x=p,o.y=d):(o.x+=p,o.y+=d),o===t&&t.markRedraw(),!0}function Pp(t){var e=t.layoutMode||t.constructor.layoutMode;return q(e)?e:e?{type:e}:null}function Op(t,e,n){var i=n&&n.ignoreSize;!Y(i)&&(i=[i,i]);var r=a(Cp[0],0),o=a(Cp[1],1);function a(n,r){var o={},a=0,u={},h=0;if(Ip(n,(function(e){u[e]=t[e]})),Ip(n,(function(t){s(e,t)&&(o[t]=u[t]=e[t]),l(o,t)&&a++,l(u,t)&&h++})),i[r])return l(e,n[1])?u[n[2]]=null:l(e,n[2])&&(u[n[1]]=null),u;if(2!==h&&a){if(a>=2)return o;for(var c=0;c=0;a--)o=C(o,n[a],!0);e.defaultOption=o}return e.defaultOption},e.prototype.getReferringComponents=function(t,e){var n=t+"Index",i=t+"Id";return Yo(this.ecModel,t,{index:this.get(n,!0),id:this.get(i,!0)},e)},e.prototype.getBoxLayoutParams=function(){var t=this;return{left:t.get("left"),top:t.get("top"),right:t.get("right"),bottom:t.get("bottom"),width:t.get("width"),height:t.get("height")}},e.prototype.getZLevelKey=function(){return""},e.prototype.setZLevel=function(t){this.option.zlevel=t},e.protoInitialize=function(){var t=e.prototype;t.type="component",t.id="",t.name="",t.mainType="",t.subType="",t.componentIndex=0}(),e}(Cc);Jo(zp,Cc),na(zp),function(t){var e={};t.registerSubTypeDefaulter=function(t,n){var i=Ko(t);e[i.main]=n},t.determineSubType=function(n,i){var r=i.type;if(!r){var o=Ko(n).main;t.hasSubTypes(n)&&e[o]&&(r=e[o](i))}return r}}(zp),function(t,e){function n(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}t.topologicalTravel=function(t,i,r,o){if(t.length){var a=function(t){var i={},r=[];return E(t,(function(o){var a=n(i,o),s=function(t,e){var n=[];return E(t,(function(t){P(e,t)>=0&&n.push(t)})),n}(a.originalDeps=e(o),t);a.entryCount=s.length,0===a.entryCount&&r.push(o),E(s,(function(t){P(a.predecessor,t)<0&&a.predecessor.push(t);var e=n(i,t);P(e.successor,t)<0&&e.successor.push(o)}))})),{graph:i,noEntryList:r}}(i),s=a.graph,l=a.noEntryList,u={};for(E(t,(function(t){u[t]=!0}));l.length;){var h=l.pop(),c=s[h],p=!!u[h];p&&(r.call(o,h,c.originalDeps.slice()),delete u[h]),E(c.successor,p?f:d)}E(u,(function(){var t="";throw new Error(t)}))}function d(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}function f(t){u[t]=!0,d(t)}}}(zp,(function(t){var e=[];E(zp.getClassesByMainType(t),(function(t){e=e.concat(t.dependencies||t.prototype.dependencies||[])})),e=z(e,(function(t){return Ko(t).main})),"dataset"!==t&&P(e,"dataset")<=0&&e.unshift("dataset");return e}));var Vp="";"undefined"!=typeof navigator&&(Vp=navigator.platform||"");var Bp="rgba(0, 0, 0, 0.2)",Fp={darkMode:"auto",colorBy:"series",color:["#5470c6","#91cc75","#fac858","#ee6666","#73c0de","#3ba272","#fc8452","#9a60b4","#ea7ccc"],gradientColor:["#f6efa6","#d88273","#bf444c"],aria:{decal:{decals:[{color:Bp,dashArrayX:[1,0],dashArrayY:[2,5],symbolSize:1,rotation:Math.PI/6},{color:Bp,symbol:"circle",dashArrayX:[[8,8],[0,8,8,0]],dashArrayY:[6,0],symbolSize:.8},{color:Bp,dashArrayX:[1,0],dashArrayY:[4,3],rotation:-Math.PI/4},{color:Bp,dashArrayX:[[6,6],[0,6,6,0]],dashArrayY:[6,0]},{color:Bp,dashArrayX:[[1,0],[1,6]],dashArrayY:[1,0,6,0],rotation:Math.PI/4},{color:Bp,symbol:"triangle",dashArrayX:[[9,9],[0,9,9,0]],dashArrayY:[7,2],symbolSize:.75}]}},textStyle:{fontFamily:Vp.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,stateAnimation:{duration:300,easing:"cubicOut"},animation:"auto",animationDuration:1e3,animationDurationUpdate:500,animationEasing:"cubicInOut",animationEasingUpdate:"cubicInOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},Gp=yt(["tooltip","label","itemName","itemId","itemGroupId","itemChildGroupId","seriesName"]),Wp="original",Hp="arrayRows",Yp="objectRows",Xp="keyedColumns",Up="typedArray",Zp="unknown",jp="column",qp="row",Kp=1,$p=2,Jp=3,Qp=Vo();function td(t,e,n){var i={},r=nd(e);if(!r||!t)return i;var o,a,s=[],l=[],u=e.ecModel,h=Qp(u).datasetMap,c=r.uid+"_"+n.seriesLayoutBy;E(t=t.slice(),(function(e,n){var r=q(e)?e:t[n]={name:e};"ordinal"===r.type&&null==o&&(o=n,a=f(r)),i[r.name]=[]}));var p=h.get(c)||h.set(c,{categoryWayDim:a,valueWayDim:0});function d(t,e,n){for(var i=0;ie)return t[i];return t[n-1]}(i,a):n;if((h=h||n)&&h.length){var c=h[l];return r&&(u[r]=c),s.paletteIdx=(l+1)%h.length,c}}var fd="\0_ec_inner";var gd=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.init=function(t,e,n,i,r,o){i=i||{},this.option=null,this._theme=new Cc(i),this._locale=new Cc(r),this._optionManager=o},e.prototype.setOption=function(t,e,n){var i=md(e);this._optionManager.setOption(t,n,i),this._resetOption(null,i)},e.prototype.resetOption=function(t,e){return this._resetOption(t,md(e))},e.prototype._resetOption=function(t,e){var n=!1,i=this._optionManager;if(!t||"recreate"===t){var r=i.mountOption("recreate"===t);0,this.option&&"recreate"!==t?(this.restoreData(),this._mergeOption(r,e)):ld(this,r),n=!0}if("timeline"!==t&&"media"!==t||this.restoreData(),!t||"recreate"===t||"timeline"===t){var o=i.getTimelineOption(this);o&&(n=!0,this._mergeOption(o,e))}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this);a.length&&E(a,(function(t){n=!0,this._mergeOption(t,e)}),this)}return n},e.prototype.mergeOption=function(t){this._mergeOption(t,null)},e.prototype._mergeOption=function(t,e){var n=this.option,i=this._componentsMap,r=this._componentsCount,o=[],a=yt(),s=e&&e.replaceMergeMainTypeMap;Qp(this).datasetMap=yt(),E(t,(function(t,e){null!=t&&(zp.hasClass(e)?e&&(o.push(e),a.set(e,!0)):n[e]=null==n[e]?T(t):C(n[e],t,!0))})),s&&s.each((function(t,e){zp.hasClass(e)&&!a.get(e)&&(o.push(e),a.set(e,!0))})),zp.topologicalTravel(o,zp.getAllClassMainTypes(),(function(e){var o=function(t,e,n){var i=od.get(e);if(!i)return n;var r=i(t);return r?n.concat(r):n}(this,e,To(t[e])),a=i.get(e),l=a?s&&s.get(e)?"replaceMerge":"normalMerge":"replaceAll",u=Lo(a,o,l);(function(t,e,n){E(t,(function(t){var i=t.newOption;q(i)&&(t.keyInfo.mainType=e,t.keyInfo.subType=function(t,e,n,i){return e.type?e.type:n?n.subType:i.determineSubType(t,e)}(e,i,t.existing,n))}))})(u,e,zp),n[e]=null,i.set(e,null),r.set(e,0);var h,c=[],p=[],d=0;E(u,(function(t,n){var i=t.existing,r=t.newOption;if(r){var o="series"===e,a=zp.getClass(e,t.keyInfo.subType,!o);if(!a)return;if("tooltip"===e){if(h)return void 0;h=!0}if(i&&i.constructor===a)i.name=t.keyInfo.name,i.mergeOption(r,this),i.optionUpdated(r,!1);else{var s=A({componentIndex:n},t.keyInfo);A(i=new a(r,this,this,s),s),t.brandNew&&(i.__requireNewView=!0),i.init(r,this,this),i.optionUpdated(null,!0)}}else i&&(i.mergeOption({},this),i.optionUpdated({},!1));i?(c.push(i.option),p.push(i),d++):(c.push(void 0),p.push(void 0))}),this),n[e]=c,i.set(e,p),r.set(e,d),"series"===e&&ad(this)}),this),this._seriesIndices||ad(this)},e.prototype.getOption=function(){var t=T(this.option);return E(t,(function(e,n){if(zp.hasClass(n)){for(var i=To(e),r=i.length,o=!1,a=r-1;a>=0;a--)i[a]&&!Eo(i[a])?o=!0:(i[a]=null,!o&&r--);i.length=r,t[n]=i}})),delete t[fd],t},e.prototype.getTheme=function(){return this._theme},e.prototype.getLocaleModel=function(){return this._locale},e.prototype.setUpdatePayload=function(t){this._payload=t},e.prototype.getUpdatePayload=function(){return this._payload},e.prototype.getComponent=function(t,e){var n=this._componentsMap.get(t);if(n){var i=n[e||0];if(i)return i;if(null==e)for(var r=0;r=e:"max"===n?t<=e:t===e})(i[a],t,o)||(r=!1)}})),r}var Td=E,Cd=q,Dd=["areaStyle","lineStyle","nodeStyle","linkStyle","chordStyle","label","labelLine"];function Ad(t){var e=t&&t.itemStyle;if(e)for(var n=0,i=Dd.length;n=0;g--){var y=t[g];if(s||(p=y.data.rawIndexOf(y.stackedByDimension,c)),p>=0){var v=y.data.getByRawIndex(y.stackResultDimension,p);if("all"===l||"positive"===l&&v>0||"negative"===l&&v<0||"samesign"===l&&d>=0&&v>0||"samesign"===l&&d<=0&&v<0){d=ro(d,v),f=v;break}}}return i[0]=d,i[1]=f,i}))}))}var Zd,jd,qd,Kd,$d,Jd=function(t){this.data=t.data||(t.sourceFormat===Xp?{}:[]),this.sourceFormat=t.sourceFormat||Zp,this.seriesLayoutBy=t.seriesLayoutBy||jp,this.startIndex=t.startIndex||0,this.dimensionsDetectedCount=t.dimensionsDetectedCount,this.metaRawOption=t.metaRawOption;var e=this.dimensionsDefine=t.dimensionsDefine;if(e)for(var n=0;nu&&(u=d)}s[0]=l,s[1]=u}},i=function(){return this._data?this._data.length/this._dimSize:0};function r(t){for(var e=0;e=0&&(s=o.interpolatedValue[l])}return null!=s?s+"":""})):void 0},t.prototype.getRawValue=function(t,e){return mf(this.getData(e),t)},t.prototype.formatTooltip=function(t,e,n){},t}();function bf(t){var e,n;return q(t)?t.type&&(n=t):e=t,{text:e,frag:n}}function wf(t){return new Sf(t)}var Sf=function(){function t(t){t=t||{},this._reset=t.reset,this._plan=t.plan,this._count=t.count,this._onDirty=t.onDirty,this._dirty=!0}return t.prototype.perform=function(t){var e,n=this._upstream,i=t&&t.skip;if(this._dirty&&n){var r=this.context;r.data=r.outputData=n.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this),this._plan&&!i&&(e=this._plan(this.context));var o,a=h(this._modBy),s=this._modDataCount||0,l=h(t&&t.modBy),u=t&&t.modDataCount||0;function h(t){return!(t>=1)&&(t=1),t}a===l&&s===u||(e="reset"),(this._dirty||"reset"===e)&&(this._dirty=!1,o=this._doReset(i)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=n?n._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var p=this._dueIndex,d=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!i&&(o||p1&&i>0?s:a}};return o;function a(){return e=t?null:oe},gte:function(t,e){return t>=e}},Af=function(){function t(t,e){if(!j(e)){var n="";0,wo(n)}this._opFn=Df[t],this._rvalFloat=yo(e)}return t.prototype.evaluate=function(t){return j(t)?this._opFn(t,this._rvalFloat):this._opFn(yo(t),this._rvalFloat)},t}(),kf=function(){function t(t,e){var n="desc"===t;this._resultLT=n?1:-1,null==e&&(e=n?"min":"max"),this._incomparable="min"===e?-1/0:1/0}return t.prototype.evaluate=function(t,e){var n=j(t)?t:yo(t),i=j(e)?e:yo(e),r=isNaN(n),o=isNaN(i);if(r&&(n=this._incomparable),o&&(i=this._incomparable),r&&o){var a=U(t),s=U(e);a&&(n=s?t:0),s&&(i=a?e:0)}return ni?-this._resultLT:0},t}(),Lf=function(){function t(t,e){this._rval=e,this._isEQ=t,this._rvalTypeof=typeof e,this._rvalFloat=yo(e)}return t.prototype.evaluate=function(t){var e=t===this._rval;if(!e){var n=typeof t;n===this._rvalTypeof||"number"!==n&&"number"!==this._rvalTypeof||(e=yo(t)===this._rvalFloat)}return this._isEQ?e:!e},t}();function Pf(t,e){return"eq"===t||"ne"===t?new Lf("eq"===t,e):_t(Df,t)?new Af(t,e):null}var Of=function(){function t(){}return t.prototype.getRawData=function(){throw new Error("not supported")},t.prototype.getRawDataItem=function(t){throw new Error("not supported")},t.prototype.cloneRawData=function(){},t.prototype.getDimensionInfo=function(t){},t.prototype.cloneAllDimensionInfo=function(){},t.prototype.count=function(){},t.prototype.retrieveValue=function(t,e){},t.prototype.retrieveValueFromItem=function(t,e){},t.prototype.convertValue=function(t,e){return If(t,e)},t}();function Rf(t){var e=t.sourceFormat;if(!Ff(e)){var n="";0,wo(n)}return t.data}function Nf(t){var e=t.sourceFormat,n=t.data;if(!Ff(e)){var i="";0,wo(i)}if(e===Hp){for(var r=[],o=0,a=n.length;o65535?Hf:Yf}function qf(t,e,n,i,r){var o=Zf[n||"float"];if(r){var a=t[e],s=a&&a.length;if(s!==i){for(var l=new o(i),u=0;ug[1]&&(g[1]=f)}return this._rawCount=this._count=s,{start:a,end:s}},t.prototype._initDataFromProvider=function(t,e,n){for(var i=this._provider,r=this._chunks,o=this._dimensions,a=o.length,s=this._rawExtent,l=z(o,(function(t){return t.property})),u=0;uy[1]&&(y[1]=g)}}!i.persistent&&i.clean&&i.clean(),this._rawCount=this._count=e,this._extent=[]},t.prototype.count=function(){return this._count},t.prototype.get=function(t,e){if(!(e>=0&&e=0&&e=this._rawCount||t<0)return-1;if(!this._indices)return t;var e=this._indices,n=e[t];if(null!=n&&nt))return o;r=o-1}}return-1},t.prototype.indicesOfNearest=function(t,e,n){var i=this._chunks[t],r=[];if(!i)return r;null==n&&(n=1/0);for(var o=1/0,a=-1,s=0,l=0,u=this.count();l=0&&a<0)&&(o=c,a=h,s=0),h===a&&(r[s++]=l))}return r.length=s,r},t.prototype.getIndices=function(){var t,e=this._indices;if(e){var n=e.constructor,i=this._count;if(n===Array){t=new n(i);for(var r=0;r=u&&x<=h||isNaN(x))&&(a[s++]=d),d++}p=!0}else if(2===r){f=c[i[0]];var y=c[i[1]],v=t[i[1]][0],m=t[i[1]][1];for(g=0;g=u&&x<=h||isNaN(x))&&(_>=v&&_<=m||isNaN(_))&&(a[s++]=d),d++}p=!0}}if(!p)if(1===r)for(g=0;g=u&&x<=h||isNaN(x))&&(a[s++]=b)}else for(g=0;gt[M][1])&&(w=!1)}w&&(a[s++]=e.getRawIndex(g))}return sy[1]&&(y[1]=g)}}}},t.prototype.lttbDownSample=function(t,e){var n,i,r,o=this.clone([t],!0),a=o._chunks[t],s=this.count(),l=0,u=Math.floor(1/e),h=this.getRawIndex(0),c=new(jf(this._rawCount))(Math.min(2*(Math.ceil(s/u)+2),s));c[l++]=h;for(var p=1;pn&&(n=i,r=I)}M>0&&M<_-x&&(c[l++]=Math.min(S,r),r=Math.max(S,r)),c[l++]=r,h=r}return c[l++]=this.getRawIndex(s-1),o._count=l,o._indices=c,o.getRawIndex=this._getRawIdx,o},t.prototype.minmaxDownSample=function(t,e){for(var n=this.clone([t],!0),i=n._chunks,r=Math.floor(1/e),o=i[t],a=this.count(),s=new(jf(this._rawCount))(2*Math.ceil(a/r)),l=0,u=0;ua&&(f=a-u);for(var g=0;gd&&(d=y,p=u+g)}var v=this.getRawIndex(h),m=this.getRawIndex(p);hu-d&&(s=u-d,a.length=s);for(var f=0;fh[1]&&(h[1]=y),c[p++]=v}return r._count=p,r._indices=c,r._updateGetRawIdx(),r},t.prototype.each=function(t,e){if(this._count)for(var n=t.length,i=this._chunks,r=0,o=this.count();ra&&(a=l)}return i=[o,a],this._extent[t]=i,i},t.prototype.getRawDataItem=function(t){var e=this.getRawIndex(t);if(this._provider.persistent)return this._provider.getItem(e);for(var n=[],i=this._chunks,r=0;r=0?this._indices[t]:-1},t.prototype._updateGetRawIdx=function(){this.getRawIndex=this._indices?this._getRawIdx:this._getRawIdxIdentity},t.internalField=function(){function t(t,e,n,i){return If(t[i],this._dimensions[i])}Gf={arrayRows:t,objectRows:function(t,e,n,i){return If(t[e],this._dimensions[i])},keyedColumns:t,original:function(t,e,n,i){var r=t&&(null==t.value?t:t.value);return If(r instanceof Array?r[i]:r,this._dimensions[i])},typedArray:function(t,e,n,i){return t[i]}}}(),t}(),$f=function(){function t(t){this._sourceList=[],this._storeList=[],this._upstreamSignList=[],this._versionSignBase=0,this._dirty=!0,this._sourceHost=t}return t.prototype.dirty=function(){this._setLocalSource([],[]),this._storeList=[],this._dirty=!0},t.prototype._setLocalSource=function(t,e){this._sourceList=t,this._upstreamSignList=e,this._versionSignBase++,this._versionSignBase>9e10&&(this._versionSignBase=0)},t.prototype._getVersionSign=function(){return this._sourceHost.uid+"_"+this._versionSignBase},t.prototype.prepareSource=function(){this._isDirty()&&(this._createSource(),this._dirty=!1)},t.prototype._createSource=function(){this._setLocalSource([],[]);var t,e,n=this._sourceHost,i=this._getUpstreamSourceManagers(),r=!!i.length;if(Qf(n)){var o=n,a=void 0,s=void 0,l=void 0;if(r){var u=i[0];u.prepareSource(),a=(l=u.getSource()).data,s=l.sourceFormat,e=[u._getVersionSign()]}else s=$(a=o.get("data",!0))?Up:Wp,e=[];var h=this._getSourceMetaRawOption()||{},c=l&&l.metaRawOption||{},p=rt(h.seriesLayoutBy,c.seriesLayoutBy)||null,d=rt(h.sourceHeader,c.sourceHeader),f=rt(h.dimensions,c.dimensions);t=p!==c.seriesLayoutBy||!!d!=!!c.sourceHeader||f?[tf(a,{seriesLayoutBy:p,sourceHeader:d,dimensions:f},s)]:[]}else{var g=n;if(r){var y=this._applyTransform(i);t=y.sourceList,e=y.upstreamSignList}else{t=[tf(g.get("source",!0),this._getSourceMetaRawOption(),null)],e=[]}}this._setLocalSource(t,e)},t.prototype._applyTransform=function(t){var e,n=this._sourceHost,i=n.get("transform",!0),r=n.get("fromTransformResult",!0);if(null!=r){var o="";1!==t.length&&tg(o)}var a,s=[],l=[];return E(t,(function(t){t.prepareSource();var e=t.getSource(r||0),n="";null==r||e||tg(n),s.push(e),l.push(t._getVersionSign())})),i?e=function(t,e,n){var i=To(t),r=i.length,o="";r||wo(o);for(var a=0,s=r;a1||n>0&&!t.noHeader;return E(t.blocks,(function(t){var n=lg(t);n>=e&&(e=n+ +(i&&(!n||ag(t)&&!t.noHeader)))})),e}return 0}function ug(t,e,n,i){var r,o=e.noHeader,a=(r=lg(e),{html:ig[r],richText:rg[r]}),s=[],l=e.blocks||[];lt(!l||Y(l)),l=l||[];var u=t.orderMode;if(e.sortBlocks&&u){l=l.slice();var h={valueAsc:"asc",valueDesc:"desc"};if(_t(h,u)){var c=new kf(h[u],null);l.sort((function(t,e){return c.evaluate(t.sortParam,e.sortParam)}))}else"seriesDesc"===u&&l.reverse()}E(l,(function(n,r){var o=e.valueFormatter,l=sg(n)(o?A(A({},t),{valueFormatter:o}):t,n,r>0?a.html:0,i);null!=l&&s.push(l)}));var p="richText"===t.renderMode?s.join(a.richText):pg(i,s.join(""),o?n:a.html);if(o)return p;var d=mp(e.header,"ordinal",t.useUTC),f=ng(i,t.renderMode).nameStyle,g=eg(i);return"richText"===t.renderMode?dg(t,d,f)+a.richText+p:pg(i,'
'+re(d)+"
"+p,n)}function hg(t,e,n,i){var r=t.renderMode,o=e.noName,a=e.noValue,s=!e.markerType,l=e.name,u=t.useUTC,h=e.valueFormatter||t.valueFormatter||function(t){return z(t=Y(t)?t:[t],(function(t,e){return mp(t,Y(d)?d[e]:d,u)}))};if(!o||!a){var c=s?"":t.markupStyleCreator.makeTooltipMarker(e.markerType,e.markerColor||"#333",r),p=o?"":mp(l,"ordinal",u),d=e.valueType,f=a?[]:h(e.value,e.dataIndex),g=!s||!o,y=!s&&o,v=ng(i,r),m=v.nameStyle,x=v.valueStyle;return"richText"===r?(s?"":c)+(o?"":dg(t,p,m))+(a?"":function(t,e,n,i,r){var o=[r],a=i?10:20;return n&&o.push({padding:[0,0,0,a],align:"right"}),t.markupStyleCreator.wrapRichTextStyle(Y(e)?e.join(" "):e,o)}(t,f,g,y,x)):pg(i,(s?"":c)+(o?"":function(t,e,n){return''+re(t)+""}(p,!s,m))+(a?"":function(t,e,n,i){var r=n?"10px":"20px",o=e?"float:right;margin-left:"+r:"";return t=Y(t)?t:[t],''+z(t,(function(t){return re(t)})).join("  ")+""}(f,g,y,x)),n)}}function cg(t,e,n,i,r,o){if(t)return sg(t)({useUTC:r,renderMode:n,orderMode:i,markupStyleCreator:e,valueFormatter:t.valueFormatter},t,0,o)}function pg(t,e,n){return'
'+e+'
'}function dg(t,e,n){return t.markupStyleCreator.wrapRichTextStyle(e,n)}function fg(t,e){return Sp(t.getData().getItemVisual(e,"style")[t.visualDrawType])}function gg(t,e){var n=t.get("padding");return null!=n?n:"richText"===e?[8,10]:10}var yg=function(){function t(){this.richTextStyles={},this._nextStyleNameId=mo()}return t.prototype._generateStyleName=function(){return"__EC_aUTo_"+this._nextStyleNameId++},t.prototype.makeTooltipMarker=function(t,e,n){var i="richText"===n?this._generateStyleName():null,r=wp({color:e,type:t,renderMode:n,markerId:i});return U(r)?r:(this.richTextStyles[i]=r.style,r.content)},t.prototype.wrapRichTextStyle=function(t,e){var n={};Y(e)?E(e,(function(t){return A(n,t)})):A(n,e);var i=this._generateStyleName();return this.richTextStyles[i]=n,"{"+i+"|"+t+"}"},t}();function vg(t){var e,n,i,r,o=t.series,a=t.dataIndex,s=t.multipleSeries,l=o.getData(),u=l.mapDimensionsAll("defaultedTooltip"),h=u.length,c=o.getRawValue(a),p=Y(c),d=fg(o,a);if(h>1||p&&!h){var f=function(t,e,n,i,r){var o=e.getData(),a=V(t,(function(t,e,n){var i=o.getDimensionInfo(n);return t||i&&!1!==i.tooltip&&null!=i.displayName}),!1),s=[],l=[],u=[];function h(t,e){var n=o.getDimensionInfo(e);n&&!1!==n.otherDims.tooltip&&(a?u.push(og("nameValue",{markerType:"subItem",markerColor:r,name:n.displayName,value:t,valueType:n.type})):(s.push(t),l.push(n.type)))}return i.length?E(i,(function(t){h(mf(o,n,t),t)})):E(t,h),{inlineValues:s,inlineValueTypes:l,blocks:u}}(c,o,a,u,d);e=f.inlineValues,n=f.inlineValueTypes,i=f.blocks,r=f.inlineValues[0]}else if(h){var g=l.getDimensionInfo(u[0]);r=e=mf(l,a,u[0]),n=g.type}else r=e=p?c[0]:c;var y=No(o),v=y&&o.name||"",m=l.getName(a),x=s?v:m;return og("section",{header:v,noHeader:s||!y,sortParam:r,blocks:[og("nameValue",{markerType:"item",markerColor:d,name:x,noName:!ut(x),value:e,valueType:n,dataIndex:a})].concat(i||[])})}var mg=Vo();function xg(t,e){return t.getName(e)||t.getId(e)}var _g="__universalTransitionEnabled",bg=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._selectedDataIndicesMap={},e}return n(e,t),e.prototype.init=function(t,e,n){this.seriesIndex=this.componentIndex,this.dataTask=wf({count:Sg,reset:Mg}),this.dataTask.context={model:this},this.mergeDefaultAndTheme(t,n),(mg(this).sourceManager=new $f(this)).prepareSource();var i=this.getInitialData(t,n);Tg(i,this),this.dataTask.context.data=i,mg(this).dataBeforeProcessed=i,wg(this),this._initSelectedMapFromData(i)},e.prototype.mergeDefaultAndTheme=function(t,e){var n=Pp(this),i=n?Rp(t):{},r=this.subType;zp.hasClass(r)&&(r+="Series"),C(t,e.getTheme().get(this.subType)),C(t,this.getDefaultOption()),Co(t,"label",["show"]),this.fillDataTextStyle(t.data),n&&Op(t,i,n)},e.prototype.mergeOption=function(t,e){t=C(this.option,t,!0),this.fillDataTextStyle(t.data);var n=Pp(this);n&&Op(this.option,t,n);var i=mg(this).sourceManager;i.dirty(),i.prepareSource();var r=this.getInitialData(t,e);Tg(r,this),this.dataTask.dirty(),this.dataTask.context.data=r,mg(this).dataBeforeProcessed=r,wg(this),this._initSelectedMapFromData(r)},e.prototype.fillDataTextStyle=function(t){if(t&&!$(t))for(var e=["show"],n=0;nthis.getShallow("animationThreshold")&&(e=!1),!!e},e.prototype.restoreData=function(){this.dataTask.dirty()},e.prototype.getColorFromPalette=function(t,e,n){var i=this.ecModel,r=cd.prototype.getColorFromPalette.call(this,t,e,n);return r||(r=i.getColorFromPalette(t,e,n)),r},e.prototype.coordDimToDataDim=function(t){return this.getRawData().mapDimensionsAll(t)},e.prototype.getProgressive=function(){return this.get("progressive")},e.prototype.getProgressiveThreshold=function(){return this.get("progressiveThreshold")},e.prototype.select=function(t,e){this._innerSelect(this.getData(e),t)},e.prototype.unselect=function(t,e){var n=this.option.selectedMap;if(n){var i=this.option.selectedMode,r=this.getData(e);if("series"===i||"all"===n)return this.option.selectedMap={},void(this._selectedDataIndicesMap={});for(var o=0;o=0&&n.push(r)}return n},e.prototype.isSelected=function(t,e){var n=this.option.selectedMap;if(!n)return!1;var i=this.getData(e);return("all"===n||n[xg(i,t)])&&!i.getItemModel(t).get(["select","disabled"])},e.prototype.isUniversalTransitionEnabled=function(){if(this[_g])return!0;var t=this.option.universalTransition;return!!t&&(!0===t||t&&t.enabled)},e.prototype._innerSelect=function(t,e){var n,i,r=this.option,o=r.selectedMode,a=e.length;if(o&&a)if("series"===o)r.selectedMap="all";else if("multiple"===o){q(r.selectedMap)||(r.selectedMap={});for(var s=r.selectedMap,l=0;l0&&this._innerSelect(t,e)}},e.registerClass=function(t){return zp.registerClass(t)},e.protoInitialize=function(){var t=e.prototype;t.type="series.__base__",t.seriesIndex=0,t.ignoreStyleOnData=!1,t.hasSymbolVisual=!1,t.defaultSymbol="circle",t.visualStyleAccessPath="itemStyle",t.visualDrawType="fill"}(),e}(zp);function wg(t){var e=t.name;No(t)||(t.name=function(t){var e=t.getRawData(),n=e.mapDimensionsAll("seriesName"),i=[];return E(n,(function(t){var n=e.getDimensionInfo(t);n.displayName&&i.push(n.displayName)})),i.join(" ")}(t)||e)}function Sg(t){return t.model.getRawData().count()}function Mg(t){var e=t.model;return e.setData(e.getRawData().cloneShallow()),Ig}function Ig(t,e){e.outputData&&t.end>e.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function Tg(t,e){E(vt(t.CHANGABLE_METHODS,t.DOWNSAMPLE_METHODS),(function(n){t.wrapMethod(n,H(Cg,e))}))}function Cg(t,e){var n=Dg(t);return n&&n.setOutputEnd((e||this).count()),e}function Dg(t){var e=(t.ecModel||{}).scheduler,n=e&&e.getPipeline(t.uid);if(n){var i=n.currentTask;if(i){var r=i.agentStubMap;r&&(i=r.get(t.uid))}return i}}R(bg,_f),R(bg,cd),Jo(bg,zp);var Ag=function(){function t(){this.group=new Br,this.uid=Ac("viewComponent")}return t.prototype.init=function(t,e){},t.prototype.render=function(t,e,n,i){},t.prototype.dispose=function(t,e){},t.prototype.updateView=function(t,e,n,i){},t.prototype.updateLayout=function(t,e,n,i){},t.prototype.updateVisual=function(t,e,n,i){},t.prototype.toggleBlurSeries=function(t,e,n){},t.prototype.eachRendered=function(t){var e=this.group;e&&e.traverse(t)},t}();function kg(){var t=Vo();return function(e){var n=t(e),i=e.pipelineContext,r=!!n.large,o=!!n.progressiveRender,a=n.large=!(!i||!i.large),s=n.progressiveRender=!(!i||!i.progressiveRender);return!(r===a&&o===s)&&"reset"}}$o(Ag),na(Ag);var Lg=Vo(),Pg=kg(),Og=function(){function t(){this.group=new Br,this.uid=Ac("viewChart"),this.renderTask=wf({plan:Eg,reset:zg}),this.renderTask.context={view:this}}return t.prototype.init=function(t,e){},t.prototype.render=function(t,e,n,i){0},t.prototype.highlight=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&Ng(r,i,"emphasis")},t.prototype.downplay=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&Ng(r,i,"normal")},t.prototype.remove=function(t,e){this.group.removeAll()},t.prototype.dispose=function(t,e){},t.prototype.updateView=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.updateLayout=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.updateVisual=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.eachRendered=function(t){Jh(this.group,t)},t.markUpdateMethod=function(t,e){Lg(t).updateMethod=e},t.protoInitialize=void(t.prototype.type="chart"),t}();function Rg(t,e,n){t&&Ql(t)&&("emphasis"===e?Ol:Rl)(t,n)}function Ng(t,e,n){var i=zo(t,e),r=e&&null!=e.highlightKey?function(t){var e=sl[t];return null==e&&al<=32&&(e=sl[t]=al++),e}(e.highlightKey):null;null!=i?E(To(i),(function(e){Rg(t.getItemGraphicEl(e),n,r)})):t.eachItemGraphicEl((function(t){Rg(t,n,r)}))}function Eg(t){return Pg(t.model)}function zg(t){var e=t.model,n=t.ecModel,i=t.api,r=t.payload,o=e.pipelineContext.progressiveRender,a=t.view,s=r&&Lg(r).updateMethod,l=o?"incrementalPrepareRender":s&&a[s]?s:"render";return"render"!==l&&a[l](e,n,i,r),Vg[l]}$o(Og),na(Og);var Vg={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},Bg="\0__throttleOriginMethod",Fg="\0__throttleRate",Gg="\0__throttleType";function Wg(t,e,n){var i,r,o,a,s,l=0,u=0,h=null;function c(){u=(new Date).getTime(),h=null,t.apply(o,a||[])}e=e||0;var p=function(){for(var t=[],p=0;p=0?c():h=setTimeout(c,-r),l=i};return p.clear=function(){h&&(clearTimeout(h),h=null)},p.debounceNextCall=function(t){s=t},p}function Hg(t,e,n,i){var r=t[e];if(r){var o=r[Bg]||r,a=r[Gg];if(r[Fg]!==n||a!==i){if(null==n||!i)return t[e]=o;(r=t[e]=Wg(o,n,"debounce"===i))[Bg]=o,r[Gg]=i,r[Fg]=n}return r}}function Yg(t,e){var n=t[e];n&&n[Bg]&&(n.clear&&n.clear(),t[e]=n[Bg])}var Xg=Vo(),Ug={itemStyle:ia(Mc,!0),lineStyle:ia(bc,!0)},Zg={lineStyle:"stroke",itemStyle:"fill"};function jg(t,e){var n=t.visualStyleMapper||Ug[e];return n||(console.warn("Unknown style type '"+e+"'."),Ug.itemStyle)}function qg(t,e){var n=t.visualDrawType||Zg[e];return n||(console.warn("Unknown style type '"+e+"'."),"fill")}var Kg={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=t.getModel(i),o=jg(t,i)(r),a=r.getShallow("decal");a&&(n.setVisual("decal",a),a.dirty=!0);var s=qg(t,i),l=o[s],u=X(l)?l:null,h="auto"===o.fill||"auto"===o.stroke;if(!o[s]||u||h){var c=t.getColorFromPalette(t.name,null,e.getSeriesCount());o[s]||(o[s]=c,n.setVisual("colorFromPalette",!0)),o.fill="auto"===o.fill||X(o.fill)?c:o.fill,o.stroke="auto"===o.stroke||X(o.stroke)?c:o.stroke}if(n.setVisual("style",o),n.setVisual("drawType",s),!e.isSeriesFiltered(t)&&u)return n.setVisual("colorFromPalette",!1),{dataEach:function(e,n){var i=t.getDataParams(n),r=A({},o);r[s]=u(i),e.setItemVisual(n,"style",r)}}}},$g=new Cc,Jg={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){if(!t.ignoreStyleOnData&&!e.isSeriesFiltered(t)){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=jg(t,i),o=n.getVisual("drawType");return{dataEach:n.hasItemOption?function(t,e){var n=t.getRawDataItem(e);if(n&&n[i]){$g.option=n[i];var a=r($g);A(t.ensureUniqueItemVisual(e,"style"),a),$g.option.decal&&(t.setItemVisual(e,"decal",$g.option.decal),$g.option.decal.dirty=!0),o in a&&t.setItemVisual(e,"colorFromPalette",!1)}}:null}}}},Qg={performRawSeries:!0,overallReset:function(t){var e=yt();t.eachSeries((function(t){var n=t.getColorBy();if(!t.isColorBySeries()){var i=t.type+"-"+n,r=e.get(i);r||(r={},e.set(i,r)),Xg(t).scope=r}})),t.eachSeries((function(e){if(!e.isColorBySeries()&&!t.isSeriesFiltered(e)){var n=e.getRawData(),i={},r=e.getData(),o=Xg(e).scope,a=e.visualStyleAccessPath||"itemStyle",s=qg(e,a);r.each((function(t){var e=r.getRawIndex(t);i[e]=t})),n.each((function(t){var a=i[t];if(r.getItemVisual(a,"colorFromPalette")){var l=r.ensureUniqueItemVisual(a,"style"),u=n.getName(t)||t+"",h=n.count();l[s]=e.getColorFromPalette(u,o,h)}}))}}))}},ty=Math.PI;var ey=function(){function t(t,e,n,i){this._stageTaskMap=yt(),this.ecInstance=t,this.api=e,n=this._dataProcessorHandlers=n.slice(),i=this._visualHandlers=i.slice(),this._allHandlers=n.concat(i)}return t.prototype.restoreData=function(t,e){t.restoreData(e),this._stageTaskMap.each((function(t){var e=t.overallTask;e&&e.dirty()}))},t.prototype.getPerformArgs=function(t,e){if(t.__pipeline){var n=this._pipelineMap.get(t.__pipeline.id),i=n.context,r=!e&&n.progressiveEnabled&&(!i||i.progressiveRender)&&t.__idxInPipeline>n.blockIndex?n.step:null,o=i&&i.modDataCount;return{step:r,modBy:null!=o?Math.ceil(o/r):null,modDataCount:o}}},t.prototype.getPipeline=function(t){return this._pipelineMap.get(t)},t.prototype.updateStreamModes=function(t,e){var n=this._pipelineMap.get(t.uid),i=t.getData().count(),r=n.progressiveEnabled&&e.incrementalPrepareRender&&i>=n.threshold,o=t.get("large")&&i>=t.get("largeThreshold"),a="mod"===t.get("progressiveChunkMode")?i:null;t.pipelineContext=n.context={progressiveRender:r,modDataCount:a,large:o}},t.prototype.restorePipelines=function(t){var e=this,n=e._pipelineMap=yt();t.eachSeries((function(t){var i=t.getProgressive(),r=t.uid;n.set(r,{id:r,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:i&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(i||700),count:0}),e._pipe(t,t.dataTask)}))},t.prototype.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.api.getModel(),n=this.api;E(this._allHandlers,(function(i){var r=t.get(i.uid)||t.set(i.uid,{}),o="";lt(!(i.reset&&i.overallReset),o),i.reset&&this._createSeriesStageTask(i,r,e,n),i.overallReset&&this._createOverallStageTask(i,r,e,n)}),this)},t.prototype.prepareView=function(t,e,n,i){var r=t.renderTask,o=r.context;o.model=e,o.ecModel=n,o.api=i,r.__block=!t.incrementalPrepareRender,this._pipe(e,r)},t.prototype.performDataProcessorTasks=function(t,e){this._performStageTasks(this._dataProcessorHandlers,t,e,{block:!0})},t.prototype.performVisualTasks=function(t,e,n){this._performStageTasks(this._visualHandlers,t,e,n)},t.prototype._performStageTasks=function(t,e,n,i){i=i||{};var r=!1,o=this;function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}E(t,(function(t,s){if(!i.visualType||i.visualType===t.visualType){var l=o._stageTaskMap.get(t.uid),u=l.seriesTaskMap,h=l.overallTask;if(h){var c,p=h.agentStubMap;p.each((function(t){a(i,t)&&(t.dirty(),c=!0)})),c&&h.dirty(),o.updatePayload(h,n);var d=o.getPerformArgs(h,i.block);p.each((function(t){t.perform(d)})),h.perform(d)&&(r=!0)}else u&&u.each((function(s,l){a(i,s)&&s.dirty();var u=o.getPerformArgs(s,i.block);u.skip=!t.performRawSeries&&e.isSeriesFiltered(s.context.model),o.updatePayload(s,n),s.perform(u)&&(r=!0)}))}})),this.unfinished=r||this.unfinished},t.prototype.performSeriesTasks=function(t){var e;t.eachSeries((function(t){e=t.dataTask.perform()||e})),this.unfinished=e||this.unfinished},t.prototype.plan=function(){this._pipelineMap.each((function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)}))},t.prototype.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},t.prototype._createSeriesStageTask=function(t,e,n,i){var r=this,o=e.seriesTaskMap,a=e.seriesTaskMap=yt(),s=t.seriesType,l=t.getTargetSeries;function u(e){var s=e.uid,l=a.set(s,o&&o.get(s)||wf({plan:ay,reset:sy,count:hy}));l.context={model:e,ecModel:n,api:i,useClearVisual:t.isVisual&&!t.isLayout,plan:t.plan,reset:t.reset,scheduler:r},r._pipe(e,l)}t.createOnAllSeries?n.eachRawSeries(u):s?n.eachRawSeriesByType(s,u):l&&l(n,i).each(u)},t.prototype._createOverallStageTask=function(t,e,n,i){var r=this,o=e.overallTask=e.overallTask||wf({reset:ny});o.context={ecModel:n,api:i,overallReset:t.overallReset,scheduler:r};var a=o.agentStubMap,s=o.agentStubMap=yt(),l=t.seriesType,u=t.getTargetSeries,h=!0,c=!1,p="";function d(t){var e=t.uid,n=s.set(e,a&&a.get(e)||(c=!0,wf({reset:iy,onDirty:oy})));n.context={model:t,overallProgress:h},n.agent=o,n.__block=h,r._pipe(t,n)}lt(!t.createOnAllSeries,p),l?n.eachRawSeriesByType(l,d):u?u(n,i).each(d):(h=!1,E(n.getSeries(),d)),c&&o.dirty()},t.prototype._pipe=function(t,e){var n=t.uid,i=this._pipelineMap.get(n);!i.head&&(i.head=e),i.tail&&i.tail.pipe(e),i.tail=e,e.__idxInPipeline=i.count++,e.__pipeline=i},t.wrapStageHandler=function(t,e){return X(t)&&(t={overallReset:t,seriesType:cy(t)}),t.uid=Ac("stageHandler"),e&&(t.visualType=e),t},t}();function ny(t){t.overallReset(t.ecModel,t.api,t.payload)}function iy(t){return t.overallProgress&&ry}function ry(){this.agent.dirty(),this.getDownstream().dirty()}function oy(){this.agent&&this.agent.dirty()}function ay(t){return t.plan?t.plan(t.model,t.ecModel,t.api,t.payload):null}function sy(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=To(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?z(e,(function(t,e){return uy(e)})):ly}var ly=uy(0);function uy(t){return function(e,n){var i=n.data,r=n.resetDefines[t];if(r&&r.dataEach)for(var o=e.start;o0&&h===r.length-u.length){var c=r.slice(0,h);"data"!==c&&(e.mainType=c,e[u.toLowerCase()]=t,s=!0)}}a.hasOwnProperty(r)&&(n[r]=t,s=!0),s||(i[r]=t)}))}return{cptQuery:e,dataQuery:n,otherQuery:i}},t.prototype.filter=function(t,e){var n=this.eventInfo;if(!n)return!0;var i=n.targetEl,r=n.packedEvent,o=n.model,a=n.view;if(!o||!a)return!0;var s=e.cptQuery,l=e.dataQuery;return u(s,o,"mainType")&&u(s,o,"subType")&&u(s,o,"index","componentIndex")&&u(s,o,"name")&&u(s,o,"id")&&u(l,r,"name")&&u(l,r,"dataIndex")&&u(l,r,"dataType")&&(!a.filterForExposedEvent||a.filterForExposedEvent(t,e.otherQuery,i,r));function u(t,e,n,i){return null==t[n]||e[i||n]===t[n]}},t.prototype.afterTrigger=function(){this.eventInfo=null},t}(),My=["symbol","symbolSize","symbolRotate","symbolOffset"],Iy=My.concat(["symbolKeepAspect"]),Ty={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData();if(t.legendIcon&&n.setVisual("legendIcon",t.legendIcon),t.hasSymbolVisual){for(var i={},r={},o=!1,a=0;a=0&&jy(l)?l:.5,t.createRadialGradient(a,s,0,a,s,l)}(t,e,n):function(t,e,n){var i=null==e.x?0:e.x,r=null==e.x2?1:e.x2,o=null==e.y?0:e.y,a=null==e.y2?0:e.y2;return e.global||(i=i*n.width+n.x,r=r*n.width+n.x,o=o*n.height+n.y,a=a*n.height+n.y),i=jy(i)?i:0,r=jy(r)?r:1,o=jy(o)?o:0,a=jy(a)?a:0,t.createLinearGradient(i,o,r,a)}(t,e,n),r=e.colorStops,o=0;o0&&(e=i.lineDash,n=i.lineWidth,e&&"solid"!==e&&n>0?"dashed"===e?[4*n,2*n]:"dotted"===e?[n]:j(e)?[e]:Y(e)?e:null:null),o=i.lineDashOffset;if(r){var a=i.strokeNoScale&&t.getLineScale?t.getLineScale():1;a&&1!==a&&(r=z(r,(function(t){return t/a})),o/=a)}return[r,o]}var Qy=new hs(!0);function tv(t){var e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))}function ev(t){return"string"==typeof t&&"none"!==t}function nv(t){var e=t.fill;return null!=e&&"none"!==e}function iv(t,e){if(null!=e.fillOpacity&&1!==e.fillOpacity){var n=t.globalAlpha;t.globalAlpha=e.fillOpacity*e.opacity,t.fill(),t.globalAlpha=n}else t.fill()}function rv(t,e){if(null!=e.strokeOpacity&&1!==e.strokeOpacity){var n=t.globalAlpha;t.globalAlpha=e.strokeOpacity*e.opacity,t.stroke(),t.globalAlpha=n}else t.stroke()}function ov(t,e,n){var i=la(e.image,e.__image,n);if(ha(i)){var r=t.createPattern(i,e.repeat||"repeat");if("function"==typeof DOMMatrix&&r&&r.setTransform){var o=new DOMMatrix;o.translateSelf(e.x||0,e.y||0),o.rotateSelf(0,0,(e.rotation||0)*wt),o.scaleSelf(e.scaleX||1,e.scaleY||1),r.setTransform(o)}return r}}var av=["shadowBlur","shadowOffsetX","shadowOffsetY"],sv=[["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]];function lv(t,e,n,i,r){var o=!1;if(!i&&e===(n=n||{}))return!1;if(i||e.opacity!==n.opacity){cv(t,r),o=!0;var a=Math.max(Math.min(e.opacity,1),0);t.globalAlpha=isNaN(a)?Ma.opacity:a}(i||e.blend!==n.blend)&&(o||(cv(t,r),o=!0),t.globalCompositeOperation=e.blend||Ma.blend);for(var s=0;s0&&t.unfinished);t.unfinished||this._zr.flush()}}},e.prototype.getDom=function(){return this._dom},e.prototype.getId=function(){return this.id},e.prototype.getZr=function(){return this._zr},e.prototype.isSSR=function(){return this._ssr},e.prototype.setOption=function(t,e,n){if(!this[Dv])if(this._disposed)om(this.id);else{var i,r,o;if(q(e)&&(n=e.lazyUpdate,i=e.silent,r=e.replaceMerge,o=e.transition,e=e.notMerge),this[Dv]=!0,!this._model||e){var a=new Md(this._api),s=this._theme,l=this._model=new gd;l.scheduler=this._scheduler,l.ssr=this._ssr,l.init(null,null,null,s,this._locale,a)}this._model.setOption(t,{replaceMerge:r},um);var u={seriesTransition:o,optionChanged:!0};if(n)this[Av]={silent:i,updateParams:u},this[Dv]=!1,this.getZr().wakeUp();else{try{Ev(this),Bv.update.call(this,null,u)}catch(t){throw this[Av]=null,this[Dv]=!1,t}this._ssr||this._zr.flush(),this[Av]=null,this[Dv]=!1,Hv.call(this,i),Yv.call(this,i)}}},e.prototype.setTheme=function(){bo()},e.prototype.getModel=function(){return this._model},e.prototype.getOption=function(){return this._model&&this._model.getOption()},e.prototype.getWidth=function(){return this._zr.getWidth()},e.prototype.getHeight=function(){return this._zr.getHeight()},e.prototype.getDevicePixelRatio=function(){return this._zr.painter.dpr||r.hasGlobalWindow&&window.devicePixelRatio||1},e.prototype.getRenderedCanvas=function(t){return this.renderToCanvas(t)},e.prototype.renderToCanvas=function(t){t=t||{};var e=this._zr.painter;return e.getRenderedCanvas({backgroundColor:t.backgroundColor||this._model.get("backgroundColor"),pixelRatio:t.pixelRatio||this.getDevicePixelRatio()})},e.prototype.renderToSVGString=function(t){t=t||{};var e=this._zr.painter;return e.renderToString({useViewBox:t.useViewBox})},e.prototype.getSvgDataURL=function(){if(r.svgSupported){var t=this._zr;return E(t.storage.getDisplayList(),(function(t){t.stopAnimation(null,!0)})),t.painter.toDataURL()}},e.prototype.getDataURL=function(t){if(!this._disposed){var e=(t=t||{}).excludeComponents,n=this._model,i=[],r=this;E(e,(function(t){n.eachComponent({mainType:t},(function(t){var e=r._componentsMap[t.__viewId];e.group.ignore||(i.push(e),e.group.ignore=!0)}))}));var o="svg"===this._zr.painter.getType()?this.getSvgDataURL():this.renderToCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return E(i,(function(t){t.group.ignore=!1})),o}om(this.id)},e.prototype.getConnectedDataURL=function(t){if(!this._disposed){var e="svg"===t.type,n=this.group,i=Math.min,r=Math.max,o=1/0;if(fm[n]){var a=o,s=o,l=-1/0,u=-1/0,c=[],p=t&&t.pixelRatio||this.getDevicePixelRatio();E(dm,(function(o,h){if(o.group===n){var p=e?o.getZr().painter.getSvgDom().innerHTML:o.renderToCanvas(T(t)),d=o.getDom().getBoundingClientRect();a=i(d.left,a),s=i(d.top,s),l=r(d.right,l),u=r(d.bottom,u),c.push({dom:p,left:d.left,top:d.top})}}));var d=(l*=p)-(a*=p),f=(u*=p)-(s*=p),g=h.createCanvas(),y=Yr(g,{renderer:e?"svg":"canvas"});if(y.resize({width:d,height:f}),e){var v="";return E(c,(function(t){var e=t.left-a,n=t.top-s;v+=''+t.dom+""})),y.painter.getSvgRoot().innerHTML=v,t.connectedBackgroundColor&&y.painter.setBackgroundColor(t.connectedBackgroundColor),y.refreshImmediately(),y.painter.toDataURL()}return t.connectedBackgroundColor&&y.add(new Ws({shape:{x:0,y:0,width:d,height:f},style:{fill:t.connectedBackgroundColor}})),E(c,(function(t){var e=new Ns({style:{x:t.left*p-a,y:t.top*p-s,image:t.dom}});y.add(e)})),y.refreshImmediately(),g.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}om(this.id)},e.prototype.convertToPixel=function(t,e){return Fv(this,"convertToPixel",t,e)},e.prototype.convertFromPixel=function(t,e){return Fv(this,"convertFromPixel",t,e)},e.prototype.containPixel=function(t,e){var n;if(!this._disposed)return E(Fo(this._model,t),(function(t,i){i.indexOf("Models")>=0&&E(t,(function(t){var r=t.coordinateSystem;if(r&&r.containPoint)n=n||!!r.containPoint(e);else if("seriesModels"===i){var o=this._chartsMap[t.__viewId];o&&o.containPoint&&(n=n||o.containPoint(e,t))}else 0}),this)}),this),!!n;om(this.id)},e.prototype.getVisual=function(t,e){var n=Fo(this._model,t,{defaultMainType:"series"}),i=n.seriesModel;var r=i.getData(),o=n.hasOwnProperty("dataIndexInside")?n.dataIndexInside:n.hasOwnProperty("dataIndex")?r.indexOfRawIndex(n.dataIndex):null;return null!=o?Dy(r,o,e):Ay(r,e)},e.prototype.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},e.prototype.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]},e.prototype._initEvents=function(){var t,e,n,i=this;E(rm,(function(t){var e=function(e){var n,r=i.getModel(),o=e.target,a="globalout"===t;if(a?n={}:o&&Oy(o,(function(t){var e=rl(t);if(e&&null!=e.dataIndex){var i=e.dataModel||r.getSeriesByIndex(e.seriesIndex);return n=i&&i.getDataParams(e.dataIndex,e.dataType,o)||{},!0}if(e.eventData)return n=A({},e.eventData),!0}),!0),n){var s=n.componentType,l=n.componentIndex;"markLine"!==s&&"markPoint"!==s&&"markArea"!==s||(s="series",l=n.seriesIndex);var u=s&&null!=l&&r.getComponent(s,l),h=u&&i["series"===u.mainType?"_chartsMap":"_componentsMap"][u.__viewId];0,n.event=e,n.type=t,i._$eventProcessor.eventInfo={targetEl:o,packedEvent:n,model:u,view:h},i.trigger(t,n)}};e.zrEventfulCallAtLast=!0,i._zr.on(t,e,i)})),E(sm,(function(t,e){i._messageCenter.on(e,(function(t){this.trigger(e,t)}),i)})),E(["selectchanged"],(function(t){i._messageCenter.on(t,(function(e){this.trigger(t,e)}),i)})),t=this._messageCenter,e=this,n=this._api,t.on("selectchanged",(function(t){var i=n.getModel();t.isFromClick?(Py("map","selectchanged",e,i,t),Py("pie","selectchanged",e,i,t)):"select"===t.fromAction?(Py("map","selected",e,i,t),Py("pie","selected",e,i,t)):"unselect"===t.fromAction&&(Py("map","unselected",e,i,t),Py("pie","unselected",e,i,t))}))},e.prototype.isDisposed=function(){return this._disposed},e.prototype.clear=function(){this._disposed?om(this.id):this.setOption({series:[]},!0)},e.prototype.dispose=function(){if(this._disposed)om(this.id);else{this._disposed=!0,this.getDom()&&Xo(this.getDom(),vm,"");var t=this,e=t._api,n=t._model;E(t._componentsViews,(function(t){t.dispose(n,e)})),E(t._chartsViews,(function(t){t.dispose(n,e)})),t._zr.dispose(),t._dom=t._model=t._chartsMap=t._componentsMap=t._chartsViews=t._componentsViews=t._scheduler=t._api=t._zr=t._throttledZrFlush=t._theme=t._coordSysMgr=t._messageCenter=null,delete dm[t.id]}},e.prototype.resize=function(t){if(!this[Dv])if(this._disposed)om(this.id);else{this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var n=e.resetOption("media"),i=t&&t.silent;this[Av]&&(null==i&&(i=this[Av].silent),n=!0,this[Av]=null),this[Dv]=!0;try{n&&Ev(this),Bv.update.call(this,{type:"resize",animation:A({duration:0},t&&t.animation)})}catch(t){throw this[Dv]=!1,t}this[Dv]=!1,Hv.call(this,i),Yv.call(this,i)}}},e.prototype.showLoading=function(t,e){if(this._disposed)om(this.id);else if(q(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),pm[t]){var n=pm[t](this._api,e),i=this._zr;this._loadingFX=n,i.add(n)}},e.prototype.hideLoading=function(){this._disposed?om(this.id):(this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null)},e.prototype.makeActionFromEvent=function(t){var e=A({},t);return e.type=sm[t.type],e},e.prototype.dispatchAction=function(t,e){if(this._disposed)om(this.id);else if(q(e)||(e={silent:!!e}),am[t.type]&&this._model)if(this[Dv])this._pendingActions.push(t);else{var n=e.silent;Wv.call(this,t,n);var i=e.flush;i?this._zr.flush():!1!==i&&r.browser.weChat&&this._throttledZrFlush(),Hv.call(this,n),Yv.call(this,n)}},e.prototype.updateLabelLayout=function(){wv.trigger("series:layoutlabels",this._model,this._api,{updatedSeries:[]})},e.prototype.appendData=function(t){if(this._disposed)om(this.id);else{var e=t.seriesIndex,n=this.getModel().getSeriesByIndex(e);0,n.appendData(t),this._scheduler.unfinished=!0,this.getZr().wakeUp()}},e.internalField=function(){function t(t){t.clearColorPalette(),t.eachSeries((function(t){t.clearColorPalette()}))}function e(t){for(var e=[],n=t.currentStates,i=0;i0?{duration:o,delay:i.get("delay"),easing:i.get("easing")}:null;n.eachRendered((function(t){if(t.states&&t.states.emphasis){if(xh(t))return;if(t instanceof ks&&function(t){var e=ll(t);e.normalFill=t.style.fill,e.normalStroke=t.style.stroke;var n=t.states.select||{};e.selectFill=n.style&&n.style.fill||null,e.selectStroke=n.style&&n.style.stroke||null}(t),t.__dirty){var n=t.prevStates;n&&t.useStates(n)}if(r){t.stateTransition=a;var i=t.getTextContent(),o=t.getTextGuideLine();i&&(i.stateTransition=a),o&&(o.stateTransition=a)}t.__dirty&&e(t)}}))}Ev=function(t){var e=t._scheduler;e.restorePipelines(t._model),e.prepareStageTasks(),zv(t,!0),zv(t,!1),e.plan()},zv=function(t,e){for(var n=t._model,i=t._scheduler,r=e?t._componentsViews:t._chartsViews,o=e?t._componentsMap:t._chartsMap,a=t._zr,s=t._api,l=0;le.get("hoverLayerThreshold")&&!r.node&&!r.worker&&e.eachSeries((function(e){if(!e.preventUsingHoverLayer){var n=t._chartsMap[e.__viewId];n.__alive&&n.eachRendered((function(t){t.states.emphasis&&(t.states.emphasis.hoverLayer=!0)}))}}))}(t,e),wv.trigger("series:afterupdate",e,n,l)},Jv=function(t){t[kv]=!0,t.getZr().wakeUp()},Qv=function(t){t[kv]&&(t.getZr().storage.traverse((function(t){xh(t)||e(t)})),t[kv]=!1)},Kv=function(t){return new(function(e){function i(){return null!==e&&e.apply(this,arguments)||this}return n(i,e),i.prototype.getCoordinateSystems=function(){return t._coordSysMgr.getCoordinateSystems()},i.prototype.getComponentByElement=function(e){for(;e;){var n=e.__ecComponentInfo;if(null!=n)return t._model.getComponent(n.mainType,n.index);e=e.parent}},i.prototype.enterEmphasis=function(e,n){Ol(e,n),Jv(t)},i.prototype.leaveEmphasis=function(e,n){Rl(e,n),Jv(t)},i.prototype.enterBlur=function(e){Nl(e),Jv(t)},i.prototype.leaveBlur=function(e){El(e),Jv(t)},i.prototype.enterSelect=function(e){zl(e),Jv(t)},i.prototype.leaveSelect=function(e){Vl(e),Jv(t)},i.prototype.getModel=function(){return t.getModel()},i.prototype.getViewOfComponentModel=function(e){return t.getViewOfComponentModel(e)},i.prototype.getViewOfSeriesModel=function(e){return t.getViewOfSeriesModel(e)},i}(_d))(t)},$v=function(t){function e(t,e){for(var n=0;n=0)){Lm.push(n);var o=ey.wrapStageHandler(n,r);o.__prio=e,o.__raw=n,t.push(o)}}function Om(t,e){pm[t]=e}function Rm(t,e,n){var i=Mv("registerMap");i&&i(t,e,n)}var Nm=function(t){var e=(t=T(t)).type,n="";e||wo(n);var i=e.split(":");2!==i.length&&wo(n);var r=!1;"echarts"===i[0]&&(e=i[1],r=!0),t.__isBuiltIn=r,Vf.set(e,t)};km(Iv,Kg),km(Tv,Jg),km(Tv,Qg),km(Iv,Ty),km(Tv,Cy),km(7e3,(function(t,e){t.eachRawSeries((function(n){if(!t.isSeriesFiltered(n)){var i=n.getData();i.hasItemVisual()&&i.each((function(t){var n=i.getItemVisual(t,"decal");n&&(i.ensureUniqueItemVisual(t,"style").decal=mv(n,e))}));var r=i.getVisual("decal");if(r)i.getVisual("style").decal=mv(r,e)}}))})),wm(Xd),Sm(900,(function(t){var e=yt();t.eachSeries((function(t){var n=t.get("stack");if(n){var i=e.get(n)||e.set(n,[]),r=t.getData(),o={stackResultDimension:r.getCalculationInfo("stackResultDimension"),stackedOverDimension:r.getCalculationInfo("stackedOverDimension"),stackedDimension:r.getCalculationInfo("stackedDimension"),stackedByDimension:r.getCalculationInfo("stackedByDimension"),isStackedByIndex:r.getCalculationInfo("isStackedByIndex"),data:r,seriesModel:t};if(!o.stackedDimension||!o.isStackedByIndex&&!o.stackedByDimension)return;i.length&&r.setCalculationInfo("stackedOnSeries",i[i.length-1].seriesModel),i.push(o)}})),e.each(Ud)})),Om("default",(function(t,e){k(e=e||{},{text:"loading",textColor:"#000",fontSize:12,fontWeight:"normal",fontStyle:"normal",fontFamily:"sans-serif",maskColor:"rgba(255, 255, 255, 0.8)",showSpinner:!0,color:"#5470c6",spinnerRadius:10,lineWidth:5,zlevel:0});var n=new Br,i=new Ws({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4});n.add(i);var r,o=new Xs({style:{text:e.text,fill:e.textColor,fontSize:e.fontSize,fontWeight:e.fontWeight,fontStyle:e.fontStyle,fontFamily:e.fontFamily},zlevel:e.zlevel,z:10001}),a=new Ws({style:{fill:"none"},textContent:o,textConfig:{position:"right",distance:10},zlevel:e.zlevel,z:10001});return n.add(a),e.showSpinner&&((r=new nh({shape:{startAngle:-ty/2,endAngle:-ty/2+.1,r:e.spinnerRadius},style:{stroke:e.color,lineCap:"round",lineWidth:e.lineWidth},zlevel:e.zlevel,z:10001})).animateShape(!0).when(1e3,{endAngle:3*ty/2}).start("circularInOut"),r.animateShape(!0).when(1e3,{startAngle:3*ty/2}).delay(300).start("circularInOut"),n.add(r)),n.resize=function(){var n=o.getBoundingRect().width,s=e.showSpinner?e.spinnerRadius:0,l=(t.getWidth()-2*s-(e.showSpinner&&n?10:0)-n)/2-(e.showSpinner&&n?0:5+n/2)+(e.showSpinner?0:n/2)+(n?0:s),u=t.getHeight()/2;e.showSpinner&&r.setShape({cx:l,cy:u}),a.setShape({x:l-s,y:u-s,width:2*s,height:2*s}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},n.resize(),n})),Cm({type:dl,event:dl,update:dl},bt),Cm({type:fl,event:fl,update:fl},bt),Cm({type:gl,event:gl,update:gl},bt),Cm({type:yl,event:yl,update:yl},bt),Cm({type:vl,event:vl,update:vl},bt),bm("light",vy),bm("dark",wy);var Em=[],zm={registerPreprocessor:wm,registerProcessor:Sm,registerPostInit:Mm,registerPostUpdate:Im,registerUpdateLifecycle:Tm,registerAction:Cm,registerCoordinateSystem:Dm,registerLayout:Am,registerVisual:km,registerTransform:Nm,registerLoading:Om,registerMap:Rm,registerImpl:function(t,e){Sv[t]=e},PRIORITY:Cv,ComponentModel:zp,ComponentView:Ag,SeriesModel:bg,ChartView:Og,registerComponentModel:function(t){zp.registerClass(t)},registerComponentView:function(t){Ag.registerClass(t)},registerSeriesModel:function(t){bg.registerClass(t)},registerChartView:function(t){Og.registerClass(t)},registerSubTypeDefaulter:function(t,e){zp.registerSubTypeDefaulter(t,e)},registerPainter:function(t,e){Xr(t,e)}};function Vm(t){Y(t)?E(t,(function(t){Vm(t)})):P(Em,t)>=0||(Em.push(t),X(t)&&(t={install:t}),t.install(zm))}function Bm(t){return null==t?0:t.length||1}function Fm(t){return t}var Gm=function(){function t(t,e,n,i,r,o){this._old=t,this._new=e,this._oldKeyGetter=n||Fm,this._newKeyGetter=i||Fm,this.context=r,this._diffModeMultiple="multiple"===o}return t.prototype.add=function(t){return this._add=t,this},t.prototype.update=function(t){return this._update=t,this},t.prototype.updateManyToOne=function(t){return this._updateManyToOne=t,this},t.prototype.updateOneToMany=function(t){return this._updateOneToMany=t,this},t.prototype.updateManyToMany=function(t){return this._updateManyToMany=t,this},t.prototype.remove=function(t){return this._remove=t,this},t.prototype.execute=function(){this[this._diffModeMultiple?"_executeMultiple":"_executeOneToOne"]()},t.prototype._executeOneToOne=function(){var t=this._old,e=this._new,n={},i=new Array(t.length),r=new Array(e.length);this._initIndexMap(t,null,i,"_oldKeyGetter"),this._initIndexMap(e,n,r,"_newKeyGetter");for(var o=0;o1){var u=s.shift();1===s.length&&(n[a]=s[0]),this._update&&this._update(u,o)}else 1===l?(n[a]=null,this._update&&this._update(s,o)):this._remove&&this._remove(o)}this._performRestAdd(r,n)},t.prototype._executeMultiple=function(){var t=this._old,e=this._new,n={},i={},r=[],o=[];this._initIndexMap(t,n,r,"_oldKeyGetter"),this._initIndexMap(e,i,o,"_newKeyGetter");for(var a=0;a1&&1===c)this._updateManyToOne&&this._updateManyToOne(u,l),i[s]=null;else if(1===h&&c>1)this._updateOneToMany&&this._updateOneToMany(u,l),i[s]=null;else if(1===h&&1===c)this._update&&this._update(u,l),i[s]=null;else if(h>1&&c>1)this._updateManyToMany&&this._updateManyToMany(u,l),i[s]=null;else if(h>1)for(var p=0;p1)for(var a=0;a30}var Qm,tx,ex,nx,ix,rx,ox,ax=q,sx=z,lx="undefined"==typeof Int32Array?Array:Int32Array,ux=["hasItemOption","_nameList","_idList","_invertedIndicesMap","_dimSummary","userOutput","_rawData","_dimValueGetter","_nameDimIdx","_idDimIdx","_nameRepeatCount"],hx=["_approximateExtent"],cx=function(){function t(t,e){var n;this.type="list",this._dimOmitted=!1,this._nameList=[],this._idList=[],this._visual={},this._layout={},this._itemVisuals=[],this._itemLayouts=[],this._graphicEls=[],this._approximateExtent={},this._calculationInfo={},this.hasItemOption=!1,this.TRANSFERABLE_METHODS=["cloneShallow","downSample","minmaxDownSample","lttbDownSample","map"],this.CHANGABLE_METHODS=["filterSelf","selectRange"],this.DOWNSAMPLE_METHODS=["downSample","minmaxDownSample","lttbDownSample"];var i=!1;qm(t)?(n=t.dimensions,this._dimOmitted=t.isDimensionOmitted(),this._schema=t):(i=!0,n=t),n=n||["x","y"];for(var r={},o=[],a={},s=!1,l={},u=0;u=e)){var n=this._store.getProvider();this._updateOrdinalMeta();var i=this._nameList,r=this._idList;if(n.getSource().sourceFormat===Wp&&!n.pure)for(var o=[],a=t;a0},t.prototype.ensureUniqueItemVisual=function(t,e){var n=this._itemVisuals,i=n[t];i||(i=n[t]={});var r=i[e];return null==r&&(Y(r=this.getVisual(e))?r=r.slice():ax(r)&&(r=A({},r)),i[e]=r),r},t.prototype.setItemVisual=function(t,e,n){var i=this._itemVisuals[t]||{};this._itemVisuals[t]=i,ax(e)?A(i,e):i[e]=n},t.prototype.clearAllVisual=function(){this._visual={},this._itemVisuals=[]},t.prototype.setLayout=function(t,e){ax(t)?A(this._layout,t):this._layout[t]=e},t.prototype.getLayout=function(t){return this._layout[t]},t.prototype.getItemLayout=function(t){return this._itemLayouts[t]},t.prototype.setItemLayout=function(t,e,n){this._itemLayouts[t]=n?A(this._itemLayouts[t]||{},e):e},t.prototype.clearItemLayouts=function(){this._itemLayouts.length=0},t.prototype.setItemGraphicEl=function(t,e){var n=this.hostModel&&this.hostModel.seriesIndex;ol(n,this.dataType,t,e),this._graphicEls[t]=e},t.prototype.getItemGraphicEl=function(t){return this._graphicEls[t]},t.prototype.eachItemGraphicEl=function(t,e){E(this._graphicEls,(function(n,i){n&&t&&t.call(e,n,i)}))},t.prototype.cloneShallow=function(e){return e||(e=new t(this._schema?this._schema:sx(this.dimensions,this._getDimInfo,this),this.hostModel)),ix(e,this),e._store=this._store,e},t.prototype.wrapMethod=function(t,e){var n=this[t];X(n)&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=n.apply(this,arguments);return e.apply(this,[t].concat(at(arguments)))})},t.internalField=(Qm=function(t){var e=t._invertedIndicesMap;E(e,(function(n,i){var r=t._dimInfos[i],o=r.ordinalMeta,a=t._store;if(o){n=e[i]=new lx(o.categories.length);for(var s=0;s1&&(s+="__ec__"+u),i[e]=s}})),t}();function px(t,e){Qd(t)||(t=ef(t));var n=(e=e||{}).coordDimensions||[],i=e.dimensionsDefine||t.dimensionsDefine||[],r=yt(),o=[],a=function(t,e,n,i){var r=Math.max(t.dimensionsDetectedCount||1,e.length,n.length,i||0);return E(e,(function(t){var e;q(t)&&(e=t.dimsDef)&&(r=Math.max(r,e.length))})),r}(t,n,i,e.dimensionsCount),s=e.canOmitUnusedDimensions&&Jm(a),l=i===t.dimensionsDefine,u=l?$m(t):Km(i),h=e.encodeDefine;!h&&e.encodeDefaulter&&(h=e.encodeDefaulter(t,a));for(var c=yt(h),p=new Xf(a),d=0;d0&&(i.name=r+(o-1)),o++,e.set(r,o)}}(o),new jm({source:t,dimensions:o,fullDimensionCount:a,dimensionOmitted:s})}function dx(t,e,n){if(n||e.hasKey(t)){for(var i=0;e.hasKey(t+i);)i++;t+=i}return e.set(t,!0),t}var fx=function(t){this.coordSysDims=[],this.axisMap=yt(),this.categoryAxisMap=yt(),this.coordSysName=t};var gx={cartesian2d:function(t,e,n,i){var r=t.getReferringComponents("xAxis",Wo).models[0],o=t.getReferringComponents("yAxis",Wo).models[0];e.coordSysDims=["x","y"],n.set("x",r),n.set("y",o),yx(r)&&(i.set("x",r),e.firstCategoryDimIndex=0),yx(o)&&(i.set("y",o),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},singleAxis:function(t,e,n,i){var r=t.getReferringComponents("singleAxis",Wo).models[0];e.coordSysDims=["single"],n.set("single",r),yx(r)&&(i.set("single",r),e.firstCategoryDimIndex=0)},polar:function(t,e,n,i){var r=t.getReferringComponents("polar",Wo).models[0],o=r.findAxisModel("radiusAxis"),a=r.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],n.set("radius",o),n.set("angle",a),yx(o)&&(i.set("radius",o),e.firstCategoryDimIndex=0),yx(a)&&(i.set("angle",a),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},geo:function(t,e,n,i){e.coordSysDims=["lng","lat"]},parallel:function(t,e,n,i){var r=t.ecModel,o=r.getComponent("parallel",t.get("parallelIndex")),a=e.coordSysDims=o.dimensions.slice();E(o.parallelAxisIndex,(function(t,o){var s=r.getComponent("parallelAxis",t),l=a[o];n.set(l,s),yx(s)&&(i.set(l,s),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=o))}))}};function yx(t){return"category"===t.get("type")}function vx(t,e,n){var i,r,o,a=(n=n||{}).byIndex,s=n.stackedCoordDimension;!function(t){return!qm(t.schema)}(e)?(r=e.schema,i=r.dimensions,o=e.store):i=e;var l,u,h,c,p=!(!t||!t.get("stack"));if(E(i,(function(t,e){U(t)&&(i[e]=t={name:t}),p&&!t.isExtraCoord&&(a||l||!t.ordinalMeta||(l=t),u||"ordinal"===t.type||"time"===t.type||s&&s!==t.coordDim||(u=t))})),!u||a||l||(a=!0),u){h="__\0ecstackresult_"+t.id,c="__\0ecstackedover_"+t.id,l&&(l.createInvertedIndices=!0);var d=u.coordDim,f=u.type,g=0;E(i,(function(t){t.coordDim===d&&g++}));var y={name:h,coordDim:d,coordDimIndex:g,type:f,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length},v={name:c,coordDim:c,coordDimIndex:g+1,type:f,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length+1};r?(o&&(y.storeDimIndex=o.ensureCalculationDimension(c,f),v.storeDimIndex=o.ensureCalculationDimension(h,f)),r.appendCalculationDimension(y),r.appendCalculationDimension(v)):(i.push(y),i.push(v))}return{stackedDimension:u&&u.name,stackedByDimension:l&&l.name,isStackedByIndex:a,stackedOverDimension:c,stackResultDimension:h}}function mx(t,e){return!!e&&e===t.getCalculationInfo("stackedDimension")}function xx(t,e){return mx(t,e)?t.getCalculationInfo("stackResultDimension"):e}function _x(t,e,n){n=n||{};var i,r=e.getSourceManager(),o=!1;t?(o=!0,i=ef(t)):o=(i=r.getSource()).sourceFormat===Wp;var a=function(t){var e=t.get("coordinateSystem"),n=new fx(e),i=gx[e];if(i)return i(t,n,n.axisMap,n.categoryAxisMap),n}(e),s=function(t,e){var n,i=t.get("coordinateSystem"),r=wd.get(i);return e&&e.coordSysDims&&(n=z(e.coordSysDims,(function(t){var n={name:t},i=e.axisMap.get(t);if(i){var r=i.get("type");n.type=Ym(r)}return n}))),n||(n=r&&(r.getDimensionsInfo?r.getDimensionsInfo():r.dimensions.slice())||["x","y"]),n}(e,a),l=n.useEncodeDefaulter,u=X(l)?l:l?H(td,s,e):null,h=px(i,{coordDimensions:s,generateCoord:n.generateCoord,encodeDefine:e.getEncode(),encodeDefaulter:u,canOmitUnusedDimensions:!o}),c=function(t,e,n){var i,r;return n&&E(t,(function(t,o){var a=t.coordDim,s=n.categoryAxisMap.get(a);s&&(null==i&&(i=o),t.ordinalMeta=s.getOrdinalMeta(),e&&(t.createInvertedIndices=!0)),null!=t.otherDims.itemName&&(r=!0)})),r||null==i||(t[i].otherDims.itemName=0),i}(h.dimensions,n.createInvertedIndices,a),p=o?null:r.getSharedDataStore(h),d=vx(e,{schema:h,store:p}),f=new cx(h,e);f.setCalculationInfo(d);var g=null!=c&&function(t){if(t.sourceFormat===Wp){var e=function(t){var e=0;for(;ee[1]&&(e[1]=t[1])},t.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},t.prototype.getExtent=function(){return this._extent.slice()},t.prototype.setExtent=function(t,e){var n=this._extent;isNaN(t)||(n[0]=t),isNaN(e)||(n[1]=e)},t.prototype.isInExtentRange=function(t){return this._extent[0]<=t&&this._extent[1]>=t},t.prototype.isBlank=function(){return this._isBlank},t.prototype.setBlank=function(t){this._isBlank=t},t}();na(bx);var Sx=0,Mx=function(){function t(t){this.categories=t.categories||[],this._needCollect=t.needCollect,this._deduplication=t.deduplication,this.uid=++Sx}return t.createByAxisModel=function(e){var n=e.option,i=n.data,r=i&&z(i,Ix);return new t({categories:r,needCollect:!r,deduplication:!1!==n.dedplication})},t.prototype.getOrdinal=function(t){return this._getOrCreateMap().get(t)},t.prototype.parseAndCollect=function(t){var e,n=this._needCollect;if(!U(t)&&!n)return t;if(n&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var i=this._getOrCreateMap();return null==(e=i.get(t))&&(n?(e=this.categories.length,this.categories[e]=t,i.set(t,e)):e=NaN),e},t.prototype._getOrCreateMap=function(){return this._map||(this._map=yt(this.categories))},t}();function Ix(t){return q(t)&&null!=t.value?t.value:t+""}function Tx(t){return"interval"===t.type||"log"===t.type}function Cx(t,e,n,i){var r={},o=t[1]-t[0],a=r.interval=po(o/e,!0);null!=n&&ai&&(a=r.interval=i);var s=r.intervalPrecision=Ax(a);return function(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),kx(t,0,e),kx(t,1,e),t[0]>t[1]&&(t[0]=t[1])}(r.niceTickExtent=[Jr(Math.ceil(t[0]/a)*a,s),Jr(Math.floor(t[1]/a)*a,s)],t),r}function Dx(t){var e=Math.pow(10,co(t)),n=t/e;return n?2===n?n=3:3===n?n=5:n*=2:n=1,Jr(n*e)}function Ax(t){return to(t)+2}function kx(t,e,n){t[e]=Math.max(Math.min(t[e],n[1]),n[0])}function Lx(t,e){return t>=e[0]&&t<=e[1]}function Px(t,e){return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])}function Ox(t,e){return t*(e[1]-e[0])+e[0]}var Rx=function(t){function e(e){var n=t.call(this,e)||this;n.type="ordinal";var i=n.getSetting("ordinalMeta");return i||(i=new Mx({})),Y(i)&&(i=new Mx({categories:z(i,(function(t){return q(t)?t.value:t}))})),n._ordinalMeta=i,n._extent=n.getSetting("extent")||[0,i.categories.length-1],n}return n(e,t),e.prototype.parse=function(t){return null==t?NaN:U(t)?this._ordinalMeta.getOrdinal(t):Math.round(t)},e.prototype.contain=function(t){return Lx(t=this.parse(t),this._extent)&&null!=this._ordinalMeta.categories[t]},e.prototype.normalize=function(t){return Px(t=this._getTickNumber(this.parse(t)),this._extent)},e.prototype.scale=function(t){return t=Math.round(Ox(t,this._extent)),this.getRawOrdinalNumber(t)},e.prototype.getTicks=function(){for(var t=[],e=this._extent,n=e[0];n<=e[1];)t.push({value:n}),n++;return t},e.prototype.getMinorTicks=function(t){},e.prototype.setSortInfo=function(t){if(null!=t){for(var e=t.ordinalNumbers,n=this._ordinalNumbersByTick=[],i=this._ticksByOrdinalNumber=[],r=0,o=this._ordinalMeta.categories.length,a=Math.min(o,e.length);r=0&&t=0&&t=t},e.prototype.getOrdinalMeta=function(){return this._ordinalMeta},e.prototype.calcNiceTicks=function(){},e.prototype.calcNiceExtent=function(){},e.type="ordinal",e}(bx);bx.registerClass(Rx);var Nx=Jr,Ex=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="interval",e._interval=0,e._intervalPrecision=2,e}return n(e,t),e.prototype.parse=function(t){return t},e.prototype.contain=function(t){return Lx(t,this._extent)},e.prototype.normalize=function(t){return Px(t,this._extent)},e.prototype.scale=function(t){return Ox(t,this._extent)},e.prototype.setExtent=function(t,e){var n=this._extent;isNaN(t)||(n[0]=parseFloat(t)),isNaN(e)||(n[1]=parseFloat(e))},e.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),this.setExtent(e[0],e[1])},e.prototype.getInterval=function(){return this._interval},e.prototype.setInterval=function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=Ax(t)},e.prototype.getTicks=function(t){var e=this._interval,n=this._extent,i=this._niceExtent,r=this._intervalPrecision,o=[];if(!e)return o;n[0]1e4)return[];var s=o.length?o[o.length-1].value:i[1];return n[1]>s&&(t?o.push({value:Nx(s+e,r)}):o.push({value:n[1]})),o},e.prototype.getMinorTicks=function(t){for(var e=this.getTicks(!0),n=[],i=this.getExtent(),r=1;ri[0]&&h0&&(o=null===o?s:Math.min(o,s))}n[i]=o}}return n}(t),n=[];return E(t,(function(t){var i,r=t.coordinateSystem.getBaseAxis(),o=r.getExtent();if("category"===r.type)i=r.getBandWidth();else if("value"===r.type||"time"===r.type){var a=r.dim+"_"+r.index,s=e[a],l=Math.abs(o[1]-o[0]),u=r.scale.getExtent(),h=Math.abs(u[1]-u[0]);i=s?l/h*s:l}else{var c=t.getData();i=Math.abs(o[1]-o[0])/c.count()}var p=$r(t.get("barWidth"),i),d=$r(t.get("barMaxWidth"),i),f=$r(t.get("barMinWidth")||(qx(t)?.5:1),i),g=t.get("barGap"),y=t.get("barCategoryGap");n.push({bandWidth:i,barWidth:p,barMaxWidth:d,barMinWidth:f,barGap:g,barCategoryGap:y,axisKey:Wx(r),stackId:Gx(t)})})),Xx(n)}function Xx(t){var e={};E(t,(function(t,n){var i=t.axisKey,r=t.bandWidth,o=e[i]||{bandWidth:r,remainedWidth:r,autoWidthCount:0,categoryGap:null,gap:"20%",stacks:{}},a=o.stacks;e[i]=o;var s=t.stackId;a[s]||o.autoWidthCount++,a[s]=a[s]||{width:0,maxWidth:0};var l=t.barWidth;l&&!a[s].width&&(a[s].width=l,l=Math.min(o.remainedWidth,l),o.remainedWidth-=l);var u=t.barMaxWidth;u&&(a[s].maxWidth=u);var h=t.barMinWidth;h&&(a[s].minWidth=h);var c=t.barGap;null!=c&&(o.gap=c);var p=t.barCategoryGap;null!=p&&(o.categoryGap=p)}));var n={};return E(e,(function(t,e){n[e]={};var i=t.stacks,r=t.bandWidth,o=t.categoryGap;if(null==o){var a=G(i).length;o=Math.max(35-4*a,15)+"%"}var s=$r(o,r),l=$r(t.gap,1),u=t.remainedWidth,h=t.autoWidthCount,c=(u-s)/(h+(h-1)*l);c=Math.max(c,0),E(i,(function(t){var e=t.maxWidth,n=t.minWidth;if(t.width){i=t.width;e&&(i=Math.min(i,e)),n&&(i=Math.max(i,n)),t.width=i,u-=i+l*i,h--}else{var i=c;e&&ei&&(i=n),i!==c&&(t.width=i,u-=i+l*i,h--)}})),c=(u-s)/(h+(h-1)*l),c=Math.max(c,0);var p,d=0;E(i,(function(t,e){t.width||(t.width=c),p=t,d+=t.width*(1+l)})),p&&(d-=p.width*l);var f=-d/2;E(i,(function(t,i){n[e][i]=n[e][i]||{bandWidth:r,offset:f,width:t.width},f+=t.width*(1+l)}))})),n}function Ux(t,e){var n=Hx(t,e),i=Yx(n);E(n,(function(t){var e=t.getData(),n=t.coordinateSystem.getBaseAxis(),r=Gx(t),o=i[Wx(n)][r],a=o.offset,s=o.width;e.setLayout({bandWidth:o.bandWidth,offset:a,size:s})}))}function Zx(t){return{seriesType:t,plan:kg(),reset:function(t){if(jx(t)){var e=t.getData(),n=t.coordinateSystem,i=n.getBaseAxis(),r=n.getOtherAxis(i),o=e.getDimensionIndex(e.mapDimension(r.dim)),a=e.getDimensionIndex(e.mapDimension(i.dim)),s=t.get("showBackground",!0),l=e.mapDimension(r.dim),u=e.getCalculationInfo("stackResultDimension"),h=mx(e,l)&&!!e.getCalculationInfo("stackedOnSeries"),c=r.isHorizontal(),p=function(t,e){var n=e.model.get("startValue");n||(n=0);return e.toGlobalCoord(e.dataToCoord("log"===e.type?n>0?n:1:n))}(0,r),d=qx(t),f=t.get("barMinHeight")||0,g=u&&e.getDimensionIndex(u),y=e.getLayout("size"),v=e.getLayout("offset");return{progress:function(t,e){for(var i,r=t.count,l=d&&Bx(3*r),u=d&&s&&Bx(3*r),m=d&&Bx(r),x=n.master.getRect(),_=c?x.width:x.height,b=e.getStore(),w=0;null!=(i=t.next());){var S=b.get(h?g:o,i),M=b.get(a,i),I=p,T=void 0;h&&(T=+S-b.get(o,i));var C=void 0,D=void 0,A=void 0,k=void 0;if(c){var L=n.dataToPoint([S,M]);if(h)I=n.dataToPoint([T,M])[0];C=I,D=L[1]+v,A=L[0]-I,k=y,Math.abs(A)0)for(var s=0;s=0;--s)if(l[u]){o=l[u];break}o=o||a.none}if(Y(o)){var h=null==t.level?0:t.level>=0?t.level:o.length+t.level;o=o[h=Math.min(h,o.length-1)]}}return Jc(new Date(t.value),o,r,i)}(t,e,n,this.getSetting("locale"),i)},e.prototype.getTicks=function(){var t=this._interval,e=this._extent,n=[];if(!t)return n;n.push({value:e[0],level:0});var i=this.getSetting("useUTC"),r=function(t,e,n,i){var r=1e4,o=jc,a=0;function s(t,e,n,r,o,a,s){for(var l=new Date(e),u=e,h=l[r]();u1&&0===u&&o.unshift({value:o[0].value-p})}}for(u=0;u=i[0]&&v<=i[1]&&c++)}var m=(i[1]-i[0])/e;if(c>1.5*m&&p>m/1.5)break;if(u.push(g),c>m||t===o[d])break}h=[]}}0;var x=B(z(u,(function(t){return B(t,(function(t){return t.value>=i[0]&&t.value<=i[1]&&!t.notAdd}))})),(function(t){return t.length>0})),_=[],b=x.length-1;for(d=0;dn&&(this._approxInterval=n);var o=$x.length,a=Math.min(function(t,e,n,i){for(;n>>1;t[r][1]16?16:t>7.5?7:t>3.5?4:t>1.5?2:1}function Qx(t){return(t/=2592e6)>6?6:t>3?3:t>2?2:1}function t_(t){return(t/=Gc)>12?12:t>6?6:t>3.5?4:t>2?2:1}function e_(t,e){return(t/=e?Fc:Bc)>30?30:t>20?20:t>15?15:t>10?10:t>5?5:t>2?2:1}function n_(t){return po(t,!0)}function i_(t,e,n){var i=new Date(t);switch(Kc(e)){case"year":case"month":i[up(n)](0);case"day":i[hp(n)](1);case"hour":i[cp(n)](0);case"minute":i[pp(n)](0);case"second":i[dp(n)](0),i[fp(n)](0)}return i.getTime()}bx.registerClass(Kx);var r_=bx.prototype,o_=Ex.prototype,a_=Jr,s_=Math.floor,l_=Math.ceil,u_=Math.pow,h_=Math.log,c_=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="log",e.base=10,e._originalScale=new Ex,e._interval=0,e}return n(e,t),e.prototype.getTicks=function(t){var e=this._originalScale,n=this._extent,i=e.getExtent();return z(o_.getTicks.call(this,t),(function(t){var e=t.value,r=Jr(u_(this.base,e));return r=e===n[0]&&this._fixMin?d_(r,i[0]):r,{value:r=e===n[1]&&this._fixMax?d_(r,i[1]):r}}),this)},e.prototype.setExtent=function(t,e){var n=h_(this.base);t=h_(Math.max(0,t))/n,e=h_(Math.max(0,e))/n,o_.setExtent.call(this,t,e)},e.prototype.getExtent=function(){var t=this.base,e=r_.getExtent.call(this);e[0]=u_(t,e[0]),e[1]=u_(t,e[1]);var n=this._originalScale.getExtent();return this._fixMin&&(e[0]=d_(e[0],n[0])),this._fixMax&&(e[1]=d_(e[1],n[1])),e},e.prototype.unionExtent=function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=h_(t[0])/h_(e),t[1]=h_(t[1])/h_(e),r_.unionExtent.call(this,t)},e.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},e.prototype.calcNiceTicks=function(t){t=t||10;var e=this._extent,n=e[1]-e[0];if(!(n===1/0||n<=0)){var i=ho(n);for(t/n*i<=.5&&(i*=10);!isNaN(i)&&Math.abs(i)<1&&Math.abs(i)>0;)i*=10;var r=[Jr(l_(e[0]/i)*i),Jr(s_(e[1]/i)*i)];this._interval=i,this._niceExtent=r}},e.prototype.calcNiceExtent=function(t){o_.calcNiceExtent.call(this,t),this._fixMin=t.fixMin,this._fixMax=t.fixMax},e.prototype.parse=function(t){return t},e.prototype.contain=function(t){return Lx(t=h_(t)/h_(this.base),this._extent)},e.prototype.normalize=function(t){return Px(t=h_(t)/h_(this.base),this._extent)},e.prototype.scale=function(t){return t=Ox(t,this._extent),u_(this.base,t)},e.type="log",e}(bx),p_=c_.prototype;function d_(t,e){return a_(t,to(e))}p_.getMinorTicks=o_.getMinorTicks,p_.getLabel=o_.getLabel,bx.registerClass(c_);var f_=function(){function t(t,e,n){this._prepareParams(t,e,n)}return t.prototype._prepareParams=function(t,e,n){n[1]0&&s>0&&!l&&(a=0),a<0&&s<0&&!u&&(s=0));var c=this._determinedMin,p=this._determinedMax;return null!=c&&(a=c,l=!0),null!=p&&(s=p,u=!0),{min:a,max:s,minFixed:l,maxFixed:u,isBlank:h}},t.prototype.modifyDataMinMax=function(t,e){this[y_[t]]=e},t.prototype.setDeterminedMinMax=function(t,e){var n=g_[t];this[n]=e},t.prototype.freeze=function(){this.frozen=!0},t}(),g_={min:"_determinedMin",max:"_determinedMax"},y_={min:"_dataMin",max:"_dataMax"};function v_(t,e,n){var i=t.rawExtentInfo;return i||(i=new f_(t,e,n),t.rawExtentInfo=i,i)}function m_(t,e){return null==e?null:nt(e)?NaN:t.parse(e)}function x_(t,e){var n=t.type,i=v_(t,e,t.getExtent()).calculate();t.setBlank(i.isBlank);var r=i.min,o=i.max,a=e.ecModel;if(a&&"time"===n){var s=Hx("bar",a),l=!1;if(E(s,(function(t){l=l||t.getBaseAxis()===e.axis})),l){var u=Yx(s),h=function(t,e,n,i){var r=n.axis.getExtent(),o=Math.abs(r[1]-r[0]),a=function(t,e,n){if(t&&e){var i=t[Wx(e)];return null!=i&&null!=n?i[Gx(n)]:i}}(i,n.axis);if(void 0===a)return{min:t,max:e};var s=1/0;E(a,(function(t){s=Math.min(t.offset,s)}));var l=-1/0;E(a,(function(t){l=Math.max(t.offset+t.width,l)})),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=h/(1-(s+l)/o)-h;return e+=c*(l/u),t-=c*(s/u),{min:t,max:e}}(r,o,e,u);r=h.min,o=h.max}}return{extent:[r,o],fixMin:i.minFixed,fixMax:i.maxFixed}}function __(t,e){var n=e,i=x_(t,n),r=i.extent,o=n.get("splitNumber");t instanceof c_&&(t.base=n.get("logBase"));var a=t.type,s=n.get("interval"),l="interval"===a||"time"===a;t.setExtent(r[0],r[1]),t.calcNiceExtent({splitNumber:o,fixMin:i.fixMin,fixMax:i.fixMax,minInterval:l?n.get("minInterval"):null,maxInterval:l?n.get("maxInterval"):null}),null!=s&&t.setInterval&&t.setInterval(s)}function b_(t,e){if(e=e||t.get("type"))switch(e){case"category":return new Rx({ordinalMeta:t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),extent:[1/0,-1/0]});case"time":return new Kx({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC")});default:return new(bx.getClass(e)||Ex)}}function w_(t){var e,n,i=t.getLabelModel().get("formatter"),r="category"===t.type?t.scale.getExtent()[0]:null;return"time"===t.scale.type?(n=i,function(e,i){return t.scale.getFormattedLabel(e,i,n)}):U(i)?function(e){return function(n){var i=t.scale.getLabel(n);return e.replace("{value}",null!=i?i:"")}}(i):X(i)?(e=i,function(n,i){return null!=r&&(i=n.value-r),e(S_(t,n),i,null!=n.level?{level:n.level}:null)}):function(e){return t.scale.getLabel(e)}}function S_(t,e){return"category"===t.type?t.scale.getLabel(e):e.value}function M_(t,e){var n=e*Math.PI/180,i=t.width,r=t.height,o=i*Math.abs(Math.cos(n))+Math.abs(r*Math.sin(n)),a=i*Math.abs(Math.sin(n))+Math.abs(r*Math.cos(n));return new ze(t.x,t.y,o,a)}function I_(t){var e=t.get("interval");return null==e?"auto":e}function T_(t){return"category"===t.type&&0===I_(t.getLabelModel())}function C_(t,e){var n={};return E(t.mapDimensionsAll(e),(function(e){n[xx(t,e)]=!0})),G(n)}var D_=function(){function t(){}return t.prototype.getNeedCrossZero=function(){return!this.option.scale},t.prototype.getCoordSysModel=function(){},t}();var A_={isDimensionStacked:mx,enableDataStack:vx,getStackedDimension:xx};var k_=Object.freeze({__proto__:null,createList:function(t){return _x(null,t)},getLayoutRect:kp,dataStack:A_,createScale:function(t,e){var n=e;e instanceof Cc||(n=new Cc(e));var i=b_(n);return i.setExtent(t[0],t[1]),__(i,n),i},mixinAxisModelCommonMethods:function(t){R(t,D_)},getECData:rl,createTextStyle:function(t,e){return oc(t,null,null,"normal"!==(e=e||{}).state)},createDimensions:function(t,e){return px(t,e).dimensions},createSymbol:Xy,enableHoverEmphasis:Ul});function L_(t,e){return Math.abs(t-e)<1e-8}function P_(t,e,n){var i=0,r=t[0];if(!r)return!1;for(var o=1;on&&(t=r,n=a)}if(t)return function(t){for(var e=0,n=0,i=0,r=t.length,o=t[r-1][0],a=t[r-1][1],s=0;s>1^-(1&s),l=l>>1^-(1&l),r=s+=r,o=l+=o,i.push([s/n,l/n])}return i}function H_(t,e){return z(B((t=function(t){if(!t.UTF8Encoding)return t;var e=t,n=e.UTF8Scale;return null==n&&(n=1024),E(e.features,(function(t){var e=t.geometry,i=e.encodeOffsets,r=e.coordinates;if(i)switch(e.type){case"LineString":e.coordinates=W_(r,i,n);break;case"Polygon":case"MultiLineString":G_(r,i,n);break;case"MultiPolygon":E(r,(function(t,e){return G_(t,i[e],n)}))}})),e.UTF8Encoding=!1,e}(t)).features,(function(t){return t.geometry&&t.properties&&t.geometry.coordinates.length>0})),(function(t){var n=t.properties,i=t.geometry,r=[];switch(i.type){case"Polygon":var o=i.coordinates;r.push(new z_(o[0],o.slice(1)));break;case"MultiPolygon":E(i.coordinates,(function(t){t[0]&&r.push(new z_(t[0],t.slice(1)))}));break;case"LineString":r.push(new V_([i.coordinates]));break;case"MultiLineString":r.push(new V_(i.coordinates))}var a=new B_(n[e||"name"],r,n.cp);return a.properties=n,a}))}var Y_=Object.freeze({__proto__:null,linearMap:Kr,round:Jr,asc:Qr,getPrecision:to,getPrecisionSafe:eo,getPixelPrecision:no,getPercentWithPrecision:function(t,e,n){return t[e]&&io(t,n)[e]||0},MAX_SAFE_INTEGER:oo,remRadian:ao,isRadianAroundZero:so,parseDate:uo,quantity:ho,quantityExponent:co,nice:po,quantile:fo,reformIntervals:go,isNumeric:vo,numericToNumber:yo}),X_=Object.freeze({__proto__:null,parse:uo,format:Jc}),U_=Object.freeze({__proto__:null,extendShape:Ch,extendPath:Ah,makePath:Ph,makeImage:Oh,mergePath:Nh,resizePath:Eh,createIcon:Uh,updateProps:vh,initProps:mh,getTransform:Bh,clipPointsByRect:Yh,clipRectByRect:Xh,registerShape:kh,getShapeClass:Lh,Group:Br,Image:Ns,Text:Xs,Circle:Su,Ellipse:Iu,Sector:Fu,Ring:Wu,Polygon:Xu,Polyline:Zu,Rect:Ws,Line:Ku,BezierCurve:th,Arc:nh,IncrementalDisplayable:dh,CompoundPath:ih,LinearGradient:oh,RadialGradient:ah,BoundingRect:ze}),Z_=Object.freeze({__proto__:null,addCommas:gp,toCamelCase:yp,normalizeCssArray:vp,encodeHTML:re,formatTpl:bp,getTooltipMarker:wp,formatTime:function(t,e,n){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var i=uo(e),r=n?"getUTC":"get",o=i[r+"FullYear"](),a=i[r+"Month"]()+1,s=i[r+"Date"](),l=i[r+"Hours"](),u=i[r+"Minutes"](),h=i[r+"Seconds"](),c=i[r+"Milliseconds"]();return t=t.replace("MM",qc(a,2)).replace("M",a).replace("yyyy",o).replace("yy",qc(o%100+"",2)).replace("dd",qc(s,2)).replace("d",s).replace("hh",qc(l,2)).replace("h",l).replace("mm",qc(u,2)).replace("m",u).replace("ss",qc(h,2)).replace("s",h).replace("SSS",qc(c,3))},capitalFirst:function(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t},truncateText:function(t,e,n,i,r){var o={};return pa(o,t,e,n,i,r),o.text},getTextRect:function(t,e,n,i,r,o,a,s){return new Xs({style:{text:t,font:e,align:n,verticalAlign:i,padding:r,rich:o,overflow:a?"truncate":null,lineHeight:s}}).getBoundingRect()}}),j_=Object.freeze({__proto__:null,map:z,each:E,indexOf:P,inherits:O,reduce:V,filter:B,bind:W,curry:H,isArray:Y,isString:U,isObject:q,isFunction:X,extend:A,defaults:k,clone:T,merge:C}),q_=Vo();function K_(t,e){var n=z(e,(function(e){return t.scale.parse(e)}));return"time"===t.type&&n.length>0&&(n.sort(),n.unshift(n[0]),n.push(n[n.length-1])),n}function $_(t){var e=t.getLabelModel().get("customValues");if(e){var n=w_(t),i=t.scale.getExtent();return{labels:z(B(K_(t,e),(function(t){return t>=i[0]&&t<=i[1]})),(function(e){var i={value:e};return{formattedLabel:n(i),rawLabel:t.scale.getLabel(i),tickValue:e}}))}}return"category"===t.type?function(t){var e=t.getLabelModel(),n=Q_(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:n.labelCategoryInterval}:n}(t):function(t){var e=t.scale.getTicks(),n=w_(t);return{labels:z(e,(function(e,i){return{level:e.level,formattedLabel:n(e,i),rawLabel:t.scale.getLabel(e),tickValue:e.value}}))}}(t)}function J_(t,e){var n=t.getTickModel().get("customValues");if(n){var i=t.scale.getExtent();return{ticks:B(K_(t,n),(function(t){return t>=i[0]&&t<=i[1]}))}}return"category"===t.type?function(t,e){var n,i,r=tb(t,"ticks"),o=I_(e),a=eb(r,o);if(a)return a;e.get("show")&&!t.scale.isBlank()||(n=[]);if(X(o))n=rb(t,o,!0);else if("auto"===o){var s=Q_(t,t.getLabelModel());i=s.labelCategoryInterval,n=z(s.labels,(function(t){return t.tickValue}))}else n=ib(t,i=o,!0);return nb(r,o,{ticks:n,tickCategoryInterval:i})}(t,e):{ticks:z(t.scale.getTicks(),(function(t){return t.value}))}}function Q_(t,e){var n,i,r=tb(t,"labels"),o=I_(e),a=eb(r,o);return a||(X(o)?n=rb(t,o):(i="auto"===o?function(t){var e=q_(t).autoInterval;return null!=e?e:q_(t).autoInterval=t.calculateCategoryInterval()}(t):o,n=ib(t,i)),nb(r,o,{labels:n,labelCategoryInterval:i}))}function tb(t,e){return q_(t)[e]||(q_(t)[e]=[])}function eb(t,e){for(var n=0;n1&&h/l>2&&(u=Math.round(Math.ceil(u/l)*l));var c=T_(t),p=a.get("showMinLabel")||c,d=a.get("showMaxLabel")||c;p&&u!==o[0]&&g(o[0]);for(var f=u;f<=o[1];f+=l)g(f);function g(t){var e={value:t};s.push(n?t:{formattedLabel:i(e),rawLabel:r.getLabel(e),tickValue:t})}return d&&f-l!==o[1]&&g(o[1]),s}function rb(t,e,n){var i=t.scale,r=w_(t),o=[];return E(i.getTicks(),(function(t){var a=i.getLabel(t),s=t.value;e(t.value,a)&&o.push(n?s:{formattedLabel:r(t),rawLabel:a,tickValue:s})})),o}var ob=[0,1],ab=function(){function t(t,e,n){this.onBand=!1,this.inverse=!1,this.dim=t,this.scale=e,this._extent=n||[0,0]}return t.prototype.contain=function(t){var e=this._extent,n=Math.min(e[0],e[1]),i=Math.max(e[0],e[1]);return t>=n&&t<=i},t.prototype.containData=function(t){return this.scale.contain(t)},t.prototype.getExtent=function(){return this._extent.slice()},t.prototype.getPixelPrecision=function(t){return no(t||this.scale.getExtent(),this._extent)},t.prototype.setExtent=function(t,e){var n=this._extent;n[0]=t,n[1]=e},t.prototype.dataToCoord=function(t,e){var n=this._extent,i=this.scale;return t=i.normalize(t),this.onBand&&"ordinal"===i.type&&sb(n=n.slice(),i.count()),Kr(t,ob,n,e)},t.prototype.coordToData=function(t,e){var n=this._extent,i=this.scale;this.onBand&&"ordinal"===i.type&&sb(n=n.slice(),i.count());var r=Kr(t,n,ob,e);return this.scale.scale(r)},t.prototype.pointToData=function(t,e){},t.prototype.getTicksCoords=function(t){var e=(t=t||{}).tickModel||this.getTickModel(),n=z(J_(this,e).ticks,(function(t){return{coord:this.dataToCoord("ordinal"===this.scale.type?this.scale.getRawOrdinalNumber(t):t),tickValue:t}}),this);return function(t,e,n,i){var r=e.length;if(!t.onBand||n||!r)return;var o,a,s=t.getExtent();if(1===r)e[0].coord=s[0],o=e[1]={coord:s[1],tickValue:e[0].tickValue};else{var l=e[r-1].tickValue-e[0].tickValue,u=(e[r-1].coord-e[0].coord)/l;E(e,(function(t){t.coord-=u/2}));var h=t.scale.getExtent();a=1+h[1]-e[r-1].tickValue,o={coord:e[r-1].coord+u*a,tickValue:h[1]+1},e.push(o)}var c=s[0]>s[1];p(e[0].coord,s[0])&&(i?e[0].coord=s[0]:e.shift());i&&p(s[0],e[0].coord)&&e.unshift({coord:s[0]});p(s[1],o.coord)&&(i?o.coord=s[1]:e.pop());i&&p(o.coord,s[1])&&e.push({coord:s[1]});function p(t,e){return t=Jr(t),e=Jr(e),c?t>e:t0&&t<100||(t=5),z(this.scale.getMinorTicks(t),(function(t){return z(t,(function(t){return{coord:this.dataToCoord(t),tickValue:t}}),this)}),this)},t.prototype.getViewLabels=function(){return $_(this).labels},t.prototype.getLabelModel=function(){return this.model.getModel("axisLabel")},t.prototype.getTickModel=function(){return this.model.getModel("axisTick")},t.prototype.getBandWidth=function(){var t=this._extent,e=this.scale.getExtent(),n=e[1]-e[0]+(this.onBand?1:0);0===n&&(n=1);var i=Math.abs(t[1]-t[0]);return Math.abs(i)/n},t.prototype.calculateCategoryInterval=function(){return function(t){var e=function(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}(t),n=w_(t),i=(e.axisRotate-e.labelRotate)/180*Math.PI,r=t.scale,o=r.getExtent(),a=r.count();if(o[1]-o[0]<1)return 0;var s=1;a>40&&(s=Math.max(1,Math.floor(a/40)));for(var l=o[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(i)),c=Math.abs(u*Math.sin(i)),p=0,d=0;l<=o[1];l+=s){var f,g,y=Sr(n({value:l}),e.font,"center","top");f=1.3*y.width,g=1.3*y.height,p=Math.max(p,f,7),d=Math.max(d,g,7)}var v=p/h,m=d/c;isNaN(v)&&(v=1/0),isNaN(m)&&(m=1/0);var x=Math.max(0,Math.floor(Math.min(v,m))),_=q_(t.model),b=t.getExtent(),w=_.lastAutoInterval,S=_.lastTickCount;return null!=w&&null!=S&&Math.abs(w-x)<=1&&Math.abs(S-a)<=1&&w>x&&_.axisExtent0===b[0]&&_.axisExtent1===b[1]?x=w:(_.lastTickCount=a,_.lastAutoInterval=x,_.axisExtent0=b[0],_.axisExtent1=b[1]),x}(this)},t}();function sb(t,e){var n=(t[1]-t[0])/e/2;t[0]+=n,t[1]-=n}var lb=2*Math.PI,ub=hs.CMD,hb=["top","right","bottom","left"];function cb(t,e,n,i,r){var o=n.width,a=n.height;switch(t){case"top":i.set(n.x+o/2,n.y-e),r.set(0,-1);break;case"bottom":i.set(n.x+o/2,n.y+a+e),r.set(0,1);break;case"left":i.set(n.x-e,n.y+a/2),r.set(-1,0);break;case"right":i.set(n.x+o+e,n.y+a/2),r.set(1,0)}}function pb(t,e,n,i,r,o,a,s,l){a-=t,s-=e;var u=Math.sqrt(a*a+s*s),h=(a/=u)*n+t,c=(s/=u)*n+e;if(Math.abs(i-r)%lb<1e-4)return l[0]=h,l[1]=c,u-n;if(o){var p=i;i=gs(r),r=gs(p)}else i=gs(i),r=gs(r);i>r&&(r+=lb);var d=Math.atan2(s,a);if(d<0&&(d+=lb),d>=i&&d<=r||d+lb>=i&&d+lb<=r)return l[0]=h,l[1]=c,u-n;var f=n*Math.cos(i)+t,g=n*Math.sin(i)+e,y=n*Math.cos(r)+t,v=n*Math.sin(r)+e,m=(f-a)*(f-a)+(g-s)*(g-s),x=(y-a)*(y-a)+(v-s)*(v-s);return m0){e=e/180*Math.PI,mb.fromArray(t[0]),xb.fromArray(t[1]),_b.fromArray(t[2]),De.sub(bb,mb,xb),De.sub(wb,_b,xb);var n=bb.len(),i=wb.len();if(!(n<.001||i<.001)){bb.scale(1/n),wb.scale(1/i);var r=bb.dot(wb);if(Math.cos(e)1&&De.copy(Ib,_b),Ib.toArray(t[1])}}}}function Cb(t,e,n){if(n<=180&&n>0){n=n/180*Math.PI,mb.fromArray(t[0]),xb.fromArray(t[1]),_b.fromArray(t[2]),De.sub(bb,xb,mb),De.sub(wb,_b,xb);var i=bb.len(),r=wb.len();if(!(i<.001||r<.001))if(bb.scale(1/i),wb.scale(1/r),bb.dot(e)=a)De.copy(Ib,_b);else{Ib.scaleAndAdd(wb,o/Math.tan(Math.PI/2-s));var l=_b.x!==xb.x?(Ib.x-xb.x)/(_b.x-xb.x):(Ib.y-xb.y)/(_b.y-xb.y);if(isNaN(l))return;l<0?De.copy(Ib,xb):l>1&&De.copy(Ib,_b)}Ib.toArray(t[1])}}}function Db(t,e,n,i){var r="normal"===n,o=r?t:t.ensureState(n);o.ignore=e;var a=i.get("smooth");a&&!0===a&&(a=.3),o.shape=o.shape||{},a>0&&(o.shape.smooth=a);var s=i.getModel("lineStyle").getLineStyle();r?t.useStyle(s):o.style=s}function Ab(t,e){var n=e.smooth,i=e.points;if(i)if(t.moveTo(i[0][0],i[0][1]),n>0&&i.length>=3){var r=Vt(i[0],i[1]),o=Vt(i[1],i[2]);if(!r||!o)return t.lineTo(i[1][0],i[1][1]),void t.lineTo(i[2][0],i[2][1]);var a=Math.min(r,o)*n,s=Gt([],i[1],i[0],a/r),l=Gt([],i[1],i[2],a/o),u=Gt([],s,l,.5);t.bezierCurveTo(s[0],s[1],s[0],s[1],u[0],u[1]),t.bezierCurveTo(l[0],l[1],l[0],l[1],i[2][0],i[2][1])}else for(var h=1;h0&&o&&_(-h/a,0,a);var f,g,y=t[0],v=t[a-1];return m(),f<0&&b(-f,.8),g<0&&b(g,.8),m(),x(f,g,1),x(g,f,-1),m(),f<0&&w(-f),g<0&&w(g),u}function m(){f=y.rect[e]-i,g=r-v.rect[e]-v.rect[n]}function x(t,e,n){if(t<0){var i=Math.min(e,-t);if(i>0){_(i*n,0,a);var r=i+t;r<0&&b(-r*n,1)}else b(-t*n,1)}}function _(n,i,r){0!==n&&(u=!0);for(var o=i;o0)for(l=0;l0;l--){_(-(o[l-1]*c),l,a)}}}function w(t){var e=t<0?-1:1;t=Math.abs(t);for(var n=Math.ceil(t/(a-1)),i=0;i0?_(n,0,i+1):_(-n,a-i-1,a),(t-=n)<=0)return}}function Rb(t,e,n,i){return Ob(t,"y","height",e,n,i)}function Nb(t){var e=[];t.sort((function(t,e){return e.priority-t.priority}));var n=new ze(0,0,0,0);function i(t){if(!t.ignore){var e=t.ensureState("emphasis");null==e.ignore&&(e.ignore=!1)}t.ignore=!0}for(var r=0;r=0&&n.attr(d.oldLayoutSelect),P(u,"emphasis")>=0&&n.attr(d.oldLayoutEmphasis)),vh(n,s,e,a)}else if(n.attr(s),!pc(n).valueAnimation){var h=rt(n.style.opacity,1);n.style.opacity=0,mh(n,{style:{opacity:h}},e,a)}if(d.oldLayout=s,n.states.select){var c=d.oldLayoutSelect={};Wb(c,s,Hb),Wb(c,n.states.select,Hb)}if(n.states.emphasis){var p=d.oldLayoutEmphasis={};Wb(p,s,Hb),Wb(p,n.states.emphasis,Hb)}fc(n,a,l,e,e)}if(i&&!i.ignore&&!i.invisible){r=(d=Gb(i)).oldLayout;var d,f={points:i.shape.points};r?(i.attr({shape:r}),vh(i,{shape:f},e)):(i.setShape(f),i.style.strokePercent=0,mh(i,{style:{strokePercent:1}},e)),d.oldLayout=f}},t}(),Xb=Vo();var Ub=Math.sin,Zb=Math.cos,jb=Math.PI,qb=2*Math.PI,Kb=180/jb,$b=function(){function t(){}return t.prototype.reset=function(t){this._start=!0,this._d=[],this._str="",this._p=Math.pow(10,t||4)},t.prototype.moveTo=function(t,e){this._add("M",t,e)},t.prototype.lineTo=function(t,e){this._add("L",t,e)},t.prototype.bezierCurveTo=function(t,e,n,i,r,o){this._add("C",t,e,n,i,r,o)},t.prototype.quadraticCurveTo=function(t,e,n,i){this._add("Q",t,e,n,i)},t.prototype.arc=function(t,e,n,i,r,o){this.ellipse(t,e,n,n,0,i,r,o)},t.prototype.ellipse=function(t,e,n,i,r,o,a,s){var l=a-o,u=!s,h=Math.abs(l),c=pi(h-qb)||(u?l>=qb:-l>=qb),p=l>0?l%qb:l%qb+qb,d=!1;d=!!c||!pi(h)&&p>=jb==!!u;var f=t+n*Zb(o),g=e+i*Ub(o);this._start&&this._add("M",f,g);var y=Math.round(r*Kb);if(c){var v=1/this._p,m=(u?1:-1)*(qb-v);this._add("A",n,i,y,1,+u,t+n*Zb(o+m),e+i*Ub(o+m)),v>.01&&this._add("A",n,i,y,0,+u,f,g)}else{var x=t+n*Zb(a),_=e+i*Ub(a);this._add("A",n,i,y,+d,+u,x,_)}},t.prototype.rect=function(t,e,n,i){this._add("M",t,e),this._add("l",n,0),this._add("l",0,i),this._add("l",-n,0),this._add("Z")},t.prototype.closePath=function(){this._d.length>0&&this._add("Z")},t.prototype._add=function(t,e,n,i,r,o,a,s,l){for(var u=[],h=this._p,c=1;c"}(r,o)+("style"!==r?re(a):a||"")+(i?""+n+z(i,(function(e){return t(e)})).join(n)+n:"")+("")}(t)}function uw(t){return{zrId:t,shadowCache:{},patternCache:{},gradientCache:{},clipPathCache:{},defs:{},cssNodes:{},cssAnims:{},cssStyleCache:{},cssAnimIdx:0,shadowIdx:0,gradientIdx:0,patternIdx:0,clipPathIdx:0}}function hw(t,e,n,i){return sw("svg","root",{width:t,height:e,xmlns:iw,"xmlns:xlink":rw,version:"1.1",baseProfile:"full",viewBox:!!i&&"0 0 "+t+" "+e},n)}var cw=0;function pw(){return cw++}var dw={cubicIn:"0.32,0,0.67,0",cubicOut:"0.33,1,0.68,1",cubicInOut:"0.65,0,0.35,1",quadraticIn:"0.11,0,0.5,0",quadraticOut:"0.5,1,0.89,1",quadraticInOut:"0.45,0,0.55,1",quarticIn:"0.5,0,0.75,0",quarticOut:"0.25,1,0.5,1",quarticInOut:"0.76,0,0.24,1",quinticIn:"0.64,0,0.78,0",quinticOut:"0.22,1,0.36,1",quinticInOut:"0.83,0,0.17,1",sinusoidalIn:"0.12,0,0.39,0",sinusoidalOut:"0.61,1,0.88,1",sinusoidalInOut:"0.37,0,0.63,1",exponentialIn:"0.7,0,0.84,0",exponentialOut:"0.16,1,0.3,1",exponentialInOut:"0.87,0,0.13,1",circularIn:"0.55,0,1,0.45",circularOut:"0,0.55,0.45,1",circularInOut:"0.85,0,0.15,1"},fw="transform-origin";function gw(t,e,n){var i=A({},t.shape);A(i,e),t.buildPath(n,i);var r=new $b;return r.reset(wi(t)),n.rebuildPath(r,1),r.generateStr(),r.getStr()}function yw(t,e){var n=e.originX,i=e.originY;(n||i)&&(t[fw]=n+"px "+i+"px")}var vw={fill:"fill",opacity:"opacity",lineWidth:"stroke-width",lineDashOffset:"stroke-dashoffset"};function mw(t,e){var n=e.zrId+"-ani-"+e.cssAnimIdx++;return e.cssAnims[n]=t,n}function xw(t){return U(t)?dw[t]?"cubic-bezier("+dw[t]+")":Pn(t)?t:"":""}function _w(t,e,n,i){var r=t.animators,o=r.length,a=[];if(t instanceof ih){var s=function(t,e,n){var i,r,o=t.shape.paths,a={};if(E(o,(function(t){var e=uw(n.zrId);e.animation=!0,_w(t,{},e,!0);var o=e.cssAnims,s=e.cssNodes,l=G(o),u=l.length;if(u){var h=o[r=l[u-1]];for(var c in h){var p=h[c];a[c]=a[c]||{d:""},a[c].d+=p.d||""}for(var d in s){var f=s[d].animation;f.indexOf(r)>=0&&(i=f)}}})),i){e.d=!1;var s=mw(a,n);return i.replace(r,s)}}(t,e,n);if(s)a.push(s);else if(!o)return}else if(!o)return;for(var l={},u=0;u0})).length)return mw(h,n)+" "+r[0]+" both"}for(var y in l){(s=g(l[y]))&&a.push(s)}if(a.length){var v=n.zrId+"-cls-"+pw();n.cssNodes["."+v]={animation:a.join(",")},e.class=v}}function bw(t,e,n,i){var r=JSON.stringify(t),o=n.cssStyleCache[r];o||(o=n.zrId+"-cls-"+pw(),n.cssStyleCache[r]=o,n.cssNodes["."+o+(i?":hover":"")]=t),e.class=e.class?e.class+" "+o:o}var ww=Math.round;function Sw(t){return t&&U(t.src)}function Mw(t){return t&&X(t.toDataURL)}function Iw(t,e,n,i){nw((function(r,o){var a="fill"===r||"stroke"===r;a&&_i(o)?Ew(e,t,r,i):a&&vi(o)?zw(n,t,r,i):t[r]=o,a&&i.ssr&&"none"===o&&(t["pointer-events"]="visible")}),e,n,!1),function(t,e,n){var i=t.style;if(function(t){return t&&(t.shadowBlur||t.shadowOffsetX||t.shadowOffsetY)}(i)){var r=function(t){var e=t.style,n=t.getGlobalScale();return[e.shadowColor,(e.shadowBlur||0).toFixed(2),(e.shadowOffsetX||0).toFixed(2),(e.shadowOffsetY||0).toFixed(2),n[0],n[1]].join(",")}(t),o=n.shadowCache,a=o[r];if(!a){var s=t.getGlobalScale(),l=s[0],u=s[1];if(!l||!u)return;var h=i.shadowOffsetX||0,c=i.shadowOffsetY||0,p=i.shadowBlur,d=hi(i.shadowColor),f=d.opacity,g=d.color,y=p/2/l+" "+p/2/u;a=n.zrId+"-s"+n.shadowIdx++,n.defs[a]=sw("filter",a,{id:a,x:"-100%",y:"-100%",width:"300%",height:"300%"},[sw("feDropShadow","",{dx:h/l,dy:c/u,stdDeviation:y,"flood-color":g,"flood-opacity":f})]),o[r]=a}e.filter=bi(a)}}(n,t,i)}function Tw(t,e){var n=Ur(e);n&&(n.each((function(e,n){null!=e&&(t[(ow+n).toLowerCase()]=e+"")})),e.isSilent()&&(t[ow+"silent"]="true"))}function Cw(t){return pi(t[0]-1)&&pi(t[1])&&pi(t[2])&&pi(t[3]-1)}function Dw(t,e,n){if(e&&(!function(t){return pi(t[4])&&pi(t[5])}(e)||!Cw(e))){var i=n?10:1e4;t.transform=Cw(e)?"translate("+ww(e[4]*i)/i+" "+ww(e[5]*i)/i+")":function(t){return"matrix("+di(t[0])+","+di(t[1])+","+di(t[2])+","+di(t[3])+","+fi(t[4])+","+fi(t[5])+")"}(e)}}function Aw(t,e,n){for(var i=t.points,r=[],o=0;o=0&&a||o;s&&(r=si(s))}var l=i.lineWidth;l&&(l/=!i.strokeNoScale&&t.transform?t.transform[0]:1);var u={cursor:"pointer"};r&&(u.fill=r),i.stroke&&(u.stroke=i.stroke),l&&(u["stroke-width"]=l),bw(u,e,n,!0)}}(t,o,e),sw(s,t.id+"",o)}function Nw(t,e){return t instanceof ks?Rw(t,e):t instanceof Ns?function(t,e){var n=t.style,i=n.image;if(i&&!U(i)&&(Sw(i)?i=i.src:Mw(i)&&(i=i.toDataURL())),i){var r=n.x||0,o=n.y||0,a={href:i,width:n.width,height:n.height};return r&&(a.x=r),o&&(a.y=o),Dw(a,t.transform),Iw(a,n,t,e),Tw(a,t),e.animation&&_w(t,a,e),sw("image",t.id+"",a)}}(t,e):t instanceof Ps?function(t,e){var n=t.style,i=n.text;if(null!=i&&(i+=""),i&&!isNaN(n.x)&&!isNaN(n.y)){var r=n.font||a,s=n.x||0,l=function(t,e,n){return"top"===n?t+=e/2:"bottom"===n&&(t-=e/2),t}(n.y||0,Tr(r),n.textBaseline),u={"dominant-baseline":"central","text-anchor":gi[n.textAlign]||n.textAlign};if($s(n)){var h="",c=n.fontStyle,p=qs(n.fontSize);if(!parseFloat(p))return;var d=n.fontFamily||o,f=n.fontWeight;h+="font-size:"+p+";font-family:"+d+";",c&&"normal"!==c&&(h+="font-style:"+c+";"),f&&"normal"!==f&&(h+="font-weight:"+f+";"),u.style=h}else u.style="font: "+r;return i.match(/\s/)&&(u["xml:space"]="preserve"),s&&(u.x=s),l&&(u.y=l),Dw(u,t.transform),Iw(u,n,t,e),Tw(u,t),e.animation&&_w(t,u,e),sw("text",t.id+"",u,void 0,i)}}(t,e):void 0}function Ew(t,e,n,i){var r,o=t[n],a={gradientUnits:o.global?"userSpaceOnUse":"objectBoundingBox"};if(mi(o))r="linearGradient",a.x1=o.x,a.y1=o.y,a.x2=o.x2,a.y2=o.y2;else{if(!xi(o))return void 0;r="radialGradient",a.cx=rt(o.x,.5),a.cy=rt(o.y,.5),a.r=rt(o.r,.5)}for(var s=o.colorStops,l=[],u=0,h=s.length;ul?Jw(t,null==n[c+1]?null:n[c+1].elm,n,s,c):Qw(t,e,a,l))}(n,i,r):jw(r)?(jw(t.text)&&Xw(n,""),Jw(n,null,r,0,r.length-1)):jw(i)?Qw(n,i,0,i.length-1):jw(t.text)&&Xw(n,""):t.text!==e.text&&(jw(i)&&Qw(n,i,0,i.length-1),Xw(n,e.text)))}var nS=0,iS=function(){function t(t,e,n){if(this.type="svg",this.refreshHover=rS("refreshHover"),this.configLayer=rS("configLayer"),this.storage=e,this._opts=n=A({},n),this.root=t,this._id="zr"+nS++,this._oldVNode=hw(n.width,n.height),t&&!n.ssr){var i=this._viewport=document.createElement("div");i.style.cssText="position:relative;overflow:hidden";var r=this._svgDom=this._oldVNode.elm=aw("svg");tS(null,this._oldVNode),i.appendChild(r),t.appendChild(i)}this.resize(n.width,n.height)}return t.prototype.getType=function(){return this.type},t.prototype.getViewportRoot=function(){return this._viewport},t.prototype.getViewportRootOffset=function(){var t=this.getViewportRoot();if(t)return{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}},t.prototype.getSvgDom=function(){return this._svgDom},t.prototype.refresh=function(){if(this.root){var t=this.renderToVNode({willUpdate:!0});t.attrs.style="position:absolute;left:0;top:0;user-select:none",function(t,e){if(Kw(t,e))eS(t,e);else{var n=t.elm,i=Hw(n);$w(e),null!==i&&(Fw(i,e.elm,Yw(n)),Qw(i,[t],0,0))}}(this._oldVNode,t),this._oldVNode=t}},t.prototype.renderOneToVNode=function(t){return Nw(t,uw(this._id))},t.prototype.renderToVNode=function(t){t=t||{};var e=this.storage.getDisplayList(!0),n=this._width,i=this._height,r=uw(this._id);r.animation=t.animation,r.willUpdate=t.willUpdate,r.compress=t.compress,r.emphasis=t.emphasis,r.ssr=this._opts.ssr;var o=[],a=this._bgVNode=function(t,e,n,i){var r;if(n&&"none"!==n)if(r=sw("rect","bg",{width:t,height:e,x:"0",y:"0"}),_i(n))Ew({fill:n},r.attrs,"fill",i);else if(vi(n))zw({style:{fill:n},dirty:bt,getBoundingRect:function(){return{width:t,height:e}}},r.attrs,"fill",i);else{var o=hi(n),a=o.color,s=o.opacity;r.attrs.fill=a,s<1&&(r.attrs["fill-opacity"]=s)}return r}(n,i,this._backgroundColor,r);a&&o.push(a);var s=t.compress?null:this._mainVNode=sw("g","main",{},[]);this._paintList(e,r,s?s.children:o),s&&o.push(s);var l=z(G(r.defs),(function(t){return r.defs[t]}));if(l.length&&o.push(sw("defs","defs",{},l)),t.animation){var u=function(t,e,n){var i=(n=n||{}).newline?"\n":"",r=" {"+i,o=i+"}",a=z(G(t),(function(e){return e+r+z(G(t[e]),(function(n){return n+":"+t[e][n]+";"})).join(i)+o})).join(i),s=z(G(e),(function(t){return"@keyframes "+t+r+z(G(e[t]),(function(n){return n+r+z(G(e[t][n]),(function(i){var r=e[t][n][i];return"d"===i&&(r='path("'+r+'")'),i+":"+r+";"})).join(i)+o})).join(i)+o})).join(i);return a||s?[""].join(i):""}(r.cssNodes,r.cssAnims,{newline:!0});if(u){var h=sw("style","stl",{},[],u);o.push(h)}}return hw(n,i,o,t.useViewBox)},t.prototype.renderToString=function(t){return t=t||{},lw(this.renderToVNode({animation:rt(t.cssAnimation,!0),emphasis:rt(t.cssEmphasis,!0),willUpdate:!1,compress:!0,useViewBox:rt(t.useViewBox,!0)}),{newline:!0})},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t},t.prototype.getSvgRoot=function(){return this._mainVNode&&this._mainVNode.elm},t.prototype._paintList=function(t,e,n){for(var i,r,o=t.length,a=[],s=0,l=0,u=0;u=0&&(!c||!r||c[f]!==r[f]);f--);for(var g=d-1;g>f;g--)i=a[--s-1];for(var y=f+1;y=a)}}for(var h=this.__startIndex;h15)break}n.prevElClipPaths&&u.restore()};if(p)if(0===p.length)s=l.__endIndex;else for(var _=d.dpr,b=0;b0&&t>i[0]){for(s=0;st);s++);a=n[i[s]]}if(i.splice(s+1,0,t),n[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?o.insertBefore(e.dom,l.nextSibling):o.appendChild(e.dom)}else o.firstChild?o.insertBefore(e.dom,o.firstChild):o.appendChild(e.dom);e.painter||(e.painter=this)}},t.prototype.eachLayer=function(t,e){for(var n=this._zlevelList,i=0;i0?uS:0),this._needsManuallyCompositing),u.__builtin__||I("ZLevel "+l+" has been used by unkown layer "+u.id),u!==o&&(u.__used=!0,u.__startIndex!==r&&(u.__dirty=!0),u.__startIndex=r,u.incremental?u.__drawIndex=-1:u.__drawIndex=r,e(r),o=u),1&s.__dirty&&!s.__inHover&&(u.__dirty=!0,u.incremental&&u.__drawIndex<0&&(u.__drawIndex=r))}e(r),this.eachBuiltinLayer((function(t,e){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)}))},t.prototype.clear=function(){return this.eachBuiltinLayer(this._clearLayer),this},t.prototype._clearLayer=function(t){t.clear()},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t,E(this._layers,(function(t){t.setUnpainted()}))},t.prototype.configLayer=function(t,e){if(e){var n=this._layerConfig;n[t]?C(n[t],e,!0):n[t]=e;for(var i=0;i-1&&(s.style.stroke=s.style.fill,s.style.fill="#fff",s.style.lineWidth=2),e},e.type="series.line",e.dependencies=["grid","polar"],e.defaultOption={z:3,coordinateSystem:"cartesian2d",legendHoverLink:!0,clip:!0,label:{position:"top"},endLabel:{show:!1,valueAnimation:!0,distance:8},lineStyle:{width:2,type:"solid"},emphasis:{scale:!0},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0,universalTransition:{divideShape:"clone"},triggerLineEvent:!1},e}(bg);function pS(t,e){var n=t.mapDimensionsAll("defaultedLabel"),i=n.length;if(1===i){var r=mf(t,e,n[0]);return null!=r?r+"":null}if(i){for(var o=[],a=0;a=0&&i.push(e[o])}return i.join(" ")}var fS=function(t){function e(e,n,i,r){var o=t.call(this)||this;return o.updateData(e,n,i,r),o}return n(e,t),e.prototype._createSymbol=function(t,e,n,i,r){this.removeAll();var o=Xy(t,-1,-1,2,2,null,r);o.attr({z2:100,culling:!0,scaleX:i[0]/2,scaleY:i[1]/2}),o.drift=gS,this._symbolType=t,this.add(o)},e.prototype.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(null,t)},e.prototype.getSymbolType=function(){return this._symbolType},e.prototype.getSymbolPath=function(){return this.childAt(0)},e.prototype.highlight=function(){Ol(this.childAt(0))},e.prototype.downplay=function(){Rl(this.childAt(0))},e.prototype.setZ=function(t,e){var n=this.childAt(0);n.zlevel=t,n.z=e},e.prototype.setDraggable=function(t,e){var n=this.childAt(0);n.draggable=t,n.cursor=!e&&t?"move":n.cursor},e.prototype.updateData=function(t,n,i,r){this.silent=!1;var o=t.getItemVisual(n,"symbol")||"circle",a=t.hostModel,s=e.getSymbolSize(t,n),l=o!==this._symbolType,u=r&&r.disableAnimation;if(l){var h=t.getItemVisual(n,"symbolKeepAspect");this._createSymbol(o,t,n,s,h)}else{(p=this.childAt(0)).silent=!1;var c={scaleX:s[0]/2,scaleY:s[1]/2};u?p.attr(c):vh(p,c,a,n),Sh(p)}if(this._updateCommon(t,n,s,i,r),l){var p=this.childAt(0);if(!u){c={scaleX:this._sizeX,scaleY:this._sizeY,style:{opacity:p.style.opacity}};p.scaleX=p.scaleY=0,p.style.opacity=0,mh(p,c,a,n)}}u&&this.childAt(0).stopAnimation("leave")},e.prototype._updateCommon=function(t,e,n,i,r){var o,a,s,l,u,h,c,p,d,f=this.childAt(0),g=t.hostModel;if(i&&(o=i.emphasisItemStyle,a=i.blurItemStyle,s=i.selectItemStyle,l=i.focus,u=i.blurScope,c=i.labelStatesModels,p=i.hoverScale,d=i.cursorStyle,h=i.emphasisDisabled),!i||t.hasItemOption){var y=i&&i.itemModel?i.itemModel:t.getItemModel(e),v=y.getModel("emphasis");o=v.getModel("itemStyle").getItemStyle(),s=y.getModel(["select","itemStyle"]).getItemStyle(),a=y.getModel(["blur","itemStyle"]).getItemStyle(),l=v.get("focus"),u=v.get("blurScope"),h=v.get("disabled"),c=rc(y),p=v.getShallow("scale"),d=y.getShallow("cursor")}var m=t.getItemVisual(e,"symbolRotate");f.attr("rotation",(m||0)*Math.PI/180||0);var x=Zy(t.getItemVisual(e,"symbolOffset"),n);x&&(f.x=x[0],f.y=x[1]),d&&f.attr("cursor",d);var _=t.getItemVisual(e,"style"),b=_.fill;if(f instanceof Ns){var w=f.style;f.useStyle(A({image:w.image,x:w.x,y:w.y,width:w.width,height:w.height},_))}else f.__isEmptyBrush?f.useStyle(A({},_)):f.useStyle(_),f.style.decal=null,f.setColor(b,r&&r.symbolInnerColor),f.style.strokeNoScale=!0;var S=t.getItemVisual(e,"liftZ"),M=this._z2;null!=S?null==M&&(this._z2=f.z2,f.z2+=S):null!=M&&(f.z2=M,this._z2=null);var I=r&&r.useNameLabel;ic(f,c,{labelFetcher:g,labelDataIndex:e,defaultText:function(e){return I?t.getName(e):pS(t,e)},inheritColor:b,defaultOpacity:_.opacity}),this._sizeX=n[0]/2,this._sizeY=n[1]/2;var T=f.ensureState("emphasis");T.style=o,f.ensureState("select").style=s,f.ensureState("blur").style=a;var C=null==p||!0===p?Math.max(1.1,3/this._sizeY):isFinite(p)&&p>0?+p:1;T.scaleX=this._sizeX*C,T.scaleY=this._sizeY*C,this.setSymbolScale(1),Zl(this,l,u,h)},e.prototype.setSymbolScale=function(t){this.scaleX=this.scaleY=t},e.prototype.fadeOut=function(t,e,n){var i=this.childAt(0),r=rl(this).dataIndex,o=n&&n.animation;if(this.silent=i.silent=!0,n&&n.fadeLabel){var a=i.getTextContent();a&&_h(a,{style:{opacity:0}},e,{dataIndex:r,removeOpt:o,cb:function(){i.removeTextContent()}})}else i.removeTextContent();_h(i,{style:{opacity:0},scaleX:0,scaleY:0},e,{dataIndex:r,cb:t,removeOpt:o})},e.getSymbolSize=function(t,e){return Uy(t.getItemVisual(e,"symbolSize"))},e}(Br);function gS(t,e){this.parent.drift(t,e)}function yS(t,e,n,i){return e&&!isNaN(e[0])&&!isNaN(e[1])&&!(i.isIgnore&&i.isIgnore(n))&&!(i.clipShape&&!i.clipShape.contain(e[0],e[1]))&&"none"!==t.getItemVisual(n,"symbol")}function vS(t){return null==t||q(t)||(t={isIgnore:t}),t||{}}function mS(t){var e=t.hostModel,n=e.getModel("emphasis");return{emphasisItemStyle:n.getModel("itemStyle").getItemStyle(),blurItemStyle:e.getModel(["blur","itemStyle"]).getItemStyle(),selectItemStyle:e.getModel(["select","itemStyle"]).getItemStyle(),focus:n.get("focus"),blurScope:n.get("blurScope"),emphasisDisabled:n.get("disabled"),hoverScale:n.get("scale"),labelStatesModels:rc(e),cursorStyle:e.get("cursor")}}var xS=function(){function t(t){this.group=new Br,this._SymbolCtor=t||fS}return t.prototype.updateData=function(t,e){this._progressiveEls=null,e=vS(e);var n=this.group,i=t.hostModel,r=this._data,o=this._SymbolCtor,a=e.disableAnimation,s=mS(t),l={disableAnimation:a},u=e.getSymbolPoint||function(e){return t.getItemLayout(e)};r||n.removeAll(),t.diff(r).add((function(i){var r=u(i);if(yS(t,r,i,e)){var a=new o(t,i,s,l);a.setPosition(r),t.setItemGraphicEl(i,a),n.add(a)}})).update((function(h,c){var p=r.getItemGraphicEl(c),d=u(h);if(yS(t,d,h,e)){var f=t.getItemVisual(h,"symbol")||"circle",g=p&&p.getSymbolType&&p.getSymbolType();if(!p||g&&g!==f)n.remove(p),(p=new o(t,h,s,l)).setPosition(d);else{p.updateData(t,h,s,l);var y={x:d[0],y:d[1]};a?p.attr(y):vh(p,y,i)}n.add(p),t.setItemGraphicEl(h,p)}else n.remove(p)})).remove((function(t){var e=r.getItemGraphicEl(t);e&&e.fadeOut((function(){n.remove(e)}),i)})).execute(),this._getSymbolPoint=u,this._data=t},t.prototype.updateLayout=function(){var t=this,e=this._data;e&&e.eachItemGraphicEl((function(e,n){var i=t._getSymbolPoint(n);e.setPosition(i),e.markRedraw()}))},t.prototype.incrementalPrepareUpdate=function(t){this._seriesScope=mS(t),this._data=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e,n){function i(t){t.isGroup||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}this._progressiveEls=[],n=vS(n);for(var r=t.start;r0?n=i[0]:i[1]<0&&(n=i[1]);return n}(r,n),a=i.dim,s=r.dim,l=e.mapDimension(s),u=e.mapDimension(a),h="x"===s||"radius"===s?1:0,c=z(t.dimensions,(function(t){return e.mapDimension(t)})),p=!1,d=e.getCalculationInfo("stackResultDimension");return mx(e,c[0])&&(p=!0,c[0]=d),mx(e,c[1])&&(p=!0,c[1]=d),{dataDimsForPoint:c,valueStart:o,valueAxisDim:s,baseAxisDim:a,stacked:!!p,valueDim:l,baseDim:u,baseDataOffset:h,stackedOverDimension:e.getCalculationInfo("stackedOverDimension")}}function bS(t,e,n,i){var r=NaN;t.stacked&&(r=n.get(n.getCalculationInfo("stackedOverDimension"),i)),isNaN(r)&&(r=t.valueStart);var o=t.baseDataOffset,a=[];return a[o]=n.get(t.baseDim,i),a[1-o]=r,e.dataToPoint(a)}var wS=Math.min,SS=Math.max;function MS(t,e){return isNaN(t)||isNaN(e)}function IS(t,e,n,i,r,o,a,s,l){for(var u,h,c,p,d,f,g=n,y=0;y=r||g<0)break;if(MS(v,m)){if(l){g+=o;continue}break}if(g===n)t[o>0?"moveTo":"lineTo"](v,m),c=v,p=m;else{var x=v-u,_=m-h;if(x*x+_*_<.5){g+=o;continue}if(a>0){for(var b=g+o,w=e[2*b],S=e[2*b+1];w===v&&S===m&&y=i||MS(w,S))d=v,f=m;else{T=w-u,C=S-h;var k=v-u,L=w-v,P=m-h,O=S-m,R=void 0,N=void 0;if("x"===s){var E=T>0?1:-1;d=v-E*(R=Math.abs(k))*a,f=m,D=v+E*(N=Math.abs(L))*a,A=m}else if("y"===s){var z=C>0?1:-1;d=v,f=m-z*(R=Math.abs(P))*a,D=v,A=m+z*(N=Math.abs(O))*a}else R=Math.sqrt(k*k+P*P),d=v-T*a*(1-(I=(N=Math.sqrt(L*L+O*O))/(N+R))),f=m-C*a*(1-I),A=m+C*a*I,D=wS(D=v+T*a*I,SS(w,v)),A=wS(A,SS(S,m)),D=SS(D,wS(w,v)),f=m-(C=(A=SS(A,wS(S,m)))-m)*R/N,d=wS(d=v-(T=D-v)*R/N,SS(u,v)),f=wS(f,SS(h,m)),D=v+(T=v-(d=SS(d,wS(u,v))))*N/R,A=m+(C=m-(f=SS(f,wS(h,m))))*N/R}t.bezierCurveTo(c,p,d,f,v,m),c=D,p=A}else t.lineTo(v,m)}u=v,h=m,g+=o}return y}var TS=function(){this.smooth=0,this.smoothConstraint=!0},CS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="ec-polyline",n}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new TS},e.prototype.buildPath=function(t,e){var n=e.points,i=0,r=n.length/2;if(e.connectNulls){for(;r>0&&MS(n[2*r-2],n[2*r-1]);r--);for(;i=0){var y=a?(h-i)*g+i:(u-n)*g+n;return a?[t,y]:[y,t]}n=u,i=h;break;case o.C:u=r[l++],h=r[l++],c=r[l++],p=r[l++],d=r[l++],f=r[l++];var v=a?_n(n,u,c,d,t,s):_n(i,h,p,f,t,s);if(v>0)for(var m=0;m=0){y=a?mn(i,h,p,f,x):mn(n,u,c,d,x);return a?[t,y]:[y,t]}}n=d,i=f}}},e}(ks),DS=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e}(TS),AS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="ec-polygon",n}return n(e,t),e.prototype.getDefaultShape=function(){return new DS},e.prototype.buildPath=function(t,e){var n=e.points,i=e.stackedOnPoints,r=0,o=n.length/2,a=e.smoothMonotone;if(e.connectNulls){for(;o>0&&MS(n[2*o-2],n[2*o-1]);o--);for(;r=0;a--){var s=t.getDimensionInfo(i[a].dimension);if("x"===(r=s&&s.coordDim)||"y"===r){o=i[a];break}}if(o){var l=e.getAxis(r),u=z(o.stops,(function(t){return{coord:l.toGlobalCoord(l.dataToCoord(t.value)),color:t.color}})),h=u.length,c=o.outerColors.slice();h&&u[0].coord>u[h-1].coord&&(u.reverse(),c.reverse());var p=function(t,e){var n,i,r=[],o=t.length;function a(t,e,n){var i=t.coord;return{coord:n,color:ti((n-i)/(e.coord-i),[t.color,e.color])}}for(var s=0;se){i?r.push(a(i,l,e)):n&&r.push(a(n,l,0),a(n,l,e));break}n&&(r.push(a(n,l,0)),n=null),r.push(l),i=l}}return r}(u,"x"===r?n.getWidth():n.getHeight()),d=p.length;if(!d&&h)return u[0].coord<0?c[1]?c[1]:u[h-1].color:c[0]?c[0]:u[0].color;var f=p[0].coord-10,g=p[d-1].coord+10,y=g-f;if(y<.001)return"transparent";E(p,(function(t){t.offset=(t.coord-f)/y})),p.push({offset:d?p[d-1].offset:.5,color:c[1]||"transparent"}),p.unshift({offset:d?p[0].offset:.5,color:c[0]||"transparent"});var v=new oh(0,0,0,0,p,!0);return v[r]=f,v[r+"2"]=g,v}}}function FS(t,e,n){var i=t.get("showAllSymbol"),r="auto"===i;if(!i||r){var o=n.getAxesByScale("ordinal")[0];if(o&&(!r||!function(t,e){var n=t.getExtent(),i=Math.abs(n[1]-n[0])/t.scale.count();isNaN(i)&&(i=0);for(var r=e.count(),o=Math.max(1,Math.round(r/5)),a=0;ai)return!1;return!0}(o,e))){var a=e.mapDimension(o.dim),s={};return E(o.getViewLabels(),(function(t){var e=o.scale.getRawOrdinalNumber(t.tickValue);s[e]=1})),function(t){return!s.hasOwnProperty(e.get(a,t))}}}}function GS(t,e){return[t[2*e],t[2*e+1]]}function WS(t){if(t.get(["endLabel","show"]))return!0;for(var e=0;e0&&"bolder"===t.get(["emphasis","lineStyle","width"]))&&(p.getState("emphasis").style.lineWidth=+p.style.lineWidth+1);rl(p).seriesIndex=t.seriesIndex,Zl(p,A,L,P);var O=zS(t.get("smooth")),R=t.get("smoothMonotone");if(p.setShape({smooth:O,smoothMonotone:R,connectNulls:b}),d){var N=o.getCalculationInfo("stackedOnSeries"),E=0;d.useStyle(k(s.getAreaStyle(),{fill:T,opacity:.7,lineJoin:"bevel",decal:o.getVisual("style").decal})),N&&(E=zS(N.get("smooth"))),d.setShape({smooth:O,stackedOnSmooth:E,smoothMonotone:R,connectNulls:b}),$l(d,t,"areaStyle"),rl(d).seriesIndex=t.seriesIndex,Zl(d,A,L,P)}var z=this._changePolyState;o.eachItemGraphicEl((function(t){t&&(t.onHoverStateChange=z)})),this._polyline.onHoverStateChange=z,this._data=o,this._coordSys=i,this._stackedOnPoints=x,this._points=l,this._step=I,this._valueOrigin=v,t.get("triggerLineEvent")&&(this.packEventData(t,p),d&&this.packEventData(t,d))},e.prototype.packEventData=function(t,e){rl(e).eventData={componentType:"series",componentSubType:"line",componentIndex:t.componentIndex,seriesIndex:t.seriesIndex,seriesName:t.name,seriesType:"line"}},e.prototype.highlight=function(t,e,n,i){var r=t.getData(),o=zo(r,i);if(this._changePolyState("emphasis"),!(o instanceof Array)&&null!=o&&o>=0){var a=r.getLayout("points"),s=r.getItemGraphicEl(o);if(!s){var l=a[2*o],u=a[2*o+1];if(isNaN(l)||isNaN(u))return;if(this._clipShapeForSymbol&&!this._clipShapeForSymbol.contain(l,u))return;var h=t.get("zlevel")||0,c=t.get("z")||0;(s=new fS(r,o)).x=l,s.y=u,s.setZ(h,c);var p=s.getSymbolPath().getTextContent();p&&(p.zlevel=h,p.z=c,p.z2=this._polyline.z2+1),s.__temp=!0,r.setItemGraphicEl(o,s),s.stopSymbolAnimation(!0),this.group.add(s)}s.highlight()}else Og.prototype.highlight.call(this,t,e,n,i)},e.prototype.downplay=function(t,e,n,i){var r=t.getData(),o=zo(r,i);if(this._changePolyState("normal"),null!=o&&o>=0){var a=r.getItemGraphicEl(o);a&&(a.__temp?(r.setItemGraphicEl(o,null),this.group.remove(a)):a.downplay())}else Og.prototype.downplay.call(this,t,e,n,i)},e.prototype._changePolyState=function(t){var e=this._polygon;Dl(this._polyline,t),e&&Dl(e,t)},e.prototype._newPolyline=function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new CS({shape:{points:t},segmentIgnoreThreshold:2,z2:10}),this._lineGroup.add(e),this._polyline=e,e},e.prototype._newPolygon=function(t,e){var n=this._polygon;return n&&this._lineGroup.remove(n),n=new AS({shape:{points:t,stackedOnPoints:e},segmentIgnoreThreshold:2}),this._lineGroup.add(n),this._polygon=n,n},e.prototype._initSymbolLabelAnimation=function(t,e,n){var i,r,o=e.getBaseAxis(),a=o.inverse;"cartesian2d"===e.type?(i=o.isHorizontal(),r=!1):"polar"===e.type&&(i="angle"===o.dim,r=!0);var s=t.hostModel,l=s.get("animationDuration");X(l)&&(l=l(null));var u=s.get("animationDelay")||0,h=X(u)?u(null):u;t.eachItemGraphicEl((function(t,o){var s=t;if(s){var c=[t.x,t.y],p=void 0,d=void 0,f=void 0;if(n)if(r){var g=n,y=e.pointToCoord(c);i?(p=g.startAngle,d=g.endAngle,f=-y[1]/180*Math.PI):(p=g.r0,d=g.r,f=y[0])}else{var v=n;i?(p=v.x,d=v.x+v.width,f=t.x):(p=v.y+v.height,d=v.y,f=t.y)}var m=d===p?0:(f-p)/(d-p);a&&(m=1-m);var x=X(u)?u(o):l*m+h,_=s.getSymbolPath(),b=_.getTextContent();s.attr({scaleX:0,scaleY:0}),s.animateTo({scaleX:1,scaleY:1},{duration:200,setToFinal:!0,delay:x}),b&&b.animateFrom({style:{opacity:0}},{duration:300,delay:x}),_.disableLabelAnimation=!0}}))},e.prototype._initOrUpdateEndLabel=function(t,e,n){var i=t.getModel("endLabel");if(WS(t)){var r=t.getData(),o=this._polyline,a=r.getLayout("points");if(!a)return o.removeTextContent(),void(this._endLabel=null);var s=this._endLabel;s||((s=this._endLabel=new Xs({z2:200})).ignoreClip=!0,o.setTextContent(this._endLabel),o.disableLabelAnimation=!0);var l=function(t){for(var e,n,i=t.length/2;i>0&&(e=t[2*i-2],n=t[2*i-1],isNaN(e)||isNaN(n));i--);return i-1}(a);l>=0&&(ic(o,rc(t,"endLabel"),{inheritColor:n,labelFetcher:t,labelDataIndex:l,defaultText:function(t,e,n){return null!=n?dS(r,n):pS(r,t)},enableTextSetter:!0},function(t,e){var n=e.getBaseAxis(),i=n.isHorizontal(),r=n.inverse,o=i?r?"right":"left":"center",a=i?"middle":r?"top":"bottom";return{normal:{align:t.get("align")||o,verticalAlign:t.get("verticalAlign")||a}}}(i,e)),o.textConfig.position=null)}else this._endLabel&&(this._polyline.removeTextContent(),this._endLabel=null)},e.prototype._endLabelOnDuring=function(t,e,n,i,r,o,a){var s=this._endLabel,l=this._polyline;if(s){t<1&&null==i.originalX&&(i.originalX=s.x,i.originalY=s.y);var u=n.getLayout("points"),h=n.hostModel,c=h.get("connectNulls"),p=o.get("precision"),d=o.get("distance")||0,f=a.getBaseAxis(),g=f.isHorizontal(),y=f.inverse,v=e.shape,m=y?g?v.x:v.y+v.height:g?v.x+v.width:v.y,x=(g?d:0)*(y?-1:1),_=(g?0:-d)*(y?-1:1),b=g?"x":"y",w=function(t,e,n){for(var i,r,o=t.length/2,a="x"===n?0:1,s=0,l=-1,u=0;u=e||i>=e&&r<=e){l=u;break}s=u,i=r}else i=r;return{range:[s,l],t:(e-i)/(r-i)}}(u,m,b),S=w.range,M=S[1]-S[0],I=void 0;if(M>=1){if(M>1&&!c){var T=GS(u,S[0]);s.attr({x:T[0]+x,y:T[1]+_}),r&&(I=h.getRawValue(S[0]))}else{(T=l.getPointOn(m,b))&&s.attr({x:T[0]+x,y:T[1]+_});var C=h.getRawValue(S[0]),D=h.getRawValue(S[1]);r&&(I=Zo(n,p,C,D,w.t))}i.lastFrameIndex=S[0]}else{var A=1===t||i.lastFrameIndex>0?S[0]:0;T=GS(u,A);r&&(I=h.getRawValue(A)),s.attr({x:T[0]+x,y:T[1]+_})}if(r){var k=pc(s);"function"==typeof k.setLabelText&&k.setLabelText(I)}}},e.prototype._doUpdateAnimation=function(t,e,n,i,r,o,a){var s=this._polyline,l=this._polygon,u=t.hostModel,h=function(t,e,n,i,r,o,a,s){for(var l=function(t,e){var n=[];return e.diff(t).add((function(t){n.push({cmd:"+",idx:t})})).update((function(t,e){n.push({cmd:"=",idx:e,idx1:t})})).remove((function(t){n.push({cmd:"-",idx:t})})).execute(),n}(t,e),u=[],h=[],c=[],p=[],d=[],f=[],g=[],y=_S(r,e,a),v=t.getLayout("points")||[],m=e.getLayout("points")||[],x=0;x3e3||l&&ES(p,f)>3e3)return s.stopAnimation(),s.setShape({points:d}),void(l&&(l.stopAnimation(),l.setShape({points:d,stackedOnPoints:f})));s.shape.__points=h.current,s.shape.points=c;var g={shape:{points:d}};h.current!==c&&(g.shape.__points=h.next),s.stopAnimation(),vh(s,g,u),l&&(l.setShape({points:c,stackedOnPoints:p}),l.stopAnimation(),vh(l,{shape:{stackedOnPoints:f}},u),s.shape.points!==l.shape.points&&(l.shape.points=s.shape.points));for(var y=[],v=h.status,m=0;me&&(e=t[n]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,n=0;n10&&"cartesian2d"===o.type&&r){var s=o.getBaseAxis(),l=o.getOtherAxis(s),u=s.getExtent(),h=n.getDevicePixelRatio(),c=Math.abs(u[1]-u[0])*(h||1),p=Math.round(a/c);if(isFinite(p)&&p>1){"lttb"===r?t.setData(i.lttbDownSample(i.mapDimension(l.dim),1/p)):"minmax"===r&&t.setData(i.minmaxDownSample(i.mapDimension(l.dim),1/p));var d=void 0;U(r)?d=US[r]:X(r)&&(d=r),d&&t.setData(i.downSample(i.mapDimension(l.dim),1/p,d,ZS))}}}}}var qS=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.getInitialData=function(t,e){return _x(null,this,{useEncodeDefaulter:!0})},e.prototype.getMarkerPosition=function(t,e,n){var i=this.coordinateSystem;if(i&&i.clampData){var r=i.clampData(t),o=i.dataToPoint(r);if(n)E(i.getAxes(),(function(t,n){if("category"===t.type&&null!=e){var i=t.getTicksCoords(),a=t.getTickModel().get("alignWithLabel"),s=r[n],l="x1"===e[n]||"y1"===e[n];if(l&&!a&&(s+=1),i.length<2)return;if(2===i.length)return void(o[n]=t.toGlobalCoord(t.getExtent()[l?1:0]));for(var u=void 0,h=void 0,c=1,p=0;ps){h=(d+u)/2;break}1===p&&(c=f-i[0].tickValue)}null==h&&(u?u&&(h=i[i.length-1].coord):h=i[0].coord),o[n]=t.toGlobalCoord(h)}}));else{var a=this.getData(),s=a.getLayout("offset"),l=a.getLayout("size"),u=i.getBaseAxis().isHorizontal()?0:1;o[u]+=s+l/2}return o}return[NaN,NaN]},e.type="series.__base_bar__",e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,barMinAngle:0,large:!1,largeThreshold:400,progressive:3e3,progressiveChunkMode:"mod"},e}(bg);bg.registerClass(qS);var KS=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.getInitialData=function(){return _x(null,this,{useEncodeDefaulter:!0,createInvertedIndices:!!this.get("realtimeSort",!0)||null})},e.prototype.getProgressive=function(){return!!this.get("large")&&this.get("progressive")},e.prototype.getProgressiveThreshold=function(){var t=this.get("progressiveThreshold"),e=this.get("largeThreshold");return e>t&&(t=e),t},e.prototype.brushSelector=function(t,e,n){return n.rect(e.getItemLayout(t))},e.type="series.bar",e.dependencies=["grid","polar"],e.defaultOption=kc(qS.defaultOption,{clip:!0,roundCap:!1,showBackground:!1,backgroundStyle:{color:"rgba(180, 180, 180, 0.2)",borderColor:null,borderWidth:0,borderType:"solid",borderRadius:0,shadowBlur:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,opacity:1},select:{itemStyle:{borderColor:"#212121"}},realtimeSort:!1}),e}(qS),$S=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0},JS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="sausage",n}return n(e,t),e.prototype.getDefaultShape=function(){return new $S},e.prototype.buildPath=function(t,e){var n=e.cx,i=e.cy,r=Math.max(e.r0||0,0),o=Math.max(e.r,0),a=.5*(o-r),s=r+a,l=e.startAngle,u=e.endAngle,h=e.clockwise,c=2*Math.PI,p=h?u-lo)return!0;o=u}return!1},e.prototype._isOrderDifferentInView=function(t,e){for(var n=e.scale,i=n.getExtent(),r=Math.max(0,i[0]),o=Math.min(i[1],n.getOrdinalMeta().categories.length-1);r<=o;++r)if(t.ordinalNumbers[r]!==n.getRawOrdinalNumber(r))return!0},e.prototype._updateSortWithinSameData=function(t,e,n,i){if(this._isOrderChangedWithinSameData(t,e,n)){var r=this._dataSort(t,n,e);this._isOrderDifferentInView(r,n)&&(this._removeOnRenderedListener(i),i.dispatchAction({type:"changeAxisOrder",componentType:n.dim+"Axis",axisId:n.index,sortInfo:r}))}},e.prototype._dispatchInitSort=function(t,e,n){var i=e.baseAxis,r=this._dataSort(t,i,(function(n){return t.get(t.mapDimension(e.otherAxis.dim),n)}));n.dispatchAction({type:"changeAxisOrder",componentType:i.dim+"Axis",isInitSort:!0,axisId:i.index,sortInfo:r})},e.prototype.remove=function(t,e){this._clear(this._model),this._removeOnRenderedListener(e)},e.prototype.dispose=function(t,e){this._removeOnRenderedListener(e)},e.prototype._removeOnRenderedListener=function(t){this._onRendered&&(t.getZr().off("rendered",this._onRendered),this._onRendered=null)},e.prototype._clear=function(t){var e=this.group,n=this._data;t&&t.isAnimationEnabled()&&n&&!this._isLargeDraw?(this._removeBackground(),this._backgroundEls=[],n.eachItemGraphicEl((function(e){wh(e,t,rl(e).dataIndex)}))):e.removeAll(),this._data=null,this._isFirstFrame=!0},e.prototype._removeBackground=function(){this.group.remove(this._backgroundGroup),this._backgroundGroup=null},e.type="bar",e}(Og),oM={cartesian2d:function(t,e){var n=e.width<0?-1:1,i=e.height<0?-1:1;n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height);var r=t.x+t.width,o=t.y+t.height,a=nM(e.x,t.x),s=iM(e.x+e.width,r),l=nM(e.y,t.y),u=iM(e.y+e.height,o),h=sr?s:a,e.y=c&&l>o?u:l,e.width=h?0:s-a,e.height=c?0:u-l,n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height),h||c},polar:function(t,e){var n=e.r0<=e.r?1:-1;if(n<0){var i=e.r;e.r=e.r0,e.r0=i}var r=iM(e.r,t.r),o=nM(e.r0,t.r0);e.r=r,e.r0=o;var a=r-o<0;if(n<0){i=e.r;e.r=e.r0,e.r0=i}return a}},aM={cartesian2d:function(t,e,n,i,r,o,a,s,l){var u=new Ws({shape:A({},i),z2:1});(u.__dataIndex=n,u.name="item",o)&&(u.shape[r?"height":"width"]=0);return u},polar:function(t,e,n,i,r,o,a,s,l){var u=!r&&l?JS:Fu,h=new u({shape:i,z2:1});h.name="item";var c,p,d=dM(r);if(h.calculateTextPosition=(c=d,p=({isRoundCap:u===JS}||{}).isRoundCap,function(t,e,n){var i=e.position;if(!i||i instanceof Array)return Dr(t,e,n);var r=c(i),o=null!=e.distance?e.distance:5,a=this.shape,s=a.cx,l=a.cy,u=a.r,h=a.r0,d=(u+h)/2,f=a.startAngle,g=a.endAngle,y=(f+g)/2,v=p?Math.abs(u-h)/2:0,m=Math.cos,x=Math.sin,_=s+u*m(f),b=l+u*x(f),w="left",S="top";switch(r){case"startArc":_=s+(h-o)*m(y),b=l+(h-o)*x(y),w="center",S="top";break;case"insideStartArc":_=s+(h+o)*m(y),b=l+(h+o)*x(y),w="center",S="bottom";break;case"startAngle":_=s+d*m(f)+QS(f,o+v,!1),b=l+d*x(f)+tM(f,o+v,!1),w="right",S="middle";break;case"insideStartAngle":_=s+d*m(f)+QS(f,-o+v,!1),b=l+d*x(f)+tM(f,-o+v,!1),w="left",S="middle";break;case"middle":_=s+d*m(y),b=l+d*x(y),w="center",S="middle";break;case"endArc":_=s+(u+o)*m(y),b=l+(u+o)*x(y),w="center",S="bottom";break;case"insideEndArc":_=s+(u-o)*m(y),b=l+(u-o)*x(y),w="center",S="top";break;case"endAngle":_=s+d*m(g)+QS(g,o+v,!0),b=l+d*x(g)+tM(g,o+v,!0),w="left",S="middle";break;case"insideEndAngle":_=s+d*m(g)+QS(g,-o+v,!0),b=l+d*x(g)+tM(g,-o+v,!0),w="right",S="middle";break;default:return Dr(t,e,n)}return(t=t||{}).x=_,t.y=b,t.align=w,t.verticalAlign=S,t}),o){var f=r?"r":"endAngle",g={};h.shape[f]=r?i.r0:i.startAngle,g[f]=i[f],(s?vh:mh)(h,{shape:g},o)}return h}};function sM(t,e,n,i,r,o,a,s){var l,u;o?(u={x:i.x,width:i.width},l={y:i.y,height:i.height}):(u={y:i.y,height:i.height},l={x:i.x,width:i.width}),s||(a?vh:mh)(n,{shape:l},e,r,null),(a?vh:mh)(n,{shape:u},e?t.baseAxis.model:null,r)}function lM(t,e){for(var n=0;n0?1:-1,a=i.height>0?1:-1;return{x:i.x+o*r/2,y:i.y+a*r/2,width:i.width-o*r,height:i.height-a*r}},polar:function(t,e,n){var i=t.getItemLayout(e);return{cx:i.cx,cy:i.cy,r0:i.r0,r:i.r,startAngle:i.startAngle,endAngle:i.endAngle,clockwise:i.clockwise}}};function dM(t){return function(t){var e=t?"Arc":"Angle";return function(t){switch(t){case"start":case"insideStart":case"end":case"insideEnd":return t+e;default:return t}}}(t)}function fM(t,e,n,i,r,o,a,s){var l=e.getItemVisual(n,"style");if(s){if(!o.get("roundCap")){var u=t.shape;A(u,eM(i.getModel("itemStyle"),u,!0)),t.setShape(u)}}else{var h=i.get(["itemStyle","borderRadius"])||0;t.setShape("r",h)}t.useStyle(l);var c=i.getShallow("cursor");c&&t.attr("cursor",c);var p=s?a?r.r>=r.r0?"endArc":"startArc":r.endAngle>=r.startAngle?"endAngle":"startAngle":a?r.height>=0?"bottom":"top":r.width>=0?"right":"left",d=rc(i);ic(t,d,{labelFetcher:o,labelDataIndex:n,defaultText:pS(o.getData(),n),inheritColor:l.fill,defaultOpacity:l.opacity,defaultOutsidePosition:p});var f=t.getTextContent();if(s&&f){var g=i.get(["label","position"]);t.textConfig.inside="middle"===g||null,function(t,e,n,i){if(j(i))t.setTextConfig({rotation:i});else if(Y(e))t.setTextConfig({rotation:0});else{var r,o=t.shape,a=o.clockwise?o.startAngle:o.endAngle,s=o.clockwise?o.endAngle:o.startAngle,l=(a+s)/2,u=n(e);switch(u){case"startArc":case"insideStartArc":case"middle":case"insideEndArc":case"endArc":r=l;break;case"startAngle":case"insideStartAngle":r=a;break;case"endAngle":case"insideEndAngle":r=s;break;default:return void t.setTextConfig({rotation:0})}var h=1.5*Math.PI-r;"middle"===u&&h>Math.PI/2&&h<1.5*Math.PI&&(h-=Math.PI),t.setTextConfig({rotation:h})}}(t,"outside"===g?p:g,dM(a),i.get(["label","rotate"]))}dc(f,d,o.getRawValue(n),(function(t){return dS(e,t)}));var y=i.getModel(["emphasis"]);Zl(t,y.get("focus"),y.get("blurScope"),y.get("disabled")),$l(t,i),function(t){return null!=t.startAngle&&null!=t.endAngle&&t.startAngle===t.endAngle}(r)&&(t.style.fill="none",t.style.stroke="none",E(t.states,(function(t){t.style&&(t.style.fill=t.style.stroke="none")})))}var gM=function(){},yM=function(t){function e(e){var n=t.call(this,e)||this;return n.type="largeBar",n}return n(e,t),e.prototype.getDefaultShape=function(){return new gM},e.prototype.buildPath=function(t,e){for(var n=e.points,i=this.baseDimIdx,r=1-this.baseDimIdx,o=[],a=[],s=this.barWidth,l=0;l=s[0]&&e<=s[0]+l[0]&&n>=s[1]&&n<=s[1]+l[1])return a[h]}return-1}(this,t.offsetX,t.offsetY);rl(this).dataIndex=e>=0?e:null}),30,!1);function xM(t,e,n){if(OS(n,"cartesian2d")){var i=e,r=n.getArea();return{x:t?i.x:r.x,y:t?r.y:i.y,width:t?i.width:r.width,height:t?r.height:i.height}}var o=e;return{cx:(r=n.getArea()).cx,cy:r.cy,r0:t?r.r0:o.r0,r:t?r.r:o.r,startAngle:t?o.startAngle:0,endAngle:t?o.endAngle:2*Math.PI}}var _M=2*Math.PI,bM=Math.PI/180;function wM(t,e){return kp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function SM(t,e){var n=wM(t,e),i=t.get("center"),r=t.get("radius");Y(r)||(r=[0,r]);var o,a,s=$r(n.width,e.getWidth()),l=$r(n.height,e.getHeight()),u=Math.min(s,l),h=$r(r[0],u/2),c=$r(r[1],u/2),p=t.coordinateSystem;if(p){var d=p.dataToPoint(i);o=d[0]||0,a=d[1]||0}else Y(i)||(i=[i,i]),o=$r(i[0],s)+n.x,a=$r(i[1],l)+n.y;return{cx:o,cy:a,r0:h,r:c}}function MM(t,e,n){e.eachSeriesByType(t,(function(t){var e=t.getData(),i=e.mapDimension("value"),r=wM(t,n),o=SM(t,n),a=o.cx,s=o.cy,l=o.r,u=o.r0,h=-t.get("startAngle")*bM,c=t.get("endAngle"),p=t.get("padAngle")*bM;c="auto"===c?h-_M:-c*bM;var d=t.get("minAngle")*bM+p,f=0;e.each(i,(function(t){!isNaN(t)&&f++}));var g=e.getSum(i),y=Math.PI/(g||f)*2,v=t.get("clockwise"),m=t.get("roseType"),x=t.get("stillShowZeroSum"),_=e.getDataExtent(i);_[0]=0;var b=v?1:-1,w=[h,c],S=b*p/2;us(w,!v),h=w[0],c=w[1];var M=IM(t);M.startAngle=h,M.endAngle=c,M.clockwise=v;var I=Math.abs(c-h),T=I,C=0,D=h;if(e.setLayout({viewRect:r,r:l}),e.each(i,(function(t,n){var i;if(isNaN(t))e.setItemLayout(n,{angle:NaN,startAngle:NaN,endAngle:NaN,clockwise:v,cx:a,cy:s,r0:u,r:m?NaN:l});else{(i="area"!==m?0===g&&x?y:t*y:I/f)i?h=o=D+b*i/2:(o=D+S,h=r-S),e.setItemLayout(n,{angle:i,startAngle:o,endAngle:h,clockwise:v,cx:a,cy:s,r0:u,r:m?Kr(t,_,[u,l]):l}),D=r}})),T<_M&&f)if(T<=.001){var A=I/f;e.each(i,(function(t,n){if(!isNaN(t)){var i=e.getItemLayout(n);i.angle=A;var r=0,o=0;An?a:o,h=Math.abs(l.label.y-n);if(h>=u.maxY){var c=l.label.x-e-l.len2*r,p=i+l.len,f=Math.abs(c)t.unconstrainedWidth?null:d:null;i.setStyle("width",f)}var g=i.getBoundingRect();o.width=g.width;var y=(i.style.margin||0)+2.1;o.height=g.height+y,o.y-=(o.height-c)/2}}}function kM(t){return"center"===t.position}function LM(t){var e,n,i=t.getData(),r=[],o=!1,a=(t.get("minShowLabelAngle")||0)*CM,s=i.getLayout("viewRect"),l=i.getLayout("r"),u=s.width,h=s.x,c=s.y,p=s.height;function d(t){t.ignore=!0}i.each((function(t){var s=i.getItemGraphicEl(t),c=s.shape,p=s.getTextContent(),f=s.getTextGuideLine(),g=i.getItemModel(t),y=g.getModel("label"),v=y.get("position")||g.get(["emphasis","label","position"]),m=y.get("distanceToLabelLine"),x=y.get("alignTo"),_=$r(y.get("edgeDistance"),u),b=y.get("bleedMargin"),w=g.getModel("labelLine"),S=w.get("length");S=$r(S,u);var M=w.get("length2");if(M=$r(M,u),Math.abs(c.endAngle-c.startAngle)0?"right":"left":k>0?"left":"right"}var B=Math.PI,F=0,G=y.get("rotate");if(j(G))F=G*(B/180);else if("center"===v)F=0;else if("radial"===G||!0===G){F=k<0?-A+B:-A}else if("tangential"===G&&"outside"!==v&&"outer"!==v){var W=Math.atan2(k,L);W<0&&(W=2*B+W),L>0&&(W=B+W),F=W-B}if(o=!!F,p.x=I,p.y=T,p.rotation=F,p.setStyle({verticalAlign:"middle"}),P){p.setStyle({align:D});var H=p.states.select;H&&(H.x+=p.x,H.y+=p.y)}else{var Y=p.getBoundingRect().clone();Y.applyTransform(p.getComputedTransform());var X=(p.style.margin||0)+2.1;Y.y-=X/2,Y.height+=X,r.push({label:p,labelLine:f,position:v,len:S,len2:M,minTurnAngle:w.get("minTurnAngle"),maxSurfaceAngle:w.get("maxSurfaceAngle"),surfaceNormal:new De(k,L),linePoints:C,textAlign:D,labelDistance:m,labelAlignTo:x,edgeDistance:_,bleedMargin:b,rect:Y,unconstrainedWidth:Y.width,labelStyleWidth:p.style.width})}s.setTextConfig({inside:P})}})),!o&&t.get("avoidLabelOverlap")&&function(t,e,n,i,r,o,a,s){for(var l=[],u=[],h=Number.MAX_VALUE,c=-Number.MAX_VALUE,p=0;p0){for(var l=o.getItemLayout(0),u=1;isNaN(l&&l.startAngle)&&u=n.r0}},e.type="pie",e}(Og);function RM(t,e,n){e=Y(e)&&{coordDimensions:e}||A({encodeDefine:t.getEncode()},e);var i=t.getSource(),r=px(i,e).dimensions,o=new cx(r,t);return o.initData(i,n),o}var NM=function(){function t(t,e){this._getDataWithEncodedVisual=t,this._getRawData=e}return t.prototype.getAllNames=function(){var t=this._getRawData();return t.mapArray(t.getName)},t.prototype.containName=function(t){return this._getRawData().indexOfName(t)>=0},t.prototype.indexOfName=function(t){return this._getDataWithEncodedVisual().indexOfName(t)},t.prototype.getItemVisual=function(t,e){return this._getDataWithEncodedVisual().getItemVisual(t,e)},t}(),EM=Vo(),zM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new NM(W(this.getData,this),W(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.mergeOption=function(){t.prototype.mergeOption.apply(this,arguments)},e.prototype.getInitialData=function(){return RM(this,{coordDimensions:["value"],encodeDefaulter:H(ed,this)})},e.prototype.getDataParams=function(e){var n=this.getData(),i=EM(n),r=i.seats;if(!r){var o=[];n.each(n.mapDimension("value"),(function(t){o.push(t)})),r=i.seats=io(o,n.hostModel.get("percentPrecision"))}var a=t.prototype.getDataParams.call(this,e);return a.percent=r[e]||0,a.$vars.push("percent"),a},e.prototype._defaultLabelLine=function(t){Co(t,"labelLine",["show"]);var e=t.labelLine,n=t.emphasis.labelLine;e.show=e.show&&t.label.show,n.show=n.show&&t.emphasis.label.show},e.type="series.pie",e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,endAngle:"auto",padAngle:0,minAngle:0,minShowLabelAngle:0,selectedOffset:10,percentPrecision:2,stillShowZeroSum:!0,left:0,top:0,right:0,bottom:0,width:null,height:null,label:{rotate:0,show:!0,overflow:"truncate",position:"outer",alignTo:"none",edgeDistance:"25%",bleedMargin:10,distanceToLabelLine:5},labelLine:{show:!0,length:15,length2:15,smooth:!1,minTurnAngle:90,maxSurfaceAngle:90,lineStyle:{width:1,type:"solid"}},itemStyle:{borderWidth:1,borderJoin:"round"},showEmptyCircle:!0,emptyCircleStyle:{color:"lightgray",opacity:1},labelLayout:{hideOverlap:!0},emphasis:{scale:!0,scaleSize:5},avoidLabelOverlap:!0,animationType:"expansion",animationDuration:1e3,animationTypeUpdate:"transition",animationEasingUpdate:"cubicInOut",animationDurationUpdate:500,animationEasing:"cubicInOut"},e}(bg);var VM=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){return _x(null,this,{useEncodeDefaulter:!0})},e.prototype.getProgressive=function(){var t=this.option.progressive;return null==t?this.option.large?5e3:this.get("progressive"):t},e.prototype.getProgressiveThreshold=function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?1e4:this.get("progressiveThreshold"):t},e.prototype.brushSelector=function(t,e,n){return n.point(e.getItemLayout(t))},e.prototype.getZLevelKey=function(){return this.getData().count()>this.getProgressiveThreshold()?this.id:""},e.type="series.scatter",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={coordinateSystem:"cartesian2d",z:2,legendHoverLink:!0,symbolSize:10,large:!1,largeThreshold:2e3,itemStyle:{opacity:.8},emphasis:{scale:!0},clip:!0,select:{itemStyle:{borderColor:"#212121"}},universalTransition:{divideShape:"clone"}},e}(bg),BM=function(){},FM=function(t){function e(e){var n=t.call(this,e)||this;return n._off=0,n.hoverDataIdx=-1,n}return n(e,t),e.prototype.getDefaultShape=function(){return new BM},e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.buildPath=function(t,e){var n,i=e.points,r=e.size,o=this.symbolProxy,a=o.shape,s=t.getContext?t.getContext():t,l=s&&r[0]<4,u=this.softClipShape;if(l)this._ctx=s;else{for(this._ctx=null,n=this._off;n=0;s--){var l=2*s,u=i[l]-o/2,h=i[l+1]-a/2;if(t>=u&&e>=h&&t<=u+o&&e<=h+a)return s}return-1},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect();return t=n[0],e=n[1],i.contain(t,e)?(this.hoverDataIdx=this.findDataIndex(t,e))>=0:(this.hoverDataIdx=-1,!1)},e.prototype.getBoundingRect=function(){var t=this._rect;if(!t){for(var e=this.shape,n=e.points,i=e.size,r=i[0],o=i[1],a=1/0,s=1/0,l=-1/0,u=-1/0,h=0;h=0&&(l.dataIndex=n+(t.startIndex||0))}))},t.prototype.remove=function(){this._clear()},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),WM=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData();this._updateSymbolDraw(i,t).updateData(i,{clipShape:this._getClipShape(t)}),this._finished=!0},e.prototype.incrementalPrepareRender=function(t,e,n){var i=t.getData();this._updateSymbolDraw(i,t).incrementalPrepareUpdate(i),this._finished=!1},e.prototype.incrementalRender=function(t,e,n){this._symbolDraw.incrementalUpdate(t,e.getData(),{clipShape:this._getClipShape(e)}),this._finished=t.end===e.getData().count()},e.prototype.updateTransform=function(t,e,n){var i=t.getData();if(this.group.dirty(),!this._finished||i.count()>1e4)return{update:!0};var r=XS("").reset(t,e,n);r.progress&&r.progress({start:0,end:i.count(),count:i.count()},i),this._symbolDraw.updateLayout(i)},e.prototype.eachRendered=function(t){this._symbolDraw&&this._symbolDraw.eachRendered(t)},e.prototype._getClipShape=function(t){if(t.get("clip",!0)){var e=t.coordinateSystem;return e&&e.getArea&&e.getArea(.1)}},e.prototype._updateSymbolDraw=function(t,e){var n=this._symbolDraw,i=e.pipelineContext.large;return n&&i===this._isLargeDraw||(n&&n.remove(),n=this._symbolDraw=i?new GM:new xS,this._isLargeDraw=i,this.group.removeAll()),this.group.add(n.group),n},e.prototype.remove=function(t,e){this._symbolDraw&&this._symbolDraw.remove(!0),this._symbolDraw=null},e.prototype.dispose=function(){},e.type="scatter",e}(Og),HM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.type="grid",e.dependencies=["xAxis","yAxis"],e.layoutMode="box",e.defaultOption={show:!1,z:0,left:"10%",top:60,right:"10%",bottom:70,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"},e}(zp),YM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("grid",Wo).models[0]},e.type="cartesian2dAxis",e}(zp);R(YM,D_);var XM={show:!0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#6E7079",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,showMinLine:!0,showMaxLine:!0,lineStyle:{color:["#E0E6F1"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.2)","rgba(210,219,238,0.2)"]}}},UM=C({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},XM),ZM=C({boundaryGap:[0,0],axisLine:{show:"auto"},axisTick:{show:"auto"},splitNumber:5,minorTick:{show:!1,splitNumber:5,length:3,lineStyle:{}},minorSplitLine:{show:!1,lineStyle:{color:"#F4F7FD",width:1}}},XM),jM={category:UM,value:ZM,time:C({splitNumber:6,axisLabel:{showMinLabel:!1,showMaxLabel:!1,rich:{primary:{fontWeight:"bold"}}},splitLine:{show:!1}},ZM),log:k({logBase:10},ZM)},qM={value:1,category:1,time:1,log:1};function KM(t,e,i,r){E(qM,(function(o,a){var s=C(C({},jM[a],!0),r,!0),l=function(t){function i(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e+"Axis."+a,n}return n(i,t),i.prototype.mergeDefaultAndTheme=function(t,e){var n=Pp(this),i=n?Rp(t):{};C(t,e.getTheme().get(a+"Axis")),C(t,this.getDefaultOption()),t.type=$M(t),n&&Op(t,i,n)},i.prototype.optionUpdated=function(){"category"===this.option.type&&(this.__ordinalMeta=Mx.createByAxisModel(this))},i.prototype.getCategories=function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},i.prototype.getOrdinalMeta=function(){return this.__ordinalMeta},i.type=e+"Axis."+a,i.defaultOption=s,i}(i);t.registerComponentModel(l)})),t.registerSubTypeDefaulter(e+"Axis",$M)}function $M(t){return t.type||(t.data?"category":"value")}var JM=function(){function t(t){this.type="cartesian",this._dimList=[],this._axes={},this.name=t||""}return t.prototype.getAxis=function(t){return this._axes[t]},t.prototype.getAxes=function(){return z(this._dimList,(function(t){return this._axes[t]}),this)},t.prototype.getAxesByScale=function(t){return t=t.toLowerCase(),B(this.getAxes(),(function(e){return e.scale.type===t}))},t.prototype.addAxis=function(t){var e=t.dim;this._axes[e]=t,this._dimList.push(e)},t}(),QM=["x","y"];function tI(t){return"interval"===t.type||"time"===t.type}var eI=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="cartesian2d",e.dimensions=QM,e}return n(e,t),e.prototype.calcAffineTransform=function(){this._transform=this._invTransform=null;var t=this.getAxis("x").scale,e=this.getAxis("y").scale;if(tI(t)&&tI(e)){var n=t.getExtent(),i=e.getExtent(),r=this.dataToPoint([n[0],i[0]]),o=this.dataToPoint([n[1],i[1]]),a=n[1]-n[0],s=i[1]-i[0];if(a&&s){var l=(o[0]-r[0])/a,u=(o[1]-r[1])/s,h=r[0]-n[0]*l,c=r[1]-i[0]*u,p=this._transform=[l,0,0,u,h,c];this._invTransform=Ie([],p)}}},e.prototype.getBaseAxis=function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAxis("x")},e.prototype.containPoint=function(t){var e=this.getAxis("x"),n=this.getAxis("y");return e.contain(e.toLocalCoord(t[0]))&&n.contain(n.toLocalCoord(t[1]))},e.prototype.containData=function(t){return this.getAxis("x").containData(t[0])&&this.getAxis("y").containData(t[1])},e.prototype.containZone=function(t,e){var n=this.dataToPoint(t),i=this.dataToPoint(e),r=this.getArea(),o=new ze(n[0],n[1],i[0]-n[0],i[1]-n[1]);return r.intersect(o)},e.prototype.dataToPoint=function(t,e,n){n=n||[];var i=t[0],r=t[1];if(this._transform&&null!=i&&isFinite(i)&&null!=r&&isFinite(r))return Wt(n,t,this._transform);var o=this.getAxis("x"),a=this.getAxis("y");return n[0]=o.toGlobalCoord(o.dataToCoord(i,e)),n[1]=a.toGlobalCoord(a.dataToCoord(r,e)),n},e.prototype.clampData=function(t,e){var n=this.getAxis("x").scale,i=this.getAxis("y").scale,r=n.getExtent(),o=i.getExtent(),a=n.parse(t[0]),s=i.parse(t[1]);return(e=e||[])[0]=Math.min(Math.max(Math.min(r[0],r[1]),a),Math.max(r[0],r[1])),e[1]=Math.min(Math.max(Math.min(o[0],o[1]),s),Math.max(o[0],o[1])),e},e.prototype.pointToData=function(t,e){var n=[];if(this._invTransform)return Wt(n,t,this._invTransform);var i=this.getAxis("x"),r=this.getAxis("y");return n[0]=i.coordToData(i.toLocalCoord(t[0]),e),n[1]=r.coordToData(r.toLocalCoord(t[1]),e),n},e.prototype.getOtherAxis=function(t){return this.getAxis("x"===t.dim?"y":"x")},e.prototype.getArea=function(t){t=t||0;var e=this.getAxis("x").getGlobalExtent(),n=this.getAxis("y").getGlobalExtent(),i=Math.min(e[0],e[1])-t,r=Math.min(n[0],n[1])-t,o=Math.max(e[0],e[1])-i+t,a=Math.max(n[0],n[1])-r+t;return new ze(i,r,o,a)},e}(JM),nI=function(t){function e(e,n,i,r,o){var a=t.call(this,e,n,i)||this;return a.index=0,a.type=r||"value",a.position=o||"bottom",a}return n(e,t),e.prototype.isHorizontal=function(){var t=this.position;return"top"===t||"bottom"===t},e.prototype.getGlobalExtent=function(t){var e=this.getExtent();return e[0]=this.toGlobalCoord(e[0]),e[1]=this.toGlobalCoord(e[1]),t&&e[0]>e[1]&&e.reverse(),e},e.prototype.pointToData=function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},e.prototype.setCategorySortInfo=function(t){if("category"!==this.type)return!1;this.model.option.categorySortInfo=t,this.scale.setSortInfo(t)},e}(ab);function iI(t,e,n){n=n||{};var i=t.coordinateSystem,r=e.axis,o={},a=r.getAxesOnZeroOf()[0],s=r.position,l=a?"onZero":s,u=r.dim,h=i.getRect(),c=[h.x,h.x+h.width,h.y,h.y+h.height],p={left:0,right:1,top:0,bottom:1,onZero:2},d=e.get("offset")||0,f="x"===u?[c[2]-d,c[3]+d]:[c[0]-d,c[1]+d];if(a){var g=a.toGlobalCoord(a.dataToCoord(0));f[p.onZero]=Math.max(Math.min(g,f[1]),f[0])}o.position=["y"===u?f[p[l]]:c[0],"x"===u?f[p[l]]:c[3]],o.rotation=Math.PI/2*("x"===u?0:1);o.labelDirection=o.tickDirection=o.nameDirection={top:-1,bottom:1,left:-1,right:1}[s],o.labelOffset=a?f[p[s]]-f[p.onZero]:0,e.get(["axisTick","inside"])&&(o.tickDirection=-o.tickDirection),it(n.labelInside,e.get(["axisLabel","inside"]))&&(o.labelDirection=-o.labelDirection);var y=e.get(["axisLabel","rotate"]);return o.labelRotate="top"===l?-y:y,o.z2=1,o}function rI(t){return"cartesian2d"===t.get("coordinateSystem")}function oI(t){var e={xAxisModel:null,yAxisModel:null};return E(e,(function(n,i){var r=i.replace(/Model$/,""),o=t.getReferringComponents(r,Wo).models[0];e[i]=o})),e}var aI=Math.log;function sI(t,e,n){var i=Ex.prototype,r=i.getTicks.call(n),o=i.getTicks.call(n,!0),a=r.length-1,s=i.getInterval.call(n),l=x_(t,e),u=l.extent,h=l.fixMin,c=l.fixMax;if("log"===t.type){var p=aI(t.base);u=[aI(u[0])/p,aI(u[1])/p]}t.setExtent(u[0],u[1]),t.calcNiceExtent({splitNumber:a,fixMin:h,fixMax:c});var d=i.getExtent.call(t);h&&(u[0]=d[0]),c&&(u[1]=d[1]);var f=i.getInterval.call(t),g=u[0],y=u[1];if(h&&c)f=(y-g)/a;else if(h)for(y=u[0]+f*a;yu[0]&&isFinite(g)&&isFinite(u[0]);)f=Dx(f),g=u[1]-f*a;else{t.getTicks().length-1>a&&(f=Dx(f));var v=f*a;(g=Jr((y=Math.ceil(u[1]/f)*f)-v))<0&&u[0]>=0?(g=0,y=Jr(v)):y>0&&u[1]<=0&&(y=0,g=-Jr(v))}var m=(r[0].value-o[0].value)/s,x=(r[a].value-o[a].value)/s;i.setExtent.call(t,g+f*m,y+f*x),i.setInterval.call(t,f),(m||x)&&i.setNiceExtent.call(t,g+f,y-f)}var lI=function(){function t(t,e,n){this.type="grid",this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this.axisPointerEnabled=!0,this.dimensions=QM,this._initCartesian(t,e,n),this.model=t}return t.prototype.getRect=function(){return this._rect},t.prototype.update=function(t,e){var n=this._axesMap;function i(t){var e,n=G(t),i=n.length;if(i){for(var r=[],o=i-1;o>=0;o--){var a=t[+n[o]],s=a.model,l=a.scale;Tx(l)&&s.get("alignTicks")&&null==s.get("interval")?r.push(a):(__(l,s),Tx(l)&&(e=a))}r.length&&(e||__((e=r.pop()).scale,e.model),E(r,(function(t){sI(t.scale,t.model,e.scale)})))}}this._updateScale(t,this.model),i(n.x),i(n.y);var r={};E(n.x,(function(t){hI(n,"y",t,r)})),E(n.y,(function(t){hI(n,"x",t,r)})),this.resize(this.model,e)},t.prototype.resize=function(t,e,n){var i=t.getBoxLayoutParams(),r=!n&&t.get("containLabel"),o=kp(i,{width:e.getWidth(),height:e.getHeight()});this._rect=o;var a=this._axesList;function s(){E(a,(function(t){var e=t.isHorizontal(),n=e?[0,o.width]:[0,o.height],i=t.inverse?1:0;t.setExtent(n[i],n[1-i]),function(t,e){var n=t.getExtent(),i=n[0]+n[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return i-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return i-t+e}}(t,e?o.x:o.y)}))}s(),r&&(E(a,(function(t){if(!t.model.get(["axisLabel","inside"])){var e=function(t){var e=t.model,n=t.scale;if(e.get(["axisLabel","show"])&&!n.isBlank()){var i,r,o=n.getExtent();r=n instanceof Rx?n.count():(i=n.getTicks()).length;var a,s=t.getLabelModel(),l=w_(t),u=1;r>40&&(u=Math.ceil(r/40));for(var h=0;h0&&i>0||n<0&&i<0)}(t)}var pI=Math.PI,dI=function(){function t(t,e){this.group=new Br,this.opt=e,this.axisModel=t,k(e,{labelOffset:0,nameDirection:1,tickDirection:1,labelDirection:1,silent:!0,handleAutoShown:function(){return!0}});var n=new Br({x:e.position[0],y:e.position[1],rotation:e.rotation});n.updateTransform(),this._transformGroup=n}return t.prototype.hasBuilder=function(t){return!!fI[t]},t.prototype.add=function(t){fI[t](this.opt,this.axisModel,this.group,this._transformGroup)},t.prototype.getGroup=function(){return this.group},t.innerTextLayout=function(t,e,n){var i,r,o=ao(e-t);return so(o)?(r=n>0?"top":"bottom",i="center"):so(o-pI)?(r=n>0?"bottom":"top",i="center"):(r="middle",i=o>0&&o0?"right":"left":n>0?"left":"right"),{rotation:o,textAlign:i,textVerticalAlign:r}},t.makeAxisEventDataBase=function(t){var e={componentType:t.mainType,componentIndex:t.componentIndex};return e[t.mainType+"Index"]=t.componentIndex,e},t.isLabelSilent=function(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)},t}(),fI={axisLine:function(t,e,n,i){var r=e.get(["axisLine","show"]);if("auto"===r&&t.handleAutoShown&&(r=t.handleAutoShown("axisLine")),r){var o=e.axis.getExtent(),a=i.transform,s=[o[0],0],l=[o[1],0],u=s[0]>l[0];a&&(Wt(s,s,a),Wt(l,l,a));var h=A({lineCap:"round"},e.getModel(["axisLine","lineStyle"]).getLineStyle()),c=new Ku({shape:{x1:s[0],y1:s[1],x2:l[0],y2:l[1]},style:h,strokeContainThreshold:t.strokeContainThreshold||5,silent:!0,z2:1});zh(c.shape,c.style.lineWidth),c.anid="line",n.add(c);var p=e.get(["axisLine","symbol"]);if(null!=p){var d=e.get(["axisLine","symbolSize"]);U(p)&&(p=[p,p]),(U(d)||j(d))&&(d=[d,d]);var f=Zy(e.get(["axisLine","symbolOffset"])||0,d),g=d[0],y=d[1];E([{rotate:t.rotation+Math.PI/2,offset:f[0],r:0},{rotate:t.rotation-Math.PI/2,offset:f[1],r:Math.sqrt((s[0]-l[0])*(s[0]-l[0])+(s[1]-l[1])*(s[1]-l[1]))}],(function(e,i){if("none"!==p[i]&&null!=p[i]){var r=Xy(p[i],-g/2,-y/2,g,y,h.stroke,!0),o=e.r+e.offset,a=u?l:s;r.attr({rotation:e.rotate,x:a[0]+o*Math.cos(t.rotation),y:a[1]-o*Math.sin(t.rotation),silent:!0,z2:11}),n.add(r)}}))}}},axisTickLabel:function(t,e,n,i){var r=function(t,e,n,i){var r=n.axis,o=n.getModel("axisTick"),a=o.get("show");"auto"===a&&i.handleAutoShown&&(a=i.handleAutoShown("axisTick"));if(!a||r.scale.isBlank())return;for(var s=o.getModel("lineStyle"),l=i.tickDirection*o.get("length"),u=mI(r.getTicksCoords(),e.transform,l,k(s.getLineStyle(),{stroke:n.get(["axisLine","lineStyle","color"])}),"ticks"),h=0;hc[1]?-1:1,d=["start"===s?c[0]-p*h:"end"===s?c[1]+p*h:(c[0]+c[1])/2,vI(s)?t.labelOffset+l*h:0],f=e.get("nameRotate");null!=f&&(f=f*pI/180),vI(s)?o=dI.innerTextLayout(t.rotation,null!=f?f:t.rotation,l):(o=function(t,e,n,i){var r,o,a=ao(n-t),s=i[0]>i[1],l="start"===e&&!s||"start"!==e&&s;so(a-pI/2)?(o=l?"bottom":"top",r="center"):so(a-1.5*pI)?(o=l?"top":"bottom",r="center"):(o="middle",r=a<1.5*pI&&a>pI/2?l?"left":"right":l?"right":"left");return{rotation:a,textAlign:r,textVerticalAlign:o}}(t.rotation,s,f||0,c),null!=(a=t.axisNameAvailableWidth)&&(a=Math.abs(a/Math.sin(o.rotation)),!isFinite(a)&&(a=null)));var g=u.getFont(),y=e.get("nameTruncate",!0)||{},v=y.ellipsis,m=it(t.nameTruncateMaxWidth,y.maxWidth,a),x=new Xs({x:d[0],y:d[1],rotation:o.rotation,silent:dI.isLabelSilent(e),style:oc(u,{text:r,font:g,overflow:"truncate",width:m,ellipsis:v,fill:u.getTextColor()||e.get(["axisLine","lineStyle","color"]),align:u.get("align")||o.textAlign,verticalAlign:u.get("verticalAlign")||o.textVerticalAlign}),z2:1});if(Kh({el:x,componentModel:e,itemName:r}),x.__fullText=r,x.anid="name",e.get("triggerEvent")){var _=dI.makeAxisEventDataBase(e);_.targetType="axisName",_.name=r,rl(x).eventData=_}i.add(x),x.updateTransform(),n.add(x),x.decomposeTransform()}}};function gI(t){t&&(t.ignore=!0)}function yI(t,e){var n=t&&t.getBoundingRect().clone(),i=e&&e.getBoundingRect().clone();if(n&&i){var r=xe([]);return Se(r,r,-t.rotation),n.applyTransform(be([],r,t.getLocalTransform())),i.applyTransform(be([],r,e.getLocalTransform())),n.intersect(i)}}function vI(t){return"middle"===t||"center"===t}function mI(t,e,n,i,r){for(var o=[],a=[],s=[],l=0;l=0||t===e}function bI(t){var e=wI(t);if(e){var n=e.axisPointerModel,i=e.axis.scale,r=n.option,o=n.get("status"),a=n.get("value");null!=a&&(a=i.parse(a));var s=SI(n);null==o&&(r.status=s?"show":"hide");var l=i.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==a||a>l[1])&&(a=l[1]),a0&&!c.min?c.min=0:null!=c.min&&c.min<0&&!c.max&&(c.max=0);var p=a;null!=c.color&&(p=k({color:c.color},a));var d=C(T(c),{boundaryGap:t,splitNumber:e,scale:n,axisLine:i,axisTick:r,axisLabel:o,name:c.text,showName:s,nameLocation:"end",nameGap:u,nameTextStyle:p,triggerEvent:h},!1);if(U(l)){var f=d.name;d.name=l.replace("{value}",null!=f?f:"")}else X(l)&&(d.name=l(d.name,d));var g=new Cc(d,null,this.ecModel);return R(g,D_.prototype),g.mainType="radar",g.componentIndex=this.componentIndex,g}),this);this._indicatorModels=c},e.prototype.getIndicatorModels=function(){return this._indicatorModels},e.type="radar",e.defaultOption={z:0,center:["50%","50%"],radius:"75%",startAngle:90,axisName:{show:!0},boundaryGap:[0,0],splitNumber:5,axisNameGap:15,scale:!1,shape:"polygon",axisLine:C({lineStyle:{color:"#bbb"}},XI.axisLine),axisLabel:UI(XI.axisLabel,!1),axisTick:UI(XI.axisTick,!1),splitLine:UI(XI.splitLine,!0),splitArea:UI(XI.splitArea,!0),indicator:[]},e}(zp),jI=["axisLine","axisTickLabel","axisName"],qI=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeAll(),this._buildAxes(t),this._buildSplitLineAndArea(t)},e.prototype._buildAxes=function(t){var e=t.coordinateSystem;E(z(e.getIndicatorAxes(),(function(t){var n=t.model.get("showName")?t.name:"";return new dI(t.model,{axisName:n,position:[e.cx,e.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})})),(function(t){E(jI,t.add,t),this.group.add(t.getGroup())}),this)},e.prototype._buildSplitLineAndArea=function(t){var e=t.coordinateSystem,n=e.getIndicatorAxes();if(n.length){var i=t.get("shape"),r=t.getModel("splitLine"),o=t.getModel("splitArea"),a=r.getModel("lineStyle"),s=o.getModel("areaStyle"),l=r.get("show"),u=o.get("show"),h=a.get("color"),c=s.get("color"),p=Y(h)?h:[h],d=Y(c)?c:[c],f=[],g=[];if("circle"===i)for(var y=n[0].getTicksCoords(),v=e.cx,m=e.cy,x=0;x3?1.4:r>1?1.2:1.1;iT(this,"zoom","zoomOnMouseWheel",t,{scale:i>0?s:1/s,originX:o,originY:a,isAvailableBehavior:null})}if(n){var l=Math.abs(i);iT(this,"scrollMove","moveOnMouseWheel",t,{scrollDelta:(i>0?1:-1)*(l>3?.4:l>1?.15:.05),originX:o,originY:a,isAvailableBehavior:null})}}},e.prototype._pinchHandler=function(t){tT(this._zr,"globalPan")||iT(this,"zoom",null,t,{scale:t.pinchScale>1?1.1:1/1.1,originX:t.pinchX,originY:t.pinchY,isAvailableBehavior:null})},e}(jt);function iT(t,e,n,i,r){t.pointerChecker&&t.pointerChecker(i,r.originX,r.originY)&&(de(i.event),rT(t,e,n,i,r))}function rT(t,e,n,i,r){r.isAvailableBehavior=W(oT,null,n,i),t.trigger(e,r)}function oT(t,e,n){var i=n[t];return!t||i&&(!U(i)||e.event[i+"Key"])}function aT(t,e,n){var i=t.target;i.x+=e,i.y+=n,i.dirty()}function sT(t,e,n,i){var r=t.target,o=t.zoomLimit,a=t.zoom=t.zoom||1;if(a*=e,o){var s=o.min||0,l=o.max||1/0;a=Math.max(Math.min(l,a),s)}var u=a/t.zoom;t.zoom=a,r.x-=(n-r.x)*(u-1),r.y-=(i-r.y)*(u-1),r.scaleX*=u,r.scaleY*=u,r.dirty()}var lT,uT={axisPointer:1,tooltip:1,brush:1};function hT(t,e,n){var i=e.getComponentByElement(t.topTarget),r=i&&i.coordinateSystem;return i&&i!==n&&!uT.hasOwnProperty(i.mainType)&&r&&r.model!==n}function cT(t){U(t)&&(t=(new DOMParser).parseFromString(t,"text/xml"));var e=t;for(9===e.nodeType&&(e=e.firstChild);"svg"!==e.nodeName.toLowerCase()||1!==e.nodeType;)e=e.nextSibling;return e}var pT={fill:"fill",stroke:"stroke","stroke-width":"lineWidth",opacity:"opacity","fill-opacity":"fillOpacity","stroke-opacity":"strokeOpacity","stroke-dasharray":"lineDash","stroke-dashoffset":"lineDashOffset","stroke-linecap":"lineCap","stroke-linejoin":"lineJoin","stroke-miterlimit":"miterLimit","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","text-anchor":"textAlign",visibility:"visibility",display:"display"},dT=G(pT),fT={"alignment-baseline":"textBaseline","stop-color":"stopColor"},gT=G(fT),yT=function(){function t(){this._defs={},this._root=null}return t.prototype.parse=function(t,e){e=e||{};var n=cT(t);this._defsUsePending=[];var i=new Br;this._root=i;var r=[],o=n.getAttribute("viewBox")||"",a=parseFloat(n.getAttribute("width")||e.width),s=parseFloat(n.getAttribute("height")||e.height);isNaN(a)&&(a=null),isNaN(s)&&(s=null),wT(n,i,null,!0,!1);for(var l,u,h=n.firstChild;h;)this._parseNode(h,i,r,null,!1,!1),h=h.nextSibling;if(function(t,e){for(var n=0;n=4&&(l={x:parseFloat(c[0]||0),y:parseFloat(c[1]||0),width:parseFloat(c[2]),height:parseFloat(c[3])})}if(l&&null!=a&&null!=s&&(u=LT(l,{x:0,y:0,width:a,height:s}),!e.ignoreViewBox)){var p=i;(i=new Br).add(p),p.scaleX=p.scaleY=u.scale,p.x=u.x,p.y=u.y}return e.ignoreRootClip||null==a||null==s||i.setClipPath(new Ws({shape:{x:0,y:0,width:a,height:s}})),{root:i,width:a,height:s,viewBoxRect:l,viewBoxTransform:u,named:r}},t.prototype._parseNode=function(t,e,n,i,r,o){var a,s=t.nodeName.toLowerCase(),l=i;if("defs"===s&&(r=!0),"text"===s&&(o=!0),"defs"===s||"switch"===s)a=e;else{if(!r){var u=lT[s];if(u&&_t(lT,s)){a=u.call(this,t,e);var h=t.getAttribute("name");if(h){var c={name:h,namedFrom:null,svgNodeTagLower:s,el:a};n.push(c),"g"===s&&(l=c)}else i&&n.push({name:i.name,namedFrom:i,svgNodeTagLower:s,el:a});e.add(a)}}var p=vT[s];if(p&&_t(vT,s)){var d=p.call(this,t),f=t.getAttribute("id");f&&(this._defs[f]=d)}}if(a&&a.isGroup)for(var g=t.firstChild;g;)1===g.nodeType?this._parseNode(g,a,n,l,r,o):3===g.nodeType&&o&&this._parseText(g,a),g=g.nextSibling},t.prototype._parseText=function(t,e){var n=new Ps({style:{text:t.textContent},silent:!0,x:this._textX||0,y:this._textY||0});_T(e,n),wT(t,n,this._defsUsePending,!1,!1),function(t,e){var n=e.__selfStyle;if(n){var i=n.textBaseline,r=i;i&&"auto"!==i?"baseline"===i?r="alphabetic":"before-edge"===i||"text-before-edge"===i?r="top":"after-edge"===i||"text-after-edge"===i?r="bottom":"central"!==i&&"mathematical"!==i||(r="middle"):r="alphabetic",t.style.textBaseline=r}var o=e.__inheritedStyle;if(o){var a=o.textAlign,s=a;a&&("middle"===a&&(s="center"),t.style.textAlign=s)}}(n,e);var i=n.style,r=i.fontSize;r&&r<9&&(i.fontSize=9,n.scaleX*=r/9,n.scaleY*=r/9);var o=(i.fontSize||i.fontFamily)&&[i.fontStyle,i.fontWeight,(i.fontSize||12)+"px",i.fontFamily||"sans-serif"].join(" ");i.font=o;var a=n.getBoundingRect();return this._textX+=a.width,e.add(n),n},t.internalField=void(lT={g:function(t,e){var n=new Br;return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n},rect:function(t,e){var n=new Ws;return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n.setShape({x:parseFloat(t.getAttribute("x")||"0"),y:parseFloat(t.getAttribute("y")||"0"),width:parseFloat(t.getAttribute("width")||"0"),height:parseFloat(t.getAttribute("height")||"0")}),n.silent=!0,n},circle:function(t,e){var n=new Su;return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n.setShape({cx:parseFloat(t.getAttribute("cx")||"0"),cy:parseFloat(t.getAttribute("cy")||"0"),r:parseFloat(t.getAttribute("r")||"0")}),n.silent=!0,n},line:function(t,e){var n=new Ku;return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n.setShape({x1:parseFloat(t.getAttribute("x1")||"0"),y1:parseFloat(t.getAttribute("y1")||"0"),x2:parseFloat(t.getAttribute("x2")||"0"),y2:parseFloat(t.getAttribute("y2")||"0")}),n.silent=!0,n},ellipse:function(t,e){var n=new Iu;return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n.setShape({cx:parseFloat(t.getAttribute("cx")||"0"),cy:parseFloat(t.getAttribute("cy")||"0"),rx:parseFloat(t.getAttribute("rx")||"0"),ry:parseFloat(t.getAttribute("ry")||"0")}),n.silent=!0,n},polygon:function(t,e){var n,i=t.getAttribute("points");i&&(n=bT(i));var r=new Xu({shape:{points:n||[]},silent:!0});return _T(e,r),wT(t,r,this._defsUsePending,!1,!1),r},polyline:function(t,e){var n,i=t.getAttribute("points");i&&(n=bT(i));var r=new Zu({shape:{points:n||[]},silent:!0});return _T(e,r),wT(t,r,this._defsUsePending,!1,!1),r},image:function(t,e){var n=new Ns;return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n.setStyle({image:t.getAttribute("xlink:href")||t.getAttribute("href"),x:+t.getAttribute("x"),y:+t.getAttribute("y"),width:+t.getAttribute("width"),height:+t.getAttribute("height")}),n.silent=!0,n},text:function(t,e){var n=t.getAttribute("x")||"0",i=t.getAttribute("y")||"0",r=t.getAttribute("dx")||"0",o=t.getAttribute("dy")||"0";this._textX=parseFloat(n)+parseFloat(r),this._textY=parseFloat(i)+parseFloat(o);var a=new Br;return _T(e,a),wT(t,a,this._defsUsePending,!1,!0),a},tspan:function(t,e){var n=t.getAttribute("x"),i=t.getAttribute("y");null!=n&&(this._textX=parseFloat(n)),null!=i&&(this._textY=parseFloat(i));var r=t.getAttribute("dx")||"0",o=t.getAttribute("dy")||"0",a=new Br;return _T(e,a),wT(t,a,this._defsUsePending,!1,!0),this._textX+=parseFloat(r),this._textY+=parseFloat(o),a},path:function(t,e){var n=_u(t.getAttribute("d")||"");return _T(e,n),wT(t,n,this._defsUsePending,!1,!1),n.silent=!0,n}}),t}(),vT={lineargradient:function(t){var e=parseInt(t.getAttribute("x1")||"0",10),n=parseInt(t.getAttribute("y1")||"0",10),i=parseInt(t.getAttribute("x2")||"10",10),r=parseInt(t.getAttribute("y2")||"0",10),o=new oh(e,n,i,r);return mT(t,o),xT(t,o),o},radialgradient:function(t){var e=parseInt(t.getAttribute("cx")||"0",10),n=parseInt(t.getAttribute("cy")||"0",10),i=parseInt(t.getAttribute("r")||"0",10),r=new ah(e,n,i);return mT(t,r),xT(t,r),r}};function mT(t,e){"userSpaceOnUse"===t.getAttribute("gradientUnits")&&(e.global=!0)}function xT(t,e){for(var n=t.firstChild;n;){if(1===n.nodeType&&"stop"===n.nodeName.toLocaleLowerCase()){var i=n.getAttribute("offset"),r=void 0;r=i&&i.indexOf("%")>0?parseInt(i,10)/100:i?parseFloat(i):0;var o={};kT(n,o,o);var a=o.stopColor||n.getAttribute("stop-color")||"#000000";e.colorStops.push({offset:r,color:a})}n=n.nextSibling}}function _T(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),k(e.__inheritedStyle,t.__inheritedStyle))}function bT(t){for(var e=TT(t),n=[],i=0;i0;o-=2){var a=i[o],s=i[o-1],l=TT(a);switch(r=r||[1,0,0,1,0,0],s){case"translate":we(r,r,[parseFloat(l[0]),parseFloat(l[1]||"0")]);break;case"scale":Me(r,r,[parseFloat(l[0]),parseFloat(l[1]||l[0])]);break;case"rotate":Se(r,r,-parseFloat(l[0])*DT,[parseFloat(l[1]||"0"),parseFloat(l[2]||"0")]);break;case"skewX":be(r,[1,0,Math.tan(parseFloat(l[0])*DT),1,0,0],r);break;case"skewY":be(r,[1,Math.tan(parseFloat(l[0])*DT),0,1,0,0],r);break;case"matrix":r[0]=parseFloat(l[0]),r[1]=parseFloat(l[1]),r[2]=parseFloat(l[2]),r[3]=parseFloat(l[3]),r[4]=parseFloat(l[4]),r[5]=parseFloat(l[5])}}e.setLocalTransform(r)}}(t,e),kT(t,a,s),i||function(t,e,n){for(var i=0;i0,f={api:n,geo:s,mapOrGeoModel:t,data:a,isVisualEncodedByVisualMap:d,isGeo:o,transformInfoRaw:c};"geoJSON"===s.resourceType?this._buildGeoJSON(f):"geoSVG"===s.resourceType&&this._buildSVG(f),this._updateController(t,e,n),this._updateMapSelectHandler(t,l,n,i)},t.prototype._buildGeoJSON=function(t){var e=this._regionsGroupByName=yt(),n=yt(),i=this._regionsGroup,r=t.transformInfoRaw,o=t.mapOrGeoModel,a=t.data,s=t.geo.projection,l=s&&s.stream;function u(t,e){return e&&(t=e(t)),t&&[t[0]*r.scaleX+r.x,t[1]*r.scaleY+r.y]}function h(t){for(var e=[],n=!l&&s&&s.project,i=0;i=0)&&(p=r);var d=a?{normal:{align:"center",verticalAlign:"middle"}}:null;ic(e,rc(i),{labelFetcher:p,labelDataIndex:c,defaultText:n},d);var f=e.getTextContent();if(f&&(JT(f).ignore=f.ignore,e.textConfig&&a)){var g=e.getBoundingRect().clone();e.textConfig.layoutRect=g,e.textConfig.position=[(a[0]-g.x)/g.width*100+"%",(a[1]-g.y)/g.height*100+"%"]}e.disableLabelAnimation=!0}else e.removeTextContent(),e.removeTextConfig(),e.disableLabelAnimation=null}function rC(t,e,n,i,r,o){t.data?t.data.setItemGraphicEl(o,e):rl(e).eventData={componentType:"geo",componentIndex:r.componentIndex,geoIndex:r.componentIndex,name:n,region:i&&i.option||{}}}function oC(t,e,n,i,r){t.data||Kh({el:e,componentModel:r,itemName:n,itemTooltipOption:i.get("tooltip")})}function aC(t,e,n,i,r){e.highDownSilentOnTouch=!!r.get("selectedMode");var o=i.getModel("emphasis"),a=o.get("focus");return Zl(e,a,o.get("blurScope"),o.get("disabled")),t.isGeo&&function(t,e,n){var i=rl(t);i.componentMainType=e.mainType,i.componentIndex=e.componentIndex,i.componentHighDownName=n}(e,r,n),a}function sC(t,e,n){var i,r=[];function o(){i=[]}function a(){i.length&&(r.push(i),i=[])}var s=e({polygonStart:o,polygonEnd:a,lineStart:o,lineEnd:a,point:function(t,e){isFinite(t)&&isFinite(e)&&i.push([t,e])},sphere:function(){}});return!n&&s.polygonStart(),E(t,(function(t){s.lineStart();for(var e=0;e-1&&(n.style.stroke=n.style.fill,n.style.fill="#fff",n.style.lineWidth=2),n},e.type="series.map",e.dependencies=["geo"],e.layoutMode="box",e.defaultOption={z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:null,showLegendSymbol:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,selectedMode:!0,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}},select:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{color:"rgba(255,215,0,0.8)"}},nameProperty:"name"},e}(bg);function hC(t){var e={};t.eachSeriesByType("map",(function(t){var n=t.getHostGeoModel(),i=n?"o"+n.id:"i"+t.getMapType();(e[i]=e[i]||[]).push(t)})),E(e,(function(t,e){for(var n,i,r,o=(n=z(t,(function(t){return t.getData()})),i=t[0].get("mapValueCalculation"),r={},E(n,(function(t){t.each(t.mapDimension("value"),(function(e,n){var i="ec-"+t.getName(n);r[i]=r[i]||[],isNaN(e)||r[i].push(e)}))})),n[0].map(n[0].mapDimension("value"),(function(t,e){for(var o="ec-"+n[0].getName(e),a=0,s=1/0,l=-1/0,u=r[o].length,h=0;h1?(d.width=p,d.height=p/x):(d.height=p,d.width=p*x),d.y=c[1]-d.height/2,d.x=c[0]-d.width/2;else{var b=t.getBoxLayoutParams();b.aspect=x,d=kp(b,{width:v,height:m})}this.setViewRect(d.x,d.y,d.width,d.height),this.setCenter(t.get("center"),e),this.setZoom(t.get("zoom"))}R(vC,dC);var _C=function(){function t(){this.dimensions=yC}return t.prototype.create=function(t,e){var n=[];function i(t){return{nameProperty:t.get("nameProperty"),aspectScale:t.get("aspectScale"),projection:t.get("projection")}}t.eachComponent("geo",(function(t,r){var o=t.get("map"),a=new vC(o+r,o,A({nameMap:t.get("nameMap")},i(t)));a.zoomLimit=t.get("scaleLimit"),n.push(a),t.coordinateSystem=a,a.model=t,a.resize=xC,a.resize(t,e)})),t.eachSeries((function(t){if("geo"===t.get("coordinateSystem")){var e=t.get("geoIndex")||0;t.coordinateSystem=n[e]}}));var r={};return t.eachSeriesByType("map",(function(t){if(!t.getHostGeoModel()){var e=t.getMapType();r[e]=r[e]||[],r[e].push(t)}})),E(r,(function(t,r){var o=z(t,(function(t){return t.get("nameMap")})),a=new vC(r,r,A({nameMap:D(o)},i(t[0])));a.zoomLimit=it.apply(null,z(t,(function(t){return t.get("scaleLimit")}))),n.push(a),a.resize=xC,a.resize(t[0],e),E(t,(function(t){t.coordinateSystem=a,function(t,e){E(e.get("geoCoord"),(function(e,n){t.addGeoCoord(n,e)}))}(a,t)}))})),n},t.prototype.getFilledRegions=function(t,e,n,i){for(var r=(t||[]).slice(),o=yt(),a=0;a=0;){var o=e[n];o.hierNode.prelim+=i,o.hierNode.modifier+=i,r+=o.hierNode.change,i+=o.hierNode.shift+r}}(t);var o=(n[0].hierNode.prelim+n[n.length-1].hierNode.prelim)/2;r?(t.hierNode.prelim=r.hierNode.prelim+e(t,r),t.hierNode.modifier=t.hierNode.prelim-o):t.hierNode.prelim=o}else r&&(t.hierNode.prelim=r.hierNode.prelim+e(t,r));t.parentNode.hierNode.defaultAncestor=function(t,e,n,i){if(e){for(var r=t,o=t,a=o.parentNode.children[0],s=e,l=r.hierNode.modifier,u=o.hierNode.modifier,h=a.hierNode.modifier,c=s.hierNode.modifier;s=PC(s),o=OC(o),s&&o;){r=PC(r),a=OC(a),r.hierNode.ancestor=t;var p=s.hierNode.prelim+c-o.hierNode.prelim-u+i(s,o);p>0&&(NC(RC(s,t,n),t,p),u+=p,l+=p),c+=s.hierNode.modifier,u+=o.hierNode.modifier,l+=r.hierNode.modifier,h+=a.hierNode.modifier}s&&!PC(r)&&(r.hierNode.thread=s,r.hierNode.modifier+=c-l),o&&!OC(a)&&(a.hierNode.thread=o,a.hierNode.modifier+=u-h,n=t)}return n}(t,r,t.parentNode.hierNode.defaultAncestor||i[0],e)}function AC(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function kC(t){return arguments.length?t:EC}function LC(t,e){return t-=Math.PI/2,{x:e*Math.cos(t),y:e*Math.sin(t)}}function PC(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function OC(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function RC(t,e,n){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:n}function NC(t,e,n){var i=n/(e.hierNode.i-t.hierNode.i);e.hierNode.change-=i,e.hierNode.shift+=n,e.hierNode.modifier+=n,e.hierNode.prelim+=n,t.hierNode.change+=i}function EC(t,e){return t.parentNode===e.parentNode?1:2}var zC=function(){this.parentPoint=[],this.childPoints=[]},VC=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new zC},e.prototype.buildPath=function(t,e){var n=e.childPoints,i=n.length,r=e.parentPoint,o=n[0],a=n[i-1];if(1===i)return t.moveTo(r[0],r[1]),void t.lineTo(o[0],o[1]);var s=e.orient,l="TB"===s||"BT"===s?0:1,u=1-l,h=$r(e.forkPosition,1),c=[];c[l]=r[l],c[u]=r[u]+(a[u]-r[u])*h,t.moveTo(r[0],r[1]),t.lineTo(c[0],c[1]),t.moveTo(o[0],o[1]),c[l]=o[l],t.lineTo(c[0],c[1]),c[l]=a[l],t.lineTo(c[0],c[1]),t.lineTo(a[0],a[1]);for(var p=1;pm.x)||(_-=Math.PI);var S=b?"left":"right",M=s.getModel("label"),I=M.get("rotate"),T=I*(Math.PI/180),C=y.getTextContent();C&&(y.setTextConfig({position:M.get("position")||S,rotation:null==I?-_:T,origin:"center"}),C.setStyle("verticalAlign","middle"))}var D=s.get(["emphasis","focus"]),A="relative"===D?vt(a.getAncestorsIndices(),a.getDescendantIndices()):"ancestor"===D?a.getAncestorsIndices():"descendant"===D?a.getDescendantIndices():null;A&&(rl(n).focus=A),function(t,e,n,i,r,o,a,s){var l=e.getModel(),u=t.get("edgeShape"),h=t.get("layout"),c=t.getOrient(),p=t.get(["lineStyle","curveness"]),d=t.get("edgeForkPosition"),f=l.getModel("lineStyle").getLineStyle(),g=i.__edge;if("curve"===u)e.parentNode&&e.parentNode!==n&&(g||(g=i.__edge=new th({shape:XC(h,c,p,r,r)})),vh(g,{shape:XC(h,c,p,o,a)},t));else if("polyline"===u)if("orthogonal"===h){if(e!==n&&e.children&&0!==e.children.length&&!0===e.isExpand){for(var y=e.children,v=[],m=0;me&&(e=i.height)}this.height=e+1},t.prototype.getNodeById=function(t){if(this.getId()===t)return this;for(var e=0,n=this.children,i=n.length;e=0&&this.hostTree.data.setItemLayout(this.dataIndex,t,e)},t.prototype.getLayout=function(){return this.hostTree.data.getItemLayout(this.dataIndex)},t.prototype.getModel=function(t){if(!(this.dataIndex<0))return this.hostTree.data.getItemModel(this.dataIndex).getModel(t)},t.prototype.getLevelModel=function(){return(this.hostTree.levelModels||[])[this.depth]},t.prototype.setVisual=function(t,e){this.dataIndex>=0&&this.hostTree.data.setItemVisual(this.dataIndex,t,e)},t.prototype.getVisual=function(t){return this.hostTree.data.getItemVisual(this.dataIndex,t)},t.prototype.getRawIndex=function(){return this.hostTree.data.getRawIndex(this.dataIndex)},t.prototype.getId=function(){return this.hostTree.data.getId(this.dataIndex)},t.prototype.getChildIndex=function(){if(this.parentNode){for(var t=this.parentNode.children,e=0;e=0){var i=n.getData().tree.root,r=t.targetNode;if(U(r)&&(r=i.getNodeById(r)),r&&i.contains(r))return{node:r};var o=t.targetNodeId;if(null!=o&&(r=i.getNodeById(o)))return{node:r}}}function rD(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function oD(t,e){return P(rD(t),e)>=0}function aD(t,e){for(var n=[];t;){var i=t.dataIndex;n.push({name:t.name,dataIndex:i,value:e.getRawValue(i)}),t=t.parentNode}return n.reverse(),n}var sD=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.hasSymbolVisual=!0,e.ignoreStyleOnData=!0,e}return n(e,t),e.prototype.getInitialData=function(t){var e={name:t.name,children:t.data},n=t.leaves||{},i=new Cc(n,this,this.ecModel),r=nD.createTree(e,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=r.getNodeByDataIndex(e);return n&&n.children.length&&n.isExpand||(t.parentModel=i),t}))}));var o=0;r.eachNode("preorder",(function(t){t.depth>o&&(o=t.depth)}));var a=t.expandAndCollapse&&t.initialTreeDepth>=0?t.initialTreeDepth:o;return r.root.eachNode("preorder",(function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=a})),r.data},e.prototype.getOrient=function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},e.prototype.setZoom=function(t){this.option.zoom=t},e.prototype.setCenter=function(t){this.option.center=t},e.prototype.formatTooltip=function(t,e,n){for(var i=this.getData().tree,r=i.root.children[0],o=i.getNodeByDataIndex(t),a=o.getValue(),s=o.name;o&&o!==r;)s=o.parentNode.name+"."+s,o=o.parentNode;return og("nameValue",{name:s,value:a,noValue:isNaN(a)||null==a})},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treeAncestors=aD(i,this),n.collapsed=!i.isExpand,n},e.type="series.tree",e.layoutMode="box",e.defaultOption={z:2,coordinateSystem:"view",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",edgeShape:"curve",edgeForkPosition:"50%",roam:!1,nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderWidth:1.5},label:{show:!0},animationEasing:"linear",animationDuration:700,animationDurationUpdate:500},e}(bg);function lD(t,e){for(var n,i=[t];n=i.pop();)if(e(n),n.isExpand){var r=n.children;if(r.length)for(var o=r.length-1;o>=0;o--)i.push(r[o])}}function uD(t,e){t.eachSeriesByType("tree",(function(t){!function(t,e){var n=function(t,e){return kp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e);t.layoutInfo=n;var i=t.get("layout"),r=0,o=0,a=null;"radial"===i?(r=2*Math.PI,o=Math.min(n.height,n.width)/2,a=kC((function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth}))):(r=n.width,o=n.height,a=kC());var s=t.getData().tree.root,l=s.children[0];if(l){!function(t){var e=t;e.hierNode={defaultAncestor:null,ancestor:e,prelim:0,modifier:0,change:0,shift:0,i:0,thread:null};for(var n,i,r=[e];n=r.pop();)if(i=n.children,n.isExpand&&i.length)for(var o=i.length-1;o>=0;o--){var a=i[o];a.hierNode={defaultAncestor:null,ancestor:a,prelim:0,modifier:0,change:0,shift:0,i:o,thread:null},r.push(a)}}(s),function(t,e,n){for(var i,r=[t],o=[];i=r.pop();)if(o.push(i),i.isExpand){var a=i.children;if(a.length)for(var s=0;sh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)}));var p=u===h?1:a(u,h)/2,d=p-u.getLayout().x,f=0,g=0,y=0,v=0;if("radial"===i)f=r/(h.getLayout().x+p+d),g=o/(c.depth-1||1),lD(l,(function(t){y=(t.getLayout().x+d)*f,v=(t.depth-1)*g;var e=LC(y,v);t.setLayout({x:e.x,y:e.y,rawX:y,rawY:v},!0)}));else{var m=t.getOrient();"RL"===m||"LR"===m?(g=o/(h.getLayout().x+p+d),f=r/(c.depth-1||1),lD(l,(function(t){v=(t.getLayout().x+d)*g,y="LR"===m?(t.depth-1)*f:r-(t.depth-1)*f,t.setLayout({x:y,y:v},!0)}))):"TB"!==m&&"BT"!==m||(f=r/(h.getLayout().x+p+d),g=o/(c.depth-1||1),lD(l,(function(t){y=(t.getLayout().x+d)*f,v="TB"===m?(t.depth-1)*g:o-(t.depth-1)*g,t.setLayout({x:y,y:v},!0)})))}}}(t,e)}))}function hD(t){t.eachSeriesByType("tree",(function(t){var e=t.getData();e.tree.eachNode((function(t){var n=t.getModel().getModel("itemStyle").getItemStyle();A(e.ensureUniqueItemVisual(t.dataIndex,"style"),n)}))}))}var cD=["treemapZoomToNode","treemapRender","treemapMove"];function pD(t){var e=t.getData().tree,n={};e.eachNode((function(e){for(var i=e;i&&i.depth>1;)i=i.parentNode;var r=pd(t.ecModel,i.name||i.dataIndex+"",n);e.setVisual("decal",r)}))}var dD=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.preventUsingHoverLayer=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){var n={name:t.name,children:t.data};fD(n);var i=t.levels||[],r=this.designatedVisualItemStyle={},o=new Cc({itemStyle:r},this,e);i=t.levels=function(t,e){var n,i,r=To(e.get("color")),o=To(e.get(["aria","decal","decals"]));if(!r)return;t=t||[],E(t,(function(t){var e=new Cc(t),r=e.get("color"),o=e.get("decal");(e.get(["itemStyle","color"])||r&&"none"!==r)&&(n=!0),(e.get(["itemStyle","decal"])||o&&"none"!==o)&&(i=!0)}));var a=t[0]||(t[0]={});n||(a.color=r.slice());!i&&o&&(a.decal=o.slice());return t}(i,e);var a=z(i||[],(function(t){return new Cc(t,o,e)}),this),s=nD.createTree(n,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=s.getNodeByDataIndex(e),i=n?a[n.depth]:null;return t.parentModel=i||o,t}))}));return s.data},e.prototype.optionUpdated=function(){this.resetViewRoot()},e.prototype.formatTooltip=function(t,e,n){var i=this.getData(),r=this.getRawValue(t);return og("nameValue",{name:i.getName(t),value:r})},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treeAncestors=aD(i,this),n.treePathInfo=n.treeAncestors,n},e.prototype.setLayoutInfo=function(t){this.layoutInfo=this.layoutInfo||{},A(this.layoutInfo,t)},e.prototype.mapIdToIndex=function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=yt(),this._idIndexMapCount=0);var n=e.get(t);return null==n&&e.set(t,n=this._idIndexMapCount++),n},e.prototype.getViewRoot=function(){return this._viewRoot},e.prototype.resetViewRoot=function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)},e.prototype.enableAriaDecal=function(){pD(this)},e.type="series.treemap",e.layoutMode="box",e.defaultOption={progressive:0,left:"center",top:"middle",width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,scaleLimit:null,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",textStyle:{color:"#fff"}},emphasis:{itemStyle:{color:"rgba(0,0,0,0.9)"}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",overflow:"truncate"},upperLabel:{show:!1,position:[0,"50%"],height:20,overflow:"truncate",verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],overflow:"truncate",verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},e}(bg);function fD(t){var e=0;E(t.children,(function(t){fD(t);var n=t.value;Y(n)&&(n=n[0]),e+=n}));var n=t.value;Y(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),Y(t.value)?t.value[0]=n:t.value=n}var gD=function(){function t(t){this.group=new Br,t.add(this.group)}return t.prototype.render=function(t,e,n,i){var r=t.getModel("breadcrumb"),o=this.group;if(o.removeAll(),r.get("show")&&n){var a=r.getModel("itemStyle"),s=r.getModel("emphasis"),l=a.getModel("textStyle"),u=s.getModel(["itemStyle","textStyle"]),h={pos:{left:r.get("left"),right:r.get("right"),top:r.get("top"),bottom:r.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:r.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(n,h,l),this._renderContent(t,h,a,s,l,u,i),Lp(o,h.pos,h.box)}},t.prototype._prepare=function(t,e,n){for(var i=t;i;i=i.parentNode){var r=Ro(i.getModel().get("name"),""),o=n.getTextRect(r),a=Math.max(o.width+16,e.emptyItemWidth);e.totalWidth+=a+8,e.renderList.push({node:i,text:r,width:a})}},t.prototype._renderContent=function(t,e,n,i,r,o,a){for(var s,l,u,h,c,p,d,f,g,y=0,v=e.emptyItemWidth,m=t.get(["breadcrumb","height"]),x=(s=e.pos,l=e.box,h=l.width,c=l.height,p=$r(s.left,h),d=$r(s.top,c),f=$r(s.right,h),g=$r(s.bottom,c),(isNaN(p)||isNaN(parseFloat(s.left)))&&(p=0),(isNaN(f)||isNaN(parseFloat(s.right)))&&(f=h),(isNaN(d)||isNaN(parseFloat(s.top)))&&(d=0),(isNaN(g)||isNaN(parseFloat(s.bottom)))&&(g=c),u=vp(u||0),{width:Math.max(f-p-u[1]-u[3],0),height:Math.max(g-d-u[0]-u[2],0)}),_=e.totalWidth,b=e.renderList,w=i.getModel("itemStyle").getItemStyle(),S=b.length-1;S>=0;S--){var M=b[S],I=M.node,T=M.width,C=M.text;_>x.width&&(_-=T-v,T=v,C=null);var D=new Xu({shape:{points:yD(y,0,T,m,S===b.length-1,0===S)},style:k(n.getItemStyle(),{lineJoin:"bevel"}),textContent:new Xs({style:oc(r,{text:C})}),textConfig:{position:"inside"},z2:1e5,onclick:H(a,I)});D.disableLabelAnimation=!0,D.getTextContent().ensureState("emphasis").style=oc(o,{text:C}),D.ensureState("emphasis").style=w,Zl(D,i.get("focus"),i.get("blurScope"),i.get("disabled")),this.group.add(D),vD(D,t,I),y+=T+8}},t.prototype.remove=function(){this.group.removeAll()},t}();function yD(t,e,n,i,r,o){var a=[[r?t:t-5,e],[t+n,e],[t+n,e+i],[r?t:t-5,e+i]];return!o&&a.splice(2,0,[t+n+5,e+i/2]),!r&&a.push([t,e+i/2]),a}function vD(t,e,n){rl(t).eventData={componentType:"series",componentSubType:"treemap",componentIndex:e.componentIndex,seriesIndex:e.seriesIndex,seriesName:e.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:n&&n.dataIndex,name:n&&n.name},treePathInfo:n&&aD(n,e)}}var mD=function(){function t(){this._storage=[],this._elExistsMap={}}return t.prototype.add=function(t,e,n,i,r){return!this._elExistsMap[t.id]&&(this._elExistsMap[t.id]=!0,this._storage.push({el:t,target:e,duration:n,delay:i,easing:r}),!0)},t.prototype.finished=function(t){return this._finishedCallback=t,this},t.prototype.start=function(){for(var t=this,e=this._storage.length,n=function(){--e<=0&&(t._storage.length=0,t._elExistsMap={},t._finishedCallback&&t._finishedCallback())},i=0,r=this._storage.length;i3||Math.abs(t.dy)>3)){var e=this.seriesModel.getData().tree.root;if(!e)return;var n=e.getLayout();if(!n)return;this.api.dispatchAction({type:"treemapMove",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:n.x+t.dx,y:n.y+t.dy,width:n.width,height:n.height}})}},e.prototype._onZoom=function(t){var e=t.originX,n=t.originY,i=t.scale;if("animating"!==this._state){var r=this.seriesModel.getData().tree.root;if(!r)return;var o=r.getLayout();if(!o)return;var a,s=new ze(o.x,o.y,o.width,o.height),l=this._controllerHost;a=l.zoomLimit;var u=l.zoom=l.zoom||1;if(u*=i,a){var h=a.min||0,c=a.max||1/0;u=Math.max(Math.min(c,u),h)}var p=u/l.zoom;l.zoom=u;var d=this.seriesModel.layoutInfo,f=[1,0,0,1,0,0];we(f,f,[-(e-=d.x),-(n-=d.y)]),Me(f,f,[p,p]),we(f,f,[e,n]),s.applyTransform(f),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:s.x,y:s.y,width:s.width,height:s.height}})}},e.prototype._initEvents=function(t){var e=this;t.on("click",(function(t){if("ready"===e._state){var n=e.seriesModel.get("nodeClick",!0);if(n){var i=e.findTarget(t.offsetX,t.offsetY);if(i){var r=i.node;if(r.getLayout().isLeafRoot)e._rootToNode(i);else if("zoomToNode"===n)e._zoomToNode(i);else if("link"===n){var o=r.hostTree.data.getItemModel(r.dataIndex),a=o.get("link",!0),s=o.get("target",!0)||"blank";a&&Mp(a,s)}}}}}),this)},e.prototype._renderBreadcrumb=function(t,e,n){var i=this;n||(n=null!=t.get("leafDepth",!0)?{node:t.getViewRoot()}:this.findTarget(e.getWidth()/2,e.getHeight()/2))||(n={node:t.getData().tree.root}),(this._breadcrumb||(this._breadcrumb=new gD(this.group))).render(t,e,n.node,(function(e){"animating"!==i._state&&(oD(t.getViewRoot(),e)?i._rootToNode({node:e}):i._zoomToNode({node:e}))}))},e.prototype.remove=function(){this._clearController(),this._containerGroup&&this._containerGroup.removeAll(),this._storage={nodeGroup:[],background:[],content:[]},this._state="ready",this._breadcrumb&&this._breadcrumb.remove()},e.prototype.dispose=function(){this._clearController()},e.prototype._zoomToNode=function(t){this.api.dispatchAction({type:"treemapZoomToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},e.prototype._rootToNode=function(t){this.api.dispatchAction({type:"treemapRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},e.prototype.findTarget=function(t,e){var n;return this.seriesModel.getViewRoot().eachNode({attr:"viewChildren",order:"preorder"},(function(i){var r=this._storage.background[i.getRawIndex()];if(r){var o=r.transformCoordToLocal(t,e),a=r.shape;if(!(a.x<=o[0]&&o[0]<=a.x+a.width&&a.y<=o[1]&&o[1]<=a.y+a.height))return!1;n={node:i,offsetX:o[0],offsetY:o[1]}}}),this),n},e.type="treemap",e}(Og);var CD=E,DD=q,AD=-1,kD=function(){function t(e){var n=e.mappingMethod,i=e.type,r=this.option=T(e);this.type=i,this.mappingMethod=n,this._normalizeData=FD[n];var o=t.visualHandlers[i];this.applyVisual=o.applyVisual,this.getColorMapper=o.getColorMapper,this._normalizedToVisual=o._normalizedToVisual[n],"piecewise"===n?(LD(r),function(t){var e=t.pieceList;t.hasSpecialVisual=!1,E(e,(function(e,n){e.originIndex=n,null!=e.visual&&(t.hasSpecialVisual=!0)}))}(r)):"category"===n?r.categories?function(t){var e=t.categories,n=t.categoryMap={},i=t.visual;if(CD(e,(function(t,e){n[t]=e})),!Y(i)){var r=[];q(i)?CD(i,(function(t,e){var i=n[e];r[null!=i?i:AD]=t})):r[-1]=i,i=BD(t,r)}for(var o=e.length-1;o>=0;o--)null==i[o]&&(delete n[e[o]],e.pop())}(r):LD(r,!0):(lt("linear"!==n||r.dataExtent),LD(r))}return t.prototype.mapValueToVisual=function(t){var e=this._normalizeData(t);return this._normalizedToVisual(e,t)},t.prototype.getNormalizer=function(){return W(this._normalizeData,this)},t.listVisualTypes=function(){return G(t.visualHandlers)},t.isValidType=function(e){return t.visualHandlers.hasOwnProperty(e)},t.eachVisual=function(t,e,n){q(t)?E(t,e,n):e.call(n,t)},t.mapVisual=function(e,n,i){var r,o=Y(e)?[]:q(e)?{}:(r=!0,null);return t.eachVisual(e,(function(t,e){var a=n.call(i,t,e);r?o=a:o[e]=a})),o},t.retrieveVisuals=function(e){var n,i={};return e&&CD(t.visualHandlers,(function(t,r){e.hasOwnProperty(r)&&(i[r]=e[r],n=!0)})),n?i:null},t.prepareVisualTypes=function(t){if(Y(t))t=t.slice();else{if(!DD(t))return[];var e=[];CD(t,(function(t,n){e.push(n)})),t=e}return t.sort((function(t,e){return"color"===e&&"color"!==t&&0===t.indexOf("color")?1:-1})),t},t.dependsOn=function(t,e){return"color"===e?!(!t||0!==t.indexOf(e)):t===e},t.findPieceIndex=function(t,e,n){for(var i,r=1/0,o=0,a=e.length;ou[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:a.name,dataExtent:u,visual:a.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var p=new kD(c);return WD(p).drColorMappingBy=h,p}(0,r,o,0,u,d);E(d,(function(t,e){if(t.depth>=n.length||t===n[t.depth]){var o=function(t,e,n,i,r,o){var a=A({},e);if(r){var s=r.type,l="color"===s&&WD(r).drColorMappingBy,u="index"===l?i:"id"===l?o.mapIdToIndex(n.getId()):n.getValue(t.get("visualDimension"));a[s]=r.mapValueToVisual(u)}return a}(r,u,t,e,f,i);YD(t,o,n,i)}}))}else s=XD(u),h.fill=s}}function XD(t){var e=UD(t,"color");if(e){var n=UD(t,"colorAlpha"),i=UD(t,"colorSaturation");return i&&(e=ni(e,null,null,i)),n&&(e=ii(e,n)),e}}function UD(t,e){var n=t[e];if(null!=n&&"none"!==n)return n}function ZD(t,e){var n=t.get(e);return Y(n)&&n.length?{name:e,range:n}:null}var jD=Math.max,qD=Math.min,KD=it,$D=E,JD=["itemStyle","borderWidth"],QD=["itemStyle","gapWidth"],tA=["upperLabel","show"],eA=["upperLabel","height"],nA={seriesType:"treemap",reset:function(t,e,n,i){var r=n.getWidth(),o=n.getHeight(),a=t.option,s=kp(t.getBoxLayoutParams(),{width:n.getWidth(),height:n.getHeight()}),l=a.size||[],u=$r(KD(s.width,l[0]),r),h=$r(KD(s.height,l[1]),o),c=i&&i.type,p=iD(i,["treemapZoomToNode","treemapRootToNode"],t),d="treemapRender"===c||"treemapMove"===c?i.rootRect:null,f=t.getViewRoot(),g=rD(f);if("treemapMove"!==c){var y="treemapZoomToNode"===c?function(t,e,n,i,r){var o,a=(e||{}).node,s=[i,r];if(!a||a===n)return s;var l=i*r,u=l*t.option.zoomToNodeRatio;for(;o=a.parentNode;){for(var h=0,c=o.children,p=0,d=c.length;poo&&(u=oo),a=o}ua[1]&&(a[1]=e)}))):a=[NaN,NaN];return{sum:i,dataExtent:a}}(e,a,s);if(0===u.sum)return t.viewChildren=[];if(u.sum=function(t,e,n,i,r){if(!i)return n;for(var o=t.get("visibleMin"),a=r.length,s=a,l=a-1;l>=0;l--){var u=r["asc"===i?a-l-1:l].getValue();u/n*ei&&(i=a));var l=t.area*t.area,u=e*e*n;return l?jD(u*i/l,l/(u*r)):1/0}function oA(t,e,n,i,r){var o=e===n.width?0:1,a=1-o,s=["x","y"],l=["width","height"],u=n[s[o]],h=e?t.area/e:0;(r||h>n[l[a]])&&(h=n[l[a]]);for(var c=0,p=t.length;ci&&(i=e);var o=i%2?i+2:i+3;r=[];for(var a=0;a0&&(m[0]=-m[0],m[1]=-m[1]);var _=v[0]<0?-1:1;if("start"!==i.__position&&"end"!==i.__position){var b=-Math.atan2(v[1],v[0]);u[0].8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";break;case"start":i.x=-h[0]*f+l[0],i.y=-h[1]*g+l[1],c=h[0]>.8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";break;case"insideStartTop":case"insideStart":case"insideStartBottom":i.x=f*_+l[0],i.y=l[1]+w,c=v[0]<0?"right":"left",i.originX=-f*_,i.originY=-w;break;case"insideMiddleTop":case"insideMiddle":case"insideMiddleBottom":case"middle":i.x=x[0],i.y=x[1]+w,c="center",i.originY=-w;break;case"insideEndTop":case"insideEnd":case"insideEndBottom":i.x=-f*_+u[0],i.y=u[1]+w,c=v[0]>=0?"right":"left",i.originX=f*_,i.originY=-w}i.scaleX=i.scaleY=r,i.setStyle({verticalAlign:i.__verticalAlign||p,align:i.__align||c})}}}function S(t,e){var n=t.__specifiedRotation;if(null==n){var i=a.tangentAt(e);t.attr("rotation",(1===e?-1:1)*Math.PI/2-Math.atan2(i[1],i[0]))}else t.attr("rotation",n)}},e}(Br),YA=function(){function t(t){this.group=new Br,this._LineCtor=t||HA}return t.prototype.updateData=function(t){var e=this;this._progressiveEls=null;var n=this,i=n.group,r=n._lineData;n._lineData=t,r||i.removeAll();var o=XA(t);t.diff(r).add((function(n){e._doAdd(t,n,o)})).update((function(n,i){e._doUpdate(r,t,i,n,o)})).remove((function(t){i.remove(r.getItemGraphicEl(t))})).execute()},t.prototype.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl((function(e,n){e.updateLayout(t,n)}),this)},t.prototype.incrementalPrepareUpdate=function(t){this._seriesScope=XA(t),this._lineData=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e){function n(t){t.isGroup||function(t){return t.animators&&t.animators.length>0}(t)||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}this._progressiveEls=[];for(var i=t.start;i=0?i+=u:i-=u:f>=0?i-=u:i+=u}return i}function ek(t,e){var n=[],i=Dn,r=[[],[],[]],o=[[],[]],a=[];e/=2,t.eachEdge((function(t,s){var l=t.getLayout(),u=t.getVisual("fromSymbol"),h=t.getVisual("toSymbol");l.__original||(l.__original=[Tt(l[0]),Tt(l[1])],l[2]&&l.__original.push(Tt(l[2])));var c=l.__original;if(null!=l[2]){if(It(r[0],c[0]),It(r[1],c[2]),It(r[2],c[1]),u&&"none"!==u){var p=SA(t.node1),d=tk(r,c[0],p*e);i(r[0][0],r[1][0],r[2][0],d,n),r[0][0]=n[3],r[1][0]=n[4],i(r[0][1],r[1][1],r[2][1],d,n),r[0][1]=n[3],r[1][1]=n[4]}if(h&&"none"!==h){p=SA(t.node2),d=tk(r,c[1],p*e);i(r[0][0],r[1][0],r[2][0],d,n),r[1][0]=n[1],r[2][0]=n[2],i(r[0][1],r[1][1],r[2][1],d,n),r[1][1]=n[1],r[2][1]=n[2]}It(l[0],r[0]),It(l[1],r[2]),It(l[2],r[1])}else{if(It(o[0],c[0]),It(o[1],c[1]),kt(a,o[1],o[0]),Et(a,a),u&&"none"!==u){p=SA(t.node1);At(o[0],o[0],a,p*e)}if(h&&"none"!==h){p=SA(t.node2);At(o[1],o[1],a,-p*e)}It(l[0],o[0]),It(l[1],o[1])}}))}function nk(t){return"view"===t.type}var ik=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){var n=new xS,i=new YA,r=this.group;this._controller=new nT(e.getZr()),this._controllerHost={target:r},r.add(n.group),r.add(i.group),this._symbolDraw=n,this._lineDraw=i,this._firstRender=!0},e.prototype.render=function(t,e,n){var i=this,r=t.coordinateSystem;this._model=t;var o=this._symbolDraw,a=this._lineDraw,s=this.group;if(nk(r)){var l={x:r.x,y:r.y,scaleX:r.scaleX,scaleY:r.scaleY};this._firstRender?s.attr(l):vh(s,l,t)}ek(t.getGraph(),wA(t));var u=t.getData();o.updateData(u);var h=t.getEdgeData();a.updateData(h),this._updateNodeAndLinkScale(),this._updateController(t,e,n),clearTimeout(this._layoutTimeout);var c=t.forceLayout,p=t.get(["force","layoutAnimation"]);c&&this._startForceLayoutIteration(c,p);var d=t.get("layout");u.graph.eachNode((function(e){var n=e.dataIndex,r=e.getGraphicEl(),o=e.getModel();if(r){r.off("drag").off("dragend");var a=o.get("draggable");a&&r.on("drag",(function(o){switch(d){case"force":c.warmUp(),!i._layouting&&i._startForceLayoutIteration(c,p),c.setFixed(n),u.setItemLayout(n,[r.x,r.y]);break;case"circular":u.setItemLayout(n,[r.x,r.y]),e.setLayout({fixed:!0},!0),TA(t,"symbolSize",e,[o.offsetX,o.offsetY]),i.updateLayout(t);break;default:u.setItemLayout(n,[r.x,r.y]),_A(t.getGraph(),t),i.updateLayout(t)}})).on("dragend",(function(){c&&c.setUnfixed(n)})),r.setDraggable(a,!!o.get("cursor")),"adjacency"===o.get(["emphasis","focus"])&&(rl(r).focus=e.getAdjacentDataIndices())}})),u.graph.eachEdge((function(t){var e=t.getGraphicEl(),n=t.getModel().get(["emphasis","focus"]);e&&"adjacency"===n&&(rl(e).focus={edge:[t.dataIndex],node:[t.node1.dataIndex,t.node2.dataIndex]})}));var f="circular"===t.get("layout")&&t.get(["circular","rotateLabel"]),g=u.getLayout("cx"),y=u.getLayout("cy");u.graph.eachNode((function(t){DA(t,f,g,y)})),this._firstRender=!1},e.prototype.dispose=function(){this.remove(),this._controller&&this._controller.dispose(),this._controllerHost=null},e.prototype._startForceLayoutIteration=function(t,e){var n=this;!function i(){t.step((function(t){n.updateLayout(n._model),(n._layouting=!t)&&(e?n._layoutTimeout=setTimeout(i,16):i())}))}()},e.prototype._updateController=function(t,e,n){var i=this,r=this._controller,o=this._controllerHost,a=this.group;r.setPointerChecker((function(e,i,r){var o=a.getBoundingRect();return o.applyTransform(a.transform),o.contain(i,r)&&!hT(e,n,t)})),nk(t.coordinateSystem)?(r.enable(t.get("roam")),o.zoomLimit=t.get("scaleLimit"),o.zoom=t.coordinateSystem.getZoom(),r.off("pan").off("zoom").on("pan",(function(e){aT(o,e.dx,e.dy),n.dispatchAction({seriesId:t.id,type:"graphRoam",dx:e.dx,dy:e.dy})})).on("zoom",(function(e){sT(o,e.scale,e.originX,e.originY),n.dispatchAction({seriesId:t.id,type:"graphRoam",zoom:e.scale,originX:e.originX,originY:e.originY}),i._updateNodeAndLinkScale(),ek(t.getGraph(),wA(t)),i._lineDraw.updateLayout(),n.updateLabelLayout()}))):r.disable()},e.prototype._updateNodeAndLinkScale=function(){var t=this._model,e=t.getData(),n=wA(t);e.eachItemGraphicEl((function(t,e){t&&t.setSymbolScale(n)}))},e.prototype.updateLayout=function(t){ek(t.getGraph(),wA(t)),this._symbolDraw.updateLayout(),this._lineDraw.updateLayout()},e.prototype.remove=function(){clearTimeout(this._layoutTimeout),this._layouting=!1,this._layoutTimeout=null,this._symbolDraw&&this._symbolDraw.remove(),this._lineDraw&&this._lineDraw.remove()},e.type="graph",e}(Og);function rk(t){return"_EC_"+t}var ok=function(){function t(t){this.type="graph",this.nodes=[],this.edges=[],this._nodesMap={},this._edgesMap={},this._directed=t||!1}return t.prototype.isDirected=function(){return this._directed},t.prototype.addNode=function(t,e){t=null==t?""+e:""+t;var n=this._nodesMap;if(!n[rk(t)]){var i=new ak(t,e);return i.hostGraph=this,this.nodes.push(i),n[rk(t)]=i,i}},t.prototype.getNodeByIndex=function(t){var e=this.data.getRawIndex(t);return this.nodes[e]},t.prototype.getNodeById=function(t){return this._nodesMap[rk(t)]},t.prototype.addEdge=function(t,e,n){var i=this._nodesMap,r=this._edgesMap;if(j(t)&&(t=this.nodes[t]),j(e)&&(e=this.nodes[e]),t instanceof ak||(t=i[rk(t)]),e instanceof ak||(e=i[rk(e)]),t&&e){var o=t.id+"-"+e.id,a=new sk(t,e,n);return a.hostGraph=this,this._directed&&(t.outEdges.push(a),e.inEdges.push(a)),t.edges.push(a),t!==e&&e.edges.push(a),this.edges.push(a),r[o]=a,a}},t.prototype.getEdgeByIndex=function(t){var e=this.edgeData.getRawIndex(t);return this.edges[e]},t.prototype.getEdge=function(t,e){t instanceof ak&&(t=t.id),e instanceof ak&&(e=e.id);var n=this._edgesMap;return this._directed?n[t+"-"+e]:n[t+"-"+e]||n[e+"-"+t]},t.prototype.eachNode=function(t,e){for(var n=this.nodes,i=n.length,r=0;r=0&&t.call(e,n[r],r)},t.prototype.eachEdge=function(t,e){for(var n=this.edges,i=n.length,r=0;r=0&&n[r].node1.dataIndex>=0&&n[r].node2.dataIndex>=0&&t.call(e,n[r],r)},t.prototype.breadthFirstTraverse=function(t,e,n,i){if(e instanceof ak||(e=this._nodesMap[rk(e)]),e){for(var r="out"===n?"outEdges":"in"===n?"inEdges":"edges",o=0;o=0&&n.node2.dataIndex>=0}));for(r=0,o=i.length;r=0&&this[t][e].setItemVisual(this.dataIndex,n,i)},getVisual:function(n){return this[t][e].getItemVisual(this.dataIndex,n)},setLayout:function(n,i){this.dataIndex>=0&&this[t][e].setItemLayout(this.dataIndex,n,i)},getLayout:function(){return this[t][e].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[t][e].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[t][e].getRawIndex(this.dataIndex)}}}function uk(t,e,n,i,r){for(var o=new ok(i),a=0;a "+p)),u++)}var d,f=n.get("coordinateSystem");if("cartesian2d"===f||"polar"===f)d=_x(t,n);else{var g=wd.get(f),y=g&&g.dimensions||[];P(y,"value")<0&&y.concat(["value"]);var v=px(t,{coordDimensions:y,encodeDefine:n.getEncode()}).dimensions;(d=new cx(v,n)).initData(t)}var m=new cx(["value"],n);return m.initData(l,s),r&&r(d,m),ZC({mainData:d,struct:o,structAttr:"graph",datas:{node:d,edge:m},datasAttr:{node:"data",edge:"edgeData"}}),o.update(),o}R(ak,lk("hostGraph","data")),R(sk,lk("hostGraph","edgeData"));var hk=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments);var n=this;function i(){return n._categoriesData}this.legendVisualProvider=new NM(i,i),this.fillDataTextStyle(e.edges||e.links),this._updateCategoriesData()},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),this.fillDataTextStyle(e.edges||e.links),this._updateCategoriesData()},e.prototype.mergeDefaultAndTheme=function(e){t.prototype.mergeDefaultAndTheme.apply(this,arguments),Co(e,"edgeLabel",["show"])},e.prototype.getInitialData=function(t,e){var n,i=t.edges||t.links||[],r=t.data||t.nodes||[],o=this;if(r&&i){dA(n=this)&&(n.__curvenessList=[],n.__edgeMap={},fA(n));var a=uk(r,i,this,!0,(function(t,e){t.wrapMethod("getItemModel",(function(t){var e=o._categoriesModels[t.getShallow("category")];return e&&(e.parentModel=t.parentModel,t.parentModel=e),t}));var n=Cc.prototype.getModel;function i(t,e){var i=n.call(this,t,e);return i.resolveParentPath=r,i}function r(t){if(t&&("label"===t[0]||"label"===t[1])){var e=t.slice();return"label"===t[0]?e[0]="edgeLabel":"label"===t[1]&&(e[1]="edgeLabel"),e}return t}e.wrapMethod("getItemModel",(function(t){return t.resolveParentPath=r,t.getModel=i,t}))}));return E(a.edges,(function(t){!function(t,e,n,i){if(dA(n)){var r=gA(t,e,n),o=n.__edgeMap,a=o[yA(r)];o[r]&&!a?o[r].isForward=!0:a&&o[r]&&(a.isForward=!0,o[r].isForward=!1),o[r]=o[r]||[],o[r].push(i)}}(t.node1,t.node2,this,t.dataIndex)}),this),a.data}},e.prototype.getGraph=function(){return this.getData().graph},e.prototype.getEdgeData=function(){return this.getGraph().edgeData},e.prototype.getCategoriesData=function(){return this._categoriesData},e.prototype.formatTooltip=function(t,e,n){if("edge"===n){var i=this.getData(),r=this.getDataParams(t,n),o=i.graph.getEdgeByIndex(t),a=i.getName(o.node1.dataIndex),s=i.getName(o.node2.dataIndex),l=[];return null!=a&&l.push(a),null!=s&&l.push(s),og("nameValue",{name:l.join(" > "),value:r.value,noValue:null==r.value})}return vg({series:this,dataIndex:t,multipleSeries:e})},e.prototype._updateCategoriesData=function(){var t=z(this.option.categories||[],(function(t){return null!=t.value?t:A({value:0},t)})),e=new cx(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray((function(t){return e.getItemModel(t)}))},e.prototype.setZoom=function(t){this.option.zoom=t},e.prototype.setCenter=function(t){this.option.center=t},e.prototype.isAnimationEnabled=function(){return t.prototype.isAnimationEnabled.call(this)&&!("force"===this.get("layout")&&this.get(["force","layoutAnimation"]))},e.type="series.graph",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={z:2,coordinateSystem:"view",legendHoverLink:!0,layout:null,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,friction:.6,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle",distance:5},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,opacity:.5},emphasis:{scale:!0,label:{show:!0}},select:{itemStyle:{borderColor:"#212121"}}},e}(bg),ck={type:"graphRoam",event:"graphRoam",update:"none"};var pk=function(){this.angle=0,this.width=10,this.r=10,this.x=0,this.y=0},dk=function(t){function e(e){var n=t.call(this,e)||this;return n.type="pointer",n}return n(e,t),e.prototype.getDefaultShape=function(){return new pk},e.prototype.buildPath=function(t,e){var n=Math.cos,i=Math.sin,r=e.r,o=e.width,a=e.angle,s=e.x-n(a)*o*(o>=r/3?1:2),l=e.y-i(a)*o*(o>=r/3?1:2);a=e.angle-Math.PI/2,t.moveTo(s,l),t.lineTo(e.x+n(a)*o,e.y+i(a)*o),t.lineTo(e.x+n(e.angle)*r,e.y+i(e.angle)*r),t.lineTo(e.x-n(a)*o,e.y-i(a)*o),t.lineTo(s,l)},e}(ks);function fk(t,e){var n=null==t?"":t+"";return e&&(U(e)?n=e.replace("{value}",n):X(e)&&(n=e(t))),n}var gk=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeAll();var i=t.get(["axisLine","lineStyle","color"]),r=function(t,e){var n=t.get("center"),i=e.getWidth(),r=e.getHeight(),o=Math.min(i,r);return{cx:$r(n[0],e.getWidth()),cy:$r(n[1],e.getHeight()),r:$r(t.get("radius"),o/2)}}(t,n);this._renderMain(t,e,n,i,r),this._data=t.getData()},e.prototype.dispose=function(){},e.prototype._renderMain=function(t,e,n,i,r){var o=this.group,a=t.get("clockwise"),s=-t.get("startAngle")/180*Math.PI,l=-t.get("endAngle")/180*Math.PI,u=t.getModel("axisLine"),h=u.get("roundCap")?JS:Fu,c=u.get("show"),p=u.getModel("lineStyle"),d=p.get("width"),f=[s,l];us(f,!a);for(var g=(l=f[1])-(s=f[0]),y=s,v=[],m=0;c&&m=t&&(0===e?0:i[e-1][0])Math.PI/2&&(V+=Math.PI):"tangential"===z?V=-M-Math.PI/2:j(z)&&(V=z*Math.PI/180),0===V?c.add(new Xs({style:oc(x,{text:O,x:N,y:E,verticalAlign:h<-.8?"top":h>.8?"bottom":"middle",align:u<-.4?"left":u>.4?"right":"center"},{inheritColor:R}),silent:!0})):c.add(new Xs({style:oc(x,{text:O,x:N,y:E,verticalAlign:"middle",align:"center"},{inheritColor:R}),silent:!0,originX:N,originY:E,rotation:V}))}if(m.get("show")&&k!==_){P=(P=m.get("distance"))?P+l:l;for(var B=0;B<=b;B++){u=Math.cos(M),h=Math.sin(M);var F=new Ku({shape:{x1:u*(f-P)+p,y1:h*(f-P)+d,x2:u*(f-S-P)+p,y2:h*(f-S-P)+d},silent:!0,style:D});"auto"===D.stroke&&F.setStyle({stroke:i((k+B/b)/_)}),c.add(F),M+=T}M-=T}else M+=I}},e.prototype._renderPointer=function(t,e,n,i,r,o,a,s,l){var u=this.group,h=this._data,c=this._progressEls,p=[],d=t.get(["pointer","show"]),f=t.getModel("progress"),g=f.get("show"),y=t.getData(),v=y.mapDimension("value"),m=+t.get("min"),x=+t.get("max"),_=[m,x],b=[o,a];function w(e,n){var i,o=y.getItemModel(e).getModel("pointer"),a=$r(o.get("width"),r.r),s=$r(o.get("length"),r.r),l=t.get(["pointer","icon"]),u=o.get("offsetCenter"),h=$r(u[0],r.r),c=$r(u[1],r.r),p=o.get("keepAspect");return(i=l?Xy(l,h-a/2,c-s,a,s,null,p):new dk({shape:{angle:-Math.PI/2,width:a,r:s,x:h,y:c}})).rotation=-(n+Math.PI/2),i.x=r.cx,i.y=r.cy,i}function S(t,e){var n=f.get("roundCap")?JS:Fu,i=f.get("overlap"),a=i?f.get("width"):l/y.count(),u=i?r.r-a:r.r-(t+1)*a,h=i?r.r:r.r-t*a,c=new n({shape:{startAngle:o,endAngle:e,cx:r.cx,cy:r.cy,clockwise:s,r0:u,r:h}});return i&&(c.z2=Kr(y.get(v,t),[m,x],[100,0],!0)),c}(g||d)&&(y.diff(h).add((function(e){var n=y.get(v,e);if(d){var i=w(e,o);mh(i,{rotation:-((isNaN(+n)?b[0]:Kr(n,_,b,!0))+Math.PI/2)},t),u.add(i),y.setItemGraphicEl(e,i)}if(g){var r=S(e,o),a=f.get("clip");mh(r,{shape:{endAngle:Kr(n,_,b,a)}},t),u.add(r),ol(t.seriesIndex,y.dataType,e,r),p[e]=r}})).update((function(e,n){var i=y.get(v,e);if(d){var r=h.getItemGraphicEl(n),a=r?r.rotation:o,s=w(e,a);s.rotation=a,vh(s,{rotation:-((isNaN(+i)?b[0]:Kr(i,_,b,!0))+Math.PI/2)},t),u.add(s),y.setItemGraphicEl(e,s)}if(g){var l=c[n],m=S(e,l?l.shape.endAngle:o),x=f.get("clip");vh(m,{shape:{endAngle:Kr(i,_,b,x)}},t),u.add(m),ol(t.seriesIndex,y.dataType,e,m),p[e]=m}})).execute(),y.each((function(t){var e=y.getItemModel(t),n=e.getModel("emphasis"),r=n.get("focus"),o=n.get("blurScope"),a=n.get("disabled");if(d){var s=y.getItemGraphicEl(t),l=y.getItemVisual(t,"style"),u=l.fill;if(s instanceof Ns){var h=s.style;s.useStyle(A({image:h.image,x:h.x,y:h.y,width:h.width,height:h.height},l))}else s.useStyle(l),"pointer"!==s.type&&s.setColor(u);s.setStyle(e.getModel(["pointer","itemStyle"]).getItemStyle()),"auto"===s.style.fill&&s.setStyle("fill",i(Kr(y.get(v,t),_,[0,1],!0))),s.z2EmphasisLift=0,$l(s,e),Zl(s,r,o,a)}if(g){var c=p[t];c.useStyle(y.getItemVisual(t,"style")),c.setStyle(e.getModel(["progress","itemStyle"]).getItemStyle()),c.z2EmphasisLift=0,$l(c,e),Zl(c,r,o,a)}})),this._progressEls=p)},e.prototype._renderAnchor=function(t,e){var n=t.getModel("anchor");if(n.get("show")){var i=n.get("size"),r=n.get("icon"),o=n.get("offsetCenter"),a=n.get("keepAspect"),s=Xy(r,e.cx-i/2+$r(o[0],e.r),e.cy-i/2+$r(o[1],e.r),i,i,null,a);s.z2=n.get("showAbove")?1:0,s.setStyle(n.getModel("itemStyle").getItemStyle()),this.group.add(s)}},e.prototype._renderTitleAndDetail=function(t,e,n,i,r){var o=this,a=t.getData(),s=a.mapDimension("value"),l=+t.get("min"),u=+t.get("max"),h=new Br,c=[],p=[],d=t.isAnimationEnabled(),f=t.get(["pointer","showAbove"]);a.diff(this._data).add((function(t){c[t]=new Xs({silent:!0}),p[t]=new Xs({silent:!0})})).update((function(t,e){c[t]=o._titleEls[e],p[t]=o._detailEls[e]})).execute(),a.each((function(e){var n=a.getItemModel(e),o=a.get(s,e),g=new Br,y=i(Kr(o,[l,u],[0,1],!0)),v=n.getModel("title");if(v.get("show")){var m=v.get("offsetCenter"),x=r.cx+$r(m[0],r.r),_=r.cy+$r(m[1],r.r);(D=c[e]).attr({z2:f?0:2,style:oc(v,{x:x,y:_,text:a.getName(e),align:"center",verticalAlign:"middle"},{inheritColor:y})}),g.add(D)}var b=n.getModel("detail");if(b.get("show")){var w=b.get("offsetCenter"),S=r.cx+$r(w[0],r.r),M=r.cy+$r(w[1],r.r),I=$r(b.get("width"),r.r),T=$r(b.get("height"),r.r),C=t.get(["progress","show"])?a.getItemVisual(e,"style").fill:y,D=p[e],A=b.get("formatter");D.attr({z2:f?0:2,style:oc(b,{x:S,y:M,text:fk(o,A),width:isNaN(I)?null:I,height:isNaN(T)?null:T,align:"center",verticalAlign:"middle"},{inheritColor:C})}),dc(D,{normal:b},o,(function(t){return fk(t,A)})),d&&fc(D,e,a,t,{getFormattedLabel:function(t,e,n,i,r,a){return fk(a?a.interpolatedValue:o,A)}}),g.add(D)}h.add(g)})),this.group.add(h),this._titleEls=c,this._detailEls=p},e.type="gauge",e}(Og),yk=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.visualStyleAccessPath="itemStyle",n}return n(e,t),e.prototype.getInitialData=function(t,e){return RM(this,["value"])},e.type="series.gauge",e.defaultOption={z:2,colorBy:"data",center:["50%","50%"],legendHoverLink:!0,radius:"75%",startAngle:225,endAngle:-45,clockwise:!0,min:0,max:100,splitNumber:10,axisLine:{show:!0,roundCap:!1,lineStyle:{color:[[1,"#E6EBF8"]],width:10}},progress:{show:!1,overlap:!0,width:10,roundCap:!1,clip:!0},splitLine:{show:!0,length:10,distance:10,lineStyle:{color:"#63677A",width:3,type:"solid"}},axisTick:{show:!0,splitNumber:5,length:6,distance:10,lineStyle:{color:"#63677A",width:1,type:"solid"}},axisLabel:{show:!0,distance:15,color:"#464646",fontSize:12,rotate:0},pointer:{icon:null,offsetCenter:[0,0],show:!0,showAbove:!0,length:"60%",width:6,keepAspect:!1},anchor:{show:!1,showAbove:!1,size:6,icon:"circle",offsetCenter:[0,0],keepAspect:!1,itemStyle:{color:"#fff",borderWidth:0,borderColor:"#5470c6"}},title:{show:!0,offsetCenter:[0,"20%"],color:"#464646",fontSize:16,valueAnimation:!1},detail:{show:!0,backgroundColor:"rgba(0,0,0,0)",borderWidth:0,borderColor:"#ccc",width:100,height:null,padding:[5,10],offsetCenter:[0,"40%"],color:"#464646",fontSize:30,fontWeight:"bold",lineHeight:30,valueAnimation:!1}},e}(bg);var vk=["itemStyle","opacity"],mk=function(t){function e(e,n){var i=t.call(this)||this,r=i,o=new Zu,a=new Xs;return r.setTextContent(a),i.setTextGuideLine(o),i.updateData(e,n,!0),i}return n(e,t),e.prototype.updateData=function(t,e,n){var i=this,r=t.hostModel,o=t.getItemModel(e),a=t.getItemLayout(e),s=o.getModel("emphasis"),l=o.get(vk);l=null==l?1:l,n||Sh(i),i.useStyle(t.getItemVisual(e,"style")),i.style.lineJoin="round",n?(i.setShape({points:a.points}),i.style.opacity=0,mh(i,{style:{opacity:l}},r,e)):vh(i,{style:{opacity:l},shape:{points:a.points}},r,e),$l(i,o),this._updateLabel(t,e),Zl(this,s.get("focus"),s.get("blurScope"),s.get("disabled"))},e.prototype._updateLabel=function(t,e){var n=this,i=this.getTextGuideLine(),r=n.getTextContent(),o=t.hostModel,a=t.getItemModel(e),s=t.getItemLayout(e).label,l=t.getItemVisual(e,"style"),u=l.fill;ic(r,rc(a),{labelFetcher:t.hostModel,labelDataIndex:e,defaultOpacity:l.opacity,defaultText:t.getName(e)},{normal:{align:s.textAlign,verticalAlign:s.verticalAlign}}),n.setTextConfig({local:!0,inside:!!s.inside,insideStroke:u,outsideFill:u});var h=s.linePoints;i.setShape({points:h}),n.textGuideLineConfig={anchor:h?new De(h[0][0],h[0][1]):null},vh(r,{style:{x:s.x,y:s.y}},o,e),r.attr({rotation:s.rotation,originX:s.x,originY:s.y,z2:10}),kb(n,Lb(a),{stroke:u})},e}(Xu),xk=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.ignoreLabelLineUpdate=!0,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this._data,o=this.group;i.diff(r).add((function(t){var e=new mk(i,t);i.setItemGraphicEl(t,e),o.add(e)})).update((function(t,e){var n=r.getItemGraphicEl(e);n.updateData(i,t),o.add(n),i.setItemGraphicEl(t,n)})).remove((function(e){wh(r.getItemGraphicEl(e),t,e)})).execute(),this._data=i},e.prototype.remove=function(){this.group.removeAll(),this._data=null},e.prototype.dispose=function(){},e.type="funnel",e}(Og),_k=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new NM(W(this.getData,this),W(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.getInitialData=function(t,e){return RM(this,{coordDimensions:["value"],encodeDefaulter:H(ed,this)})},e.prototype._defaultLabelLine=function(t){Co(t,"labelLine",["show"]);var e=t.labelLine,n=t.emphasis.labelLine;e.show=e.show&&t.label.show,n.show=n.show&&t.emphasis.label.show},e.prototype.getDataParams=function(e){var n=this.getData(),i=t.prototype.getDataParams.call(this,e),r=n.mapDimension("value"),o=n.getSum(r);return i.percent=o?+(n.get(r,e)/o*100).toFixed(2):0,i.$vars.push("percent"),i},e.type="series.funnel",e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",left:80,top:60,right:80,bottom:60,minSize:"0%",maxSize:"100%",sort:"descending",orient:"vertical",gap:0,funnelAlign:"center",label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{show:!0}},select:{itemStyle:{borderColor:"#212121"}}},e}(bg);function bk(t,e){t.eachSeriesByType("funnel",(function(t){var n=t.getData(),i=n.mapDimension("value"),r=t.get("sort"),o=function(t,e){return kp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e),a=t.get("orient"),s=o.width,l=o.height,u=function(t,e){for(var n=t.mapDimension("value"),i=t.mapArray(n,(function(t){return t})),r=[],o="ascending"===e,a=0,s=t.count();a5)return;var i=this._model.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]);"none"!==i.behavior&&this._dispatchExpand({axisExpandWindow:i.axisExpandWindow})}this._mouseDownPoint=null},mousemove:function(t){if(!this._mouseDownPoint&&Rk(this,"mousemove")){var e=this._model,n=e.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]),i=n.behavior;"jump"===i&&this._throttledDispatchExpand.debounceNextCall(e.get("axisExpandDebounce")),this._throttledDispatchExpand("none"===i?null:{axisExpandWindow:n.axisExpandWindow,animation:"jump"===i?null:{duration:0}})}}};function Rk(t,e){var n=t._model;return n.get("axisExpandable")&&n.get("axisExpandTriggerOn")===e}var Nk=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(){t.prototype.init.apply(this,arguments),this.mergeOption({})},e.prototype.mergeOption=function(t){var e=this.option;t&&C(e,t,!0),this._initDimensions()},e.prototype.contains=function(t,e){var n=t.get("parallelIndex");return null!=n&&e.getComponent("parallel",n)===this},e.prototype.setAxisExpand=function(t){E(["axisExpandable","axisExpandCenter","axisExpandCount","axisExpandWidth","axisExpandWindow"],(function(e){t.hasOwnProperty(e)&&(this.option[e]=t[e])}),this)},e.prototype._initDimensions=function(){var t=this.dimensions=[],e=this.parallelAxisIndex=[];E(B(this.ecModel.queryComponents({mainType:"parallelAxis"}),(function(t){return(t.get("parallelIndex")||0)===this.componentIndex}),this),(function(n){t.push("dim"+n.get("dim")),e.push(n.componentIndex)}))},e.type="parallel",e.dependencies=["parallelAxis"],e.layoutMode="box",e.defaultOption={z:0,left:80,top:60,right:80,bottom:60,layout:"horizontal",axisExpandable:!1,axisExpandCenter:null,axisExpandCount:0,axisExpandWidth:50,axisExpandRate:17,axisExpandDebounce:50,axisExpandSlideTriggerArea:[-.15,.05,.4],axisExpandTriggerOn:"click",parallelAxisDefault:null},e}(zp),Ek=function(t){function e(e,n,i,r,o){var a=t.call(this,e,n,i)||this;return a.type=r||"value",a.axisIndex=o,a}return n(e,t),e.prototype.isHorizontal=function(){return"horizontal"!==this.coordinateSystem.getModel().get("layout")},e}(ab);function zk(t,e,n,i,r,o){t=t||0;var a=n[1]-n[0];if(null!=r&&(r=Bk(r,[0,a])),null!=o&&(o=Math.max(o,null!=r?r:0)),"all"===i){var s=Math.abs(e[1]-e[0]);s=Bk(s,[0,a]),r=o=Bk(s,[r,o]),i=0}e[0]=Bk(e[0],n),e[1]=Bk(e[1],n);var l=Vk(e,i);e[i]+=t;var u,h=r||0,c=n.slice();return l.sign<0?c[0]+=h:c[1]-=h,e[i]=Bk(e[i],c),u=Vk(e,i),null!=r&&(u.sign!==l.sign||u.spano&&(e[1-i]=e[i]+u.sign*o),e}function Vk(t,e){var n=t[e]-t[1-e];return{span:Math.abs(n),sign:n>0?-1:n<0?1:e?-1:1}}function Bk(t,e){return Math.min(null!=e[1]?e[1]:1/0,Math.max(null!=e[0]?e[0]:-1/0,t))}var Fk=E,Gk=Math.min,Wk=Math.max,Hk=Math.floor,Yk=Math.ceil,Xk=Jr,Uk=Math.PI,Zk=function(){function t(t,e,n){this.type="parallel",this._axesMap=yt(),this._axesLayout={},this.dimensions=t.dimensions,this._model=t,this._init(t,e,n)}return t.prototype._init=function(t,e,n){var i=t.dimensions,r=t.parallelAxisIndex;Fk(i,(function(t,n){var i=r[n],o=e.getComponent("parallelAxis",i),a=this._axesMap.set(t,new Ek(t,b_(o),[0,0],o.get("type"),i)),s="category"===a.type;a.onBand=s&&o.get("boundaryGap"),a.inverse=o.get("inverse"),o.axis=a,a.model=o,a.coordinateSystem=o.coordinateSystem=this}),this)},t.prototype.update=function(t,e){this._updateAxesFromSeries(this._model,t)},t.prototype.containPoint=function(t){var e=this._makeLayoutInfo(),n=e.axisBase,i=e.layoutBase,r=e.pixelDimIndex,o=t[1-r],a=t[r];return o>=n&&o<=n+e.axisLength&&a>=i&&a<=i+e.layoutLength},t.prototype.getModel=function(){return this._model},t.prototype._updateAxesFromSeries=function(t,e){e.eachSeries((function(n){if(t.contains(n,e)){var i=n.getData();Fk(this.dimensions,(function(t){var e=this._axesMap.get(t);e.scale.unionExtentFromData(i,i.mapDimension(t)),__(e.scale,e.model)}),this)}}),this)},t.prototype.resize=function(t,e){this._rect=kp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()}),this._layoutAxes()},t.prototype.getRect=function(){return this._rect},t.prototype._makeLayoutInfo=function(){var t,e=this._model,n=this._rect,i=["x","y"],r=["width","height"],o=e.get("layout"),a="horizontal"===o?0:1,s=n[r[a]],l=[0,s],u=this.dimensions.length,h=jk(e.get("axisExpandWidth"),l),c=jk(e.get("axisExpandCount")||0,[0,u]),p=e.get("axisExpandable")&&u>3&&u>c&&c>1&&h>0&&s>0,d=e.get("axisExpandWindow");d?(t=jk(d[1]-d[0],l),d[1]=d[0]+t):(t=jk(h*(c-1),l),(d=[h*(e.get("axisExpandCenter")||Hk(u/2))-t/2])[1]=d[0]+t);var f=(s-t)/(u-c);f<3&&(f=0);var g=[Hk(Xk(d[0]/h,1))+1,Yk(Xk(d[1]/h,1))-1],y=f/h*d[0];return{layout:o,pixelDimIndex:a,layoutBase:n[i[a]],layoutLength:s,axisBase:n[i[1-a]],axisLength:n[r[1-a]],axisExpandable:p,axisExpandWidth:h,axisCollapseWidth:f,axisExpandWindow:d,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:y}},t.prototype._layoutAxes=function(){var t=this._rect,e=this._axesMap,n=this.dimensions,i=this._makeLayoutInfo(),r=i.layout;e.each((function(t){var e=[0,i.axisLength],n=t.inverse?1:0;t.setExtent(e[n],e[1-n])})),Fk(n,(function(e,n){var o=(i.axisExpandable?Kk:qk)(n,i),a={horizontal:{x:o.position,y:i.axisLength},vertical:{x:0,y:o.position}},s={horizontal:Uk/2,vertical:0},l=[a[r].x+t.x,a[r].y+t.y],u=s[r],h=[1,0,0,1,0,0];Se(h,h,u),we(h,h,l),this._axesLayout[e]={position:l,rotation:u,transform:h,axisNameAvailableWidth:o.axisNameAvailableWidth,axisLabelShow:o.axisLabelShow,nameTruncateMaxWidth:o.nameTruncateMaxWidth,tickDirection:1,labelDirection:1}}),this)},t.prototype.getAxis=function(t){return this._axesMap.get(t)},t.prototype.dataToPoint=function(t,e){return this.axisCoordToPoint(this._axesMap.get(e).dataToCoord(t),e)},t.prototype.eachActiveState=function(t,e,n,i){null==n&&(n=0),null==i&&(i=t.count());var r=this._axesMap,o=this.dimensions,a=[],s=[];E(o,(function(e){a.push(t.mapDimension(e)),s.push(r.get(e).model)}));for(var l=this.hasAxisBrushed(),u=n;ur*(1-h[0])?(l="jump",a=s-r*(1-h[2])):(a=s-r*h[1])>=0&&(a=s-r*(1-h[1]))<=0&&(a=0),(a*=e.axisExpandWidth/u)?zk(a,i,o,"all"):l="none";else{var p=i[1]-i[0];(i=[Wk(0,o[1]*s/p-p/2)])[1]=Gk(o[1],i[0]+p),i[0]=i[1]-p}return{axisExpandWindow:i,behavior:l}},t}();function jk(t,e){return Gk(Wk(t,e[0]),e[1])}function qk(t,e){var n=e.layoutLength/(e.axisCount-1);return{position:n*t,axisNameAvailableWidth:n,axisLabelShow:!0}}function Kk(t,e){var n,i,r=e.layoutLength,o=e.axisExpandWidth,a=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,h=!1;return t=0;n--)Qr(e[n])},e.prototype.getActiveState=function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(+t))return"inactive";if(1===e.length){var n=e[0];if(n[0]<=t&&t<=n[1])return"active"}else for(var i=0,r=e.length;i6}(t)||o){if(a&&!o){"single"===s.brushMode&&vL(t);var l=T(s);l.brushType=RL(l.brushType,a),l.panelId=a===Qk?null:a.panelId,o=t._creatingCover=uL(t,l),t._covers.push(o)}if(o){var u=zL[RL(t._brushType,a)];o.__brushOption.range=u.getCreatingRange(kL(t,o,t._track)),i&&(hL(t,o),u.updateCommon(t,o)),cL(t,o),r={isEnd:i}}}else i&&"single"===s.brushMode&&s.removeOnClick&&gL(t,e,n)&&vL(t)&&(r={isEnd:i,removeOnClick:!0});return r}function RL(t,e){return"auto"===t?e.defaultBrushType:t}var NL={mousedown:function(t){if(this._dragging)EL(this,t);else if(!t.target||!t.target.draggable){LL(t);var e=this.group.transformCoordToLocal(t.offsetX,t.offsetY);this._creatingCover=null,(this._creatingPanel=gL(this,t,e))&&(this._dragging=!0,this._track=[e.slice()])}},mousemove:function(t){var e=t.offsetX,n=t.offsetY,i=this.group.transformCoordToLocal(e,n);if(function(t,e,n){if(t._brushType&&!function(t,e,n){var i=t._zr;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}(t,e.offsetX,e.offsetY)){var i=t._zr,r=t._covers,o=gL(t,e,n);if(!t._dragging)for(var a=0;a=0&&(o[r[a].depth]=new Cc(r[a],this,e));var s=uk(i,n,this,!0,(function(t,e){t.wrapMethod("getItemModel",(function(t,e){var n=t.parentModel,i=n.getData().getItemLayout(e);if(i){var r=i.depth,o=n.levelModels[r];o&&(t.parentModel=o)}return t})),e.wrapMethod("getItemModel",(function(t,e){var n=t.parentModel,i=n.getGraph().getEdgeByIndex(e).node1.getLayout();if(i){var r=i.depth,o=n.levelModels[r];o&&(t.parentModel=o)}return t}))}));return s.data},e.prototype.setNodePosition=function(t,e){var n=(this.option.data||this.option.nodes)[t];n.localX=e[0],n.localY=e[1]},e.prototype.getGraph=function(){return this.getData().graph},e.prototype.getEdgeData=function(){return this.getGraph().edgeData},e.prototype.formatTooltip=function(t,e,n){function i(t){return isNaN(t)||null==t}if("edge"===n){var r=this.getDataParams(t,n),o=r.data,a=r.value;return og("nameValue",{name:o.source+" -- "+o.target,value:a,noValue:i(a)})}var s=this.getGraph().getNodeByIndex(t).getLayout().value,l=this.getDataParams(t,n).data.name;return og("nameValue",{name:null!=l?l+"":null,value:s,noValue:i(s)})},e.prototype.optionUpdated=function(){},e.prototype.getDataParams=function(e,n){var i=t.prototype.getDataParams.call(this,e,n);if(null==i.value&&"node"===n){var r=this.getGraph().getNodeByIndex(e).getLayout().value;i.value=r}return i},e.type="series.sankey",e.defaultOption={z:2,coordinateSystem:"view",left:"5%",top:"5%",right:"20%",bottom:"5%",orient:"horizontal",nodeWidth:20,nodeGap:8,draggable:!0,layoutIterations:32,label:{show:!0,position:"right",fontSize:12},edgeLabel:{show:!1,fontSize:12},levels:[],nodeAlign:"justify",lineStyle:{color:"#314656",opacity:.2,curveness:.5},emphasis:{label:{show:!0},lineStyle:{opacity:.5}},select:{itemStyle:{borderColor:"#212121"}},animationEasing:"linear",animationDuration:1e3},e}(bg);function QL(t,e){t.eachSeriesByType("sankey",(function(t){var n=t.get("nodeWidth"),i=t.get("nodeGap"),r=function(t,e){return kp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e);t.layoutInfo=r;var o=r.width,a=r.height,s=t.getGraph(),l=s.nodes,u=s.edges;!function(t){E(t,(function(t){var e=uP(t.outEdges,lP),n=uP(t.inEdges,lP),i=t.getValue()||0,r=Math.max(e,n,i);t.setLayout({value:r},!0)}))}(l),function(t,e,n,i,r,o,a,s,l){(function(t,e,n,i,r,o,a){for(var s=[],l=[],u=[],h=[],c=0,p=0;p=0;v&&y.depth>d&&(d=y.depth),g.setLayout({depth:v?y.depth:c},!0),"vertical"===o?g.setLayout({dy:n},!0):g.setLayout({dx:n},!0);for(var m=0;mc-1?d:c-1;a&&"left"!==a&&function(t,e,n,i){if("right"===e){for(var r=[],o=t,a=0;o.length;){for(var s=0;s0;o--)nP(s,l*=.99,a),eP(s,r,n,i,a),hP(s,l,a),eP(s,r,n,i,a)}(t,e,o,r,i,a,s),function(t,e){var n="vertical"===e?"x":"y";E(t,(function(t){t.outEdges.sort((function(t,e){return t.node2.getLayout()[n]-e.node2.getLayout()[n]})),t.inEdges.sort((function(t,e){return t.node1.getLayout()[n]-e.node1.getLayout()[n]}))})),E(t,(function(t){var e=0,n=0;E(t.outEdges,(function(t){t.setLayout({sy:e},!0),e+=t.getLayout().dy})),E(t.inEdges,(function(t){t.setLayout({ty:n},!0),n+=t.getLayout().dy}))}))}(t,s)}(l,u,n,i,o,a,0!==B(l,(function(t){return 0===t.getLayout().value})).length?0:t.get("layoutIterations"),t.get("orient"),t.get("nodeAlign"))}))}function tP(t){var e=t.hostGraph.data.getRawDataItem(t.dataIndex);return null!=e.depth&&e.depth>=0}function eP(t,e,n,i,r){var o="vertical"===r?"x":"y";E(t,(function(t){var a,s,l;t.sort((function(t,e){return t.getLayout()[o]-e.getLayout()[o]}));for(var u=0,h=t.length,c="vertical"===r?"dx":"dy",p=0;p0&&(a=s.getLayout()[o]+l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]+s.getLayout()[c]+e;if((l=u-e-("vertical"===r?i:n))>0){a=s.getLayout()[o]-l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0),u=a;for(p=h-2;p>=0;--p)(l=(s=t[p]).getLayout()[o]+s.getLayout()[c]+e-u)>0&&(a=s.getLayout()[o]-l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]}}))}function nP(t,e,n){E(t.slice().reverse(),(function(t){E(t,(function(t){if(t.outEdges.length){var i=uP(t.outEdges,iP,n)/uP(t.outEdges,lP);if(isNaN(i)){var r=t.outEdges.length;i=r?uP(t.outEdges,rP,n)/r:0}if("vertical"===n){var o=t.getLayout().x+(i-sP(t,n))*e;t.setLayout({x:o},!0)}else{var a=t.getLayout().y+(i-sP(t,n))*e;t.setLayout({y:a},!0)}}}))}))}function iP(t,e){return sP(t.node2,e)*t.getValue()}function rP(t,e){return sP(t.node2,e)}function oP(t,e){return sP(t.node1,e)*t.getValue()}function aP(t,e){return sP(t.node1,e)}function sP(t,e){return"vertical"===e?t.getLayout().x+t.getLayout().dx/2:t.getLayout().y+t.getLayout().dy/2}function lP(t){return t.getValue()}function uP(t,e,n){for(var i=0,r=t.length,o=-1;++oo&&(o=e)})),E(n,(function(e){var n=new kD({type:"color",mappingMethod:"linear",dataExtent:[r,o],visual:t.get("color")}).mapValueToVisual(e.getLayout().value),i=e.getModel().get(["itemStyle","color"]);null!=i?(e.setVisual("color",i),e.setVisual("style",{fill:i})):(e.setVisual("color",n),e.setVisual("style",{fill:n}))}))}i.length&&E(i,(function(t){var e=t.getModel().get("lineStyle");t.setVisual("style",e)}))}))}var pP=function(){function t(){}return t.prototype._hasEncodeRule=function(t){var e=this.getEncode();return e&&null!=e.get(t)},t.prototype.getInitialData=function(t,e){var n,i,r=e.getComponent("xAxis",this.get("xAxisIndex")),o=e.getComponent("yAxis",this.get("yAxisIndex")),a=r.get("type"),s=o.get("type");"category"===a?(t.layout="horizontal",n=r.getOrdinalMeta(),i=!this._hasEncodeRule("x")):"category"===s?(t.layout="vertical",n=o.getOrdinalMeta(),i=!this._hasEncodeRule("y")):t.layout=t.layout||"horizontal";var l=["x","y"],u="horizontal"===t.layout?0:1,h=this._baseAxisDim=l[u],c=l[1-u],p=[r,o],d=p[u].get("type"),f=p[1-u].get("type"),g=t.data;if(g&&i){var y=[];E(g,(function(t,e){var n;Y(t)?(n=t.slice(),t.unshift(e)):Y(t.value)?((n=A({},t)).value=n.value.slice(),t.value.unshift(e)):n=t,y.push(n)})),t.data=y}var v=this.defaultValueDimensions,m=[{name:h,type:Ym(d),ordinalMeta:n,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:c,type:Ym(f),dimsDef:v.slice()}];return RM(this,{coordDimensions:m,dimensionsCount:v.length+1,encodeDefaulter:H(td,m,this)})},t.prototype.getBaseAxis=function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis},t}(),dP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.defaultValueDimensions=[{name:"min",defaultTooltip:!0},{name:"Q1",defaultTooltip:!0},{name:"median",defaultTooltip:!0},{name:"Q3",defaultTooltip:!0},{name:"max",defaultTooltip:!0}],n.visualDrawType="stroke",n}return n(e,t),e.type="series.boxplot",e.dependencies=["xAxis","yAxis","grid"],e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,layout:null,boxWidth:[7,50],itemStyle:{color:"#fff",borderWidth:1},emphasis:{scale:!0,itemStyle:{borderWidth:2,shadowBlur:5,shadowOffsetX:1,shadowOffsetY:1,shadowColor:"rgba(0,0,0,0.2)"}},animationDuration:800},e}(bg);R(dP,pP,!0);var fP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this.group,o=this._data;this._data||r.removeAll();var a="horizontal"===t.get("layout")?1:0;i.diff(o).add((function(t){if(i.hasValue(t)){var e=vP(i.getItemLayout(t),i,t,a,!0);i.setItemGraphicEl(t,e),r.add(e)}})).update((function(t,e){var n=o.getItemGraphicEl(e);if(i.hasValue(t)){var s=i.getItemLayout(t);n?(Sh(n),mP(s,n,i,t)):n=vP(s,i,t,a),r.add(n),i.setItemGraphicEl(t,n)}else r.remove(n)})).remove((function(t){var e=o.getItemGraphicEl(t);e&&r.remove(e)})).execute(),this._data=i},e.prototype.remove=function(t){var e=this.group,n=this._data;this._data=null,n&&n.eachItemGraphicEl((function(t){t&&e.remove(t)}))},e.type="boxplot",e}(Og),gP=function(){},yP=function(t){function e(e){var n=t.call(this,e)||this;return n.type="boxplotBoxPath",n}return n(e,t),e.prototype.getDefaultShape=function(){return new gP},e.prototype.buildPath=function(t,e){var n=e.points,i=0;for(t.moveTo(n[i][0],n[i][1]),i++;i<4;i++)t.lineTo(n[i][0],n[i][1]);for(t.closePath();ig){var _=[v,x];i.push(_)}}}return{boxData:n,outliers:i}}(e.getRawData(),t.config);return[{dimensions:["ItemName","Low","Q1","Q2","Q3","High"],data:i.boxData},{data:i.outliers}]}};var SP=["itemStyle","borderColor"],MP=["itemStyle","borderColor0"],IP=["itemStyle","borderColorDoji"],TP=["itemStyle","color"],CP=["itemStyle","color0"];function DP(t,e){return e.get(t>0?TP:CP)}function AP(t,e){return e.get(0===t?IP:t>0?SP:MP)}var kP={seriesType:"candlestick",plan:kg(),performRawSeries:!0,reset:function(t,e){if(!e.isSeriesFiltered(t))return!t.pipelineContext.large&&{progress:function(t,e){for(var n;null!=(n=t.next());){var i=e.getItemModel(n),r=e.getItemLayout(n).sign,o=i.getItemStyle();o.fill=DP(r,i),o.stroke=AP(r,i)||o.fill,A(e.ensureUniqueItemVisual(n,"style"),o)}}}}},LP=["color","borderColor"],PP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeClipPath(),this._progressiveEls=null,this._updateDrawMode(t),this._isLargeDraw?this._renderLarge(t):this._renderNormal(t)},e.prototype.incrementalPrepareRender=function(t,e,n){this._clear(),this._updateDrawMode(t)},e.prototype.incrementalRender=function(t,e,n,i){this._progressiveEls=[],this._isLargeDraw?this._incrementalRenderLarge(t,e):this._incrementalRenderNormal(t,e)},e.prototype.eachRendered=function(t){Jh(this._progressiveEls||this.group,t)},e.prototype._updateDrawMode=function(t){var e=t.pipelineContext.large;null!=this._isLargeDraw&&e===this._isLargeDraw||(this._isLargeDraw=e,this._clear())},e.prototype._renderNormal=function(t){var e=t.getData(),n=this._data,i=this.group,r=e.getLayout("isSimpleBox"),o=t.get("clip",!0),a=t.coordinateSystem,s=a.getArea&&a.getArea();this._data||i.removeAll(),e.diff(n).add((function(n){if(e.hasValue(n)){var a=e.getItemLayout(n);if(o&&EP(s,a))return;var l=NP(a,n,!0);mh(l,{shape:{points:a.ends}},t,n),zP(l,e,n,r),i.add(l),e.setItemGraphicEl(n,l)}})).update((function(a,l){var u=n.getItemGraphicEl(l);if(e.hasValue(a)){var h=e.getItemLayout(a);o&&EP(s,h)?i.remove(u):(u?(vh(u,{shape:{points:h.ends}},t,a),Sh(u)):u=NP(h),zP(u,e,a,r),i.add(u),e.setItemGraphicEl(a,u))}else i.remove(u)})).remove((function(t){var e=n.getItemGraphicEl(t);e&&i.remove(e)})).execute(),this._data=e},e.prototype._renderLarge=function(t){this._clear(),GP(t,this.group);var e=t.get("clip",!0)?PS(t.coordinateSystem,!1,t):null;e?this.group.setClipPath(e):this.group.removeClipPath()},e.prototype._incrementalRenderNormal=function(t,e){for(var n,i=e.getData(),r=i.getLayout("isSimpleBox");null!=(n=t.next());){var o=NP(i.getItemLayout(n));zP(o,i,n,r),o.incremental=!0,this.group.add(o),this._progressiveEls.push(o)}},e.prototype._incrementalRenderLarge=function(t,e){GP(e,this.group,this._progressiveEls,!0)},e.prototype.remove=function(t){this._clear()},e.prototype._clear=function(){this.group.removeAll(),this._data=null},e.type="candlestick",e}(Og),OP=function(){},RP=function(t){function e(e){var n=t.call(this,e)||this;return n.type="normalCandlestickBox",n}return n(e,t),e.prototype.getDefaultShape=function(){return new OP},e.prototype.buildPath=function(t,e){var n=e.points;this.__simpleBox?(t.moveTo(n[4][0],n[4][1]),t.lineTo(n[6][0],n[6][1])):(t.moveTo(n[0][0],n[0][1]),t.lineTo(n[1][0],n[1][1]),t.lineTo(n[2][0],n[2][1]),t.lineTo(n[3][0],n[3][1]),t.closePath(),t.moveTo(n[4][0],n[4][1]),t.lineTo(n[5][0],n[5][1]),t.moveTo(n[6][0],n[6][1]),t.lineTo(n[7][0],n[7][1]))},e}(ks);function NP(t,e,n){var i=t.ends;return new RP({shape:{points:n?VP(i,t):i},z2:100})}function EP(t,e){for(var n=!0,i=0;id?x[1]:m[1],ends:w,brushRect:T(f,g,c)})}function M(t,n){var i=[];return i[0]=n,i[1]=t,isNaN(n)||isNaN(t)?[NaN,NaN]:e.dataToPoint(i)}function I(t,e,n){var r=e.slice(),o=e.slice();r[0]=Vh(r[0]+i/2,1,!1),o[0]=Vh(o[0]-i/2,1,!0),n?t.push(r,o):t.push(o,r)}function T(t,e,n){var r=M(t,n),o=M(e,n);return r[0]-=i/2,o[0]-=i/2,{x:r[0],y:r[1],width:i,height:o[1]-r[1]}}function C(t){return t[0]=Vh(t[0],1),t}}}}};function UP(t,e,n,i,r,o){return n>i?-1:n0?t.get(r,e-1)<=i?1:-1:1}function ZP(t,e){var n=e.rippleEffectColor||e.color;t.eachChild((function(t){t.attr({z:e.z,zlevel:e.zlevel,style:{stroke:"stroke"===e.brushType?n:null,fill:"fill"===e.brushType?n:null}})}))}var jP=function(t){function e(e,n){var i=t.call(this)||this,r=new fS(e,n),o=new Br;return i.add(r),i.add(o),i.updateData(e,n),i}return n(e,t),e.prototype.stopEffectAnimation=function(){this.childAt(1).removeAll()},e.prototype.startEffectAnimation=function(t){for(var e=t.symbolType,n=t.color,i=t.rippleNumber,r=this.childAt(1),o=0;o0&&(o=this._getLineLength(i)/l*1e3),o!==this._period||a!==this._loop||s!==this._roundTrip){i.stopAnimation();var h=void 0;h=X(u)?u(n):u,i.__t>0&&(h=-o*i.__t),this._animateSymbol(i,o,h,a,s)}this._period=o,this._loop=a,this._roundTrip=s}},e.prototype._animateSymbol=function(t,e,n,i,r){if(e>0){t.__t=0;var o=this,a=t.animate("",i).when(r?2*e:e,{__t:r?2:1}).delay(n).during((function(){o._updateSymbolPosition(t)}));i||a.done((function(){o.remove(t)})),a.start()}},e.prototype._getLineLength=function(t){return Vt(t.__p1,t.__cp1)+Vt(t.__cp1,t.__p2)},e.prototype._updateAnimationPoints=function(t,e){t.__p1=e[0],t.__p2=e[1],t.__cp1=e[2]||[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]},e.prototype.updateData=function(t,e,n){this.childAt(0).updateData(t,e,n),this._updateEffectSymbol(t,e)},e.prototype._updateSymbolPosition=function(t){var e=t.__p1,n=t.__p2,i=t.__cp1,r=t.__t<1?t.__t:2-t.__t,o=[t.x,t.y],a=o.slice(),s=In,l=Tn;o[0]=s(e[0],i[0],n[0],r),o[1]=s(e[1],i[1],n[1],r);var u=t.__t<1?l(e[0],i[0],n[0],r):l(n[0],i[0],e[0],1-r),h=t.__t<1?l(e[1],i[1],n[1],r):l(n[1],i[1],e[1],1-r);t.rotation=-Math.atan2(h,u)-Math.PI/2,"line"!==this._symbolType&&"rect"!==this._symbolType&&"roundRect"!==this._symbolType||(void 0!==t.__lastT&&t.__lastT=0&&!(i[o]<=e);o--);o=Math.min(o,r-2)}else{for(o=a;oe);o++);o=Math.min(o-1,r-2)}var s=(e-i[o])/(i[o+1]-i[o]),l=n[o],u=n[o+1];t.x=l[0]*(1-s)+s*u[0],t.y=l[1]*(1-s)+s*u[1];var h=t.__t<1?u[0]-l[0]:l[0]-u[0],c=t.__t<1?u[1]-l[1]:l[1]-u[1];t.rotation=-Math.atan2(c,h)-Math.PI/2,this._lastFrame=o,this._lastFramePercent=e,t.ignore=!1}},e}($P),tO=function(){this.polyline=!1,this.curveness=0,this.segs=[]},eO=function(t){function e(e){var n=t.call(this,e)||this;return n._off=0,n.hoverDataIdx=-1,n}return n(e,t),e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new tO},e.prototype.buildPath=function(t,e){var n,i=e.segs,r=e.curveness;if(e.polyline)for(n=this._off;n0){t.moveTo(i[n++],i[n++]);for(var a=1;a0){var c=(s+u)/2-(l-h)*r,p=(l+h)/2-(u-s)*r;t.quadraticCurveTo(c,p,u,h)}else t.lineTo(u,h)}this.incremental&&(this._off=n,this.notClear=!0)},e.prototype.findDataIndex=function(t,e){var n=this.shape,i=n.segs,r=n.curveness,o=this.style.lineWidth;if(n.polyline)for(var a=0,s=0;s0)for(var u=i[s++],h=i[s++],c=1;c0){if(ds(u,h,(u+p)/2-(h-d)*r,(h+d)/2-(p-u)*r,p,d,o,t,e))return a}else if(cs(u,h,p,d,o,t,e))return a;a++}return-1},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect();return t=n[0],e=n[1],i.contain(t,e)?(this.hoverDataIdx=this.findDataIndex(t,e))>=0:(this.hoverDataIdx=-1,!1)},e.prototype.getBoundingRect=function(){var t=this._rect;if(!t){for(var e=this.shape.segs,n=1/0,i=1/0,r=-1/0,o=-1/0,a=0;a0&&(o.dataIndex=n+t.__startIndex)}))},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),iO={seriesType:"lines",plan:kg(),reset:function(t){var e=t.coordinateSystem;if(e){var n=t.get("polyline"),i=t.pipelineContext.large;return{progress:function(r,o){var a=[];if(i){var s=void 0,l=r.end-r.start;if(n){for(var u=0,h=r.start;h0&&(l||s.configLayer(o,{motionBlur:!0,lastFrameAlpha:Math.max(Math.min(a/10+.9,1),0)})),r.updateData(i);var u=t.get("clip",!0)&&PS(t.coordinateSystem,!1,t);u?this.group.setClipPath(u):this.group.removeClipPath(),this._lastZlevel=o,this._finished=!0},e.prototype.incrementalPrepareRender=function(t,e,n){var i=t.getData();this._updateLineDraw(i,t).incrementalPrepareUpdate(i),this._clearLayer(n),this._finished=!1},e.prototype.incrementalRender=function(t,e,n){this._lineDraw.incrementalUpdate(t,e.getData()),this._finished=t.end===e.getData().count()},e.prototype.eachRendered=function(t){this._lineDraw&&this._lineDraw.eachRendered(t)},e.prototype.updateTransform=function(t,e,n){var i=t.getData(),r=t.pipelineContext;if(!this._finished||r.large||r.progressiveRender)return{update:!0};var o=iO.reset(t,e,n);o.progress&&o.progress({start:0,end:i.count(),count:i.count()},i),this._lineDraw.updateLayout(),this._clearLayer(n)},e.prototype._updateLineDraw=function(t,e){var n=this._lineDraw,i=this._showEffect(e),r=!!e.get("polyline"),o=e.pipelineContext.large;return n&&i===this._hasEffet&&r===this._isPolyline&&o===this._isLargeDraw||(n&&n.remove(),n=this._lineDraw=o?new nO:new YA(r?i?QP:JP:i?$P:HA),this._hasEffet=i,this._isPolyline=r,this._isLargeDraw=o),this.group.add(n.group),n},e.prototype._showEffect=function(t){return!!t.get(["effect","show"])},e.prototype._clearLayer=function(t){var e=t.getZr();"svg"===e.painter.getType()||null==this._lastZlevel||e.painter.getLayer(this._lastZlevel).clear(!0)},e.prototype.remove=function(t,e){this._lineDraw&&this._lineDraw.remove(),this._lineDraw=null,this._clearLayer(e)},e.prototype.dispose=function(t,e){this.remove(t,e)},e.type="lines",e}(Og),oO="undefined"==typeof Uint32Array?Array:Uint32Array,aO="undefined"==typeof Float64Array?Array:Float64Array;function sO(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=z(e,(function(t){var e={coords:[t[0].coord,t[1].coord]};return t[0].name&&(e.fromName=t[0].name),t[1].name&&(e.toName=t[1].name),D([e,t[0],t[1]])})))}var lO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.visualStyleAccessPath="lineStyle",n.visualDrawType="stroke",n}return n(e,t),e.prototype.init=function(e){e.data=e.data||[],sO(e);var n=this._processFlatCoordsArray(e.data);this._flatCoords=n.flatCoords,this._flatCoordsOffset=n.flatCoordsOffset,n.flatCoords&&(e.data=new Float32Array(n.count)),t.prototype.init.apply(this,arguments)},e.prototype.mergeOption=function(e){if(sO(e),e.data){var n=this._processFlatCoordsArray(e.data);this._flatCoords=n.flatCoords,this._flatCoordsOffset=n.flatCoordsOffset,n.flatCoords&&(e.data=new Float32Array(n.count))}t.prototype.mergeOption.apply(this,arguments)},e.prototype.appendData=function(t){var e=this._processFlatCoordsArray(t.data);e.flatCoords&&(this._flatCoords?(this._flatCoords=vt(this._flatCoords,e.flatCoords),this._flatCoordsOffset=vt(this._flatCoordsOffset,e.flatCoordsOffset)):(this._flatCoords=e.flatCoords,this._flatCoordsOffset=e.flatCoordsOffset),t.data=new Float32Array(e.count)),this.getRawData().appendData(t.data)},e.prototype._getCoordsFromItemModel=function(t){var e=this.getData().getItemModel(t),n=e.option instanceof Array?e.option:e.getShallow("coords");return n},e.prototype.getLineCoordsCount=function(t){return this._flatCoordsOffset?this._flatCoordsOffset[2*t+1]:this._getCoordsFromItemModel(t).length},e.prototype.getLineCoords=function(t,e){if(this._flatCoordsOffset){for(var n=this._flatCoordsOffset[2*t],i=this._flatCoordsOffset[2*t+1],r=0;r ")})},e.prototype.preventIncremental=function(){return!!this.get(["effect","show"])},e.prototype.getProgressive=function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},e.prototype.getProgressiveThreshold=function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},e.prototype.getZLevelKey=function(){var t=this.getModel("effect"),e=t.get("trailLength");return this.getData().count()>this.getProgressiveThreshold()?this.id:t.get("show")&&e>0?e+"":""},e.type="series.lines",e.dependencies=["grid","polar","geo","calendar"],e.defaultOption={coordinateSystem:"geo",z:2,legendHoverLink:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,clip:!0,label:{show:!1,position:"end"},lineStyle:{opacity:.5}},e}(bg);function uO(t){return t instanceof Array||(t=[t,t]),t}var hO={seriesType:"lines",reset:function(t){var e=uO(t.get("symbol")),n=uO(t.get("symbolSize")),i=t.getData();return i.setVisual("fromSymbol",e&&e[0]),i.setVisual("toSymbol",e&&e[1]),i.setVisual("fromSymbolSize",n&&n[0]),i.setVisual("toSymbolSize",n&&n[1]),{dataEach:i.hasItemOption?function(t,e){var n=t.getItemModel(e),i=uO(n.getShallow("symbol",!0)),r=uO(n.getShallow("symbolSize",!0));i[0]&&t.setItemVisual(e,"fromSymbol",i[0]),i[1]&&t.setItemVisual(e,"toSymbol",i[1]),r[0]&&t.setItemVisual(e,"fromSymbolSize",r[0]),r[1]&&t.setItemVisual(e,"toSymbolSize",r[1])}:null}}};var cO=function(){function t(){this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={inRange:null,outOfRange:null};var t=h.createCanvas();this.canvas=t}return t.prototype.update=function(t,e,n,i,r,o){var a=this._getBrush(),s=this._getGradient(r,"inRange"),l=this._getGradient(r,"outOfRange"),u=this.pointSize+this.blurSize,h=this.canvas,c=h.getContext("2d"),p=t.length;h.width=e,h.height=n;for(var d=0;d0){var I=o(v)?s:l;v>0&&(v=v*S+w),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*v*256}else _+=4}return c.putImageData(m,0,0),h},t.prototype._getBrush=function(){var t=this._brushCanvas||(this._brushCanvas=h.createCanvas()),e=this.pointSize+this.blurSize,n=2*e;t.width=n,t.height=n;var i=t.getContext("2d");return i.clearRect(0,0,n,n),i.shadowOffsetX=n,i.shadowBlur=this.blurSize,i.shadowColor="#000",i.beginPath(),i.arc(-e,e,this.pointSize,0,2*Math.PI,!0),i.closePath(),i.fill(),t},t.prototype._getGradient=function(t,e){for(var n=this._gradientPixels,i=n[e]||(n[e]=new Uint8ClampedArray(1024)),r=[0,0,0,0],o=0,a=0;a<256;a++)t[e](a/255,!0,r),i[o++]=r[0],i[o++]=r[1],i[o++]=r[2],i[o++]=r[3];return i},t}();function pO(t){var e=t.dimensions;return"lng"===e[0]&&"lat"===e[1]}var dO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i;e.eachComponent("visualMap",(function(e){e.eachTargetSeries((function(n){n===t&&(i=e)}))})),this._progressiveEls=null,this.group.removeAll();var r=t.coordinateSystem;"cartesian2d"===r.type||"calendar"===r.type?this._renderOnCartesianAndCalendar(t,n,0,t.getData().count()):pO(r)&&this._renderOnGeo(r,t,i,n)},e.prototype.incrementalPrepareRender=function(t,e,n){this.group.removeAll()},e.prototype.incrementalRender=function(t,e,n,i){var r=e.coordinateSystem;r&&(pO(r)?this.render(e,n,i):(this._progressiveEls=[],this._renderOnCartesianAndCalendar(e,i,t.start,t.end,!0)))},e.prototype.eachRendered=function(t){Jh(this._progressiveEls||this.group,t)},e.prototype._renderOnCartesianAndCalendar=function(t,e,n,i,r){var o,a,s,l,u=t.coordinateSystem,h=OS(u,"cartesian2d");if(h){var c=u.getAxis("x"),p=u.getAxis("y");0,o=c.getBandWidth()+.5,a=p.getBandWidth()+.5,s=c.scale.getExtent(),l=p.scale.getExtent()}for(var d=this.group,f=t.getData(),g=t.getModel(["emphasis","itemStyle"]).getItemStyle(),y=t.getModel(["blur","itemStyle"]).getItemStyle(),v=t.getModel(["select","itemStyle"]).getItemStyle(),m=t.get(["itemStyle","borderRadius"]),x=rc(t),_=t.getModel("emphasis"),b=_.get("focus"),w=_.get("blurScope"),S=_.get("disabled"),M=h?[f.mapDimension("x"),f.mapDimension("y"),f.mapDimension("value")]:[f.mapDimension("time"),f.mapDimension("value")],I=n;Is[1]||Al[1])continue;var k=u.dataToPoint([D,A]);T=new Ws({shape:{x:k[0]-o/2,y:k[1]-a/2,width:o,height:a},style:C})}else{if(isNaN(f.get(M[1],I)))continue;T=new Ws({z2:1,shape:u.dataToRect([f.get(M[0],I)]).contentShape,style:C})}if(f.hasItemOption){var L=f.getItemModel(I),P=L.getModel("emphasis");g=P.getModel("itemStyle").getItemStyle(),y=L.getModel(["blur","itemStyle"]).getItemStyle(),v=L.getModel(["select","itemStyle"]).getItemStyle(),m=L.get(["itemStyle","borderRadius"]),b=P.get("focus"),w=P.get("blurScope"),S=P.get("disabled"),x=rc(L)}T.shape.r=m;var O=t.getRawValue(I),R="-";O&&null!=O[2]&&(R=O[2]+""),ic(T,x,{labelFetcher:t,labelDataIndex:I,defaultOpacity:C.opacity,defaultText:R}),T.ensureState("emphasis").style=g,T.ensureState("blur").style=y,T.ensureState("select").style=v,Zl(T,b,w,S),T.incremental=r,r&&(T.states.emphasis.hoverLayer=!0),d.add(T),f.setItemGraphicEl(I,T),this._progressiveEls&&this._progressiveEls.push(T)}},e.prototype._renderOnGeo=function(t,e,n,i){var r=n.targetVisuals.inRange,o=n.targetVisuals.outOfRange,a=e.getData(),s=this._hmLayer||this._hmLayer||new cO;s.blurSize=e.get("blurSize"),s.pointSize=e.get("pointSize"),s.minOpacity=e.get("minOpacity"),s.maxOpacity=e.get("maxOpacity");var l=t.getViewRect().clone(),u=t.getRoamTransform();l.applyTransform(u);var h=Math.max(l.x,0),c=Math.max(l.y,0),p=Math.min(l.width+l.x,i.getWidth()),d=Math.min(l.height+l.y,i.getHeight()),f=p-h,g=d-c,y=[a.mapDimension("lng"),a.mapDimension("lat"),a.mapDimension("value")],v=a.mapArray(y,(function(e,n,i){var r=t.dataToPoint([e,n]);return r[0]-=h,r[1]-=c,r.push(i),r})),m=n.getExtent(),x="visualMap.continuous"===n.type?function(t,e){var n=t[1]-t[0];return e=[(e[0]-t[0])/n,(e[1]-t[0])/n],function(t){return t>=e[0]&&t<=e[1]}}(m,n.option.range):function(t,e,n){var i=t[1]-t[0],r=(e=z(e,(function(e){return{interval:[(e.interval[0]-t[0])/i,(e.interval[1]-t[0])/i]}}))).length,o=0;return function(t){var i;for(i=o;i=0;i--){var a;if((a=e[i].interval)[0]<=t&&t<=a[1]){o=i;break}}return i>=0&&i=0?1:-1:o>0?1:-1}(n,o,r,i,c),function(t,e,n,i,r,o,a,s,l,u){var h,c=l.valueDim,p=l.categoryDim,d=Math.abs(n[p.wh]),f=t.getItemVisual(e,"symbolSize");h=Y(f)?f.slice():null==f?["100%","100%"]:[f,f];h[p.index]=$r(h[p.index],d),h[c.index]=$r(h[c.index],i?d:Math.abs(o)),u.symbolSize=h;var g=u.symbolScale=[h[0]/s,h[1]/s];g[c.index]*=(l.isHorizontal?-1:1)*a}(t,e,r,o,0,c.boundingLength,c.pxSign,u,i,c),function(t,e,n,i,r){var o=t.get(gO)||0;o&&(vO.attr({scaleX:e[0],scaleY:e[1],rotation:n}),vO.updateTransform(),o/=vO.getLineScale(),o*=e[i.valueDim.index]);r.valueLineWidth=o||0}(n,c.symbolScale,l,i,c);var p=c.symbolSize,d=Zy(n.get("symbolOffset"),p);return function(t,e,n,i,r,o,a,s,l,u,h,c){var p=h.categoryDim,d=h.valueDim,f=c.pxSign,g=Math.max(e[d.index]+s,0),y=g;if(i){var v=Math.abs(l),m=it(t.get("symbolMargin"),"15%")+"",x=!1;m.lastIndexOf("!")===m.length-1&&(x=!0,m=m.slice(0,m.length-1));var _=$r(m,e[d.index]),b=Math.max(g+2*_,0),w=x?0:2*_,S=vo(i),M=S?i:NO((v+w)/b);b=g+2*(_=(v-M*g)/2/(x?M:Math.max(M-1,1))),w=x?0:2*_,S||"fixed"===i||(M=u?NO((Math.abs(u)+w)/b):0),y=M*b-w,c.repeatTimes=M,c.symbolMargin=_}var I=f*(y/2),T=c.pathPosition=[];T[p.index]=n[p.wh]/2,T[d.index]="start"===a?I:"end"===a?l-I:l/2,o&&(T[0]+=o[0],T[1]+=o[1]);var C=c.bundlePosition=[];C[p.index]=n[p.xy],C[d.index]=n[d.xy];var D=c.barRectShape=A({},n);D[d.wh]=f*Math.max(Math.abs(n[d.wh]),Math.abs(T[d.index]+I)),D[p.wh]=n[p.wh];var k=c.clipShape={};k[p.xy]=-n[p.xy],k[p.wh]=h.ecSize[p.wh],k[d.xy]=0,k[d.wh]=n[d.wh]}(n,p,r,o,0,d,s,c.valueLineWidth,c.boundingLength,c.repeatCutLength,i,c),c}function _O(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function bO(t){var e=t.symbolPatternSize,n=Xy(t.symbolType,-e/2,-e/2,e,e);return n.attr({culling:!0}),"image"!==n.type&&n.setStyle({strokeNoScale:!0}),n}function wO(t,e,n,i){var r=t.__pictorialBundle,o=n.symbolSize,a=n.valueLineWidth,s=n.pathPosition,l=e.valueDim,u=n.repeatTimes||0,h=0,c=o[e.valueDim.index]+a+2*n.symbolMargin;for(PO(t,(function(t){t.__pictorialAnimationIndex=h,t.__pictorialRepeatTimes=u,h0:i<0)&&(r=u-1-t),e[l.index]=c*(r-u/2+.5)+s[l.index],{x:e[0],y:e[1],scaleX:n.symbolScale[0],scaleY:n.symbolScale[1],rotation:n.rotation}}}function SO(t,e,n,i){var r=t.__pictorialBundle,o=t.__pictorialMainPath;o?OO(o,null,{x:n.pathPosition[0],y:n.pathPosition[1],scaleX:n.symbolScale[0],scaleY:n.symbolScale[1],rotation:n.rotation},n,i):(o=t.__pictorialMainPath=bO(n),r.add(o),OO(o,{x:n.pathPosition[0],y:n.pathPosition[1],scaleX:0,scaleY:0,rotation:n.rotation},{scaleX:n.symbolScale[0],scaleY:n.symbolScale[1]},n,i))}function MO(t,e,n){var i=A({},e.barRectShape),r=t.__pictorialBarRect;r?OO(r,null,{shape:i},e,n):((r=t.__pictorialBarRect=new Ws({z2:2,shape:i,silent:!0,style:{stroke:"transparent",fill:"transparent",lineWidth:0}})).disableMorphing=!0,t.add(r))}function IO(t,e,n,i){if(n.symbolClip){var r=t.__pictorialClipPath,o=A({},n.clipShape),a=e.valueDim,s=n.animationModel,l=n.dataIndex;if(r)vh(r,{shape:o},s,l);else{o[a.wh]=0,r=new Ws({shape:o}),t.__pictorialBundle.setClipPath(r),t.__pictorialClipPath=r;var u={};u[a.wh]=n.clipShape[a.wh],Qh[i?"updateProps":"initProps"](r,{shape:u},s,l)}}}function TO(t,e){var n=t.getItemModel(e);return n.getAnimationDelayParams=CO,n.isAnimationEnabled=DO,n}function CO(t){return{index:t.__pictorialAnimationIndex,count:t.__pictorialRepeatTimes}}function DO(){return this.parentModel.isAnimationEnabled()&&!!this.getShallow("animation")}function AO(t,e,n,i){var r=new Br,o=new Br;return r.add(o),r.__pictorialBundle=o,o.x=n.bundlePosition[0],o.y=n.bundlePosition[1],n.symbolRepeat?wO(r,e,n):SO(r,0,n),MO(r,n,i),IO(r,e,n,i),r.__pictorialShapeStr=LO(t,n),r.__pictorialSymbolMeta=n,r}function kO(t,e,n,i){var r=i.__pictorialBarRect;r&&r.removeTextContent();var o=[];PO(i,(function(t){o.push(t)})),i.__pictorialMainPath&&o.push(i.__pictorialMainPath),i.__pictorialClipPath&&(n=null),E(o,(function(t){_h(t,{scaleX:0,scaleY:0},n,e,(function(){i.parent&&i.parent.remove(i)}))})),t.setItemGraphicEl(e,null)}function LO(t,e){return[t.getItemVisual(e.dataIndex,"symbol")||"none",!!e.symbolRepeat,!!e.symbolClip].join(":")}function PO(t,e,n){E(t.__pictorialBundle.children(),(function(i){i!==t.__pictorialBarRect&&e.call(n,i)}))}function OO(t,e,n,i,r,o){e&&t.attr(e),i.symbolClip&&!r?n&&t.attr(n):n&&Qh[r?"updateProps":"initProps"](t,n,i.animationModel,i.dataIndex,o)}function RO(t,e,n){var i=n.dataIndex,r=n.itemModel,o=r.getModel("emphasis"),a=o.getModel("itemStyle").getItemStyle(),s=r.getModel(["blur","itemStyle"]).getItemStyle(),l=r.getModel(["select","itemStyle"]).getItemStyle(),u=r.getShallow("cursor"),h=o.get("focus"),c=o.get("blurScope"),p=o.get("scale");PO(t,(function(t){if(t instanceof Ns){var e=t.style;t.useStyle(A({image:e.image,x:e.x,y:e.y,width:e.width,height:e.height},n.style))}else t.useStyle(n.style);var i=t.ensureState("emphasis");i.style=a,p&&(i.scaleX=1.1*t.scaleX,i.scaleY=1.1*t.scaleY),t.ensureState("blur").style=s,t.ensureState("select").style=l,u&&(t.cursor=u),t.z2=n.z2}));var d=e.valueDim.posDesc[+(n.boundingLength>0)],f=t.__pictorialBarRect;f.ignoreClip=!0,ic(f,rc(r),{labelFetcher:e.seriesModel,labelDataIndex:i,defaultText:pS(e.seriesModel.getData(),i),inheritColor:n.style.fill,defaultOpacity:n.style.opacity,defaultOutsidePosition:d}),Zl(t,h,c,o.get("disabled"))}function NO(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}var EO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n.defaultSymbol="roundRect",n}return n(e,t),e.prototype.getInitialData=function(e){return e.stack=null,t.prototype.getInitialData.apply(this,arguments)},e.type="series.pictorialBar",e.dependencies=["grid"],e.defaultOption=kc(qS.defaultOption,{symbol:"circle",symbolSize:null,symbolRotate:null,symbolPosition:null,symbolOffset:null,symbolMargin:null,symbolRepeat:!1,symbolRepeatDirection:"end",symbolClip:!1,symbolBoundingData:null,symbolPatternSize:400,barGap:"-100%",clip:!1,progressive:0,emphasis:{scale:!1},select:{itemStyle:{borderColor:"#212121"}}}),e}(qS);var zO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._layers=[],n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this,o=this.group,a=t.getLayerSeries(),s=i.getLayout("layoutInfo"),l=s.rect,u=s.boundaryGap;function h(t){return t.name}o.x=0,o.y=l.y+u[0];var c=new Gm(this._layersSeries||[],a,h,h),p=[];function d(e,n,s){var l=r._layers;if("remove"!==e){for(var u,h,c=[],d=[],f=a[n].indices,g=0;go&&(o=s),i.push(s)}for(var u=0;uo&&(o=c)}return{y0:r,max:o}}(l),h=u.y0,c=n/u.max,p=o.length,d=o[0].indices.length,f=0;fI&&!so(C-I)&&C0?(r.virtualPiece?r.virtualPiece.updateData(!1,i,t,e,n):(r.virtualPiece=new GO(i,t,e,n),l.add(r.virtualPiece)),o.piece.off("click"),r.virtualPiece.on("click",(function(t){r._rootToNode(o.parentNode)}))):r.virtualPiece&&(l.remove(r.virtualPiece),r.virtualPiece=null)}(a,s),this._initEvents(),this._oldChildren=h},e.prototype._initEvents=function(){var t=this;this.group.off("click"),this.group.on("click",(function(e){var n=!1;t.seriesModel.getViewRoot().eachNode((function(i){if(!n&&i.piece&&i.piece===e.target){var r=i.getModel().get("nodeClick");if("rootToNode"===r)t._rootToNode(i);else if("link"===r){var o=i.getModel(),a=o.get("link");if(a)Mp(a,o.get("target",!0)||"_blank")}n=!0}}))}))},e.prototype._rootToNode=function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:WO,from:this.uid,seriesId:this.seriesModel.id,targetNode:t})},e.prototype.containPoint=function(t,e){var n=e.getData().getItemLayout(0);if(n){var i=t[0]-n.cx,r=t[1]-n.cy,o=Math.sqrt(i*i+r*r);return o<=n.r&&o>=n.r0}},e.type="sunburst",e}(Og),XO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.ignoreStyleOnData=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){var n={name:t.name,children:t.data};UO(n);var i=this._levelModels=z(t.levels||[],(function(t){return new Cc(t,this,e)}),this),r=nD.createTree(n,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=r.getNodeByDataIndex(e),o=i[n.depth];return o&&(t.parentModel=o),t}))}));return r.data},e.prototype.optionUpdated=function(){this.resetViewRoot()},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treePathInfo=aD(i,this),n},e.prototype.getLevelModel=function(t){return this._levelModels&&this._levelModels[t.depth]},e.prototype.getViewRoot=function(){return this._viewRoot},e.prototype.resetViewRoot=function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)},e.prototype.enableAriaDecal=function(){pD(this)},e.type="series.sunburst",e.defaultOption={z:2,center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,minAngle:0,stillShowZeroSum:!0,nodeClick:"rootToNode",renderLabelForZeroData:!1,label:{rotate:"radial",show:!0,opacity:1,align:"center",position:"inside",distance:5,silent:!0},itemStyle:{borderWidth:1,borderColor:"white",borderType:"solid",shadowBlur:0,shadowColor:"rgba(0, 0, 0, 0.2)",shadowOffsetX:0,shadowOffsetY:0,opacity:1},emphasis:{focus:"descendant"},blur:{itemStyle:{opacity:.2},label:{opacity:.1}},animationType:"expansion",animationDuration:1e3,animationDurationUpdate:500,data:[],sort:"desc"},e}(bg);function UO(t){var e=0;E(t.children,(function(t){UO(t);var n=t.value;Y(n)&&(n=n[0]),e+=n}));var n=t.value;Y(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),Y(t.value)?t.value[0]=n:t.value=n}var ZO=Math.PI/180;function jO(t,e,n){e.eachSeriesByType(t,(function(t){var e=t.get("center"),i=t.get("radius");Y(i)||(i=[0,i]),Y(e)||(e=[e,e]);var r=n.getWidth(),o=n.getHeight(),a=Math.min(r,o),s=$r(e[0],r),l=$r(e[1],o),u=$r(i[0],a/2),h=$r(i[1],a/2),c=-t.get("startAngle")*ZO,p=t.get("minAngle")*ZO,d=t.getData().tree.root,f=t.getViewRoot(),g=f.depth,y=t.get("sort");null!=y&&qO(f,y);var v=0;E(f.children,(function(t){!isNaN(t.getValue())&&v++}));var m=f.getValue(),x=Math.PI/(m||v)*2,_=f.depth>0,b=f.height-(_?-1:1),w=(h-u)/(b||1),S=t.get("clockwise"),M=t.get("stillShowZeroSum"),I=S?1:-1,T=function(e,n){if(e){var i=n;if(e!==d){var r=e.getValue(),o=0===m&&M?x:r*x;o1;)r=r.parentNode;var o=n.getColorFromPalette(r.name||r.dataIndex+"",e);return t.depth>1&&U(o)&&(o=$n(o,(t.depth-1)/(i-1)*.5)),o}(r,t,i.root.height)),A(n.ensureUniqueItemVisual(r.dataIndex,"style"),o)}))}))}var $O={color:"fill",borderColor:"stroke"},JO={symbol:1,symbolSize:1,symbolKeepAspect:1,legendIcon:1,visualMeta:1,liftZ:1,decal:1},QO=Vo(),tR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(){this.currentZLevel=this.get("zlevel",!0),this.currentZ=this.get("z",!0)},e.prototype.getInitialData=function(t,e){return _x(null,this)},e.prototype.getDataParams=function(e,n,i){var r=t.prototype.getDataParams.call(this,e,n);return i&&(r.info=QO(i).info),r},e.type="series.custom",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={coordinateSystem:"cartesian2d",z:2,legendHoverLink:!0,clip:!1},e}(bg);function eR(t,e){return e=e||[0,0],z(["x","y"],(function(n,i){var r=this.getAxis(n),o=e[i],a=t[i]/2;return"category"===r.type?r.getBandWidth():Math.abs(r.dataToCoord(o-a)-r.dataToCoord(o+a))}),this)}function nR(t,e){return e=e||[0,0],z([0,1],(function(n){var i=e[n],r=t[n]/2,o=[],a=[];return o[n]=i-r,a[n]=i+r,o[1-n]=a[1-n]=e[1-n],Math.abs(this.dataToPoint(o)[n]-this.dataToPoint(a)[n])}),this)}function iR(t,e){var n=this.getAxis(),i=e instanceof Array?e[0]:e,r=(t instanceof Array?t[0]:t)/2;return"category"===n.type?n.getBandWidth():Math.abs(n.dataToCoord(i-r)-n.dataToCoord(i+r))}function rR(t,e){return e=e||[0,0],z(["Radius","Angle"],(function(n,i){var r=this["get"+n+"Axis"](),o=e[i],a=t[i]/2,s="category"===r.type?r.getBandWidth():Math.abs(r.dataToCoord(o-a)-r.dataToCoord(o+a));return"Angle"===n&&(s=s*Math.PI/180),s}),this)}function oR(t,e,n,i){return t&&(t.legacy||!1!==t.legacy&&!n&&!i&&"tspan"!==e&&("text"===e||_t(t,"text")))}function aR(t,e,n){var i,r,o,a=t;if("text"===e)o=a;else{o={},_t(a,"text")&&(o.text=a.text),_t(a,"rich")&&(o.rich=a.rich),_t(a,"textFill")&&(o.fill=a.textFill),_t(a,"textStroke")&&(o.stroke=a.textStroke),_t(a,"fontFamily")&&(o.fontFamily=a.fontFamily),_t(a,"fontSize")&&(o.fontSize=a.fontSize),_t(a,"fontStyle")&&(o.fontStyle=a.fontStyle),_t(a,"fontWeight")&&(o.fontWeight=a.fontWeight),r={type:"text",style:o,silent:!0},i={};var s=_t(a,"textPosition");n?i.position=s?a.textPosition:"inside":s&&(i.position=a.textPosition),_t(a,"textPosition")&&(i.position=a.textPosition),_t(a,"textOffset")&&(i.offset=a.textOffset),_t(a,"textRotation")&&(i.rotation=a.textRotation),_t(a,"textDistance")&&(i.distance=a.textDistance)}return sR(o,t),E(o.rich,(function(t){sR(t,t)})),{textConfig:i,textContent:r}}function sR(t,e){e&&(e.font=e.textFont||e.font,_t(e,"textStrokeWidth")&&(t.lineWidth=e.textStrokeWidth),_t(e,"textAlign")&&(t.align=e.textAlign),_t(e,"textVerticalAlign")&&(t.verticalAlign=e.textVerticalAlign),_t(e,"textLineHeight")&&(t.lineHeight=e.textLineHeight),_t(e,"textWidth")&&(t.width=e.textWidth),_t(e,"textHeight")&&(t.height=e.textHeight),_t(e,"textBackgroundColor")&&(t.backgroundColor=e.textBackgroundColor),_t(e,"textPadding")&&(t.padding=e.textPadding),_t(e,"textBorderColor")&&(t.borderColor=e.textBorderColor),_t(e,"textBorderWidth")&&(t.borderWidth=e.textBorderWidth),_t(e,"textBorderRadius")&&(t.borderRadius=e.textBorderRadius),_t(e,"textBoxShadowColor")&&(t.shadowColor=e.textBoxShadowColor),_t(e,"textBoxShadowBlur")&&(t.shadowBlur=e.textBoxShadowBlur),_t(e,"textBoxShadowOffsetX")&&(t.shadowOffsetX=e.textBoxShadowOffsetX),_t(e,"textBoxShadowOffsetY")&&(t.shadowOffsetY=e.textBoxShadowOffsetY))}function lR(t,e,n){var i=t;i.textPosition=i.textPosition||n.position||"inside",null!=n.offset&&(i.textOffset=n.offset),null!=n.rotation&&(i.textRotation=n.rotation),null!=n.distance&&(i.textDistance=n.distance);var r=i.textPosition.indexOf("inside")>=0,o=t.fill||"#000";uR(i,e);var a=null==i.textFill;return r?a&&(i.textFill=n.insideFill||"#fff",!i.textStroke&&n.insideStroke&&(i.textStroke=n.insideStroke),!i.textStroke&&(i.textStroke=o),null==i.textStrokeWidth&&(i.textStrokeWidth=2)):(a&&(i.textFill=t.fill||n.outsideFill||"#000"),!i.textStroke&&n.outsideStroke&&(i.textStroke=n.outsideStroke)),i.text=e.text,i.rich=e.rich,E(e.rich,(function(t){uR(t,t)})),i}function uR(t,e){e&&(_t(e,"fill")&&(t.textFill=e.fill),_t(e,"stroke")&&(t.textStroke=e.fill),_t(e,"lineWidth")&&(t.textStrokeWidth=e.lineWidth),_t(e,"font")&&(t.font=e.font),_t(e,"fontStyle")&&(t.fontStyle=e.fontStyle),_t(e,"fontWeight")&&(t.fontWeight=e.fontWeight),_t(e,"fontSize")&&(t.fontSize=e.fontSize),_t(e,"fontFamily")&&(t.fontFamily=e.fontFamily),_t(e,"align")&&(t.textAlign=e.align),_t(e,"verticalAlign")&&(t.textVerticalAlign=e.verticalAlign),_t(e,"lineHeight")&&(t.textLineHeight=e.lineHeight),_t(e,"width")&&(t.textWidth=e.width),_t(e,"height")&&(t.textHeight=e.height),_t(e,"backgroundColor")&&(t.textBackgroundColor=e.backgroundColor),_t(e,"padding")&&(t.textPadding=e.padding),_t(e,"borderColor")&&(t.textBorderColor=e.borderColor),_t(e,"borderWidth")&&(t.textBorderWidth=e.borderWidth),_t(e,"borderRadius")&&(t.textBorderRadius=e.borderRadius),_t(e,"shadowColor")&&(t.textBoxShadowColor=e.shadowColor),_t(e,"shadowBlur")&&(t.textBoxShadowBlur=e.shadowBlur),_t(e,"shadowOffsetX")&&(t.textBoxShadowOffsetX=e.shadowOffsetX),_t(e,"shadowOffsetY")&&(t.textBoxShadowOffsetY=e.shadowOffsetY),_t(e,"textShadowColor")&&(t.textShadowColor=e.textShadowColor),_t(e,"textShadowBlur")&&(t.textShadowBlur=e.textShadowBlur),_t(e,"textShadowOffsetX")&&(t.textShadowOffsetX=e.textShadowOffsetX),_t(e,"textShadowOffsetY")&&(t.textShadowOffsetY=e.textShadowOffsetY))}var hR={position:["x","y"],scale:["scaleX","scaleY"],origin:["originX","originY"]},cR=G(hR),pR=(V(mr,(function(t,e){return t[e]=1,t}),{}),mr.join(", "),["","style","shape","extra"]),dR=Vo();function fR(t,e,n,i,r){var o=t+"Animation",a=gh(t,i,r)||{},s=dR(e).userDuring;return a.duration>0&&(a.during=s?W(bR,{el:e,userDuring:s}):null,a.setToFinal=!0,a.scope=t),A(a,n[o]),a}function gR(t,e,n,i){var r=(i=i||{}).dataIndex,o=i.isInit,a=i.clearStyle,s=n.isAnimationEnabled(),l=dR(t),u=e.style;l.userDuring=e.during;var h={},c={};if(function(t,e,n){for(var i=0;i=0)){var c=t.getAnimationStyleProps(),p=c?c.style:null;if(p){!r&&(r=i.style={});var d=G(n);for(u=0;u0&&t.animateFrom(p,d)}else!function(t,e,n,i,r){if(r){var o=fR("update",t,e,i,n);o.duration>0&&t.animateFrom(r,o)}}(t,e,r||0,n,h);yR(t,e),u?t.dirty():t.markRedraw()}function yR(t,e){for(var n=dR(t).leaveToProps,i=0;i=0){!o&&(o=i[t]={});var p=G(a);for(h=0;hi[1]&&i.reverse(),{coordSys:{type:"polar",cx:t.cx,cy:t.cy,r:i[1],r0:i[0]},api:{coord:function(i){var r=e.dataToRadius(i[0]),o=n.dataToAngle(i[1]),a=t.coordToPoint([r,o]);return a.push(r,o*Math.PI/180),a},size:W(rR,t)}}},calendar:function(t){var e=t.getRect(),n=t.getRangeInfo();return{coordSys:{type:"calendar",x:e.x,y:e.y,width:e.width,height:e.height,cellWidth:t.getCellWidth(),cellHeight:t.getCellHeight(),rangeInfo:{start:n.start,end:n.end,weeks:n.weeks,dayCount:n.allDay}},api:{coord:function(e,n){return t.dataToPoint(e,n)}}}}};function BR(t){return t instanceof ks}function FR(t){return t instanceof Da}var GR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n,i){this._progressiveEls=null;var r=this._data,o=t.getData(),a=this.group,s=UR(t,o,e,n);r||a.removeAll(),o.diff(r).add((function(e){jR(n,null,e,s(e,i),t,a,o)})).remove((function(e){var n=r.getItemGraphicEl(e);n&&vR(n,QO(n).option,t)})).update((function(e,l){var u=r.getItemGraphicEl(l);jR(n,u,e,s(e,i),t,a,o)})).execute();var l=t.get("clip",!0)?PS(t.coordinateSystem,!1,t):null;l?a.setClipPath(l):a.removeClipPath(),this._data=o},e.prototype.incrementalPrepareRender=function(t,e,n){this.group.removeAll(),this._data=null},e.prototype.incrementalRender=function(t,e,n,i,r){var o=e.getData(),a=UR(e,o,n,i),s=this._progressiveEls=[];function l(t){t.isGroup||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}for(var u=t.start;u=0?e.getStore().get(r,n):void 0}var o=e.get(i.name,n),a=i&&i.ordinalMeta;return a?a.categories[o]:o},styleEmphasis:function(n,i){0;null==i&&(i=s);var r=m(i,AR).getItemStyle(),o=x(i,AR),a=oc(o,null,null,!0,!0);a.text=o.getShallow("show")?ot(t.getFormattedLabel(i,AR),t.getFormattedLabel(i,kR),pS(e,i)):null;var l=ac(o,null,!0);return b(n,r),r=lR(r,a,l),n&&_(r,n),r.legacy=!0,r},visual:function(t,n){if(null==n&&(n=s),_t($O,t)){var i=e.getItemVisual(n,"style");return i?i[$O[t]]:null}if(_t(JO,t))return e.getItemVisual(n,t)},barLayout:function(t){if("cartesian2d"===o.type){return function(t){var e=[],n=t.axis,i="axis0";if("category"===n.type){for(var r=n.getBandWidth(),o=0;o=c;f--){var g=e.childAt(f);tN(e,g,r)}}(t,c,n,i,r),a>=0?o.replaceAt(c,a):o.add(c),c}function KR(t,e,n){var i,r=QO(t),o=e.type,a=e.shape,s=e.style;return n.isUniversalTransitionEnabled()||null!=o&&o!==r.customGraphicType||"path"===o&&((i=a)&&(_t(i,"pathData")||_t(i,"d")))&&rN(a)!==r.customPathData||"image"===o&&_t(s,"image")&&s.image!==r.customImagePath}function $R(t,e,n){var i=e?JR(t,e):t,r=e?QR(t,i,AR):t.style,o=t.type,a=i?i.textConfig:null,s=t.textContent,l=s?e?JR(s,e):s:null;if(r&&(n.isLegacy||oR(r,o,!!a,!!l))){n.isLegacy=!0;var u=aR(r,o,!e);!a&&u.textConfig&&(a=u.textConfig),!l&&u.textContent&&(l=u.textContent)}if(!e&&l){var h=l;!h.type&&(h.type="text")}var c=e?n[e]:n.normal;c.cfg=a,c.conOpt=l}function JR(t,e){return e?t?t[e]:null:t}function QR(t,e,n){var i=e&&e.style;return null==i&&n===AR&&t&&(i=t.styleEmphasis),i}function tN(t,e,n){e&&vR(e,QO(t).option,n)}function eN(t,e){var n=t&&t.name;return null!=n?n:"e\0\0"+e}function nN(t,e){var n=this.context,i=null!=t?n.newChildren[t]:null,r=null!=e?n.oldChildren[e]:null;qR(n.api,r,n.dataIndex,i,n.seriesModel,n.group)}function iN(t){var e=this.context,n=e.oldChildren[t];n&&vR(n,QO(n).option,e.seriesModel)}function rN(t){return t&&(t.pathData||t.d)}var oN=Vo(),aN=T,sN=W,lN=function(){function t(){this._dragging=!1,this.animationThreshold=15}return t.prototype.render=function(t,e,n,i){var r=e.get("value"),o=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=n,i||this._lastValue!==r||this._lastStatus!==o){this._lastValue=r,this._lastStatus=o;var a=this._group,s=this._handle;if(!o||"hide"===o)return a&&a.hide(),void(s&&s.hide());a&&a.show(),s&&s.show();var l={};this.makeElOption(l,r,t,e,n);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(n),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(a){var c=H(uN,e,h);this.updatePointerEl(a,l,c),this.updateLabelEl(a,l,c,e)}else a=this._group=new Br,this.createPointerEl(a,l,t,e),this.createLabelEl(a,l,t,e),n.getZr().add(a);dN(a,e,!0),this._renderHandle(r)}},t.prototype.remove=function(t){this.clear(t)},t.prototype.dispose=function(t){this.clear(t)},t.prototype.determineAnimation=function(t,e){var n=e.get("animation"),i=t.axis,r="category"===i.type,o=e.get("snap");if(!o&&!r)return!1;if("auto"===n||null==n){var a=this.animationThreshold;if(r&&i.getBandWidth()>a)return!0;if(o){var s=wI(t).seriesDataCount,l=i.getExtent();return Math.abs(l[0]-l[1])/s>a}return!1}return!0===n},t.prototype.makeElOption=function(t,e,n,i,r){},t.prototype.createPointerEl=function(t,e,n,i){var r=e.pointer;if(r){var o=oN(t).pointerEl=new Qh[r.type](aN(e.pointer));t.add(o)}},t.prototype.createLabelEl=function(t,e,n,i){if(e.label){var r=oN(t).labelEl=new Xs(aN(e.label));t.add(r),cN(r,i)}},t.prototype.updatePointerEl=function(t,e,n){var i=oN(t).pointerEl;i&&e.pointer&&(i.setStyle(e.pointer.style),n(i,{shape:e.pointer.shape}))},t.prototype.updateLabelEl=function(t,e,n,i){var r=oN(t).labelEl;r&&(r.setStyle(e.label.style),n(r,{x:e.label.x,y:e.label.y}),cN(r,i))},t.prototype._renderHandle=function(t){if(!this._dragging&&this.updateHandleTransform){var e,n=this._axisPointerModel,i=this._api.getZr(),r=this._handle,o=n.getModel("handle"),a=n.get("status");if(!o.get("show")||!a||"hide"===a)return r&&i.remove(r),void(this._handle=null);this._handle||(e=!0,r=this._handle=Uh(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){de(t.event)},onmousedown:sN(this._onHandleDragMove,this,0,0),drift:sN(this._onHandleDragMove,this),ondragend:sN(this._onHandleDragEnd,this)}),i.add(r)),dN(r,n,!1),r.setStyle(o.getItemStyle(null,["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"]));var s=o.get("size");Y(s)||(s=[s,s]),r.scaleX=s[0]/2,r.scaleY=s[1]/2,Hg(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,e)}},t.prototype._moveHandleToValue=function(t,e){uN(this._axisPointerModel,!e&&this._moveAnimation,this._handle,pN(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},t.prototype._onHandleDragMove=function(t,e){var n=this._handle;if(n){this._dragging=!0;var i=this.updateHandleTransform(pN(n),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=i,n.stopAnimation(),n.attr(pN(i)),oN(n).lastProp=null,this._doDispatchAxisPointer()}},t.prototype._doDispatchAxisPointer=function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},t.prototype._onHandleDragEnd=function(){if(this._dragging=!1,this._handle){var t=this._axisPointerModel.get("value");this._moveHandleToValue(t),this._api.dispatchAction({type:"hideTip"})}},t.prototype.clear=function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),n=this._group,i=this._handle;e&&n&&(this._lastGraphicKey=null,n&&e.remove(n),i&&e.remove(i),this._group=null,this._handle=null,this._payloadInfo=null),Yg(this,"_doDispatchAxisPointer")},t.prototype.doClear=function(){},t.prototype.buildLabel=function(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}},t}();function uN(t,e,n,i){hN(oN(n).lastProp,i)||(oN(n).lastProp=i,e?vh(n,i,t):(n.stopAnimation(),n.attr(i)))}function hN(t,e){if(q(t)&&q(e)){var n=!0;return E(e,(function(e,i){n=n&&hN(t[i],e)})),!!n}return t===e}function cN(t,e){t[e.get(["label","show"])?"show":"hide"]()}function pN(t){return{x:t.x||0,y:t.y||0,rotation:t.rotation||0}}function dN(t,e,n){var i=e.get("z"),r=e.get("zlevel");t&&t.traverse((function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=r&&(t.zlevel=r),t.silent=n)}))}function fN(t){var e,n=t.get("type"),i=t.getModel(n+"Style");return"line"===n?(e=i.getLineStyle()).fill=null:"shadow"===n&&((e=i.getAreaStyle()).stroke=null),e}function gN(t,e,n,i,r){var o=yN(n.get("value"),e.axis,e.ecModel,n.get("seriesDataIndices"),{precision:n.get(["label","precision"]),formatter:n.get(["label","formatter"])}),a=n.getModel("label"),s=vp(a.get("padding")||0),l=a.getFont(),u=Sr(o,l),h=r.position,c=u.width+s[1]+s[3],p=u.height+s[0]+s[2],d=r.align;"right"===d&&(h[0]-=c),"center"===d&&(h[0]-=c/2);var f=r.verticalAlign;"bottom"===f&&(h[1]-=p),"middle"===f&&(h[1]-=p/2),function(t,e,n,i){var r=i.getWidth(),o=i.getHeight();t[0]=Math.min(t[0]+e,r)-e,t[1]=Math.min(t[1]+n,o)-n,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}(h,c,p,i);var g=a.get("backgroundColor");g&&"auto"!==g||(g=e.get(["axisLine","lineStyle","color"])),t.label={x:h[0],y:h[1],style:oc(a,{text:o,font:l,fill:a.getTextColor(),padding:s,backgroundColor:g}),z2:10}}function yN(t,e,n,i,r){t=e.scale.parse(t);var o=e.scale.getLabel({value:t},{precision:r.precision}),a=r.formatter;if(a){var s={value:S_(e,{value:t}),axisDimension:e.dim,axisIndex:e.index,seriesData:[]};E(i,(function(t){var e=n.getSeriesByIndex(t.seriesIndex),i=t.dataIndexInside,r=e&&e.getDataParams(i);r&&s.seriesData.push(r)})),U(a)?o=a.replace("{value}",o):X(a)&&(o=a(s))}return o}function vN(t,e,n){var i=[1,0,0,1,0,0];return Se(i,i,n.rotation),we(i,i,n.position),Fh([t.dataToCoord(e),(n.labelOffset||0)+(n.labelDirection||1)*(n.labelMargin||0)],i)}function mN(t,e,n,i,r,o){var a=dI.innerTextLayout(n.rotation,0,n.labelDirection);n.labelMargin=r.get(["label","margin"]),gN(e,i,r,o,{position:vN(i.axis,t,n),align:a.textAlign,verticalAlign:a.textVerticalAlign})}function xN(t,e,n){return{x1:t[n=n||0],y1:t[1-n],x2:e[n],y2:e[1-n]}}function _N(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}}function bN(t,e,n,i,r,o){return{cx:t,cy:e,r0:n,r:i,startAngle:r,endAngle:o,clockwise:!0}}var wN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis,a=o.grid,s=i.get("type"),l=SN(a,o).getOtherAxis(o).getGlobalExtent(),u=o.toGlobalCoord(o.dataToCoord(e,!0));if(s&&"none"!==s){var h=fN(i),c=MN[s](o,u,l);c.style=h,t.graphicKey=c.type,t.pointer=c}mN(e,t,iI(a.model,n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=iI(e.axis.grid.model,e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=vN(e.axis,t,i);return{x:r[0],y:r[1],rotation:i.rotation+(i.labelDirection<0?Math.PI:0)}},e.prototype.updateHandleTransform=function(t,e,n,i){var r=n.axis,o=r.grid,a=r.getGlobalExtent(!0),s=SN(o,r).getOtherAxis(r).getGlobalExtent(),l="x"===r.dim?0:1,u=[t.x,t.y];u[l]+=e[l],u[l]=Math.min(a[1],u[l]),u[l]=Math.max(a[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];return{x:u[0],y:u[1],rotation:t.rotation,cursorPoint:c,tooltipOption:[{verticalAlign:"middle"},{align:"center"}][l]}},e}(lN);function SN(t,e){var n={};return n[e.dim+"AxisIndex"]=e.index,t.getCartesian(n)}var MN={line:function(t,e,n){return{type:"Line",subPixelOptimize:!0,shape:xN([e,n[0]],[e,n[1]],IN(t))}},shadow:function(t,e,n){var i=Math.max(1,t.getBandWidth()),r=n[1]-n[0];return{type:"Rect",shape:_N([e-i/2,n[0]],[i,r],IN(t))}}};function IN(t){return"x"===t.dim?0:1}var TN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="axisPointer",e.defaultOption={show:"auto",z:50,type:"line",snap:!1,triggerTooltip:!0,triggerEmphasis:!0,value:null,status:null,link:[],animation:null,animationDurationUpdate:200,lineStyle:{color:"#B9BEC9",width:1,type:"dashed"},shadowStyle:{color:"rgba(210,219,238,0.2)"},label:{show:!0,formatter:null,precision:"auto",margin:3,color:"#fff",padding:[5,7,5,7],backgroundColor:"auto",borderColor:null,borderWidth:0,borderRadius:3},handle:{show:!1,icon:"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z",size:45,margin:50,color:"#333",shadowBlur:3,shadowColor:"#aaa",shadowOffsetX:0,shadowOffsetY:2,throttle:40}},e}(zp),CN=Vo(),DN=E;function AN(t,e,n){if(!r.node){var i=e.getZr();CN(i).records||(CN(i).records={}),function(t,e){if(CN(t).initialized)return;function n(n,i){t.on(n,(function(n){var r=function(t){var e={showTip:[],hideTip:[]},n=function(i){var r=e[i.type];r?r.push(i):(i.dispatchAction=n,t.dispatchAction(i))};return{dispatchAction:n,pendings:e}}(e);DN(CN(t).records,(function(t){t&&i(t,n,r.dispatchAction)})),function(t,e){var n,i=t.showTip.length,r=t.hideTip.length;i?n=t.showTip[i-1]:r&&(n=t.hideTip[r-1]);n&&(n.dispatchAction=null,e.dispatchAction(n))}(r.pendings,e)}))}CN(t).initialized=!0,n("click",H(LN,"click")),n("mousemove",H(LN,"mousemove")),n("globalout",kN)}(i,e),(CN(i).records[t]||(CN(i).records[t]={})).handler=n}}function kN(t,e,n){t.handler("leave",null,n)}function LN(t,e,n,i){e.handler(t,n,i)}function PN(t,e){if(!r.node){var n=e.getZr();(CN(n).records||{})[t]&&(CN(n).records[t]=null)}}var ON=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=e.getComponent("tooltip"),r=t.get("triggerOn")||i&&i.get("triggerOn")||"mousemove|click";AN("axisPointer",n,(function(t,e,n){"none"!==r&&("leave"===t||r.indexOf(t)>=0)&&n({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})}))},e.prototype.remove=function(t,e){PN("axisPointer",e)},e.prototype.dispose=function(t,e){PN("axisPointer",e)},e.type="axisPointer",e}(Ag);function RN(t,e){var n,i=[],r=t.seriesIndex;if(null==r||!(n=e.getSeriesByIndex(r)))return{point:[]};var o=n.getData(),a=zo(o,t);if(null==a||a<0||Y(a))return{point:[]};var s=o.getItemGraphicEl(a),l=n.coordinateSystem;if(n.getTooltipPosition)i=n.getTooltipPosition(a)||[];else if(l&&l.dataToPoint)if(t.isStacked){var u=l.getBaseAxis(),h=l.getOtherAxis(u).dim,c=u.dim,p="x"===h||"radius"===h?1:0,d=o.mapDimension(c),f=[];f[p]=o.get(d,a),f[1-p]=o.get(o.getCalculationInfo("stackResultDimension"),a),i=l.dataToPoint(f)||[]}else i=l.dataToPoint(o.getValues(z(l.dimensions,(function(t){return o.mapDimension(t)})),a))||[];else if(s){var g=s.getBoundingRect().clone();g.applyTransform(s.transform),i=[g.x+g.width/2,g.y+g.height/2]}return{point:i,el:s}}var NN=Vo();function EN(t,e,n){var i=t.currTrigger,r=[t.x,t.y],o=t,a=t.dispatchAction||W(n.dispatchAction,n),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){GN(r)&&(r=RN({seriesIndex:o.seriesIndex,dataIndex:o.dataIndex},e).point);var l=GN(r),u=o.axesInfo,h=s.axesInfo,c="leave"===i||GN(r),p={},d={},f={list:[],map:{}},g={showPointer:H(VN,d),showTooltip:H(BN,f)};E(s.coordSysMap,(function(t,e){var n=l||t.containPoint(r);E(s.coordSysAxesInfo[e],(function(t,e){var i=t.axis,o=function(t,e){for(var n=0;n<(t||[]).length;n++){var i=t[n];if(e.axis.dim===i.axisDim&&e.axis.model.componentIndex===i.axisIndex)return i}}(u,t);if(!c&&n&&(!u||o)){var a=o&&o.value;null!=a||l||(a=i.pointToData(r)),null!=a&&zN(t,a,g,!1,p)}}))}));var y={};return E(h,(function(t,e){var n=t.linkGroup;n&&!d[e]&&E(n.axesInfo,(function(e,i){var r=d[i];if(e!==t&&r){var o=r.value;n.mapper&&(o=t.axis.scale.parse(n.mapper(o,FN(e),FN(t)))),y[t.key]=o}}))})),E(y,(function(t,e){zN(h[e],t,g,!0,p)})),function(t,e,n){var i=n.axesInfo=[];E(e,(function(e,n){var r=e.axisPointerModel.option,o=t[n];o?(!e.useHandle&&(r.status="show"),r.value=o.value,r.seriesDataIndices=(o.payloadBatch||[]).slice()):!e.useHandle&&(r.status="hide"),"show"===r.status&&i.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:r.value})}))}(d,h,p),function(t,e,n,i){if(GN(e)||!t.list.length)return void i({type:"hideTip"});var r=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};i({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:n.tooltipOption,position:n.position,dataIndexInside:r.dataIndexInside,dataIndex:r.dataIndex,seriesIndex:r.seriesIndex,dataByCoordSys:t.list})}(f,r,t,a),function(t,e,n){var i=n.getZr(),r="axisPointerLastHighlights",o=NN(i)[r]||{},a=NN(i)[r]={};E(t,(function(t,e){var n=t.axisPointerModel.option;"show"===n.status&&t.triggerEmphasis&&E(n.seriesDataIndices,(function(t){var e=t.seriesIndex+" | "+t.dataIndex;a[e]=t}))}));var s=[],l=[];E(o,(function(t,e){!a[e]&&l.push(t)})),E(a,(function(t,e){!o[e]&&s.push(t)})),l.length&&n.dispatchAction({type:"downplay",escapeConnect:!0,notBlur:!0,batch:l}),s.length&&n.dispatchAction({type:"highlight",escapeConnect:!0,notBlur:!0,batch:s})}(h,0,n),p}}function zN(t,e,n,i,r){var o=t.axis;if(!o.scale.isBlank()&&o.containData(e))if(t.involveSeries){var a=function(t,e){var n=e.axis,i=n.dim,r=t,o=[],a=Number.MAX_VALUE,s=-1;return E(e.seriesModels,(function(e,l){var u,h,c=e.getData().mapDimensionsAll(i);if(e.getAxisTooltipData){var p=e.getAxisTooltipData(c,t,n);h=p.dataIndices,u=p.nestestValue}else{if(!(h=e.getData().indicesOfNearest(c[0],t,"category"===n.type?.5:null)).length)return;u=e.getData().get(c[0],h[0])}if(null!=u&&isFinite(u)){var d=t-u,f=Math.abs(d);f<=a&&((f=0&&s<0)&&(a=f,s=d,r=u,o.length=0),E(h,(function(t){o.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})})))}})),{payloadBatch:o,snapToValue:r}}(e,t),s=a.payloadBatch,l=a.snapToValue;s[0]&&null==r.seriesIndex&&A(r,s[0]),!i&&t.snap&&o.containData(l)&&null!=l&&(e=l),n.showPointer(t,e,s),n.showTooltip(t,a,l)}else n.showPointer(t,e)}function VN(t,e,n,i){t[e.key]={value:n,payloadBatch:i}}function BN(t,e,n,i){var r=n.payloadBatch,o=e.axis,a=o.model,s=e.axisPointerModel;if(e.triggerTooltip&&r.length){var l=e.coordSys.model,u=MI(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:o.dim,axisIndex:a.componentIndex,axisType:a.type,axisId:a.id,value:i,valueLabelOpt:{precision:s.get(["label","precision"]),formatter:s.get(["label","formatter"])},seriesDataIndices:r.slice()})}}function FN(t){var e=t.axis.model,n={},i=n.axisDim=t.axis.dim;return n.axisIndex=n[i+"AxisIndex"]=e.componentIndex,n.axisName=n[i+"AxisName"]=e.name,n.axisId=n[i+"AxisId"]=e.id,n}function GN(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function WN(t){TI.registerAxisPointerClass("CartesianAxisPointer",wN),t.registerComponentModel(TN),t.registerComponentView(ON),t.registerPreprocessor((function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!Y(e)&&(t.axisPointer.link=[e])}})),t.registerProcessor(t.PRIORITY.PROCESSOR.STATISTIC,(function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=xI(t,e)})),t.registerAction({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},EN)}var HN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis;"angle"===o.dim&&(this.animationThreshold=Math.PI/18);var a=o.polar,s=a.getOtherAxis(o).getExtent(),l=o.dataToCoord(e),u=i.get("type");if(u&&"none"!==u){var h=fN(i),c=YN[u](o,a,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}var p=function(t,e,n,i,r){var o=e.axis,a=o.dataToCoord(t),s=i.getAngleAxis().getExtent()[0];s=s/180*Math.PI;var l,u,h,c=i.getRadiusAxis().getExtent();if("radius"===o.dim){var p=[1,0,0,1,0,0];Se(p,p,s),we(p,p,[i.cx,i.cy]),l=Fh([a,-r],p);var d=e.getModel("axisLabel").get("rotate")||0,f=dI.innerTextLayout(s,d*Math.PI/180,-1);u=f.textAlign,h=f.textVerticalAlign}else{var g=c[1];l=i.coordToPoint([g+r,a]);var y=i.cx,v=i.cy;u=Math.abs(l[0]-y)/g<.3?"center":l[0]>y?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}(e,n,0,a,i.get(["label","margin"]));gN(t,n,i,r,p)},e}(lN);var YN={line:function(t,e,n,i){return"angle"===t.dim?{type:"Line",shape:xN(e.coordToPoint([i[0],n]),e.coordToPoint([i[1],n]))}:{type:"Circle",shape:{cx:e.cx,cy:e.cy,r:n}}},shadow:function(t,e,n,i){var r=Math.max(1,t.getBandWidth()),o=Math.PI/180;return"angle"===t.dim?{type:"Sector",shape:bN(e.cx,e.cy,i[0],i[1],(-n-r/2)*o,(r/2-n)*o)}:{type:"Sector",shape:bN(e.cx,e.cy,n-r/2,n+r/2,0,2*Math.PI)}}},XN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.findAxisModel=function(t){var e;return this.ecModel.eachComponent(t,(function(t){t.getCoordSysModel()===this&&(e=t)}),this),e},e.type="polar",e.dependencies=["radiusAxis","angleAxis"],e.defaultOption={z:0,center:["50%","50%"],radius:"80%"},e}(zp),UN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("polar",Wo).models[0]},e.type="polarAxis",e}(zp);R(UN,D_);var ZN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="angleAxis",e}(UN),jN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="radiusAxis",e}(UN),qN=function(t){function e(e,n){return t.call(this,"radius",e,n)||this}return n(e,t),e.prototype.pointToData=function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},e}(ab);qN.prototype.dataToRadius=ab.prototype.dataToCoord,qN.prototype.radiusToData=ab.prototype.coordToData;var KN=Vo(),$N=function(t){function e(e,n){return t.call(this,"angle",e,n||[0,360])||this}return n(e,t),e.prototype.pointToData=function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},e.prototype.calculateCategoryInterval=function(){var t=this,e=t.getLabelModel(),n=t.scale,i=n.getExtent(),r=n.count();if(i[1]-i[0]<1)return 0;var o=i[0],a=t.dataToCoord(o+1)-t.dataToCoord(o),s=Math.abs(a),l=Sr(null==o?"":o+"",e.getFont(),"center","top"),u=Math.max(l.height,7)/s;isNaN(u)&&(u=1/0);var h=Math.max(0,Math.floor(u)),c=KN(t.model),p=c.lastAutoInterval,d=c.lastTickCount;return null!=p&&null!=d&&Math.abs(p-h)<=1&&Math.abs(d-r)<=1&&p>h?h=p:(c.lastTickCount=r,c.lastAutoInterval=h),h},e}(ab);$N.prototype.dataToAngle=ab.prototype.dataToCoord,$N.prototype.angleToData=ab.prototype.coordToData;var JN=["radius","angle"],QN=function(){function t(t){this.dimensions=JN,this.type="polar",this.cx=0,this.cy=0,this._radiusAxis=new qN,this._angleAxis=new $N,this.axisPointerEnabled=!0,this.name=t||"",this._radiusAxis.polar=this._angleAxis.polar=this}return t.prototype.containPoint=function(t){var e=this.pointToCoord(t);return this._radiusAxis.contain(e[0])&&this._angleAxis.contain(e[1])},t.prototype.containData=function(t){return this._radiusAxis.containData(t[0])&&this._angleAxis.containData(t[1])},t.prototype.getAxis=function(t){return this["_"+t+"Axis"]},t.prototype.getAxes=function(){return[this._radiusAxis,this._angleAxis]},t.prototype.getAxesByScale=function(t){var e=[],n=this._angleAxis,i=this._radiusAxis;return n.scale.type===t&&e.push(n),i.scale.type===t&&e.push(i),e},t.prototype.getAngleAxis=function(){return this._angleAxis},t.prototype.getRadiusAxis=function(){return this._radiusAxis},t.prototype.getOtherAxis=function(t){var e=this._angleAxis;return t===e?this._radiusAxis:e},t.prototype.getBaseAxis=function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAngleAxis()},t.prototype.getTooltipAxes=function(t){var e=null!=t&&"auto"!==t?this.getAxis(t):this.getBaseAxis();return{baseAxes:[e],otherAxes:[this.getOtherAxis(e)]}},t.prototype.dataToPoint=function(t,e){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)])},t.prototype.pointToData=function(t,e){var n=this.pointToCoord(t);return[this._radiusAxis.radiusToData(n[0],e),this._angleAxis.angleToData(n[1],e)]},t.prototype.pointToCoord=function(t){var e=t[0]-this.cx,n=t[1]-this.cy,i=this.getAngleAxis(),r=i.getExtent(),o=Math.min(r[0],r[1]),a=Math.max(r[0],r[1]);i.inverse?o=a-360:a=o+360;var s=Math.sqrt(e*e+n*n);e/=s,n/=s;for(var l=Math.atan2(-n,e)/Math.PI*180,u=la;)l+=360*u;return[s,l]},t.prototype.coordToPoint=function(t){var e=t[0],n=t[1]/180*Math.PI;return[Math.cos(n)*e+this.cx,-Math.sin(n)*e+this.cy]},t.prototype.getArea=function(){var t=this.getAngleAxis(),e=this.getRadiusAxis().getExtent().slice();e[0]>e[1]&&e.reverse();var n=t.getExtent(),i=Math.PI/180,r=1e-4;return{cx:this.cx,cy:this.cy,r0:e[0],r:e[1],startAngle:-n[0]*i,endAngle:-n[1]*i,clockwise:t.inverse,contain:function(t,e){var n=t-this.cx,i=e-this.cy,o=n*n+i*i,a=this.r,s=this.r0;return a!==s&&o-r<=a*a&&o+r>=s*s}}},t.prototype.convertToPixel=function(t,e,n){return tE(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return tE(e)===this?this.pointToData(n):null},t}();function tE(t){var e=t.seriesModel,n=t.polarModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}function eE(t,e){var n=this,i=n.getAngleAxis(),r=n.getRadiusAxis();if(i.scale.setExtent(1/0,-1/0),r.scale.setExtent(1/0,-1/0),t.eachSeries((function(t){if(t.coordinateSystem===n){var e=t.getData();E(C_(e,"radius"),(function(t){r.scale.unionExtentFromData(e,t)})),E(C_(e,"angle"),(function(t){i.scale.unionExtentFromData(e,t)}))}})),__(i.scale,i.model),__(r.scale,r.model),"category"===i.type&&!i.onBand){var o=i.getExtent(),a=360/i.scale.count();i.inverse?o[1]+=a:o[1]-=a,i.setExtent(o[0],o[1])}}function nE(t,e){var n;if(t.type=e.get("type"),t.scale=b_(e),t.onBand=e.get("boundaryGap")&&"category"===t.type,t.inverse=e.get("inverse"),function(t){return"angleAxis"===t.mainType}(e)){t.inverse=t.inverse!==e.get("clockwise");var i=e.get("startAngle"),r=null!==(n=e.get("endAngle"))&&void 0!==n?n:i+(t.inverse?-360:360);t.setExtent(i,r)}e.axis=t,t.model=e}var iE={dimensions:JN,create:function(t,e){var n=[];return t.eachComponent("polar",(function(t,i){var r=new QN(i+"");r.update=eE;var o=r.getRadiusAxis(),a=r.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");nE(o,s),nE(a,l),function(t,e,n){var i=e.get("center"),r=n.getWidth(),o=n.getHeight();t.cx=$r(i[0],r),t.cy=$r(i[1],o);var a=t.getRadiusAxis(),s=Math.min(r,o)/2,l=e.get("radius");null==l?l=[0,"100%"]:Y(l)||(l=[0,l]);var u=[$r(l[0],s),$r(l[1],s)];a.inverse?a.setExtent(u[1],u[0]):a.setExtent(u[0],u[1])}(r,t,e),n.push(r),t.coordinateSystem=r,r.model=t})),t.eachSeries((function(t){if("polar"===t.get("coordinateSystem")){var e=t.getReferringComponents("polar",Wo).models[0];0,t.coordinateSystem=e.coordinateSystem}})),n}},rE=["axisLine","axisLabel","axisTick","minorTick","splitLine","minorSplitLine","splitArea"];function oE(t,e,n){e[1]>e[0]&&(e=e.slice().reverse());var i=t.coordToPoint([e[0],n]),r=t.coordToPoint([e[1],n]);return{x1:i[0],y1:i[1],x2:r[0],y2:r[1]}}function aE(t){return t.getRadiusAxis().inverse?0:1}function sE(t){var e=t[0],n=t[t.length-1];e&&n&&Math.abs(Math.abs(e.coord-n.coord)-360)<1e-4&&t.pop()}var lE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.axisPointerClass="PolarAxisPointer",n}return n(e,t),e.prototype.render=function(t,e){if(this.group.removeAll(),t.get("show")){var n=t.axis,i=n.polar,r=i.getRadiusAxis().getExtent(),o=n.getTicksCoords(),a=n.getMinorTicksCoords(),s=z(n.getViewLabels(),(function(t){t=T(t);var e=n.scale,i="ordinal"===e.type?e.getRawOrdinalNumber(t.tickValue):t.tickValue;return t.coord=n.dataToCoord(i),t}));sE(s),sE(o),E(rE,(function(e){!t.get([e,"show"])||n.scale.isBlank()&&"axisLine"!==e||uE[e](this.group,t,i,o,a,r,s)}),this)}},e.type="angleAxis",e}(TI),uE={axisLine:function(t,e,n,i,r,o){var a,s=e.getModel(["axisLine","lineStyle"]),l=n.getAngleAxis(),u=Math.PI/180,h=l.getExtent(),c=aE(n),p=c?0:1,d=360===Math.abs(h[1]-h[0])?"Circle":"Arc";(a=0===o[p]?new Qh[d]({shape:{cx:n.cx,cy:n.cy,r:o[c],startAngle:-h[0]*u,endAngle:-h[1]*u,clockwise:l.inverse},style:s.getLineStyle(),z2:1,silent:!0}):new Wu({shape:{cx:n.cx,cy:n.cy,r:o[c],r0:o[p]},style:s.getLineStyle(),z2:1,silent:!0})).style.fill=null,t.add(a)},axisTick:function(t,e,n,i,r,o){var a=e.getModel("axisTick"),s=(a.get("inside")?-1:1)*a.get("length"),l=o[aE(n)],u=z(i,(function(t){return new Ku({shape:oE(n,[l,l+s],t.coord)})}));t.add(Nh(u,{style:k(a.getModel("lineStyle").getLineStyle(),{stroke:e.get(["axisLine","lineStyle","color"])})}))},minorTick:function(t,e,n,i,r,o){if(r.length){for(var a=e.getModel("axisTick"),s=e.getModel("minorTick"),l=(a.get("inside")?-1:1)*s.get("length"),u=o[aE(n)],h=[],c=0;cf?"left":"right",v=Math.abs(d[1]-g)/p<.3?"middle":d[1]>g?"top":"bottom";if(s&&s[c]){var m=s[c];q(m)&&m.textStyle&&(a=new Cc(m.textStyle,l,l.ecModel))}var x=new Xs({silent:dI.isLabelSilent(e),style:oc(a,{x:d[0],y:d[1],fill:a.getTextColor()||e.get(["axisLine","lineStyle","color"]),text:i.formattedLabel,align:y,verticalAlign:v})});if(t.add(x),h){var _=dI.makeAxisEventDataBase(e);_.targetType="axisLabel",_.value=i.rawLabel,rl(x).eventData=_}}),this)},splitLine:function(t,e,n,i,r,o){var a=e.getModel("splitLine").getModel("lineStyle"),s=a.get("color"),l=0;s=s instanceof Array?s:[s];for(var u=[],h=0;h=0?"p":"n",C=b;m&&(i[s][I]||(i[s][I]={p:b,n:b}),C=i[s][I][T]);var D=void 0,A=void 0,k=void 0,L=void 0;if("radius"===c.dim){var P=c.dataToCoord(M)-b,O=o.dataToCoord(I);Math.abs(P)=L})}}}))}var vE={startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:0}},mE={splitNumber:5},xE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="polar",e}(Ag);function _E(t,e){e=e||{};var n=t.coordinateSystem,i=t.axis,r={},o=i.position,a=i.orient,s=n.getRect(),l=[s.x,s.x+s.width,s.y,s.y+s.height],u={horizontal:{top:l[2],bottom:l[3]},vertical:{left:l[0],right:l[1]}};r.position=["vertical"===a?u.vertical[o]:l[0],"horizontal"===a?u.horizontal[o]:l[3]];r.rotation=Math.PI/2*{horizontal:0,vertical:1}[a];r.labelDirection=r.tickDirection=r.nameDirection={top:-1,bottom:1,right:1,left:-1}[o],t.get(["axisTick","inside"])&&(r.tickDirection=-r.tickDirection),it(e.labelInside,t.get(["axisLabel","inside"]))&&(r.labelDirection=-r.labelDirection);var h=e.rotate;return null==h&&(h=t.get(["axisLabel","rotate"])),r.labelRotation="top"===o?-h:h,r.z2=1,r}var bE=["axisLine","axisTickLabel","axisName"],wE=["splitArea","splitLine"],SE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.axisPointerClass="SingleAxisPointer",n}return n(e,t),e.prototype.render=function(e,n,i,r){var o=this.group;o.removeAll();var a=this._axisGroup;this._axisGroup=new Br;var s=_E(e),l=new dI(e,s);E(bE,l.add,l),o.add(this._axisGroup),o.add(l.getGroup()),E(wE,(function(t){e.get([t,"show"])&&ME[t](this,this.group,this._axisGroup,e)}),this),Hh(a,this._axisGroup,e),t.prototype.render.call(this,e,n,i,r)},e.prototype.remove=function(){AI(this)},e.type="singleAxis",e}(TI),ME={splitLine:function(t,e,n,i){var r=i.axis;if(!r.scale.isBlank()){var o=i.getModel("splitLine"),a=o.getModel("lineStyle"),s=a.get("color");s=s instanceof Array?s:[s];for(var l=a.get("width"),u=i.coordinateSystem.getRect(),h=r.isHorizontal(),c=[],p=0,d=r.getTicksCoords({tickModel:o}),f=[],g=[],y=0;y=e.y&&t[1]<=e.y+e.height:n.contain(n.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},t.prototype.pointToData=function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},t.prototype.dataToPoint=function(t){var e=this.getAxis(),n=this.getRect(),i=[],r="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),i[r]=e.toGlobalCoord(e.dataToCoord(+t)),i[1-r]=0===r?n.y+n.height/2:n.x+n.width/2,i},t.prototype.convertToPixel=function(t,e,n){return AE(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return AE(e)===this?this.pointToData(n):null},t}();function AE(t){var e=t.seriesModel,n=t.singleAxisModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}var kE={create:function(t,e){var n=[];return t.eachComponent("singleAxis",(function(i,r){var o=new DE(i,t,e);o.name="single_"+r,o.resize(i,e),i.coordinateSystem=o,n.push(o)})),t.eachSeries((function(t){if("singleAxis"===t.get("coordinateSystem")){var e=t.getReferringComponents("singleAxis",Wo).models[0];t.coordinateSystem=e&&e.coordinateSystem}})),n},dimensions:CE},LE=["x","y"],PE=["width","height"],OE=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis,a=o.coordinateSystem,s=EE(a,1-NE(o)),l=a.dataToPoint(e)[0],u=i.get("type");if(u&&"none"!==u){var h=fN(i),c=RE[u](o,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}mN(e,t,_E(n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=_E(e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=vN(e.axis,t,i);return{x:r[0],y:r[1],rotation:i.rotation+(i.labelDirection<0?Math.PI:0)}},e.prototype.updateHandleTransform=function(t,e,n,i){var r=n.axis,o=r.coordinateSystem,a=NE(r),s=EE(o,a),l=[t.x,t.y];l[a]+=e[a],l[a]=Math.min(s[1],l[a]),l[a]=Math.max(s[0],l[a]);var u=EE(o,1-a),h=(u[1]+u[0])/2,c=[h,h];return c[a]=l[a],{x:l[0],y:l[1],rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}},e}(lN),RE={line:function(t,e,n){return{type:"Line",subPixelOptimize:!0,shape:xN([e,n[0]],[e,n[1]],NE(t))}},shadow:function(t,e,n){var i=t.getBandWidth(),r=n[1]-n[0];return{type:"Rect",shape:_N([e-i/2,n[0]],[i,r],NE(t))}}};function NE(t){return t.isHorizontal()?0:1}function EE(t,e){var n=t.getRect();return[n[LE[e]],n[LE[e]]+n[PE[e]]]}var zE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="single",e}(Ag);var VE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(e,n,i){var r=Rp(e);t.prototype.init.apply(this,arguments),BE(e,r)},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),BE(this.option,e)},e.prototype.getCellSize=function(){return this.option.cellSize},e.type="calendar",e.defaultOption={z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},e}(zp);function BE(t,e){var n,i=t.cellSize;1===(n=Y(i)?i:t.cellSize=[i,i]).length&&(n[1]=n[0]);var r=z([0,1],(function(t){return function(t,e){return null!=t[Cp[e][0]]||null!=t[Cp[e][1]]&&null!=t[Cp[e][2]]}(e,t)&&(n[t]="auto"),null!=n[t]&&"auto"!==n[t]}));Op(t,e,{type:"box",ignoreSize:r})}var FE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=this.group;i.removeAll();var r=t.coordinateSystem,o=r.getRangeInfo(),a=r.getOrient(),s=e.getLocaleModel();this._renderDayRect(t,o,i),this._renderLines(t,o,a,i),this._renderYearText(t,o,a,i),this._renderMonthText(t,s,a,i),this._renderWeekText(t,s,o,a,i)},e.prototype._renderDayRect=function(t,e,n){for(var i=t.coordinateSystem,r=t.getModel("itemStyle").getItemStyle(),o=i.getCellWidth(),a=i.getCellHeight(),s=e.start.time;s<=e.end.time;s=i.getNextNDay(s,1).time){var l=i.dataToRect([s],!1).tl,u=new Ws({shape:{x:l[0],y:l[1],width:o,height:a},cursor:"default",style:r});n.add(u)}},e.prototype._renderLines=function(t,e,n,i){var r=this,o=t.coordinateSystem,a=t.getModel(["splitLine","lineStyle"]).getLineStyle(),s=t.get(["splitLine","show"]),l=a.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var u=e.start,h=0;u.time<=e.end.time;h++){p(u.formatedDate),0===h&&(u=o.getDateInfo(e.start.y+"-"+e.start.m));var c=u.date;c.setMonth(c.getMonth()+1),u=o.getDateInfo(c)}function p(e){r._firstDayOfMonth.push(o.getDateInfo(e)),r._firstDayPoints.push(o.dataToRect([e],!1).tl);var l=r._getLinePointsOfOneWeek(t,e,n);r._tlpoints.push(l[0]),r._blpoints.push(l[l.length-1]),s&&r._drawSplitline(l,a,i)}p(o.getNextNDay(e.end.time,1).formatedDate),s&&this._drawSplitline(r._getEdgesPoints(r._tlpoints,l,n),a,i),s&&this._drawSplitline(r._getEdgesPoints(r._blpoints,l,n),a,i)},e.prototype._getEdgesPoints=function(t,e,n){var i=[t[0].slice(),t[t.length-1].slice()],r="horizontal"===n?0:1;return i[0][r]=i[0][r]-e/2,i[1][r]=i[1][r]+e/2,i},e.prototype._drawSplitline=function(t,e,n){var i=new Zu({z2:20,shape:{points:t},style:e});n.add(i)},e.prototype._getLinePointsOfOneWeek=function(t,e,n){for(var i=t.coordinateSystem,r=i.getDateInfo(e),o=[],a=0;a<7;a++){var s=i.getNextNDay(r.time,a),l=i.dataToRect([s.time],!1);o[2*s.day]=l.tl,o[2*s.day+1]=l["horizontal"===n?"bl":"tr"]}return o},e.prototype._formatterLabel=function(t,e){return U(t)&&t?(n=t,E(e,(function(t,e){n=n.replace("{"+e+"}",i?re(t):t)})),n):X(t)?t(e):e.nameMap;var n,i},e.prototype._yearTextPositionControl=function(t,e,n,i,r){var o=e[0],a=e[1],s=["center","bottom"];"bottom"===i?(a+=r,s=["center","top"]):"left"===i?o-=r:"right"===i?(o+=r,s=["center","top"]):a-=r;var l=0;return"left"!==i&&"right"!==i||(l=Math.PI/2),{rotation:l,x:o,y:a,style:{align:s[0],verticalAlign:s[1]}}},e.prototype._renderYearText=function(t,e,n,i){var r=t.getModel("yearLabel");if(r.get("show")){var o=r.get("margin"),a=r.get("position");a||(a="horizontal"!==n?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===n?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},p=e.start.y;+e.end.y>+e.start.y&&(p=p+"-"+e.end.y);var d=r.get("formatter"),f={start:e.start.y,end:e.end.y,nameMap:p},g=this._formatterLabel(d,f),y=new Xs({z2:30,style:oc(r,{text:g}),silent:r.get("silent")});y.attr(this._yearTextPositionControl(y,c[a],n,a,o)),i.add(y)}},e.prototype._monthTextPositionControl=function(t,e,n,i,r){var o="left",a="top",s=t[0],l=t[1];return"horizontal"===n?(l+=r,e&&(o="center"),"start"===i&&(a="bottom")):(s+=r,e&&(a="middle"),"start"===i&&(o="right")),{x:s,y:l,align:o,verticalAlign:a}},e.prototype._renderMonthText=function(t,e,n,i){var r=t.getModel("monthLabel");if(r.get("show")){var o=r.get("nameMap"),a=r.get("margin"),s=r.get("position"),l=r.get("align"),u=[this._tlpoints,this._blpoints];o&&!U(o)||(o&&(e=Vc(o)||e),o=e.get(["time","monthAbbr"])||[]);var h="start"===s?0:1,c="horizontal"===n?0:1;a="start"===s?-a:a;for(var p="center"===l,d=r.get("silent"),f=0;f=i.start.time&&n.timea.end.time&&t.reverse(),t},t.prototype._getRangeInfo=function(t){var e,n=[this.getDateInfo(t[0]),this.getDateInfo(t[1])];n[0].time>n[1].time&&(e=!0,n.reverse());var i=Math.floor(n[1].time/GE)-Math.floor(n[0].time/GE)+1,r=new Date(n[0].time),o=r.getDate(),a=n[1].date.getDate();r.setDate(o+i-1);var s=r.getDate();if(s!==a)for(var l=r.getTime()-n[1].time>0?1:-1;(s=r.getDate())!==a&&(r.getTime()-n[1].time)*l>0;)i-=l,r.setDate(s-l);var u=Math.floor((i+n[0].day+6)/7),h=e?1-u:u-1;return e&&n.reverse(),{range:[n[0].formatedDate,n[1].formatedDate],start:n[0],end:n[1],allDay:i,weeks:u,nthWeek:h,fweek:n[0].day,lweek:n[1].day}},t.prototype._getDateByWeeksAndDay=function(t,e,n){var i=this._getRangeInfo(n);if(t>i.weeks||0===t&&ei.lweek)return null;var r=7*(t-1)-i.fweek+e,o=new Date(i.start.time);return o.setDate(+i.start.d+r),this.getDateInfo(o)},t.create=function(e,n){var i=[];return e.eachComponent("calendar",(function(r){var o=new t(r,e,n);i.push(o),r.coordinateSystem=o})),e.eachSeries((function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("calendarIndex")||0])})),i},t.dimensions=["time","value"],t}();function HE(t){var e=t.calendarModel,n=t.seriesModel;return e?e.coordinateSystem:n?n.coordinateSystem:null}function YE(t,e){var n;return E(e,(function(e){null!=t[e]&&"auto"!==t[e]&&(n=!0)})),n}var XE=["transition","enterFrom","leaveTo"],UE=XE.concat(["enterAnimation","updateAnimation","leaveAnimation"]);function ZE(t,e,n){if(n&&(!t[n]&&e[n]&&(t[n]={}),t=t[n],e=e[n]),t&&e)for(var i=n?XE:UE,r=0;r=0;l--){var p,d,f;if(f=null!=(d=Ro((p=n[l]).id,null))?r.get(d):null){var g=f.parent,y=(c=KE(g),{}),v=Lp(f,p,g===i?{width:o,height:a}:{width:c.width,height:c.height},null,{hv:p.hv,boundingMode:p.bounding},y);if(!KE(f).isNew&&v){for(var m=p.transition,x={},_=0;_=0)?x[b]=w:f[b]=w}vh(f,x,t,0)}else f.attr(y)}}},e.prototype._clear=function(){var t=this,e=this._elMap;e.each((function(n){tz(n,KE(n).option,e,t._lastGraphicModel)})),this._elMap=yt()},e.prototype.dispose=function(){this._clear()},e.type="graphic",e}(Ag);function JE(t){var e=_t(qE,t)?qE[t]:Lh(t);var n=new e({});return KE(n).type=t,n}function QE(t,e,n,i){var r=JE(n);return e.add(r),i.set(t,r),KE(r).id=t,KE(r).isNew=!0,r}function tz(t,e,n,i){t&&t.parent&&("group"===t.type&&t.traverse((function(t){tz(t,e,n,i)})),vR(t,e,i),n.removeKey(KE(t).id))}function ez(t,e,n,i){t.isGroup||E([["cursor",Da.prototype.cursor],["zlevel",i||0],["z",n||0],["z2",0]],(function(n){var i=n[0];_t(e,i)?t[i]=rt(e[i],n[1]):null==t[i]&&(t[i]=n[1])})),E(G(e),(function(n){if(0===n.indexOf("on")){var i=e[n];t[n]=X(i)?i:null}})),_t(e,"draggable")&&(t.draggable=e.draggable),null!=e.name&&(t.name=e.name),null!=e.id&&(t.id=e.id)}var nz=["x","y","radius","angle","single"],iz=["cartesian2d","polar","singleAxis"];function rz(t){return t+"Axis"}function oz(t,e){var n,i=yt(),r=[],o=yt();t.eachComponent({mainType:"dataZoom",query:e},(function(t){o.get(t.uid)||s(t)}));do{n=!1,t.eachComponent("dataZoom",a)}while(n);function a(t){!o.get(t.uid)&&function(t){var e=!1;return t.eachTargetAxis((function(t,n){var r=i.get(t);r&&r[n]&&(e=!0)})),e}(t)&&(s(t),n=!0)}function s(t){o.set(t.uid,!0),r.push(t),t.eachTargetAxis((function(t,e){(i.get(t)||i.set(t,[]))[e]=!0}))}return r}function az(t){var e=t.ecModel,n={infoList:[],infoMap:yt()};return t.eachTargetAxis((function(t,i){var r=e.getComponent(rz(t),i);if(r){var o=r.getCoordSysModel();if(o){var a=o.uid,s=n.infoMap.get(a);s||(s={model:o,axisModels:[]},n.infoList.push(s),n.infoMap.set(a,s)),s.axisModels.push(r)}}})),n}var sz=function(){function t(){this.indexList=[],this.indexMap=[]}return t.prototype.add=function(t){this.indexMap[t]||(this.indexList.push(t),this.indexMap[t]=!0)},t}(),lz=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._autoThrottle=!0,n._noTarget=!0,n._rangePropMode=["percent","percent"],n}return n(e,t),e.prototype.init=function(t,e,n){var i=uz(t);this.settledOption=i,this.mergeDefaultAndTheme(t,n),this._doInit(i)},e.prototype.mergeOption=function(t){var e=uz(t);C(this.option,t,!0),C(this.settledOption,e,!0),this._doInit(e)},e.prototype._doInit=function(t){var e=this.option;this._setDefaultThrottle(t),this._updateRangeUse(t);var n=this.settledOption;E([["start","startValue"],["end","endValue"]],(function(t,i){"value"===this._rangePropMode[i]&&(e[t[0]]=n[t[0]]=null)}),this),this._resetTarget()},e.prototype._resetTarget=function(){var t=this.get("orient",!0),e=this._targetAxisInfoMap=yt();this._fillSpecifiedTargetAxis(e)?this._orient=t||this._makeAutoOrientByTargetAxis():(this._orient=t||"horizontal",this._fillAutoTargetAxisByOrient(e,this._orient)),this._noTarget=!0,e.each((function(t){t.indexList.length&&(this._noTarget=!1)}),this)},e.prototype._fillSpecifiedTargetAxis=function(t){var e=!1;return E(nz,(function(n){var i=this.getReferringComponents(rz(n),Ho);if(i.specified){e=!0;var r=new sz;E(i.models,(function(t){r.add(t.componentIndex)})),t.set(n,r)}}),this),e},e.prototype._fillAutoTargetAxisByOrient=function(t,e){var n=this.ecModel,i=!0;if(i){var r="vertical"===e?"y":"x";o(n.findComponents({mainType:r+"Axis"}),r)}i&&o(n.findComponents({mainType:"singleAxis",filter:function(t){return t.get("orient",!0)===e}}),"single");function o(e,n){var r=e[0];if(r){var o=new sz;if(o.add(r.componentIndex),t.set(n,o),i=!1,"x"===n||"y"===n){var a=r.getReferringComponents("grid",Wo).models[0];a&&E(e,(function(t){r.componentIndex!==t.componentIndex&&a===t.getReferringComponents("grid",Wo).models[0]&&o.add(t.componentIndex)}))}}}i&&E(nz,(function(e){if(i){var r=n.findComponents({mainType:rz(e),filter:function(t){return"category"===t.get("type",!0)}});if(r[0]){var o=new sz;o.add(r[0].componentIndex),t.set(e,o),i=!1}}}),this)},e.prototype._makeAutoOrientByTargetAxis=function(){var t;return this.eachTargetAxis((function(e){!t&&(t=e)}),this),"y"===t?"vertical":"horizontal"},e.prototype._setDefaultThrottle=function(t){if(t.hasOwnProperty("throttle")&&(this._autoThrottle=!1),this._autoThrottle){var e=this.ecModel.option;this.option.throttle=e.animation&&e.animationDurationUpdate>0?100:20}},e.prototype._updateRangeUse=function(t){var e=this._rangePropMode,n=this.get("rangeMode");E([["start","startValue"],["end","endValue"]],(function(i,r){var o=null!=t[i[0]],a=null!=t[i[1]];o&&!a?e[r]="percent":!o&&a?e[r]="value":n?e[r]=n[r]:o&&(e[r]="percent")}))},e.prototype.noTarget=function(){return this._noTarget},e.prototype.getFirstTargetAxisModel=function(){var t;return this.eachTargetAxis((function(e,n){null==t&&(t=this.ecModel.getComponent(rz(e),n))}),this),t},e.prototype.eachTargetAxis=function(t,e){this._targetAxisInfoMap.each((function(n,i){E(n.indexList,(function(n){t.call(e,i,n)}))}))},e.prototype.getAxisProxy=function(t,e){var n=this.getAxisModel(t,e);if(n)return n.__dzAxisProxy},e.prototype.getAxisModel=function(t,e){var n=this._targetAxisInfoMap.get(t);if(n&&n.indexMap[e])return this.ecModel.getComponent(rz(t),e)},e.prototype.setRawRange=function(t){var e=this.option,n=this.settledOption;E([["start","startValue"],["end","endValue"]],(function(i){null==t[i[0]]&&null==t[i[1]]||(e[i[0]]=n[i[0]]=t[i[0]],e[i[1]]=n[i[1]]=t[i[1]])}),this),this._updateRangeUse(t)},e.prototype.setCalculatedRange=function(t){var e=this.option;E(["start","startValue","end","endValue"],(function(n){e[n]=t[n]}))},e.prototype.getPercentRange=function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},e.prototype.getValueRange=function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var n=this.findRepresentativeAxisProxy();return n?n.getDataValueWindow():void 0},e.prototype.findRepresentativeAxisProxy=function(t){if(t)return t.__dzAxisProxy;for(var e,n=this._targetAxisInfoMap.keys(),i=0;i=0}(e)){var n=rz(this._dimName),i=e.getReferringComponents(n,Wo).models[0];i&&this._axisIndex===i.componentIndex&&t.push(e)}}),this),t},t.prototype.getAxisModel=function(){return this.ecModel.getComponent(this._dimName+"Axis",this._axisIndex)},t.prototype.getMinMaxSpan=function(){return T(this._minMaxSpan)},t.prototype.calculateDataWindow=function(t){var e,n=this._dataExtent,i=this.getAxisModel().axis.scale,r=this._dataZoomModel.getRangePropMode(),o=[0,100],a=[],s=[];dz(["start","end"],(function(l,u){var h=t[l],c=t[l+"Value"];"percent"===r[u]?(null==h&&(h=o[u]),c=i.parse(Kr(h,o,n))):(e=!0,h=Kr(c=null==c?n[u]:i.parse(c),n,o)),s[u]=null==c||isNaN(c)?n[u]:c,a[u]=null==h||isNaN(h)?o[u]:h})),fz(s),fz(a);var l=this._minMaxSpan;function u(t,e,n,r,o){var a=o?"Span":"ValueSpan";zk(0,t,n,"all",l["min"+a],l["max"+a]);for(var s=0;s<2;s++)e[s]=Kr(t[s],n,r,!0),o&&(e[s]=i.parse(e[s]))}return e?u(s,a,n,o,!1):u(a,s,o,n,!0),{valueWindow:s,percentWindow:a}},t.prototype.reset=function(t){if(t===this._dataZoomModel){var e=this.getTargetSeriesModels();this._dataExtent=function(t,e,n){var i=[1/0,-1/0];dz(n,(function(t){!function(t,e,n){e&&E(C_(e,n),(function(n){var i=e.getApproximateExtent(n);i[0]t[1]&&(t[1]=i[1])}))}(i,t.getData(),e)}));var r=t.getAxisModel(),o=v_(r.axis.scale,r,i).calculate();return[o.min,o.max]}(this,this._dimName,e),this._updateMinMaxSpan();var n=this.calculateDataWindow(t.settledOption);this._valueWindow=n.valueWindow,this._percentWindow=n.percentWindow,this._setAxisModel()}},t.prototype.filterData=function(t,e){if(t===this._dataZoomModel){var n=this._dimName,i=this.getTargetSeriesModels(),r=t.get("filterMode"),o=this._valueWindow;"none"!==r&&dz(i,(function(t){var e=t.getData(),i=e.mapDimensionsAll(n);if(i.length){if("weakFilter"===r){var a=e.getStore(),s=z(i,(function(t){return e.getDimensionIndex(t)}),e);e.filterSelf((function(t){for(var e,n,r,l=0;lo[1];if(h&&!c&&!p)return!0;h&&(r=!0),c&&(e=!0),p&&(n=!0)}return r&&e&&n}))}else dz(i,(function(n){if("empty"===r)t.setData(e=e.map(n,(function(t){return function(t){return t>=o[0]&&t<=o[1]}(t)?t:NaN})));else{var i={};i[n]=o,e.selectRange(i)}}));dz(i,(function(t){e.setApproximateExtent(o,t)}))}}))}},t.prototype._updateMinMaxSpan=function(){var t=this._minMaxSpan={},e=this._dataZoomModel,n=this._dataExtent;dz(["min","max"],(function(i){var r=e.get(i+"Span"),o=e.get(i+"ValueSpan");null!=o&&(o=this.getAxisModel().axis.scale.parse(o)),null!=o?r=Kr(n[0]+o,n,[0,100],!0):null!=r&&(o=Kr(r,[0,100],n,!0)-n[0]),t[i+"Span"]=r,t[i+"ValueSpan"]=o}),this)},t.prototype._setAxisModel=function(){var t=this.getAxisModel(),e=this._percentWindow,n=this._valueWindow;if(e){var i=no(n,[0,500]);i=Math.min(i,20);var r=t.axis.scale.rawExtentInfo;0!==e[0]&&r.setDeterminedMinMax("min",+n[0].toFixed(i)),100!==e[1]&&r.setDeterminedMinMax("max",+n[1].toFixed(i)),r.freeze()}},t}();var yz={getTargetSeries:function(t){function e(e){t.eachComponent("dataZoom",(function(n){n.eachTargetAxis((function(i,r){var o=t.getComponent(rz(i),r);e(i,r,o,n)}))}))}e((function(t,e,n,i){n.__dzAxisProxy=null}));var n=[];e((function(e,i,r,o){r.__dzAxisProxy||(r.__dzAxisProxy=new gz(e,i,o,t),n.push(r.__dzAxisProxy))}));var i=yt();return E(n,(function(t){E(t.getTargetSeriesModels(),(function(t){i.set(t.uid,t)}))})),i},overallReset:function(t,e){t.eachComponent("dataZoom",(function(t){t.eachTargetAxis((function(e,n){t.getAxisProxy(e,n).reset(t)})),t.eachTargetAxis((function(n,i){t.getAxisProxy(n,i).filterData(t,e)}))})),t.eachComponent("dataZoom",(function(t){var e=t.findRepresentativeAxisProxy();if(e){var n=e.getDataPercentWindow(),i=e.getDataValueWindow();t.setCalculatedRange({start:n[0],end:n[1],startValue:i[0],endValue:i[1]})}}))}};var vz=!1;function mz(t){vz||(vz=!0,t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,yz),function(t){t.registerAction("dataZoom",(function(t,e){E(oz(e,t),(function(e){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})}))}))}(t),t.registerSubTypeDefaulter("dataZoom",(function(){return"slider"})))}function xz(t){t.registerComponentModel(hz),t.registerComponentView(pz),mz(t)}var _z=function(){},bz={};function wz(t,e){bz[t]=e}function Sz(t){return bz[t]}var Mz=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(){t.prototype.optionUpdated.apply(this,arguments);var e=this.ecModel;E(this.option.feature,(function(t,n){var i=Sz(n);i&&(i.getDefaultOption&&(i.defaultOption=i.getDefaultOption(e)),C(t,i.defaultOption))}))},e.type="toolbox",e.layoutMode={type:"box",ignoreSize:!0},e.defaultOption={show:!0,z:6,orient:"horizontal",left:"right",top:"top",backgroundColor:"transparent",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemSize:15,itemGap:8,showTitle:!0,iconStyle:{borderColor:"#666",color:"none"},emphasis:{iconStyle:{borderColor:"#3E98C5"}},tooltip:{show:!1,position:"bottom"}},e}(zp);function Iz(t,e){var n=vp(e.get("padding")),i=e.getItemStyle(["color","opacity"]);return i.fill=e.get("backgroundColor"),t=new Ws({shape:{x:t.x-n[3],y:t.y-n[0],width:t.width+n[1]+n[3],height:t.height+n[0]+n[2],r:e.get("borderRadius")},style:i,silent:!0,z2:-1})}var Tz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n,i){var r=this.group;if(r.removeAll(),t.get("show")){var o=+t.get("itemSize"),a="vertical"===t.get("orient"),s=t.get("feature")||{},l=this._features||(this._features={}),u=[];E(s,(function(t,e){u.push(e)})),new Gm(this._featureNames||[],u).add(h).update(h).remove(H(h,null)).execute(),this._featureNames=u,function(t,e,n){var i=e.getBoxLayoutParams(),r=e.get("padding"),o={width:n.getWidth(),height:n.getHeight()},a=kp(i,o,r);Ap(e.get("orient"),t,e.get("itemGap"),a.width,a.height),Lp(t,i,o,r)}(r,t,n),r.add(Iz(r.getBoundingRect(),t)),a||r.eachChild((function(t){var e=t.__title,i=t.ensureState("emphasis"),a=i.textConfig||(i.textConfig={}),s=t.getTextContent(),l=s&&s.ensureState("emphasis");if(l&&!X(l)&&e){var u=l.style||(l.style={}),h=Sr(e,Xs.makeFont(u)),c=t.x+r.x,p=!1;t.y+r.y+o+h.height>n.getHeight()&&(a.position="top",p=!0);var d=p?-5-h.height:o+10;c+h.width/2>n.getWidth()?(a.position=["100%",d],u.align="right"):c-h.width/2<0&&(a.position=[0,d],u.align="left")}}))}function h(h,c){var p,d=u[h],f=u[c],g=s[d],y=new Cc(g,t,t.ecModel);if(i&&null!=i.newTitle&&i.featureName===d&&(g.title=i.newTitle),d&&!f){if(function(t){return 0===t.indexOf("my")}(d))p={onclick:y.option.onclick,featureName:d};else{var v=Sz(d);if(!v)return;p=new v}l[d]=p}else if(!(p=l[f]))return;p.uid=Ac("toolbox-feature"),p.model=y,p.ecModel=e,p.api=n;var m=p instanceof _z;d||!f?!y.get("show")||m&&p.unusable?m&&p.remove&&p.remove(e,n):(!function(i,s,l){var u,h,c=i.getModel("iconStyle"),p=i.getModel(["emphasis","iconStyle"]),d=s instanceof _z&&s.getIcons?s.getIcons():i.get("icon"),f=i.get("title")||{};U(d)?(u={})[l]=d:u=d;U(f)?(h={})[l]=f:h=f;var g=i.iconPaths={};E(u,(function(l,u){var d=Uh(l,{},{x:-o/2,y:-o/2,width:o,height:o});d.setStyle(c.getItemStyle()),d.ensureState("emphasis").style=p.getItemStyle();var f=new Xs({style:{text:h[u],align:p.get("textAlign"),borderRadius:p.get("textBorderRadius"),padding:p.get("textPadding"),fill:null,font:cc({fontStyle:p.get("textFontStyle"),fontFamily:p.get("textFontFamily"),fontSize:p.get("textFontSize"),fontWeight:p.get("textFontWeight")},e)},ignore:!0});d.setTextContent(f),Kh({el:d,componentModel:t,itemName:u,formatterParamsExtra:{title:h[u]}}),d.__title=h[u],d.on("mouseover",(function(){var e=p.getItemStyle(),i=a?null==t.get("right")&&"right"!==t.get("left")?"right":"left":null==t.get("bottom")&&"bottom"!==t.get("top")?"bottom":"top";f.setStyle({fill:p.get("textFill")||e.fill||e.stroke||"#000",backgroundColor:p.get("textBackgroundColor")}),d.setTextConfig({position:p.get("textPosition")||i}),f.ignore=!t.get("showTitle"),n.enterEmphasis(this)})).on("mouseout",(function(){"emphasis"!==i.get(["iconStatus",u])&&n.leaveEmphasis(this),f.hide()})),("emphasis"===i.get(["iconStatus",u])?Ol:Rl)(d),r.add(d),d.on("click",W(s.onclick,s,e,n,u)),g[u]=d}))}(y,p,d),y.setIconStatus=function(t,e){var n=this.option,i=this.iconPaths;n.iconStatus=n.iconStatus||{},n.iconStatus[t]=e,i[t]&&("emphasis"===e?Ol:Rl)(i[t])},p instanceof _z&&p.render&&p.render(y,e,n,i)):m&&p.dispose&&p.dispose(e,n)}},e.prototype.updateView=function(t,e,n,i){E(this._features,(function(t){t instanceof _z&&t.updateView&&t.updateView(t.model,e,n,i)}))},e.prototype.remove=function(t,e){E(this._features,(function(n){n instanceof _z&&n.remove&&n.remove(t,e)})),this.group.removeAll()},e.prototype.dispose=function(t,e){E(this._features,(function(n){n instanceof _z&&n.dispose&&n.dispose(t,e)}))},e.type="toolbox",e}(Ag);var Cz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.onclick=function(t,e){var n=this.model,i=n.get("name")||t.get("title.0.text")||"echarts",o="svg"===e.getZr().painter.getType(),a=o?"svg":n.get("type",!0)||"png",s=e.getConnectedDataURL({type:a,backgroundColor:n.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",connectedBackgroundColor:n.get("connectedBackgroundColor"),excludeComponents:n.get("excludeComponents"),pixelRatio:n.get("pixelRatio")}),l=r.browser;if("function"!=typeof MouseEvent||!l.newEdge&&(l.ie||l.edge))if(window.navigator.msSaveOrOpenBlob||o){var u=s.split(","),h=u[0].indexOf("base64")>-1,c=o?decodeURIComponent(u[1]):u[1];h&&(c=window.atob(c));var p=i+"."+a;if(window.navigator.msSaveOrOpenBlob){for(var d=c.length,f=new Uint8Array(d);d--;)f[d]=c.charCodeAt(d);var g=new Blob([f]);window.navigator.msSaveOrOpenBlob(g,p)}else{var y=document.createElement("iframe");document.body.appendChild(y);var v=y.contentWindow,m=v.document;m.open("image/svg+xml","replace"),m.write(c),m.close(),v.focus(),m.execCommand("SaveAs",!0,p),document.body.removeChild(y)}}else{var x=n.get("lang"),_='',b=window.open();b.document.write(_),b.document.title=i}else{var w=document.createElement("a");w.download=i+"."+a,w.target="_blank",w.href=s;var S=new MouseEvent("click",{view:document.defaultView,bubbles:!0,cancelable:!1});w.dispatchEvent(S)}},e.getDefaultOption=function(t){return{show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:t.getLocaleModel().get(["toolbox","saveAsImage","title"]),type:"png",connectedBackgroundColor:"#fff",name:"",excludeComponents:["toolbox"],lang:t.getLocaleModel().get(["toolbox","saveAsImage","lang"])}},e}(_z),Dz="__ec_magicType_stack__",Az=[["line","bar"],["stack"]],kz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getIcons=function(){var t=this.model,e=t.get("icon"),n={};return E(t.get("type"),(function(t){e[t]&&(n[t]=e[t])})),n},e.getDefaultOption=function(t){return{show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z"},title:t.getLocaleModel().get(["toolbox","magicType","title"]),option:{},seriesIndex:{}}},e.prototype.onclick=function(t,e,n){var i=this.model,r=i.get(["seriesIndex",n]);if(Lz[n]){var o,a={series:[]};E(Az,(function(t){P(t,n)>=0&&E(t,(function(t){i.setIconStatus(t,"normal")}))})),i.setIconStatus(n,"emphasis"),t.eachComponent({mainType:"series",query:null==r?null:{seriesIndex:r}},(function(t){var e=t.subType,r=t.id,o=Lz[n](e,r,t,i);o&&(k(o,t.option),a.series.push(o));var s=t.coordinateSystem;if(s&&"cartesian2d"===s.type&&("line"===n||"bar"===n)){var l=s.getAxesByScale("ordinal")[0];if(l){var u=l.dim+"Axis",h=t.getReferringComponents(u,Wo).models[0].componentIndex;a[u]=a[u]||[];for(var c=0;c<=h;c++)a[u][h]=a[u][h]||{};a[u][h].boundaryGap="bar"===n}}}));var s=n;"stack"===n&&(o=C({stack:i.option.title.tiled,tiled:i.option.title.stack},i.option.title),"emphasis"!==i.get(["iconStatus",n])&&(s="tiled")),e.dispatchAction({type:"changeMagicType",currentType:s,newOption:a,newTitle:o,featureName:"magicType"})}},e}(_z),Lz={line:function(t,e,n,i){if("bar"===t)return C({id:e,type:"line",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},i.get(["option","line"])||{},!0)},bar:function(t,e,n,i){if("line"===t)return C({id:e,type:"bar",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},i.get(["option","bar"])||{},!0)},stack:function(t,e,n,i){var r=n.get("stack")===Dz;if("line"===t||"bar"===t)return i.setIconStatus("stack",r?"normal":"emphasis"),C({id:e,stack:r?"":Dz},i.get(["option","stack"])||{},!0)}};Cm({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},(function(t,e){e.mergeOption(t.newOption)}));var Pz=new Array(60).join("-"),Oz="\t";function Rz(t){return t.replace(/^\s\s*/,"").replace(/\s\s*$/,"")}var Nz=new RegExp("[\t]+","g");function Ez(t,e){var n=t.split(new RegExp("\n*"+Pz+"\n*","g")),i={series:[]};return E(n,(function(t,n){if(function(t){if(t.slice(0,t.indexOf("\n")).indexOf(Oz)>=0)return!0}(t)){var r=function(t){for(var e=t.split(/\n+/g),n=[],i=z(Rz(e.shift()).split(Nz),(function(t){return{name:t,data:[]}})),r=0;r=0)&&t(r,i._targetInfoList)}))}return t.prototype.setOutputRanges=function(t,e){return this.matchOutputRanges(t,e,(function(t,e,n){if((t.coordRanges||(t.coordRanges=[])).push(e),!t.coordRange){t.coordRange=e;var i=Kz[t.brushType](0,n,e);t.__rangeOffset={offset:Jz[t.brushType](i.values,t.range,[1,1]),xyMinMax:i.xyMinMax}}})),t},t.prototype.matchOutputRanges=function(t,e,n){E(t,(function(t){var i=this.findTargetInfo(t,e);i&&!0!==i&&E(i.coordSyses,(function(i){var r=Kz[t.brushType](1,i,t.range,!0);n(t,r.values,i,e)}))}),this)},t.prototype.setInputRanges=function(t,e){E(t,(function(t){var n,i,r,o,a,s=this.findTargetInfo(t,e);if(t.range=t.range||[],s&&!0!==s){t.panelId=s.panelId;var l=Kz[t.brushType](0,s.coordSys,t.coordRange),u=t.__rangeOffset;t.range=u?Jz[t.brushType](l.values,u.offset,(n=l.xyMinMax,i=u.xyMinMax,r=tV(n),o=tV(i),a=[r[0]/o[0],r[1]/o[1]],isNaN(a[0])&&(a[0]=1),isNaN(a[1])&&(a[1]=1),a)):l.values}}),this)},t.prototype.makePanelOpts=function(t,e){return z(this._targetInfoList,(function(n){var i=n.getPanelRect();return{panelId:n.panelId,defaultBrushType:e?e(n):null,clipPath:BL(i),isTargetByCursor:GL(i,t,n.coordSysModel),getLinearBrushOtherExtent:FL(i)}}))},t.prototype.controlSeries=function(t,e,n){var i=this.findTargetInfo(t,n);return!0===i||i&&P(i.coordSyses,e.coordinateSystem)>=0},t.prototype.findTargetInfo=function(t,e){for(var n=this._targetInfoList,i=Uz(e,t),r=0;rt[1]&&t.reverse(),t}function Uz(t,e){return Fo(t,e,{includeMainTypes:Hz})}var Zz={grid:function(t,e){var n=t.xAxisModels,i=t.yAxisModels,r=t.gridModels,o=yt(),a={},s={};(n||i||r)&&(E(n,(function(t){var e=t.axis.grid.model;o.set(e.id,e),a[e.id]=!0})),E(i,(function(t){var e=t.axis.grid.model;o.set(e.id,e),s[e.id]=!0})),E(r,(function(t){o.set(t.id,t),a[t.id]=!0,s[t.id]=!0})),o.each((function(t){var r=t.coordinateSystem,o=[];E(r.getCartesians(),(function(t,e){(P(n,t.getAxis("x").model)>=0||P(i,t.getAxis("y").model)>=0)&&o.push(t)})),e.push({panelId:"grid--"+t.id,gridModel:t,coordSysModel:t,coordSys:o[0],coordSyses:o,getPanelRect:qz.grid,xAxisDeclared:a[t.id],yAxisDeclared:s[t.id]})})))},geo:function(t,e){E(t.geoModels,(function(t){var n=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:n,coordSyses:[n],getPanelRect:qz.geo})}))}},jz=[function(t,e){var n=t.xAxisModel,i=t.yAxisModel,r=t.gridModel;return!r&&n&&(r=n.axis.grid.model),!r&&i&&(r=i.axis.grid.model),r&&r===e.gridModel},function(t,e){var n=t.geoModel;return n&&n===e.geoModel}],qz={grid:function(){return this.coordSys.master.getRect().clone()},geo:function(){var t=this.coordSys,e=t.getBoundingRect().clone();return e.applyTransform(Bh(t)),e}},Kz={lineX:H($z,0),lineY:H($z,1),rect:function(t,e,n,i){var r=t?e.pointToData([n[0][0],n[1][0]],i):e.dataToPoint([n[0][0],n[1][0]],i),o=t?e.pointToData([n[0][1],n[1][1]],i):e.dataToPoint([n[0][1],n[1][1]],i),a=[Xz([r[0],o[0]]),Xz([r[1],o[1]])];return{values:a,xyMinMax:a}},polygon:function(t,e,n,i){var r=[[1/0,-1/0],[1/0,-1/0]];return{values:z(n,(function(n){var o=t?e.pointToData(n,i):e.dataToPoint(n,i);return r[0][0]=Math.min(r[0][0],o[0]),r[1][0]=Math.min(r[1][0],o[1]),r[0][1]=Math.max(r[0][1],o[0]),r[1][1]=Math.max(r[1][1],o[1]),o})),xyMinMax:r}}};function $z(t,e,n,i){var r=n.getAxis(["x","y"][t]),o=Xz(z([0,1],(function(t){return e?r.coordToData(r.toLocalCoord(i[t]),!0):r.toGlobalCoord(r.dataToCoord(i[t]))}))),a=[];return a[t]=o,a[1-t]=[NaN,NaN],{values:o,xyMinMax:a}}var Jz={lineX:H(Qz,0),lineY:H(Qz,1),rect:function(t,e,n){return[[t[0][0]-n[0]*e[0][0],t[0][1]-n[0]*e[0][1]],[t[1][0]-n[1]*e[1][0],t[1][1]-n[1]*e[1][1]]]},polygon:function(t,e,n){return z(t,(function(t,i){return[t[0]-n[0]*e[i][0],t[1]-n[1]*e[i][1]]}))}};function Qz(t,e,n,i){return[e[0]-i[t]*n[0],e[1]-i[t]*n[1]]}function tV(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}var eV,nV,iV=E,rV=Io+"toolbox-dataZoom_",oV=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n,i){this._brushController||(this._brushController=new lL(n.getZr()),this._brushController.on("brush",W(this._onBrush,this)).mount()),function(t,e,n,i,r){var o=n._isZoomActive;i&&"takeGlobalCursor"===i.type&&(o="dataZoomSelect"===i.key&&i.dataZoomSelectActive);n._isZoomActive=o,t.setIconStatus("zoom",o?"emphasis":"normal");var a=new Yz(sV(t),e,{include:["grid"]}),s=a.makePanelOpts(r,(function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"}));n._brushController.setPanels(s).enableBrush(!(!o||!s.length)&&{brushType:"auto",brushStyle:t.getModel("brushStyle").getItemStyle()})}(t,e,this,i,n),function(t,e){t.setIconStatus("back",function(t){return Gz(t).length}(e)>1?"emphasis":"normal")}(t,e)},e.prototype.onclick=function(t,e,n){aV[n].call(this)},e.prototype.remove=function(t,e){this._brushController&&this._brushController.unmount()},e.prototype.dispose=function(t,e){this._brushController&&this._brushController.dispose()},e.prototype._onBrush=function(t){var e=t.areas;if(t.isEnd&&e.length){var n={},i=this.ecModel;this._brushController.updateCovers([]),new Yz(sV(this.model),i,{include:["grid"]}).matchOutputRanges(e,i,(function(t,e,n){if("cartesian2d"===n.type){var i=t.brushType;"rect"===i?(r("x",n,e[0]),r("y",n,e[1])):r({lineX:"x",lineY:"y"}[i],n,e)}})),function(t,e){var n=Gz(t);Bz(e,(function(e,i){for(var r=n.length-1;r>=0&&!n[r][i];r--);if(r<0){var o=t.queryComponents({mainType:"dataZoom",subType:"select",id:i})[0];if(o){var a=o.getPercentRange();n[0][i]={dataZoomId:i,start:a[0],end:a[1]}}}})),n.push(e)}(i,n),this._dispatchZoomAction(n)}function r(t,e,r){var o=e.getAxis(t),a=o.model,s=function(t,e,n){var i;return n.eachComponent({mainType:"dataZoom",subType:"select"},(function(n){n.getAxisModel(t,e.componentIndex)&&(i=n)})),i}(t,a,i),l=s.findRepresentativeAxisProxy(a).getMinMaxSpan();null==l.minValueSpan&&null==l.maxValueSpan||(r=zk(0,r.slice(),o.scale.getExtent(),0,l.minValueSpan,l.maxValueSpan)),s&&(n[s.id]={dataZoomId:s.id,startValue:r[0],endValue:r[1]})}},e.prototype._dispatchZoomAction=function(t){var e=[];iV(t,(function(t,n){e.push(T(t))})),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},e.getDefaultOption=function(t){return{show:!0,filterMode:"filter",icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:t.getLocaleModel().get(["toolbox","dataZoom","title"]),brushStyle:{borderWidth:0,color:"rgba(210,219,238,0.2)"}}},e}(_z),aV={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(function(t){var e=Gz(t),n=e[e.length-1];e.length>1&&e.pop();var i={};return Bz(n,(function(t,n){for(var r=e.length-1;r>=0;r--)if(t=e[r][n]){i[n]=t;break}})),i}(this.ecModel))}};function sV(t){var e={xAxisIndex:t.get("xAxisIndex",!0),yAxisIndex:t.get("yAxisIndex",!0),xAxisId:t.get("xAxisId",!0),yAxisId:t.get("yAxisId",!0)};return null==e.xAxisIndex&&null==e.xAxisId&&(e.xAxisIndex="all"),null==e.yAxisIndex&&null==e.yAxisId&&(e.yAxisIndex="all"),e}eV="dataZoom",nV=function(t){var e=t.getComponent("toolbox",0),n=["feature","dataZoom"];if(e&&null!=e.get(n)){var i=e.getModel(n),r=[],o=Fo(t,sV(i));return iV(o.xAxisModels,(function(t){return a(t,"xAxis","xAxisIndex")})),iV(o.yAxisModels,(function(t){return a(t,"yAxis","yAxisIndex")})),r}function a(t,e,n){var o=t.componentIndex,a={type:"select",$fromToolbox:!0,filterMode:i.get("filterMode",!0)||"filter",id:rV+e+o};a[n]=o,r.push(a)}},lt(null==od.get(eV)&&nV),od.set(eV,nV);var lV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="tooltip",e.dependencies=["axisPointer"],e.defaultOption={z:60,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove|click",alwaysShowContent:!1,displayMode:"single",renderMode:"auto",confine:null,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"#fff",shadowBlur:10,shadowColor:"rgba(0, 0, 0, .2)",shadowOffsetX:1,shadowOffsetY:2,borderRadius:4,borderWidth:1,padding:null,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:"auto",animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",crossStyle:{color:"#999",width:1,type:"dashed",textStyle:{}}},textStyle:{color:"#666",fontSize:14}},e}(zp);function uV(t){var e=t.get("confine");return null!=e?!!e:"richText"===t.get("renderMode")}function hV(t){if(r.domSupported)for(var e=document.documentElement.style,n=0,i=t.length;n-1?(u+="top:50%",h+="translateY(-50%) rotate("+(a="left"===s?-225:-45)+"deg)"):(u+="left:50%",h+="translateX(-50%) rotate("+(a="top"===s?225:45)+"deg)");var c=a*Math.PI/180,p=l+r,d=p*Math.abs(Math.cos(c))+p*Math.abs(Math.sin(c)),f=e+" solid "+r+"px;";return'
'}(n,i,r)),U(t))o.innerHTML=t+a;else if(t){o.innerHTML="",Y(t)||(t=[t]);for(var s=0;s=0?this._tryShow(n,i):"leave"===e&&this._hide(i))}),this))},e.prototype._keepShow=function(){var t=this._tooltipModel,e=this._ecModel,n=this._api,i=t.get("triggerOn");if(null!=this._lastX&&null!=this._lastY&&"none"!==i&&"click"!==i){var r=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout((function(){!n.isDisposed()&&r.manuallyShowTip(t,e,n,{x:r._lastX,y:r._lastY,dataByCoordSys:r._lastDataByCoordSys})}))}},e.prototype.manuallyShowTip=function(t,e,n,i){if(i.from!==this.uid&&!r.node&&n.getDom()){var o=CV(i,n);this._ticket="";var a=i.dataByCoordSys,s=function(t,e,n){var i=Go(t).queryOptionMap,r=i.keys()[0];if(!r||"series"===r)return;var o=Yo(e,r,i.get(r),{useDefault:!1,enableAll:!1,enableNone:!1}),a=o.models[0];if(!a)return;var s,l=n.getViewOfComponentModel(a);if(l.group.traverse((function(e){var n=rl(e).tooltipConfig;if(n&&n.name===t.name)return s=e,!0})),s)return{componentMainType:r,componentIndex:a.componentIndex,el:s}}(i,e,n);if(s){var l=s.el.getBoundingRect().clone();l.applyTransform(s.el.transform),this._tryShow({offsetX:l.x+l.width/2,offsetY:l.y+l.height/2,target:s.el,position:i.position,positionDefault:"bottom"},o)}else if(i.tooltip&&null!=i.x&&null!=i.y){var u=MV;u.x=i.x,u.y=i.y,u.update(),rl(u).tooltipConfig={name:null,option:i.tooltip},this._tryShow({offsetX:i.x,offsetY:i.y,target:u},o)}else if(a)this._tryShow({offsetX:i.x,offsetY:i.y,position:i.position,dataByCoordSys:a,tooltipOption:i.tooltipOption},o);else if(null!=i.seriesIndex){if(this._manuallyAxisShowTip(t,e,n,i))return;var h=RN(i,e),c=h.point[0],p=h.point[1];null!=c&&null!=p&&this._tryShow({offsetX:c,offsetY:p,target:h.el,position:i.position,positionDefault:"bottom"},o)}else null!=i.x&&null!=i.y&&(n.dispatchAction({type:"updateAxisPointer",x:i.x,y:i.y}),this._tryShow({offsetX:i.x,offsetY:i.y,position:i.position,target:n.getZr().findHover(i.x,i.y).target},o))}},e.prototype.manuallyHideTip=function(t,e,n,i){var r=this._tooltipContent;this._tooltipModel&&r.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=this._lastDataByCoordSys=null,i.from!==this.uid&&this._hide(CV(i,n))},e.prototype._manuallyAxisShowTip=function(t,e,n,i){var r=i.seriesIndex,o=i.dataIndex,a=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=r&&null!=o&&null!=a){var s=e.getSeriesByIndex(r);if(s)if("axis"===TV([s.getData().getItemModel(o),s,(s.coordinateSystem||{}).model],this._tooltipModel).get("trigger"))return n.dispatchAction({type:"updateAxisPointer",seriesIndex:r,dataIndex:o,position:i.position}),!0}},e.prototype._tryShow=function(t,e){var n=t.target;if(this._tooltipModel){this._lastX=t.offsetX,this._lastY=t.offsetY;var i=t.dataByCoordSys;if(i&&i.length)this._showAxisTooltip(i,t);else if(n){var r,o;if("legend"===rl(n).ssrType)return;this._lastDataByCoordSys=null,Oy(n,(function(t){return null!=rl(t).dataIndex?(r=t,!0):null!=rl(t).tooltipConfig?(o=t,!0):void 0}),!0),r?this._showSeriesItemTooltip(t,r,e):o?this._showComponentItemTooltip(t,o,e):this._hide(e)}else this._lastDataByCoordSys=null,this._hide(e)}},e.prototype._showOrMove=function(t,e){var n=t.get("showDelay");e=W(e,this),clearTimeout(this._showTimout),n>0?this._showTimout=setTimeout(e,n):e()},e.prototype._showAxisTooltip=function(t,e){var n=this._ecModel,i=this._tooltipModel,r=[e.offsetX,e.offsetY],o=TV([e.tooltipOption],i),a=this._renderMode,s=[],l=og("section",{blocks:[],noHeader:!0}),u=[],h=new yg;E(t,(function(t){E(t.dataByAxis,(function(t){var e=n.getComponent(t.axisDim+"Axis",t.axisIndex),r=t.value;if(e&&null!=r){var o=yN(r,e.axis,n,t.seriesDataIndices,t.valueLabelOpt),c=og("section",{header:o,noHeader:!ut(o),sortBlocks:!0,blocks:[]});l.blocks.push(c),E(t.seriesDataIndices,(function(l){var p=n.getSeriesByIndex(l.seriesIndex),d=l.dataIndexInside,f=p.getDataParams(d);if(!(f.dataIndex<0)){f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=S_(e.axis,{value:r}),f.axisValueLabel=o,f.marker=h.makeTooltipMarker("item",Sp(f.color),a);var g=bf(p.formatTooltip(d,!0,null)),y=g.frag;if(y){var v=TV([p],i).get("valueFormatter");c.blocks.push(v?A({valueFormatter:v},y):y)}g.text&&u.push(g.text),s.push(f)}}))}}))})),l.blocks.reverse(),u.reverse();var c=e.position,p=o.get("order"),d=cg(l,h,a,p,n.get("useUTC"),o.get("textStyle"));d&&u.unshift(d);var f="richText"===a?"\n\n":"
",g=u.join(f);this._showOrMove(o,(function(){this._updateContentNotChangedOnAxis(t,s)?this._updatePosition(o,c,r[0],r[1],this._tooltipContent,s):this._showTooltipContent(o,g,s,Math.random()+"",r[0],r[1],c,null,h)}))},e.prototype._showSeriesItemTooltip=function(t,e,n){var i=this._ecModel,r=rl(e),o=r.seriesIndex,a=i.getSeriesByIndex(o),s=r.dataModel||a,l=r.dataIndex,u=r.dataType,h=s.getData(u),c=this._renderMode,p=t.positionDefault,d=TV([h.getItemModel(l),s,a&&(a.coordinateSystem||{}).model],this._tooltipModel,p?{position:p}:null),f=d.get("trigger");if(null==f||"item"===f){var g=s.getDataParams(l,u),y=new yg;g.marker=y.makeTooltipMarker("item",Sp(g.color),c);var v=bf(s.formatTooltip(l,!1,u)),m=d.get("order"),x=d.get("valueFormatter"),_=v.frag,b=_?cg(x?A({valueFormatter:x},_):_,y,c,m,i.get("useUTC"),d.get("textStyle")):v.text,w="item_"+s.name+"_"+l;this._showOrMove(d,(function(){this._showTooltipContent(d,b,g,w,t.offsetX,t.offsetY,t.position,t.target,y)})),n({type:"showTip",dataIndexInside:l,dataIndex:h.getRawIndex(l),seriesIndex:o,from:this.uid})}},e.prototype._showComponentItemTooltip=function(t,e,n){var i="html"===this._renderMode,r=rl(e),o=r.tooltipConfig.option||{},a=o.encodeHTMLContent;if(U(o)){o={content:o,formatter:o},a=!0}a&&i&&o.content&&((o=T(o)).content=re(o.content));var s=[o],l=this._ecModel.getComponent(r.componentMainType,r.componentIndex);l&&s.push(l),s.push({formatter:o.content});var u=t.positionDefault,h=TV(s,this._tooltipModel,u?{position:u}:null),c=h.get("content"),p=Math.random()+"",d=new yg;this._showOrMove(h,(function(){var n=T(h.get("formatterParams")||{});this._showTooltipContent(h,c,n,p,t.offsetX,t.offsetY,t.position,e,d)})),n({type:"showTip",from:this.uid})},e.prototype._showTooltipContent=function(t,e,n,i,r,o,a,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent;u.setEnterable(t.get("enterable"));var h=t.get("formatter");a=a||t.get("position");var c=e,p=this._getNearestPoint([r,o],n,t.get("trigger"),t.get("borderColor")).color;if(h)if(U(h)){var d=t.ecModel.get("useUTC"),f=Y(n)?n[0]:n;c=h,f&&f.axisType&&f.axisType.indexOf("time")>=0&&(c=Jc(f.axisValue,c,d)),c=bp(c,n,!0)}else if(X(h)){var g=W((function(e,i){e===this._ticket&&(u.setContent(i,l,t,p,a),this._updatePosition(t,a,r,o,u,n,s))}),this);this._ticket=i,c=h(n,i,g)}else c=h;u.setContent(c,l,t,p,a),u.show(t,p),this._updatePosition(t,a,r,o,u,n,s)}},e.prototype._getNearestPoint=function(t,e,n,i){return"axis"===n||Y(e)?{color:i||("html"===this._renderMode?"#fff":"none")}:Y(e)?void 0:{color:i||e.color||e.borderColor}},e.prototype._updatePosition=function(t,e,n,i,r,o,a){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=r.getSize(),h=t.get("align"),c=t.get("verticalAlign"),p=a&&a.getBoundingRect().clone();if(a&&p.applyTransform(a.transform),X(e)&&(e=e([n,i],o,r.el,p,{viewSize:[s,l],contentSize:u.slice()})),Y(e))n=$r(e[0],s),i=$r(e[1],l);else if(q(e)){var d=e;d.width=u[0],d.height=u[1];var f=kp(d,{width:s,height:l});n=f.x,i=f.y,h=null,c=null}else if(U(e)&&a){var g=function(t,e,n,i){var r=n[0],o=n[1],a=Math.ceil(Math.SQRT2*i)+8,s=0,l=0,u=e.width,h=e.height;switch(t){case"inside":s=e.x+u/2-r/2,l=e.y+h/2-o/2;break;case"top":s=e.x+u/2-r/2,l=e.y-o-a;break;case"bottom":s=e.x+u/2-r/2,l=e.y+h+a;break;case"left":s=e.x-r-a,l=e.y+h/2-o/2;break;case"right":s=e.x+u+a,l=e.y+h/2-o/2}return[s,l]}(e,p,u,t.get("borderWidth"));n=g[0],i=g[1]}else{g=function(t,e,n,i,r,o,a){var s=n.getSize(),l=s[0],u=s[1];null!=o&&(t+l+o+2>i?t-=l+o:t+=o);null!=a&&(e+u+a>r?e-=u+a:e+=a);return[t,e]}(n,i,r,s,l,h?null:20,c?null:20);n=g[0],i=g[1]}if(h&&(n-=DV(h)?u[0]/2:"right"===h?u[0]:0),c&&(i-=DV(c)?u[1]/2:"bottom"===c?u[1]:0),uV(t)){g=function(t,e,n,i,r){var o=n.getSize(),a=o[0],s=o[1];return t=Math.min(t+a,i)-a,e=Math.min(e+s,r)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}(n,i,r,s,l);n=g[0],i=g[1]}r.moveTo(n,i)},e.prototype._updateContentNotChangedOnAxis=function(t,e){var n=this._lastDataByCoordSys,i=this._cbParamsList,r=!!n&&n.length===t.length;return r&&E(n,(function(n,o){var a=n.dataByAxis||[],s=(t[o]||{}).dataByAxis||[];(r=r&&a.length===s.length)&&E(a,(function(t,n){var o=s[n]||{},a=t.seriesDataIndices||[],l=o.seriesDataIndices||[];(r=r&&t.value===o.value&&t.axisType===o.axisType&&t.axisId===o.axisId&&a.length===l.length)&&E(a,(function(t,e){var n=l[e];r=r&&t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})),i&&E(t.seriesDataIndices,(function(t){var n=t.seriesIndex,o=e[n],a=i[n];o&&a&&a.data!==o.data&&(r=!1)}))}))})),this._lastDataByCoordSys=t,this._cbParamsList=e,!!r},e.prototype._hide=function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},e.prototype.dispose=function(t,e){!r.node&&e.getDom()&&(Yg(this,"_updatePosition"),this._tooltipContent.dispose(),PN("itemTooltip",e))},e.type="tooltip",e}(Ag);function TV(t,e,n){var i,r=e.ecModel;n?(i=new Cc(n,r,r),i=new Cc(e.option,i,r)):i=e;for(var o=t.length-1;o>=0;o--){var a=t[o];a&&(a instanceof Cc&&(a=a.get("tooltip",!0)),U(a)&&(a={formatter:a}),a&&(i=new Cc(a,i,r)))}return i}function CV(t,e){return t.dispatchAction||W(e.dispatchAction,e)}function DV(t){return"center"===t||"middle"===t}var AV=["rect","polygon","keep","clear"];function kV(t,e){var n=To(t?t.brush:[]);if(n.length){var i=[];E(n,(function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(i=i.concat(e))}));var r=t&&t.toolbox;Y(r)&&(r=r[0]),r||(r={feature:{}},t.toolbox=[r]);var o=r.feature||(r.feature={}),a=o.brush||(o.brush={}),s=a.type||(a.type=[]);s.push.apply(s,i),function(t){var e={};E(t,(function(t){e[t]=1})),t.length=0,E(e,(function(e,n){t.push(n)}))}(s),e&&!s.length&&s.push.apply(s,AV)}}var LV=E;function PV(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function OV(t,e,n){var i={};return LV(e,(function(e){var r,o=i[e]=((r=function(){}).prototype.__hidden=r.prototype,new r);LV(t[e],(function(t,i){if(kD.isValidType(i)){var r={type:i,visual:t};n&&n(r,e),o[i]=new kD(r),"opacity"===i&&((r=T(r)).type="colorAlpha",o.__hidden.__alphaForOpacity=new kD(r))}}))})),i}function RV(t,e,n){var i;E(n,(function(t){e.hasOwnProperty(t)&&PV(e[t])&&(i=!0)})),i&&E(n,(function(n){e.hasOwnProperty(n)&&PV(e[n])?t[n]=T(e[n]):delete t[n]}))}var NV={lineX:EV(0),lineY:EV(1),rect:{point:function(t,e,n){return t&&n.boundingRect.contain(t[0],t[1])},rect:function(t,e,n){return t&&n.boundingRect.intersect(t)}},polygon:{point:function(t,e,n){return t&&n.boundingRect.contain(t[0],t[1])&&P_(n.range,t[0],t[1])},rect:function(t,e,n){var i=n.range;if(!t||i.length<=1)return!1;var r=t.x,o=t.y,a=t.width,s=t.height,l=i[0];return!!(P_(i,r,o)||P_(i,r+a,o)||P_(i,r,o+s)||P_(i,r+a,o+s)||ze.create(t).contain(l[0],l[1])||Zh(r,o,r+a,o,i)||Zh(r,o,r,o+s,i)||Zh(r+a,o,r+a,o+s,i)||Zh(r,o+s,r+a,o+s,i))||void 0}}};function EV(t){var e=["x","y"],n=["width","height"];return{point:function(e,n,i){if(e){var r=i.range;return zV(e[t],r)}},rect:function(i,r,o){if(i){var a=o.range,s=[i[e[t]],i[e[t]]+i[n[t]]];return s[1]e[0][1]&&(e[0][1]=o[0]),o[1]e[1][1]&&(e[1][1]=o[1])}return e&&UV(e)}};function UV(t){return new ze(t[0][0],t[1][0],t[0][1]-t[0][0],t[1][1]-t[1][0])}var ZV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new lL(e.getZr())).on("brush",W(this._onBrush,this)).mount()},e.prototype.render=function(t,e,n,i){this.model=t,this._updateController(t,e,n,i)},e.prototype.updateTransform=function(t,e,n,i){GV(e),this._updateController(t,e,n,i)},e.prototype.updateVisual=function(t,e,n,i){this.updateTransform(t,e,n,i)},e.prototype.updateView=function(t,e,n,i){this._updateController(t,e,n,i)},e.prototype._updateController=function(t,e,n,i){(!i||i.$from!==t.id)&&this._brushController.setPanels(t.brushTargetManager.makePanelOpts(n)).enableBrush(t.brushOption).updateCovers(t.areas.slice())},e.prototype.dispose=function(){this._brushController.dispose()},e.prototype._onBrush=function(t){var e=this.model.id,n=this.model.brushTargetManager.setOutputRanges(t.areas,this.ecModel);(!t.isEnd||t.removeOnClick)&&this.api.dispatchAction({type:"brush",brushId:e,areas:T(n),$from:e}),t.isEnd&&this.api.dispatchAction({type:"brushEnd",brushId:e,areas:T(n),$from:e})},e.type="brush",e}(Ag),jV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.areas=[],n.brushOption={},n}return n(e,t),e.prototype.optionUpdated=function(t,e){var n=this.option;!e&&RV(n,t,["inBrush","outOfBrush"]);var i=n.inBrush=n.inBrush||{};n.outOfBrush=n.outOfBrush||{color:"#ddd"},i.hasOwnProperty("liftZ")||(i.liftZ=5)},e.prototype.setAreas=function(t){t&&(this.areas=z(t,(function(t){return qV(this.option,t)}),this))},e.prototype.setBrushOption=function(t){this.brushOption=qV(this.option,t),this.brushType=this.brushOption.brushType},e.type="brush",e.dependencies=["geo","grid","xAxis","yAxis","parallel","series"],e.defaultOption={seriesIndex:"all",brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(210,219,238,0.3)",borderColor:"#D2DBEE"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},e}(zp);function qV(t,e){return C({brushType:t.brushType,brushMode:t.brushMode,transformable:t.transformable,brushStyle:new Cc(t.brushStyle).getItemStyle(),removeOnClick:t.removeOnClick,z:t.z},e,!0)}var KV=["rect","polygon","lineX","lineY","keep","clear"],$V=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n){var i,r,o;e.eachComponent({mainType:"brush"},(function(t){i=t.brushType,r=t.brushOption.brushMode||"single",o=o||!!t.areas.length})),this._brushType=i,this._brushMode=r,E(t.get("type",!0),(function(e){t.setIconStatus(e,("keep"===e?"multiple"===r:"clear"===e?o:e===i)?"emphasis":"normal")}))},e.prototype.updateView=function(t,e,n){this.render(t,e,n)},e.prototype.getIcons=function(){var t=this.model,e=t.get("icon",!0),n={};return E(t.get("type",!0),(function(t){e[t]&&(n[t]=e[t])})),n},e.prototype.onclick=function(t,e,n){var i=this._brushType,r=this._brushMode;"clear"===n?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===n?i:i!==n&&n,brushMode:"keep"===n?"multiple"===r?"single":"multiple":r}})},e.getDefaultOption=function(t){return{show:!0,type:KV.slice(),icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:t.getLocaleModel().get(["toolbox","brush","title"])}},e}(_z);var JV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.layoutMode={type:"box",ignoreSize:!0},n}return n(e,t),e.type="title",e.defaultOption={z:6,show:!0,text:"",target:"blank",subtext:"",subtarget:"blank",left:0,top:0,backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bold",color:"#464646"},subtextStyle:{fontSize:12,color:"#6E7079"}},e}(zp),QV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){if(this.group.removeAll(),t.get("show")){var i=this.group,r=t.getModel("textStyle"),o=t.getModel("subtextStyle"),a=t.get("textAlign"),s=rt(t.get("textBaseline"),t.get("textVerticalAlign")),l=new Xs({style:oc(r,{text:t.get("text"),fill:r.getTextColor()},{disableBox:!0}),z2:10}),u=l.getBoundingRect(),h=t.get("subtext"),c=new Xs({style:oc(o,{text:h,fill:o.getTextColor(),y:u.height+t.get("itemGap"),verticalAlign:"top"},{disableBox:!0}),z2:10}),p=t.get("link"),d=t.get("sublink"),f=t.get("triggerEvent",!0);l.silent=!p&&!f,c.silent=!d&&!f,p&&l.on("click",(function(){Mp(p,"_"+t.get("target"))})),d&&c.on("click",(function(){Mp(d,"_"+t.get("subtarget"))})),rl(l).eventData=rl(c).eventData=f?{componentType:"title",componentIndex:t.componentIndex}:null,i.add(l),h&&i.add(c);var g=i.getBoundingRect(),y=t.getBoxLayoutParams();y.width=g.width,y.height=g.height;var v=kp(y,{width:n.getWidth(),height:n.getHeight()},t.get("padding"));a||("middle"===(a=t.get("left")||t.get("right"))&&(a="center"),"right"===a?v.x+=v.width:"center"===a&&(v.x+=v.width/2)),s||("center"===(s=t.get("top")||t.get("bottom"))&&(s="middle"),"bottom"===s?v.y+=v.height:"middle"===s&&(v.y+=v.height/2),s=s||"top"),i.x=v.x,i.y=v.y,i.markRedraw();var m={align:a,verticalAlign:s};l.setStyle(m),c.setStyle(m),g=i.getBoundingRect();var x=v.margin,_=t.getItemStyle(["color","opacity"]);_.fill=t.get("backgroundColor");var b=new Ws({shape:{x:g.x-x[3],y:g.y-x[0],width:g.width+x[1]+x[3],height:g.height+x[0]+x[2],r:t.get("borderRadius")},style:_,subPixelOptimize:!0,silent:!0});i.add(b)}},e.type="title",e}(Ag);var tB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.layoutMode="box",n}return n(e,t),e.prototype.init=function(t,e,n){this.mergeDefaultAndTheme(t,n),this._initData()},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),this._initData()},e.prototype.setCurrentIndex=function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},e.prototype.getCurrentIndex=function(){return this.option.currentIndex},e.prototype.isIndexMax=function(){return this.getCurrentIndex()>=this._data.count()-1},e.prototype.setPlayState=function(t){this.option.autoPlay=!!t},e.prototype.getPlayState=function(){return!!this.option.autoPlay},e.prototype._initData=function(){var t,e=this.option,n=e.data||[],i=e.axisType,r=this._names=[];"category"===i?(t=[],E(n,(function(e,n){var i,o=Ro(Ao(e),"");q(e)?(i=T(e)).value=n:i=n,t.push(i),r.push(o)}))):t=n;var o={category:"ordinal",time:"time",value:"number"}[i]||"number";(this._data=new cx([{name:"value",type:o}],this)).initData(t,r)},e.prototype.getData=function(){return this._data},e.prototype.getCategories=function(){if("category"===this.get("axisType"))return this._names.slice()},e.type="timeline",e.defaultOption={z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},e}(zp),eB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="timeline.slider",e.defaultOption=kc(tB.defaultOption,{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"circle",symbolSize:12,lineStyle:{show:!0,width:2,color:"#DAE1F5"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#A4B1D7"},itemStyle:{color:"#A4B1D7",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:15,color:"#316bf3",borderColor:"#fff",borderWidth:2,shadowBlur:2,shadowOffsetX:1,shadowOffsetY:1,shadowColor:"rgba(0, 0, 0, 0.3)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:24,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"M2,18.5A1.52,1.52,0,0,1,.92,18a1.49,1.49,0,0,1,0-2.12L7.81,9.36,1,3.11A1.5,1.5,0,1,1,3,.89l8,7.34a1.48,1.48,0,0,1,.49,1.09,1.51,1.51,0,0,1-.46,1.1L3,18.08A1.5,1.5,0,0,1,2,18.5Z",prevIcon:"M10,.5A1.52,1.52,0,0,1,11.08,1a1.49,1.49,0,0,1,0,2.12L4.19,9.64,11,15.89a1.5,1.5,0,1,1-2,2.22L1,10.77A1.48,1.48,0,0,1,.5,9.68,1.51,1.51,0,0,1,1,8.58L9,.92A1.5,1.5,0,0,1,10,.5Z",prevBtnSize:18,nextBtnSize:18,color:"#A4B1D7",borderColor:"#A4B1D7",borderWidth:1},emphasis:{label:{show:!0,color:"#6f778d"},itemStyle:{color:"#316BF3"},controlStyle:{color:"#316BF3",borderColor:"#316BF3",borderWidth:2}},progress:{lineStyle:{color:"#316BF3"},itemStyle:{color:"#316BF3"},label:{color:"#6f778d"}},data:[]}),e}(tB);R(eB,_f.prototype);var nB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="timeline",e}(Ag),iB=function(t){function e(e,n,i,r){var o=t.call(this,e,n,i)||this;return o.type=r||"value",o}return n(e,t),e.prototype.getLabelModel=function(){return this.model.getModel("label")},e.prototype.isHorizontal=function(){return"horizontal"===this.model.get("orient")},e}(ab),rB=Math.PI,oB=Vo(),aB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){this.api=e},e.prototype.render=function(t,e,n){if(this.model=t,this.api=n,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var i=this._layout(t,n),r=this._createGroup("_mainGroup"),o=this._createGroup("_labelGroup"),a=this._axis=this._createAxis(i,t);t.formatTooltip=function(t){return og("nameValue",{noName:!0,value:a.scale.getLabel({value:t})})},E(["AxisLine","AxisTick","Control","CurrentPointer"],(function(e){this["_render"+e](i,r,a,t)}),this),this._renderAxisLabel(i,o,a,t),this._position(i,t)}this._doPlayStop(),this._updateTicksStatus()},e.prototype.remove=function(){this._clearTimer(),this.group.removeAll()},e.prototype.dispose=function(){this._clearTimer()},e.prototype._layout=function(t,e){var n,i,r,o,a=t.get(["label","position"]),s=t.get("orient"),l=function(t,e){return kp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()},t.get("padding"))}(t,e),u={horizontal:"center",vertical:(n=null==a||"auto"===a?"horizontal"===s?l.y+l.height/2=0||"+"===n?"left":"right"},h={horizontal:n>=0||"+"===n?"top":"bottom",vertical:"middle"},c={horizontal:0,vertical:rB/2},p="vertical"===s?l.height:l.width,d=t.getModel("controlStyle"),f=d.get("show",!0),g=f?d.get("itemSize"):0,y=f?d.get("itemGap"):0,v=g+y,m=t.get(["label","rotate"])||0;m=m*rB/180;var x=d.get("position",!0),_=f&&d.get("showPlayBtn",!0),b=f&&d.get("showPrevBtn",!0),w=f&&d.get("showNextBtn",!0),S=0,M=p;"left"===x||"bottom"===x?(_&&(i=[0,0],S+=v),b&&(r=[S,0],S+=v),w&&(o=[M-g,0],M-=v)):(_&&(i=[M-g,0],M-=v),b&&(r=[0,0],S+=v),w&&(o=[M-g,0],M-=v));var I=[S,M];return t.get("inverse")&&I.reverse(),{viewRect:l,mainLength:p,orient:s,rotation:c[s],labelRotation:m,labelPosOpt:n,labelAlign:t.get(["label","align"])||u[s],labelBaseline:t.get(["label","verticalAlign"])||t.get(["label","baseline"])||h[s],playPosition:i,prevBtnPosition:r,nextBtnPosition:o,axisExtent:I,controlSize:g,controlGap:y}},e.prototype._position=function(t,e){var n=this._mainGroup,i=this._labelGroup,r=t.viewRect;if("vertical"===t.orient){var o=[1,0,0,1,0,0],a=r.x,s=r.y+r.height;we(o,o,[-a,-s]),Se(o,o,-rB/2),we(o,o,[a,s]),(r=r.clone()).applyTransform(o)}var l=y(r),u=y(n.getBoundingRect()),h=y(i.getBoundingRect()),c=[n.x,n.y],p=[i.x,i.y];p[0]=c[0]=l[0][0];var d,f=t.labelPosOpt;null==f||U(f)?(v(c,u,l,1,d="+"===f?0:1),v(p,h,l,1,1-d)):(v(c,u,l,1,d=f>=0?0:1),p[1]=c[1]+f);function g(t){t.originX=l[0][0]-t.x,t.originY=l[1][0]-t.y}function y(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function v(t,e,n,i,r){t[i]+=n[i][r]-e[i][r]}n.setPosition(c),i.setPosition(p),n.rotation=i.rotation=t.rotation,g(n),g(i)},e.prototype._createAxis=function(t,e){var n=e.getData(),i=e.get("axisType"),r=function(t,e){if(e=e||t.get("type"),e)switch(e){case"category":return new Rx({ordinalMeta:t.getCategories(),extent:[1/0,-1/0]});case"time":return new Kx({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC")});default:return new Ex}}(e,i);r.getTicks=function(){return n.mapArray(["value"],(function(t){return{value:t}}))};var o=n.getDataExtent("value");r.setExtent(o[0],o[1]),r.calcNiceTicks();var a=new iB("value",r,t.axisExtent,i);return a.model=e,a},e.prototype._createGroup=function(t){var e=this[t]=new Br;return this.group.add(e),e},e.prototype._renderAxisLine=function(t,e,n,i){var r=n.getExtent();if(i.get(["lineStyle","show"])){var o=new Ku({shape:{x1:r[0],y1:0,x2:r[1],y2:0},style:A({lineCap:"round"},i.getModel("lineStyle").getLineStyle()),silent:!0,z2:1});e.add(o);var a=this._progressLine=new Ku({shape:{x1:r[0],x2:this._currentPointer?this._currentPointer.x:r[0],y1:0,y2:0},style:k({lineCap:"round",lineWidth:o.style.lineWidth},i.getModel(["progress","lineStyle"]).getLineStyle()),silent:!0,z2:1});e.add(a)}},e.prototype._renderAxisTick=function(t,e,n,i){var r=this,o=i.getData(),a=n.scale.getTicks();this._tickSymbols=[],E(a,(function(t){var a=n.dataToCoord(t.value),s=o.getItemModel(t.value),l=s.getModel("itemStyle"),u=s.getModel(["emphasis","itemStyle"]),h=s.getModel(["progress","itemStyle"]),c={x:a,y:0,onclick:W(r._changeTimeline,r,t.value)},p=sB(s,l,e,c);p.ensureState("emphasis").style=u.getItemStyle(),p.ensureState("progress").style=h.getItemStyle(),Ul(p);var d=rl(p);s.get("tooltip")?(d.dataIndex=t.value,d.dataModel=i):d.dataIndex=d.dataModel=null,r._tickSymbols.push(p)}))},e.prototype._renderAxisLabel=function(t,e,n,i){var r=this;if(n.getLabelModel().get("show")){var o=i.getData(),a=n.getViewLabels();this._tickLabels=[],E(a,(function(i){var a=i.tickValue,s=o.getItemModel(a),l=s.getModel("label"),u=s.getModel(["emphasis","label"]),h=s.getModel(["progress","label"]),c=n.dataToCoord(i.tickValue),p=new Xs({x:c,y:0,rotation:t.labelRotation-t.rotation,onclick:W(r._changeTimeline,r,a),silent:!1,style:oc(l,{text:i.formattedLabel,align:t.labelAlign,verticalAlign:t.labelBaseline})});p.ensureState("emphasis").style=oc(u),p.ensureState("progress").style=oc(h),e.add(p),Ul(p),oB(p).dataIndex=a,r._tickLabels.push(p)}))}},e.prototype._renderControl=function(t,e,n,i){var r=t.controlSize,o=t.rotation,a=i.getModel("controlStyle").getItemStyle(),s=i.getModel(["emphasis","controlStyle"]).getItemStyle(),l=i.getPlayState(),u=i.get("inverse",!0);function h(t,n,l,u){if(t){var h=Cr(rt(i.get(["controlStyle",n+"BtnSize"]),r),r),c=function(t,e,n,i){var r=i.style,o=Uh(t.get(["controlStyle",e]),i||{},new ze(n[0],n[1],n[2],n[3]));r&&o.setStyle(r);return o}(i,n+"Icon",[0,-h/2,h,h],{x:t[0],y:t[1],originX:r/2,originY:0,rotation:u?-o:0,rectHover:!0,style:a,onclick:l});c.ensureState("emphasis").style=s,e.add(c),Ul(c)}}h(t.nextBtnPosition,"next",W(this._changeTimeline,this,u?"-":"+")),h(t.prevBtnPosition,"prev",W(this._changeTimeline,this,u?"+":"-")),h(t.playPosition,l?"stop":"play",W(this._handlePlayClick,this,!l),!0)},e.prototype._renderCurrentPointer=function(t,e,n,i){var r=i.getData(),o=i.getCurrentIndex(),a=r.getItemModel(o).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=W(s._handlePointerDrag,s),t.ondragend=W(s._handlePointerDragend,s),lB(t,s._progressLine,o,n,i,!0)},onUpdate:function(t){lB(t,s._progressLine,o,n,i)}};this._currentPointer=sB(a,a,this._mainGroup,{},this._currentPointer,l)},e.prototype._handlePlayClick=function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},e.prototype._handlePointerDrag=function(t,e,n){this._clearTimer(),this._pointerChangeTimeline([n.offsetX,n.offsetY])},e.prototype._handlePointerDragend=function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},e.prototype._pointerChangeTimeline=function(t,e){var n=this._toAxisCoord(t)[0],i=Qr(this._axis.getExtent().slice());n>i[1]&&(n=i[1]),n=0&&(a[o]=+a[o].toFixed(c)),[a,h]}var xB={min:H(mB,"min"),max:H(mB,"max"),average:H(mB,"average"),median:H(mB,"median")};function _B(t,e){if(e){var n=t.getData(),i=t.coordinateSystem,r=i&&i.dimensions;if(!function(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}(e)&&!Y(e.coord)&&Y(r)){var o=bB(e,n,i,t);if((e=T(e)).type&&xB[e.type]&&o.baseAxis&&o.valueAxis){var a=P(r,o.baseAxis.dim),s=P(r,o.valueAxis.dim),l=xB[e.type](n,o.baseDataDim,o.valueDataDim,a,s);e.coord=l[0],e.value=l[1]}else e.coord=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis]}if(null!=e.coord&&Y(r))for(var u=e.coord,h=0;h<2;h++)xB[u[h]]&&(u[h]=MB(n,n.mapDimension(r[h]),u[h]));else e.coord=[];return e}}function bB(t,e,n,i){var r={};return null!=t.valueIndex||null!=t.valueDim?(r.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,r.valueAxis=n.getAxis(function(t,e){var n=t.getData().getDimensionInfo(e);return n&&n.coordDim}(i,r.valueDataDim)),r.baseAxis=n.getOtherAxis(r.valueAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim)):(r.baseAxis=i.getBaseAxis(),r.valueAxis=n.getOtherAxis(r.baseAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim),r.valueDataDim=e.mapDimension(r.valueAxis.dim)),r}function wB(t,e){return!(t&&t.containData&&e.coord&&!vB(e))||t.containData(e.coord)}function SB(t,e){return t?function(t,n,i,r){return If(r<2?t.coord&&t.coord[r]:t.value,e[r])}:function(t,n,i,r){return If(t.value,e[r])}}function MB(t,e,n){if("average"===n){var i=0,r=0;return t.each(e,(function(t,e){isNaN(t)||(i+=t,r++)})),i/r}return"median"===n?t.getMedian(e):t.getDataExtent(e)["max"===n?1:0]}var IB=Vo(),TB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(){this.markerGroupMap=yt()},e.prototype.render=function(t,e,n){var i=this,r=this.markerGroupMap;r.each((function(t){IB(t).keep=!1})),e.eachSeries((function(t){var r=gB.getMarkerModelFromSeries(t,i.type);r&&i.renderSeries(t,r,e,n)})),r.each((function(t){!IB(t).keep&&i.group.remove(t.group)}))},e.prototype.markKeep=function(t){IB(t).keep=!0},e.prototype.toggleBlurSeries=function(t,e){var n=this;E(t,(function(t){var i=gB.getMarkerModelFromSeries(t,n.type);i&&i.getData().eachItemGraphicEl((function(t){t&&(e?Nl(t):El(t))}))}))},e.type="marker",e}(Ag);function CB(t,e,n){var i=e.coordinateSystem;t.each((function(r){var o,a=t.getItemModel(r),s=$r(a.get("x"),n.getWidth()),l=$r(a.get("y"),n.getHeight());if(isNaN(s)||isNaN(l)){if(e.getMarkerPosition)o=e.getMarkerPosition(t.getValues(t.dimensions,r));else if(i){var u=t.get(i.dimensions[0],r),h=t.get(i.dimensions[1],r);o=i.dataToPoint([u,h])}}else o=[s,l];isNaN(s)||(o[0]=s),isNaN(l)||(o[1]=l),t.setItemLayout(r,o)}))}var DB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=gB.getMarkerModelFromSeries(t,"markPoint");e&&(CB(e.getData(),t,n),this.markerGroupMap.get(t.id).updateLayout())}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,new xS),u=function(t,e,n){var i;i=t?z(t&&t.dimensions,(function(t){return A(A({},e.getData().getDimensionInfo(e.getData().mapDimension(t))||{}),{name:t,ordinalMeta:null})})):[{name:"value",type:"float"}];var r=new cx(i,n),o=z(n.get("data"),H(_B,e));t&&(o=B(o,H(wB,t)));var a=SB(!!t,i);return r.initData(o,null,a),r}(r,t,e);e.setData(u),CB(e.getData(),t,i),u.each((function(t){var n=u.getItemModel(t),i=n.getShallow("symbol"),r=n.getShallow("symbolSize"),o=n.getShallow("symbolRotate"),s=n.getShallow("symbolOffset"),l=n.getShallow("symbolKeepAspect");if(X(i)||X(r)||X(o)||X(s)){var h=e.getRawValue(t),c=e.getDataParams(t);X(i)&&(i=i(h,c)),X(r)&&(r=r(h,c)),X(o)&&(o=o(h,c)),X(s)&&(s=s(h,c))}var p=n.getModel("itemStyle").getItemStyle(),d=Ay(a,"color");p.fill||(p.fill=d),u.setItemVisual(t,{symbol:i,symbolSize:r,symbolRotate:o,symbolOffset:s,symbolKeepAspect:l,style:p})})),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl((function(t){t.traverse((function(t){rl(t).dataModel=e}))})),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markPoint",e}(TB);var AB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.createMarkerModelFromSeries=function(t,n,i){return new e(t,n,i)},e.type="markLine",e.defaultOption={z:5,symbol:["circle","arrow"],symbolSize:[8,16],symbolOffset:0,precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end",distance:5},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"},e}(gB),kB=Vo(),LB=function(t,e,n,i){var r,o=t.getData();if(Y(i))r=i;else{var a=i.type;if("min"===a||"max"===a||"average"===a||"median"===a||null!=i.xAxis||null!=i.yAxis){var s=void 0,l=void 0;if(null!=i.yAxis||null!=i.xAxis)s=e.getAxis(null!=i.yAxis?"y":"x"),l=it(i.yAxis,i.xAxis);else{var u=bB(i,o,e,t);s=u.valueAxis,l=MB(o,xx(o,u.valueDataDim),a)}var h="x"===s.dim?0:1,c=1-h,p=T(i),d={coord:[]};p.type=null,p.coord=[],p.coord[c]=-1/0,d.coord[c]=1/0;var f=n.get("precision");f>=0&&j(l)&&(l=+l.toFixed(Math.min(f,20))),p.coord[h]=d.coord[h]=l,r=[p,d,{type:a,valueIndex:i.valueIndex,value:l}]}else r=[]}var g=[_B(t,r[0]),_B(t,r[1]),A({},r[2])];return g[2].type=g[2].type||null,C(g[2],g[0]),C(g[2],g[1]),g};function PB(t){return!isNaN(t)&&!isFinite(t)}function OB(t,e,n,i){var r=1-t,o=i.dimensions[t];return PB(e[r])&&PB(n[r])&&e[t]===n[t]&&i.getAxis(o).containData(e[t])}function RB(t,e){if("cartesian2d"===t.type){var n=e[0].coord,i=e[1].coord;if(n&&i&&(OB(1,n,i,t)||OB(0,n,i,t)))return!0}return wB(t,e[0])&&wB(t,e[1])}function NB(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=$r(s.get("x"),r.getWidth()),u=$r(s.get("y"),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition)o=i.getMarkerPosition(t.getValues(t.dimensions,e));else{var h=a.dimensions,c=t.get(h[0],e),p=t.get(h[1],e);o=a.dataToPoint([c,p])}if(OS(a,"cartesian2d")){var d=a.getAxis("x"),f=a.getAxis("y");h=a.dimensions;PB(t.get(h[0],e))?o[0]=d.toGlobalCoord(d.getExtent()[n?0:1]):PB(t.get(h[1],e))&&(o[1]=f.toGlobalCoord(f.getExtent()[n?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];t.setItemLayout(e,o)}var EB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=gB.getMarkerModelFromSeries(t,"markLine");if(e){var i=e.getData(),r=kB(e).from,o=kB(e).to;r.each((function(e){NB(r,e,!0,t,n),NB(o,e,!1,t,n)})),i.each((function(t){i.setItemLayout(t,[r.getItemLayout(t),o.getItemLayout(t)])})),this.markerGroupMap.get(t.id).updateLayout()}}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,new YA);this.group.add(l.group);var u=function(t,e,n){var i;i=t?z(t&&t.dimensions,(function(t){return A(A({},e.getData().getDimensionInfo(e.getData().mapDimension(t))||{}),{name:t,ordinalMeta:null})})):[{name:"value",type:"float"}];var r=new cx(i,n),o=new cx(i,n),a=new cx([],n),s=z(n.get("data"),H(LB,e,t,n));t&&(s=B(s,H(RB,t)));var l=SB(!!t,i);return r.initData(z(s,(function(t){return t[0]})),null,l),o.initData(z(s,(function(t){return t[1]})),null,l),a.initData(z(s,(function(t){return t[2]}))),a.hasItemOption=!0,{from:r,to:o,line:a}}(r,t,e),h=u.from,c=u.to,p=u.line;kB(e).from=h,kB(e).to=c,e.setData(p);var d=e.get("symbol"),f=e.get("symbolSize"),g=e.get("symbolRotate"),y=e.get("symbolOffset");function v(e,n,r){var o=e.getItemModel(n);NB(e,n,r,t,i);var s=o.getModel("itemStyle").getItemStyle();null==s.fill&&(s.fill=Ay(a,"color")),e.setItemVisual(n,{symbolKeepAspect:o.get("symbolKeepAspect"),symbolOffset:rt(o.get("symbolOffset",!0),y[r?0:1]),symbolRotate:rt(o.get("symbolRotate",!0),g[r?0:1]),symbolSize:rt(o.get("symbolSize"),f[r?0:1]),symbol:rt(o.get("symbol",!0),d[r?0:1]),style:s})}Y(d)||(d=[d,d]),Y(f)||(f=[f,f]),Y(g)||(g=[g,g]),Y(y)||(y=[y,y]),u.from.each((function(t){v(h,t,!0),v(c,t,!1)})),p.each((function(t){var e=p.getItemModel(t).getModel("lineStyle").getLineStyle();p.setItemLayout(t,[h.getItemLayout(t),c.getItemLayout(t)]),null==e.stroke&&(e.stroke=h.getItemVisual(t,"style").fill),p.setItemVisual(t,{fromSymbolKeepAspect:h.getItemVisual(t,"symbolKeepAspect"),fromSymbolOffset:h.getItemVisual(t,"symbolOffset"),fromSymbolRotate:h.getItemVisual(t,"symbolRotate"),fromSymbolSize:h.getItemVisual(t,"symbolSize"),fromSymbol:h.getItemVisual(t,"symbol"),toSymbolKeepAspect:c.getItemVisual(t,"symbolKeepAspect"),toSymbolOffset:c.getItemVisual(t,"symbolOffset"),toSymbolRotate:c.getItemVisual(t,"symbolRotate"),toSymbolSize:c.getItemVisual(t,"symbolSize"),toSymbol:c.getItemVisual(t,"symbol"),style:e})})),l.updateData(p),u.line.eachItemGraphicEl((function(t){rl(t).dataModel=e,t.traverse((function(t){rl(t).dataModel=e}))})),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markLine",e}(TB);var zB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.createMarkerModelFromSeries=function(t,n,i){return new e(t,n,i)},e.type="markArea",e.defaultOption={z:1,tooltip:{trigger:"item"},animation:!1,label:{show:!0,position:"top"},itemStyle:{borderWidth:0},emphasis:{label:{show:!0,position:"top"}}},e}(gB),VB=Vo(),BB=function(t,e,n,i){var r=i[0],o=i[1];if(r&&o){var a=_B(t,r),s=_B(t,o),l=a.coord,u=s.coord;l[0]=it(l[0],-1/0),l[1]=it(l[1],-1/0),u[0]=it(u[0],1/0),u[1]=it(u[1],1/0);var h=D([{},a,s]);return h.coord=[a.coord,s.coord],h.x0=a.x,h.y0=a.y,h.x1=s.x,h.y1=s.y,h}};function FB(t){return!isNaN(t)&&!isFinite(t)}function GB(t,e,n,i){var r=1-t;return FB(e[r])&&FB(n[r])}function WB(t,e){var n=e.coord[0],i=e.coord[1],r={coord:n,x:e.x0,y:e.y0},o={coord:i,x:e.x1,y:e.y1};return OS(t,"cartesian2d")?!(!n||!i||!GB(1,n,i)&&!GB(0,n,i))||function(t,e,n){return!(t&&t.containZone&&e.coord&&n.coord&&!vB(e)&&!vB(n))||t.containZone(e.coord,n.coord)}(t,r,o):wB(t,r)||wB(t,o)}function HB(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=$r(s.get(n[0]),r.getWidth()),u=$r(s.get(n[1]),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition){var h=t.getValues(["x0","y0"],e),c=t.getValues(["x1","y1"],e),p=a.clampData(h),d=a.clampData(c),f=[];"x0"===n[0]?f[0]=p[0]>d[0]?c[0]:h[0]:f[0]=p[0]>d[0]?h[0]:c[0],"y0"===n[1]?f[1]=p[1]>d[1]?c[1]:h[1]:f[1]=p[1]>d[1]?h[1]:c[1],o=i.getMarkerPosition(f,n,!0)}else{var g=[m=t.get(n[0],e),x=t.get(n[1],e)];a.clampData&&a.clampData(g,g),o=a.dataToPoint(g,!0)}if(OS(a,"cartesian2d")){var y=a.getAxis("x"),v=a.getAxis("y"),m=t.get(n[0],e),x=t.get(n[1],e);FB(m)?o[0]=y.toGlobalCoord(y.getExtent()["x0"===n[0]?0:1]):FB(x)&&(o[1]=v.toGlobalCoord(v.getExtent()["y0"===n[1]?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];return o}var YB=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]],XB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=gB.getMarkerModelFromSeries(t,"markArea");if(e){var i=e.getData();i.each((function(e){var r=z(YB,(function(r){return HB(i,e,r,t,n)}));i.setItemLayout(e,r),i.getItemGraphicEl(e).setShape("points",r)}))}}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,{group:new Br});this.group.add(l.group),this.markKeep(l);var u=function(t,e,n){var i,r,o=["x0","y0","x1","y1"];if(t){var a=z(t&&t.dimensions,(function(t){var n=e.getData();return A(A({},n.getDimensionInfo(n.mapDimension(t))||{}),{name:t,ordinalMeta:null})}));r=z(o,(function(t,e){return{name:t,type:a[e%2].type}})),i=new cx(r,n)}else i=new cx(r=[{name:"value",type:"float"}],n);var s=z(n.get("data"),H(BB,e,t,n));t&&(s=B(s,H(WB,t)));var l=t?function(t,e,n,i){return If(t.coord[Math.floor(i/2)][i%2],r[i])}:function(t,e,n,i){return If(t.value,r[i])};return i.initData(s,null,l),i.hasItemOption=!0,i}(r,t,e);e.setData(u),u.each((function(e){var n=z(YB,(function(n){return HB(u,e,n,t,i)})),o=r.getAxis("x").scale,s=r.getAxis("y").scale,l=o.getExtent(),h=s.getExtent(),c=[o.parse(u.get("x0",e)),o.parse(u.get("x1",e))],p=[s.parse(u.get("y0",e)),s.parse(u.get("y1",e))];Qr(c),Qr(p);var d=!!(l[0]>c[1]||l[1]p[1]||h[1]=0},e.prototype.getOrient=function(){return"vertical"===this.get("orient")?{index:1,name:"vertical"}:{index:0,name:"horizontal"}},e.type="legend.plain",e.dependencies=["series"],e.defaultOption={z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,symbolRotate:"inherit",symbolKeepAspect:!0,inactiveColor:"#ccc",inactiveBorderColor:"#ccc",inactiveBorderWidth:"auto",itemStyle:{color:"inherit",opacity:"inherit",borderColor:"inherit",borderWidth:"auto",borderCap:"inherit",borderJoin:"inherit",borderDashOffset:"inherit",borderMiterLimit:"inherit"},lineStyle:{width:"auto",color:"inherit",inactiveColor:"#ccc",inactiveWidth:2,opacity:"inherit",type:"inherit",cap:"inherit",join:"inherit",dashOffset:"inherit",miterLimit:"inherit"},textStyle:{color:"#333"},selectedMode:!0,selector:!1,selectorLabel:{show:!0,borderRadius:10,padding:[3,5,3,5],fontSize:12,fontFamily:"sans-serif",color:"#666",borderWidth:1,borderColor:"#666"},emphasis:{selectorLabel:{show:!0,color:"#eee",backgroundColor:"#666"}},selectorPosition:"auto",selectorItemGap:7,selectorButtonGap:10,tooltip:{show:!1}},e}(zp),ZB=H,jB=E,qB=Br,KB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.newlineDisabled=!1,n}return n(e,t),e.prototype.init=function(){this.group.add(this._contentGroup=new qB),this.group.add(this._selectorGroup=new qB),this._isFirstRender=!0},e.prototype.getContentGroup=function(){return this._contentGroup},e.prototype.getSelectorGroup=function(){return this._selectorGroup},e.prototype.render=function(t,e,n){var i=this._isFirstRender;if(this._isFirstRender=!1,this.resetInner(),t.get("show",!0)){var r=t.get("align"),o=t.get("orient");r&&"auto"!==r||(r="right"===t.get("left")&&"vertical"===o?"right":"left");var a=t.get("selector",!0),s=t.get("selectorPosition",!0);!a||s&&"auto"!==s||(s="horizontal"===o?"end":"start"),this.renderInner(r,t,e,n,a,o,s);var l=t.getBoxLayoutParams(),u={width:n.getWidth(),height:n.getHeight()},h=t.get("padding"),c=kp(l,u,h),p=this.layoutInner(t,r,c,i,a,s),d=kp(k({width:p.width,height:p.height},l),u,h);this.group.x=d.x-p.x,this.group.y=d.y-p.y,this.group.markRedraw(),this.group.add(this._backgroundEl=Iz(p,t))}},e.prototype.resetInner=function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl),this.getSelectorGroup().removeAll()},e.prototype.renderInner=function(t,e,n,i,r,o,a){var s=this.getContentGroup(),l=yt(),u=e.get("selectedMode"),h=[];n.eachRawSeries((function(t){!t.get("legendHoverLink")&&h.push(t.id)})),jB(e.getData(),(function(r,o){var a=r.get("name");if(!this.newlineDisabled&&(""===a||"\n"===a)){var c=new qB;return c.newline=!0,void s.add(c)}var p=n.getSeriesByName(a)[0];if(!l.get(a)){if(p){var d=p.getData(),f=d.getVisual("legendLineStyle")||{},g=d.getVisual("legendIcon"),y=d.getVisual("style"),v=this._createItem(p,a,o,r,e,t,f,y,g,u,i);v.on("click",ZB($B,a,null,i,h)).on("mouseover",ZB(QB,p.name,null,i,h)).on("mouseout",ZB(tF,p.name,null,i,h)),n.ssr&&v.eachChild((function(t){var e=rl(t);e.seriesIndex=p.seriesIndex,e.dataIndex=o,e.ssrType="legend"})),l.set(a,!0)}else n.eachRawSeries((function(s){if(!l.get(a)&&s.legendVisualProvider){var c=s.legendVisualProvider;if(!c.containName(a))return;var p=c.indexOfName(a),d=c.getItemVisual(p,"style"),f=c.getItemVisual(p,"legendIcon"),g=qn(d.fill);g&&0===g[3]&&(g[3]=.2,d=A(A({},d),{fill:ri(g,"rgba")}));var y=this._createItem(s,a,o,r,e,t,{},d,f,u,i);y.on("click",ZB($B,null,a,i,h)).on("mouseover",ZB(QB,null,a,i,h)).on("mouseout",ZB(tF,null,a,i,h)),n.ssr&&y.eachChild((function(t){var e=rl(t);e.seriesIndex=s.seriesIndex,e.dataIndex=o,e.ssrType="legend"})),l.set(a,!0)}}),this);0}}),this),r&&this._createSelector(r,e,i,o,a)},e.prototype._createSelector=function(t,e,n,i,r){var o=this.getSelectorGroup();jB(t,(function(t){var i=t.type,r=new Xs({style:{x:0,y:0,align:"center",verticalAlign:"middle"},onclick:function(){n.dispatchAction({type:"all"===i?"legendAllSelect":"legendInverseSelect",legendId:e.id})}});o.add(r),ic(r,{normal:e.getModel("selectorLabel"),emphasis:e.getModel(["emphasis","selectorLabel"])},{defaultText:t.title}),Ul(r)}))},e.prototype._createItem=function(t,e,n,i,r,o,a,s,l,u,h){var c=t.visualDrawType,p=r.get("itemWidth"),d=r.get("itemHeight"),f=r.isSelected(e),g=i.get("symbolRotate"),y=i.get("symbolKeepAspect"),v=i.get("icon"),m=function(t,e,n,i,r,o,a){function s(t,e){"auto"===t.lineWidth&&(t.lineWidth=e.lineWidth>0?2:0),jB(t,(function(n,i){"inherit"===t[i]&&(t[i]=e[i])}))}var l=e.getModel("itemStyle"),u=l.getItemStyle(),h=0===t.lastIndexOf("empty",0)?"fill":"stroke",c=l.getShallow("decal");u.decal=c&&"inherit"!==c?mv(c,a):i.decal,"inherit"===u.fill&&(u.fill=i[r]);"inherit"===u.stroke&&(u.stroke=i[h]);"inherit"===u.opacity&&(u.opacity=("fill"===r?i:n).opacity);s(u,i);var p=e.getModel("lineStyle"),d=p.getLineStyle();if(s(d,n),"auto"===u.fill&&(u.fill=i.fill),"auto"===u.stroke&&(u.stroke=i.fill),"auto"===d.stroke&&(d.stroke=i.fill),!o){var f=e.get("inactiveBorderWidth"),g=u[h];u.lineWidth="auto"===f?i.lineWidth>0&&g?2:0:u.lineWidth,u.fill=e.get("inactiveColor"),u.stroke=e.get("inactiveBorderColor"),d.stroke=p.get("inactiveColor"),d.lineWidth=p.get("inactiveWidth")}return{itemStyle:u,lineStyle:d}}(l=v||l||"roundRect",i,a,s,c,f,h),x=new qB,_=i.getModel("textStyle");if(!X(t.getLegendIcon)||v&&"inherit"!==v){var b="inherit"===v&&t.getData().getVisual("symbol")?"inherit"===g?t.getData().getVisual("symbolRotate"):g:0;x.add(function(t){var e=t.icon||"roundRect",n=Xy(e,0,0,t.itemWidth,t.itemHeight,t.itemStyle.fill,t.symbolKeepAspect);n.setStyle(t.itemStyle),n.rotation=(t.iconRotate||0)*Math.PI/180,n.setOrigin([t.itemWidth/2,t.itemHeight/2]),e.indexOf("empty")>-1&&(n.style.stroke=n.style.fill,n.style.fill="#fff",n.style.lineWidth=2);return n}({itemWidth:p,itemHeight:d,icon:l,iconRotate:b,itemStyle:m.itemStyle,lineStyle:m.lineStyle,symbolKeepAspect:y}))}else x.add(t.getLegendIcon({itemWidth:p,itemHeight:d,icon:l,iconRotate:g,itemStyle:m.itemStyle,lineStyle:m.lineStyle,symbolKeepAspect:y}));var w="left"===o?p+5:-5,S=o,M=r.get("formatter"),I=e;U(M)&&M?I=M.replace("{name}",null!=e?e:""):X(M)&&(I=M(e));var T=f?_.getTextColor():i.get("inactiveColor");x.add(new Xs({style:oc(_,{text:I,x:w,y:d/2,fill:T,align:S,verticalAlign:"middle"},{inheritColor:T})}));var C=new Ws({shape:x.getBoundingRect(),style:{fill:"transparent"}}),D=i.getModel("tooltip");return D.get("show")&&Kh({el:C,componentModel:r,itemName:e,itemTooltipOption:D.option}),x.add(C),x.eachChild((function(t){t.silent=!0})),C.silent=!u,this.getContentGroup().add(x),Ul(x),x.__legendDataIndex=n,x},e.prototype.layoutInner=function(t,e,n,i,r,o){var a=this.getContentGroup(),s=this.getSelectorGroup();Ap(t.get("orient"),a,t.get("itemGap"),n.width,n.height);var l=a.getBoundingRect(),u=[-l.x,-l.y];if(s.markRedraw(),a.markRedraw(),r){Ap("horizontal",s,t.get("selectorItemGap",!0));var h=s.getBoundingRect(),c=[-h.x,-h.y],p=t.get("selectorButtonGap",!0),d=t.getOrient().index,f=0===d?"width":"height",g=0===d?"height":"width",y=0===d?"y":"x";"end"===o?c[d]+=l[f]+p:u[d]+=h[f]+p,c[1-d]+=l[g]/2-h[g]/2,s.x=c[0],s.y=c[1],a.x=u[0],a.y=u[1];var v={x:0,y:0};return v[f]=l[f]+p+h[f],v[g]=Math.max(l[g],h[g]),v[y]=Math.min(0,h[y]+c[1-d]),v}return a.x=u[0],a.y=u[1],this.group.getBoundingRect()},e.prototype.remove=function(){this.getContentGroup().removeAll(),this._isFirstRender=!0},e.type="legend.plain",e}(Ag);function $B(t,e,n,i){tF(t,e,n,i),n.dispatchAction({type:"legendToggleSelect",name:null!=t?t:e}),QB(t,e,n,i)}function JB(t){for(var e,n=t.getZr().storage.getDisplayList(),i=0,r=n.length;in[r],f=[-c.x,-c.y];e||(f[i]=l[s]);var g=[0,0],y=[-p.x,-p.y],v=rt(t.get("pageButtonGap",!0),t.get("itemGap",!0));d&&("end"===t.get("pageButtonPosition",!0)?y[i]+=n[r]-p[r]:g[i]+=p[r]+v);y[1-i]+=c[o]/2-p[o]/2,l.setPosition(f),u.setPosition(g),h.setPosition(y);var m={x:0,y:0};if(m[r]=d?n[r]:c[r],m[o]=Math.max(c[o],p[o]),m[a]=Math.min(0,p[a]+y[1-i]),u.__rectSize=n[r],d){var x={x:0,y:0};x[r]=Math.max(n[r]-p[r]-v,0),x[o]=m[o],u.setClipPath(new Ws({shape:x})),u.__rectSize=x[r]}else h.eachChild((function(t){t.attr({invisible:!0,silent:!0})}));var _=this._getPageInfo(t);return null!=_.pageIndex&&vh(l,{x:_.contentPosition[0],y:_.contentPosition[1]},d?t:null),this._updatePageInfoView(t,_),m},e.prototype._pageGo=function(t,e,n){var i=this._getPageInfo(e)[t];null!=i&&n.dispatchAction({type:"legendScroll",scrollDataIndex:i,legendId:e.id})},e.prototype._updatePageInfoView=function(t,e){var n=this._controllerGroup;E(["pagePrev","pageNext"],(function(i){var r=null!=e[i+"DataIndex"],o=n.childOfName(i);o&&(o.setStyle("fill",r?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),o.cursor=r?"pointer":"default")}));var i=n.childOfName("pageText"),r=t.get("pageFormatter"),o=e.pageIndex,a=null!=o?o+1:0,s=e.pageCount;i&&r&&i.setStyle("text",U(r)?r.replace("{current}",null==a?"":a+"").replace("{total}",null==s?"":s+""):r({current:a,total:s}))},e.prototype._getPageInfo=function(t){var e=t.get("scrollDataIndex",!0),n=this.getContentGroup(),i=this._containerGroup.__rectSize,r=t.getOrient().index,o=lF[r],a=uF[r],s=this._findTargetItemIndex(e),l=n.children(),u=l[s],h=l.length,c=h?1:0,p={contentPosition:[n.x,n.y],pageCount:c,pageIndex:c-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!u)return p;var d=m(u);p.contentPosition[r]=-d.s;for(var f=s+1,g=d,y=d,v=null;f<=h;++f)(!(v=m(l[f]))&&y.e>g.s+i||v&&!x(v,g.s))&&(g=y.i>g.i?y:v)&&(null==p.pageNextDataIndex&&(p.pageNextDataIndex=g.i),++p.pageCount),y=v;for(f=s-1,g=d,y=d,v=null;f>=-1;--f)(v=m(l[f]))&&x(y,v.s)||!(g.i=e&&t.s<=e+i}},e.prototype._findTargetItemIndex=function(t){return this._showController?(this.getContentGroup().eachChild((function(i,r){var o=i.__legendDataIndex;null==n&&null!=o&&(n=r),o===t&&(e=r)})),null!=e?e:n):0;var e,n},e.type="legend.scroll",e}(KB);function cF(t){Vm(rF),t.registerComponentModel(oF),t.registerComponentView(hF),function(t){t.registerAction("legendScroll","legendscroll",(function(t,e){var n=t.scrollDataIndex;null!=n&&e.eachComponent({mainType:"legend",subType:"scroll",query:t},(function(t){t.setScrollDataIndex(n)}))}))}(t)}var pF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="dataZoom.inside",e.defaultOption=kc(lz.defaultOption,{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}),e}(lz),dF=Vo();function fF(t,e,n){dF(t).coordSysRecordMap.each((function(t){var i=t.dataZoomInfoMap.get(e.uid);i&&(i.getRange=n)}))}function gF(t,e){if(e){t.removeKey(e.model.uid);var n=e.controller;n&&n.dispose()}}function yF(t,e){t.isDisposed()||t.dispatchAction({type:"dataZoom",animation:{easing:"cubicOut",duration:100},batch:e})}function vF(t,e,n,i){return t.coordinateSystem.containPoint([n,i])}function mF(t){t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,(function(t,e){var n=dF(e),i=n.coordSysRecordMap||(n.coordSysRecordMap=yt());i.each((function(t){t.dataZoomInfoMap=null})),t.eachComponent({mainType:"dataZoom",subType:"inside"},(function(t){E(az(t).infoList,(function(n){var r=n.model.uid,o=i.get(r)||i.set(r,function(t,e){var n={model:e,containsPoint:H(vF,e),dispatchAction:H(yF,t),dataZoomInfoMap:null,controller:null},i=n.controller=new nT(t.getZr());return E(["pan","zoom","scrollMove"],(function(t){i.on(t,(function(e){var i=[];n.dataZoomInfoMap.each((function(r){if(e.isAvailableBehavior(r.model.option)){var o=(r.getRange||{})[t],a=o&&o(r.dzReferCoordSysInfo,n.model.mainType,n.controller,e);!r.model.get("disabled",!0)&&a&&i.push({dataZoomId:r.model.id,start:a[0],end:a[1]})}})),i.length&&n.dispatchAction(i)}))})),n}(e,n.model));(o.dataZoomInfoMap||(o.dataZoomInfoMap=yt())).set(t.uid,{dzReferCoordSysInfo:n,model:t,getRange:null})}))})),i.each((function(t){var e,n=t.controller,r=t.dataZoomInfoMap;if(r){var o=r.keys()[0];null!=o&&(e=r.get(o))}if(e){var a=function(t){var e,n="type_",i={type_true:2,type_move:1,type_false:0,type_undefined:-1},r=!0;return t.each((function(t){var o=t.model,a=!o.get("disabled",!0)&&(!o.get("zoomLock",!0)||"move");i[n+a]>i[n+e]&&(e=a),r=r&&o.get("preventDefaultMouseMove",!0)})),{controlType:e,opt:{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!0,preventDefaultMouseMove:!!r}}}(r);n.enable(a.controlType,a.opt),n.setPointerChecker(t.containsPoint),Hg(t,"dispatchAction",e.model.get("throttle",!0),"fixRate")}else gF(i,t)}))}))}var xF=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="dataZoom.inside",e}return n(e,t),e.prototype.render=function(e,n,i){t.prototype.render.apply(this,arguments),e.noTarget()?this._clear():(this.range=e.getPercentRange(),fF(i,e,{pan:W(_F.pan,this),zoom:W(_F.zoom,this),scrollMove:W(_F.scrollMove,this)}))},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){!function(t,e){for(var n=dF(t).coordSysRecordMap,i=n.keys(),r=0;r0?s.pixelStart+s.pixelLength-s.pixel:s.pixel-s.pixelStart)/s.pixelLength*(o[1]-o[0])+o[0],u=Math.max(1/i.scale,0);o[0]=(o[0]-l)*u+l,o[1]=(o[1]-l)*u+l;var h=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return zk(0,o,[0,100],0,h.minSpan,h.maxSpan),this.range=o,r[0]!==o[0]||r[1]!==o[1]?o:void 0}},pan:bF((function(t,e,n,i,r,o){var a=wF[i]([o.oldX,o.oldY],[o.newX,o.newY],e,r,n);return a.signal*(t[1]-t[0])*a.pixel/a.pixelLength})),scrollMove:bF((function(t,e,n,i,r,o){return wF[i]([0,0],[o.scrollDelta,o.scrollDelta],e,r,n).signal*(t[1]-t[0])*o.scrollDelta}))};function bF(t){return function(e,n,i,r){var o=this.range,a=o.slice(),s=e.axisModels[0];if(s)return zk(t(a,s,e,n,i,r),a,[0,100],"all"),this.range=a,o[0]!==a[0]||o[1]!==a[1]?a:void 0}}var wF={grid:function(t,e,n,i,r){var o=n.axis,a={},s=r.model.coordinateSystem.getRect();return t=t||[0,0],"x"===o.dim?(a.pixel=e[0]-t[0],a.pixelLength=s.width,a.pixelStart=s.x,a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=s.height,a.pixelStart=s.y,a.signal=o.inverse?-1:1),a},polar:function(t,e,n,i,r){var o=n.axis,a={},s=r.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),u=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===n.mainType?(a.pixel=e[0]-t[0],a.pixelLength=l[1]-l[0],a.pixelStart=l[0],a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=u[1]-u[0],a.pixelStart=u[0],a.signal=o.inverse?-1:1),a},singleAxis:function(t,e,n,i,r){var o=n.axis,a=r.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===o.orient?(s.pixel=e[0]-t[0],s.pixelLength=a.width,s.pixelStart=a.x,s.signal=o.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=a.height,s.pixelStart=a.y,s.signal=o.inverse?-1:1),s}};function SF(t){mz(t),t.registerComponentModel(pF),t.registerComponentView(xF),mF(t)}var MF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="dataZoom.slider",e.layoutMode="box",e.defaultOption=kc(lz.defaultOption,{show:!0,right:"ph",top:"ph",width:"ph",height:"ph",left:null,bottom:null,borderColor:"#d2dbee",borderRadius:3,backgroundColor:"rgba(47,69,84,0)",dataBackground:{lineStyle:{color:"#d2dbee",width:.5},areaStyle:{color:"#d2dbee",opacity:.2}},selectedDataBackground:{lineStyle:{color:"#8fb0f7",width:.5},areaStyle:{color:"#8fb0f7",opacity:.2}},fillerColor:"rgba(135,175,274,0.2)",handleIcon:"path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z",handleSize:"100%",handleStyle:{color:"#fff",borderColor:"#ACB8D1"},moveHandleSize:7,moveHandleIcon:"path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z",moveHandleStyle:{color:"#D2DBEE",opacity:.7},showDetail:!0,showDataShadow:"auto",realtime:!0,zoomLock:!1,textStyle:{color:"#6E7079"},brushSelect:!0,brushStyle:{color:"rgba(135,175,274,0.15)"},emphasis:{handleLabel:{show:!0},handleStyle:{borderColor:"#8FB0F7"},moveHandleStyle:{color:"#8FB0F7"}}}),e}(lz),IF=Ws,TF="horizontal",CF="vertical",DF=["line","bar","candlestick","scatter"],AF={easing:"cubicOut",duration:100,delay:0},kF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._displayables={},n}return n(e,t),e.prototype.init=function(t,e){this.api=e,this._onBrush=W(this._onBrush,this),this._onBrushEnd=W(this._onBrushEnd,this)},e.prototype.render=function(e,n,i,r){if(t.prototype.render.apply(this,arguments),Hg(this,"_dispatchZoomAction",e.get("throttle"),"fixRate"),this._orient=e.getOrient(),!1!==e.get("show")){if(e.noTarget())return this._clear(),void this.group.removeAll();r&&"dataZoom"===r.type&&r.from===this.uid||this._buildView(),this._updateView()}else this.group.removeAll()},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){Yg(this,"_dispatchZoomAction");var t=this.api.getZr();t.off("mousemove",this._onBrush),t.off("mouseup",this._onBrushEnd)},e.prototype._buildView=function(){var t=this.group;t.removeAll(),this._brushing=!1,this._displayables.brushRect=null,this._resetLocation(),this._resetInterval();var e=this._displayables.sliderGroup=new Br;this._renderBackground(),this._renderHandle(),this._renderDataShadow(),t.add(e),this._positionGroup()},e.prototype._resetLocation=function(){var t=this.dataZoomModel,e=this.api,n=t.get("brushSelect")?7:0,i=this._findCoordRect(),r={width:e.getWidth(),height:e.getHeight()},o=this._orient===TF?{right:r.width-i.x-i.width,top:r.height-30-7-n,width:i.width,height:30}:{right:7,top:i.y,width:30,height:i.height},a=Rp(t.option);E(["right","top","width","height"],(function(t){"ph"===a[t]&&(a[t]=o[t])}));var s=kp(a,r);this._location={x:s.x,y:s.y},this._size=[s.width,s.height],this._orient===CF&&this._size.reverse()},e.prototype._positionGroup=function(){var t=this.group,e=this._location,n=this._orient,i=this.dataZoomModel.getFirstTargetAxisModel(),r=i&&i.get("inverse"),o=this._displayables.sliderGroup,a=(this._dataShadowInfo||{}).otherAxisInverse;o.attr(n!==TF||r?n===TF&&r?{scaleY:a?1:-1,scaleX:-1}:n!==CF||r?{scaleY:a?-1:1,scaleX:-1,rotation:Math.PI/2}:{scaleY:a?-1:1,scaleX:1,rotation:Math.PI/2}:{scaleY:a?1:-1,scaleX:1});var s=t.getBoundingRect([o]);t.x=e.x-s.x,t.y=e.y-s.y,t.markRedraw()},e.prototype._getViewExtent=function(){return[0,this._size[0]]},e.prototype._renderBackground=function(){var t=this.dataZoomModel,e=this._size,n=this._displayables.sliderGroup,i=t.get("brushSelect");n.add(new IF({silent:!0,shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:t.get("backgroundColor")},z2:-40}));var r=new IF({shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:"transparent"},z2:0,onclick:W(this._onClickPanel,this)}),o=this.api.getZr();i?(r.on("mousedown",this._onBrushStart,this),r.cursor="crosshair",o.on("mousemove",this._onBrush),o.on("mouseup",this._onBrushEnd)):(o.off("mousemove",this._onBrush),o.off("mouseup",this._onBrushEnd)),n.add(r)},e.prototype._renderDataShadow=function(){var t=this._dataShadowInfo=this._prepareDataShadowInfo();if(this._displayables.dataShadowSegs=[],t){var e=this._size,n=this._shadowSize||[],i=t.series,r=i.getRawData(),o=i.getShadowDim&&i.getShadowDim(),a=o&&r.getDimensionInfo(o)?i.getShadowDim():t.otherDim;if(null!=a){var s=this._shadowPolygonPts,l=this._shadowPolylinePts;if(r!==this._shadowData||a!==this._shadowDim||e[0]!==n[0]||e[1]!==n[1]){var u=r.getDataExtent(a),h=.3*(u[1]-u[0]);u=[u[0]-h,u[1]+h];var c,p=[0,e[1]],d=[0,e[0]],f=[[e[0],0],[0,0]],g=[],y=d[1]/(r.count()-1),v=0,m=Math.round(r.count()/e[0]);r.each([a],(function(t,e){if(m>0&&e%m)v+=y;else{var n=null==t||isNaN(t)||""===t,i=n?0:Kr(t,u,p,!0);n&&!c&&e?(f.push([f[f.length-1][0],0]),g.push([g[g.length-1][0],0])):!n&&c&&(f.push([v,0]),g.push([v,0])),f.push([v,i]),g.push([v,i]),v+=y,c=n}})),s=this._shadowPolygonPts=f,l=this._shadowPolylinePts=g}this._shadowData=r,this._shadowDim=a,this._shadowSize=[e[0],e[1]];for(var x=this.dataZoomModel,_=0;_<3;_++){var b=w(1===_);this._displayables.sliderGroup.add(b),this._displayables.dataShadowSegs.push(b)}}}function w(t){var e=x.getModel(t?"selectedDataBackground":"dataBackground"),n=new Br,i=new Xu({shape:{points:s},segmentIgnoreThreshold:1,style:e.getModel("areaStyle").getAreaStyle(),silent:!0,z2:-20}),r=new Zu({shape:{points:l},segmentIgnoreThreshold:1,style:e.getModel("lineStyle").getLineStyle(),silent:!0,z2:-19});return n.add(i),n.add(r),n}},e.prototype._prepareDataShadowInfo=function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(!1!==e){var n,i=this.ecModel;return t.eachTargetAxis((function(r,o){E(t.getAxisProxy(r,o).getTargetSeriesModels(),(function(t){if(!(n||!0!==e&&P(DF,t.get("type"))<0)){var a,s=i.getComponent(rz(r),o).axis,l=function(t){var e={x:"y",y:"x",radius:"angle",angle:"radius"};return e[t]}(r),u=t.coordinateSystem;null!=l&&u.getOtherAxis&&(a=u.getOtherAxis(s).inverse),l=t.getData().mapDimension(l),n={thisAxis:s,series:t,thisDim:r,otherDim:l,otherAxisInverse:a}}}),this)}),this),n}},e.prototype._renderHandle=function(){var t=this.group,e=this._displayables,n=e.handles=[null,null],i=e.handleLabels=[null,null],r=this._displayables.sliderGroup,o=this._size,a=this.dataZoomModel,s=this.api,l=a.get("borderRadius")||0,u=a.get("brushSelect"),h=e.filler=new IF({silent:u,style:{fill:a.get("fillerColor")},textConfig:{position:"inside"}});r.add(h),r.add(new IF({silent:!0,subPixelOptimize:!0,shape:{x:0,y:0,width:o[0],height:o[1],r:l},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:1,fill:"rgba(0,0,0,0)"}})),E([0,1],(function(e){var o=a.get("handleIcon");!Wy[o]&&o.indexOf("path://")<0&&o.indexOf("image://")<0&&(o="path://"+o);var s=Xy(o,-1,0,2,2,null,!0);s.attr({cursor:LF(this._orient),draggable:!0,drift:W(this._onDragMove,this,e),ondragend:W(this._onDragEnd,this),onmouseover:W(this._showDataInfo,this,!0),onmouseout:W(this._showDataInfo,this,!1),z2:5});var l=s.getBoundingRect(),u=a.get("handleSize");this._handleHeight=$r(u,this._size[1]),this._handleWidth=l.width/l.height*this._handleHeight,s.setStyle(a.getModel("handleStyle").getItemStyle()),s.style.strokeNoScale=!0,s.rectHover=!0,s.ensureState("emphasis").style=a.getModel(["emphasis","handleStyle"]).getItemStyle(),Ul(s);var h=a.get("handleColor");null!=h&&(s.style.fill=h),r.add(n[e]=s);var c=a.getModel("textStyle"),p=(a.get("handleLabel")||{}).show||!1;t.add(i[e]=new Xs({silent:!0,invisible:!p,style:oc(c,{x:0,y:0,text:"",verticalAlign:"middle",align:"center",fill:c.getTextColor(),font:c.getFont()}),z2:10}))}),this);var c=h;if(u){var p=$r(a.get("moveHandleSize"),o[1]),d=e.moveHandle=new Ws({style:a.getModel("moveHandleStyle").getItemStyle(),silent:!0,shape:{r:[0,0,2,2],y:o[1]-.5,height:p}}),f=.8*p,g=e.moveHandleIcon=Xy(a.get("moveHandleIcon"),-f/2,-f/2,f,f,"#fff",!0);g.silent=!0,g.y=o[1]+p/2-.5,d.ensureState("emphasis").style=a.getModel(["emphasis","moveHandleStyle"]).getItemStyle();var y=Math.min(o[1]/2,Math.max(p,10));(c=e.moveZone=new Ws({invisible:!0,shape:{y:o[1]-y,height:p+y}})).on("mouseover",(function(){s.enterEmphasis(d)})).on("mouseout",(function(){s.leaveEmphasis(d)})),r.add(d),r.add(g),r.add(c)}c.attr({draggable:!0,cursor:LF(this._orient),drift:W(this._onDragMove,this,"all"),ondragstart:W(this._showDataInfo,this,!0),ondragend:W(this._onDragEnd,this),onmouseover:W(this._showDataInfo,this,!0),onmouseout:W(this._showDataInfo,this,!1)})},e.prototype._resetInterval=function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[Kr(t[0],[0,100],e,!0),Kr(t[1],[0,100],e,!0)]},e.prototype._updateInterval=function(t,e){var n=this.dataZoomModel,i=this._handleEnds,r=this._getViewExtent(),o=n.findRepresentativeAxisProxy().getMinMaxSpan(),a=[0,100];zk(e,i,r,n.get("zoomLock")?"all":t,null!=o.minSpan?Kr(o.minSpan,a,r,!0):null,null!=o.maxSpan?Kr(o.maxSpan,a,r,!0):null);var s=this._range,l=this._range=Qr([Kr(i[0],r,a,!0),Kr(i[1],r,a,!0)]);return!s||s[0]!==l[0]||s[1]!==l[1]},e.prototype._updateView=function(t){var e=this._displayables,n=this._handleEnds,i=Qr(n.slice()),r=this._size;E([0,1],(function(t){var i=e.handles[t],o=this._handleHeight;i.attr({scaleX:o/2,scaleY:o/2,x:n[t]+(t?-1:1),y:r[1]/2-o/2})}),this),e.filler.setShape({x:i[0],y:0,width:i[1]-i[0],height:r[1]});var o={x:i[0],width:i[1]-i[0]};e.moveHandle&&(e.moveHandle.setShape(o),e.moveZone.setShape(o),e.moveZone.getBoundingRect(),e.moveHandleIcon&&e.moveHandleIcon.attr("x",o.x+o.width/2));for(var a=e.dataShadowSegs,s=[0,i[0],i[1],r[0]],l=0;le[0]||n[1]<0||n[1]>e[1])){var i=this._handleEnds,r=(i[0]+i[1])/2,o=this._updateInterval("all",n[0]-r);this._updateView(),o&&this._dispatchZoomAction(!1)}},e.prototype._onBrushStart=function(t){var e=t.offsetX,n=t.offsetY;this._brushStart=new De(e,n),this._brushing=!0,this._brushStartTime=+new Date},e.prototype._onBrushEnd=function(t){if(this._brushing){var e=this._displayables.brushRect;if(this._brushing=!1,e){e.attr("ignore",!0);var n=e.shape;if(!(+new Date-this._brushStartTime<200&&Math.abs(n.width)<5)){var i=this._getViewExtent(),r=[0,100];this._range=Qr([Kr(n.x,i,r,!0),Kr(n.x+n.width,i,r,!0)]),this._handleEnds=[n.x,n.x+n.width],this._updateView(),this._dispatchZoomAction(!1)}}}},e.prototype._onBrush=function(t){this._brushing&&(de(t.event),this._updateBrushRect(t.offsetX,t.offsetY))},e.prototype._updateBrushRect=function(t,e){var n=this._displayables,i=this.dataZoomModel,r=n.brushRect;r||(r=n.brushRect=new IF({silent:!0,style:i.getModel("brushStyle").getItemStyle()}),n.sliderGroup.add(r)),r.attr("ignore",!1);var o=this._brushStart,a=this._displayables.sliderGroup,s=a.transformCoordToLocal(t,e),l=a.transformCoordToLocal(o.x,o.y),u=this._size;s[0]=Math.max(Math.min(u[0],s[0]),0),r.setShape({x:l[0],y:0,width:s[0]-l[0],height:u[1]})},e.prototype._dispatchZoomAction=function(t){var e=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,animation:t?AF:null,start:e[0],end:e[1]})},e.prototype._findCoordRect=function(){var t,e=az(this.dataZoomModel).infoList;if(!t&&e.length){var n=e[0].model.coordinateSystem;t=n.getRect&&n.getRect()}if(!t){var i=this.api.getWidth(),r=this.api.getHeight();t={x:.2*i,y:.2*r,width:.6*i,height:.6*r}}return t},e.type="dataZoom.slider",e}(cz);function LF(t){return"vertical"===t?"ns-resize":"ew-resize"}function PF(t){t.registerComponentModel(MF),t.registerComponentView(kF),mz(t)}var OF=function(t,e,n){var i=T((RF[t]||{})[e]);return n&&Y(i)?i[i.length-1]:i},RF={color:{active:["#006edd","#e0ffff"],inactive:["rgba(0,0,0,0)"]},colorHue:{active:[0,360],inactive:[0,0]},colorSaturation:{active:[.3,1],inactive:[0,0]},colorLightness:{active:[.9,.5],inactive:[0,0]},colorAlpha:{active:[.3,1],inactive:[0,0]},opacity:{active:[.3,1],inactive:[0,0]},symbol:{active:["circle","roundRect","diamond"],inactive:["none"]},symbolSize:{active:[10,50],inactive:[0,0]}},NF=kD.mapVisual,EF=kD.eachVisual,zF=Y,VF=E,BF=Qr,FF=Kr,GF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.stateList=["inRange","outOfRange"],n.replacableOptionKeys=["inRange","outOfRange","target","controller","color"],n.layoutMode={type:"box",ignoreSize:!0},n.dataBound=[-1/0,1/0],n.targetVisuals={},n.controllerVisuals={},n}return n(e,t),e.prototype.init=function(t,e,n){this.mergeDefaultAndTheme(t,n)},e.prototype.optionUpdated=function(t,e){var n=this.option;!e&&RV(n,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},e.prototype.resetVisual=function(t){var e=this.stateList;t=W(t,this),this.controllerVisuals=OV(this.option.controller,e,t),this.targetVisuals=OV(this.option.target,e,t)},e.prototype.getItemSymbol=function(){return null},e.prototype.getTargetSeriesIndices=function(){var t=this.option.seriesIndex,e=[];return null==t||"all"===t?this.ecModel.eachSeries((function(t,n){e.push(n)})):e=To(t),e},e.prototype.eachTargetSeries=function(t,e){E(this.getTargetSeriesIndices(),(function(n){var i=this.ecModel.getSeriesByIndex(n);i&&t.call(e,i)}),this)},e.prototype.isTargetSeries=function(t){var e=!1;return this.eachTargetSeries((function(n){n===t&&(e=!0)})),e},e.prototype.formatValueText=function(t,e,n){var i,r=this.option,o=r.precision,a=this.dataBound,s=r.formatter;n=n||["<",">"],Y(t)&&(t=t.slice(),i=!0);var l=e?t:i?[u(t[0]),u(t[1])]:u(t);return U(s)?s.replace("{value}",i?l[0]:l).replace("{value2}",i?l[1]:l):X(s)?i?s(t[0],t[1]):s(t):i?t[0]===a[0]?n[0]+" "+l[1]:t[1]===a[1]?n[1]+" "+l[0]:l[0]+" - "+l[1]:l;function u(t){return t===a[0]?"min":t===a[1]?"max":(+t).toFixed(Math.min(o,20))}},e.prototype.resetExtent=function(){var t=this.option,e=BF([t.min,t.max]);this._dataExtent=e},e.prototype.getDataDimensionIndex=function(t){var e=this.option.dimension;if(null!=e)return t.getDimensionIndex(e);for(var n=t.dimensions,i=n.length-1;i>=0;i--){var r=n[i],o=t.getDimensionInfo(r);if(!o.isCalculationCoord)return o.storeDimIndex}},e.prototype.getExtent=function(){return this._dataExtent.slice()},e.prototype.completeVisualOption=function(){var t=this.ecModel,e=this.option,n={inRange:e.inRange,outOfRange:e.outOfRange},i=e.target||(e.target={}),r=e.controller||(e.controller={});C(i,n),C(r,n);var o=this.isCategory();function a(n){zF(e.color)&&!n.inRange&&(n.inRange={color:e.color.slice().reverse()}),n.inRange=n.inRange||{color:t.get("gradientColor")}}a.call(this,i),a.call(this,r),function(t,e,n){var i=t[e],r=t[n];i&&!r&&(r=t[n]={},VF(i,(function(t,e){if(kD.isValidType(e)){var n=OF(e,"inactive",o);null!=n&&(r[e]=n,"color"!==e||r.hasOwnProperty("opacity")||r.hasOwnProperty("colorAlpha")||(r.opacity=[0,0]))}})))}.call(this,i,"inRange","outOfRange"),function(t){var e=(t.inRange||{}).symbol||(t.outOfRange||{}).symbol,n=(t.inRange||{}).symbolSize||(t.outOfRange||{}).symbolSize,i=this.get("inactiveColor"),r=this.getItemSymbol()||"roundRect";VF(this.stateList,(function(a){var s=this.itemSize,l=t[a];l||(l=t[a]={color:o?i:[i]}),null==l.symbol&&(l.symbol=e&&T(e)||(o?r:[r])),null==l.symbolSize&&(l.symbolSize=n&&T(n)||(o?s[0]:[s[0],s[0]])),l.symbol=NF(l.symbol,(function(t){return"none"===t?r:t}));var u=l.symbolSize;if(null!=u){var h=-1/0;EF(u,(function(t){t>h&&(h=t)})),l.symbolSize=NF(u,(function(t){return FF(t,[0,h],[0,s[0]],!0)}))}}),this)}.call(this,r)},e.prototype.resetItemSize=function(){this.itemSize=[parseFloat(this.get("itemWidth")),parseFloat(this.get("itemHeight"))]},e.prototype.isCategory=function(){return!!this.option.categories},e.prototype.setSelected=function(t){},e.prototype.getSelected=function(){return null},e.prototype.getValueState=function(t){return null},e.prototype.getVisualMeta=function(t){return null},e.type="visualMap",e.dependencies=["series"],e.defaultOption={show:!0,z:4,seriesIndex:"all",min:0,max:200,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",contentColor:"#5793f3",inactiveColor:"#aaa",borderWidth:0,padding:5,textGap:10,precision:0,textStyle:{color:"#333"}},e}(zp),WF=[20,140],HF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(e,n){t.prototype.optionUpdated.apply(this,arguments),this.resetExtent(),this.resetVisual((function(t){t.mappingMethod="linear",t.dataExtent=this.getExtent()})),this._resetRange()},e.prototype.resetItemSize=function(){t.prototype.resetItemSize.apply(this,arguments);var e=this.itemSize;(null==e[0]||isNaN(e[0]))&&(e[0]=WF[0]),(null==e[1]||isNaN(e[1]))&&(e[1]=WF[1])},e.prototype._resetRange=function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):Y(e)&&(e[0]>e[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},e.prototype.completeVisualOption=function(){t.prototype.completeVisualOption.apply(this,arguments),E(this.stateList,(function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=e[1]/3)}),this)},e.prototype.setSelected=function(t){this.option.range=t.slice(),this._resetRange()},e.prototype.getSelected=function(){var t=this.getExtent(),e=Qr((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=n[1]||t<=e[1])?"inRange":"outOfRange"},e.prototype.findTargetDataIndices=function(t){var e=[];return this.eachTargetSeries((function(n){var i=[],r=n.getData();r.each(this.getDataDimensionIndex(r),(function(e,n){t[0]<=e&&e<=t[1]&&i.push(n)}),this),e.push({seriesId:n.id,dataIndex:i})}),this),e},e.prototype.getVisualMeta=function(t){var e=YF(this,"outOfRange",this.getExtent()),n=YF(this,"inRange",this.option.range.slice()),i=[];function r(e,n){i.push({value:e,color:t(e,n)})}for(var o=0,a=0,s=n.length,l=e.length;at[1])break;n.push({color:this.getControllerVisual(o,"color",e),offset:r/100})}return n.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),n},e.prototype._createBarPoints=function(t,e){var n=this.visualMapModel.itemSize;return[[n[0]-e[0],t[0]],[n[0],t[0]],[n[0],t[1]],[n[0]-e[1],t[1]]]},e.prototype._createBarGroup=function(t){var e=this._orient,n=this.visualMapModel.get("inverse");return new Br("horizontal"!==e||n?"horizontal"===e&&n?{scaleX:"bottom"===t?-1:1,rotation:-Math.PI/2}:"vertical"!==e||n?{scaleX:"left"===t?1:-1}:{scaleX:"left"===t?1:-1,scaleY:-1}:{scaleX:"bottom"===t?1:-1,rotation:Math.PI/2})},e.prototype._updateHandle=function(t,e){if(this._useHandle){var n=this._shapes,i=this.visualMapModel,r=n.handleThumbs,o=n.handleLabels,a=i.itemSize,s=i.getExtent(),l=this._applyTransform("left",n.mainGroup);KF([0,1],(function(u){var h=r[u];h.setStyle("fill",e.handlesColor[u]),h.y=t[u];var c=qF(t[u],[0,a[1]],s,!0),p=this.getControllerVisual(c,"symbolSize");h.scaleX=h.scaleY=p/a[0],h.x=a[0]-p/2;var d=Fh(n.handleLabelPoints[u],Bh(h,this.group));if("horizontal"===this._orient){var f="left"===l||"top"===l?(a[0]-p)/2:(a[0]-p)/-2;d[1]+=f}o[u].setStyle({x:d[0],y:d[1],text:i.formatValueText(this._dataInterval[u]),verticalAlign:"middle",align:"vertical"===this._orient?this._applyTransform("left",n.mainGroup):"center"})}),this)}},e.prototype._showIndicator=function(t,e,n,i){var r=this.visualMapModel,o=r.getExtent(),a=r.itemSize,s=[0,a[1]],l=this._shapes,u=l.indicator;if(u){u.attr("invisible",!1);var h=this.getControllerVisual(t,"color",{convertOpacityToAlpha:!0}),c=this.getControllerVisual(t,"symbolSize"),p=qF(t,o,s,!0),d=a[0]-c/2,f={x:u.x,y:u.y};u.y=p,u.x=d;var g=Fh(l.indicatorLabelPoint,Bh(u,this.group)),y=l.indicatorLabel;y.attr("invisible",!1);var v=this._applyTransform("left",l.mainGroup),m="horizontal"===this._orient;y.setStyle({text:(n||"")+r.formatValueText(e),verticalAlign:m?v:"middle",align:m?"center":v});var x={x:d,y:p,style:{fill:h}},_={style:{x:g[0],y:g[1]}};if(r.ecModel.isAnimationEnabled()&&!this._firstShowIndicator){var b={duration:100,easing:"cubicInOut",additive:!0};u.x=f.x,u.y=f.y,u.animateTo(x,b),y.animateTo(_,b)}else u.attr(x),y.attr(_);this._firstShowIndicator=!1;var w=this._shapes.handleLabels;if(w)for(var S=0;Sr[1]&&(u[1]=1/0),e&&(u[0]===-1/0?this._showIndicator(l,u[1],"< ",a):u[1]===1/0?this._showIndicator(l,u[0],"> ",a):this._showIndicator(l,l,"≈ ",a));var h=this._hoverLinkDataIndices,c=[];(e||eG(n))&&(c=this._hoverLinkDataIndices=n.findTargetDataIndices(u));var p=function(t,e){var n={},i={};return r(t||[],n),r(e||[],i,n),[o(n),o(i)];function r(t,e,n){for(var i=0,r=t.length;i=0&&(r.dimension=o,i.push(r))}})),t.getData().setVisual("visualMeta",i)}}];function aG(t,e,n,i){for(var r=e.targetVisuals[i],o=kD.prepareVisualTypes(r),a={color:Ay(t.getData(),"color")},s=0,l=o.length;s0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"})),t.registerAction(iG,rG),E(oG,(function(e){t.registerVisual(t.PRIORITY.VISUAL.COMPONENT,e)})),t.registerPreprocessor(lG))}function pG(t){t.registerComponentModel(HF),t.registerComponentView(QF),cG(t)}var dG=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._pieceList=[],n}return n(e,t),e.prototype.optionUpdated=function(e,n){t.prototype.optionUpdated.apply(this,arguments),this.resetExtent();var i=this._mode=this._determineMode();this._pieceList=[],fG[this._mode].call(this,this._pieceList),this._resetSelected(e,n);var r=this.option.categories;this.resetVisual((function(t,e){"categories"===i?(t.mappingMethod="category",t.categories=T(r)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=z(this._pieceList,(function(t){return t=T(t),"inRange"!==e&&(t.visual=null),t})))}))},e.prototype.completeVisualOption=function(){var e=this.option,n={},i=kD.listVisualTypes(),r=this.isCategory();function o(t,e,n){return t&&t[e]&&t[e].hasOwnProperty(n)}E(e.pieces,(function(t){E(i,(function(e){t.hasOwnProperty(e)&&(n[e]=1)}))})),E(n,(function(t,n){var i=!1;E(this.stateList,(function(t){i=i||o(e,t,n)||o(e.target,t,n)}),this),!i&&E(this.stateList,(function(t){(e[t]||(e[t]={}))[n]=OF(n,"inRange"===t?"active":"inactive",r)}))}),this),t.prototype.completeVisualOption.apply(this,arguments)},e.prototype._resetSelected=function(t,e){var n=this.option,i=this._pieceList,r=(e?n:t).selected||{};if(n.selected=r,E(i,(function(t,e){var n=this.getSelectedMapKey(t);r.hasOwnProperty(n)||(r[n]=!0)}),this),"single"===n.selectedMode){var o=!1;E(i,(function(t,e){var n=this.getSelectedMapKey(t);r[n]&&(o?r[n]=!1:o=!0)}),this)}},e.prototype.getItemSymbol=function(){return this.get("itemSymbol")},e.prototype.getSelectedMapKey=function(t){return"categories"===this._mode?t.value+"":t.index+""},e.prototype.getPieceList=function(){return this._pieceList},e.prototype._determineMode=function(){var t=this.option;return t.pieces&&t.pieces.length>0?"pieces":this.option.categories?"categories":"splitNumber"},e.prototype.setSelected=function(t){this.option.selected=T(t)},e.prototype.getValueState=function(t){var e=kD.findPieceIndex(t,this._pieceList);return null!=e&&this.option.selected[this.getSelectedMapKey(this._pieceList[e])]?"inRange":"outOfRange"},e.prototype.findTargetDataIndices=function(t){var e=[],n=this._pieceList;return this.eachTargetSeries((function(i){var r=[],o=i.getData();o.each(this.getDataDimensionIndex(o),(function(e,i){kD.findPieceIndex(e,n)===t&&r.push(i)}),this),e.push({seriesId:i.id,dataIndex:r})}),this),e},e.prototype.getRepresentValue=function(t){var e;if(this.isCategory())e=t.value;else if(null!=t.value)e=t.value;else{var n=t.interval||[];e=n[0]===-1/0&&n[1]===1/0?0:(n[0]+n[1])/2}return e},e.prototype.getVisualMeta=function(t){if(!this.isCategory()){var e=[],n=["",""],i=this,r=this._pieceList.slice();if(r.length){var o=r[0].interval[0];o!==-1/0&&r.unshift({interval:[-1/0,o]}),(o=r[r.length-1].interval[1])!==1/0&&r.push({interval:[o,1/0]})}else r.push({interval:[-1/0,1/0]});var a=-1/0;return E(r,(function(t){var e=t.interval;e&&(e[0]>a&&s([a,e[0]],"outOfRange"),s(e.slice()),a=e[1])}),this),{stops:e,outerColors:n}}function s(r,o){var a=i.getRepresentValue({interval:r});o||(o=i.getValueState(a));var s=t(a,o);r[0]===-1/0?n[0]=s:r[1]===1/0?n[1]=s:e.push({value:r[0],color:s},{value:r[1],color:s})}},e.type="visualMap.piecewise",e.defaultOption=kc(GF.defaultOption,{selected:null,minOpen:!1,maxOpen:!1,align:"auto",itemWidth:20,itemHeight:14,itemSymbol:"roundRect",pieces:null,categories:null,splitNumber:5,selectedMode:"multiple",itemGap:10,hoverLink:!0}),e}(GF),fG={splitNumber:function(t){var e=this.option,n=Math.min(e.precision,20),i=this.getExtent(),r=e.splitNumber;r=Math.max(parseInt(r,10),1),e.splitNumber=r;for(var o=(i[1]-i[0])/r;+o.toFixed(n)!==o&&n<5;)n++;e.precision=n,o=+o.toFixed(n),e.minOpen&&t.push({interval:[-1/0,i[0]],close:[0,0]});for(var a=0,s=i[0];a","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,n)}),this)}};function gG(t,e){var n=t.inverse;("vertical"===t.orient?!n:n)&&e.reverse()}var yG=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.doRender=function(){var t=this.group;t.removeAll();var e=this.visualMapModel,n=e.get("textGap"),i=e.textStyleModel,r=i.getFont(),o=i.getTextColor(),a=this._getItemAlign(),s=e.itemSize,l=this._getViewData(),u=l.endsText,h=it(e.get("showLabel",!0),!u),c=!e.get("selectedMode");u&&this._renderEndsText(t,u[0],s,h,a),E(l.viewPieceList,(function(i){var l=i.piece,u=new Br;u.onclick=W(this._onItemClick,this,l),this._enableHoverLink(u,i.indexInModelPieceList);var p=e.getRepresentValue(l);if(this._createItemSymbol(u,p,[0,0,s[0],s[1]],c),h){var d=this.visualMapModel.getValueState(p);u.add(new Xs({style:{x:"right"===a?-n:s[0]+n,y:s[1]/2,text:l.text,verticalAlign:"middle",align:a,font:r,fill:o,opacity:"outOfRange"===d?.5:1},silent:c}))}t.add(u)}),this),u&&this._renderEndsText(t,u[1],s,h,a),Ap(e.get("orient"),t,e.get("itemGap")),this.renderBackground(t),this.positionGroup(t)},e.prototype._enableHoverLink=function(t,e){var n=this;t.on("mouseover",(function(){return i("highlight")})).on("mouseout",(function(){return i("downplay")}));var i=function(t){var i=n.visualMapModel;i.option.hoverLink&&n.api.dispatchAction({type:t,batch:jF(i.findTargetDataIndices(e),i)})}},e.prototype._getItemAlign=function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return ZF(t,this.api,t.itemSize);var n=e.align;return n&&"auto"!==n||(n="left"),n},e.prototype._renderEndsText=function(t,e,n,i,r){if(e){var o=new Br,a=this.visualMapModel.textStyleModel;o.add(new Xs({style:oc(a,{x:i?"right"===r?n[0]:0:n[0]/2,y:n[1]/2,verticalAlign:"middle",align:i?r:"center",text:e})})),t.add(o)}},e.prototype._getViewData=function(){var t=this.visualMapModel,e=z(t.getPieceList(),(function(t,e){return{piece:t,indexInModelPieceList:e}})),n=t.get("text"),i=t.get("orient"),r=t.get("inverse");return("horizontal"===i?r:!r)?e.reverse():n&&(n=n.slice().reverse()),{viewPieceList:e,endsText:n}},e.prototype._createItemSymbol=function(t,e,n,i){var r=Xy(this.getControllerVisual(e,"symbol"),n[0],n[1],n[2],n[3],this.getControllerVisual(e,"color"));r.silent=i,t.add(r)},e.prototype._onItemClick=function(t){var e=this.visualMapModel,n=e.option,i=n.selectedMode;if(i){var r=T(n.selected),o=e.getSelectedMapKey(t);"single"===i||!0===i?(r[o]=!0,E(r,(function(t,e){r[e]=e===o}))):r[o]=!r[o],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:r})}},e.type="visualMap.piecewise",e}(XF);function vG(t){t.registerComponentModel(dG),t.registerComponentView(yG),cG(t)}var mG={label:{enabled:!0},decal:{show:!1}},xG=Vo(),_G={};function bG(t,e){var n=t.getModel("aria");if(n.get("enabled")){var i=T(mG);C(i.label,t.getLocaleModel().get("aria"),!1),C(n.option,i,!1),function(){if(n.getModel("decal").get("show")){var e=yt();t.eachSeries((function(t){if(!t.isColorBySeries()){var n=e.get(t.type);n||(n={},e.set(t.type,n)),xG(t).scope=n}})),t.eachRawSeries((function(e){if(!t.isSeriesFiltered(e))if(X(e.enableAriaDecal))e.enableAriaDecal();else{var n=e.getData();if(e.isColorBySeries()){var i=pd(e.ecModel,e.name,_G,t.getSeriesCount()),r=n.getVisual("decal");n.setVisual("decal",u(r,i))}else{var o=e.getRawData(),a={},s=xG(e).scope;n.each((function(t){var e=n.getRawIndex(t);a[e]=t}));var l=o.count();o.each((function(t){var i=a[t],r=o.getName(t)||t+"",h=pd(e.ecModel,r,s,l),c=n.getItemVisual(i,"decal");n.setItemVisual(i,"decal",u(c,h))}))}}function u(t,e){var n=t?A(A({},e),t):e;return n.dirty=!0,n}}))}}(),function(){var i=e.getZr().dom;if(!i)return;var o=t.getLocaleModel().get("aria"),a=n.getModel("label");if(a.option=k(a.option,o),!a.get("enabled"))return;if(i.setAttribute("role","img"),a.get("description"))return void i.setAttribute("aria-label",a.get("description"));var s,l=t.getSeriesCount(),u=a.get(["data","maxCount"])||10,h=a.get(["series","maxCount"])||10,c=Math.min(l,h);if(l<1)return;var p=function(){var e=t.get("title");e&&e.length&&(e=e[0]);return e&&e.text}();s=p?r(a.get(["general","withTitle"]),{title:p}):a.get(["general","withoutTitle"]);var d=[];s+=r(l>1?a.get(["series","multiple","prefix"]):a.get(["series","single","prefix"]),{seriesCount:l}),t.eachSeries((function(e,n){if(n1?a.get(["series","multiple",o]):a.get(["series","single",o]),{seriesId:e.seriesIndex,seriesName:e.get("name"),seriesType:(_=e.subType,b=t.getLocaleModel().get(["series","typeNames"]),b[_]||b.chart)});var s=e.getData();if(s.count()>u)i+=r(a.get(["data","partialData"]),{displayCnt:u});else i+=a.get(["data","allData"]);for(var h=a.get(["data","separator","middle"]),p=a.get(["data","separator","end"]),f=a.get(["data","excludeDimensionId"]),g=[],y=0;y":"gt",">=":"gte","=":"eq","!=":"ne","<>":"ne"},MG=function(){function t(t){if(null==(this._condVal=U(t)?new RegExp(t):et(t)?t:null)){var e="";0,wo(e)}}return t.prototype.evaluate=function(t){var e=typeof t;return U(e)?this._condVal.test(t):!!j(e)&&this._condVal.test(t+"")},t}(),IG=function(){function t(){}return t.prototype.evaluate=function(){return this.value},t}(),TG=function(){function t(){}return t.prototype.evaluate=function(){for(var t=this.children,e=0;e2&&l.push(e),e=[t,n]}function f(t,n,i,r){BG(t,i)&&BG(n,r)||e.push(t,n,i,r,i,r)}function g(t,n,i,r,o,a){var s=Math.abs(n-t),l=4*Math.tan(s/4)/3,u=nM:C2&&l.push(e),l}function GG(t,e,n,i,r,o,a,s,l,u){if(BG(t,n)&&BG(e,i)&&BG(r,a)&&BG(o,s))l.push(a,s);else{var h=2/u,c=h*h,p=a-t,d=s-e,f=Math.sqrt(p*p+d*d);p/=f,d/=f;var g=n-t,y=i-e,v=r-a,m=o-s,x=g*g+y*y,_=v*v+m*m;if(x=0&&_-w*w=0)l.push(a,s);else{var S=[],M=[];wn(t,n,r,a,.5,S),wn(e,i,o,s,.5,M),GG(S[0],M[0],S[1],M[1],S[2],M[2],S[3],M[3],l,u),GG(S[4],M[4],S[5],M[5],S[6],M[6],S[7],M[7],l,u)}}}}function WG(t,e,n){var i=t[e],r=t[1-e],o=Math.abs(i/r),a=Math.ceil(Math.sqrt(o*n)),s=Math.floor(n/a);0===s&&(s=1,a=n);for(var l=[],u=0;u0)for(u=0;uMath.abs(u),c=WG([l,u],h?0:1,e),p=(h?s:u)/c.length,d=0;d1?null:new De(d*l+t,d*u+e)}function UG(t,e,n){var i=new De;De.sub(i,n,e),i.normalize();var r=new De;return De.sub(r,t,e),r.dot(i)}function ZG(t,e){var n=t[t.length-1];n&&n[0]===e[0]&&n[1]===e[1]||t.push(e)}function jG(t){var e=t.points,n=[],i=[];Ba(e,n,i);var r=new ze(n[0],n[1],i[0]-n[0],i[1]-n[1]),o=r.width,a=r.height,s=r.x,l=r.y,u=new De,h=new De;return o>a?(u.x=h.x=s+o/2,u.y=l,h.y=l+a):(u.y=h.y=l+a/2,u.x=s,h.x=s+o),function(t,e,n){for(var i=t.length,r=[],o=0;or,a=WG([i,r],o?0:1,e),s=o?"width":"height",l=o?"height":"width",u=o?"x":"y",h=o?"y":"x",c=t[s]/a.length,p=0;p0)for(var b=i/n,w=-i/2;w<=i/2;w+=b){var S=Math.sin(w),M=Math.cos(w),I=0;for(x=0;x0;l/=2){var u=0,h=0;(t&l)>0&&(u=1),(e&l)>0&&(h=1),s+=l*l*(3*u^h),0===h&&(1===u&&(t=l-1-t,e=l-1-e),a=t,t=e,e=a)}return s}function cW(t){var e=1/0,n=1/0,i=-1/0,r=-1/0,o=z(t,(function(t){var o=t.getBoundingRect(),a=t.getComputedTransform(),s=o.x+o.width/2+(a?a[4]:0),l=o.y+o.height/2+(a?a[5]:0);return e=Math.min(s,e),n=Math.min(l,n),i=Math.max(s,i),r=Math.max(l,r),[s,l]}));return z(o,(function(o,a){return{cp:o,z:hW(o[0],o[1],e,n,i,r),path:t[a]}})).sort((function(t,e){return t.z-e.z})).map((function(t){return t.path}))}function pW(t){return $G(t.path,t.count)}function dW(t){return Y(t[0])}function fW(t,e){for(var n=[],i=t.length,r=0;r=0;r--)if(!n[r].many.length){var l=n[s].many;if(l.length<=1){if(!s)return n;s=0}o=l.length;var u=Math.ceil(o/2);n[r].many=l.slice(u,o),n[s].many=l.slice(0,u),s++}return n}var gW={clone:function(t){for(var e=[],n=1-Math.pow(1-t.path.style.opacity,1/t.count),i=0;i0){var s,l,u=i.getModel("universalTransition").get("delay"),h=Object.assign({setToFinal:!0},a);dW(t)&&(s=t,l=e),dW(e)&&(s=e,l=t);for(var c=s?s===t:t.length>e.length,p=s?fW(l,s):fW(c?e:t,[c?t:e]),d=0,f=0;f1e4))for(var r=n.getIndices(),o=0;o0&&i.group.traverse((function(t){t instanceof ks&&!t.animators.length&&t.animateFrom({style:{opacity:0}},r)}))}))}function TW(t){var e=t.getModel("universalTransition").get("seriesKey");return e||t.id}function CW(t){return Y(t)?t.sort().join(","):t}function DW(t){if(t.hostModel)return t.hostModel.getModel("universalTransition").get("divideShape")}function AW(t,e){for(var n=0;n=0&&r.push({dataGroupId:e.oldDataGroupIds[n],data:e.oldData[n],divide:DW(e.oldData[n]),groupIdDim:t.dimension})})),E(To(t.to),(function(t){var i=AW(n.updatedSeries,t);if(i>=0){var r=n.updatedSeries[i].getData();o.push({dataGroupId:e.oldDataGroupIds[i],data:r,divide:DW(r),groupIdDim:t.dimension})}})),r.length>0&&o.length>0&&IW(r,o,i)}(t,i,n,e)}));else{var o=function(t,e){var n=yt(),i=yt(),r=yt();return E(t.oldSeries,(function(e,n){var o=t.oldDataGroupIds[n],a=t.oldData[n],s=TW(e),l=CW(s);i.set(l,{dataGroupId:o,data:a}),Y(s)&&E(s,(function(t){r.set(t,{key:l,dataGroupId:o,data:a})}))})),E(e.updatedSeries,(function(t){if(t.isUniversalTransitionEnabled()&&t.isAnimationEnabled()){var e=t.get("dataGroupId"),o=t.getData(),a=TW(t),s=CW(a),l=i.get(s);if(l)n.set(s,{oldSeries:[{dataGroupId:l.dataGroupId,divide:DW(l.data),data:l.data}],newSeries:[{dataGroupId:e,divide:DW(o),data:o}]});else if(Y(a)){var u=[];E(a,(function(t){var e=i.get(t);e.data&&u.push({dataGroupId:e.dataGroupId,divide:DW(e.data),data:e.data})})),u.length&&n.set(s,{oldSeries:u,newSeries:[{dataGroupId:e,data:o,divide:DW(o)}]})}else{var h=r.get(a);if(h){var c=n.get(h.key);c||(c={oldSeries:[{dataGroupId:h.dataGroupId,data:h.data,divide:DW(h.data)}],newSeries:[]},n.set(h.key,c)),c.newSeries.push({dataGroupId:e,data:o,divide:DW(o)})}}}})),n}(i,n);E(o.keys(),(function(t){var n=o.get(t);IW(n.oldSeries,n.newSeries,e)}))}E(n.updatedSeries,(function(t){t[_g]&&(t[_g]=!1)}))}for(var a=t.getSeries(),s=i.oldSeries=[],l=i.oldDataGroupIds=[],u=i.oldData=[],h=0;h **设计原则**:学院用户内部通过数据权限区分粒度(院长看院级汇总,专业负责人看专业详情,就业指导老师侧重企业和薪资),但共用同一套功能菜单,降低系统复杂度。 + +## 二、角色旅程地图 + +### 第一阶段:数据准备期 + +``` +系统管理员(R3) + │ + ├── 配置校内数据对接(实习平台、就业系统) + ├── 配置外部数据采集(杭州就业网、本地人才网) + ├── 执行数据清洗 & 岗位归一 + ├── 确认数据质量,处理异常 + ├── 配置用户账号与权限 + └── 触发分析引擎,生成32个专业报告 +``` + +### 第二阶段:分析与使用期 + +``` +校级管理者(R2) 学院用户(R1) + │ │ + ├── 查看全校专业对比总览 ├── 查看本院/专业匹配度分析 + ├── 查看人才缺口汇总 ├── 查看技能图谱 & 薪资对比 + ├── 导出供需会议材料包 ├── 查看人才缺口详情 + └── 控制大屏展示内容 ├── 查看课程调整建议 + ├── 获取企业推荐列表 + 大屏展示 └── 导出专业/学院报告 + │ + └── 大屏展示(无需登录) +``` + +### 第三阶段:落地跟进期 + +``` +学院用户(R1) 校级管理者(R2) 系统管理员(R3) + │ │ │ + ├── 对接推荐企业 ├── 跟踪各学院改进计划 ├── 归档本期分析数据 + ├── 根据建议调整培养方案 └── 下一周期数据对比 ├── 更新数据采集策略 + └── 引导学生关注缺口方向 └── 准备下一周期数据 +``` + +## 三、角色-功能矩阵 + +| 功能模块 | R1 学院用户 | R2 校级管理者 | R3 系统管理员 | 大屏展示 | +|---------|:---------:|:-----------:|:-----------:|:------:| +| 数据源配置与接入 | | | ✅ | | +| 数据清洗与岗位归一 | | | ✅ | | +| 数据质量监控 | | 👁 | ✅ | | +| 岗位匹配度分析 | ✅ | ✅ | | 👁 | +| 人才缺口识别 | ✅ | ✅ | | 👁 | +| 薪资对比分析 | ✅ | ✅ | | 👁 | +| 专业技能图谱 | ✅ | ✅ | | 👁 | +| 课程调整建议 | ✅ | 👁 | | | +| 合作企业推荐 | ✅ | 👁 | | 👁 | +| 就业去向分布 | ✅ | ✅ | | | +| 专业/学院报告导出 | ✅ | | | | +| 全校专业对比总览 | | ✅ | | 👁 | +| 全校缺口汇总 | | ✅ | | | +| 供需会材料导出 | | ✅ | | | +| 大屏内容配置 | | ✅ | | | +| 用户权限管理 | | | ✅ | | +| 系统配置与运维 | | | ✅ | | + +> ✅ = 主要操作者   👁 = 只读查看 diff --git a/docs/plan/from-hk/01-US-学院用户.md b/docs/plan/from-hk/01-US-学院用户.md new file mode 100644 index 0000000..7d69592 --- /dev/null +++ b/docs/plan/from-hk/01-US-学院用户.md @@ -0,0 +1,154 @@ +# User Story — R1 学院用户 + +> **角色画像**:二级学院的院长、专业负责人、就业指导老师。关注本院/本专业的供需匹配情况,需要从数据中获取课程优化方向、企业合作线索和学生就业指导依据。系统内通过数据权限控制可见范围(院级/专业级)。 + +--- + +## US-R1-01 查看本院专业匹配度总览 + +**作为** 学院用户, +**我希望** 登录后看到本院所有专业与市场需求的匹配度总览, +**以便** 快速掌握哪些专业与市场吻合、哪些偏离较大。 + +### 验收标准 +- [ ] 默认展示本院专业列表,每个专业显示匹配度评分(百分制) +- [ ] 匹配度低于阈值(如60%)的专业红色高亮预警 +- [ ] 点击专业可进入详细分析页 +- [ ] 支持按时间范围切换(本学期/本学年/近三年趋势) + +--- + +## US-R1-02 查看专业供需匹配详细分析 + +**作为** 学院用户, +**我希望** 查看某一专业的毕业生就业岗位与市场需求岗位的详细对比, +**以便** 精确了解学生实际去向与市场需求之间的偏差。 + +### 验收标准 +- [ ] 展示本专业TOP就业岗位 vs 市场TOP需求岗位对比表 +- [ ] 每个岗位显示:学生就业人数/占比、市场需求量/增速、匹配度评分 +- [ ] 支持按年度查看变化趋势(折线图) +- [ ] 标注"高匹配"、"待关注"、"严重偏离"三档 + +--- + +## US-R1-03 查看专业技能图谱 + +**作为** 学院用户, +**我希望** 查看本专业所需技能与市场要求技能的匹配情况, +**以便** 明确课程在技能覆盖上的盲区。 + +### 验收标准 +- [ ] 雷达图/能力图谱展示:市场要求TOP技能 vs 本专业课程覆盖的技能 +- [ ] 技能数据来源于招聘JD高频关键词提取 +- [ ] 标注覆盖充足(绿)、部分覆盖(黄)、严重不足(红) +- [ ] 可查看技能对应的推荐课程/教学内容 + +--- + +## US-R1-04 查看薪资对比分析 + +**作为** 学院用户, +**我希望** 查看本专业学生实习/就业薪资与市场薪资的对比, +**以便** 评估学生市场竞争力,并为就业指导提供薪资预期参考。 + +### 验收标准 +- [ ] 展示:本专业实习平均工资、就业平均薪资、市场同岗位薪资 +- [ ] 分位数展示(25%/50%/75%),避免只看均值 +- [ ] 支持按城市维度筛选(杭州/省内/一线/新一线) +- [ ] 支持按经验维度筛选(实习/应届/1-3年) +- [ ] 与上一周期对比,展示薪资变化趋势 + +--- + +## US-R1-05 查看人才缺口分析 + +**作为** 学院用户, +**我希望** 查看与本院/本专业相关的人才缺口方向, +**以便** 评估是否需要调整培养方向或引导学生关注新兴岗位。 + +### 验收标准 +- [ ] 展示缺口岗位TOP列表:岗位名称、市场需求量、学院覆盖人数、缺口率 +- [ ] 每个缺口岗位展示:职责描述、技能要求、薪资范围、需求企业数 +- [ ] 标注缺口岗位与本专业的关联度(强关联/弱关联) +- [ ] 支持按岗位大类筛选,展示近年需求趋势 + +--- + +## US-R1-06 获取课程调整建议 + +**作为** 学院用户, +**我希望** 系统基于供需分析和技能图谱,自动生成课程调整建议, +**以便** 修订培养方案时有数据支撑的参考。 + +### 验收标准 +- [ ] 建议分类:建议新增课程方向、建议强化的现有课程、建议弱化/合并的课程 +- [ ] 每条建议引用具体市场数据(如"Python技能在XX岗位JD中出现率85%,当前仅覆盖1门基础课") +- [ ] 建议标注优先级(高/中/低) +- [ ] 支持对建议标记"采纳/暂缓/驳回",供后续跟踪 + +--- + +## US-R1-07 获取合作企业推荐 + +**作为** 学院用户, +**我希望** 系统推荐与本专业高度匹配的企业, +**以便** 拓展实习/就业渠道,主动对接合作。 + +### 验收标准 +- [ ] 推荐企业按匹配度排序:企业名称、行业、规模、招聘岗位、历史招聘人数 +- [ ] 区分"已合作企业"和"新推荐企业" +- [ ] 已合作企业显示历史数据(接收学生数、评价) +- [ ] 新推荐企业显示推荐理由(如"近1年发布XX岗位38个,匹配度92%") +- [ ] 支持导出企业联系清单(Excel) + +--- + +## US-R1-08 查看学生就业去向分布 + +**作为** 学院用户, +**我希望** 查看本院/本专业学生的就业去向分布, +**以便** 有针对性地开展就业指导。 + +### 验收标准 +- [ ] 按行业/地域/企业类型(国企/民企/外企/事业单位)三个维度展示 +- [ ] 支持按届次筛选(2024/2025/2026届) +- [ ] 可视化展示(饼图/桑基图) +- [ ] 显示与上一届的变化情况 + +--- + +## US-R1-09 查看政策与行业动态 + +**作为** 学院用户, +**我希望** 查看与就业相关的政策和行业动态摘要, +**以便** 在就业指导中传递最新信息。 + +### 验收标准 +- [ ] 聚合展示:政府就业政策、行业报告摘要、新闻动态 +- [ ] 按专业/行业维度智能推荐相关内容 +- [ ] 支持按时间排序和关键词搜索 +- [ ] 重点政策标注"必读"标签 + +--- + +## US-R1-10 导出专业/学院报告 + +**作为** 学院用户, +**我希望** 导出本专业或本院的供需分析报告(PDF/Word), +**以便** 用于汇报、专业评估、教学改革立项。 + +### 验收标准 + +**P0 基础版报告**(随核心分析功能上线): +- [ ] 专业报告涵盖:供需匹配分析(岗位对比表、匹配度评分) +- [ ] 学院报告涵盖:院级总览 + 各专业匹配度摘要 +- [ ] 32个专业均可独立生成报告 + +**完整版报告**(随P1分析功能逐步丰富): +- [ ] 增加:技能图谱、薪资对比、缺口分析章节 +- [ ] 增加:课程调整建议章节(P3上线后) + +**通用要求**: +- [ ] 报告自动带有学校LOGO、学院名称、生成日期 +- [ ] 支持PDF/Word两种格式,导出不超过30秒 diff --git a/docs/plan/from-hk/02-US-校级管理者.md b/docs/plan/from-hk/02-US-校级管理者.md new file mode 100644 index 0000000..80f16f4 --- /dev/null +++ b/docs/plan/from-hk/02-US-校级管理者.md @@ -0,0 +1,93 @@ +# User Story — R2 校级管理者 + +> **角色画像**:教务处/就业处领导,从全校维度统筹管理,关注各学院/专业的整体供需表现,推动各学院改进措施落地。 + +--- + +## US-R2-01 查看全校专业对比总览 + +**作为** 校级管理者, +**我希望** 在一个总览页面看到全校32个专业的供需匹配对比, +**以便** 快速识别表现优秀和需要重点关注的专业。 + +### 验收标准 +- [ ] 32个专业以矩阵/排行榜展示:匹配度评分、缺口率、薪资竞争力 +- [ ] 支持按学院分组查看 +- [ ] 支持按匹配度/缺口率/薪资竞争力排序 +- [ ] "红绿灯"机制:绿(优秀)、黄(一般)、红(预警) +- [ ] 与上一周期对比,展示变化箭头(↑↓→) + +--- + +## US-R2-02 查看全校人才缺口汇总 + +**作为** 校级管理者, +**我希望** 查看跨学院维度的人才缺口汇总分析, +**以便** 从全校层面规划新专业申报和招生计划调整。 + +### 验收标准 +- [ ] 展示全校未覆盖的TOP缺口岗位方向(市场有需求,学校无对应专业) +- [ ] 展示覆盖不足的岗位方向(有专业但产出不够) +- [ ] 每个缺口标注:市场需求规模、增长趋势、建议对应学院 +- [ ] 支持导出为决策参考报告 + +--- + +## US-R2-03 导出供需会议材料包 + +**作为** 校级管理者, +**我希望** 一键导出完整的供需会议材料包, +**以便** 用于汇报或报送教育厅。 + +### 验收标准 +- [ ] 材料包包含: + - 全校供需分析总报告(校级管理者视角的汇总) + - 32个专业人才需求报告(复用 US-R1-10 的报告产出,独立文件) + - 全校数据摘要(关键指标一页纸) +- [ ] 支持一键打包下载(ZIP) +- [ ] 报告格式统一、排版美观,可直接用于正式场合 +- [ ] 材料包中数据时间戳一致,口径统一 + +> **依赖说明**:材料包中的32份专业报告由 US-R1-10 的报告生成能力提供,材料包功能负责汇总打包和生成全校总报告。报告内容丰富度随 P0→P1→P3 逐步增强。 + +--- + +## US-R2-04 管理展示大屏 + +**作为** 校级管理者, +**我希望** 配置供需会大屏的展示内容和布局, +**以便** 展示人才培养与市场对接成果。 + +### 验收标准 +- [ ] 支持选择大屏展示模块(匹配度排行、缺口地图、薪资对比、趋势图等) +- [ ] 支持大屏布局调整(多屏轮播/分区展示) +- [ ] 支持预览模式(电脑上预览效果) +- [ ] 全屏模式,适配常见大屏比例 + +--- + +## US-R2-05 跟踪各学院改进情况 + +**作为** 校级管理者, +**我希望** 跟踪各学院对供需分析建议的响应和改进情况, +**以便** 推动建议落地,形成闭环。 + +### 验收标准 +- [ ] 展示各学院/专业的建议采纳情况(已采纳/进行中/未响应) +- [ ] 支持设置改进计划截止时间 +- [ ] 自动统计各学院响应率 +- [ ] 可导出改进跟踪报告 + +--- + +## US-R2-06 查看数据质量概况 + +**作为** 校级管理者, +**我希望** 了解系统数据的完整性和质量状况, +**以便** 对分析结果的可靠性心中有数。 + +### 验收标准 +- [ ] 展示各数据源接入状态(正常/异常/未接入) +- [ ] 展示各专业数据完整度百分比 +- [ ] 数据质量异常时有醒目提示 +- [ ] 展示最近一次数据更新时间 diff --git a/docs/plan/from-hk/03-US-系统管理员.md b/docs/plan/from-hk/03-US-系统管理员.md new file mode 100644 index 0000000..adfcb7c --- /dev/null +++ b/docs/plan/from-hk/03-US-系统管理员.md @@ -0,0 +1,123 @@ +# User Story — R3 系统管理员 + +> **角色画像**:信息中心人员,兼顾数据管理和系统运维。负责数据全生命周期(接入→清洗→归一→分析触发)以及用户权限、系统配置、运行监控。是系统正常运行的基石。 + +--- + +## US-R3-01 配置校内数据源对接 + +**作为** 系统管理员, +**我希望** 通过配置界面接入校内实习平台和就业数据系统, +**以便** 系统自动获取校内最新数据,减少人工导入。 + +### 验收标准 +- [ ] 支持API对接配置(接口地址、认证信息、字段映射) +- [ ] 支持数据库直连配置(数据库类型、连接串、查询SQL/视图) +- [ ] 支持Excel/CSV手动上传作为兜底 +- [ ] 配置后可"测试连接"验证可用性 +- [ ] 支持设置自动同步频率(每日/每周/手动) + +--- + +## US-R3-02 配置外部数据采集 + +**作为** 系统管理员, +**我希望** 配置和管理外部就业数据的采集任务, +**以便** 持续获取市场端最新供需信息。 + +### 验收标准 +- [ ] 支持配置采集源:杭州就业网、杭州本地人才网等 +- [ ] 每个采集源可配置:采集频率、范围(地域/行业/岗位类型)、采集量限制 +- [ ] 展示采集任务运行状态(运行中/暂停/异常) +- [ ] 采集异常时自动告警(邮件/站内消息) +- [ ] 展示每个采集源的历史采集统计(数据量、成功率) + +--- + +## US-R3-03 管理数据清洗规则 + +**作为** 系统管理员, +**我希望** 配置数据清洗规则, +**以便** 确保进入分析引擎的数据质量达标。 + +### 验收标准 +- [ ] 支持去重规则(相同岗位/企业判定条件) +- [ ] 支持数据补全规则(缺失字段的默认值/推断策略) +- [ ] 支持异常数据过滤规则(薪资异常值、无效岗位等) +- [ ] 清洗规则可预览效果(清洗前后对比) +- [ ] 清洗日志可查,支持追溯 + +--- + +## US-R3-04 维护岗位分类体系 + +**作为** 系统管理员, +**我希望** 维护统一的岗位分类体系和归一映射规则, +**以便** 不同来源的岗位数据能在同一体系下对比分析。 + +### 验收标准 +- [ ] 提供标准岗位分类树(大类-中类-小类) +- [ ] 支持添加/编辑/合并岗位分类 +- [ ] 支持岗位别名映射(如"前端工程师"="Web前端开发"="前端开发工程师") +- [ ] 新数据自动尝试归一,未匹配的进入待审核队列 +- [ ] 待审核队列支持批量处理 + +--- + +## US-R3-05 监控数据质量 + +**作为** 系统管理员, +**我希望** 有数据质量监控看板, +**以便** 及时发现和处理数据问题,保障分析可靠性。 + +### 验收标准 +- [ ] 展示各数据源同步状态、最近同步时间、数据量变化 +- [ ] 展示数据完整度(各字段填充率) +- [ ] 展示归一覆盖率(已归一岗位占比) +- [ ] 异常条目数及处理状态 +- [ ] 支持告警阈值设置(如连续3天同步失败则告警) + +--- + +## US-R3-06 触发与管理分析任务 + +**作为** 系统管理员, +**我希望** 在数据就绪后触发分析引擎生成报告, +**以便** 控制报告生成时机,确保基于最新最完整的数据。 + +### 验收标准 +- [ ] 支持手动触发全量分析(32专业)或单专业分析 +- [ ] 支持自动分析计划(如每月1日) +- [ ] 分析任务显示进度条和预计完成时间 +- [ ] 分析完成后自动通知相关角色 +- [ ] 保留历史分析版本,支持版本对比 + +--- + +## US-R3-07 管理用户账号与权限 + +**作为** 系统管理员, +**我希望** 管理系统用户账号,按角色分配权限, +**以便** 每个用户只能访问职责范围内的数据和功能。 + +### 验收标准 +- [ ] 支持创建/编辑/禁用/删除用户 +- [ ] 预置角色模板:学院用户、校级管理者、系统管理员 +- [ ] 学院用户可绑定所属学院/专业,控制数据可见范围 +- [ ] 支持批量导入用户(Excel) +- [ ] 可选对接学校统一身份认证(CAS/OAuth) + +--- + +## US-R3-08 系统配置与运维 + +**作为** 系统管理员, +**我希望** 通过配置界面管理全局参数,并监控系统运行状态, +**以便** 保障系统稳定运行。 + +### 验收标准 +- [ ] 可配置:学校信息(名称/LOGO/学院专业列表)、分析参数(阈值/周期)、报告模板、通知规则 +- [ ] 运维看板:服务状态、资源使用(CPU/内存/磁盘)、在线用户数、访问量 +- [ ] 异常告警:服务宕机/资源超阈值时通知 +- [ ] 操作日志:记录关键操作,支持筛选和导出 +- [ ] 数据备份:支持自动/手动备份,可从备份恢复 diff --git a/docs/plan/from-hk/04-大屏展示模块.md b/docs/plan/from-hk/04-大屏展示模块.md new file mode 100644 index 0000000..0c0fed2 --- /dev/null +++ b/docs/plan/from-hk/04-大屏展示模块.md @@ -0,0 +1,73 @@ +# 大屏展示模块(功能模块,非独立角色) + +> **使用场景**:供需数据的可视化展示。无需登录,由校级管理者配置内容后自动轮播。要求视觉效果专业、信息直观。 + +--- + +## US-DS-01 大屏首页 — 学校供需总览 + +**展示内容**:学校人才培养与市场需求的宏观对接指标。 + +### 验收标准 +- [ ] 关键指标:全校专业数、在校生总数、整体就业率、平均匹配度、合作企业总数、覆盖行业数 +- [ ] 数字动态计数器效果(滚动数字) +- [ ] 深色背景、高对比度配色,视觉效果专业 +- [ ] 关键数字突出显示,信息层次清晰 + +--- + +## US-DS-02 大屏 — 专业匹配度排行 + +**展示内容**:32个专业与市场需求的匹配度排名。 + +### 验收标准 +- [ ] 排行榜/柱状图展示 +- [ ] 自动高亮TOP5和BOTTOM5 +- [ ] 支持按学院分组展示 +- [ ] 自动轮播翻页(每屏16个专业) + +--- + +## US-DS-03 大屏 — 人才缺口可视化 + +**展示内容**:市场急需方向的人才缺口分布。 + +### 验收标准 +- [ ] 热力图/气泡图展示,气泡大小=缺口程度,颜色=行业类别 +- [ ] 动态效果(缓慢浮动/呼吸灯) +- [ ] 旁注关键数据(如"AI方向缺口率67%") + +--- + +## US-DS-04 大屏 — 薪资对比 + +**展示内容**:校内培养薪资 vs 市场薪资对比。 + +### 验收标准 +- [ ] 对比图:校内实习薪资 vs 市场实习薪资、校内就业薪资 vs 市场就业薪资 +- [ ] 按专业/行业维度自动切换 +- [ ] 绿色箭头=优于市场,红色=低于市场 + +--- + +## US-DS-05 大屏 — 校企合作成果 + +**展示内容**:学校与企业的合作成果展示。 + +### 验收标准 +- [ ] 合作企业LOGO墙/地图分布 +- [ ] 关键数据:合作企业总数、覆盖行业、累计接收学生数、提供岗位数 +- [ ] 企业LOGO动态滚动/飞入效果 +- [ ] 标注重点合作企业(500强/行业龙头) + +--- + +## 大屏通用要求 + +| 项目 | 要求 | +|------|------| +| 分辨率 | 适配1920×1080及以上,支持16:9/21:9 | +| 自动轮播 | 各页面按设定间隔自动切换,支持手动翻页 | +| 免登录 | 通过专用URL直接访问,无需登录 | +| 自动刷新 | 数据按设定周期自动刷新 | +| 动效 | 适度动态效果,避免喧宾夺主 | diff --git a/docs/plan/from-hk/05-优先级与排期建议.md b/docs/plan/from-hk/05-优先级与排期建议.md new file mode 100644 index 0000000..dd91377 --- /dev/null +++ b/docs/plan/from-hk/05-优先级与排期建议.md @@ -0,0 +1,118 @@ +# 供需会系统 — User Story 优先级与排期建议 + +## 一、优先级分级 + +### P0 — 供需会核心交付(必须上线) + +| 编号 | User Story | 角色 | 说明 | +|------|-----------|------|------| +| US-R3-01 | 配置校内数据源对接 | 系统管理员 | 没有数据,一切无从谈起 | +| US-R3-02 | 配置外部数据采集 | 系统管理员 | 市场端数据是对比的基础 | +| US-R3-04 | 维护岗位分类体系 | 系统管理员 | 岗位归一是分析的前提 | +| US-R3-03 | 管理数据清洗规则 | 系统管理员 | 保障数据质量 | +| US-R3-06 | 触发与管理分析任务 | 系统管理员 | 报告生成的入口 | +| US-R3-07 | 管理用户账号与权限 | 系统管理员 | 系统可用的前提 | +| US-R1-01 | 查看本院专业匹配度总览 | 学院用户 | **院级入口页,登录后首页** | +| US-R1-02 | 查看专业供需匹配详细分析 | 学院用户 | 核心分析功能 | +| US-R1-10 | 导出专业/学院报告(基础版) | 学院用户 | **32个专业报告,明确P0** | +| US-R2-01 | 查看全校专业对比总览 | 校级管理者 | 全校维度核心功能 | +| US-R2-03 | 导出供需会议材料包 | 校级管理者 | 供需会直接产出物 | + +### P1 — 分析深度增强(强烈建议) + +| 编号 | User Story | 角色 | 说明 | +|------|-----------|------|------| +| US-R1-03 | 查看专业技能图谱 | 学院用户 | 丰富报告内容 | +| US-R1-04 | 查看薪资对比分析 | 学院用户 | 丰富报告内容 | +| US-R1-05 | 查看人才缺口分析 | 学院用户 | 丰富报告内容 | +| US-R2-02 | 查看全校人才缺口汇总 | 校级管理者 | 全校缺口视图 | +| US-R2-04 | 管理展示大屏 | 校级管理者 | **大屏配置与大屏展示同期** | +| US-R3-05 | 监控数据质量 | 系统管理员 | 保障数据可靠性 | +| US-DS-01 | 大屏-学校供需总览 | 大屏模块 | 大屏核心展示 | +| US-DS-02 | 大屏-专业匹配度排行 | 大屏模块 | 大屏核心展示 | + +### P2 — 展示与体验提升 + +| 编号 | User Story | 角色 | 说明 | +|------|-----------|------|------| +| US-R1-07 | 获取合作企业推荐 | 学院用户 | 企业对接场景 | +| US-R1-08 | 查看学生就业去向分布 | 学院用户 | 就业指导场景 | +| US-R2-06 | 查看数据质量概况 | 校级管理者 | 管理可视化 | +| US-DS-03 | 大屏-人才缺口可视化 | 大屏模块 | 大屏进阶展示 | +| US-DS-04 | 大屏-薪资对比 | 大屏模块 | 大屏进阶展示 | +| US-DS-05 | 大屏-校企合作成果 | 大屏模块 | 大屏进阶展示 | +| US-R3-08 | 系统配置与运维 | 系统管理员 | 运维保障 | + +### P3 — 智能增值功能 + +| 编号 | User Story | 角色 | +|------|-----------|------| +| US-R1-06 | 获取课程调整建议 | 学院用户 | +| US-R1-09 | 查看政策与行业动态 | 学院用户 | +| US-R2-05 | 跟踪各学院改进情况 | 校级管理者 | + +--- + +## 二、建议交付节奏 + +``` + 月份1 月份2 月份3 月份4 + ┌────────────────┬────────────────┬────────────────┬────────────────┐ + │ │ │ │ │ + │ P0 数据层 │ P0 分析+报告 │ P1 深度分析 │ P2+P3 │ + │ │ │ + 大屏 │ 增值功能 │ + │ · 数据对接 │ · 分析引擎 │ · 技能图谱 │ · 课程建议 │ + │ · 数据清洗 │ · 院级总览 │ · 薪资分析 │ · 政策聚合 │ + │ · 岗位归一 │ · 专业分析 │ · 缺口分析 │ · 闭环跟踪 │ + │ · 用户权限 │ · 32份基础报告 │ · 大屏配置 │ · 企业推荐 │ + │ │ · 全校总览 │ · 大屏核心页 │ · 大屏进阶 │ + │ │ · 材料导出 │ · 报告内容丰富 │ · 就业去向 │ + │ │ │ │ │ + └────────────────┴────────────────┴────────────────┴────────────────┘ + 里程碑1 里程碑2 里程碑3 里程碑4 + 数据跑通验证 核心功能上线 供需会就绪 持续迭代 +``` + +--- + +## 三、关键依赖关系 + +``` +数据源接入(R3-01/02) + │ + ▼ +数据清洗 & 岗位归一(R3-03/04) + │ + ▼ +分析引擎(R3-06) + │ + ├──────────────────────────────────┐ + ▼ ▼ +院级总览(R1-01) ──► 专业分析(R1-02) 全校总览(R2-01) + │ │ + ├── 技能图谱(R1-03)├── 缺口汇总(R2-02) + ├── 薪资对比(R1-04)├── 大屏配置(R2-04) ──► 大屏展示(DS-xx) + ├── 缺口分析(R1-05)└── 材料导出(R2-03) ──┐ + │ │ + ├── 报告导出(R1-10)◄─────────────────────┘ + │ (基础版P0 → 完整版随P1/P3丰富) 复用 + └── 课程建议(R1-06) +``` + +> **关键依赖说明**: +> - R1-01(院级总览)是 R1-02(专业详情)的入口页面,必须同期交付 +> - R2-04(大屏配置)是 DS-xx(大屏展示)的管理入口,必须同期交付 +> - R2-03(材料包)复用 R1-10(报告导出)的产出,不重复生成 +> - R1-10 报告内容随 P0→P1→P3 逐步丰富,不阻塞P0交付 + +--- + +## 四、风险提示 + +| 风险项 | 影响 | 建议应对 | +|--------|------|---------| +| 校内系统无可用API | 退化为手动导入 | 提前确认接口能力,准备Excel方案 | +| 外部数据采集合规 | 爬虫可能违反ToS | 优先对接开放API,控制采集频率 | +| 岗位分类标准不统一 | 分析结果不可信 | 早期投入分类体系,参考国标+行业标准 | +| 32专业数据完整度差异大 | 部分报告质量低 | 设置完整度阈值,不达标专业标注说明 | +| 供需会时间节点固定 | 倒排工期压力 | 确认供需会日期,按里程碑严控 | diff --git a/docs/plan/from-hk/10-技术方案-供需会智能分析系统.md b/docs/plan/from-hk/10-技术方案-供需会智能分析系统.md new file mode 100644 index 0000000..38bb785 --- /dev/null +++ b/docs/plan/from-hk/10-技术方案-供需会智能分析系统.md @@ -0,0 +1,573 @@ +# 供需会智能分析系统 — 技术方案 + +> **项目名称**:杭州科技职业技术学院 供需会智能分析系统 + +## 目录 + +- [一、项目背景与目标](#一项目背景与目标) +- [二、系统总体架构](#二系统总体架构) +- [三、核心功能设计](#三核心功能设计) +- [四、AI能力详解](#四ai能力详解) +- [五、数据安全与部署方案](#五数据安全与部署方案) +- [六、实施计划](#六实施计划) +- [七、投资估算](#七投资估算) + +## 一、项目背景与目标 + +### 1.1 项目背景 + +高校供需对接是高等教育服务区域经济发展的核心环节。杭州科技职业技术学院覆盖32个专业方向,每年为杭州及周边地区输送大量技术技能型人才。供需会作为学校与行业企业对接的重要机制,承担着人才培养方向校准、校企合作推进、就业质量提升等多重使命。 + +当前,学校在供需对接方面面临以下挑战: + +| 挑战 | 现状 | +|------|------| +| **数据分散** | 校内实习数据、就业数据、市场招聘数据分散在不同系统,无法统一分析 | +| **分析依赖人工** | 供需匹配主要靠人工调研和经验判断,缺少数据化、智能化的分析手段 | +| **报告产出效率低** | 32个专业的人才需求报告需逐一手工编写,耗时长、口径难统一 | +| **决策缺少数据支撑** | 课程调整、专业建设、企业合作等决策缺乏市场数据的量化支撑 | +| **展示手段单一** | 缺少直观、专业的数据可视化展示手段 | + +### 1.2 建设目标 + +建设一套 **AI驱动的供需会智能分析系统**,实现以下目标: + +1. **数据汇聚**:打通校内实习平台、就业系统与外部就业市场数据,建立统一的供需数据底座 +2. **智能分析**:运用大模型和数据分析技术,自动完成岗位匹配、技能解析、缺口识别、薪资对标 +3. **报告自动化**:一键生成32个专业的人才需求分析报告,支持供需会材料批量导出 +4. **辅助决策**:为学院提供AI驱动的课程调整建议和企业合作推荐 +5. **可视化展示**:提供供需会专用数据大屏,直观呈现人才培养与市场需求的对接成果 + +## 二、系统总体架构 + +### 2.1 总体架构图 + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ 应用展示层 │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌───────────┐ │ +│ │ 学院工作台 │ │ 校级管理台 │ │ 系统管理台 │ │ 展示大屏 │ │ +│ │ · 专业分析 │ │ · 全校总览 │ │ · 数据管理 │ │ · 供需总览│ │ +│ │ · 报告导出 │ │ · 缺口汇总 │ │ · 用户权限 │ │ · 匹配排行│ │ +│ │ · 企业推荐 │ │ · 材料导出 │ │ · 系统运维 │ │ · 缺口地图│ │ +│ │ · 就业指导 │ │ · 大屏管理 │ │ · 分析任务 │ │ · 薪资对比│ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ └───────────┘ │ +├─────────────────────────────────────────────────────────────────────┤ +│ AI 智能分析引擎 │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ JD智能解析│ │ 岗位匹配 │ │ 缺口识别 │ │ 报告生成 │ │ +│ │ 大模型 │ │ 引擎 │ │ 引擎 │ │ 引擎 │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 技能图谱 │ │ 薪资分析 │ │ 课程建议 │ │ +│ │ 构建 │ │ 引擎 │ │ AI生成 │ │ +│ └──────────┘ └──────────┘ └──────────┘ │ +├─────────────────────────────────────────────────────────────────────┤ +│ 数据治理层 │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ 数据清洗 │ │ 岗位归一 │ │ 质量监控 │ │ 数据仓库 │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +├─────────────────────────────────────────────────────────────────────┤ +│ 数据源层 │ +│ ┌───────────────────────┐ ┌───────────────────────────────────┐ │ +│ │ 校内数据 │ │ 外部数据 │ │ +│ │ · 实习平台(含工资) │ │ · 杭州就业网 · 杭州本地人才网 │ │ +│ │ · 就业管理系统 │ │ · 政策/行业报告 │ │ +│ └───────────────────────┘ └───────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 2.2 架构设计原则 + +| 原则 | 说明 | +|------|------| +| **一体化部署** | 一套系统覆盖全部功能,统一部署维护,降低学校信息中心的运维负担 | +| **数据驱动** | 从数据采集到报告生成形成完整链路,所有分析结论均可溯源至原始数据 | +| **AI原生** | 大模型能力深度集成于分析引擎,而非简单的功能叠加,确保智能分析的精准性 | +| **渐进增强** | 系统分阶段交付,核心功能优先上线,AI高级功能逐步丰富,不影响基础使用 | +| **安全可控** | 支持校内私有化部署,数据不出校园;大模型可对接私有化部署的模型服务 | + +## 三、核心功能设计 + +### 3.1 数据接入与治理 + +数据是系统的基础。本模块负责从多方数据源汇聚数据,并经过清洗、标准化后,形成统一的供需数据底座。 + +#### 3.1.1 校内数据对接 + +| 数据源 | 接入数据 | 对接方式 | +|--------|---------|---------| +| 校内实习平台 | 实习岗位、实习企业、实习工资(新增) | 优先API对接,兜底Excel导入 | +| 就业管理系统 | 就业岗位、就业薪资、就业企业、就业去向 | 优先API/数据库视图对接 | + +> 系统提供可视化的数据对接配置界面,支持字段映射、同步频率设置和连接测试,无需修改代码即可适配学校现有系统。 + +#### 3.1.2 外部数据采集 + +| 数据源 | 采集内容 | 采集策略 | +|--------|---------|---------| +| 杭州就业网 | 岗位需求、企业信息、薪资范围 | 定时采集,按行业/地域配置范围 | +| 杭州本地人才网 | 招聘岗位、技能要求、薪资数据 | 定时采集 | +| 行业报告/新闻 | 行业趋势、政策动态 | 定时采集+人工录入 | + +#### 3.1.3 数据治理 + +``` +原始数据 ──► 数据清洗 ──► 岗位归一 ──► 质量检验 ──► 数据仓库 + │ │ │ + ▼ ▼ ▼ + · 去重去噪 · 统一分类 · 完整度检查 + · 格式标准化 · 别名映射 · 异常值检测 + · 缺失值处理 · 待审核队列 · 质量评分 +``` + +**岗位分类归一**是数据治理的核心环节。系统建立三级岗位分类体系(大类-中类-小类),通过AI辅助的别名映射和人工审核相结合,确保来自不同数据源的岗位信息能在同一体系下进行对比分析。 + +### 3.2 AI智能分析引擎 + +这是系统的核心价值所在。AI分析引擎对治理后的供需数据进行深度分析,产出六大维度的分析结果。各维度的详细能力说明见 [第四章 AI能力详解](#四ai能力详解)。 + +#### 六大分析维度 + +| 分析维度 | 分析内容 | 产出 | +|---------|---------|------| +| **岗位匹配度分析** | 将校内就业/实习岗位与市场需求岗位进行智能比对 | 32个专业的匹配度评分及详细对比 | +| **人才缺口识别** | 识别市场有需求但学校覆盖不足的方向 | 缺口岗位TOP排行、缺口率、趋势 | +| **薪资对标分析** | 校内实习工资/就业薪资与市场水平横向对比 | 分位数对比、城市维度、趋势变化 | +| **专业技能图谱** | 从招聘信息中AI提取技能要求,与课程设置比对 | 32个专业的技能覆盖雷达图 | +| **课程调整建议** | 基于供需偏差和技能缺口,AI生成优化建议 | 按专业输出新增/强化/弱化课程建议 | +| **企业推荐** | 基于岗位匹配度,推荐潜在合作企业 | 按专业输出推荐企业列表及推荐理由 | + +#### 分析引擎工作流程 + +``` + 数据仓库 + │ + ├──────────────────────────┐ + ▼ ▼ ▼ + 校内就业数据 市场需求数据 招聘信息原文 + │ │ │ + │ │ ▼ + │ │ AI智能解析(技能/要求提取) + │ │ │ + ▼ ▼ ▼ + ┌──────────────────────────┐ + │ 多维度分析引擎 │ + │ 岗位匹配 · 缺口识别 │ + │ 薪资对标 · 技能图谱 │ + │ 企业推荐 · 课程建议 │ + └────────────┬─────────────┘ + │ + ▼ + 分析结果库(版本化存储) + │ + ┌─────────┼─────────┐ + ▼ ▼ ▼ + 报告生成 数据看板 大屏展示 +``` + +### 3.3 专业人才需求报告 + +系统自动生成32个专业的人才需求分析报告,是供需会的核心产出物。 + +#### 报告内容结构 + +``` +《XX专业人才需求分析报告》 + + 1. 专业概况 + - 在校生规模、近三年就业率 + + 2. 供需匹配分析 + - 毕业生TOP就业岗位 vs 市场TOP需求岗位 + - 匹配度评分及档位 + + 3. 技能图谱分析 + - 市场要求技能 vs 课程覆盖技能(雷达图) + - 技能覆盖盲区标注 + + 4. 薪资对标分析 + - 实习/就业薪资 vs 市场薪资(分位数对比) + - 城市维度、趋势变化 + + 5. 人才缺口分析 + - 相关方向缺口岗位及规模 + - 缺口趋势判断 + + 6. 课程调整建议(AI生成) + - 建议新增/强化/弱化的课程方向 + - 每条建议的数据支撑和优先级 + + 7. 合作企业推荐 + - 高匹配度企业列表 + - 推荐理由 +``` + +#### 报告生成策略 + +报告内容随系统功能上线逐步丰富,32个专业从第一期起即全部覆盖: + +| 阶段 | 报告版本 | 包含内容 | +|------|---------|---------| +| 第一期(M2) | 基础版 | 供需匹配分析(岗位对比、匹配度评分) | +| 第二期(M3) | 完整版 | 增加技能图谱、薪资对标、缺口分析 | +| 第三期(M4) | 智能版 | 增加AI课程建议、企业推荐 | + +- 支持PDF/Word格式导出,统一排版,带学校LOGO和元信息 +- 校级管理者可一键打包导出全部32份报告 + 全校总报告 + +### 3.4 多角色工作台 + +系统面向三类用户,提供差异化的工作台。 + +#### 3.4.1 学院工作台 + +> 面向学院院长、专业负责人、就业指导老师 + +| 功能板块 | 功能说明 | +|---------|---------| +| 专业匹配度总览 | 本院所有专业与市场需求匹配度排行,支持预警标注 | +| 专业详细分析 | 单专业维度的完整分析(岗位对比、技能图谱、薪资、缺口) | +| 课程调整建议 | AI生成的课程优化方向,支持采纳/暂缓/驳回标记 | +| 企业推荐 | 高匹配度企业列表,区分已合作和新推荐,支持导出 | +| 就业去向分布 | 学生就业流向可视化(行业/地域/企业类型) | +| 政策与动态 | 相关就业政策、行业报告聚合 | +| 报告导出 | 导出专业报告或学院报告(PDF/Word) | + +> 通过数据权限控制,院长可查看院级汇总,专业负责人看本专业详情,就业指导老师侧重企业和薪资信息。 + +#### 3.4.2 校级管理台 + +> 面向教务处、就业处领导 + +| 功能板块 | 功能说明 | +|---------|---------| +| 全校专业对比 | 32个专业匹配度/缺口率/薪资竞争力排行,红绿灯预警 | +| 人才缺口汇总 | 全校维度的缺口方向汇总,辅助新专业申报和招生调整 | +| 改进跟踪 | 各学院对建议的响应情况统计 | +| 数据质量概览 | 各数据源接入状态、数据完整度 | +| 材料包导出 | 一键打包导出供需会全套材料(ZIP) | +| 大屏管理 | 配置大屏展示内容、布局、轮播策略 | + +#### 3.4.3 系统管理台 + +> 面向信息中心运维人员 + +| 功能板块 | 功能说明 | +|---------|---------| +| 数据源管理 | 校内/外部数据源配置、测试连接、同步策略 | +| 数据清洗 | 清洗规则配置、预览、执行日志 | +| 岗位分类 | 分类体系维护、别名映射、待审核队列 | +| 分析任务 | 手动/自动触发分析、进度监控、版本管理 | +| 用户权限 | 用户CRUD、角色分配、学院/专业数据范围绑定 | +| 系统运维 | 全局配置、运行监控、操作日志、数据备份 | + +### 3.5 供需会展示大屏 + +展示大屏用于供需数据的可视化呈现,无需登录,由校级管理者配置展示内容。 + +#### 大屏页面规划 + +| 页面 | 展示内容 | 核心视觉元素 | +|------|---------|-------------| +| 学校供需总览 | 全校宏观指标(专业数、就业率、匹配度、企业数) | 动态计数器、指标卡片 | +| 专业匹配度排行 | 32个专业匹配度排名 | 柱状图/排行榜,TOP5高亮 | +| 人才缺口地图 | 市场急需方向分布 | 热力气泡图,动态浮动 | +| 薪资对比 | 校内薪资 vs 市场薪资 | 双轴对比图,涨跌箭头 | +| 校企合作成果 | 合作企业展示 | 企业LOGO墙/地图分布 | + +#### 大屏技术要求 + +- 适配1920×1080及以上分辨率,支持16:9/21:9比例 +- 深色主题、高对比度配色,视觉效果专业 +- 各页面按设定间隔自动轮播,支持手动切换 +- 通过专用URL免登录访问 +- 关键数字突出显示,信息层次清晰 + +## 四、AI能力详解 + +AI能力是本系统区别于传统数据统计工具的核心差异点。系统深度集成大语言模型,在以下四个关键场景中发挥智能化作用。 + +### 4.1 大模型驱动的JD智能解析 + +**痛点**:市场招聘数据中,岗位JD以自然语言描述,格式各异,传统关键词匹配难以准确提取结构化信息。 + +**方案**:利用大模型的语义理解能力,将非结构化JD文本自动解析为结构化数据。 + +``` +┌───────────────────────────────────────┐ +│ 原始JD文本(输入) │ +│ │ +│ "招聘Python后端开发工程师,要求熟悉 │ +│ Django/Flask框架,有Redis/MySQL经验, │ +│ 了解Docker容器化部署,薪资15-25K..." │ +├───────────────────────────────────────┤ +│ 大模型解析 │ +├───────────────────────────────────────┤ +│ 结构化结果(输出) │ +│ │ +│ · 岗位类别:互联网/软件开发/后端开发 │ +│ · 核心技能:Python, Django, Flask, │ +│ Redis, MySQL, Docker │ +│ · 技能层级:熟悉(Django/Flask/Redis) │ +│ 了解(Docker) │ +│ · 薪资范围:15K-25K │ +│ · 经验要求:推断为1-3年 │ +└───────────────────────────────────────┘ +``` + +**价值**: +- 解析准确率显著优于传统关键词匹配 +- 能理解语义近义(如"熟练使用"="精通"、"有经验"="熟悉") +- 支持自动适配不同平台、不同格式的JD文本 + +### 4.2 AI岗位匹配与人才缺口识别 + +**痛点**:校内就业岗位名称与市场岗位名称往往不同(如学生就业登记为"程序员",市场叫"后端开发工程师"),简单文本匹配会导致大量漏匹配。 + +**方案**:利用大模型的语义相似度计算和推理能力,实现"理解岗位本质"的智能匹配。 + +``` +校内就业岗位 市场需求岗位 +───────────── ───────────── +"程序员" ──AI匹配──► "后端开发工程师" ✅ 高匹配 +"网页设计" ──AI匹配──► "UI/UX设计师" ✅ 中匹配 +"文员" ──AI匹配──► "数据分析师" ❌ 低匹配 + "算法工程师" ⚠️ 无对应(缺口) +``` + +**匹配方式**: +1. AI理解岗位的实际含义,而非简单比对文字 +2. 结合岗位分类体系进行层级匹配 +3. 综合技能要求重合度进行交叉验证 +4. 输出匹配度评分(0-100)和匹配置信度 + +**缺口识别逻辑**: +- 市场需求量大 + 学校就业覆盖少 = 人才缺口 +- 结合需求增长趋势判断缺口紧迫性 +- 关联到具体专业,给出"该缺口应由哪个专业响应"的建议 + +### 4.3 智能课程调整建议 + +**痛点**:即使识别了供需偏差,从"市场需要什么技能"到"学校应该调整什么课程"之间的推理链条复杂,依赖专业人员的经验判断。 + +**方案**:利用大模型的推理能力,自动生成从市场数据到课程建议的完整推理链。 + +``` +┌─────────────────────────────────────────────────────┐ +│ AI课程建议生成流程 │ +│ │ +│ 输入: │ +│ · 本专业技能图谱(市场要求 vs 课程覆盖) │ +│ · 本专业供需匹配偏差数据 │ +│ · 本专业现有课程设置清单 │ +│ │ +│ 大模型推理: │ +│ 1. 识别技能覆盖盲区 │ +│ 2. 关联盲区技能到具体岗位需求 │ +│ 3. 评估该技能的市场重要程度和增长趋势 │ +│ 4. 生成课程调整建议(新增/强化/弱化) │ +│ 5. 为每条建议给出数据支撑和优先级 │ +│ │ +│ 输出示例: │ +│ ┌─────────────────────────────────────────────────┐ │ +│ │ 建议【高优先级】:新增"容器化与云原生"课程方向 │ │ +│ │ │ │ +│ │ 依据:Docker/K8s技能在后端开发岗位JD中出现率 │ │ +│ │ 从2024年的42%上升至2026年的78%,而当前课程体系 │ │ +│ │ 中仅在"Linux基础"课程中简要提及容器概念。 │ │ +│ │ │ │ +│ │ 建议措施:新增1门32学时选修课,覆盖Docker基础、 │ │ +│ │ 容器编排、CI/CD流水线等内容。 │ │ +│ └─────────────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────┘ +``` + +**价值**: +- 从"数据发现"到"行动建议"自动闭环 +- 每条建议有明确的数据支撑,可追溯、可验证 +- 大幅降低专业负责人分析市场数据的工作量 + +### 4.4 专业能力图谱自动构建 + +**痛点**:32个专业分别需要哪些技能、每个技能市场需求强度如何、学校课程覆盖如何——这张图谱需要大量人力梳理。 + +**方案**:由AI自动从海量招聘JD中提取、归类、量化技能要求,并与课程设置自动比对,生成专业能力图谱。 + +``` + 计算机科学与技术 · 能力图谱 + + Java ★★★★★ + / + Python ★★★★ MySQL ★★★★ + / \ + Docker ★★★ Redis ★★★ + \ / + Linux ★★★★ Git ★★★★ + \ / + Spring ★★★★★ + + ★ 市场需求强度 ● 课程覆盖度 + + 覆盖充足:Java, Python, MySQL, Linux + 部分覆盖:Spring, Git + 严重不足:Docker, Redis ◄── 重点关注 +``` + +**构建流程**: +1. 从招聘JD中通过大模型提取技能关键词及层级要求 +2. 统计每个技能在对口岗位中的出现频率,计算市场需求强度 +3. 将技能与学校课程大纲进行比对(课程名称+教学内容关键词匹配) +4. 生成雷达图/能力矩阵,标注覆盖状态 + +## 五、数据安全与部署方案 + +### 5.1 数据安全策略 + +| 安全维度 | 措施 | +|---------|------| +| **数据存储** | 所有数据存储在学校服务器内,不外传;数据库加密存储 | +| **访问控制** | 基于角色的权限控制,学院用户只能访问本单位数据 | +| **传输安全** | 全站HTTPS加密传输 | +| **操作审计** | 关键操作(数据导入/导出、报告下载、权限变更)全程日志记录 | +| **数据备份** | 支持自动定时备份,可手动触发,支持从备份恢复 | +| **AI安全** | AI模型可对接学校私有化部署的服务,敏感数据不传入公网 | + +### 5.2 部署方案 + +系统采用**校内私有化部署**,部署在学校数据中心或指定云服务器上。 + +``` +┌──────────────────────────────────────┐ +│ 学校数据中心/云服务器 │ +│ │ +│ ┌─────────┐ ┌─────────┐ │ +│ │ Web前端 │ │ 后端服务 │ │ +│ └─────────┘ └─────────┘ │ +│ ┌─────────┐ ┌─────────┐ │ +│ │ 数据库 │ │ 缓存服务 │ │ +│ └─────────┘ └─────────┘ │ +│ ┌─────────┐ │ +│ │ AI模型 │ (可选私有化部署 │ +│ │ 服务 │ 或对接云端API) │ +│ └─────────┘ │ +└──────────────────────────────────────┘ +``` + +**服务器推荐配置**: + +| 项目 | 基础配置 | 推荐配置 | +|------|---------|---------| +| CPU | 8核 | 16核 | +| 内存 | 16GB | 32GB | +| 磁盘 | 200GB SSD | 500GB SSD | +| GPU(如需私有化AI模型) | — | 独立GPU卡×1 | + +> 如不部署私有化AI模型,可通过API调用云端AI服务,此时无需GPU。 + +## 六、实施计划 + +### 6.1 分期交付计划 + +项目采用分期迭代交付模式,共4个里程碑,总周期约4个月。 + +``` + 月份1 月份2 月份3 月份4 + ┌────────────────┬────────────────┬────────────────┬────────────────┐ + │ │ │ │ │ + │ 里程碑1 │ 里程碑2 │ 里程碑3 │ 里程碑4 │ + │ 数据跑通 │ 核心功能上线 │ 供需会就绪 │ 持续迭代 │ + │ │ │ │ │ + │ · 数据源对接 │ · AI分析引擎 │ · 技能图谱 │ · AI课程建议 │ + │ · 数据清洗归一 │ · 院级/专业分析│ · 薪资对标 │ · 政策聚合 │ + │ · 岗位分类体系 │ · 32份基础报告 │ · 缺口分析 │ · 改进跟踪 │ + │ · 用户权限 │ · 全校总览 │ · 大屏配置+展示│ · 企业推荐 │ + │ │ · 材料包导出 │ · 报告内容丰富 │ · 就业去向 │ + │ │ │ │ · 大屏进阶 │ + └────────────────┴────────────────┴────────────────┴────────────────┘ + + 验收点1: 验收点2: 验收点3: 验收点4: + 数据链路跑通 系统可用于 完整分析+大屏 全功能交付 + 样本数据可查 报告生成和导出 +``` + +### 6.2 里程碑交付物 + +| 里程碑 | 交付物 | 验收标准 | +|--------|--------|---------| +| M1 数据跑通 | 数据治理模块上线,样本数据入库 | 校内+外部数据可接入,清洗归一后可查询 | +| M2 核心上线 | 分析引擎+报告+工作台上线 | 可生成32份基础版专业报告并导出 | +| M3 供需会就绪 | 完整分析+大屏上线 | 报告含完整分析维度,大屏可正常展示 | +| M4 全功能交付 | 全部功能上线 | AI课程建议等高级功能可用,全系统验收 | + +### 6.3 项目配合要求 + +| 阶段 | 需校方配合事项 | +|------|--------------| +| 启动阶段 | 提供校内系统接口文档或数据库访问权限;确认32个专业清单和课程设置 | +| M1阶段 | 配合数据对接调试;提供样本数据验证清洗效果 | +| M2阶段 | 业务部门试用反馈;确认报告格式和内容模板 | +| M3阶段 | 确认大屏展示需求;提供大屏显示设备参数(屏幕尺寸/分辨率) | +| 全程 | 指定1名项目对接人,负责协调校内各部门 | + +## 七、投资估算 + +### 7.1 软件开发工作量 + +以下按功能模块估算开发工作量,单位为**人天**。 + +| 模块 | 功能范围 | 人天 | 阶段 | +|------|---------|:----:|:----:| +| **数据接入与治理** | | | | +|  校内数据对接 | 多种对接方式,字段映射,自动同步 | 15 | M1 | +|  外部数据采集 | 3个采集源配置,采集调度,异常告警 | 18 | M1 | +|  数据清洗引擎 | 去重/补全/过滤规则,配置界面,执行日志 | 12 | M1 | +|  岗位分类归一 | 三级分类体系,别名映射,AI辅助归一,审核队列 | 15 | M1 | +|  数据质量监控 | 监控看板,完整度/归一率指标,告警配置 | 8 | M1 | +| **AI智能分析引擎** | | | | +|  JD智能解析 | AI驱动的招聘信息结构化解析,批量处理 | 12 | M2 | +|  岗位匹配引擎 | 智能语义匹配,匹配度评分,多维度校验 | 15 | M2 | +|  人才缺口识别 | 缺口计算,趋势分析,关联专业推荐 | 10 | M2/M3 | +|  薪资分析引擎 | 多维度薪资对比,趋势分析 | 8 | M3 | +|  技能图谱构建 | AI技能提取,课程比对,图谱生成 | 15 | M3 | +|  AI课程建议 | AI驱动的课程调整建议生成 | 12 | M4 | +|  企业推荐引擎 | 企业-专业匹配度计算,推荐理由生成 | 8 | M4 | +| **报告生成** | | | | +|  报告模板与生成 | 模板设计,数据填充,图表渲染,PDF/Word输出 | 15 | M2 | +|  材料包导出 | 32份报告+总报告汇总,批量打包下载 | 5 | M2 | +| **应用工作台** | | | | +|  学院工作台 | 7个功能板块的界面与服务 | 25 | M2/M3 | +|  校级管理台 | 6个功能板块的界面与服务 | 20 | M2/M3 | +|  系统管理台 | 6个功能板块的界面与服务 | 20 | M1/M2 | +| **展示大屏** | | | | +|  大屏核心页面 | 5个大屏页面设计+开发,轮播,免登录 | 20 | M3 | +|  大屏管理功能 | 内容配置,布局调整,预览 | 8 | M3 | +| **基础设施** | | | | +|  用户权限系统 | 角色管理,数据权限,可选对接学校统一认证 | 10 | M1 | +|  系统运维 | 全局配置,运行监控,操作日志,备份恢复 | 10 | M3/M4 | +|  部署与联调 | 环境搭建,联调测试,上线部署 | 15 | 全程 | +| | | | | +| **合计** | | **311** | | + +### 7.2 工作量汇总(按阶段) + +| 阶段 | 周期 | 工作量 | 核心交付 | +|------|------|:------:|---------| +| M1 数据跑通 | 第1个月 | 78 人天 | 数据治理全链路 + 用户权限 | +| M2 核心上线 | 第2个月 | 100 人天 | AI分析引擎 + 报告生成 + 工作台核心 | +| M3 供需会就绪 | 第3个月 | 83 人天 | 深度分析 + 大屏 + 工作台完善 | +| M4 持续迭代 | 第4个月 | 50 人天 | AI课程建议 + 企业推荐 + 运维 | +| **合计** | **4个月** | **311 人天** | | + +### 7.3 其他费用参考 + +| 项目 | 说明 | 预估(年) | +|------|------|-----------| +| 服务器 | 校方自备或采购(见5.2配置推荐) | 视校方情况 | +| AI模型云端调用 | 如使用云端AI服务(按调用量计费) | 1-3万元 | +| AI模型私有化部署 | 如需校内私有化部署(含GPU服务器) | 视模型规模 | +| 年度运维 | 系统维护、数据更新、版本升级 | 另行协商 | + +> 以上AI服务费用为参考值,实际费用取决于分析频率和数据规模。32个专业每月分析一次,年均费用约1-2万元。 + +*— 文档结束 —* diff --git a/docs/plan/from-hk/10-技术方案-供需会系统.docx b/docs/plan/from-hk/10-技术方案-供需会系统.docx new file mode 100644 index 0000000..a876d61 Binary files /dev/null and b/docs/plan/from-hk/10-技术方案-供需会系统.docx differ diff --git a/docs/plan/from-hk/10-技术方案-架构图.html b/docs/plan/from-hk/10-技术方案-架构图.html new file mode 100644 index 0000000..beb1528 --- /dev/null +++ b/docs/plan/from-hk/10-技术方案-架构图.html @@ -0,0 +1,369 @@ + + + + +供需会智能分析系统 — 架构图(Word粘贴版) + + + + +

图2.1 — 系统总体架构图

+ +
+ 应用展示层 +
+
+
学院工作台
+
  • 专业分析
  • 报告导出
  • 企业推荐
  • 就业指导
+
+
+
校级管理台
+
  • 全校总览
  • 缺口汇总
  • 材料导出
  • 大屏管理
+
+
+
系统管理台
+
  • 数据管理
  • 用户权限
  • 系统运维
  • 分析任务
+
+
+
展示大屏
+
  • 供需总览
  • 匹配排行
  • 缺口地图
  • 薪资对比
+
+
+
+
+ AI 智能分析引擎 +
+
JD智能解析
+
岗位匹配引擎
+
缺口识别引擎
+
报告生成引擎
+
+
+
技能图谱构建
+
薪资分析引擎
+
课程建议 AI生成
+
+
+
+ 数据治理层 +
+
数据清洗
+
岗位归一
+
质量监控
+
数据仓库
+
+
+
+ 数据源层 +
+
+
校内数据
+
  • 实习平台(含工资)
  • 就业管理系统
+
+
+
外部数据
+
  • 杭州就业网
  • 杭州本地人才网
  • 政策 / 行业报告
+
+
+
+ +

图3.1 — 数据治理流程

+ +
+
原始数据
+ ▼ +
数据清洗
+
去重去噪 · 格式标准化 · 缺失值处理
+ ▼ +
岗位归一
+
统一分类 · 别名映射 · 待审核队列
+ ▼ +
质量检验
+
完整度检查 · 异常值检测 · 质量评分
+ ▼ +
数据仓库
+
+ +

图3.2 — 分析引擎工作流程

+ +
+
数据仓库
+ ▼ +
+
校内就业数据
+
市场需求数据
+
招聘信息原文
→ AI智能解析
+
+ ▼ +
+ 多维度分析引擎
+ 岗位匹配 · 缺口识别 · 薪资对标 · 技能图谱 · 企业推荐 · 课程建议 +
+ ▼ +
分析结果库(版本化存储)
+ ▼ +
+
报告生成
+
数据看板
+
大屏展示
+
+
+ +

图4.1 — JD智能解析示例

+ +
+
+
原始JD文本(输入)
+
"招聘Python后端开发工程师,要求熟悉Django/Flask框架,有Redis/MySQL经验,了解Docker容器化部署,薪资15-25K..."
+
+
▼   大模型解析   ▼
+
+
结构化结果(输出)
+
+ 岗位类别:互联网 / 软件开发 / 后端开发
+ 核心技能:Python, Django, Flask, Redis, MySQL, Docker
+ 技能层级:熟悉(Django/Flask/Redis)、了解(Docker)
+ 薪资范围:15K - 25K
+ 经验要求:推断为1-3年 +
+
+
+ +

图4.2 — AI岗位匹配示例

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
校内就业岗位市场需求岗位匹配结果
"程序员"→ AI匹配 →"后端开发工程师"✅ 高匹配
"网页设计"→ AI匹配 →"UI/UX设计师"✅ 中匹配
"文员"→ AI匹配 →"数据分析师"❌ 低匹配
(无对应)"算法工程师"⚠️ 缺口
+ +

图4.3 — AI课程建议生成流程

+ +
+
+
技能图谱
市场要求 vs 课程覆盖
+
供需匹配偏差数据
+
现有课程设置清单
+
+ ▼ 输入 ▼ +
+ 大模型推理
+ + ① 识别技能覆盖盲区 → ② 关联到岗位需求 → ③ 评估市场趋势
+ → ④ 生成课程建议 → ⑤ 给出数据支撑和优先级 +
+
+ ▼ 输出 ▼ +
+
+
建议【高优先级】:新增"容器化与云原生"课程方向
+
+ 依据:Docker/K8s技能在后端开发岗位JD中出现率从2024年的42%上升至2026年的78%,而当前课程体系中仅在"Linux基础"课程中简要提及容器概念。

+ 建议措施:新增1门32学时选修课,覆盖Docker基础、容器编排、CI/CD流水线等内容。 +
+
+ +

图4.4 — 专业能力图谱示例

+ +

计算机科学与技术 · 能力图谱

+ + + + + + + + + + + + + + + +
技能市场需求强度课程覆盖状态
Java★★★★★覆盖充足 ✓
Python★★★★☆覆盖充足 ✓
Spring★★★★★部分覆盖 △
MySQL★★★★☆覆盖充足 ✓
Linux★★★★☆覆盖充足 ✓
Git★★★★☆部分覆盖 △
Docker★★★☆☆严重不足 ✗
Redis★★★☆☆严重不足 ✗
+ +

图5.2 — 部署架构图

+ +
+
学校数据中心 / 云服务器
+
+
Web前端
+
后端服务
+
+
+
数据库
+
缓存服务
+
+
+
AI模型服务
可选私有化部署或对接云端
+
+
+ +

图6.1 — 分期交付计划

+ + + + + + + + + + + + + + +
月份1月份2月份3月份4
+
里程碑1 · 数据跑通
+
    +
  • 数据源对接
  • +
  • 数据清洗归一
  • +
  • 岗位分类体系
  • +
  • 用户权限
  • +
+
✓ 验收:数据链路跑通,样本数据可查
+
+
里程碑2 · 核心功能上线
+
    +
  • AI分析引擎
  • +
  • 院级/专业分析
  • +
  • 32份基础报告
  • +
  • 全校总览
  • +
  • 材料包导出
  • +
+
✓ 验收:系统可用于报告生成和导出
+
+
里程碑3 · 系统就绪
+
    +
  • 技能图谱
  • +
  • 薪资对标
  • +
  • 缺口分析
  • +
  • 大屏配置+展示
  • +
  • 报告内容丰富
  • +
+
✓ 验收:完整分析+大屏
+
+
里程碑4 · 持续迭代
+
    +
  • AI课程建议
  • +
  • 政策聚合
  • +
  • 改进跟踪
  • +
  • 企业推荐
  • +
  • 就业去向
  • +
  • 大屏进阶
  • +
+
✓ 验收:全功能交付
+
+ + + diff --git a/docs/plan/from-hk/README.md b/docs/plan/from-hk/README.md new file mode 100644 index 0000000..b2646c9 --- /dev/null +++ b/docs/plan/from-hk/README.md @@ -0,0 +1,33 @@ +# 供需会系统 — User Story 文档索引 + +> 本目录包含供需会系统的完整 User Story 规划文档,按角色维度组织。 + +## 📁 文档清单 + +| 文件 | 内容 | Story 数量 | +|------|------|:----------:| +| [00-角色总览与旅程地图](./00-角色总览与旅程地图.md) | 3个角色+大屏模块定义、旅程地图、功能矩阵 | — | +| [01-US-学院用户](./01-US-学院用户.md) | R1 学院用户(院长+专业负责人+就业指导) | 10 | +| [02-US-校级管理者](./02-US-校级管理者.md) | R2 校级管理者(教务处/就业处) | 6 | +| [03-US-系统管理员](./03-US-系统管理员.md) | R3 系统管理员(运维+数据管理) | 8 | +| [04-大屏展示模块](./04-大屏展示模块.md) | 大屏展示功能模块(非独立角色) | 5 | +| [05-优先级与排期建议](./05-优先级与排期建议.md) | 优先级分级、交付节奏、依赖关系、风险 | — | +| [10-技术方案-供需会智能分析系统](./10-技术方案-供需会智能分析系统.md) | **面向甲方的技术方案**(架构、功能、AI、部署、排期、报价) | — | + +## 📊 汇总 + +| 指标 | 数量 | +|------|------| +| 角色 | 3 个 + 1 个展示模块 | +| User Story 总数 | 29 个 | +| P0(核心交付) | 11 个 | +| P1(深度增强) | 8 个 | +| P2(体验提升) | 7 个 | +| P3(智能增值) | 3 个 | + +## 🔄 使用说明 + +1. 从 `00-角色总览与旅程地图.md` 开始,了解全貌 +2. 按角色文件确认各 User Story 是否完整 +3. 参考 `05-优先级与排期建议.md` 确定交付计划 +4. 各 Story 的验收标准可直接转化为测试用例 diff --git a/docs/product-line.md b/docs/product-line.md new file mode 100644 index 0000000..be9735e --- /dev/null +++ b/docs/product-line.md @@ -0,0 +1,132 @@ +我先把这组方向整理成一个清晰的产品矩阵。整体可归纳为 **平台产品、工具产品、定制服务、垂直行业方案** 四条产品线。 + +| 产品线 | 方向 | 主要客户 | 产品形态 | 核心内容 | +|---|---|---|---|---| +| 平台产品 | 产教结合 | 高校、职业院校、产业学院、企业培训部门 | 产教融合平台 | 专业建设、课程共建、项目实训、企业导师、过程管理、成果评价 | +| 工具产品 | 录播课程转 AI 课程 | 教师、教研室、课程制作团队 | AI 课程生产工具 | 从录播内容提取教纲,生成课程思政建议、PPT、数字人课程及配套教学材料 | +| 定制服务 | 知识库与个性化应用 | 学校、学院、专业团队及机构客户 | 私有知识库+定制智能应用 | 文档治理、知识检索、智能问答、个性化教学与业务工作流 | +| 垂直方案 | 宴席/越剧 | 专业、学院及行业机构 | 专业知识平台+教学应用 | 专业知识整理、课程资源建设、行业问答、数字内容生产及特色人才培养 | + +## 建议采用的产品架构 + +### 一、产教融合平台 + +服务学校、学院与企业联合培养人才,覆盖: + +- 专业和课程共建; +- 企业项目进入教学; +- 学生实训和作品管理; +- 校内教师与企业导师协作; +- 学习过程与项目成果评价; +- 产业学院运营数据管理。 + +这条线承担统一账号、组织、课程、项目、资源和数据管理,适合作为基础平台。 + +### 二、AI 课程生产工具 + +将已有录播课加工为结构化教学资源。建议明确输入与输出: + +**输入:** + +- 录播视频或音频; +- 已有教案、教材和课件; +- 课程标准及教学要求; +- 经审核的课程思政材料; +- 教师授权的形象与声音素材。 + +**输出:** + +- 课程大纲和章节结构; +- 知识点及教学目标; +- PPT 初稿; +- 教案、讲义和题目初稿; +- 课程思政建议及引用位置; +- 数字人讲解视频; +- 字幕、摘要和资源标签。 + +产品表述建议使用“辅助生成”和“教师审核后发布”。课程思政内容、专业结论、引用来源和评价题目不能未经审核直接进入正式课程。 + +### 三、知识库与个性化应用 + +面向不同学校、专业和机构进行配置或定制,包括: + +- 校级、院级和专业级知识库; +- 教材、教案、制度、案例和行业资料入库; +- 基于授权资料的检索与问答; +- 面向教师、学生和管理人员的不同入口; +- 个性化学习建议; +- 专业术语词典和引用溯源; +- 权限、版本、审计与内容更新; +- 与现有教学平台或业务系统对接。 + +产品化部分应尽量沉淀为统一知识库平台;客户特有的数据治理、接口和工作流作为定制项目交付。 + +### 四、宴席与越剧垂直方案 + +这两个方向建议分别建设,避免合并为一个模糊的“文化产品”。 + +#### 宴席方向 + +如果这里指宴席设计、餐饮文化或烹饪教育,可以围绕: + +- 宴席菜单和菜品知识; +- 原料、工艺与成本核算; +- 地方饮食文化; +- 宴席主题与场景设计; +- 实训课程和案例库; +- 食品安全与操作规范; +- 面向师生的专业问答。 + +#### 越剧方向 + +建议先从“越剧教学知识平台”切入,再评估生成式唱腔能力: + +- 剧目、唱段和流派资料库; +- 越剧字音、唱词和术语检索; +- 板式、行当和流派教学; +- 音视频切分、字幕和唱词对齐; +- 教学课件与课程资源生成; +- 经授权的数字人讲解; +- 唱腔分析、音高曲线和跟唱练习; +- 授权数据条件下的实验性唱腔合成。 + +越剧唱腔生成不宜在早期直接承诺为成熟产品。模型效果取决于授权录音、流派标注、越剧字音、音素边界、实际音高和演唱技法数据。更现实的首期产品是**知识库+教学资源生产+唱段分析**。 + +## 四条线之间的关系 + +```text +产教融合平台 +├─ AI课程生产工具 +│ ├─ 录播解析 +│ ├─ 教纲与教案 +│ ├─ PPT与题目 +│ ├─ 课程思政辅助 +│ └─ 数字人课程 +├─ 专业知识库 +│ ├─ 文档治理 +│ ├─ 检索问答 +│ ├─ 内容溯源 +│ └─ 个性化应用 +└─ 垂直专业方案 + ├─ 宴席专业 + └─ 越剧专业 +``` + +其中: + +- **产教融合平台**负责组织、课程、项目和教学过程; +- **AI 课程工具**负责内容加工; +- **知识库**负责专业资料沉淀和可信问答; +- **宴席、越剧**是平台与工具在具体专业中的落地方案。 + +## 更简洁的对外表述 + +> 面向职业院校和专业学院,提供产教融合平台、AI 课程生产工具与专业知识库服务。平台覆盖校企协作、课程建设、项目实训和成果评价;AI 工具将已有录播和教学资料加工为教纲、课件、教案、题目及数字人课程;专业知识库支持授权资料的检索、问答和个性化教学。宴席、越剧等特色专业采用垂直方案建设,结合专业资源、教学流程和行业实践配置具体应用。 + +## 建议优先级 + +1. **先做录播转 AI 课程工具**:输入输出明确,容易形成可演示产品。 +2. **同步建设知识库底层能力**:为教纲、PPT、问答和垂直专业应用提供统一事实来源。 +3. **将工具接入产教融合平台**:形成课程建设、项目实训和评价的完整业务流程。 +4. **选择一个垂直专业做样板**:如果已有越剧学院、教师和授权资料,优先做越剧;如果宴席专业的数据和课程更完备,则先做宴席。 +5. **唱腔生成放在研究或联合实验室阶段**:首期避免把实验能力写成正式交付承诺。