diff --git a/.env.development b/.env.development index b64e147..240c0dd 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,3 @@ # 环境变量配置 VITE_API_BASE_URL=http://localhost:8001 +VITE_LOG_CENTER_URL=http://localhost:8002 diff --git a/.env.production b/.env.production index c681ed5..d5db146 100644 --- a/.env.production +++ b/.env.production @@ -1,2 +1,3 @@ # 生产环境配置 VITE_API_BASE_URL=https://qiyuan-rtc-api.airlabs.art +VITE_LOG_CENTER_URL=https://qiyuan-log-center-api.airlabs.art diff --git a/DESIGN_SPEC.md b/DESIGN_SPEC.md new file mode 100644 index 0000000..40d35b9 --- /dev/null +++ b/DESIGN_SPEC.md @@ -0,0 +1,647 @@ +# RTC Web 前端设计规范 + +> 本文档定义 rtc_web 管理后台的 UI 设计规范。所有新页面和组件必须遵循此规范,确保视觉一致性。 + +--- + +## 1. 技术栈 + +| 技术 | 版本 | 用途 | +|------|------|------| +| React | 19.x | UI 框架 | +| TypeScript | 5.9+ | 类型安全 | +| Ant Design | 5.x | 组件库 | +| @ant-design/pro-components | 2.x | ProTable 等高级组件 | +| @ant-design/charts | 2.x | 图表 (Pie, Column 等) | +| Zustand | 5.x | 状态管理 | +| Vite | 7.x | 构建工具 | + +--- + +## 2. 色彩体系 + +### 2.1 主题色 + +主题色通过 `src/theme/tokens.ts` 统一配置,由 Ant Design 的 `ConfigProvider` 全局应用。 + +| 语义 | 色值 | 用途 | +|------|------|------| +| **Primary** | `#6366f1` | 主操作按钮、链接、选中态、品牌色 | +| Success | `#10b981` | 成功状态、已绑定、完成 | +| Warning | `#f59e0b` | 警告、未导入、待处理 | +| Error | `#ef4444` | 错误、删除、禁用 | +| Info | `#3b82f6` | 信息提示、只读状态 | + +### 2.2 统计卡片专用色(`statColors`) + +从 `src/theme/tokens.ts` 中导入 `statColors`: + +```typescript +import { statColors } from '../../theme/tokens'; + +// 可用颜色: +statColors.primary // #6366f1 - 紫蓝 +statColors.success // #10b981 - 绿 +statColors.warning // #f59e0b - 橙 +statColors.error // #ef4444 - 红 +statColors.info // #3b82f6 - 蓝 +statColors.purple // #8b5cf6 - 紫 +statColors.cyan // #06b6d4 - 青 +statColors.pink // #ec4899 - 粉 +``` + +### 2.3 中性色 + +| 用途 | 色值 | +|------|------| +| 正文标题 | `#1f2937` | +| 正文内容 | `#374151` | +| 辅助文字 | `#6b7280` | +| 占位/禁用 | `#9ca3af` | +| 边框 | `#e5e7eb` | +| 浅背景 | `#f5f5f7` (Layout 背景) | +| 白色容器 | `#ffffff` | + +### 2.4 CSS 变量 + +全局 CSS 变量定义在 `src/index.css` 的 `:root` 中,可在任何 CSS 文件中使用: + +```css +var(--color-primary) /* #6366f1 */ +var(--color-primary-light) /* #818cf8 */ +var(--color-primary-dark) /* #4f46e5 */ +var(--color-bg-base) /* #f5f5f7 */ +var(--color-bg-elevated) /* #ffffff */ +var(--color-border) /* #e5e7eb */ +var(--shadow-sm) /* 微弱阴影 */ +var(--shadow-md) /* 中等阴影 */ +var(--shadow-lg) /* 强阴影 */ +var(--transition-fast) /* 150ms */ +var(--transition-base) /* 200ms */ +var(--transition-slow) /* 300ms */ +``` + +--- + +## 3. 圆角规范 + +| 场景 | 值 | 说明 | +|------|------|------| +| 小组件 (Tag) | `6px` | `borderRadiusSM` | +| 标准组件 (Button, Input) | `8px` | `borderRadius` | +| 大容器 (Card, Modal) | `12px` | `borderRadiusLG` | +| 特殊场景 (登录卡片) | `16-20px` | 仅限全屏独立页面 | +| 图标背景 | `12px` | 统计卡片图标容器 | + +--- + +## 4. 间距规范 + +基于 **8px** 网格系统: + +| 场景 | 值 | +|------|------| +| 紧凑间距 | `8px` | +| 小间距 | `12px` | +| 标准间距 | `16px` | +| 中等间距 | `24px` (内容区 padding、页面级 margin) | +| 宽松间距 | `32px` | + +**常见用法:** + +```tsx +// 页面标题与内容 +页面标题 + +// Row 间距 + + +// Card body padding + + +// 区块间距 + +``` + +--- + +## 5. 阴影规范 + +``` +轻微: 0 1px 2px rgba(0,0,0,0.03) → 内容区、Card 默认 +中等: 0 1px 3px rgba(0,0,0,0.06) → Header +悬停: var(--shadow-md) → Card:hover (全局自动) +强调: 0 25px 50px rgba(99,102,241,0.25) → 登录卡片 +``` + +--- + +## 6. 页面结构模板 + +### 6.1 列表页(ProTable 页面) + +这是最常见的页面类型,用于设备类型、批次、用户、管理员等管理页面。 + +```tsx +import React, { useState, useRef } from 'react'; +import { Button, message, Modal, Form, Input, Space, Tag, Popconfirm } from 'antd'; +import { PlusOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons'; +import { ProTable } from '@ant-design/pro-components'; +import type { ProColumns, ActionType } from '@ant-design/pro-components'; +import { getItems, createItem, updateItem, deleteItem } from '../../api/xxx'; +import type { Item } from '../../api/xxx'; + +const XxxPage: React.FC = () => { + const actionRef = useRef(null); + const [modalVisible, setModalVisible] = useState(false); + const [editingRecord, setEditingRecord] = useState(null); + const [form] = Form.useForm(); + const [loading, setLoading] = useState(false); + + // --- CRUD handlers --- + const handleAdd = () => { + setEditingRecord(null); + form.resetFields(); + setModalVisible(true); + }; + + const handleEdit = (record: Item) => { + setEditingRecord(record); + form.setFieldsValue(record); + setModalVisible(true); + }; + + const handleDelete = async (id: number) => { + try { + await deleteItem(id); + message.success('删除成功'); + actionRef.current?.reload(); + } catch (error) { + message.error(error instanceof Error ? error.message : '删除失败'); + } + }; + + const handleSubmit = async () => { + try { + const values = await form.validateFields(); + setLoading(true); + if (editingRecord) { + await updateItem(editingRecord.id, values); + message.success('更新成功'); + } else { + await createItem(values); + message.success('创建成功'); + } + setModalVisible(false); + form.resetFields(); + actionRef.current?.reload(); + } catch (error) { + if (error instanceof Error) { + message.error(error.message); + } + } finally { + setLoading(false); + } + }; + + // --- Column definitions --- + const columns: ProColumns[] = [ + { + title: 'ID', + dataIndex: 'id', + width: 80, + search: false, + }, + { + title: '名称', + dataIndex: 'name', + ellipsis: true, + }, + { + title: '状态', + dataIndex: 'is_active', + width: 80, + search: false, + render: (_, record) => ( + + {record.is_active ? '正常' : '禁用'} + + ), + }, + { + title: '创建时间', + dataIndex: 'created_at', + valueType: 'dateTime', + width: 180, + search: false, + }, + { + title: '操作', + width: 150, + search: false, + render: (_, record) => ( + + + handleDelete(record.id)}> + + + + ), + }, + ]; + + return ( +
+ {/* ✅ 必须加 cardBordered */} + + headerTitle="Xxx 管理" + rowKey="id" + actionRef={actionRef} + columns={columns} + cardBordered + request={async (params) => { + try { + const res = await getItems({ + page: params.current, + page_size: params.pageSize, + }); + return { + data: res.data.items, + total: res.data.total, + success: true, + }; + } catch (error) { + message.error('获取数据失败'); + return { data: [], total: 0, success: false }; + } + }} + toolBarRender={() => [ + , + ]} + pagination={{ + defaultPageSize: 10, + showSizeChanger: true, + }} + /> + + {/* Modal - 统一 layout="vertical" + marginTop 24 */} + setModalVisible(false)} + confirmLoading={loading} + destroyOnClose + > +
+ + + +
+
+
+ ); +}; + +export default XxxPage; +``` + +**关键规则:** + +1. ProTable 必须添加 `cardBordered` 属性 +2. Modal 内 Form 统一 `layout="vertical"` + `style={{ marginTop: 24 }}` +3. 删除操作必须用 `Popconfirm` 确认 +4. ID 列:`width: 80, search: false` +5. 时间列:`valueType: 'dateTime', width: 180, search: false` +6. 操作列:`search: false`,按钮用 `type="link" size="small"` +7. 分页统一:`defaultPageSize: 10, showSizeChanger: true` + +### 6.2 详情页 + +```tsx +import { statColors } from '../../theme/tokens'; + +// 页头:返回按钮 + 标题 + + + + 详情 - {record.name} + + + +// 信息卡片 + + + + + + +// 统计数据 + + + + + + + + +// 子表格 + +``` + +### 6.3 统计卡片 + +Dashboard 风格的统计卡片模板: + +```tsx +import { statColors } from '../../theme/tokens'; + + +
+ {/* 图标容器 */} +
+ +
+ {/* 数值区 */} +
+
+ 标题 +
+
+ {value.toLocaleString()} +
+
+
+
+``` + +**图标背景色规则:** 使用对应 statColor 的 8% 透明度作为背景。 + +``` +rgba(99, 102, 241, 0.08) → primary 背景 +rgba(16, 185, 129, 0.08) → success 背景 +rgba(139, 92, 246, 0.08) → purple 背景 +rgba(245, 158, 11, 0.08) → warning 背景 +rgba(6, 182, 212, 0.08) → cyan 背景 +rgba(236, 72, 153, 0.08) → pink 背景 +``` + +--- + +## 7. 图表规范 + +使用 `@ant-design/charts`,导入方式: + +```typescript +import { Pie, Column, Line, Area } from '@ant-design/charts'; +``` + +### 7.1 饼图 + +```tsx +const pieConfig = { + data: [{ type: '类别', value: 100 }], + angleField: 'value', + colorField: 'type', + radius: 0.85, + innerRadius: 0.6, // 环形图 + color: [statColors.primary, statColors.success, statColors.warning], + label: { + text: (d) => `${d.type}\n${d.value}`, + style: { fontSize: 12, fontWeight: 500 }, + }, + legend: { + color: { + position: 'bottom' as const, + layout: { justifyContent: 'center' as const }, + }, + }, +}; + +``` + +### 7.2 柱状图 + +```tsx +const columnConfig = { + data: [{ name: '类别', value: 100 }], + xField: 'name', + yField: 'value', + style: { + radiusTopLeft: 6, + radiusTopRight: 6, + fill: statColors.primary, + fillOpacity: 0.85, + }, + label: { + text: (d) => `${d.value}`, + textBaseline: 'bottom' as const, + style: { dy: -4, fontSize: 12 }, + }, + axis: { + y: { title: false }, + x: { title: false }, + }, +}; + +``` + +### 7.3 图表容器 + +```tsx + +
+ +
+
+``` + +- 图表容器高度统一 `320px` +- 空数据时显示居中灰色提示文字 +- 图表颜色优先使用 `statColors` 中的色值 + +--- + +## 8. Tag 状态映射 + +### 8.1 通用状态 + +```tsx +// 启用/禁用 + + {record.is_active ? '正常' : '禁用'} + + +// 设备状态 +const statusMap = { + in_stock: { color: 'default', text: '库存中' }, + bound: { color: 'green', text: '已绑定' }, + offline: { color: 'red', text: '离线' }, +}; + +// 布尔属性 +{value ? '是' : '否'} + +// 缺失数据 +record.field || 未导入 +``` + +### 8.2 角色 + +```tsx +const roleMap = { + super_admin: { text: '超级管理员', color: 'red' }, + admin: { text: '管理员', color: 'blue' }, + operator: { text: '操作员', color: 'default' }, +}; +``` + +--- + +## 9. 响应式断点 + +基于 Ant Design Grid 的断点系统: + +```tsx +// 统计卡片 (6列网格) + + +// 图表区域 (2列) + + +// 详情页统计 (4列) + + +// Descriptions 响应式列数 + +``` + +--- + +## 10. 样式规则 + +### 10.1 使用优先级 + +1. **Ant Design Theme Token** → 优先使用 `theme.useToken()` 获取的值 +2. **statColors** → 统计、图表颜色用 `statColors` +3. **CSS 变量** → 阴影、过渡动画用 `var(--xxx)` +4. **内联 style** → 布局、间距等用内联样式 +5. **全局 CSS** → 仅用于 Ant Design 组件覆盖(已有的 CSS 文件) + +### 10.2 禁止事项 + +- **不要** 硬编码 `#1890ff`(旧主题色),使用 `themeToken.colorPrimary` 或 `statColors.primary` +- **不要** 创建 `.module.css` 文件,保持现有内联样式模式 +- **不要** 在页面组件中直接引用 CSS 文件,全局 CSS 已在 `App.tsx` 统一导入 +- **不要** 使用 `style={{ color: '#999' }}`,用 `#6b7280` 或 `#9ca3af` 代替 +- **不要** 遗漏 ProTable 的 `cardBordered` 属性 + +### 10.3 获取主题 Token + +```tsx +import { theme } from 'antd'; + +const MyComponent: React.FC = () => { + const { token: themeToken } = theme.useToken(); + + return ( +
+ ... +
+ ); +}; +``` + +--- + +## 11. 文件结构 + +``` +src/ +├── theme/ +│ ├── tokens.ts # 主题配置 (themeConfig + statColors) +│ └── sidebar.css # 侧边栏样式 +├── styles/ +│ └── protable-theme.css # ProTable 全局样式 +├── components/ +│ └── Layout/ +│ └── index.tsx # 主布局 (侧边栏 + 头部 + Content) +├── pages/ +│ ├── Login/index.tsx # 登录页 (独立布局) +│ ├── Dashboard/index.tsx +│ ├── [Module]/ +│ │ ├── index.tsx # 列表页 +│ │ └── Detail.tsx # 详情页 (如有) +├── api/ # API 层 +├── store/ # Zustand 状态 +├── routes/index.tsx # 路由配置 +├── App.tsx # 根组件 (ConfigProvider + 主题) +└── index.css # CSS 变量 + 全局基础样式 +``` + +--- + +## 12. 新增页面检查清单 + +新开发一个页面时,逐项检查: + +- [ ] ProTable 添加了 `cardBordered` +- [ ] 使用 `statColors` 而非硬编码颜色 +- [ ] Tag 状态映射与已有页面一致 +- [ ] Modal Form 使用 `layout="vertical"` + `style={{ marginTop: 24 }}` +- [ ] 删除操作使用 `Popconfirm` +- [ ] 时间列使用 `valueType: 'dateTime'` +- [ ] 页面标题 `` + `marginBottom: 24` +- [ ] 响应式布局使用 `Row/Col` + 正确断点 +- [ ] 详情页有返回按钮 (`type="text"`) +- [ ] 空状态文字颜色使用 `#9ca3af` +- [ ] 图表容器高度 `320px` +- [ ] 分页配置 `defaultPageSize: 10, showSizeChanger: true` + +--- + +## 13. 新增路由步骤 + +1. 在 `src/pages/` 下创建页面组件 +2. 在 `src/routes/index.tsx` 的 `children` 数组中添加路由 +3. 在 `src/components/Layout/index.tsx` 的 `menuItems` 中添加菜单项 +4. 在 `src/api/` 下创建对应的 API 文件 + +```tsx +// routes/index.tsx +{ + path: 'new-page', + element: <NewPage />, +} + +// Layout/index.tsx menuItems +{ + key: '/new-page', + icon: <SomeOutlined />, + label: '新页面', +} +``` diff --git a/package-lock.json b/package-lock.json index a346677..7c0e211 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "rtc_web", "version": "0.0.0", "dependencies": { + "@ant-design/charts": "^2.6.7", "@ant-design/icons": "^6.1.0", "@ant-design/pro-components": "^2.8.10", "antd": "^5.29.3", @@ -33,6 +34,34 @@ "vite": "^7.2.4" } }, + "node_modules/@ant-design/charts": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/@ant-design/charts/-/charts-2.6.7.tgz", + "integrity": "sha512-XfmsnspUpfrMlRFGTwmHJ2TPKcosq5a5nSxAfIOpEXAvmJBT2N16oejGTZhUFTzba8W3XtBOziwRAXmDmLUqvA==", + "license": "MIT", + "dependencies": { + "@ant-design/graphs": "^2.1.1", + "@ant-design/plots": "^2.6.7", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">=16.8.4", + "react-dom": ">=16.8.4" + } + }, + "node_modules/@ant-design/charts-util": { + "version": "0.0.1-alpha.7", + "resolved": "https://registry.npmjs.org/@ant-design/charts-util/-/charts-util-0.0.1-alpha.7.tgz", + "integrity": "sha512-Yh0o6EdO6SvdSnStFZMbnUzjyymkVzV+TQ9ymVW9hlVgO/fUkUII3JYSdV+UVcFnYwUF0YiDKuSTLCZNAzg2bQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">=16.8.4", + "react-dom": ">=16.8.4" + } + }, "node_modules/@ant-design/colors": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-8.0.1.tgz", @@ -85,6 +114,24 @@ "node": ">=8.x" } }, + "node_modules/@ant-design/graphs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ant-design/graphs/-/graphs-2.1.1.tgz", + "integrity": "sha512-qT3Oo8BWeoAmZEy9gfR6uIk+rczbNJ3sWXKonoOD5koATWv7dY0kgvS1JnhdM1QW4FkfPPJTeQVSlRRUtvWDwA==", + "license": "MIT", + "dependencies": { + "@ant-design/charts-util": "0.0.1-alpha.7", + "@antv/g6": "^5.0.44", + "@antv/g6-extension-react": "^0.2.0", + "@antv/graphin": "^3.0.4", + "lodash": "^4.17.21", + "styled-components": "^6.1.15" + }, + "peerDependencies": { + "react": ">=16.8.4", + "react-dom": ">=16.8.4" + } + }, "node_modules/@ant-design/icons": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-6.1.0.tgz", @@ -110,6 +157,37 @@ "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==", "license": "MIT" }, + "node_modules/@ant-design/plots": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/@ant-design/plots/-/plots-2.6.8.tgz", + "integrity": "sha512-QsunUs2d5rbq/1BwVhga/siA5H50OaG23YopMYwPD4sPsza6NQzPQ8FM3elNIsD/BIk298tihqX1cJ/MmvVJbQ==", + "license": "MIT", + "dependencies": { + "@ant-design/charts-util": "0.0.3", + "@antv/event-emitter": "^0.1.3", + "@antv/g": "^6.1.7", + "@antv/g2": "^5.2.7", + "@antv/g2-extension-plot": "^0.2.1", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">=16.8.4", + "react-dom": ">=16.8.4" + } + }, + "node_modules/@ant-design/plots/node_modules/@ant-design/charts-util": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@ant-design/charts-util/-/charts-util-0.0.3.tgz", + "integrity": "sha512-x1H7UT6t4dXAyGRoHqlOnEsEqBSTANFGTZEAMI0CWYhYUpp13n0o9grl9oPtoL6FEQMjUBTY+zGJKlHkz8smMw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">=16.8.4", + "react-dom": ">=16.8.4" + } + }, "node_modules/@ant-design/pro-card": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@ant-design/pro-card/-/pro-card-2.10.0.tgz", @@ -716,6 +794,366 @@ "react": ">=16.9.0" } }, + "node_modules/@antv/algorithm": { + "version": "0.1.26", + "resolved": "https://registry.npmjs.org/@antv/algorithm/-/algorithm-0.1.26.tgz", + "integrity": "sha512-DVhcFSQ8YQnMNW34Mk8BSsfc61iC1sAnmcfYoXTAshYHuU50p/6b7x3QYaGctDNKWGvi1ub7mPcSY0bK+aN0qg==", + "license": "MIT", + "dependencies": { + "@antv/util": "^2.0.13", + "tslib": "^2.0.0" + } + }, + "node_modules/@antv/algorithm/node_modules/@antv/util": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@antv/util/-/util-2.0.17.tgz", + "integrity": "sha512-o6I9hi5CIUvLGDhth0RxNSFDRwXeywmt6ExR4+RmVAzIi48ps6HUy+svxOCayvrPBN37uE6TAc2KDofRo0nK9Q==", + "license": "ISC", + "dependencies": { + "csstype": "^3.0.8", + "tslib": "^2.0.3" + } + }, + "node_modules/@antv/component": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@antv/component/-/component-2.1.11.tgz", + "integrity": "sha512-dTdz8VAd3rpjOaGEZTluz82mtzrP4XCtNlNQyrxY7VNRNcjtvpTLDn57bUL2lRu1T+iklKvgbE2llMriWkq9vQ==", + "license": "MIT", + "dependencies": { + "@antv/g": "^6.1.11", + "@antv/scale": "^0.4.16", + "@antv/util": "^3.3.10", + "svg-path-parser": "^1.1.0" + } + }, + "node_modules/@antv/component/node_modules/@antv/scale": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@antv/scale/-/scale-0.4.16.tgz", + "integrity": "sha512-5wg/zB5kXHxpTV5OYwJD3ja6R8yTiqIOkjOhmpEJiowkzRlbEC/BOyMvNUq5fqFIHnMCE9woO7+c3zxEQCKPjw==", + "license": "MIT", + "dependencies": { + "@antv/util": "^3.3.7", + "color-string": "^1.5.5", + "fecha": "^4.2.1" + } + }, + "node_modules/@antv/coord": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@antv/coord/-/coord-0.4.7.tgz", + "integrity": "sha512-UTbrMLhwJUkKzqJx5KFnSRpU3BqrdLORJbwUbHK2zHSCT3q3bjcFA//ZYLVfIlwqFDXp/hzfMyRtp0c77A9ZVA==", + "license": "MIT", + "dependencies": { + "@antv/scale": "^0.4.12", + "@antv/util": "^2.0.13", + "gl-matrix": "^3.4.3" + } + }, + "node_modules/@antv/coord/node_modules/@antv/scale": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@antv/scale/-/scale-0.4.16.tgz", + "integrity": "sha512-5wg/zB5kXHxpTV5OYwJD3ja6R8yTiqIOkjOhmpEJiowkzRlbEC/BOyMvNUq5fqFIHnMCE9woO7+c3zxEQCKPjw==", + "license": "MIT", + "dependencies": { + "@antv/util": "^3.3.7", + "color-string": "^1.5.5", + "fecha": "^4.2.1" + } + }, + "node_modules/@antv/coord/node_modules/@antv/scale/node_modules/@antv/util": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@antv/util/-/util-3.3.11.tgz", + "integrity": "sha512-FII08DFM4ABh2q5rPYdr0hMtKXRgeZazvXaFYCs7J7uTcWDHUhczab2qOCJLNDugoj8jFag1djb7wS9ehaRYBg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "gl-matrix": "^3.3.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@antv/coord/node_modules/@antv/util": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@antv/util/-/util-2.0.17.tgz", + "integrity": "sha512-o6I9hi5CIUvLGDhth0RxNSFDRwXeywmt6ExR4+RmVAzIi48ps6HUy+svxOCayvrPBN37uE6TAc2KDofRo0nK9Q==", + "license": "ISC", + "dependencies": { + "csstype": "^3.0.8", + "tslib": "^2.0.3" + } + }, + "node_modules/@antv/event-emitter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@antv/event-emitter/-/event-emitter-0.1.3.tgz", + "integrity": "sha512-4ddpsiHN9Pd4UIlWuKVK1C4IiZIdbwQvy9i7DUSI3xNJ89FPUFt8lxDYj8GzzfdllV0NkJTRxnG+FvLk0llidg==", + "license": "MIT" + }, + "node_modules/@antv/expr": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@antv/expr/-/expr-1.0.2.tgz", + "integrity": "sha512-vrfdmPHkTuiS5voVutKl2l06w1ihBh9A8SFdQPEE+2KMVpkymzGOF1eWpfkbGZ7tiFE15GodVdhhHomD/hdIwg==", + "license": "MIT" + }, + "node_modules/@antv/g": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@antv/g/-/g-6.3.1.tgz", + "integrity": "sha512-WYEKqy86LHB2PzTmrZXrIsIe+3Epeds2f68zceQ+BJtRoGki7Sy4IhlC8LrUMztgfT1t3d/0L745NWZwITroKA==", + "license": "MIT", + "dependencies": { + "@antv/g-lite": "2.7.0", + "@antv/util": "^3.3.5", + "@babel/runtime": "^7.25.6", + "gl-matrix": "^3.4.3", + "html2canvas": "^1.4.1" + } + }, + "node_modules/@antv/g-canvas": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@antv/g-canvas/-/g-canvas-2.2.0.tgz", + "integrity": "sha512-h7zVBBo2aO64DuGKvq9sG+yTU3sCUb9DALCVm7nz8qGPs8hhLuFOkKPEzUDNfNYZGJUGzY8UDtJ3QRGRFcvEQg==", + "license": "MIT", + "dependencies": { + "@antv/g-lite": "2.7.0", + "@antv/g-math": "3.1.0", + "@antv/util": "^3.3.5", + "@babel/runtime": "^7.25.6", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } + }, + "node_modules/@antv/g-lite": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@antv/g-lite/-/g-lite-2.7.0.tgz", + "integrity": "sha512-uSzgHYa5bwR5L2Au7/5tsOhFmXKZKLPBH90+Q9bP9teVs5VT4kOAi0isPSpDI8uhdDC2/VrfTWu5K9HhWI6FWw==", + "license": "MIT", + "dependencies": { + "@antv/g-math": "3.1.0", + "@antv/util": "^3.3.5", + "@antv/vendor": "^1.0.3", + "@babel/runtime": "^7.25.6", + "eventemitter3": "^5.0.1", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } + }, + "node_modules/@antv/g-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@antv/g-math/-/g-math-3.1.0.tgz", + "integrity": "sha512-DtN1Gj/yI0UiK18nSBsZX8RK0LszGwqfb+cBYWgE+ddyTm8dZnW4tPUhV7QXePsS6/A5hHC+JFpAAK7OEGo5ZQ==", + "license": "MIT", + "dependencies": { + "@antv/util": "^3.3.5", + "@babel/runtime": "^7.25.6", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } + }, + "node_modules/@antv/g-plugin-dragndrop": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@antv/g-plugin-dragndrop/-/g-plugin-dragndrop-2.1.1.tgz", + "integrity": "sha512-+aesDUJVQDs6UJ2bOBbDlaGAPCfHmU0MbrMTlQlfpwNplWueqtgVAZ3L57oZ2ZGHRWUHiRwZGPjXMBM3O2LELw==", + "license": "MIT", + "dependencies": { + "@antv/g-lite": "2.7.0", + "@antv/util": "^3.3.5", + "@babel/runtime": "^7.25.6", + "tslib": "^2.5.3" + } + }, + "node_modules/@antv/g-svg": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@antv/g-svg/-/g-svg-2.1.1.tgz", + "integrity": "sha512-gVzBkjqA8FzDTbkuIxj6L0Omz/X/hFbYLzK6alWr0sHTfywqP6czcjDUJU8DF2MRIY1Twy55uZYW4dqqLXOXXg==", + "license": "MIT", + "dependencies": { + "@antv/g-lite": "2.7.0", + "@antv/util": "^3.3.5", + "@babel/runtime": "^7.25.6", + "gl-matrix": "^3.4.3", + "tslib": "^2.5.3" + } + }, + "node_modules/@antv/g2": { + "version": "5.4.8", + "resolved": "https://registry.npmjs.org/@antv/g2/-/g2-5.4.8.tgz", + "integrity": "sha512-IvgIpwmT4M5/QAd3Mn2WiHIDeBqFJ4WA2gcZhRRSZuZ2KmgCqZWZwwIT0hc+kIGxwYeDoCQqf//t6FMVu3ryBg==", + "license": "MIT", + "dependencies": { + "@antv/component": "^2.1.9", + "@antv/coord": "^0.4.7", + "@antv/event-emitter": "^0.1.3", + "@antv/expr": "^1.0.2", + "@antv/g": "^6.1.24", + "@antv/g-canvas": "^2.0.43", + "@antv/g-plugin-dragndrop": "^2.0.35", + "@antv/scale": "^0.5.1", + "@antv/util": "^3.3.10", + "@antv/vendor": "^1.0.11", + "flru": "^1.0.2", + "pdfast": "^0.2.0" + } + }, + "node_modules/@antv/g2-extension-plot": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@antv/g2-extension-plot/-/g2-extension-plot-0.2.2.tgz", + "integrity": "sha512-KJXCXO7as+h0hDqirGXf1omrNuYzQmY3VmBmp7lIvkepbQ7sz3pPwy895r1FWETGF3vTk5UeFcAF5yzzBHWgbw==", + "dependencies": { + "@antv/g2": "^5.1.8", + "@antv/util": "^3.3.5", + "@antv/vendor": "^1.0.10" + } + }, + "node_modules/@antv/g6": { + "version": "5.0.51", + "resolved": "https://registry.npmjs.org/@antv/g6/-/g6-5.0.51.tgz", + "integrity": "sha512-/88LJDZ7FHKtpyJibXOnJWZ8gFRp32mLb8KzEFrMuiIC/dsZgTf/oYVw6L4tLKooPXfXqUtrJb2tWFMGR04EMg==", + "license": "MIT", + "dependencies": { + "@antv/algorithm": "^0.1.26", + "@antv/component": "^2.1.7", + "@antv/event-emitter": "^0.1.3", + "@antv/g": "^6.1.28", + "@antv/g-canvas": "^2.0.48", + "@antv/g-plugin-dragndrop": "^2.0.38", + "@antv/graphlib": "^2.0.4", + "@antv/hierarchy": "^0.7.1", + "@antv/layout": "1.2.14-beta.9", + "@antv/util": "^3.3.11", + "bubblesets-js": "^2.3.4" + } + }, + "node_modules/@antv/g6-extension-react": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@antv/g6-extension-react/-/g6-extension-react-0.2.6.tgz", + "integrity": "sha512-JWOiWMz/r4jG+Nn2Y28LfohpxfUaf9M/0brLdKBshSVa4DraQFfQvA9OTIbzahLLoxIXsKKG2KteQ9QcXL26Kw==", + "license": "MIT", + "dependencies": { + "@antv/g": "^6.1.24", + "@antv/g-svg": "^2.0.38" + }, + "peerDependencies": { + "@antv/g6": "^5.0.50", + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@antv/graphin": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@antv/graphin/-/graphin-3.0.5.tgz", + "integrity": "sha512-V/j8R8Ty44wUqxVIYLdpPuIO8WWCTIVq1eBJg5YRunL5t5o5qAFpC/qkQxslbBMWyKdIH0oWBnvHA74riGi7cw==", + "license": "MIT", + "dependencies": { + "@antv/g6": "^5.0.28" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.1.0", + "react-dom": "^18.0.0 || ^19.1.0" + } + }, + "node_modules/@antv/graphlib": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@antv/graphlib/-/graphlib-2.0.4.tgz", + "integrity": "sha512-zc/5oQlsdk42Z0ib1mGklwzhJ5vczLFiPa1v7DgJkTbgJ2YxRh9xdarf86zI49sKVJmgbweRpJs7Nu5bIiwv4w==", + "license": "MIT", + "dependencies": { + "@antv/event-emitter": "^0.1.3" + } + }, + "node_modules/@antv/hierarchy": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@antv/hierarchy/-/hierarchy-0.7.1.tgz", + "integrity": "sha512-7r22r+HxfcRZp79ZjGmsn97zgC1Iajrv0Mm9DIgx3lPfk+Kme2MG/+EKdZj1iEBsN0rJRzjWVPGL5YrBdVHchw==", + "license": "MIT" + }, + "node_modules/@antv/layout": { + "version": "1.2.14-beta.9", + "resolved": "https://registry.npmjs.org/@antv/layout/-/layout-1.2.14-beta.9.tgz", + "integrity": "sha512-wPlwBFMtq2lWZFc89/7Lzb8fjHnyKVZZ9zBb2h+zZIP0YWmVmHRE8+dqCiPKOyOGUXEdDtn813f1g107dCHZlg==", + "license": "MIT", + "dependencies": { + "@antv/event-emitter": "^0.1.3", + "@antv/graphlib": "^2.0.0", + "@antv/util": "^3.3.2", + "@naoak/workerize-transferable": "^0.1.0", + "comlink": "^4.4.1", + "d3-force": "^3.0.0", + "d3-force-3d": "^3.0.5", + "d3-octree": "^1.0.2", + "d3-quadtree": "^3.0.1", + "dagre": "^0.8.5", + "ml-matrix": "^6.10.4", + "tslib": "^2.5.0" + } + }, + "node_modules/@antv/scale": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@antv/scale/-/scale-0.5.2.tgz", + "integrity": "sha512-rTHRAwvpHWC5PGZF/mJ2ZuTDqwwvVBDRph0Uu5PV9BXwzV7K8+9lsqGJ+XHVLxe8c6bKog5nlzvV/dcYb0d5Ow==", + "license": "MIT", + "dependencies": { + "@antv/util": "^3.3.7", + "color-string": "^1.5.5", + "fecha": "^4.2.1" + } + }, + "node_modules/@antv/util": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@antv/util/-/util-3.3.11.tgz", + "integrity": "sha512-FII08DFM4ABh2q5rPYdr0hMtKXRgeZazvXaFYCs7J7uTcWDHUhczab2qOCJLNDugoj8jFag1djb7wS9ehaRYBg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "gl-matrix": "^3.3.0", + "tslib": "^2.3.1" + } + }, + "node_modules/@antv/vendor": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@antv/vendor/-/vendor-1.0.11.tgz", + "integrity": "sha512-LmhPEQ+aapk3barntaiIxJ5VHno/Tyab2JnfdcPzp5xONh/8VSfed4bo/9xKo5HcUAEydko38vYLfj6lJliLiw==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.2.1", + "@types/d3-color": "^3.1.3", + "@types/d3-dispatch": "^3.0.6", + "@types/d3-dsv": "^3.0.7", + "@types/d3-ease": "^3.0.2", + "@types/d3-fetch": "^3.0.7", + "@types/d3-force": "^3.0.10", + "@types/d3-format": "^3.0.4", + "@types/d3-geo": "^3.1.0", + "@types/d3-hierarchy": "^3.1.7", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-path": "^3.1.0", + "@types/d3-quadtree": "^3.0.6", + "@types/d3-random": "^3.0.3", + "@types/d3-scale": "^4.0.9", + "@types/d3-scale-chromatic": "^3.1.0", + "@types/d3-shape": "^3.1.7", + "@types/d3-time": "^3.0.4", + "@types/d3-timer": "^3.0.2", + "d3-array": "^3.2.4", + "d3-color": "^3.1.0", + "d3-dispatch": "^3.0.1", + "d3-dsv": "^3.0.1", + "d3-ease": "^3.0.1", + "d3-fetch": "^3.0.1", + "d3-force": "^3.0.0", + "d3-force-3d": "^3.0.5", + "d3-format": "^3.1.0", + "d3-geo": "^3.1.1", + "d3-geo-projection": "^4.0.0", + "d3-hierarchy": "^3.1.2", + "d3-interpolate": "^3.0.1", + "d3-path": "^3.1.0", + "d3-quadtree": "^3.0.1", + "d3-random": "^3.0.1", + "d3-regression": "^1.3.10", + "d3-scale": "^4.0.2", + "d3-scale-chromatic": "^3.1.0", + "d3-shape": "^3.2.0", + "d3-time": "^3.1.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/@babel/code-frame": { "version": "7.28.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", @@ -1102,6 +1540,21 @@ "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==", "license": "MIT" }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, "node_modules/@emotion/unitless": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", @@ -1763,7 +2216,6 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1785,30 +2237,47 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@naoak/workerize-transferable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@naoak/workerize-transferable/-/workerize-transferable-0.1.0.tgz", + "integrity": "sha512-fDLfuP71IPNP5+zSfxFb52OHgtjZvauRJWbVnpzQ7G7BjcbLjTny0OW1d3ZO806XKpLWNKmeeW3MhE0sy8iwYQ==", + "license": "MIT", + "peerDependencies": { + "workerize-loader": "*" + } + }, "node_modules/@rc-component/async-validator": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.1.0.tgz", @@ -2384,25 +2853,179 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "24.10.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.9.tgz", "integrity": "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~7.16.0" @@ -2428,6 +3051,12 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/stylis": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.7.tgz", + "integrity": "sha512-VgDNokpBoKF+wrdvhAAfS55OMQpL6QRglwTwNC3kIgBrzZxA4WsFj+2eLfEA/uMUDzBcEhYmjSbwQakn/i3ajA==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.54.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.54.0.tgz", @@ -2733,11 +3362,185 @@ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "license": "Apache-2.0", + "peer": true + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -2746,6 +3549,19 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -2782,6 +3598,48 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, "node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2935,16 +3793,34 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/baseline-browser-mapping": { "version": "2.9.19", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", - "dev": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" } }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": "*" + } + }, "node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -2960,7 +3836,6 @@ "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -2990,6 +3865,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/bubblesets-js": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/bubblesets-js/-/bubblesets-js-2.3.4.tgz", + "integrity": "sha512-DyMjHmpkS2+xcFNtyN00apJYL3ESdp9fTrkDr5+9Qg/GPqFmcWgGsK1akZnttE1XFxJ/VMy4DNNGMGYtmFp1Sg==", + "license": "MIT" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT", + "peer": true + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -3013,11 +3901,19 @@ "node": ">=6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001766", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3051,6 +3947,16 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -3083,9 +3989,18 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3098,6 +4013,21 @@ "node": ">= 0.8" } }, + "node_modules/comlink": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz", + "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==", + "license": "Apache-2.0" + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/compute-scroll-into-view": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.1.tgz", @@ -3155,12 +4085,339 @@ "node": ">= 8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-line-break": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", + "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-binarytree": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz", + "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==", + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "license": "ISC", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "license": "ISC", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force-3d": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/d3-force-3d/-/d3-force-3d-3.0.6.tgz", + "integrity": "sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==", + "license": "MIT", + "dependencies": { + "d3-binarytree": "1", + "d3-dispatch": "1 - 3", + "d3-octree": "1", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo-projection": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-4.0.0.tgz", + "integrity": "sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==", + "license": "ISC", + "dependencies": { + "commander": "7", + "d3-array": "1 - 3", + "d3-geo": "1.12.0 - 3" + }, + "bin": { + "geo2svg": "bin/geo2svg.js", + "geograticule": "bin/geograticule.js", + "geoproject": "bin/geoproject.js", + "geoquantize": "bin/geoquantize.js", + "geostitch": "bin/geostitch.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-octree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz", + "integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==", + "license": "MIT" + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-regression": { + "version": "1.3.10", + "resolved": "https://registry.npmjs.org/d3-regression/-/d3-regression-1.3.10.tgz", + "integrity": "sha512-PF8GWEL70cHHWpx2jUQXc68r1pyPHIA+St16muk/XRokETzlegj5LriNKg7o4LR0TySug4nHYPJNNRz/W+/Niw==", + "license": "BSD-3-Clause" + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/dagre": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", + "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==", + "license": "MIT", + "dependencies": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, "node_modules/dayjs": { "version": "1.11.19", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", @@ -3228,9 +4485,32 @@ "version": "1.5.279", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.279.tgz", "integrity": "sha512-0bblUU5UNdOt5G7XqGiJtpZMONma6WAfq9vsFmtn9x1+joAObr6x1chfqyxFSDCAFwFhCQDrqeAr6MYdpwJ9Hg==", - "dev": true, "license": "ISC" }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -3249,6 +4529,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", + "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "license": "MIT", + "peer": true + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -3322,7 +4609,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -3496,7 +4782,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -3509,7 +4794,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -3525,11 +4809,26 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { @@ -3546,6 +4845,23 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -3564,6 +4880,12 @@ } } }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3615,6 +4937,15 @@ "dev": true, "license": "ISC" }, + "node_modules/flru": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/flru/-/flru-1.0.2.tgz", + "integrity": "sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -3722,6 +5053,12 @@ "node": ">= 0.4" } }, + "node_modules/gl-matrix": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.4.tgz", + "integrity": "sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==", + "license": "MIT" + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3735,6 +5072,13 @@ "node": ">=10.13.0" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "license": "BSD-2-Clause", + "peer": true + }, "node_modules/globals": { "version": "16.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", @@ -3760,11 +5104,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC", + "peer": true + }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3826,6 +5185,31 @@ "hermes-estree": "0.25.1" } }, + "node_modules/html2canvas": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", + "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", + "license": "MIT", + "dependencies": { + "css-line-break": "^2.1.0", + "text-segmentation": "^1.0.3" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3863,6 +5247,27 @@ "node": ">=0.8.19" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-any-array": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-any-array/-/is-any-array-2.0.1.tgz", + "integrity": "sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==", + "license": "MIT" + }, + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3899,6 +5304,37 @@ "dev": true, "license": "ISC" }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3938,6 +5374,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT", + "peer": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3965,7 +5408,6 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -3998,6 +5440,35 @@ "node": ">= 0.8.0" } }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", + "peer": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4064,6 +5535,13 @@ "node": ">= 0.4" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT", + "peer": true + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -4098,6 +5576,45 @@ "node": "*" } }, + "node_modules/ml-array-max": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/ml-array-max/-/ml-array-max-1.2.4.tgz", + "integrity": "sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.0" + } + }, + "node_modules/ml-array-min": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/ml-array-min/-/ml-array-min-1.2.3.tgz", + "integrity": "sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.0" + } + }, + "node_modules/ml-array-rescale": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ml-array-rescale/-/ml-array-rescale-1.3.7.tgz", + "integrity": "sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.0", + "ml-array-max": "^1.2.4", + "ml-array-min": "^1.2.3" + } + }, + "node_modules/ml-matrix": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/ml-matrix/-/ml-matrix-6.12.1.tgz", + "integrity": "sha512-TJ+8eOFdp+INvzR4zAuwBQJznDUfktMtOB6g/hUcGh3rcyjxbz4Te57Pgri8Q9bhSQ7Zys4IYOGhFdnlgeB6Lw==", + "license": "MIT", + "dependencies": { + "is-any-array": "^2.0.1", + "ml-array-rescale": "^1.3.7" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4109,7 +5626,6 @@ "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, "funding": [ { "type": "github", @@ -4131,11 +5647,17 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT", + "peer": true + }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true, "license": "MIT" }, "node_modules/object-assign": { @@ -4239,11 +5761,16 @@ "node": ">=16" } }, + "node_modules/pdfast": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pdfast/-/pdfast-0.2.0.tgz", + "integrity": "sha512-cq6TTu6qKSFUHwEahi68k/kqN2mfepjkGrG9Un70cgdRRKLKY6Rf8P8uvP2NvZktaQZNF3YE7agEkLj0vGK9bA==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -4288,6 +5815,12 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4331,6 +5864,16 @@ "node": ">=6" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/rc-cascader": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.34.0.tgz", @@ -5027,6 +6570,16 @@ "lodash": "^4.0.1" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", @@ -5088,6 +6641,33 @@ "fsevents": "~2.3.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", + "license": "BSD-3-Clause" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, "node_modules/safe-stable-stringify": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", @@ -5097,12 +6677,75 @@ "node": ">=10" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT", + "peer": true + }, "node_modules/scroll-into-view-if-needed": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", @@ -5122,6 +6765,16 @@ "semver": "bin/semver.js" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-cookie-parser": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", @@ -5157,16 +6810,45 @@ "node": ">=8" } }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/string-convert": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", @@ -5186,6 +6868,73 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/styled-components": { + "version": "6.3.9", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.3.9.tgz", + "integrity": "sha512-J72R4ltw0UBVUlEjTzI0gg2STOqlI9JBhQOL4Dxt7aJOnnSesy0qJDn4PYfMCafk9cWOaVg129Pesl5o+DIh0Q==", + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.4.0", + "@emotion/unitless": "0.10.0", + "@types/stylis": "4.2.7", + "css-to-react-native": "3.2.0", + "csstype": "3.2.3", + "postcss": "8.4.49", + "shallowequal": "1.1.0", + "stylis": "4.3.6", + "tslib": "2.8.1" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/stylis": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", @@ -5205,6 +6954,12 @@ "node": ">=8" } }, + "node_modules/svg-path-parser": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/svg-path-parser/-/svg-path-parser-1.1.0.tgz", + "integrity": "sha512-jGCUqcQyXpfe38R7RFfhrMyfXcBmpMNJI/B+4CE9/Unkh98UporAc461GTthv+TVDuZXsBx7/WiwJb1Oh4tt4A==", + "license": "MIT" + }, "node_modules/swr": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.8.tgz", @@ -5218,6 +6973,90 @@ "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.16", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", + "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT", + "peer": true + }, + "node_modules/text-segmentation": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", + "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", + "license": "MIT", + "dependencies": { + "utrie": "^1.0.2" + } + }, "node_modules/throttle-debounce": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", @@ -5330,14 +7169,12 @@ "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, "license": "MIT" }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, "funding": [ { "type": "opencollective", @@ -5383,6 +7220,15 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/utrie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", + "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", + "license": "MIT", + "dependencies": { + "base64-arraybuffer": "^1.0.2" + } + }, "node_modules/vite": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", @@ -5467,6 +7313,103 @@ "loose-envify": "^1.0.0" } }, + "node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.105.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", + "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.19.0", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.5.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5493,6 +7436,19 @@ "node": ">=0.10.0" } }, + "node_modules/workerize-loader": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/workerize-loader/-/workerize-loader-2.0.2.tgz", + "integrity": "sha512-HoZ6XY4sHWxA2w0WpzgBwUiR3dv1oo7bS+oCwIpb6n54MclQ/7KXdXsVIChTCygyuHtVuGBO1+i3HzTt699UJQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "loader-utils": "^2.0.0" + }, + "peerDependencies": { + "webpack": "*" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 6de560b..ba577ed 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@ant-design/charts": "^2.6.7", "@ant-design/icons": "^6.1.0", "@ant-design/pro-components": "^2.8.10", "antd": "^5.29.3", diff --git a/src/App.tsx b/src/App.tsx index 8992976..4ae526a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,22 +2,17 @@ import { RouterProvider } from 'react-router-dom'; import { ConfigProvider } from 'antd'; import zhCN from 'antd/locale/zh_CN'; import router from './routes'; +import { themeConfig } from './theme/tokens'; import 'dayjs/locale/zh-cn'; +import './theme/sidebar.css'; +import './styles/protable-theme.css'; function App() { - return ( - <ConfigProvider - locale={zhCN} - theme={{ - token: { - colorPrimary: '#1890ff', - borderRadius: 6, - }, - }} - > - <RouterProvider router={router} /> - </ConfigProvider> - ); + return ( + <ConfigProvider locale={zhCN} theme={themeConfig}> + <RouterProvider router={router} /> + </ConfigProvider> + ); } export default App; diff --git a/src/api/batch.ts b/src/api/batch.ts index 0000449..ba23490 100644 --- a/src/api/batch.ts +++ b/src/api/batch.ts @@ -43,6 +43,7 @@ export const getBatches = (params?: { page?: number; page_size?: number; device_type?: number; + batch_no?: string; }) => { return request.get<unknown, ApiResponse<PaginatedResponse<DeviceBatch>>>('/api/admin/device-batches/', { params }); }; diff --git a/src/api/deviceType.ts b/src/api/deviceType.ts index d054a97..ff69964 100644 --- a/src/api/deviceType.ts +++ b/src/api/deviceType.ts @@ -13,7 +13,13 @@ export interface DeviceType { } // 获取设备类型列表 -export const getDeviceTypes = (params?: { page?: number; page_size?: number }) => { +export const getDeviceTypes = (params?: { + page?: number; + page_size?: number; + brand?: string; + product_code?: string; + name?: string; +}) => { return request.get<unknown, ApiResponse<PaginatedResponse<DeviceType>>>('/api/admin/device-types/', { params }); }; diff --git a/src/api/request.ts b/src/api/request.ts index 5fcb8a2..8fd57c1 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -41,16 +41,18 @@ function reportToLogCenter(error: Error, context?: Record<string, unknown>) { }; // 使用 sendBeacon 确保页面关闭时也能发送 + const body = JSON.stringify(payload); if (navigator.sendBeacon) { + const blob = new Blob([body], { type: 'application/json' }); navigator.sendBeacon( `${LOG_CENTER_URL}/api/v1/logs/report`, - JSON.stringify(payload) + blob ); } else { fetch(`${LOG_CENTER_URL}/api/v1/logs/report`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload), + body, keepalive: true, }).catch(() => { }); // 静默失败 } @@ -85,6 +87,10 @@ request.interceptors.request.use( // 响应拦截器 - 统一处理响应 request.interceptors.response.use( (response) => { + // 文件下载(blob)直接返回完整 response + if (response.config.responseType === 'blob') { + return response; + } const data = response.data; // 业务错误处理 if (data.code !== 0) { diff --git a/src/api/user.ts b/src/api/user.ts index 6973d22..a7606bc 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -48,7 +48,7 @@ export const toggleAppUserStatus = (id: number) => { }; // 获取管理员列表 -export const getAdminUsers = (params?: { page?: number; page_size?: number }) => { +export const getAdminUsers = (params?: { page?: number; page_size?: number; username?: string }) => { return request.get<unknown, ApiResponse<PaginatedResponse<AdminUser>>>('/api/admin/admins/', { params }); }; diff --git a/src/components/Layout/index.tsx b/src/components/Layout/index.tsx index 015f615..9207857 100644 --- a/src/components/Layout/index.tsx +++ b/src/components/Layout/index.tsx @@ -8,6 +8,7 @@ import { theme, Button, Space, + Tag, } from 'antd'; import { DashboardOutlined, @@ -92,21 +93,23 @@ const MainLayout: React.FC = () => { ]; const getRoleLabel = (role?: string) => { - const roleMap: Record<string, string> = { - super_admin: '超级管理员', - admin: '管理员', - operator: '操作员', + const roleMap: Record<string, { label: string; color: string }> = { + super_admin: { label: '超级管理员', color: 'purple' }, + admin: { label: '管理员', color: 'blue' }, + operator: { label: '操作员', color: 'default' }, }; - return roleMap[role || ''] || role; + return roleMap[role || ''] || { label: role, color: 'default' }; }; + const roleInfo = getRoleLabel(adminInfo?.role); + return ( <Layout style={{ minHeight: '100vh' }}> <Sider trigger={null} collapsible collapsed={collapsed} - theme="dark" + className="rtc-sidebar" style={{ overflow: 'auto', height: '100vh', @@ -116,19 +119,9 @@ const MainLayout: React.FC = () => { bottom: 0, }} > - <div - style={{ - height: 64, - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - color: '#fff', - fontSize: collapsed ? 16 : 20, - fontWeight: 'bold', - borderBottom: '1px solid rgba(255,255,255,0.1)', - }} - > - {collapsed ? 'RTC' : 'RTC 管理后台'} + <div className="rtc-sidebar-logo"> + <div className="rtc-sidebar-logo-icon">R</div> + {!collapsed && <span>RTC 管理后台</span>} </div> <Menu theme="dark" @@ -136,9 +129,15 @@ const MainLayout: React.FC = () => { selectedKeys={[location.pathname]} items={menuItems} onClick={handleMenuClick} + style={{ borderRight: 0 }} /> </Sider> - <Layout style={{ marginLeft: collapsed ? 80 : 200, transition: 'margin-left 0.2s' }}> + <Layout + style={{ + marginLeft: collapsed ? 80 : 200, + transition: 'margin-left 0.2s cubic-bezier(0.4, 0, 0.2, 1)', + }} + > <Header style={{ padding: '0 24px', @@ -146,26 +145,40 @@ const MainLayout: React.FC = () => { display: 'flex', alignItems: 'center', justifyContent: 'space-between', - boxShadow: '0 1px 4px rgba(0,0,0,0.08)', + boxShadow: '0 1px 3px rgba(0,0,0,0.06)', position: 'sticky', top: 0, zIndex: 10, + borderBottom: '1px solid rgba(0,0,0,0.04)', }} > <Button type="text" icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />} onClick={() => setCollapsed(!collapsed)} - style={{ fontSize: 16 }} + style={{ fontSize: 16, color: '#6b7280' }} /> - <Space> + <Space size={12}> <Dropdown menu={{ items: userMenuItems }} placement="bottomRight"> - <Space style={{ cursor: 'pointer' }}> - <Avatar icon={<UserOutlined />} style={{ backgroundColor: themeToken.colorPrimary }} /> - <span>{adminInfo?.name || adminInfo?.username}</span> - <span style={{ color: themeToken.colorTextSecondary, fontSize: 12 }}> - ({getRoleLabel(adminInfo?.role)}) - </span> + <Space style={{ cursor: 'pointer', padding: '4px 8px', borderRadius: 8 }}> + <Avatar + size={34} + icon={<UserOutlined />} + style={{ + background: `linear-gradient(135deg, ${themeToken.colorPrimary}, #8b5cf6)`, + }} + /> + <div style={{ lineHeight: 1.3 }}> + <div style={{ fontSize: 14, fontWeight: 500, color: '#1f2937' }}> + {adminInfo?.name || adminInfo?.username} + </div> + <Tag + color={roleInfo.color} + style={{ fontSize: 11, lineHeight: '18px', margin: 0, padding: '0 6px' }} + > + {roleInfo.label} + </Tag> + </div> </Space> </Dropdown> </Space> @@ -177,6 +190,7 @@ const MainLayout: React.FC = () => { background: themeToken.colorBgContainer, borderRadius: themeToken.borderRadiusLG, minHeight: 280, + boxShadow: '0 1px 2px rgba(0,0,0,0.03)', }} > <Outlet /> diff --git a/src/index.css b/src/index.css index 3e45fdf..ade7021 100644 --- a/src/index.css +++ b/src/index.css @@ -1,41 +1,62 @@ +:root { + --color-primary: #6366f1; + --color-primary-light: #818cf8; + --color-primary-dark: #4f46e5; + --color-bg-base: #f5f5f7; + --color-bg-elevated: #ffffff; + --color-border: #e5e7eb; + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.04); + --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05); + --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04); + --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); + --transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1); + --transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1); +} + * { - margin: 0; - padding: 0; - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } html, body, #root { - height: 100%; - width: 100%; + height: 100%; + width: 100%; } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Inter', 'Helvetica Neue', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background: var(--color-bg-base); } -/* 滚动条样式 */ +/* Scrollbar */ ::-webkit-scrollbar { - width: 8px; - height: 8px; + width: 6px; + height: 6px; } ::-webkit-scrollbar-track { - background: #f1f1f1; - border-radius: 4px; + background: transparent; } ::-webkit-scrollbar-thumb { - background: #c1c1c1; - border-radius: 4px; + background: #d1d5db; + border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { - background: #a1a1a1; + background: #9ca3af; } -/* ProTable 调整 */ -.ant-pro-table-list-toolbar-title { - font-weight: 600; +/* Smooth transitions */ +a, button, .ant-btn, .ant-card, .ant-tag { + transition: all var(--transition-fast); +} + +/* Card hover */ +.ant-card.ant-card-hoverable:hover { + box-shadow: var(--shadow-md); + transform: translateY(-1px); } diff --git a/src/main.tsx b/src/main.tsx index 6f4ac9b..3281537 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,6 +2,22 @@ import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import App from './App.tsx' import './index.css' +import { reportToLogCenter } from './api/request.ts' + +// 全局未捕获错误上报 +window.onerror = (_message, source, lineno, _colno, error) => { + if (error) { + reportToLogCenter(error, { source, lineno }) + } +} + +// 全局未处理 Promise 拒绝上报 +window.onunhandledrejection = (event) => { + const error = event.reason instanceof Error + ? event.reason + : new Error(String(event.reason)) + reportToLogCenter(error, { type: 'unhandledrejection' }) +} createRoot(document.getElementById('root')!).render( <StrictMode> diff --git a/src/pages/Admin/index.tsx b/src/pages/Admin/index.tsx index 4174c55..289058a 100644 --- a/src/pages/Admin/index.tsx +++ b/src/pages/Admin/index.tsx @@ -172,7 +172,7 @@ const AdminPage: React.FC = () => { if (!isSuperAdmin) { return ( - <div style={{ textAlign: 'center', padding: 100, color: '#999' }}> + <div style={{ textAlign: 'center', padding: 100, color: '#9ca3af' }}> 仅超级管理员可访问此页面 </div> ); @@ -185,11 +185,13 @@ const AdminPage: React.FC = () => { rowKey="id" actionRef={actionRef} columns={columns} + cardBordered request={async (params) => { try { const res = await getAdminUsers({ page: params.current, page_size: params.pageSize, + username: params.username, }); return { data: res.data.items, diff --git a/src/pages/Batch/Detail.tsx b/src/pages/Batch/Detail.tsx index 8146c2d..f1afe3d 100644 --- a/src/pages/Batch/Detail.tsx +++ b/src/pages/Batch/Detail.tsx @@ -21,6 +21,7 @@ import { ProTable } from '@ant-design/pro-components'; import type { ProColumns } from '@ant-design/pro-components'; import { getBatch, getBatchDevices, exportBatchExcel } from '../../api/batch'; import type { Device, DeviceBatch } from '../../api/batch'; +import { statColors } from '../../theme/tokens'; const { Title } = Typography; @@ -107,22 +108,34 @@ const BatchDetail: React.FC = () => { } if (!batch) { - return <div>批次不存在</div>; + return <div style={{ textAlign: 'center', padding: 100, color: '#9ca3af' }}>批次不存在</div>; } + const statItems = batch.statistics ? [ + { title: '总数量', value: batch.statistics.total, color: statColors.primary }, + { title: '已导入MAC', value: batch.statistics.with_mac, color: statColors.success }, + { title: '库存中', value: batch.statistics.in_stock, color: statColors.warning }, + { title: '已绑定', value: batch.statistics.bound, color: statColors.info }, + ] : []; + return ( <div> - <Space style={{ marginBottom: 24 }}> - <Button icon={<ArrowLeftOutlined />} onClick={() => navigate('/batches')}> + <Space style={{ marginBottom: 24 }} align="center"> + <Button + icon={<ArrowLeftOutlined />} + onClick={() => navigate('/batches')} + type="text" + style={{ color: '#6b7280' }} + > 返回 </Button> - <Title level={4} style={{ margin: 0 }}> + <Title level={4} style={{ margin: 0, color: '#1f2937' }}> 批次详情 - {batch.batch_no} - - + + {batch.device_type_info?.name} @@ -138,39 +151,19 @@ const BatchDetail: React.FC = () => { - {batch.statistics && ( - - - - - - - - - - - - - - - - - - - - - + {statItems.length > 0 && ( + + {statItems.map((item, index) => ( + + + + + + ))} )} @@ -179,6 +172,7 @@ const BatchDetail: React.FC = () => { rowKey="id" columns={deviceColumns} search={false} + cardBordered request={async (params) => { try { const res = await getBatchDevices(parseInt(id!), { diff --git a/src/pages/Batch/index.tsx b/src/pages/Batch/index.tsx index 10095f3..72e05f9 100644 --- a/src/pages/Batch/index.tsx +++ b/src/pages/Batch/index.tsx @@ -85,13 +85,19 @@ const BatchPage: React.FC = () => { const handleExport = async (batchId: number) => { try { const res = await exportBatchExcel(batchId); - const blob = new Blob([res as unknown as BlobPart], { + // res 是完整的 AxiosResponse,data 已经是 Blob + const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; - link.download = `batch_${batchId}_sn_codes.xlsx`; + // 尝试从 Content-Disposition 获取文件名 + const disposition = res.headers?.['content-disposition']; + const filename = disposition + ? decodeURIComponent(disposition.split('filename=')[1]?.replace(/"/g, '') || `batch_${batchId}.xlsx`) + : `batch_${batchId}_sn_codes.xlsx`; + link.download = filename; link.click(); window.URL.revokeObjectURL(url); message.success('导出成功'); @@ -262,11 +268,13 @@ const BatchPage: React.FC = () => { rowKey="id" actionRef={actionRef} columns={columns} + cardBordered request={async (params) => { try { const res = await getBatches({ page: params.current, page_size: params.pageSize, + batch_no: params.batch_no, }); return { data: res.data.items, diff --git a/src/pages/Dashboard/index.tsx b/src/pages/Dashboard/index.tsx index 475a100..d2033f8 100644 --- a/src/pages/Dashboard/index.tsx +++ b/src/pages/Dashboard/index.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { Row, Col, Card, Statistic, Typography, Spin } from 'antd'; +import { Row, Col, Card, Typography, Spin } from 'antd'; import { UserOutlined, MobileOutlined, @@ -8,7 +8,9 @@ import { CheckCircleOutlined, DatabaseOutlined, } from '@ant-design/icons'; +import { Pie, Column } from '@ant-design/charts'; import request from '../../api/request'; +import { statColors } from '../../theme/tokens'; const { Title } = Typography; @@ -21,7 +23,6 @@ interface DashboardStats { in_stock_device_count: number; } -// 调用真实后端API const getDashboardStats = async (): Promise => { const res = await request.get('/api/admin/dashboard/stats/'); return res.data; @@ -29,7 +30,7 @@ const getDashboardStats = async (): Promise => { const Dashboard: React.FC = () => { const [loading, setLoading] = useState(true); - const [stats, setStats] = useState({ + const [stats, setStats] = useState({ user_count: 0, device_count: 0, device_type_count: 0, @@ -58,99 +59,190 @@ const Dashboard: React.FC = () => { title: '用户总数', value: stats.user_count, icon: , - color: '#1890ff', + color: statColors.primary, + bgColor: 'rgba(99, 102, 241, 0.08)', }, { title: '设备总数', value: stats.device_count, icon: , - color: '#52c41a', + color: statColors.success, + bgColor: 'rgba(16, 185, 129, 0.08)', }, { title: '设备类型', value: stats.device_type_count, icon: , - color: '#722ed1', + color: statColors.purple, + bgColor: 'rgba(139, 92, 246, 0.08)', }, { title: '入库批次', value: stats.batch_count, icon: , - color: '#fa8c16', + color: statColors.warning, + bgColor: 'rgba(245, 158, 11, 0.08)', }, { title: '已绑定设备', value: stats.bound_device_count, icon: , - color: '#13c2c2', + color: statColors.cyan, + bgColor: 'rgba(6, 182, 212, 0.08)', }, { title: '库存设备', value: stats.in_stock_device_count, icon: , - color: '#eb2f96', + color: statColors.pink, + bgColor: 'rgba(236, 72, 153, 0.08)', }, ]; + // 设备状态分布数据 + const otherCount = Math.max(0, stats.device_count - stats.in_stock_device_count - stats.bound_device_count); + const pieData = [ + { type: '库存中', value: stats.in_stock_device_count }, + { type: '已绑定', value: stats.bound_device_count }, + ...(otherCount > 0 ? [{ type: '其他', value: otherCount }] : []), + ]; + + const pieConfig = { + data: pieData, + angleField: 'value', + colorField: 'type', + radius: 0.85, + innerRadius: 0.6, + color: [statColors.primary, statColors.success, statColors.warning], + label: { + text: (d: { type: string; value: number }) => `${d.type}\n${d.value}`, + style: { fontSize: 12, fontWeight: 500 }, + }, + legend: { + color: { + position: 'bottom' as const, + layout: { justifyContent: 'center' as const }, + }, + }, + interaction: { + elementHighlight: true, + }, + }; + + // 数据概览柱状图 + const columnData = [ + { name: '用户', value: stats.user_count, type: '数量' }, + { name: '设备', value: stats.device_count, type: '数量' }, + { name: '已绑定', value: stats.bound_device_count, type: '数量' }, + { name: '库存', value: stats.in_stock_device_count, type: '数量' }, + { name: '批次', value: stats.batch_count, type: '数量' }, + { name: '类型', value: stats.device_type_count, type: '数量' }, + ]; + + const columnConfig = { + data: columnData, + xField: 'name', + yField: 'value', + color: statColors.primary, + style: { + radiusTopLeft: 6, + radiusTopRight: 6, + fill: statColors.primary, + fillOpacity: 0.85, + }, + label: { + text: (d: { value: number }) => `${d.value}`, + textBaseline: 'bottom' as const, + style: { dy: -4, fontSize: 12 }, + }, + axis: { + y: { title: false }, + x: { title: false }, + }, + }; + return (
- + <Title level={4} style={{ marginBottom: 24, color: '#1f2937' }}> 仪表盘 - + {/* Stat Cards */} + {statCards.map((stat, index) => ( - - - {stat.icon} - - } - valueStyle={{ color: stat.color }} - /> + +
+
+ {stat.icon} +
+
+
+ {stat.title} +
+
+ {stat.value.toLocaleString()} +
+
+
))}
-
- - - -
-
📊
-
图表功能开发中...
-
-
- - - -
-
🚀
-
使用左侧菜单进行管理操作
-
-
- -
+ {/* Charts */} + + + +
+ {stats.device_count > 0 ? ( + + ) : ( +
+ 暂无设备数据 +
+ )} +
+
+ + + +
+ +
+
+ +
+
); }; diff --git a/src/pages/Device/index.tsx b/src/pages/Device/index.tsx index 99f206f..7efe7fd 100644 --- a/src/pages/Device/index.tsx +++ b/src/pages/Device/index.tsx @@ -51,6 +51,7 @@ const DevicePage: React.FC = () => { headerTitle="设备列表" rowKey="id" columns={columns} + cardBordered request={async (params) => { try { // 先获取所有批次,再获取设备 diff --git a/src/pages/DeviceType/index.tsx b/src/pages/DeviceType/index.tsx index 9d19131..aff533d 100644 --- a/src/pages/DeviceType/index.tsx +++ b/src/pages/DeviceType/index.tsx @@ -90,7 +90,7 @@ const DeviceTypePage: React.FC = () => { width: 100, search: false, render: (_, record) => ( - + {record.is_network_required ? '联网' : '离线'} ), @@ -135,11 +135,15 @@ const DeviceTypePage: React.FC = () => { headerTitle="设备类型管理" rowKey="id" columns={columns} + cardBordered request={async (params) => { try { const res = await getDeviceTypes({ page: params.current, page_size: params.pageSize, + brand: params.brand, + product_code: params.product_code, + name: params.name, }); return { data: res.data.items, diff --git a/src/pages/Login/index.tsx b/src/pages/Login/index.tsx index 73ec067..948d25d 100644 --- a/src/pages/Login/index.tsx +++ b/src/pages/Login/index.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Form, Input, Button, Card, message, Typography } from 'antd'; +import { Form, Input, Button, message, Typography } from 'antd'; import { UserOutlined, LockOutlined } from '@ant-design/icons'; import { login } from '../../api/auth'; import { useAuthStore } from '../../store/useAuthStore'; -const { Title } = Typography; +const { Title, Text } = Typography; const LoginPage: React.FC = () => { const [loading, setLoading] = useState(false); @@ -33,22 +33,69 @@ const LoginPage: React.FC = () => { display: 'flex', justifyContent: 'center', alignItems: 'center', - background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', + background: 'linear-gradient(135deg, #312e81 0%, #6366f1 50%, #8b5cf6 100%)', + position: 'relative', + overflow: 'hidden', }} > - +
+ +
-
- + <div style={{ textAlign: 'center', marginBottom: 36 }}> + <div + style={{ + width: 56, + height: 56, + borderRadius: 16, + background: 'linear-gradient(135deg, #6366f1, #8b5cf6)', + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + marginBottom: 16, + boxShadow: '0 8px 20px rgba(99, 102, 241, 0.3)', + }} + > + <span style={{ fontSize: 24, fontWeight: 800, color: '#fff' }}>R</span> + </div> + <Title level={3} style={{ marginBottom: 4, color: '#1f2937' }}> RTC 管理后台 - 设备管理 · 库存管理 · 用户管理 + + 设备管理 · 库存管理 · 用户管理 +
{ rules={[{ required: true, message: '请输入用户名' }]} > } + prefix={} placeholder="用户名" + style={{ height: 48, borderRadius: 10 }} /> @@ -72,24 +120,31 @@ const LoginPage: React.FC = () => { rules={[{ required: true, message: '请输入密码' }]} > } + prefix={} placeholder="密码" + style={{ height: 48, borderRadius: 10 }} /> - + - +
); }; diff --git a/src/pages/User/index.tsx b/src/pages/User/index.tsx index d9703ba..c59b527 100644 --- a/src/pages/User/index.tsx +++ b/src/pages/User/index.tsx @@ -1,15 +1,18 @@ -import React from 'react'; +import React, { useRef } from 'react'; import { Button, message, Tag, Space, Popconfirm } from 'antd'; import { ProTable } from '@ant-design/pro-components'; -import type { ProColumns } from '@ant-design/pro-components'; +import type { ProColumns, ActionType } from '@ant-design/pro-components'; import { getAppUsers, toggleAppUserStatus } from '../../api/user'; import type { AppUser } from '../../api/user'; const UserPage: React.FC = () => { + const actionRef = useRef(null); + const handleToggleStatus = async (id: number, currentStatus: boolean) => { try { await toggleAppUserStatus(id); message.success(currentStatus ? '已禁用' : '已启用'); + actionRef.current?.reload(); } catch (error) { message.error(error instanceof Error ? error.message : '操作失败'); } @@ -90,7 +93,9 @@ const UserPage: React.FC = () => { headerTitle="用户管理" rowKey="id" + actionRef={actionRef} columns={columns} + cardBordered request={async (params) => { try { const res = await getAppUsers({ diff --git a/src/styles/protable-theme.css b/src/styles/protable-theme.css new file mode 100644 index 0000000..33684da --- /dev/null +++ b/src/styles/protable-theme.css @@ -0,0 +1,45 @@ +/* ProTable global enhancements */ + +.ant-pro-table-list-toolbar-title { + font-weight: 600; + font-size: 16px; + color: #1f2937; +} + +/* Table header */ +.ant-pro-table .ant-table-thead > tr > th, +.ant-pro-table .ant-table-thead > tr > td { + font-weight: 600; + color: #374151; + font-size: 13px; +} + +/* Row hover */ +.ant-pro-table .ant-table-tbody > tr:hover > td { + background: #f9fafb !important; +} + +/* Link buttons in tables */ +.ant-pro-table .ant-btn-link { + padding: 2px 6px; + height: auto; + font-size: 13px; +} + +/* Search form */ +.ant-pro-table-search { + border-radius: 8px; + margin-bottom: 12px; +} + +/* Pagination */ +.ant-pro-table .ant-pagination { + margin-top: 8px; +} + +/* Tag styles in tables */ +.ant-pro-table .ant-tag { + border-radius: 6px; + font-size: 12px; + padding: 1px 8px; +} diff --git a/src/theme/sidebar.css b/src/theme/sidebar.css new file mode 100644 index 0000000..107449b --- /dev/null +++ b/src/theme/sidebar.css @@ -0,0 +1,72 @@ +/* Modern dark sidebar with gradient */ +.rtc-sidebar { + background: linear-gradient(180deg, #1e1b4b 0%, #312e81 100%) !important; + box-shadow: 2px 0 12px rgba(0, 0, 0, 0.15); +} + +.rtc-sidebar::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: radial-gradient( + ellipse at top left, + rgba(99, 102, 241, 0.12) 0%, + transparent 60% + ); + pointer-events: none; +} + +/* Logo area */ +.rtc-sidebar-logo { + height: 64px; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + color: #e0e7ff; + font-weight: 700; + font-size: 17px; + letter-spacing: 0.3px; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); + position: relative; + z-index: 1; +} + +.rtc-sidebar-logo-icon { + width: 32px; + height: 32px; + background: linear-gradient(135deg, #6366f1, #8b5cf6); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + font-size: 16px; + font-weight: 800; + color: #fff; + flex-shrink: 0; +} + +/* Menu selected item with left accent */ +.rtc-sidebar .ant-menu-item-selected { + position: relative; +} + +.rtc-sidebar .ant-menu-item-selected::before { + content: ''; + position: absolute; + left: 0; + top: 25%; + bottom: 25%; + width: 3px; + background: #818cf8; + border-radius: 0 2px 2px 0; +} + +/* Menu items hover */ +.rtc-sidebar .ant-menu-item { + margin-block: 2px; + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} diff --git a/src/theme/tokens.ts b/src/theme/tokens.ts new file mode 100644 index 0000000..e419a00 --- /dev/null +++ b/src/theme/tokens.ts @@ -0,0 +1,66 @@ +import type { ThemeConfig } from 'antd'; + +export const themeConfig: ThemeConfig = { + token: { + colorPrimary: '#6366f1', + colorSuccess: '#10b981', + colorWarning: '#f59e0b', + colorError: '#ef4444', + colorInfo: '#3b82f6', + colorBgLayout: '#f5f5f7', + borderRadius: 8, + borderRadiusLG: 12, + borderRadiusSM: 6, + fontFamily: + '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", "Helvetica Neue", sans-serif', + }, + components: { + Layout: { + headerBg: '#ffffff', + headerHeight: 64, + headerPadding: '0 24px', + siderBg: '#1e1b4b', + }, + Card: { + borderRadiusLG: 12, + }, + Table: { + headerBg: '#fafafb', + borderRadius: 8, + }, + Button: { + borderRadius: 8, + controlHeight: 36, + }, + Input: { + borderRadius: 8, + }, + Select: { + borderRadius: 8, + }, + Modal: { + borderRadiusLG: 12, + }, + Menu: { + darkItemBg: 'transparent', + darkSubMenuItemBg: 'transparent', + darkItemSelectedBg: 'rgba(99, 102, 241, 0.2)', + darkItemHoverBg: 'rgba(255, 255, 255, 0.06)', + darkItemSelectedColor: '#c7d2fe', + itemBorderRadius: 8, + itemMarginInline: 8, + }, + }, +}; + +// 统计卡片颜色配置 +export const statColors = { + primary: '#6366f1', + success: '#10b981', + warning: '#f59e0b', + error: '#ef4444', + info: '#3b82f6', + purple: '#8b5cf6', + cyan: '#06b6d4', + pink: '#ec4899', +}; diff --git a/vite.config.ts b/vite.config.ts index 250fc67..01c5baa 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,7 +8,7 @@ export default defineConfig({ port: 5174, proxy: { '/api': { - target: 'http://localhost:8001', + target: 'http://192.168.124.24:8000/', changeOrigin: true, secure: false, },