From 37781216b2d320135b53f98aeed2dae086cd17c7 Mon Sep 17 00:00:00 2001 From: yangsy Date: Thu, 11 Dec 2025 13:42:22 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 优化 `车站-设备-告警` 轮询机制 - 改进设备卡片的布局 - 支持修改设备 - 告警轮询中获取完整告警数据 - 车站告警详情支持导出完整的 `今日告警列表` - 支持将状态持久化到 `IndexedDB` - 新增轮询控制 (调试模式) - 新增离线开发模式 (调试模式) - 新增 `IndexedDB` 数据控制 (调试模式) --- .editorconfig | 8 + .env | 25 + .gitattributes | 1 + .gitignore | 37 + .prettierrc.json | 10 + .vscode/extensions.json | 8 + .vscode/settings.json | 13 + README.md | 57 + build/post-build.ts | 16 + build/pre-build.ts | 17 + env.d.ts | 1 + eslint.config.ts | 32 + index.html | 13 + package.json | 62 + pnpm-lock.yaml | 4273 +++++++++++++++++ pnpm-workspace.yaml | 4 + public/favicon.ico | Bin 0 -> 4286 bytes public/manifest.json | 4 + src/App.vue | 34 + src/apis/client/index.ts | 2 + src/apis/client/ndm-client.ts | 32 + src/apis/client/user-client.ts | 33 + src/apis/domain/biz/diag/index.ts | 6 + .../domain/biz/diag/ndm-camera-diag-info.ts | 5 + .../domain/biz/diag/ndm-decoder-diag-info.ts | 14 + src/apis/domain/biz/diag/ndm-nvr-diag-info.ts | 31 + .../biz/diag/ndm-security-box-diag-info.ts | 24 + .../domain/biz/diag/ndm-server-diag-info.ts | 9 + .../domain/biz/diag/ndm-switch-diag-info.ts | 22 + src/apis/domain/biz/index.ts | 2 + src/apis/domain/biz/station/alarm.ts | 35 + src/apis/domain/biz/station/device.ts | 43 + src/apis/domain/biz/station/index.ts | 3 + src/apis/domain/biz/station/station.ts | 6 + src/apis/domain/index.ts | 3 + src/apis/domain/user/index.ts | 2 + src/apis/domain/user/login-params.ts | 8 + src/apis/domain/user/login-result.ts | 8 + src/apis/domain/version/index.ts | 1 + src/apis/domain/version/version-info.ts | 4 + src/apis/index.ts | 4 + src/apis/model/base/index.ts | 3 + src/apis/model/base/model.ts | 18 + src/apis/model/base/page.ts | 43 + src/apis/model/base/reduce.ts | 3 + src/apis/model/biz/entity/alarm/index.ts | 1 + .../model/biz/entity/alarm/ndm-alarm-host.ts | 39 + .../biz/entity/icmp/icmp-entity-result.ts | 11 + .../entity/icmp/icmp-entity-with-station.ts | 9 + src/apis/model/biz/entity/icmp/icmp-entity.ts | 8 + src/apis/model/biz/entity/icmp/index.ts | 3 + src/apis/model/biz/entity/index.ts | 37 + src/apis/model/biz/entity/log/index.ts | 6 + src/apis/model/biz/entity/log/ndm-call-log.ts | 18 + .../biz/entity/log/ndm-device-alarm-log.ts | 28 + src/apis/model/biz/entity/log/ndm-icmp-log.ts | 17 + .../model/biz/entity/log/ndm-record-check.ts | 8 + src/apis/model/biz/entity/log/ndm-snmp-log.ts | 18 + src/apis/model/biz/entity/log/ndm-vimp-log.ts | 26 + src/apis/model/biz/entity/other/index.ts | 2 + .../biz/entity/other/ndm-security-box.ts | 35 + src/apis/model/biz/entity/other/ndm-switch.ts | 35 + src/apis/model/biz/entity/storage/index.ts | 1 + src/apis/model/biz/entity/storage/ndm-nvr.ts | 46 + src/apis/model/biz/entity/upper-ndm/index.ts | 2 + .../upper-ndm/sync-camera-result-detail.ts | 6 + .../entity/upper-ndm/sync-camera-result.ts | 10 + src/apis/model/biz/entity/video/index.ts | 6 + .../biz/entity/video/ndm-camera-ignore.ts | 14 + src/apis/model/biz/entity/video/ndm-camera.ts | 45 + .../model/biz/entity/video/ndm-decoder.ts | 42 + .../model/biz/entity/video/ndm-keyboard.ts | 35 + .../biz/entity/video/ndm-media-server.ts | 39 + .../biz/entity/video/ndm-video-server.ts | 39 + src/apis/model/biz/index.ts | 4 + src/apis/model/biz/nvr/client-channel.ts | 15 + src/apis/model/biz/nvr/index.ts | 3 + src/apis/model/biz/nvr/record-info.ts | 12 + src/apis/model/biz/nvr/record-item.ts | 4 + src/apis/model/biz/verify/index.ts | 1 + src/apis/model/biz/verify/verify-server.ts | 7 + src/apis/model/biz/vimp/index.ts | 1 + src/apis/model/biz/vimp/snap-result.ts | 5 + src/apis/model/index.ts | 3 + src/apis/model/system/def-parameter.ts | 18 + src/apis/model/system/index.ts | 1 + src/apis/request/biz/alarm/index.ts | 0 src/apis/request/biz/alarm/ndm-alarm-host.ts | 71 + src/apis/request/biz/all/index.ts | 1 + src/apis/request/biz/all/ndm-devices.ts | 13 + .../request/biz/composed/detail-device.ts | 59 + src/apis/request/biz/composed/index.ts | 2 + src/apis/request/biz/composed/probe-device.ts | 33 + src/apis/request/biz/constant/index.ts | 1 + .../biz/constant/reset-monitor-shedule.ts | 11 + src/apis/request/biz/icmp/batch-verify.ts | 11 + src/apis/request/biz/icmp/index.ts | 3 + src/apis/request/biz/icmp/ndm-icmp-export.ts | 55 + src/apis/request/biz/icmp/verify.ts | 11 + src/apis/request/biz/index.ts | 9 + src/apis/request/biz/log/index.ts | 6 + src/apis/request/biz/log/ndm-call-log.ts | 25 + .../request/biz/log/ndm-device-alarm-log.ts | 37 + src/apis/request/biz/log/ndm-icmp-log.ts | 13 + src/apis/request/biz/log/ndm-record-check.ts | 55 + src/apis/request/biz/log/ndm-snmp-log.ts | 13 + src/apis/request/biz/log/ndm-vimp-log.ts | 25 + src/apis/request/biz/other/index.ts | 2 + .../request/biz/other/ndm-security-box.ts | 105 + src/apis/request/biz/other/ndm-switch.ts | 71 + src/apis/request/biz/storage/index.ts | 1 + src/apis/request/biz/storage/ndm-nvr.ts | 81 + src/apis/request/biz/video/index.ts | 6 + .../request/biz/video/ndm-camera-ignore.ts | 61 + src/apis/request/biz/video/ndm-camera.ts | 94 + src/apis/request/biz/video/ndm-decoder.ts | 71 + src/apis/request/biz/video/ndm-keyboard.ts | 61 + .../request/biz/video/ndm-media-server.ts | 81 + .../request/biz/video/ndm-video-server.ts | 81 + src/apis/request/index.ts | 2 + src/apis/request/system/def-parameter.ts | 26 + src/apis/request/system/index.ts | 1 + .../current-diag/device-common-card.vue | 29 + .../current-diag/device-hardware-card.vue | 77 + .../current-diag/device-header-card.vue | 156 + .../components/current-diag/index.ts | 10 + .../components/current-diag/nvr-disk-card.vue | 168 + .../current-diag/nvr-record-card.vue | 246 + .../security-box-circuit-card.vue | 170 + .../current-diag/security-box-env-card.vue | 98 + .../current-diag/switch-port-card.vue | 146 + .../device-alarm-history-card.vue | 152 + .../history-diag/device-icmp-history-card.vue | 183 + .../device-usage-history-card.vue | 153 + .../history-diag/history-diag-filter-card.vue | 42 + .../components/history-diag/index.ts | 27 + .../history-diag/nvr-disk-history-card.vue | 155 + .../security-box-runtime-history-card.vue | 230 + .../history-diag/switch-port-history-card.vue | 206 + .../device/device-card/components/index.ts | 3 + .../components/raw-diag/device-raw-card.vue | 26 + .../device-card/components/raw-diag/index.ts | 3 + src/components/device/device-card/index.ts | 9 + .../ndm-alarm-host/alarm-host-card.vue | 71 + .../alarm-host-current-diag.vue | 31 + .../alarm-host-history-diag.vue | 76 + .../ndm-alarm-host/alarm-host-update.vue | 152 + .../device-card/ndm-alarm-host/index.ts | 6 + .../device-card/ndm-camera/camera-card.vue | 71 + .../ndm-camera/camera-current-diag.vue | 52 + .../ndm-camera/camera-history-diag.vue | 76 + .../device-card/ndm-camera/camera-update.vue | 133 + .../device/device-card/ndm-camera/index.ts | 6 + .../device-card/ndm-decoder/decoder-card.vue | 71 + .../ndm-decoder/decoder-current-diag.vue | 47 + .../ndm-decoder/decoder-history-diag.vue | 100 + .../ndm-decoder/decoder-update.vue | 154 + .../device/device-card/ndm-decoder/index.ts | 6 + .../device/device-card/ndm-keyboard/index.ts | 6 + .../ndm-keyboard/keyboard-card.vue | 71 + .../ndm-keyboard/keyboard-current-diag.vue | 21 + .../ndm-keyboard/keyboard-history-diag.vue | 76 + .../ndm-keyboard/keyboard-update.vue | 142 + .../device/device-card/ndm-nvr/index.ts | 6 + .../device/device-card/ndm-nvr/nvr-card.vue | 71 + .../device-card/ndm-nvr/nvr-current-diag.vue | 54 + .../device-card/ndm-nvr/nvr-history-diag.vue | 113 + .../device/device-card/ndm-nvr/nvr-update.vue | 154 + .../device-card/ndm-security-box/index.ts | 6 + .../ndm-security-box/security-box-card.vue | 71 + .../security-box-current-diag.vue | 56 + .../security-box-history-diag.vue | 118 + .../ndm-security-box/security-box-update.vue | 145 + .../device/device-card/ndm-server/index.ts | 6 + .../device-card/ndm-server/server-card.vue | 71 + .../ndm-server/server-current-diag.vue | 35 + .../ndm-server/server-history-diag.vue | 102 + .../device-card/ndm-server/server-update.vue | 164 + .../device/device-card/ndm-switch/index.ts | 6 + .../device-card/ndm-switch/switch-card.vue | 71 + .../ndm-switch/switch-current-diag.vue | 36 + .../ndm-switch/switch-history-diag.vue | 118 + .../device-card/ndm-switch/switch-update.vue | 154 + .../device-renderer/device-renderer.vue | 72 + .../device/device-renderer/index.ts | 3 + .../device/device-tree/device-tree.export.vue | 475 ++ .../device/device-tree/device-tree.vue | 420 ++ src/components/device/device-tree/index.ts | 6 + src/components/device/index.ts | 3 + .../global-feedback/global-feedback.vue | 12 + .../global/global-feedback/index.ts | 3 + src/components/global/index.ts | 3 + .../global/settings-drawer/index.ts | 3 + .../settings-drawer/settings-drawer.vue | 277 ++ src/components/global/theme-switch/index.ts | 3 + .../global/theme-switch/theme-switch.vue | 71 + src/components/index.ts | 3 + .../alarm-detail-modal/alarm-detail-modal.vue | 144 + .../station/alarm-detail-modal/index.ts | 3 + .../device-detail-modal.vue | 24 + .../station/device-detail-modal/index.ts | 3 + .../device-param-config.modal.vue | 258 + .../device-param-config-modal/index.ts | 3 + .../icmp-export-modal/icmp-export-modal.vue | 127 + .../station/icmp-export-modal/index.ts | 3 + src/components/station/index.ts | 7 + .../record-check-export-modal/index.ts | 3 + .../record-check-export-modal.vue | 98 + src/components/station/station-card/index.ts | 6 + .../station/station-card/station-card.vue | 164 + .../station/sync-camera-result-modal/index.ts | 3 + .../sync-camera-result-modal.vue | 88 + src/composables/alarm/index.ts | 2 + .../alarm/use-alarm-action-column.ts | 149 + .../alarm/use-camera-snap-column.ts | 66 + src/composables/device/index.ts | 1 + src/composables/device/use-device-tree.ts | 89 + src/composables/index.ts | 4 + src/composables/query/index.ts | 4 + .../query/use-line-alarms-query.ts | 88 + .../query/use-line-devices-query.ts | 55 + .../query/use-line-stations-query.ts | 73 + .../query/use-version-check-query.ts | 75 + src/composables/stomp/index.ts | 1 + src/composables/stomp/use-stomp-client.ts | 123 + src/constants/index.ts | 5 + src/constants/java.ts | 2 + src/constants/mutation.ts | 3 + src/constants/query.ts | 4 + src/constants/stomp.ts | 3 + src/constants/store.ts | 6 + src/enums/alarm-type.ts | 6 + src/enums/device-type.ts | 47 + src/enums/fault-level.ts | 7 + src/enums/index.ts | 3 + src/global.d.ts | 12 + src/helpers/device-alarm.ts | 89 + src/helpers/export-record-diag-csv.ts | 26 + src/helpers/index.ts | 5 + src/helpers/nvr-cluster.ts | 8 + src/helpers/record-check.ts | 69 + src/helpers/switch-port.ts | 26 + src/layouts/app-layout.vue | 229 + src/main.ts | 31 + src/pages/alarm-page.vue | 305 ++ src/pages/call-log-page.vue | 258 + src/pages/device-page.vue | 34 + src/pages/login-page.vue | 104 + src/pages/not-found-page.vue | 20 + src/pages/station-page.vue | 225 + src/pages/vimp-log-page.vue | 297 ++ src/plugins/index.ts | 1 + src/plugins/pinia/index.ts | 8 + src/plugins/pinia/persist-to-indexeddb.ts | 31 + src/router/index.ts | 75 + src/stores/alarm.ts | 62 + src/stores/device.ts | 46 + src/stores/index.ts | 6 + src/stores/polling.ts | 35 + src/stores/setting.ts | 81 + src/stores/station.ts | 28 + src/stores/user.ts | 142 + src/styles/reset.scss | 68 + src/types/axios.ts | 10 + src/types/index.ts | 2 + src/types/util-type.ts | 3 + src/utils/cipher.ts | 58 + src/utils/download.ts | 17 + src/utils/env.ts | 26 + src/utils/format-duration.ts | 23 + src/utils/index.ts | 7 + src/utils/random-num.ts | 29 + src/utils/request-client.ts | 136 + src/utils/sleep.ts | 3 + tsconfig.app.json | 23 + tsconfig.json | 11 + tsconfig.node.json | 21 + vite.config.ts | 143 + 278 files changed, 17988 insertions(+) create mode 100644 .editorconfig create mode 100644 .env create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .prettierrc.json create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 build/post-build.ts create mode 100644 build/pre-build.ts create mode 100644 env.d.ts create mode 100644 eslint.config.ts create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 public/favicon.ico create mode 100644 public/manifest.json create mode 100644 src/App.vue create mode 100644 src/apis/client/index.ts create mode 100644 src/apis/client/ndm-client.ts create mode 100644 src/apis/client/user-client.ts create mode 100644 src/apis/domain/biz/diag/index.ts create mode 100644 src/apis/domain/biz/diag/ndm-camera-diag-info.ts create mode 100644 src/apis/domain/biz/diag/ndm-decoder-diag-info.ts create mode 100644 src/apis/domain/biz/diag/ndm-nvr-diag-info.ts create mode 100644 src/apis/domain/biz/diag/ndm-security-box-diag-info.ts create mode 100644 src/apis/domain/biz/diag/ndm-server-diag-info.ts create mode 100644 src/apis/domain/biz/diag/ndm-switch-diag-info.ts create mode 100644 src/apis/domain/biz/index.ts create mode 100644 src/apis/domain/biz/station/alarm.ts create mode 100644 src/apis/domain/biz/station/device.ts create mode 100644 src/apis/domain/biz/station/index.ts create mode 100644 src/apis/domain/biz/station/station.ts create mode 100644 src/apis/domain/index.ts create mode 100644 src/apis/domain/user/index.ts create mode 100644 src/apis/domain/user/login-params.ts create mode 100644 src/apis/domain/user/login-result.ts create mode 100644 src/apis/domain/version/index.ts create mode 100644 src/apis/domain/version/version-info.ts create mode 100644 src/apis/index.ts create mode 100644 src/apis/model/base/index.ts create mode 100644 src/apis/model/base/model.ts create mode 100644 src/apis/model/base/page.ts create mode 100644 src/apis/model/base/reduce.ts create mode 100644 src/apis/model/biz/entity/alarm/index.ts create mode 100644 src/apis/model/biz/entity/alarm/ndm-alarm-host.ts create mode 100644 src/apis/model/biz/entity/icmp/icmp-entity-result.ts create mode 100644 src/apis/model/biz/entity/icmp/icmp-entity-with-station.ts create mode 100644 src/apis/model/biz/entity/icmp/icmp-entity.ts create mode 100644 src/apis/model/biz/entity/icmp/index.ts create mode 100644 src/apis/model/biz/entity/index.ts create mode 100644 src/apis/model/biz/entity/log/index.ts create mode 100644 src/apis/model/biz/entity/log/ndm-call-log.ts create mode 100644 src/apis/model/biz/entity/log/ndm-device-alarm-log.ts create mode 100644 src/apis/model/biz/entity/log/ndm-icmp-log.ts create mode 100644 src/apis/model/biz/entity/log/ndm-record-check.ts create mode 100644 src/apis/model/biz/entity/log/ndm-snmp-log.ts create mode 100644 src/apis/model/biz/entity/log/ndm-vimp-log.ts create mode 100644 src/apis/model/biz/entity/other/index.ts create mode 100644 src/apis/model/biz/entity/other/ndm-security-box.ts create mode 100644 src/apis/model/biz/entity/other/ndm-switch.ts create mode 100644 src/apis/model/biz/entity/storage/index.ts create mode 100644 src/apis/model/biz/entity/storage/ndm-nvr.ts create mode 100644 src/apis/model/biz/entity/upper-ndm/index.ts create mode 100644 src/apis/model/biz/entity/upper-ndm/sync-camera-result-detail.ts create mode 100644 src/apis/model/biz/entity/upper-ndm/sync-camera-result.ts create mode 100644 src/apis/model/biz/entity/video/index.ts create mode 100644 src/apis/model/biz/entity/video/ndm-camera-ignore.ts create mode 100644 src/apis/model/biz/entity/video/ndm-camera.ts create mode 100644 src/apis/model/biz/entity/video/ndm-decoder.ts create mode 100644 src/apis/model/biz/entity/video/ndm-keyboard.ts create mode 100644 src/apis/model/biz/entity/video/ndm-media-server.ts create mode 100644 src/apis/model/biz/entity/video/ndm-video-server.ts create mode 100644 src/apis/model/biz/index.ts create mode 100644 src/apis/model/biz/nvr/client-channel.ts create mode 100644 src/apis/model/biz/nvr/index.ts create mode 100644 src/apis/model/biz/nvr/record-info.ts create mode 100644 src/apis/model/biz/nvr/record-item.ts create mode 100644 src/apis/model/biz/verify/index.ts create mode 100644 src/apis/model/biz/verify/verify-server.ts create mode 100644 src/apis/model/biz/vimp/index.ts create mode 100644 src/apis/model/biz/vimp/snap-result.ts create mode 100644 src/apis/model/index.ts create mode 100644 src/apis/model/system/def-parameter.ts create mode 100644 src/apis/model/system/index.ts create mode 100644 src/apis/request/biz/alarm/index.ts create mode 100644 src/apis/request/biz/alarm/ndm-alarm-host.ts create mode 100644 src/apis/request/biz/all/index.ts create mode 100644 src/apis/request/biz/all/ndm-devices.ts create mode 100644 src/apis/request/biz/composed/detail-device.ts create mode 100644 src/apis/request/biz/composed/index.ts create mode 100644 src/apis/request/biz/composed/probe-device.ts create mode 100644 src/apis/request/biz/constant/index.ts create mode 100644 src/apis/request/biz/constant/reset-monitor-shedule.ts create mode 100644 src/apis/request/biz/icmp/batch-verify.ts create mode 100644 src/apis/request/biz/icmp/index.ts create mode 100644 src/apis/request/biz/icmp/ndm-icmp-export.ts create mode 100644 src/apis/request/biz/icmp/verify.ts create mode 100644 src/apis/request/biz/index.ts create mode 100644 src/apis/request/biz/log/index.ts create mode 100644 src/apis/request/biz/log/ndm-call-log.ts create mode 100644 src/apis/request/biz/log/ndm-device-alarm-log.ts create mode 100644 src/apis/request/biz/log/ndm-icmp-log.ts create mode 100644 src/apis/request/biz/log/ndm-record-check.ts create mode 100644 src/apis/request/biz/log/ndm-snmp-log.ts create mode 100644 src/apis/request/biz/log/ndm-vimp-log.ts create mode 100644 src/apis/request/biz/other/index.ts create mode 100644 src/apis/request/biz/other/ndm-security-box.ts create mode 100644 src/apis/request/biz/other/ndm-switch.ts create mode 100644 src/apis/request/biz/storage/index.ts create mode 100644 src/apis/request/biz/storage/ndm-nvr.ts create mode 100644 src/apis/request/biz/video/index.ts create mode 100644 src/apis/request/biz/video/ndm-camera-ignore.ts create mode 100644 src/apis/request/biz/video/ndm-camera.ts create mode 100644 src/apis/request/biz/video/ndm-decoder.ts create mode 100644 src/apis/request/biz/video/ndm-keyboard.ts create mode 100644 src/apis/request/biz/video/ndm-media-server.ts create mode 100644 src/apis/request/biz/video/ndm-video-server.ts create mode 100644 src/apis/request/index.ts create mode 100644 src/apis/request/system/def-parameter.ts create mode 100644 src/apis/request/system/index.ts create mode 100644 src/components/device/device-card/components/current-diag/device-common-card.vue create mode 100644 src/components/device/device-card/components/current-diag/device-hardware-card.vue create mode 100644 src/components/device/device-card/components/current-diag/device-header-card.vue create mode 100644 src/components/device/device-card/components/current-diag/index.ts create mode 100644 src/components/device/device-card/components/current-diag/nvr-disk-card.vue create mode 100644 src/components/device/device-card/components/current-diag/nvr-record-card.vue create mode 100644 src/components/device/device-card/components/current-diag/security-box-circuit-card.vue create mode 100644 src/components/device/device-card/components/current-diag/security-box-env-card.vue create mode 100644 src/components/device/device-card/components/current-diag/switch-port-card.vue create mode 100644 src/components/device/device-card/components/history-diag/device-alarm-history-card.vue create mode 100644 src/components/device/device-card/components/history-diag/device-icmp-history-card.vue create mode 100644 src/components/device/device-card/components/history-diag/device-usage-history-card.vue create mode 100644 src/components/device/device-card/components/history-diag/history-diag-filter-card.vue create mode 100644 src/components/device/device-card/components/history-diag/index.ts create mode 100644 src/components/device/device-card/components/history-diag/nvr-disk-history-card.vue create mode 100644 src/components/device/device-card/components/history-diag/security-box-runtime-history-card.vue create mode 100644 src/components/device/device-card/components/history-diag/switch-port-history-card.vue create mode 100644 src/components/device/device-card/components/index.ts create mode 100644 src/components/device/device-card/components/raw-diag/device-raw-card.vue create mode 100644 src/components/device/device-card/components/raw-diag/index.ts create mode 100644 src/components/device/device-card/index.ts create mode 100644 src/components/device/device-card/ndm-alarm-host/alarm-host-card.vue create mode 100644 src/components/device/device-card/ndm-alarm-host/alarm-host-current-diag.vue create mode 100644 src/components/device/device-card/ndm-alarm-host/alarm-host-history-diag.vue create mode 100644 src/components/device/device-card/ndm-alarm-host/alarm-host-update.vue create mode 100644 src/components/device/device-card/ndm-alarm-host/index.ts create mode 100644 src/components/device/device-card/ndm-camera/camera-card.vue create mode 100644 src/components/device/device-card/ndm-camera/camera-current-diag.vue create mode 100644 src/components/device/device-card/ndm-camera/camera-history-diag.vue create mode 100644 src/components/device/device-card/ndm-camera/camera-update.vue create mode 100644 src/components/device/device-card/ndm-camera/index.ts create mode 100644 src/components/device/device-card/ndm-decoder/decoder-card.vue create mode 100644 src/components/device/device-card/ndm-decoder/decoder-current-diag.vue create mode 100644 src/components/device/device-card/ndm-decoder/decoder-history-diag.vue create mode 100644 src/components/device/device-card/ndm-decoder/decoder-update.vue create mode 100644 src/components/device/device-card/ndm-decoder/index.ts create mode 100644 src/components/device/device-card/ndm-keyboard/index.ts create mode 100644 src/components/device/device-card/ndm-keyboard/keyboard-card.vue create mode 100644 src/components/device/device-card/ndm-keyboard/keyboard-current-diag.vue create mode 100644 src/components/device/device-card/ndm-keyboard/keyboard-history-diag.vue create mode 100644 src/components/device/device-card/ndm-keyboard/keyboard-update.vue create mode 100644 src/components/device/device-card/ndm-nvr/index.ts create mode 100644 src/components/device/device-card/ndm-nvr/nvr-card.vue create mode 100644 src/components/device/device-card/ndm-nvr/nvr-current-diag.vue create mode 100644 src/components/device/device-card/ndm-nvr/nvr-history-diag.vue create mode 100644 src/components/device/device-card/ndm-nvr/nvr-update.vue create mode 100644 src/components/device/device-card/ndm-security-box/index.ts create mode 100644 src/components/device/device-card/ndm-security-box/security-box-card.vue create mode 100644 src/components/device/device-card/ndm-security-box/security-box-current-diag.vue create mode 100644 src/components/device/device-card/ndm-security-box/security-box-history-diag.vue create mode 100644 src/components/device/device-card/ndm-security-box/security-box-update.vue create mode 100644 src/components/device/device-card/ndm-server/index.ts create mode 100644 src/components/device/device-card/ndm-server/server-card.vue create mode 100644 src/components/device/device-card/ndm-server/server-current-diag.vue create mode 100644 src/components/device/device-card/ndm-server/server-history-diag.vue create mode 100644 src/components/device/device-card/ndm-server/server-update.vue create mode 100644 src/components/device/device-card/ndm-switch/index.ts create mode 100644 src/components/device/device-card/ndm-switch/switch-card.vue create mode 100644 src/components/device/device-card/ndm-switch/switch-current-diag.vue create mode 100644 src/components/device/device-card/ndm-switch/switch-history-diag.vue create mode 100644 src/components/device/device-card/ndm-switch/switch-update.vue create mode 100644 src/components/device/device-renderer/device-renderer.vue create mode 100644 src/components/device/device-renderer/index.ts create mode 100644 src/components/device/device-tree/device-tree.export.vue create mode 100644 src/components/device/device-tree/device-tree.vue create mode 100644 src/components/device/device-tree/index.ts create mode 100644 src/components/device/index.ts create mode 100644 src/components/global/global-feedback/global-feedback.vue create mode 100644 src/components/global/global-feedback/index.ts create mode 100644 src/components/global/index.ts create mode 100644 src/components/global/settings-drawer/index.ts create mode 100644 src/components/global/settings-drawer/settings-drawer.vue create mode 100644 src/components/global/theme-switch/index.ts create mode 100644 src/components/global/theme-switch/theme-switch.vue create mode 100644 src/components/index.ts create mode 100644 src/components/station/alarm-detail-modal/alarm-detail-modal.vue create mode 100644 src/components/station/alarm-detail-modal/index.ts create mode 100644 src/components/station/device-detail-modal/device-detail-modal.vue create mode 100644 src/components/station/device-detail-modal/index.ts create mode 100644 src/components/station/device-param-config-modal/device-param-config.modal.vue create mode 100644 src/components/station/device-param-config-modal/index.ts create mode 100644 src/components/station/icmp-export-modal/icmp-export-modal.vue create mode 100644 src/components/station/icmp-export-modal/index.ts create mode 100644 src/components/station/index.ts create mode 100644 src/components/station/record-check-export-modal/index.ts create mode 100644 src/components/station/record-check-export-modal/record-check-export-modal.vue create mode 100644 src/components/station/station-card/index.ts create mode 100644 src/components/station/station-card/station-card.vue create mode 100644 src/components/station/sync-camera-result-modal/index.ts create mode 100644 src/components/station/sync-camera-result-modal/sync-camera-result-modal.vue create mode 100644 src/composables/alarm/index.ts create mode 100644 src/composables/alarm/use-alarm-action-column.ts create mode 100644 src/composables/alarm/use-camera-snap-column.ts create mode 100644 src/composables/device/index.ts create mode 100644 src/composables/device/use-device-tree.ts create mode 100644 src/composables/index.ts create mode 100644 src/composables/query/index.ts create mode 100644 src/composables/query/use-line-alarms-query.ts create mode 100644 src/composables/query/use-line-devices-query.ts create mode 100644 src/composables/query/use-line-stations-query.ts create mode 100644 src/composables/query/use-version-check-query.ts create mode 100644 src/composables/stomp/index.ts create mode 100644 src/composables/stomp/use-stomp-client.ts create mode 100644 src/constants/index.ts create mode 100644 src/constants/java.ts create mode 100644 src/constants/mutation.ts create mode 100644 src/constants/query.ts create mode 100644 src/constants/stomp.ts create mode 100644 src/constants/store.ts create mode 100644 src/enums/alarm-type.ts create mode 100644 src/enums/device-type.ts create mode 100644 src/enums/fault-level.ts create mode 100644 src/enums/index.ts create mode 100644 src/global.d.ts create mode 100644 src/helpers/device-alarm.ts create mode 100644 src/helpers/export-record-diag-csv.ts create mode 100644 src/helpers/index.ts create mode 100644 src/helpers/nvr-cluster.ts create mode 100644 src/helpers/record-check.ts create mode 100644 src/helpers/switch-port.ts create mode 100644 src/layouts/app-layout.vue create mode 100644 src/main.ts create mode 100644 src/pages/alarm-page.vue create mode 100644 src/pages/call-log-page.vue create mode 100644 src/pages/device-page.vue create mode 100644 src/pages/login-page.vue create mode 100644 src/pages/not-found-page.vue create mode 100644 src/pages/station-page.vue create mode 100644 src/pages/vimp-log-page.vue create mode 100644 src/plugins/index.ts create mode 100644 src/plugins/pinia/index.ts create mode 100644 src/plugins/pinia/persist-to-indexeddb.ts create mode 100644 src/router/index.ts create mode 100644 src/stores/alarm.ts create mode 100644 src/stores/device.ts create mode 100644 src/stores/index.ts create mode 100644 src/stores/polling.ts create mode 100644 src/stores/setting.ts create mode 100644 src/stores/station.ts create mode 100644 src/stores/user.ts create mode 100644 src/styles/reset.scss create mode 100644 src/types/axios.ts create mode 100644 src/types/index.ts create mode 100644 src/types/util-type.ts create mode 100644 src/utils/cipher.ts create mode 100644 src/utils/download.ts create mode 100644 src/utils/env.ts create mode 100644 src/utils/format-duration.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/random-num.ts create mode 100644 src/utils/request-client.ts create mode 100644 src/utils/sleep.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3b510aa --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}] +charset = utf-8 +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +max_line_length = 100 diff --git a/.env b/.env new file mode 100644 index 0000000..f1bc0d4 --- /dev/null +++ b/.env @@ -0,0 +1,25 @@ +# APP名称 +VITE_APP_TITLE = 网络设备管理平台 + +# 轮询间隔 +VITE_REQUEST_INTERVAL = 120 + +# 网管的appKey +VITE_NDM_APP_KEY = ndm + +# clientId 和 clientSecret 用于生成 Authorization +VITE_LAMP_CLIENT_ID = cuedes_admin +VITE_LAMP_CLIENT_SECRET = cuedes_admin_secret + +# 用于登录 LAMP 系统的用户名和密码 +VITE_LAMP_USERNAME = lamp +VITE_LAMP_PASSWORD = fjoc(1KHP(Ls&Bje)C + +# 如果 Authorization 已存在则会直接采用, 否则会根据 clientId 和 clientSecret 生成 +VITE_LAMP_AUTHORIZATION = Y3VlZGVzX2FkbWluOmN1ZWRlc19hZG1pbl9zZWNyZXQ= + +# 当需要重置localStorage时, 修改此变量 +VITE_STORAGE_VERSION = 3 + +# 调试码 +VITE_DEBUG_CODE = ndm_debug diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0392c28 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo + +.eslintcache + +# Cypress +/cypress/videos/ +/cypress/screenshots/ + +# Vitest +__screenshots__/ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..e34de79 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "endOfLine": "lf", + "printWidth": 200, + "semi": true, + "singleAttributePerLine": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "all" +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..c92168f --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "Vue.volar", + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "esbenp.prettier-vscode" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b69a0a4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll": "explicit" + }, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[vue]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..be8511e --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# 网络设备管理平台 + +从 `ndm-web-client` 项目重构而来,包含升级依赖库、目录结构调整、轮询机制优化、enum重构、持久化方案改进等大型变更,因此重新命名为 `ndm-web-platform`。 + +## 安装依赖 + +```bash +pnpm install +``` + +### `vite` 代理配置 + +在 `vite.config.ts` 中,已经配置了4号线和10号线的代理,并启用了10号线的 `/api` 和 `/minio` 请求代理。 + +需要注意 `ProxyItem` 类型中的 `rewrite` 字段,它用于配置请求路径的重写规则。 + +例如有这样一个 `ProxyItem` 配置: + +```typescript +{ key: '/1001/api', target: 'http://10.18.129.10:18760', rewrite: ['/1001/api', '/api'] } +``` + +此时如果我们发送一个请求到路径为 `/1001/api/ndm/ndmCamera/page` 的接口,则会命中 `vite` 的代理配置,将请求代理到 `http://10.18.129.10:18760` 上。 + +而 `vite` 的默认行为会将 `target` 和 `key` 拼接起来,即完整的请求路径是 `http://10.18.129.10:18760/1001/api/ndm/ndmCamera/page`,但是我们配置了 `rewrite` 规则,那么 `vite` 会将请求路径中的 `/1001/api` 替换为 `/api`,即最终的请求路径是 `http://10.18.129.10:18760/api/ndm/ndmCamera/page`。 + +因此,在克隆该项目后,需要根据实际情况修改 `vite.config.ts` 中的代理配置,并将 `target` 和 `key` 替换为实际的目标地址和路径前缀。 + +## 启动项目 + +```bash +pnpm dev +``` + +## 构建项目 + +```bash +pnpm build +``` + +在执行 `pnpm build` 之前,你可以在 `package.json` 中修改 `version` 字段,将其设置为你期望的版本号,构建完成后,项目的根目录中除了 `dist` 目录外,还会生成三个压缩包,文件名的格式统一为 `ndm-web-platform_v_`,文件格式则分别为 `zip`、`tar`、`tar.gz`。 + +## 调试模式 + +在调试模式中,用户可以查看设备的原始诊断数据,也可以对轮询器进行控制,或者启用离线开发模式,系统不会自动调用一些主动触发的请求。 + +### 开启调试模式 + +在非登录页的任意页面中,使用键盘组合键 `Ctrl+Alt+D`,系统会弹出一个输入框,输入环境变量 `.env` 中的 `VITE_DEBUG_CODE` 对应的值即可开启调试模式,如需关闭调试模式,再次使用上述组合键并点击 `确认` 按钮即可。 + +注意调试模式与其内部的功能之间没有联动关系,例如在开启调试模式后可以关闭轮询或者启用离线开发模式,但是在关闭调试模式后,轮询不会重新被开启,离线开发模式也不会被关闭,因此在关闭离线开发模式前,请务必确保系统处于正确的运行状态下。 + +### 关于离线开发模式 + +由于离线开发模式涉及到登录操作,因此项目中将离线开发模式暴露到了全局变量 `window.$offlineDev` 中,允许在登录页中直接开启离线开发模式。 + +如果你第一次启动这个项目,系统在正常情况下会先跳转至登录页,此时如果希望开启离线模式,可以直接打开浏览器的开发者工具,在控制台输入 `window.$offlineDev.value = true` 即可,系统会直接跳转到首页。 diff --git a/build/post-build.ts b/build/post-build.ts new file mode 100644 index 0000000..9dd7ae2 --- /dev/null +++ b/build/post-build.ts @@ -0,0 +1,16 @@ +import { tgz, zip } from 'compressing'; +import dayjs from 'dayjs'; + +import packageJson from '../package.json'; + +const now = dayjs(); + +const fileName = `${packageJson.name}_v${packageJson.version}_${now.format('YYMMDD-HHmmss')}`; + +try { + await zip.compressDir('./dist', `${fileName}.zip`); + await tgz.compressDir('./dist', `${fileName}.tar`); + await tgz.compressDir('./dist', `${fileName}.tar.gz`); +} catch (error) { + console.error('压缩失败:', error); +} diff --git a/build/pre-build.ts b/build/pre-build.ts new file mode 100644 index 0000000..bef9507 --- /dev/null +++ b/build/pre-build.ts @@ -0,0 +1,17 @@ +import { writeFile } from 'fs/promises'; +import dayjs from 'dayjs'; + +import packageJson from '../package.json'; + +const now = dayjs(); + +const versionInfo = { + version: packageJson.version, + buildTime: now.format('YYYY-MM-DD HH:mm:ss'), +}; + +try { + await writeFile('./public/manifest.json', JSON.stringify(versionInfo, null, 2)); +} catch (error) { + console.error('写入manifest失败:', error); +} diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 0000000..67095f9 --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,32 @@ +import { globalIgnores } from 'eslint/config'; +import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'; +import pluginVue from 'eslint-plugin-vue'; +import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'; + +// To allow more languages other than `ts` in `.vue` files, uncomment the following lines: +// import { configureVueProject } from '@vue/eslint-config-typescript' +// configureVueProject({ scriptLangs: ['ts', 'tsx'] }) +// More info at https://github.com/vuejs/eslint-config-typescript/#advanced-setup + +export default defineConfigWithVueTs( + { + name: 'app/files-to-lint', + files: ['**/*.{ts,mts,tsx,vue}'], + }, + + globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']), + + pluginVue.configs['flat/essential'], + vueTsConfigs.recommended, + skipFormatting, + + { + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-empty-object-type': 'off', + '@typescript-eslint/no-unused-vars': 'warn', + 'vue/valid-template-root': 'off', + 'vue/multi-word-component-names': 'off', + }, + }, +); diff --git a/index.html b/index.html new file mode 100644 index 0000000..1456564 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..9fe5870 --- /dev/null +++ b/package.json @@ -0,0 +1,62 @@ +{ + "name": "ndm-web-platform", + "version": "0.0.0", + "private": true, + "type": "module", + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "scripts": { + "dev": "vite", + "build": "tsx build/pre-build.ts && vue-tsc --build && vite build && tsx build/post-build.ts", + "preview": "vite preview", + "build-only": "vite build", + "type-check": "vue-tsc --build", + "lint": "eslint . --fix --cache", + "format": "prettier --write src/" + }, + "dependencies": { + "@stomp/stompjs": "^7.2.1", + "@tanstack/vue-query": "^5.91.0", + "@tanstack/vue-query-devtools": "^6.0.0", + "@vueuse/core": "^14.0.0", + "axios": "^1.13.2", + "compressing": "^2.0.0", + "crypto-js": "^4.2.0", + "dayjs": "^1.11.19", + "destr": "^2.0.5", + "echarts": "^6.0.0", + "es-toolkit": "^1.41.0", + "localforage": "^1.10.0", + "naive-ui": "^2.43.1", + "pinia": "^3.0.4", + "pinia-plugin-persistedstate": "^4.7.1", + "sass": "^1.94.0", + "vue": "^3.5.24", + "vue-router": "^4.6.3", + "ws": "^8.18.3" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.2", + "@types/crypto-js": "^4.2.2", + "@types/node": "^22.18.11", + "@vicons/antd": "^0.13.0", + "@vicons/ionicons5": "^0.13.0", + "@vitejs/plugin-vue": "^6.0.1", + "@vitejs/plugin-vue-jsx": "^5.1.1", + "@vue/eslint-config-prettier": "^10.2.0", + "@vue/eslint-config-typescript": "^14.6.0", + "@vue/tsconfig": "^0.8.1", + "eslint": "^9.39.1", + "eslint-plugin-vue": "~10.5.1", + "jiti": "^2.6.1", + "npm-run-all2": "^8.0.4", + "prettier": "3.6.2", + "tsx": "^4.20.6", + "typescript": "~5.9.3", + "vite": "^7.2.2", + "vite-plugin-vue-devtools": "^8.0.3", + "vue-tsc": "^3.1.3" + }, + "packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..98c2c2c --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4273 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@stomp/stompjs': + specifier: ^7.2.1 + version: 7.2.1 + '@tanstack/vue-query': + specifier: ^5.91.0 + version: 5.91.0(vue@3.5.24(typescript@5.9.3)) + '@tanstack/vue-query-devtools': + specifier: ^6.0.0 + version: 6.0.0(@tanstack/vue-query@5.91.0(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3)) + '@vueuse/core': + specifier: ^14.0.0 + version: 14.0.0(vue@3.5.24(typescript@5.9.3)) + axios: + specifier: ^1.13.2 + version: 1.13.2 + compressing: + specifier: ^2.0.0 + version: 2.0.0 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 + dayjs: + specifier: ^1.11.19 + version: 1.11.19 + destr: + specifier: ^2.0.5 + version: 2.0.5 + echarts: + specifier: ^6.0.0 + version: 6.0.0 + es-toolkit: + specifier: ^1.41.0 + version: 1.41.0 + localforage: + specifier: ^1.10.0 + version: 1.10.0 + naive-ui: + specifier: ^2.43.1 + version: 2.43.1(vue@3.5.24(typescript@5.9.3)) + pinia: + specifier: ^3.0.4 + version: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) + pinia-plugin-persistedstate: + specifier: ^4.7.1 + version: 4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))) + sass: + specifier: ^1.94.0 + version: 1.94.0 + vue: + specifier: ^3.5.24 + version: 3.5.24(typescript@5.9.3) + vue-router: + specifier: ^4.6.3 + version: 4.6.3(vue@3.5.24(typescript@5.9.3)) + ws: + specifier: ^8.18.3 + version: 8.18.3 + devDependencies: + '@tsconfig/node22': + specifier: ^22.0.2 + version: 22.0.3 + '@types/crypto-js': + specifier: ^4.2.2 + version: 4.2.2 + '@types/node': + specifier: ^22.18.11 + version: 22.19.1 + '@vicons/antd': + specifier: ^0.13.0 + version: 0.13.0 + '@vicons/ionicons5': + specifier: ^0.13.0 + version: 0.13.0 + '@vitejs/plugin-vue': + specifier: ^6.0.1 + version: 6.0.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3)) + '@vitejs/plugin-vue-jsx': + specifier: ^5.1.1 + version: 5.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3)) + '@vue/eslint-config-prettier': + specifier: ^10.2.0 + version: 10.2.0(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) + '@vue/eslint-config-typescript': + specifier: ^14.6.0 + version: 14.6.0(eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.1(jiti@2.6.1))))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@vue/tsconfig': + specifier: ^0.8.1 + version: 0.8.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) + eslint: + specifier: ^9.39.1 + version: 9.39.1(jiti@2.6.1) + eslint-plugin-vue: + specifier: ~10.5.1 + version: 10.5.1(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.1(jiti@2.6.1))) + jiti: + specifier: ^2.6.1 + version: 2.6.1 + npm-run-all2: + specifier: ^8.0.4 + version: 8.0.4 + prettier: + specifier: 3.6.2 + version: 3.6.2 + tsx: + specifier: ^4.20.6 + version: 4.20.6 + typescript: + specifier: ~5.9.3 + version: 5.9.3 + vite: + specifier: ^7.2.2 + version: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + vite-plugin-vue-devtools: + specifier: ^8.0.3 + version: 8.0.3(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3)) + vue-tsc: + specifier: ^3.1.3 + version: 3.1.3(typescript@5.9.3) + +packages: + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.5': + resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-proposal-decorators@7.28.0': + resolution: {integrity: sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.27.1': + resolution: {integrity: sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.5': + resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@css-render/plugin-bem@0.15.14': + resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} + peerDependencies: + css-render: ~0.15.14 + + '@css-render/vue3-ssr@0.15.14': + resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} + peerDependencies: + vue: ^3.0.11 + + '@eggjs/yauzl@2.11.0': + resolution: {integrity: sha512-Jq+k2fCZJ3i3HShb0nxLUiAgq5pwo8JTT1TrH22JoehZQ0Nm2dvByGIja1NYfNyuE4Tx5/Dns5nVsBN/mlC8yg==} + + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.1': + resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@juggle/resize-observer@3.4.0': + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + + '@pkgr/core@0.2.9': + resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@rolldown/pluginutils@1.0.0-beta.29': + resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} + + '@rolldown/pluginutils@1.0.0-beta.50': + resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==} + + '@rollup/rollup-android-arm-eabi@4.53.2': + resolution: {integrity: sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.53.2': + resolution: {integrity: sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.53.2': + resolution: {integrity: sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.53.2': + resolution: {integrity: sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.53.2': + resolution: {integrity: sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.53.2': + resolution: {integrity: sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + resolution: {integrity: sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.53.2': + resolution: {integrity: sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.53.2': + resolution: {integrity: sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.53.2': + resolution: {integrity: sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.53.2': + resolution: {integrity: sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.53.2': + resolution: {integrity: sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.53.2': + resolution: {integrity: sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.53.2': + resolution: {integrity: sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.53.2': + resolution: {integrity: sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.53.2': + resolution: {integrity: sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.53.2': + resolution: {integrity: sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openharmony-arm64@4.53.2': + resolution: {integrity: sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.53.2': + resolution: {integrity: sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.53.2': + resolution: {integrity: sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.53.2': + resolution: {integrity: sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.53.2': + resolution: {integrity: sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==} + cpu: [x64] + os: [win32] + + '@stomp/stompjs@7.2.1': + resolution: {integrity: sha512-DLd/WeicnHS5SsWWSk3x6/pcivqchNaEvg9UEGVqAcfYEBVmS9D6980ckXjTtfpXLjdLDsd96M7IuX4w7nzq5g==} + + '@tanstack/match-sorter-utils@8.19.4': + resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} + engines: {node: '>=12'} + + '@tanstack/query-core@5.90.8': + resolution: {integrity: sha512-4E0RP/0GJCxSNiRF2kAqE/LQkTJVlL/QNU7gIJSptaseV9HP6kOuA+N11y4bZKZxa3QopK3ZuewwutHx6DqDXQ==} + + '@tanstack/query-devtools@5.90.1': + resolution: {integrity: sha512-GtINOPjPUH0OegJExZ70UahT9ykmAhmtNVcmtdnOZbxLwT7R5OmRztR5Ahe3/Cu7LArEmR6/588tAycuaWb1xQ==} + + '@tanstack/vue-query-devtools@6.0.0': + resolution: {integrity: sha512-68ym4x7BMQNrzBJoXWPkc2dbRLautJsU+4gLgKxF0kCWsLH4FevzGjpJ9xqKfT1zFT8yBQob/GZ7smD+M6n4CA==} + peerDependencies: + '@tanstack/vue-query': ^5.91.0 + vue: ^3.3.0 + + '@tanstack/vue-query@5.91.0': + resolution: {integrity: sha512-oyYZPu/HNfYhfd6doJHKil4hQG7I0GgZYA7cmyV6rBGsDpIYvDbBSRUWLmcd3+wkp2QnrnwqsC/4XM0lMJgGOA==} + peerDependencies: + '@vue/composition-api': ^1.1.2 + vue: ^2.6.0 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + '@tsconfig/node22@22.0.3': + resolution: {integrity: sha512-9UTUkYWI58+MiZhwcQWx2TNZbzkGRss9SCyjrSYeqkMIDYq8jv2FSRknrLOjsRmcYFUsYj79m/bgQYSD/yiRxw==} + + '@types/crypto-js@4.2.2': + resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + + '@types/node@22.19.1': + resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} + + '@types/web-bluetooth@0.0.21': + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + + '@typescript-eslint/eslint-plugin@8.46.4': + resolution: {integrity: sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.46.4 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.46.4': + resolution: {integrity: sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.46.4': + resolution: {integrity: sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.46.4': + resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.46.4': + resolution: {integrity: sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.46.4': + resolution: {integrity: sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.46.4': + resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.46.4': + resolution: {integrity: sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.46.4': + resolution: {integrity: sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.46.4': + resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vicons/antd@0.13.0': + resolution: {integrity: sha512-yrUGoUSz2BbGupk9ghQOahc04n5H3MwUDM9pVPsLh9U1uqB47oRWZvYRiZaT1JKPqgTgSE6BXcVw4i9MOF4M+g==} + + '@vicons/ionicons5@0.13.0': + resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==} + + '@vitejs/plugin-vue-jsx@5.1.1': + resolution: {integrity: sha512-uQkfxzlF8SGHJJVH966lFTdjM/lGcwJGzwAHpVqAPDD/QcsqoUGa+q31ox1BrUfi+FLP2ChVp7uLXE3DkHyDdQ==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@6.0.1': + resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.23': + resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} + + '@volar/source-map@2.4.23': + resolution: {integrity: sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==} + + '@volar/typescript@2.4.23': + resolution: {integrity: sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==} + + '@vue/babel-helper-vue-transform-on@1.5.0': + resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==} + + '@vue/babel-plugin-jsx@1.5.0': + resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.5.0': + resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.24': + resolution: {integrity: sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==} + + '@vue/compiler-dom@3.5.24': + resolution: {integrity: sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==} + + '@vue/compiler-sfc@3.5.24': + resolution: {integrity: sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==} + + '@vue/compiler-ssr@3.5.24': + resolution: {integrity: sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/devtools-api@7.7.8': + resolution: {integrity: sha512-BtFcAmDbtXGwurWUFf8ogIbgZyR+rcVES1TSNEI8Em80fD8Anu+qTRN1Fc3J6vdRHlVM3fzPV1qIo+B4AiqGzw==} + + '@vue/devtools-core@8.0.3': + resolution: {integrity: sha512-gCEQN7aMmeaigEWJQ2Z2o3g7/CMqGTPvNS1U3n/kzpLoAZ1hkAHNgi4ml/POn/9uqGILBk65GGOUdrraHXRj5Q==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.7.8': + resolution: {integrity: sha512-4Y8op+AoxOJhB9fpcEF6d5vcJXWKgHxC3B0ytUB8zz15KbP9g9WgVzral05xluxi2fOeAy6t140rdQ943GcLRQ==} + + '@vue/devtools-kit@8.0.3': + resolution: {integrity: sha512-UF4YUOVGdfzXLCv5pMg2DxocB8dvXz278fpgEE+nJ/DRALQGAva7sj9ton0VWZ9hmXw+SV8yKMrxP2MpMhq9Wg==} + + '@vue/devtools-shared@7.7.8': + resolution: {integrity: sha512-XHpO3jC5nOgYr40M9p8Z4mmKfTvUxKyRcUnpBAYg11pE78eaRFBKb0kG5yKLroMuJeeNH9LWmKp2zMU5LUc7CA==} + + '@vue/devtools-shared@8.0.3': + resolution: {integrity: sha512-s/QNll7TlpbADFZrPVsaUNPCOF8NvQgtgmmB7Tip6pLf/HcOvBTly0lfLQ0Eylu9FQ4OqBhFpLyBgwykiSf8zw==} + + '@vue/eslint-config-prettier@10.2.0': + resolution: {integrity: sha512-GL3YBLwv/+b86yHcNNfPJxOTtVFJ4Mbc9UU3zR+KVoG7SwGTjPT+32fXamscNumElhcpXW3mT0DgzS9w32S7Bw==} + peerDependencies: + eslint: '>= 8.21.0' + prettier: '>= 3.0.0' + + '@vue/eslint-config-typescript@14.6.0': + resolution: {integrity: sha512-UpiRY/7go4Yps4mYCjkvlIbVWmn9YvPGQDxTAlcKLphyaD77LjIu3plH4Y9zNT0GB4f3K5tMmhhtRhPOgrQ/bQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^9.10.0 + eslint-plugin-vue: ^9.28.0 || ^10.0.0 + typescript: '>=4.8.4' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/language-core@3.1.3': + resolution: {integrity: sha512-KpR1F/eGAG9D1RZ0/T6zWJs6dh/pRLfY5WupecyYKJ1fjVmDMgTPw9wXmKv2rBjo4zCJiOSiyB8BDP1OUwpMEA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.24': + resolution: {integrity: sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==} + + '@vue/runtime-core@3.5.24': + resolution: {integrity: sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==} + + '@vue/runtime-dom@3.5.24': + resolution: {integrity: sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==} + + '@vue/server-renderer@3.5.24': + resolution: {integrity: sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==} + peerDependencies: + vue: 3.5.24 + + '@vue/shared@3.5.24': + resolution: {integrity: sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==} + + '@vue/tsconfig@0.8.1': + resolution: {integrity: sha512-aK7feIWPXFSUhsCP9PFqPyFOcz4ENkb8hZ2pneL6m2UjCkccvaOhC/5KCKluuBufvp2KzkbdA2W2pk20vLzu3g==} + peerDependencies: + typescript: 5.x + vue: ^3.4.0 + peerDependenciesMeta: + typescript: + optional: true + vue: + optional: true + + '@vueuse/core@14.0.0': + resolution: {integrity: sha512-d6tKRWkZE8IQElX2aHBxXOMD478fHIYV+Dzm2y9Ag122ICBpNKtGICiXKOhWU3L1kKdttDD9dCMS4bGP3jhCTQ==} + peerDependencies: + vue: ^3.5.0 + + '@vueuse/metadata@14.0.0': + resolution: {integrity: sha512-6yoGqbJcMldVCevkFiHDBTB1V5Hq+G/haPlGIuaFZHpXC0HADB0EN1ryQAAceiW+ryS3niUwvdFbGiqHqBrfVA==} + + '@vueuse/shared@14.0.0': + resolution: {integrity: sha512-mTCA0uczBgurRlwVaQHfG0Ja7UdGe4g9mwffiJmvLiTtp1G4AQyIjej6si/k8c8pUwTfVpNufck+23gXptPAkw==} + peerDependencies: + vue: ^3.5.0 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + alien-signals@3.1.0: + resolution: {integrity: sha512-yufC6VpSy8tK3I0lO67pjumo5JvDQVQyr38+3OHqe6CHl1t2VZekKZ7EKKZSqk0cRmE7U7tfZbpXiKNzuc+ckg==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@1.13.2: + resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.8.28: + resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} + hasBin: true + + birpc@2.8.0: + resolution: {integrity: sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==} + + bl@1.2.3: + resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.0: + resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-alloc-unsafe@1.1.0: + resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} + + buffer-alloc@1.2.0: + resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-fill@1.0.0: + resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001754: + resolution: {integrity: sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + compressing@2.0.0: + resolution: {integrity: sha512-hRG5wpuy/lkO/oO8AEhSmLw2FVJOs2DnFPtmm0XUVWoDP6k3HAw5RVgyzbbATl0ytjJDCY03DvRiyjHkSHc1Dg==} + engines: {node: '>= 18.0.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copy-anything@4.0.5: + resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} + engines: {node: '>=18'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-render@0.15.14: + resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.0.11: + resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + date-fns-tz@3.2.0: + resolution: {integrity: sha512-sg8HqoTEulcbbbVXeg84u5UnlsQa8GS5QXMqjjYIhS4abEVVKIUwe0/l/UhrZdKaL/W5eWZNlbTeEIiOXTcsBQ==} + peerDependencies: + date-fns: ^3.0.0 || ^4.0.0 + + date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.3.0: + resolution: {integrity: sha512-Qq68+VkJlc8tjnPV1i7HtbIn7ohmjZa88qUvHMIK0ZKUXMCuV45cT7cEXALPUmeXCe0q1DWQkQTemHVaLIFSrg==} + engines: {node: '>=18'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + echarts@6.0.0: + resolution: {integrity: sha512-Tte/grDQRiETQP4xz3iZWSvoHrkCQtwqd6hs+mifXcjrCuo2iKWbajFObuLJVBlDIJlOzgQPd1hsaKt/3+OMkQ==} + + electron-to-chromium@1.5.251: + resolution: {integrity: sha512-lmyEOp4G0XT3qrYswNB4np1kx90k6QCXpnSHYv2xEsUuEu8JCobpDVYO6vMseirQyyCC6GCIGGxd5szMBa0tRA==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-toolkit@1.41.0: + resolution: {integrity: sha512-bDd3oRmbVgqZCJS6WmeQieOrzpl3URcWBUVDXxOELlUW2FuW+0glPOz1n0KnRie+PdyvUZcXz2sOn00c6pPRIA==} + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-prettier@5.5.4: + resolution: {integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-vue@10.5.1: + resolution: {integrity: sha512-SbR9ZBUFKgvWAbq3RrdCtWaW0IKm6wwUiApxf3BVTNfqUIo4IQQmreMg2iHFJJ6C/0wss3LXURBJ1OwS/MhFcQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 + eslint: ^8.57.0 || ^9.0.0 + vue-eslint-parser: ^10.0.0 + peerDependenciesMeta: + '@stylistic/eslint-plugin': + optional: true + '@typescript-eslint/parser': + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.39.1: + resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + evtd@0.2.4: + resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fd-slicer2@1.2.0: + resolution: {integrity: sha512-3lBUNUckhMZduCc4g+Pw4Ve16LD9vpX9b8qUkkKq2mgDRLYWzblszZH2luADnJqjJe+cypngjCuKRm/IW12rRw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + flushwritable@1.0.0: + resolution: {integrity: sha512-3VELfuWCLVzt5d2Gblk8qcqFro6nuwvxwMzHaENVDHI7rxcBRtMCwTk/E9FXcgh+82DSpavPNDueA9+RxXJoFg==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-ready@1.0.0: + resolution: {integrity: sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==} + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + iconv-lite@0.5.2: + resolution: {integrity: sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immutable@5.1.4: + resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-what@5.5.0: + resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==} + engines: {node: '>=18'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@4.0.0: + resolution: {integrity: sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==} + engines: {node: ^18.17.0 || >=20.5.0} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + + localforage@1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + naive-ui@2.43.1: + resolution: {integrity: sha512-w52W0mOhdOGt4uucFSZmP0DI44PCsFyuxeLSs9aoUThfIuxms90MYjv46Qrr7xprjyJRw5RU6vYpCx4o9ind3A==} + peerDependencies: + vue: ^3.0.0 + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.1.6: + resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} + engines: {node: ^18 || >=20} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + npm-normalize-package-bin@4.0.0: + resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==} + engines: {node: ^18.17.0 || >=20.5.0} + + npm-run-all2@8.0.4: + resolution: {integrity: sha512-wdbB5My48XKp2ZfJUlhnLVihzeuA1hgBnqB2J9ahV77wLS+/YAJAlN8I+X3DIFIPZ3m5L7nplmlbhNiFDmXRDA==} + engines: {node: ^20.5.0 || >=22.0.0, npm: '>= 10'} + hasBin: true + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + perfect-debounce@2.0.0: + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pinia-plugin-persistedstate@4.7.1: + resolution: {integrity: sha512-WHOqh2esDlR3eAaknPbqXrkkj0D24h8shrDPqysgCFR6ghqP/fpFfJmMPJp0gETHsvrh9YNNg6dQfo2OEtDnIQ==} + peerDependencies: + '@nuxt/kit': '>=3.0.0' + '@pinia/nuxt': '>=0.10.0' + pinia: '>=3.0.0' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@pinia/nuxt': + optional: true + pinia: + optional: true + + pinia@3.0.4: + resolution: {integrity: sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==} + peerDependencies: + typescript: '>=4.5.0' + vue: ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-package-json-fast@4.0.0: + resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==} + engines: {node: ^18.17.0 || >=20.5.0} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rollup@4.53.2: + resolution: {integrity: sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass@1.94.0: + resolution: {integrity: sha512-Dqh7SiYcaFtdv5Wvku6QgS5IGPm281L+ZtVD1U2FJa7Q0EFRlq8Z3sjYtz6gYObsYThUOz9ArwFqPZx+1azILQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + seemly@0.3.10: + resolution: {integrity: sha512-2+SMxtG1PcsL0uyhkumlOU6Qo9TAQ/WyH7tthnPIOQB05/12jz9naq6GZ6iZ6ApVsO3rr2gsnTf3++OV63kE1Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + streamifier@0.1.1: + resolution: {integrity: sha512-zDgl+muIlWzXNsXeyUfOk9dChMjlpkq0DRsxujtYPgyJ676yQ8jEm6zzaaWHFDg5BNcLuif0eD2MTyJdZqXpdg==} + engines: {node: '>=0.10'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + superjson@2.2.5: + resolution: {integrity: sha512-zWPTX96LVsA/eVYnqOM2+ofcdPqdS1dAF1LN4TS2/MWuUpfitd9ctTa87wt4xrYnZnkLtS69xpBdSxVBP5Rm6w==} + engines: {node: '>=16'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + synckit@0.11.11: + resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==} + engines: {node: ^14.18.0 || >=16.0.0} + + tar-stream@1.6.2: + resolution: {integrity: sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==} + engines: {node: '>= 0.8.0'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + treemate@0.3.11: + resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.46.4: + resolution: {integrity: sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unplugin-utils@0.3.1: + resolution: {integrity: sha512-5lWVjgi6vuHhJ526bI4nlCOmkCIF3nnfXkCMDeMJrtdvxTs6ZFCM8oNufGTsDbKv/tJ/xj8RpvXjRuPBZJuJog==} + engines: {node: '>=20.19.0'} + + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vdirs@0.1.8: + resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} + peerDependencies: + vue: ^3.0.11 + + vite-dev-rpc@1.1.0: + resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 + + vite-hot-client@2.1.0: + resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 + + vite-plugin-inspect@11.3.3: + resolution: {integrity: sha512-u2eV5La99oHoYPHE6UvbwgEqKKOQGz86wMg40CCosP6q8BkB6e5xPneZfYagK4ojPJSj5anHCrnvC20DpwVdRA==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-devtools@8.0.3: + resolution: {integrity: sha512-yIi3u31xUi28HcLlTpV0BvSLQHgZ2dA8Zqa59kWfIeMdHqbsunt6TCjq4wCNfOcGSju+E7qyHyI09EjRRFMbuQ==} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^6.0.0 || ^7.0.0-0 + + vite-plugin-vue-inspector@5.3.2: + resolution: {integrity: sha512-YvEKooQcSiBTAs0DoYLfefNja9bLgkFM7NI2b07bE2SruuvX0MEa9cMaxjKVMkeCp5Nz9FRIdcN1rOdFVBeL6Q==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 + + vite@7.2.2: + resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vooks@0.2.12: + resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} + peerDependencies: + vue: ^3.0.0 + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-eslint-parser@10.2.0: + resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + vue-router@4.6.3: + resolution: {integrity: sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==} + peerDependencies: + vue: ^3.5.0 + + vue-tsc@3.1.3: + resolution: {integrity: sha512-StMNfZHwPIXQgY3KxPKM0Jsoc8b46mDV3Fn2UlHCBIwRJApjqrSwqeMYgWf0zpN+g857y74pv7GWuBm+UqQe1w==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue@3.5.24: + resolution: {integrity: sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vueuc@0.4.65: + resolution: {integrity: sha512-lXuMl+8gsBmruudfxnMF9HW4be8rFziylXFu1VHVNbLVhRTXXV4njvpRuJapD/8q+oFEMSfQMH16E/85VoWRyQ==} + peerDependencies: + vue: ^3.0.11 + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@5.0.0: + resolution: {integrity: sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==} + engines: {node: ^18.17.0 || >=20.5.0} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + wsl-utils@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yazl@2.5.1: + resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zrender@6.0.0: + resolution: {integrity: sha512-41dFXEEXuJpNecuUQq6JlbybmnHaqqpGlbH1yxnA5V9MMP4SbohSVZsJIwz+zdjQXSSlR1Vc34EgH1zxyTDvhg==} + +snapshots: + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.5': {} + + '@babel/core@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.5 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-proposal-decorators@7.28.0(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-decorators': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-decorators@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@css-render/plugin-bem@0.15.14(css-render@0.15.14)': + dependencies: + css-render: 0.15.14 + + '@css-render/vue3-ssr@0.15.14(vue@3.5.24(typescript@5.9.3))': + dependencies: + vue: 3.5.24(typescript@5.9.3) + + '@eggjs/yauzl@2.11.0': + dependencies: + buffer-crc32: 0.2.13 + fd-slicer2: 1.2.0 + + '@emotion/hash@0.8.0': {} + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.1(jiti@2.6.1))': + dependencies: + eslint: 9.39.1(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.1': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@juggle/resize-observer@3.4.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + optional: true + + '@pkgr/core@0.2.9': {} + + '@polka/url@1.0.0-next.29': {} + + '@rolldown/pluginutils@1.0.0-beta.29': {} + + '@rolldown/pluginutils@1.0.0-beta.50': {} + + '@rollup/rollup-android-arm-eabi@4.53.2': + optional: true + + '@rollup/rollup-android-arm64@4.53.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.2': + optional: true + + '@rollup/rollup-darwin-x64@4.53.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.2': + optional: true + + '@stomp/stompjs@7.2.1': {} + + '@tanstack/match-sorter-utils@8.19.4': + dependencies: + remove-accents: 0.5.0 + + '@tanstack/query-core@5.90.8': {} + + '@tanstack/query-devtools@5.90.1': {} + + '@tanstack/vue-query-devtools@6.0.0(@tanstack/vue-query@5.91.0(vue@3.5.24(typescript@5.9.3)))(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@tanstack/query-devtools': 5.90.1 + '@tanstack/vue-query': 5.91.0(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + + '@tanstack/vue-query@5.91.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@tanstack/match-sorter-utils': 8.19.4 + '@tanstack/query-core': 5.90.8 + '@vue/devtools-api': 6.6.4 + vue: 3.5.24(typescript@5.9.3) + vue-demi: 0.14.10(vue@3.5.24(typescript@5.9.3)) + + '@tsconfig/node22@22.0.3': {} + + '@types/crypto-js@4.2.2': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/katex@0.16.7': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.20 + + '@types/lodash@4.17.20': {} + + '@types/node@22.19.1': + dependencies: + undici-types: 6.21.0 + + '@types/web-bluetooth@0.0.21': {} + + '@typescript-eslint/eslint-plugin@8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/type-utils': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.4 + eslint: 9.39.1(jiti@2.6.1) + graphemer: 1.4.0 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.4 + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.46.4(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) + '@typescript-eslint/types': 8.46.4 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.46.4': + dependencies: + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/visitor-keys': 8.46.4 + + '@typescript-eslint/tsconfig-utils@8.46.4(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.46.4': {} + + '@typescript-eslint/typescript-estree@8.46.4(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.46.4(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.4(typescript@5.9.3) + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/visitor-keys': 8.46.4 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.46.4 + '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.46.4': + dependencies: + '@typescript-eslint/types': 8.46.4 + eslint-visitor-keys: 4.2.1 + + '@vicons/antd@0.13.0': {} + + '@vicons/ionicons5@0.13.0': {} + + '@vitejs/plugin-vue-jsx@5.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.50 + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + vue: 3.5.24(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@6.0.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.29 + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + vue: 3.5.24(typescript@5.9.3) + + '@volar/language-core@2.4.23': + dependencies: + '@volar/source-map': 2.4.23 + + '@volar/source-map@2.4.23': {} + + '@volar/typescript@2.4.23': + dependencies: + '@volar/language-core': 2.4.23 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 + + '@vue/babel-helper-vue-transform-on@1.5.0': {} + + '@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.5)': + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@vue/babel-helper-vue-transform-on': 1.5.0 + '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.28.5) + '@vue/shared': 3.5.24 + optionalDependencies: + '@babel/core': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.28.5)': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.28.5 + '@vue/compiler-sfc': 3.5.24 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.24': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.24 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.24': + dependencies: + '@vue/compiler-core': 3.5.24 + '@vue/shared': 3.5.24 + + '@vue/compiler-sfc@3.5.24': + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.24 + '@vue/compiler-dom': 3.5.24 + '@vue/compiler-ssr': 3.5.24 + '@vue/shared': 3.5.24 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.6 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.24': + dependencies: + '@vue/compiler-dom': 3.5.24 + '@vue/shared': 3.5.24 + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-api@7.7.8': + dependencies: + '@vue/devtools-kit': 7.7.8 + + '@vue/devtools-core@8.0.3(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@vue/devtools-kit': 8.0.3 + '@vue/devtools-shared': 8.0.3 + mitt: 3.0.1 + nanoid: 5.1.6 + pathe: 2.0.3 + vite-hot-client: 2.1.0(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)) + vue: 3.5.24(typescript@5.9.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.7.8': + dependencies: + '@vue/devtools-shared': 7.7.8 + birpc: 2.8.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.5 + + '@vue/devtools-kit@8.0.3': + dependencies: + '@vue/devtools-shared': 8.0.3 + birpc: 2.8.0 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 2.0.0 + speakingurl: 14.0.1 + superjson: 2.2.5 + + '@vue/devtools-shared@7.7.8': + dependencies: + rfdc: 1.4.1 + + '@vue/devtools-shared@8.0.3': + dependencies: + rfdc: 1.4.1 + + '@vue/eslint-config-prettier@10.2.0(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2)': + dependencies: + eslint: 9.39.1(jiti@2.6.1) + eslint-config-prettier: 10.1.8(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-prettier: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2) + prettier: 3.6.2 + transitivePeerDependencies: + - '@types/eslint' + + '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.1(jiti@2.6.1))))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) + eslint-plugin-vue: 10.5.1(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.1(jiti@2.6.1))) + fast-glob: 3.3.3 + typescript-eslint: 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + vue-eslint-parser: 10.2.0(eslint@9.39.1(jiti@2.6.1)) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@vue/language-core@3.1.3(typescript@5.9.3)': + dependencies: + '@volar/language-core': 2.4.23 + '@vue/compiler-dom': 3.5.24 + '@vue/shared': 3.5.24 + alien-signals: 3.1.0 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.3 + optionalDependencies: + typescript: 5.9.3 + + '@vue/reactivity@3.5.24': + dependencies: + '@vue/shared': 3.5.24 + + '@vue/runtime-core@3.5.24': + dependencies: + '@vue/reactivity': 3.5.24 + '@vue/shared': 3.5.24 + + '@vue/runtime-dom@3.5.24': + dependencies: + '@vue/reactivity': 3.5.24 + '@vue/runtime-core': 3.5.24 + '@vue/shared': 3.5.24 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@vue/compiler-ssr': 3.5.24 + '@vue/shared': 3.5.24 + vue: 3.5.24(typescript@5.9.3) + + '@vue/shared@3.5.24': {} + + '@vue/tsconfig@0.8.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))': + optionalDependencies: + typescript: 5.9.3 + vue: 3.5.24(typescript@5.9.3) + + '@vueuse/core@14.0.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 14.0.0 + '@vueuse/shared': 14.0.0(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + + '@vueuse/metadata@14.0.0': {} + + '@vueuse/shared@14.0.0(vue@3.5.24(typescript@5.9.3))': + dependencies: + vue: 3.5.24(typescript@5.9.3) + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + alien-signals@3.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + ansis@4.2.0: {} + + argparse@2.0.1: {} + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axios@1.13.2: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + baseline-browser-mapping@2.8.28: {} + + birpc@2.8.0: {} + + bl@1.2.3: + dependencies: + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + + boolbase@1.0.0: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.2: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.0: + dependencies: + baseline-browser-mapping: 2.8.28 + caniuse-lite: 1.0.30001754 + electron-to-chromium: 1.5.251 + node-releases: 2.0.27 + update-browserslist-db: 1.1.4(browserslist@4.28.0) + + buffer-alloc-unsafe@1.1.0: {} + + buffer-alloc@1.2.0: + dependencies: + buffer-alloc-unsafe: 1.1.0 + buffer-fill: 1.0.0 + + buffer-crc32@0.2.13: {} + + buffer-fill@1.0.0: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001754: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + compressing@2.0.0: + dependencies: + '@eggjs/yauzl': 2.11.0 + flushwritable: 1.0.0 + get-ready: 1.0.0 + iconv-lite: 0.5.2 + streamifier: 0.1.1 + tar-stream: 1.6.2 + yazl: 2.5.1 + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + copy-anything@4.0.5: + dependencies: + is-what: 5.5.0 + + core-util-is@1.0.3: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-js@4.2.0: {} + + css-render@0.15.14: + dependencies: + '@emotion/hash': 0.8.0 + csstype: 3.0.11 + + cssesc@3.0.0: {} + + csstype@3.0.11: {} + + csstype@3.1.3: {} + + date-fns-tz@3.2.0(date-fns@3.6.0): + dependencies: + date-fns: 3.6.0 + + date-fns@3.6.0: {} + + dayjs@1.11.19: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + default-browser-id@5.0.0: {} + + default-browser@5.3.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@3.0.0: {} + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + destr@2.0.5: {} + + detect-libc@1.0.3: + optional: true + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + echarts@6.0.0: + dependencies: + tslib: 2.3.0 + zrender: 6.0.0 + + electron-to-chromium@1.5.251: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + entities@4.5.0: {} + + error-stack-parser-es@1.0.5: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-toolkit@1.41.0: {} + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)): + dependencies: + eslint: 9.39.1(jiti@2.6.1) + + eslint-plugin-prettier@5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(prettier@3.6.2): + dependencies: + eslint: 9.39.1(jiti@2.6.1) + prettier: 3.6.2 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.11 + optionalDependencies: + eslint-config-prettier: 10.1.8(eslint@9.39.1(jiti@2.6.1)) + + eslint-plugin-vue@10.5.1(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(vue-eslint-parser@10.2.0(eslint@9.39.1(jiti@2.6.1))): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + eslint: 9.39.1(jiti@2.6.1) + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.7.3 + vue-eslint-parser: 10.2.0(eslint@9.39.1(jiti@2.6.1)) + xml-name-validator: 4.0.0 + optionalDependencies: + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint@9.39.1(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.39.1 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + evtd@0.2.4: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fd-slicer2@1.2.0: + dependencies: + pend: 1.2.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + flushwritable@1.0.0: {} + + follow-redirects@1.15.11: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + fs-constants@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-ready@1.0.0: {} + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + gopd@1.2.0: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + highlight.js@11.11.1: {} + + hookable@5.5.3: {} + + iconv-lite@0.5.2: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + immediate@3.0.6: {} + + immutable@5.1.4: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inherits@2.0.4: {} + + is-callable@1.2.7: {} + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-number@7.0.0: {} + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-what@5.5.0: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isexe@3.1.1: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@4.0.0: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kolorist@1.8.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lie@3.1.1: + dependencies: + immediate: 3.0.6 + + localforage@1.10.0: + dependencies: + lie: 3.1.1 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + math-intrinsics@1.1.0: {} + + memorystream@0.3.1: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + mitt@3.0.1: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + naive-ui@2.43.1(vue@3.5.24(typescript@5.9.3)): + dependencies: + '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) + '@css-render/vue3-ssr': 0.15.14(vue@3.5.24(typescript@5.9.3)) + '@types/katex': 0.16.7 + '@types/lodash': 4.17.20 + '@types/lodash-es': 4.17.12 + async-validator: 4.2.5 + css-render: 0.15.14 + csstype: 3.1.3 + date-fns: 3.6.0 + date-fns-tz: 3.2.0(date-fns@3.6.0) + evtd: 0.2.4 + highlight.js: 11.11.1 + lodash: 4.17.21 + lodash-es: 4.17.21 + seemly: 0.3.10 + treemate: 0.3.11 + vdirs: 0.1.8(vue@3.5.24(typescript@5.9.3)) + vooks: 0.2.12(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + vueuc: 0.4.65(vue@3.5.24(typescript@5.9.3)) + + nanoid@3.3.11: {} + + nanoid@5.1.6: {} + + natural-compare@1.4.0: {} + + node-addon-api@7.1.1: + optional: true + + node-releases@2.0.27: {} + + npm-normalize-package-bin@4.0.0: {} + + npm-run-all2@8.0.4: + dependencies: + ansi-styles: 6.2.3 + cross-spawn: 7.0.6 + memorystream: 0.3.1 + picomatch: 4.0.3 + pidtree: 0.6.0 + read-package-json-fast: 4.0.0 + shell-quote: 1.8.3 + which: 5.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + ohash@2.0.11: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + open@10.2.0: + dependencies: + default-browser: 5.3.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + pathe@2.0.3: {} + + pend@1.2.0: {} + + perfect-debounce@1.0.0: {} + + perfect-debounce@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pidtree@0.6.0: {} + + pinia-plugin-persistedstate@4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3))): + dependencies: + defu: 6.1.4 + optionalDependencies: + pinia: 3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) + + pinia@3.0.4(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)): + dependencies: + '@vue/devtools-api': 7.7.8 + vue: 3.5.24(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + + possible-typed-array-names@1.1.0: {} + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.6.2: {} + + process-nextick-args@2.0.1: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + read-package-json-fast@4.0.0: + dependencies: + json-parse-even-better-errors: 4.0.0 + npm-normalize-package-bin: 4.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readdirp@4.1.2: {} + + remove-accents@0.5.0: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + rollup@4.53.2: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.53.2 + '@rollup/rollup-android-arm64': 4.53.2 + '@rollup/rollup-darwin-arm64': 4.53.2 + '@rollup/rollup-darwin-x64': 4.53.2 + '@rollup/rollup-freebsd-arm64': 4.53.2 + '@rollup/rollup-freebsd-x64': 4.53.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.53.2 + '@rollup/rollup-linux-arm-musleabihf': 4.53.2 + '@rollup/rollup-linux-arm64-gnu': 4.53.2 + '@rollup/rollup-linux-arm64-musl': 4.53.2 + '@rollup/rollup-linux-loong64-gnu': 4.53.2 + '@rollup/rollup-linux-ppc64-gnu': 4.53.2 + '@rollup/rollup-linux-riscv64-gnu': 4.53.2 + '@rollup/rollup-linux-riscv64-musl': 4.53.2 + '@rollup/rollup-linux-s390x-gnu': 4.53.2 + '@rollup/rollup-linux-x64-gnu': 4.53.2 + '@rollup/rollup-linux-x64-musl': 4.53.2 + '@rollup/rollup-openharmony-arm64': 4.53.2 + '@rollup/rollup-win32-arm64-msvc': 4.53.2 + '@rollup/rollup-win32-ia32-msvc': 4.53.2 + '@rollup/rollup-win32-x64-gnu': 4.53.2 + '@rollup/rollup-win32-x64-msvc': 4.53.2 + fsevents: 2.3.3 + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + sass@1.94.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.4 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.1 + + seemly@0.3.10: {} + + semver@6.3.1: {} + + semver@7.7.3: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + sirv@3.0.2: + dependencies: + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + speakingurl@14.0.1: {} + + streamifier@0.1.1: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-json-comments@3.1.1: {} + + superjson@2.2.5: + dependencies: + copy-anything: 4.0.5 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + + tar-stream@1.6.2: + dependencies: + bl: 1.2.3 + buffer-alloc: 1.2.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + readable-stream: 2.3.8 + to-buffer: 1.2.2 + xtend: 4.0.2 + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + treemate@0.3.11: {} + + ts-api-utils@2.1.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + tslib@2.3.0: {} + + tsx@4.20.6: + dependencies: + esbuild: 0.25.12 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typescript-eslint@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.46.4(@typescript-eslint/parser@8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.4(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.1(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + unplugin-utils@0.3.1: + dependencies: + pathe: 2.0.3 + picomatch: 4.0.3 + + update-browserslist-db@1.1.4(browserslist@4.28.0): + dependencies: + browserslist: 4.28.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vdirs@0.1.8(vue@3.5.24(typescript@5.9.3)): + dependencies: + evtd: 0.2.4 + vue: 3.5.24(typescript@5.9.3) + + vite-dev-rpc@1.1.0(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)): + dependencies: + birpc: 2.8.0 + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + vite-hot-client: 2.1.0(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)) + + vite-hot-client@2.1.0(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)): + dependencies: + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + + vite-plugin-inspect@11.3.3(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)): + dependencies: + ansis: 4.2.0 + debug: 4.4.3 + error-stack-parser-es: 1.0.5 + ohash: 2.0.11 + open: 10.2.0 + perfect-debounce: 2.0.0 + sirv: 3.0.2 + unplugin-utils: 0.3.1 + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + vite-dev-rpc: 1.1.0(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)) + transitivePeerDependencies: + - supports-color + + vite-plugin-vue-devtools@8.0.3(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3)): + dependencies: + '@vue/devtools-core': 8.0.3(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6))(vue@3.5.24(typescript@5.9.3)) + '@vue/devtools-kit': 8.0.3 + '@vue/devtools-shared': 8.0.3 + sirv: 3.0.2 + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + vite-plugin-inspect: 11.3.3(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)) + vite-plugin-vue-inspector: 5.3.2(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)) + transitivePeerDependencies: + - '@nuxt/kit' + - supports-color + - vue + + vite-plugin-vue-inspector@5.3.2(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6)): + dependencies: + '@babel/core': 7.28.5 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.5) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.5) + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.5) + '@vue/compiler-dom': 3.5.24 + kolorist: 1.8.0 + magic-string: 0.30.21 + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6) + transitivePeerDependencies: + - supports-color + + vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(sass@1.94.0)(tsx@4.20.6): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.53.2 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.1 + fsevents: 2.3.3 + jiti: 2.6.1 + sass: 1.94.0 + tsx: 4.20.6 + + vooks@0.2.12(vue@3.5.24(typescript@5.9.3)): + dependencies: + evtd: 0.2.4 + vue: 3.5.24(typescript@5.9.3) + + vscode-uri@3.1.0: {} + + vue-demi@0.14.10(vue@3.5.24(typescript@5.9.3)): + dependencies: + vue: 3.5.24(typescript@5.9.3) + + vue-eslint-parser@10.2.0(eslint@9.39.1(jiti@2.6.1)): + dependencies: + debug: 4.4.3 + eslint: 9.39.1(jiti@2.6.1) + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + + vue-router@4.6.3(vue@3.5.24(typescript@5.9.3)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.24(typescript@5.9.3) + + vue-tsc@3.1.3(typescript@5.9.3): + dependencies: + '@volar/typescript': 2.4.23 + '@vue/language-core': 3.1.3(typescript@5.9.3) + typescript: 5.9.3 + + vue@3.5.24(typescript@5.9.3): + dependencies: + '@vue/compiler-dom': 3.5.24 + '@vue/compiler-sfc': 3.5.24 + '@vue/runtime-dom': 3.5.24 + '@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.9.3)) + '@vue/shared': 3.5.24 + optionalDependencies: + typescript: 5.9.3 + + vueuc@0.4.65(vue@3.5.24(typescript@5.9.3)): + dependencies: + '@css-render/vue3-ssr': 0.15.14(vue@3.5.24(typescript@5.9.3)) + '@juggle/resize-observer': 3.4.0 + css-render: 0.15.14 + evtd: 0.2.4 + seemly: 0.3.10 + vdirs: 0.1.8(vue@3.5.24(typescript@5.9.3)) + vooks: 0.2.12(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@5.0.0: + dependencies: + isexe: 3.1.1 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + ws@8.18.3: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.0 + + xml-name-validator@4.0.0: {} + + xtend@4.0.2: {} + + yallist@3.1.1: {} + + yazl@2.5.1: + dependencies: + buffer-crc32: 0.2.13 + + yocto-queue@0.1.0: {} + + zrender@6.0.0: + dependencies: + tslib: 2.3.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..d3a3ea9 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,4 @@ +onlyBuiltDependencies: + - '@parcel/watcher' + - esbuild + - vue-demi diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f9f3edc2d847bf38acb25797c3a4afe3ac5e6b22 GIT binary patch literal 4286 zcmeHJJx>Bb5M8376e~kz2$d!N0<9>pF@_%^ogEqr3Kg`bv@tRM2OA210R@#N)=G_X zzIQU`utS=01$c;a4gd{+pY1V>XO2TQG#oE{yT;z}o*YTY;y` zS{_z~9XPC_Gq7HS?K^Oc6)kMVfujbr_VR+o{1g^=Y=n5U2aNk39P|5%liJMn@t!E` zZ48e2b%piug>i+eCve^>tk#!naG~;D`aP@*mg6}6GliA?JN4C`^!{D?OPMcqw7l#5 zrH)hHQ@<(9gj?6IYw6kes^T5SU|$rD_p{BT=Us&@1A7g-Q#sF*dF%12wyLn~3-;@S z!g9>mSDlc9c?(8Pa)~zQ)G7<7_6ir(N3Y8mIA?##y7s_E_m_^l#=l5k>d$()%&xx+ zBeAIdu5;EgXuYc%$Tj;eKhj#RF|>IvEMgDjjC$UsJx>f=srzpp-n7_7>4VqzewTNR zc)nAlFF2OC&(C}xxXu+kaqoB0%j%==1D7^q>YTD_#OC>QC9d>)DQe0dr1@$tadL(G z5*?ox9DMlvg=asA&eZpvkHe0W3zk)XAi3}Zn>)??kL&+b{nPZH^jDJ4(tok{k?M)L za7q2b9?Qy|A}_Ij!IAd)n^bdqJ=OC!sXoiL9;oB^a4knWZ?w1DjnALN?vFNChT~?3 f_G(N)EEqR~(B5_ei4B9G6IubDHkr%1k_ +import { useVersionCheckQuery } from './composables'; +import { GlobalFeedback } from '@/components'; +import { useSettingStore } from '@/stores'; +import { VueQueryDevtools } from '@tanstack/vue-query-devtools'; +import { dateZhCN, NConfigProvider, NDialogProvider, NLoadingBarProvider, NMessageProvider, NNotificationProvider, zhCN } from 'naive-ui'; +import { storeToRefs } from 'pinia'; + +const settingStore = useSettingStore(); +const { themeMode, offlineDev } = storeToRefs(settingStore); + +// 允许通过控制台启用离线开发模式 (登录页适用) +window.$offlineDev = offlineDev; + +useVersionCheckQuery(); + + + + + diff --git a/src/apis/client/index.ts b/src/apis/client/index.ts new file mode 100644 index 0000000..dcc9981 --- /dev/null +++ b/src/apis/client/index.ts @@ -0,0 +1,2 @@ +export * from './ndm-client'; +export * from './user-client'; diff --git a/src/apis/client/ndm-client.ts b/src/apis/client/ndm-client.ts new file mode 100644 index 0000000..9d1d4ed --- /dev/null +++ b/src/apis/client/ndm-client.ts @@ -0,0 +1,32 @@ +import { useUserStore } from '@/stores'; +import { getAppEnvConfig, RequestClient } from '@/utils'; +import type { AxiosError } from 'axios'; + +export const ndmClient = new RequestClient({ + requestInterceptor: async (config) => { + const userStore = useUserStore(); + const { lampAuthorization, lampClientId, lampClientSecret } = getAppEnvConfig(); + const newAuthorization = window.btoa(`${lampClientId}:${lampClientSecret}`); + const authorization = lampAuthorization.trim() !== '' ? lampAuthorization : newAuthorization; + config.headers.set('accept-language', 'zh-CN,zh;q=0.9'); + config.headers.set('accept', 'application/json, text/plain, */*'); + config.headers.set('Applicationid', ''); + config.headers.set('Tenantid', '1'); + config.headers.set('Authorization', authorization); + const staticCode = config.url?.split('/api').at(0)?.split('/').at(-1) ?? ''; + config.headers.set('token', userStore.lampLoginResultRecord?.[staticCode]?.token ?? ''); + return config; + }, + responseErrorInterceptor: async (error) => { + const err = error as AxiosError; + if (err.response?.status === 401) { + // 当车站请求由于token时效而失败时,需要重新登录车站获取token,然后重新请求 + const stationCode = err.config?.url?.split('/api').at(0)?.split('/').at(-1) ?? ''; + const userStore = useUserStore(); + await userStore.lampLogin(stationCode); + error.config.headers.token = userStore.lampLoginResultRecord?.[stationCode]?.token ?? ''; + return ndmClient.requestInstance(error.config); + } + return Promise.reject(error); + }, +}); diff --git a/src/apis/client/user-client.ts b/src/apis/client/user-client.ts new file mode 100644 index 0000000..014b719 --- /dev/null +++ b/src/apis/client/user-client.ts @@ -0,0 +1,33 @@ +import router from '@/router'; +import { useUserStore } from '@/stores'; +import { getAppEnvConfig, RequestClient } from '@/utils'; +import type { AxiosError } from 'axios'; + +export const userClient = new RequestClient({ + requestInterceptor: (config) => { + const userStore = useUserStore(); + const { lampAuthorization, lampClientId, lampClientSecret } = getAppEnvConfig(); + const newAuthorization = window.btoa(`${lampClientId}:${lampClientSecret}`); + const authorization = lampAuthorization.trim() !== '' ? lampAuthorization : newAuthorization; + config.headers.set('accept-language', 'zh-CN,zh;q=0.9'); + config.headers.set('accept', 'application/json, text/plain, */*'); + config.headers.set('Applicationid', ''); + config.headers.set('Tenantid', '1'); + config.headers.set('Authorization', authorization); + config.headers.set('token', userStore.userLoginResult?.token ?? ''); + return config; + }, + responseInterceptor: (response) => { + return response; + }, + responseErrorInterceptor: (error) => { + const err = error as AxiosError; + if (err.response?.status === 401) { + window.$message.error('登录超时,请重新登录'); + const userStore = useUserStore(); + userStore.resetStore(); + router.push({ path: '/login' }); + } + return Promise.reject(error); + }, +}); diff --git a/src/apis/domain/biz/diag/index.ts b/src/apis/domain/biz/diag/index.ts new file mode 100644 index 0000000..71d7c76 --- /dev/null +++ b/src/apis/domain/biz/diag/index.ts @@ -0,0 +1,6 @@ +export * from './ndm-camera-diag-info'; +export * from './ndm-decoder-diag-info'; +export * from './ndm-nvr-diag-info'; +export * from './ndm-security-box-diag-info'; +export * from './ndm-server-diag-info'; +export * from './ndm-switch-diag-info'; diff --git a/src/apis/domain/biz/diag/ndm-camera-diag-info.ts b/src/apis/domain/biz/diag/ndm-camera-diag-info.ts new file mode 100644 index 0000000..522b285 --- /dev/null +++ b/src/apis/domain/biz/diag/ndm-camera-diag-info.ts @@ -0,0 +1,5 @@ +export interface NdmCameraDiagInfo { + [key: string]: any; + logTime?: string; + info?: string; +} diff --git a/src/apis/domain/biz/diag/ndm-decoder-diag-info.ts b/src/apis/domain/biz/diag/ndm-decoder-diag-info.ts new file mode 100644 index 0000000..30444cf --- /dev/null +++ b/src/apis/domain/biz/diag/ndm-decoder-diag-info.ts @@ -0,0 +1,14 @@ +export interface NdmDecoderDiagInfo { + [key: string]: any; + logTime?: string; + stCommonInfo?: { + 设备ID?: string; + 软件版本?: string; + 设备厂商?: string; + 设备别名?: string; + 设备型号?: string; + 硬件版本?: string; + 内存使用率?: string; + CPU使用率?: string; + }; +} diff --git a/src/apis/domain/biz/diag/ndm-nvr-diag-info.ts b/src/apis/domain/biz/diag/ndm-nvr-diag-info.ts new file mode 100644 index 0000000..ce3cd4a --- /dev/null +++ b/src/apis/domain/biz/diag/ndm-nvr-diag-info.ts @@ -0,0 +1,31 @@ +export interface NdmNvrDiagInfo { + [key: string]: any; + logTime?: string; + info?: { + diskHealth?: number[]; + groupInfoList?: { + freeSize?: number; + state?: number; + stateValue?: string; + totalSize?: number; + }[]; + }; + stCommonInfo?: { + 设备ID?: string; + 软件版本?: string; + 生产厂商?: string; + 设备别名?: string; + 设备型号?: string; + 硬件版本?: string; + 内存使用率?: string; + CPU使用率?: string; + }; + cdFanInfo?: { + 索引号?: string; + '风扇转速(rpm)'?: string; + }[]; + cdPowerSupplyInfo?: { + 索引号?: string; + 电源状态?: string; + }[]; +} diff --git a/src/apis/domain/biz/diag/ndm-security-box-diag-info.ts b/src/apis/domain/biz/diag/ndm-security-box-diag-info.ts new file mode 100644 index 0000000..3798678 --- /dev/null +++ b/src/apis/domain/biz/diag/ndm-security-box-diag-info.ts @@ -0,0 +1,24 @@ +export interface NdmSecurityBoxDiagInfo { + [key: string]: any; + info?: [ + { + addrCode?: number; + circuits?: NdmSecurityBoxCircuit[]; + fanSpeeds?: number[]; + humidity?: number; + switches?: [number, number, number, number]; + temperature?: number; + }, + ]; + stCommonInfo?: { + [key: string]: any; + 内存使用率?: string; + CPU使用率?: string; + }; +} + +export interface NdmSecurityBoxCircuit { + current: number; + status: number; + voltage: number; +} diff --git a/src/apis/domain/biz/diag/ndm-server-diag-info.ts b/src/apis/domain/biz/diag/ndm-server-diag-info.ts new file mode 100644 index 0000000..38d7a26 --- /dev/null +++ b/src/apis/domain/biz/diag/ndm-server-diag-info.ts @@ -0,0 +1,9 @@ +export interface NdmServerDiagInfo { + [key: string]: any; + commInfo?: { + CPU使用率?: string; + 内存使用率?: string; + 磁盘使用率?: string; + 系统运行时间?: string; + }; +} diff --git a/src/apis/domain/biz/diag/ndm-switch-diag-info.ts b/src/apis/domain/biz/diag/ndm-switch-diag-info.ts new file mode 100644 index 0000000..aea0e4f --- /dev/null +++ b/src/apis/domain/biz/diag/ndm-switch-diag-info.ts @@ -0,0 +1,22 @@ +export interface NdmSwitchDiagInfo { + [key: string]: any; + cpuRatio?: string; // 因环境不同可能不存在 + memoryRatio?: string; // 因环境不同可能不存在 + logTime?: string; + info?: { + overFlowPorts?: string[]; + portInfoList?: NdmSwitchPortInfo[]; + }; +} + +export interface NdmSwitchPortInfo { + flow: number; + inBytes: number; + inFlow: number; + lastInBytes: number; + lastOutBytes: number; + outBytes: number; + outFlow: number; + portName: string; + upDown: number; +} diff --git a/src/apis/domain/biz/index.ts b/src/apis/domain/biz/index.ts new file mode 100644 index 0000000..7952147 --- /dev/null +++ b/src/apis/domain/biz/index.ts @@ -0,0 +1,2 @@ +export * from './diag'; +export * from './station'; diff --git a/src/apis/domain/biz/station/alarm.ts b/src/apis/domain/biz/station/alarm.ts new file mode 100644 index 0000000..0f754be --- /dev/null +++ b/src/apis/domain/biz/station/alarm.ts @@ -0,0 +1,35 @@ +import type { NdmDeviceAlarmLogResultVO } from '@/apis/model'; +import { DEVICE_TYPE_LITERALS } from '@/enums'; +import type { Station } from './station'; + +export interface StationAlarms { + [DEVICE_TYPE_LITERALS.ndmAlarmHost]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmCamera]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmDecoder]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmKeyboard]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmMediaServer]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmNvr]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmSecurityBox]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmSwitch]: NdmDeviceAlarmLogResultVO[]; + [DEVICE_TYPE_LITERALS.ndmVideoServer]: NdmDeviceAlarmLogResultVO[]; + unclassified: NdmDeviceAlarmLogResultVO[]; +} + +export interface LineAlarms { + [stationCode: Station['code']]: StationAlarms; +} + +export const initStationAlarms = (): StationAlarms => { + return { + [DEVICE_TYPE_LITERALS.ndmAlarmHost]: [], + [DEVICE_TYPE_LITERALS.ndmCamera]: [], + [DEVICE_TYPE_LITERALS.ndmDecoder]: [], + [DEVICE_TYPE_LITERALS.ndmKeyboard]: [], + [DEVICE_TYPE_LITERALS.ndmMediaServer]: [], + [DEVICE_TYPE_LITERALS.ndmNvr]: [], + [DEVICE_TYPE_LITERALS.ndmSecurityBox]: [], + [DEVICE_TYPE_LITERALS.ndmSwitch]: [], + [DEVICE_TYPE_LITERALS.ndmVideoServer]: [], + unclassified: [], + }; +}; diff --git a/src/apis/domain/biz/station/device.ts b/src/apis/domain/biz/station/device.ts new file mode 100644 index 0000000..fe94cef --- /dev/null +++ b/src/apis/domain/biz/station/device.ts @@ -0,0 +1,43 @@ +import type { + NdmAlarmHostResultVO, + NdmCameraResultVO, + NdmDecoderResultVO, + NdmKeyboardResultVO, + NdmMediaServerResultVO, + NdmNvrResultVO, + NdmSecurityBoxResultVO, + NdmSwitchResultVO, + NdmVideoServerResultVO, + Station, +} from '@/apis'; +import { DEVICE_TYPE_LITERALS } from '@/enums'; + +export interface StationDevices { + [DEVICE_TYPE_LITERALS.ndmAlarmHost]: NdmAlarmHostResultVO[]; + [DEVICE_TYPE_LITERALS.ndmCamera]: NdmCameraResultVO[]; + [DEVICE_TYPE_LITERALS.ndmDecoder]: NdmDecoderResultVO[]; + [DEVICE_TYPE_LITERALS.ndmKeyboard]: NdmKeyboardResultVO[]; + [DEVICE_TYPE_LITERALS.ndmMediaServer]: NdmMediaServerResultVO[]; + [DEVICE_TYPE_LITERALS.ndmNvr]: NdmNvrResultVO[]; + [DEVICE_TYPE_LITERALS.ndmSecurityBox]: NdmSecurityBoxResultVO[]; + [DEVICE_TYPE_LITERALS.ndmSwitch]: NdmSwitchResultVO[]; + [DEVICE_TYPE_LITERALS.ndmVideoServer]: NdmVideoServerResultVO[]; +} + +export interface LineDevices { + [stationCode: Station['code']]: StationDevices; +} + +export const initStationDevices = (): StationDevices => { + return { + [DEVICE_TYPE_LITERALS.ndmAlarmHost]: [], + [DEVICE_TYPE_LITERALS.ndmCamera]: [], + [DEVICE_TYPE_LITERALS.ndmDecoder]: [], + [DEVICE_TYPE_LITERALS.ndmKeyboard]: [], + [DEVICE_TYPE_LITERALS.ndmMediaServer]: [], + [DEVICE_TYPE_LITERALS.ndmNvr]: [], + [DEVICE_TYPE_LITERALS.ndmSecurityBox]: [], + [DEVICE_TYPE_LITERALS.ndmSwitch]: [], + [DEVICE_TYPE_LITERALS.ndmVideoServer]: [], + }; +}; diff --git a/src/apis/domain/biz/station/index.ts b/src/apis/domain/biz/station/index.ts new file mode 100644 index 0000000..771a0cc --- /dev/null +++ b/src/apis/domain/biz/station/index.ts @@ -0,0 +1,3 @@ +export * from './alarm'; +export * from './device'; +export * from './station'; diff --git a/src/apis/domain/biz/station/station.ts b/src/apis/domain/biz/station/station.ts new file mode 100644 index 0000000..5113778 --- /dev/null +++ b/src/apis/domain/biz/station/station.ts @@ -0,0 +1,6 @@ +export interface Station { + code: string; + name: string; + online: boolean; + ip: string; +} diff --git a/src/apis/domain/index.ts b/src/apis/domain/index.ts new file mode 100644 index 0000000..6007978 --- /dev/null +++ b/src/apis/domain/index.ts @@ -0,0 +1,3 @@ +export * from './biz'; +export * from './user'; +export * from './version'; diff --git a/src/apis/domain/user/index.ts b/src/apis/domain/user/index.ts new file mode 100644 index 0000000..4accf30 --- /dev/null +++ b/src/apis/domain/user/index.ts @@ -0,0 +1,2 @@ +export * from './login-params'; +export * from './login-result'; diff --git a/src/apis/domain/user/login-params.ts b/src/apis/domain/user/login-params.ts new file mode 100644 index 0000000..822f283 --- /dev/null +++ b/src/apis/domain/user/login-params.ts @@ -0,0 +1,8 @@ +export interface LoginParams { + username: string; + password: string; + code: string; + key: string; + grantType: 'PASSWORD' | 'CAPTCHA' | 'REFRESH_TOKEN'; + refreshToken?: string; +} diff --git a/src/apis/domain/user/login-result.ts b/src/apis/domain/user/login-result.ts new file mode 100644 index 0000000..08ffe74 --- /dev/null +++ b/src/apis/domain/user/login-result.ts @@ -0,0 +1,8 @@ +export interface LoginResult { + tenantId: string; + uuid: string; + token: string; + refreshToken: string; + expire: string; + expiration: string; +} diff --git a/src/apis/domain/version/index.ts b/src/apis/domain/version/index.ts new file mode 100644 index 0000000..bab4781 --- /dev/null +++ b/src/apis/domain/version/index.ts @@ -0,0 +1 @@ +export * from './version-info'; diff --git a/src/apis/domain/version/version-info.ts b/src/apis/domain/version/version-info.ts new file mode 100644 index 0000000..179d1aa --- /dev/null +++ b/src/apis/domain/version/version-info.ts @@ -0,0 +1,4 @@ +export interface VersionInfo { + version: string; + buildTime: string; +} diff --git a/src/apis/index.ts b/src/apis/index.ts new file mode 100644 index 0000000..de109ef --- /dev/null +++ b/src/apis/index.ts @@ -0,0 +1,4 @@ +export * from './client'; +export * from './domain'; +export * from './model'; +export * from './request'; diff --git a/src/apis/model/base/index.ts b/src/apis/model/base/index.ts new file mode 100644 index 0000000..196d27e --- /dev/null +++ b/src/apis/model/base/index.ts @@ -0,0 +1,3 @@ +export * from './model'; +export * from './page'; +export * from './reduce'; diff --git a/src/apis/model/base/model.ts b/src/apis/model/base/model.ts new file mode 100644 index 0000000..cddd42d --- /dev/null +++ b/src/apis/model/base/model.ts @@ -0,0 +1,18 @@ +export interface SuperModel { + id: string; + createdBy: string; + createdTime: string; + echoMap?: any; +} + +export interface BaseModel extends SuperModel { + updatedBy: string; + updatedTime: string; +} + +export interface TreeModel extends BaseModel { + parentId: string; + sortValue: number; + treeGrade: number; + treePath: string; +} diff --git a/src/apis/model/base/page.ts b/src/apis/model/base/page.ts new file mode 100644 index 0000000..b93a8de --- /dev/null +++ b/src/apis/model/base/page.ts @@ -0,0 +1,43 @@ +import type { BaseModel } from './model'; + +export interface BasicPageParams { + page: number; + pageSize: number; +} + +export interface BasicFetchResult { + items: T[]; + total: number; +} + +export interface RemoteData { + key: string | number; + data?: any; +} + +export type PageQueryExtraKeyPrefix = keyof T & string; +export type PageQueryExtraKeySuffix = 'in' | 'like' | 'likeLeft' | 'likeRight' | 'ge' | 'le' | 'precisest' | 'preciseed'; +export type PageQueryExtraKey = `${PageQueryExtraKeyPrefix}_${PageQueryExtraKeySuffix}`; +// export type PageQueryExtra = Partial, any>>; +export type PageQueryExtra = { + [K in PageQueryExtraKey]?: any; +}; + +export interface PageParams { + model: T; + size: number; + current: number; + sort?: keyof T & string; + order?: 'ascending' | 'descending'; + extra?: PageQueryExtra; +} + +export interface PageResult { + records: T[]; + // offset: number + pages: string; + current: string; + total: string; + size: string; + orders: any[]; +} diff --git a/src/apis/model/base/reduce.ts b/src/apis/model/base/reduce.ts new file mode 100644 index 0000000..63764a9 --- /dev/null +++ b/src/apis/model/base/reduce.ts @@ -0,0 +1,3 @@ +export type ReduceForUpdateVO = 'createdTime' | 'createdBy' | 'updatedTime' | 'updatedBy' | 'echoMap'; +export type ReduceForSaveVO = ReduceForUpdateVO | 'id'; +export type ReduceForPageQuery = ReduceForUpdateVO; diff --git a/src/apis/model/biz/entity/alarm/index.ts b/src/apis/model/biz/entity/alarm/index.ts new file mode 100644 index 0000000..8e1b71a --- /dev/null +++ b/src/apis/model/biz/entity/alarm/index.ts @@ -0,0 +1 @@ +export * from './ndm-alarm-host'; diff --git a/src/apis/model/biz/entity/alarm/ndm-alarm-host.ts b/src/apis/model/biz/entity/alarm/ndm-alarm-host.ts new file mode 100644 index 0000000..5a30073 --- /dev/null +++ b/src/apis/model/biz/entity/alarm/ndm-alarm-host.ts @@ -0,0 +1,39 @@ +import type { BaseModel, ReduceForPageQuery, ReduceForSaveVO, ReduceForUpdateVO } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmAlarmHost extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + gbCode: string; + gbPort: number; + gbDomain: string; + gb28181Enabled: boolean; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmAlarmHostResultVO = Nullable; + +export type NdmAlarmHostSaveVO = Partial>; + +export type NdmAlarmHostUpdateVO = Optional>; + +export type NdmAlarmHostPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/icmp/icmp-entity-result.ts b/src/apis/model/biz/entity/icmp/icmp-entity-result.ts new file mode 100644 index 0000000..31e60db --- /dev/null +++ b/src/apis/model/biz/entity/icmp/icmp-entity-result.ts @@ -0,0 +1,11 @@ +import type { IcmpEntity } from './icmp-entity'; + +export interface IcmpEntityResult { + name: string; + ipAddress: string; + stationCode: string; + url: string; + success: boolean; + icmpEntities: IcmpEntity[]; + errorMessage: string; +} diff --git a/src/apis/model/biz/entity/icmp/icmp-entity-with-station.ts b/src/apis/model/biz/entity/icmp/icmp-entity-with-station.ts new file mode 100644 index 0000000..4a58baf --- /dev/null +++ b/src/apis/model/biz/entity/icmp/icmp-entity-with-station.ts @@ -0,0 +1,9 @@ +export interface IcmpEntityWithStation { + id: string; + deviceId: string; + name: string; + ipAddress: string; + deviceStatus: string; + deviceType: string; + stationName: string; +} diff --git a/src/apis/model/biz/entity/icmp/icmp-entity.ts b/src/apis/model/biz/entity/icmp/icmp-entity.ts new file mode 100644 index 0000000..f07cfc3 --- /dev/null +++ b/src/apis/model/biz/entity/icmp/icmp-entity.ts @@ -0,0 +1,8 @@ +export interface IcmpEntity { + id: string; + deviceId: string; + name: string; + ipAddress: string; + deviceStatus: string; + deviceType: string; +} diff --git a/src/apis/model/biz/entity/icmp/index.ts b/src/apis/model/biz/entity/icmp/index.ts new file mode 100644 index 0000000..05b54fa --- /dev/null +++ b/src/apis/model/biz/entity/icmp/index.ts @@ -0,0 +1,3 @@ +export * from './icmp-entity'; +export * from './icmp-entity-result'; +export * from './icmp-entity-with-station'; diff --git a/src/apis/model/biz/entity/index.ts b/src/apis/model/biz/entity/index.ts new file mode 100644 index 0000000..b75a782 --- /dev/null +++ b/src/apis/model/biz/entity/index.ts @@ -0,0 +1,37 @@ +import type { Nullable } from '@/types'; +import type { NdmAlarmHost } from './alarm'; +import type { NdmSecurityBox, NdmSwitch } from './other'; +import type { NdmNvr } from './storage'; +import type { + NdmCamera, + NdmDecoder, + NdmKeyboard, + NdmMediaServer, + NdmMediaServerPageQuery, + NdmMediaServerResultVO, + NdmMediaServerSaveVO, + NdmMediaServerUpdateVO, + NdmVideoServer, + NdmVideoServerPageQuery, + NdmVideoServerResultVO, + NdmVideoServerSaveVO, + NdmVideoServerUpdateVO, +} from './video'; + +export type NdmDevice = NdmAlarmHost | NdmCamera | NdmDecoder | NdmKeyboard | NdmMediaServer | NdmNvr | NdmSecurityBox | NdmSwitch | NdmVideoServer; + +export type NdmDeviceResultVO = Nullable; + +export type NdmServer = NdmMediaServer | NdmVideoServer; +export type NdmServerResultVO = NdmMediaServerResultVO | NdmVideoServerResultVO; +export type NdmServerSaveVO = NdmMediaServerSaveVO | NdmVideoServerSaveVO; +export type NdmServerUpdateVO = NdmMediaServerUpdateVO | NdmVideoServerUpdateVO; +export type NdmServerPageQuery = NdmMediaServerPageQuery | NdmVideoServerPageQuery; + +export * from './alarm'; +export * from './icmp'; +export * from './log'; +export * from './other'; +export * from './storage'; +export * from './upper-ndm'; +export * from './video'; diff --git a/src/apis/model/biz/entity/log/index.ts b/src/apis/model/biz/entity/log/index.ts new file mode 100644 index 0000000..9868bd2 --- /dev/null +++ b/src/apis/model/biz/entity/log/index.ts @@ -0,0 +1,6 @@ +export * from './ndm-call-log'; +export * from './ndm-device-alarm-log'; +export * from './ndm-icmp-log'; +export * from './ndm-record-check'; +export * from './ndm-snmp-log'; +export * from './ndm-vimp-log'; diff --git a/src/apis/model/biz/entity/log/ndm-call-log.ts b/src/apis/model/biz/entity/log/ndm-call-log.ts new file mode 100644 index 0000000..05f1db9 --- /dev/null +++ b/src/apis/model/biz/entity/log/ndm-call-log.ts @@ -0,0 +1,18 @@ +import type { BaseModel, ReduceForPageQuery, ReduceForSaveVO, ReduceForUpdateVO } from '@/apis'; +import type { Nullable } from '@/types'; + +export interface NdmCallLog extends BaseModel { + sourceGbId: string; + targetGbId: string; + method: string; + messageType: string; + cmdType: string; +} + +export type NdmCallLogResultVO = Nullable; + +export type NdmCallLogSaveVO = Partial>; + +export type NdmCallLogUpdateVO = Partial>; + +export type NdmCallLogPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/log/ndm-device-alarm-log.ts b/src/apis/model/biz/entity/log/ndm-device-alarm-log.ts new file mode 100644 index 0000000..011a2d8 --- /dev/null +++ b/src/apis/model/biz/entity/log/ndm-device-alarm-log.ts @@ -0,0 +1,28 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable } from '@/types'; + +export interface NdmDeviceAlarmLog extends BaseModel { + alarmNo: string; + alarmDate: string; + faultLocation: string; + faultDescription: string; + faultLevel: string; + faultCode: string; + deviceId: string; + deviceName: string; + alarmCategory: string; + alarmConfirm: string; + alarmRepairSuggestion: string; + impactService: string; + alarmType: string; + deviceType: string; + stationCode: string; +} + +export type NdmDeviceAlarmLogResultVO = Nullable; + +export type NdmDeviceAlarmLogSaveVO = Partial>; + +export type NdmDeviceAlarmLogUpdateVO = Partial>; + +export type NdmDeviceAlarmLogPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/log/ndm-icmp-log.ts b/src/apis/model/biz/entity/log/ndm-icmp-log.ts new file mode 100644 index 0000000..cd93fe8 --- /dev/null +++ b/src/apis/model/biz/entity/log/ndm-icmp-log.ts @@ -0,0 +1,17 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable } from '@/types'; + +export interface NdmIcmpLog extends BaseModel { + deviceId: string; + name: string; + ipAddress: string; + deviceStatus: string; +} + +export type NdmIcmpLogResultVO = Nullable; + +export type NdmIcmpLogSaveVO = Partial>; + +export type NdmIcmpLogUpdateVO = Partial>; + +export type NdmIcmpLogPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/log/ndm-record-check.ts b/src/apis/model/biz/entity/log/ndm-record-check.ts new file mode 100644 index 0000000..212fa03 --- /dev/null +++ b/src/apis/model/biz/entity/log/ndm-record-check.ts @@ -0,0 +1,8 @@ +export interface NdmRecordCheck { + gbCode: string; + parentGbCode: string; + name: string; + ipAddress: string; + diagInfo: string; + checkDate: string; +} diff --git a/src/apis/model/biz/entity/log/ndm-snmp-log.ts b/src/apis/model/biz/entity/log/ndm-snmp-log.ts new file mode 100644 index 0000000..181f1ba --- /dev/null +++ b/src/apis/model/biz/entity/log/ndm-snmp-log.ts @@ -0,0 +1,18 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable } from '@/types'; + +export interface NdmSnmpLog extends BaseModel { + deviceId: string; + name: string; + ipAddress: string; + diagInfo: string; + deviceType: string; +} + +export type NdmSnmpLogResultVO = Nullable; + +export type NdmSnmpLogSaveVO = Partial>; + +export type NdmSnmpLogUpdateVO = Partial>; + +export type NdmSnmpLogPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/log/ndm-vimp-log.ts b/src/apis/model/biz/entity/log/ndm-vimp-log.ts new file mode 100644 index 0000000..ad17253 --- /dev/null +++ b/src/apis/model/biz/entity/log/ndm-vimp-log.ts @@ -0,0 +1,26 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable } from '@/types'; + +export interface NdmVimpLog extends BaseModel { + requestIp: string; + description: string; + classPath: string; + methodName: string; + startTime: string; + endTime: string; + consumedTime: string; + params: string; + result: string; + httpMethod: string; + userId: string; + logType: number; + targetCode: string; +} + +export type NdmVimpLogResultVO = Nullable; + +export type NdmVimpLogSaveVO = Partial>; + +export type NdmVimpLogUpdateVO = Partial>; + +export type NdmVimpLogPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/other/index.ts b/src/apis/model/biz/entity/other/index.ts new file mode 100644 index 0000000..7ac828d --- /dev/null +++ b/src/apis/model/biz/entity/other/index.ts @@ -0,0 +1,2 @@ +export * from './ndm-security-box'; +export * from './ndm-switch'; diff --git a/src/apis/model/biz/entity/other/ndm-security-box.ts b/src/apis/model/biz/entity/other/ndm-security-box.ts new file mode 100644 index 0000000..51ab9e0 --- /dev/null +++ b/src/apis/model/biz/entity/other/ndm-security-box.ts @@ -0,0 +1,35 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmSecurityBox extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmSecurityBoxResultVO = Nullable; + +export type NdmSecurityBoxSaveVO = Partial>; + +export type NdmSecurityBoxUpdateVO = Optional>; + +export type NdmSecurityBoxPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/other/ndm-switch.ts b/src/apis/model/biz/entity/other/ndm-switch.ts new file mode 100644 index 0000000..169269a --- /dev/null +++ b/src/apis/model/biz/entity/other/ndm-switch.ts @@ -0,0 +1,35 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmSwitch extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmSwitchResultVO = Nullable; + +export type NdmSwitchSaveVO = Partial>; + +export type NdmSwitchUpdateVO = Optional>; + +export type NdmSwitchPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/storage/index.ts b/src/apis/model/biz/entity/storage/index.ts new file mode 100644 index 0000000..d564e7c --- /dev/null +++ b/src/apis/model/biz/entity/storage/index.ts @@ -0,0 +1 @@ +export * from './ndm-nvr'; diff --git a/src/apis/model/biz/entity/storage/ndm-nvr.ts b/src/apis/model/biz/entity/storage/ndm-nvr.ts new file mode 100644 index 0000000..0dd2f7d --- /dev/null +++ b/src/apis/model/biz/entity/storage/ndm-nvr.ts @@ -0,0 +1,46 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmNvr extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + gbCode: string; + gbPort: number; + gbDomain: string; + gb28181Enabled: boolean; + onvifPort: number; + onvifUsername: string; + onvifPassword: string; + onvifMajorIndex: number; + onvifMinorIndex: number; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; + recordCheckEnabled: boolean; + clusterList: string; +} + +export type NdmNvrResultVO = Nullable; + +export type NdmNvrSaveVO = Partial>; + +export type NdmNvrUpdateVO = Optional>; + +export type NdmNvrPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/upper-ndm/index.ts b/src/apis/model/biz/entity/upper-ndm/index.ts new file mode 100644 index 0000000..f40cabb --- /dev/null +++ b/src/apis/model/biz/entity/upper-ndm/index.ts @@ -0,0 +1,2 @@ +export * from './sync-camera-result'; +export * from './sync-camera-result-detail'; diff --git a/src/apis/model/biz/entity/upper-ndm/sync-camera-result-detail.ts b/src/apis/model/biz/entity/upper-ndm/sync-camera-result-detail.ts new file mode 100644 index 0000000..3247e33 --- /dev/null +++ b/src/apis/model/biz/entity/upper-ndm/sync-camera-result-detail.ts @@ -0,0 +1,6 @@ +export interface SyncCameraResultDetail { + name: string; + deviceId: string; + ipAddress: string; + gbCode: string; +} diff --git a/src/apis/model/biz/entity/upper-ndm/sync-camera-result.ts b/src/apis/model/biz/entity/upper-ndm/sync-camera-result.ts new file mode 100644 index 0000000..c311888 --- /dev/null +++ b/src/apis/model/biz/entity/upper-ndm/sync-camera-result.ts @@ -0,0 +1,10 @@ +import type { SyncCameraResultDetail } from './sync-camera-result-detail'; + +export interface SyncCameraResult { + stationCode: string; + startTime: string; + endTime: string; + insertList: SyncCameraResultDetail[]; + updateList: SyncCameraResultDetail[]; + deleteList: SyncCameraResultDetail[]; +} diff --git a/src/apis/model/biz/entity/video/index.ts b/src/apis/model/biz/entity/video/index.ts new file mode 100644 index 0000000..4a25f3b --- /dev/null +++ b/src/apis/model/biz/entity/video/index.ts @@ -0,0 +1,6 @@ +export * from './ndm-camera'; +export * from './ndm-camera-ignore'; +export * from './ndm-decoder'; +export * from './ndm-keyboard'; +export * from './ndm-media-server'; +export * from './ndm-video-server'; diff --git a/src/apis/model/biz/entity/video/ndm-camera-ignore.ts b/src/apis/model/biz/entity/video/ndm-camera-ignore.ts new file mode 100644 index 0000000..af4204a --- /dev/null +++ b/src/apis/model/biz/entity/video/ndm-camera-ignore.ts @@ -0,0 +1,14 @@ +import type { BaseModel, ReduceForPageQuery, ReduceForSaveVO, ReduceForUpdateVO } from '@/apis'; + +export interface NdmCameraIgnore extends BaseModel { + deviceId: string; + ignoreType: string; +} + +export type NdmCameraIgnoreResultVO = Partial; + +export type NdmCameraIgnoreSaveVO = Partial>; + +export type NdmCameraIgnoreUpdateVO = Partial>; + +export type NdmCameraIgnorePageQuery = Partial>; diff --git a/src/apis/model/biz/entity/video/ndm-camera.ts b/src/apis/model/biz/entity/video/ndm-camera.ts new file mode 100644 index 0000000..cde06be --- /dev/null +++ b/src/apis/model/biz/entity/video/ndm-camera.ts @@ -0,0 +1,45 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmCamera extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + gbCode: string; + gbPort: number; + gbDomain: string; + gb28181Enabled: boolean; + onvifPort: number; + onvifUsername: string; + onvifPassword: string; + onvifMajorIndex: number; + onvifMinorIndex: number; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + cameraType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmCameraResultVO = Nullable; + +export type NdmCameraSaveVO = Partial>; + +export type NdmCameraUpdateVO = Optional>; + +export type NdmCameraPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/video/ndm-decoder.ts b/src/apis/model/biz/entity/video/ndm-decoder.ts new file mode 100644 index 0000000..cd7e192 --- /dev/null +++ b/src/apis/model/biz/entity/video/ndm-decoder.ts @@ -0,0 +1,42 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmDecoder extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + gbCode: string; + gbPort: number; + gbDomain: string; + gb28181Enabled: boolean; + onvifPort: number; + onvifUsername: string; + onvifPassword: string; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmDecoderResultVO = Nullable; + +export type NdmDecoderSaveVO = Partial>; + +export type NdmDecoderUpdateVO = Optional>; + +export type NdmDecoderPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/video/ndm-keyboard.ts b/src/apis/model/biz/entity/video/ndm-keyboard.ts new file mode 100644 index 0000000..fa8278d --- /dev/null +++ b/src/apis/model/biz/entity/video/ndm-keyboard.ts @@ -0,0 +1,35 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmKeyboard extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmKeyboardResultVO = Nullable; + +export type NdmKeyboardSaveVO = Partial>; + +export type NdmKeyboardUpdateVO = Optional>; + +export type NdmKeyboardPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/video/ndm-media-server.ts b/src/apis/model/biz/entity/video/ndm-media-server.ts new file mode 100644 index 0000000..83b558d --- /dev/null +++ b/src/apis/model/biz/entity/video/ndm-media-server.ts @@ -0,0 +1,39 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmMediaServer extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + gbCode: string; + gbPort: number; + gbDomain: string; + gb28181Enabled: boolean; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmMediaServerResultVO = Nullable; + +export type NdmMediaServerSaveVO = Partial>; + +export type NdmMediaServerUpdateVO = Optional>; + +export type NdmMediaServerPageQuery = Partial>; diff --git a/src/apis/model/biz/entity/video/ndm-video-server.ts b/src/apis/model/biz/entity/video/ndm-video-server.ts new file mode 100644 index 0000000..208969a --- /dev/null +++ b/src/apis/model/biz/entity/video/ndm-video-server.ts @@ -0,0 +1,39 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable, Optional } from '@/types'; + +export interface NdmVideoServer extends BaseModel { + deviceId: string; + name: string; + manufacturer: string; + state: boolean; + model: string; + ipAddress: string; + manageUrl: string; + manageUsername: string; + managePassword: string; + gbCode: string; + gbPort: number; + gbDomain: string; + gb28181Enabled: boolean; + diagFlag: string; + diagParam: string; + diagFormat: string; + lastDiagInfo: string; + lastDiagTime: string; + icmpEnabled: boolean; + description: string; + deviceStatus: string; + deviceType: string; + community: string; + frontendConfig: string; + linkDescription: string; + snmpEnabled: boolean; +} + +export type NdmVideoServerResultVO = Nullable; + +export type NdmVideoServerSaveVO = Partial>; + +export type NdmVideoServerUpdateVO = Optional>; + +export type NdmVideoServerPageQuery = Partial>; diff --git a/src/apis/model/biz/index.ts b/src/apis/model/biz/index.ts new file mode 100644 index 0000000..c4454f2 --- /dev/null +++ b/src/apis/model/biz/index.ts @@ -0,0 +1,4 @@ +export * from './entity'; +export * from './nvr'; +export * from './verify'; +export * from './vimp'; diff --git a/src/apis/model/biz/nvr/client-channel.ts b/src/apis/model/biz/nvr/client-channel.ts new file mode 100644 index 0000000..5e6d60b --- /dev/null +++ b/src/apis/model/biz/nvr/client-channel.ts @@ -0,0 +1,15 @@ +export interface ClientChannel { + code: string; + name: string; + manufacture: string; + model: string; + owner: string; + civilCode: string; + block: string; + address: string; + parental: number; + parentId: string; + status: number; + longitude: number; + latitude: number; +} diff --git a/src/apis/model/biz/nvr/index.ts b/src/apis/model/biz/nvr/index.ts new file mode 100644 index 0000000..5db1448 --- /dev/null +++ b/src/apis/model/biz/nvr/index.ts @@ -0,0 +1,3 @@ +export * from './client-channel'; +export * from './record-info'; +export * from './record-item'; diff --git a/src/apis/model/biz/nvr/record-info.ts b/src/apis/model/biz/nvr/record-info.ts new file mode 100644 index 0000000..cd08684 --- /dev/null +++ b/src/apis/model/biz/nvr/record-info.ts @@ -0,0 +1,12 @@ +import type { RecordItem } from './record-item'; + +export interface RecordInfo { + deviceId: string; + channelId: string; + sn: string; + name: string; + sumNum: number; + count: number; + lastTime: number; + recordList: RecordItem[]; +} diff --git a/src/apis/model/biz/nvr/record-item.ts b/src/apis/model/biz/nvr/record-item.ts new file mode 100644 index 0000000..5f3457f --- /dev/null +++ b/src/apis/model/biz/nvr/record-item.ts @@ -0,0 +1,4 @@ +export interface RecordItem { + startTime: string; + endTime: string; +} diff --git a/src/apis/model/biz/verify/index.ts b/src/apis/model/biz/verify/index.ts new file mode 100644 index 0000000..b74d8b9 --- /dev/null +++ b/src/apis/model/biz/verify/index.ts @@ -0,0 +1 @@ +export * from './verify-server'; diff --git a/src/apis/model/biz/verify/verify-server.ts b/src/apis/model/biz/verify/verify-server.ts new file mode 100644 index 0000000..6222675 --- /dev/null +++ b/src/apis/model/biz/verify/verify-server.ts @@ -0,0 +1,7 @@ +export interface VerifyServer { + name: string; + ipAddress: string; + stationCode: string; + verifyUrl: string; + onlineState: boolean; +} diff --git a/src/apis/model/biz/vimp/index.ts b/src/apis/model/biz/vimp/index.ts new file mode 100644 index 0000000..29a8dc2 --- /dev/null +++ b/src/apis/model/biz/vimp/index.ts @@ -0,0 +1 @@ +export * from './snap-result'; diff --git a/src/apis/model/biz/vimp/snap-result.ts b/src/apis/model/biz/vimp/snap-result.ts new file mode 100644 index 0000000..81aa63c --- /dev/null +++ b/src/apis/model/biz/vimp/snap-result.ts @@ -0,0 +1,5 @@ +export interface SnapResult { + absoluteFilePath: string; + path: string; + url: string; +} diff --git a/src/apis/model/index.ts b/src/apis/model/index.ts new file mode 100644 index 0000000..10cbc67 --- /dev/null +++ b/src/apis/model/index.ts @@ -0,0 +1,3 @@ +export * from './base'; +export * from './biz'; +export * from './system'; diff --git a/src/apis/model/system/def-parameter.ts b/src/apis/model/system/def-parameter.ts new file mode 100644 index 0000000..88f969e --- /dev/null +++ b/src/apis/model/system/def-parameter.ts @@ -0,0 +1,18 @@ +import type { BaseModel, ReduceForSaveVO, ReduceForUpdateVO, ReduceForPageQuery } from '@/apis'; +import type { Nullable } from '@/types'; + +export interface DefParameter extends BaseModel { + key: string; + value: string; + name: string; + remarks: string; + paramType: string; +} + +export type DefParameterResultVO = Nullable; + +export type DefParameterSaveVO = Partial>; + +export type DefParameterUpdateVO = Partial>; + +export type DefParameterPageQuery = Partial>; diff --git a/src/apis/model/system/index.ts b/src/apis/model/system/index.ts new file mode 100644 index 0000000..28a74a0 --- /dev/null +++ b/src/apis/model/system/index.ts @@ -0,0 +1 @@ +export * from './def-parameter'; diff --git a/src/apis/request/biz/alarm/index.ts b/src/apis/request/biz/alarm/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/apis/request/biz/alarm/ndm-alarm-host.ts b/src/apis/request/biz/alarm/ndm-alarm-host.ts new file mode 100644 index 0000000..262e621 --- /dev/null +++ b/src/apis/request/biz/alarm/ndm-alarm-host.ts @@ -0,0 +1,71 @@ +import { + ndmClient, + userClient, + type NdmAlarmHostPageQuery, + type NdmAlarmHostResultVO, + type NdmAlarmHostSaveVO, + type NdmAlarmHostUpdateVO, + type PageParams, + type PageResult, + type Station, +} from '@/apis'; + +export const pageAlarmHostApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmAlarmHost/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailAlarmHostApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmAlarmHost/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveAlarmHostApi = async (saveVO: NdmAlarmHostSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmAlarmHost`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateAlarmHostApi = async (updateVO: NdmAlarmHostUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmAlarmHost`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteAlarmHostApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmAlarmHost`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/all/index.ts b/src/apis/request/biz/all/index.ts new file mode 100644 index 0000000..b028008 --- /dev/null +++ b/src/apis/request/biz/all/index.ts @@ -0,0 +1 @@ +export * from './ndm-devices'; diff --git a/src/apis/request/biz/all/ndm-devices.ts b/src/apis/request/biz/all/ndm-devices.ts new file mode 100644 index 0000000..709b657 --- /dev/null +++ b/src/apis/request/biz/all/ndm-devices.ts @@ -0,0 +1,13 @@ +import { ndmClient, userClient, type StationDevices } from '@/apis'; + +export const getAllDevicesApi = async (options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDevices/all`; + const resp = await client.get(endpoint, { retRaw: true, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/composed/detail-device.ts b/src/apis/request/biz/composed/detail-device.ts new file mode 100644 index 0000000..ae2f4d7 --- /dev/null +++ b/src/apis/request/biz/composed/detail-device.ts @@ -0,0 +1,59 @@ +import { + detailCameraApi, + detailDecoderApi, + detailKeyboardApi, + detailMediaServerApi, + detailNvrApi, + detailSecurityBoxApi, + detailSwitchApi, + detailVideoServerApi, + type NdmDeviceResultVO, + type Station, +} from '@/apis'; +import { DEVICE_TYPE_LITERALS, tryGetDeviceType } from '@/enums'; +import { detailAlarmHostApi } from '../alarm/ndm-alarm-host'; + +export const detailDeviceApi = async (device: NdmDeviceResultVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }): Promise => { + const { stationCode, signal } = options ?? {}; + const { id, deviceType: deviceTypeCode } = device; + if (!id || !deviceTypeCode) throw new Error('未知的设备'); + const deviceType = tryGetDeviceType(deviceTypeCode); + if (!deviceType) throw new Error('未知的设备'); + if (deviceType === DEVICE_TYPE_LITERALS.ndmAlarmHost) { + await detailAlarmHostApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmCamera) { + await detailCameraApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmDecoder) { + await detailDecoderApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmKeyboard) { + await detailKeyboardApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmMediaServer) { + await detailMediaServerApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmNvr) { + await detailNvrApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmSecurityBox) { + await detailSecurityBoxApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmSwitch) { + await detailSwitchApi(id, { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmVideoServer) { + await detailVideoServerApi(id, { stationCode, signal }); + return; + } + return undefined; +}; diff --git a/src/apis/request/biz/composed/index.ts b/src/apis/request/biz/composed/index.ts new file mode 100644 index 0000000..ce99900 --- /dev/null +++ b/src/apis/request/biz/composed/index.ts @@ -0,0 +1,2 @@ +export * from './detail-device'; +export * from './probe-device'; diff --git a/src/apis/request/biz/composed/probe-device.ts b/src/apis/request/biz/composed/probe-device.ts new file mode 100644 index 0000000..2c2118b --- /dev/null +++ b/src/apis/request/biz/composed/probe-device.ts @@ -0,0 +1,33 @@ +import { probeDecoderApi, probeMediaServerApi, probeNvrApi, probeSecurityBoxApi, probeSwitchApi, probeVideoServerApi, type NdmDeviceResultVO, type Station } from '@/apis'; +import { DEVICE_TYPE_LITERALS, tryGetDeviceType } from '@/enums'; + +export const probeDeviceApi = async (device: NdmDeviceResultVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const deviceType = tryGetDeviceType(device.deviceType); + const deviceDbId = device.id; + if (!deviceType || !deviceDbId) throw new Error('未知的设备'); + if (deviceType === DEVICE_TYPE_LITERALS.ndmDecoder) { + await probeDecoderApi([deviceDbId], { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmNvr) { + await probeNvrApi([deviceDbId], { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmSecurityBox) { + await probeSecurityBoxApi([deviceDbId], { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmMediaServer) { + await probeMediaServerApi([deviceDbId], { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmSwitch) { + await probeSwitchApi([deviceDbId], { stationCode, signal }); + return; + } + if (deviceType === DEVICE_TYPE_LITERALS.ndmVideoServer) { + await probeVideoServerApi([deviceDbId], { stationCode, signal }); + return; + } +}; diff --git a/src/apis/request/biz/constant/index.ts b/src/apis/request/biz/constant/index.ts new file mode 100644 index 0000000..92c9fec --- /dev/null +++ b/src/apis/request/biz/constant/index.ts @@ -0,0 +1 @@ +export * from './reset-monitor-shedule'; diff --git a/src/apis/request/biz/constant/reset-monitor-shedule.ts b/src/apis/request/biz/constant/reset-monitor-shedule.ts new file mode 100644 index 0000000..c9eaeda --- /dev/null +++ b/src/apis/request/biz/constant/reset-monitor-shedule.ts @@ -0,0 +1,11 @@ +import { ndmClient, userClient, type Station } from '@/apis'; + +export const resetMonitorScheduleApi = async (options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmConstant/anyTenant/resetMonitorSchedule`; + const resp = await client.get(endpoint, { signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/biz/icmp/batch-verify.ts b/src/apis/request/biz/icmp/batch-verify.ts new file mode 100644 index 0000000..872e545 --- /dev/null +++ b/src/apis/request/biz/icmp/batch-verify.ts @@ -0,0 +1,11 @@ +import { userClient, type VerifyServer } from '@/apis'; + +export const batchVerifyApi = async (options?: { signal?: AbortSignal }) => { + const { signal } = options ?? {}; + const endpoint = `/api/ndm/ndmKeepAlive/batchVerify`; + const resp = await userClient.post(endpoint, {}, { retRaw: true, timeout: 5000, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/icmp/index.ts b/src/apis/request/biz/icmp/index.ts new file mode 100644 index 0000000..8c2847f --- /dev/null +++ b/src/apis/request/biz/icmp/index.ts @@ -0,0 +1,3 @@ +export * from './batch-verify'; +export * from './ndm-icmp-export'; +export * from './verify'; diff --git a/src/apis/request/biz/icmp/ndm-icmp-export.ts b/src/apis/request/biz/icmp/ndm-icmp-export.ts new file mode 100644 index 0000000..51e44c7 --- /dev/null +++ b/src/apis/request/biz/icmp/ndm-icmp-export.ts @@ -0,0 +1,55 @@ +import { ndmClient, userClient, type IcmpEntity, type Station } from '@/apis'; + +export const exportIcmpApi = async (status?: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmIcmpExport/exportByTemplate`; + const body = new URLSearchParams(); + body.append('status', status ?? ''); + const resp = await client.post(endpoint, body, { + responseType: 'blob', + retRaw: true, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + signal, + }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const exportIcmpByStationApi = async (stationCodes: Station['code'][], status: string, options?: { signal?: AbortSignal }) => { + const { signal } = options ?? {}; + const client = ndmClient; + const prefix = ''; + const endpoint = `${prefix}/api/ndm/ndmIcmpExport/exportByTemplateByStation`; + const resp = await client.post( + endpoint, + { + stationCode: stationCodes, + status, + }, + { + responseType: 'blob', + retRaw: true, + signal, + }, + ); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const icmpEntityByDeviceId = async (deviceId: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmIcmpExport/icmpEntityByDeviceId`; + const resp = await client.get(endpoint, { params: { deviceId }, signal, retRaw: true }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/icmp/verify.ts b/src/apis/request/biz/icmp/verify.ts new file mode 100644 index 0000000..f897a46 --- /dev/null +++ b/src/apis/request/biz/icmp/verify.ts @@ -0,0 +1,11 @@ +import { ndmClient, userClient, type Station } from '@/apis'; + +export const verifyApi = async (options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmKeepAlive/verify`; + const resp = await client.post(endpoint, {}, { timeout: 5000, signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/biz/index.ts b/src/apis/request/biz/index.ts new file mode 100644 index 0000000..79a3c5a --- /dev/null +++ b/src/apis/request/biz/index.ts @@ -0,0 +1,9 @@ +export * from './alarm'; +export * from './all'; +export * from './composed'; +export * from './constant'; +export * from './icmp'; +export * from './log'; +export * from './storage'; +export * from './other'; +export * from './video'; diff --git a/src/apis/request/biz/log/index.ts b/src/apis/request/biz/log/index.ts new file mode 100644 index 0000000..441b30d --- /dev/null +++ b/src/apis/request/biz/log/index.ts @@ -0,0 +1,6 @@ +export * from './ndm-call-log'; +export * from './ndm-device-alarm-log'; +export * from './ndm-icmp-log'; +export * from './ndm-snmp-log'; +export * from './ndm-record-check'; +export * from './ndm-vimp-log'; diff --git a/src/apis/request/biz/log/ndm-call-log.ts b/src/apis/request/biz/log/ndm-call-log.ts new file mode 100644 index 0000000..ed24f05 --- /dev/null +++ b/src/apis/request/biz/log/ndm-call-log.ts @@ -0,0 +1,25 @@ +import { ndmClient, userClient, type NdmCallLogPageQuery, type NdmCallLogResultVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageCallLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCallLog/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const exportCallLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCallLog/defaultExportByTemplate`; + const resp = await client.post(endpoint, pageQuery, { responseType: 'blob', retRaw: true, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/log/ndm-device-alarm-log.ts b/src/apis/request/biz/log/ndm-device-alarm-log.ts new file mode 100644 index 0000000..129d726 --- /dev/null +++ b/src/apis/request/biz/log/ndm-device-alarm-log.ts @@ -0,0 +1,37 @@ +import { ndmClient, userClient, type NdmDeviceAlarmLogPageQuery, type NdmDeviceAlarmLogResultVO, type NdmDeviceAlarmLogUpdateVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageDeviceAlarmLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDeviceAlarmLog/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateDeviceAlarmLogApi = async (updateVO: NdmDeviceAlarmLogUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDeviceAlarmLog`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const exportDeviceAlarmLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDeviceAlarmLog/defaultExportByTemplate`; + const resp = await client.post(endpoint, pageQuery, { responseType: 'blob', retRaw: true, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/log/ndm-icmp-log.ts b/src/apis/request/biz/log/ndm-icmp-log.ts new file mode 100644 index 0000000..47ab04e --- /dev/null +++ b/src/apis/request/biz/log/ndm-icmp-log.ts @@ -0,0 +1,13 @@ +import { ndmClient, userClient, type NdmIcmpLogPageQuery, type NdmIcmpLogResultVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageIcmpLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmIcmpLog/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/log/ndm-record-check.ts b/src/apis/request/biz/log/ndm-record-check.ts new file mode 100644 index 0000000..de7ea8e --- /dev/null +++ b/src/apis/request/biz/log/ndm-record-check.ts @@ -0,0 +1,55 @@ +import { ndmClient, userClient, type ClientChannel, type NdmNvrResultVO, type NdmRecordCheck } from '@/apis'; +import dayjs from 'dayjs'; + +export const getChannelListApi = async (ndmNvr: NdmNvrResultVO, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmRecordCheck/getChannelList`; + const resp = await client.post(endpoint, { code: ndmNvr.gbCode, time: '' }, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const getRecordCheckApi = async (ndmNvr: NdmNvrResultVO, lastDays: number, gbCodeList: string[], options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmRecordCheck/getRecordCheckByParentId`; + const endDateTime = dayjs(); + const startDateTime = endDateTime.subtract(lastDays, 'day'); + const start = startDateTime.format('YYYY-MM-DD'); + const end = endDateTime.format('YYYY-MM-DD'); + const parentId = ndmNvr.gbCode; + const resp = await client.post(endpoint, { start, end, parentId, gbCodeList }, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const reloadRecordCheckApi = async (channel: ClientChannel, dayOffset: number, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmRecordCheck/reloadRecordCheckByGbId`; + const resp = await client.post(endpoint, { ...channel, dayOffset }, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const reloadAllRecordCheckApi = async (dayOffset: number, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmRecordCheck/reloadAllRecordCheck`; + const resp = await client.post(endpoint, dayOffset, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/log/ndm-snmp-log.ts b/src/apis/request/biz/log/ndm-snmp-log.ts new file mode 100644 index 0000000..78c7cb6 --- /dev/null +++ b/src/apis/request/biz/log/ndm-snmp-log.ts @@ -0,0 +1,13 @@ +import { ndmClient, userClient, type NdmSnmpLogPageQuery, type NdmSnmpLogResultVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageSnmpLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSnmpLog/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/log/ndm-vimp-log.ts b/src/apis/request/biz/log/ndm-vimp-log.ts new file mode 100644 index 0000000..016f781 --- /dev/null +++ b/src/apis/request/biz/log/ndm-vimp-log.ts @@ -0,0 +1,25 @@ +import { ndmClient, userClient, type NdmVimpLogPageQuery, type NdmVimpLogResultVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageVimpLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVimpLog/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const exportVimpLogApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVimpLog/defaultExportByTemplate`; + const resp = await client.post(endpoint, pageQuery, { responseType: 'blob', retRaw: true, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/other/index.ts b/src/apis/request/biz/other/index.ts new file mode 100644 index 0000000..7ac828d --- /dev/null +++ b/src/apis/request/biz/other/index.ts @@ -0,0 +1,2 @@ +export * from './ndm-security-box'; +export * from './ndm-switch'; diff --git a/src/apis/request/biz/other/ndm-security-box.ts b/src/apis/request/biz/other/ndm-security-box.ts new file mode 100644 index 0000000..9861904 --- /dev/null +++ b/src/apis/request/biz/other/ndm-security-box.ts @@ -0,0 +1,105 @@ +import { + ndmClient, + userClient, + type NdmSecurityBoxPageQuery, + type NdmSecurityBoxResultVO, + type NdmSecurityBoxSaveVO, + type NdmSecurityBoxUpdateVO, + type PageParams, + type PageResult, + type Station, +} from '@/apis'; + +export const pageSecurityBoxApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailSecurityBoxApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveSecurityBoxApi = async (saveVO: NdmSecurityBoxSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateSecurityBoxApi = async (updateVO: NdmSecurityBoxUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteSecurityBoxApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const probeSecurityBoxApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox/probeByIds`; + const resp = await client.post(endpoint, ids, { signal }); + const [err] = resp; + if (err) throw err; +}; + +export const turnCitcuitStatusApi = async (ipAddress: string, circuitIndex: number, status: number, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox/turnStatus`; + const resp = await client.post(endpoint, { community: 'public', ipAddress, circuit: `${circuitIndex}`, status }, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const rebootSecurityBoxApi = async (ipAddress: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSecurityBox/reboot`; + const resp = await client.post(endpoint, { community: 'public', ipAddress }, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/other/ndm-switch.ts b/src/apis/request/biz/other/ndm-switch.ts new file mode 100644 index 0000000..4056faa --- /dev/null +++ b/src/apis/request/biz/other/ndm-switch.ts @@ -0,0 +1,71 @@ +import { ndmClient, type NdmSwitchPageQuery, type NdmSwitchResultVO, type NdmSwitchSaveVO, type NdmSwitchUpdateVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageSwitchApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : ndmClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSwitch/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailSwitchApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : ndmClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSwitch/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveSwitchApi = async (saveVO: NdmSwitchSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : ndmClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSwitch`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateSwitchApi = async (updateVO: NdmSwitchUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : ndmClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSwitch`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteSwitchApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : ndmClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSwitch`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const probeSwitchApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : ndmClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmSwitch/probeByIds`; + const resp = await client.post(endpoint, ids, { signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/biz/storage/index.ts b/src/apis/request/biz/storage/index.ts new file mode 100644 index 0000000..d564e7c --- /dev/null +++ b/src/apis/request/biz/storage/index.ts @@ -0,0 +1 @@ +export * from './ndm-nvr'; diff --git a/src/apis/request/biz/storage/ndm-nvr.ts b/src/apis/request/biz/storage/ndm-nvr.ts new file mode 100644 index 0000000..bfe023e --- /dev/null +++ b/src/apis/request/biz/storage/ndm-nvr.ts @@ -0,0 +1,81 @@ +import { ndmClient, userClient, type NdmNvrPageQuery, type NdmNvrResultVO, type NdmNvrSaveVO, type NdmNvrUpdateVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageNvrPageApi = async (pageQuery: PageParams, options?: { stationCode: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailNvrApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveNvrApi = async (saveVO: NdmNvrSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateNvrApi = async (updateVO: NdmNvrUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteNvrApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const probeNvrApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr/probeByIds`; + const resp = await client.post(endpoint, ids, { signal }); + const [err] = resp; + if (err) throw err; +}; + +export const syncNvrChannelsApi = async (options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmNvr/syncNvrChannels`; + const resp = await client.get(endpoint, { signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/biz/video/index.ts b/src/apis/request/biz/video/index.ts new file mode 100644 index 0000000..4a25f3b --- /dev/null +++ b/src/apis/request/biz/video/index.ts @@ -0,0 +1,6 @@ +export * from './ndm-camera'; +export * from './ndm-camera-ignore'; +export * from './ndm-decoder'; +export * from './ndm-keyboard'; +export * from './ndm-media-server'; +export * from './ndm-video-server'; diff --git a/src/apis/request/biz/video/ndm-camera-ignore.ts b/src/apis/request/biz/video/ndm-camera-ignore.ts new file mode 100644 index 0000000..49e956e --- /dev/null +++ b/src/apis/request/biz/video/ndm-camera-ignore.ts @@ -0,0 +1,61 @@ +import { ndmClient, userClient, type NdmCameraIgnorePageQuery, type NdmCameraIgnoreResultVO, type NdmCameraIgnoreSaveVO, type NdmCameraIgnoreUpdateVO, type PageParams, type PageResult } from '@/apis'; + +export const pageCameraIgnoreApi = async (pageQuery: PageParams, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCameraIgnore/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailCameraIgnoreApi = async (id: string, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCameraIgnore/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveCameraIgnoreApi = async (saveVO: NdmCameraIgnoreSaveVO, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCameraIgnore`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateCameraIgnoreApi = async (updateVO: NdmCameraIgnoreUpdateVO, options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCameraIgnore`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteCameraIgnoreApi = async (ids: string[], options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCameraIgnore`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/video/ndm-camera.ts b/src/apis/request/biz/video/ndm-camera.ts new file mode 100644 index 0000000..efbf572 --- /dev/null +++ b/src/apis/request/biz/video/ndm-camera.ts @@ -0,0 +1,94 @@ +import { + ndmClient, + userClient, + type NdmCameraPageQuery, + type NdmCameraResultVO, + type NdmCameraSaveVO, + type NdmCameraUpdateVO, + type PageParams, + type PageResult, + type SnapResult, + type Station, +} from '@/apis'; + +export const pageCameraApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCamera/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailCameraApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCamera/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveCameraApi = async (saveVO: NdmCameraSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCamera`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateCameraApi = async (updateVO: NdmCameraUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCamera`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteCameraApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCamera`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const getCameraSnapApi = async (deviceId: string, options?: { signal?: AbortSignal }) => { + const { signal } = options ?? {}; + const endpoint = `/api/ndm/ndmCamera/getSnapByDeviceId`; + const resp = await ndmClient.get(endpoint, { params: { deviceId }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const syncCameraApi = async (options?: { stationCode?: string; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmCamera/syncCamera`; + const resp = await client.get(endpoint, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/video/ndm-decoder.ts b/src/apis/request/biz/video/ndm-decoder.ts new file mode 100644 index 0000000..bf901b0 --- /dev/null +++ b/src/apis/request/biz/video/ndm-decoder.ts @@ -0,0 +1,71 @@ +import { ndmClient, userClient, type NdmDecoderPageQuery, type NdmDecoderResultVO, type NdmDecoderSaveVO, type NdmDecoderUpdateVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageDecoderApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDecoder/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailDecoderApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDecoder/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveDecoderApi = async (saveVO: NdmDecoderSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDecoder`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateDecoderApi = async (updateVO: NdmDecoderUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDecoder`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteDecoderApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDecoder`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const probeDecoderApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmDecoder/probeByIds`; + const resp = await client.post(endpoint, ids, { signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/biz/video/ndm-keyboard.ts b/src/apis/request/biz/video/ndm-keyboard.ts new file mode 100644 index 0000000..8bae6a8 --- /dev/null +++ b/src/apis/request/biz/video/ndm-keyboard.ts @@ -0,0 +1,61 @@ +import { ndmClient, userClient, type NdmKeyboardPageQuery, type NdmKeyboardResultVO, type NdmKeyboardSaveVO, type NdmKeyboardUpdateVO, type PageParams, type PageResult, type Station } from '@/apis'; + +export const pageKeyboardApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmKeyboard/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailKeyboardApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmKeyboard/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveKeyboardApi = async (saveVO: NdmKeyboardSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmKeyboard`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateKeyboardApi = async (updateVO: NdmKeyboardUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmKeyboard`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteKeyboardApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmKeyboard`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/biz/video/ndm-media-server.ts b/src/apis/request/biz/video/ndm-media-server.ts new file mode 100644 index 0000000..fe67ec2 --- /dev/null +++ b/src/apis/request/biz/video/ndm-media-server.ts @@ -0,0 +1,81 @@ +import { + ndmClient, + userClient, + type NdmMediaServerPageQuery, + type NdmMediaServerResultVO, + type NdmMediaServerSaveVO, + type NdmMediaServerUpdateVO, + type PageParams, + type PageResult, + type Station, +} from '@/apis'; + +export const postNdmMediaServerPage = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmMediaServer/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailMediaServerApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmMediaServer/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveMediaServerApi = async (saveVO: NdmMediaServerSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmMediaServer`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateMediaServerApi = async (updateVO: NdmMediaServerUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmMediaServer`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteMediaServerApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmMediaServer`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const probeMediaServerApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmMediaServer/probeByIds`; + const resp = await client.post(endpoint, ids, { signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/biz/video/ndm-video-server.ts b/src/apis/request/biz/video/ndm-video-server.ts new file mode 100644 index 0000000..a4a46bf --- /dev/null +++ b/src/apis/request/biz/video/ndm-video-server.ts @@ -0,0 +1,81 @@ +import { + ndmClient, + userClient, + type NdmVideoServerPageQuery, + type NdmVideoServerResultVO, + type NdmVideoServerSaveVO, + type NdmVideoServerUpdateVO, + type PageParams, + type PageResult, + type Station, +} from '@/apis'; + +export const pageVideoServerApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVideoServer/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const detailVideoServerApi = async (id: string, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVideoServer/detail`; + const resp = await client.get(endpoint, { params: { id }, signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const saveVideoServerApi = async (saveVO: NdmVideoServerSaveVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVideoServer`; + const resp = await client.post(endpoint, saveVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateVideoServerApi = async (id: string, updateVO: NdmVideoServerUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVideoServer`; + const resp = await client.put(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const deleteVideoServerApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVideoServer`; + const resp = await client.delete(endpoint, ids, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const probeVideoServerApi = async (ids: string[], options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/ndm/ndmVideoServer/probeByIds`; + const resp = await client.post(endpoint, ids, { signal }); + const [err] = resp; + if (err) throw err; +}; diff --git a/src/apis/request/index.ts b/src/apis/request/index.ts new file mode 100644 index 0000000..ced1b3c --- /dev/null +++ b/src/apis/request/index.ts @@ -0,0 +1,2 @@ +export * from './biz'; +export * from './system'; diff --git a/src/apis/request/system/def-parameter.ts b/src/apis/request/system/def-parameter.ts new file mode 100644 index 0000000..9c3814e --- /dev/null +++ b/src/apis/request/system/def-parameter.ts @@ -0,0 +1,26 @@ +import { ndmClient, userClient, type DefParameterPageQuery, type DefParameterResultVO, type DefParameterUpdateVO, type PageParams, type PageResult, type Station } from '@/apis'; +import type { Result } from '@/types'; + +export const pageDefParameterApi = async (pageQuery: PageParams, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/system/defParameter/page`; + const resp = await client.post>(endpoint, pageQuery, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; + +export const updateDefParameterApi = async (updateVO: DefParameterUpdateVO, options?: { stationCode?: Station['code']; signal?: AbortSignal }) => { + const { stationCode, signal } = options ?? {}; + const client = stationCode ? ndmClient : userClient; + const prefix = stationCode ? `/${stationCode}` : ''; + const endpoint = `${prefix}/api/system/defParameter`; + const resp = await client.put>(endpoint, updateVO, { signal }); + const [err, data] = resp; + if (err) throw err; + if (!data) throw new Error(`${data}`); + return data; +}; diff --git a/src/apis/request/system/index.ts b/src/apis/request/system/index.ts new file mode 100644 index 0000000..28a74a0 --- /dev/null +++ b/src/apis/request/system/index.ts @@ -0,0 +1 @@ +export * from './def-parameter'; diff --git a/src/components/device/device-card/components/current-diag/device-common-card.vue b/src/components/device/device-card/components/current-diag/device-common-card.vue new file mode 100644 index 0000000..b30f196 --- /dev/null +++ b/src/components/device/device-card/components/current-diag/device-common-card.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/device-hardware-card.vue b/src/components/device/device-card/components/current-diag/device-hardware-card.vue new file mode 100644 index 0000000..dc3d64e --- /dev/null +++ b/src/components/device/device-card/components/current-diag/device-hardware-card.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/device-header-card.vue b/src/components/device/device-card/components/current-diag/device-header-card.vue new file mode 100644 index 0000000..39af8c6 --- /dev/null +++ b/src/components/device/device-card/components/current-diag/device-header-card.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/index.ts b/src/components/device/device-card/components/current-diag/index.ts new file mode 100644 index 0000000..ad5707e --- /dev/null +++ b/src/components/device/device-card/components/current-diag/index.ts @@ -0,0 +1,10 @@ +import DeviceCommonCard from './device-common-card.vue'; +import DeviceHardwareCard from './device-hardware-card.vue'; +import DeviceHeaderCard from './device-header-card.vue'; +import NvrDiskCard from './nvr-disk-card.vue'; +import NvrRecordCard from './nvr-record-card.vue'; +import SecurityBoxCircuitCard from './security-box-circuit-card.vue'; +import SecurityBoxEnvCard from './security-box-env-card.vue'; +import SwitchPortCard from './switch-port-card.vue'; + +export { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, NvrDiskCard, NvrRecordCard, SecurityBoxCircuitCard, SecurityBoxEnvCard, SwitchPortCard }; diff --git a/src/components/device/device-card/components/current-diag/nvr-disk-card.vue b/src/components/device/device-card/components/current-diag/nvr-disk-card.vue new file mode 100644 index 0000000..cc7a8cc --- /dev/null +++ b/src/components/device/device-card/components/current-diag/nvr-disk-card.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/nvr-record-card.vue b/src/components/device/device-card/components/current-diag/nvr-record-card.vue new file mode 100644 index 0000000..4fc2937 --- /dev/null +++ b/src/components/device/device-card/components/current-diag/nvr-record-card.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/security-box-circuit-card.vue b/src/components/device/device-card/components/current-diag/security-box-circuit-card.vue new file mode 100644 index 0000000..36b2087 --- /dev/null +++ b/src/components/device/device-card/components/current-diag/security-box-circuit-card.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/security-box-env-card.vue b/src/components/device/device-card/components/current-diag/security-box-env-card.vue new file mode 100644 index 0000000..2fcace6 --- /dev/null +++ b/src/components/device/device-card/components/current-diag/security-box-env-card.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/components/device/device-card/components/current-diag/switch-port-card.vue b/src/components/device/device-card/components/current-diag/switch-port-card.vue new file mode 100644 index 0000000..48476f3 --- /dev/null +++ b/src/components/device/device-card/components/current-diag/switch-port-card.vue @@ -0,0 +1,146 @@ + + + + + diff --git a/src/components/device/device-card/components/history-diag/device-alarm-history-card.vue b/src/components/device/device-card/components/history-diag/device-alarm-history-card.vue new file mode 100644 index 0000000..dca4dfd --- /dev/null +++ b/src/components/device/device-card/components/history-diag/device-alarm-history-card.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/components/device/device-card/components/history-diag/device-icmp-history-card.vue b/src/components/device/device-card/components/history-diag/device-icmp-history-card.vue new file mode 100644 index 0000000..b4a6e58 --- /dev/null +++ b/src/components/device/device-card/components/history-diag/device-icmp-history-card.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/src/components/device/device-card/components/history-diag/device-usage-history-card.vue b/src/components/device/device-card/components/history-diag/device-usage-history-card.vue new file mode 100644 index 0000000..173a09e --- /dev/null +++ b/src/components/device/device-card/components/history-diag/device-usage-history-card.vue @@ -0,0 +1,153 @@ + + + + + + + diff --git a/src/components/device/device-card/components/history-diag/history-diag-filter-card.vue b/src/components/device/device-card/components/history-diag/history-diag-filter-card.vue new file mode 100644 index 0000000..eaa9308 --- /dev/null +++ b/src/components/device/device-card/components/history-diag/history-diag-filter-card.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/device/device-card/components/history-diag/index.ts b/src/components/device/device-card/components/history-diag/index.ts new file mode 100644 index 0000000..c0c9b77 --- /dev/null +++ b/src/components/device/device-card/components/history-diag/index.ts @@ -0,0 +1,27 @@ +import DeviceAlarmHistoryCard from './device-alarm-history-card.vue'; +import DeviceIcmpHistoryCard from './device-icmp-history-card.vue'; +import DeviceUsageHistoryCard from './device-usage-history-card.vue'; +import HistoryDiagFilterCard from './history-diag-filter-card.vue'; +import NvrDiskHistoryCard from './nvr-disk-history-card.vue'; +import SecurityBoxRuntimeHistoryCard from './security-box-runtime-history-card.vue'; +import SwitchPortHistoryCard from './switch-port-history-card.vue'; +import type { ComponentInstance } from 'vue'; + +export type HistoryDiagFilterCardProps = ComponentInstance['$props']; +export type DeviceIcmpHistoryCardProps = ComponentInstance['$props']; +export type DeviceAlarmHistoryCardProps = ComponentInstance['$props']; +export type DeviceUsageHistoryCardProps = ComponentInstance['$props']; +export type NvrDiskHistoryCardProps = ComponentInstance['$props']; +export type SecurityBoxRuntimeHistoryCardProps = ComponentInstance['$props']; +export type SwitchPortHistoryCardProps = ComponentInstance['$props']; + +export { + // + DeviceAlarmHistoryCard, + DeviceIcmpHistoryCard, + DeviceUsageHistoryCard, + HistoryDiagFilterCard, + NvrDiskHistoryCard, + SecurityBoxRuntimeHistoryCard, + SwitchPortHistoryCard, +}; diff --git a/src/components/device/device-card/components/history-diag/nvr-disk-history-card.vue b/src/components/device/device-card/components/history-diag/nvr-disk-history-card.vue new file mode 100644 index 0000000..e101a78 --- /dev/null +++ b/src/components/device/device-card/components/history-diag/nvr-disk-history-card.vue @@ -0,0 +1,155 @@ + + + + + + + diff --git a/src/components/device/device-card/components/history-diag/security-box-runtime-history-card.vue b/src/components/device/device-card/components/history-diag/security-box-runtime-history-card.vue new file mode 100644 index 0000000..42f8190 --- /dev/null +++ b/src/components/device/device-card/components/history-diag/security-box-runtime-history-card.vue @@ -0,0 +1,230 @@ + + + + + + + diff --git a/src/components/device/device-card/components/history-diag/switch-port-history-card.vue b/src/components/device/device-card/components/history-diag/switch-port-history-card.vue new file mode 100644 index 0000000..040b6b1 --- /dev/null +++ b/src/components/device/device-card/components/history-diag/switch-port-history-card.vue @@ -0,0 +1,206 @@ + + + + + + + diff --git a/src/components/device/device-card/components/index.ts b/src/components/device/device-card/components/index.ts new file mode 100644 index 0000000..b9c0ecf --- /dev/null +++ b/src/components/device/device-card/components/index.ts @@ -0,0 +1,3 @@ +export * from './current-diag'; +export * from './history-diag'; +export * from './raw-diag'; diff --git a/src/components/device/device-card/components/raw-diag/device-raw-card.vue b/src/components/device/device-card/components/raw-diag/device-raw-card.vue new file mode 100644 index 0000000..f9a0db2 --- /dev/null +++ b/src/components/device/device-card/components/raw-diag/device-raw-card.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/src/components/device/device-card/components/raw-diag/index.ts b/src/components/device/device-card/components/raw-diag/index.ts new file mode 100644 index 0000000..07142bc --- /dev/null +++ b/src/components/device/device-card/components/raw-diag/index.ts @@ -0,0 +1,3 @@ +import DeviceRawCard from './device-raw-card.vue'; + +export { DeviceRawCard }; diff --git a/src/components/device/device-card/index.ts b/src/components/device/device-card/index.ts new file mode 100644 index 0000000..6d8a071 --- /dev/null +++ b/src/components/device/device-card/index.ts @@ -0,0 +1,9 @@ +export * from './components'; +export * from './ndm-alarm-host'; +export * from './ndm-camera'; +export * from './ndm-decoder'; +export * from './ndm-keyboard'; +export * from './ndm-nvr'; +export * from './ndm-security-box'; +export * from './ndm-server'; +export * from './ndm-switch'; diff --git a/src/components/device/device-card/ndm-alarm-host/alarm-host-card.vue b/src/components/device/device-card/ndm-alarm-host/alarm-host-card.vue new file mode 100644 index 0000000..a8d357f --- /dev/null +++ b/src/components/device/device-card/ndm-alarm-host/alarm-host-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-alarm-host/alarm-host-current-diag.vue b/src/components/device/device-card/ndm-alarm-host/alarm-host-current-diag.vue new file mode 100644 index 0000000..fcdb39a --- /dev/null +++ b/src/components/device/device-card/ndm-alarm-host/alarm-host-current-diag.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/src/components/device/device-card/ndm-alarm-host/alarm-host-history-diag.vue b/src/components/device/device-card/ndm-alarm-host/alarm-host-history-diag.vue new file mode 100644 index 0000000..a188787 --- /dev/null +++ b/src/components/device/device-card/ndm-alarm-host/alarm-host-history-diag.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/components/device/device-card/ndm-alarm-host/alarm-host-update.vue b/src/components/device/device-card/ndm-alarm-host/alarm-host-update.vue new file mode 100644 index 0000000..7e6a91b --- /dev/null +++ b/src/components/device/device-card/ndm-alarm-host/alarm-host-update.vue @@ -0,0 +1,152 @@ + + + + + diff --git a/src/components/device/device-card/ndm-alarm-host/index.ts b/src/components/device/device-card/ndm-alarm-host/index.ts new file mode 100644 index 0000000..ba920ce --- /dev/null +++ b/src/components/device/device-card/ndm-alarm-host/index.ts @@ -0,0 +1,6 @@ +import AlarmHostCard from './alarm-host-card.vue'; +import AlarmHostCurrentDiag from './alarm-host-current-diag.vue'; +import AlarmHostHistoryDiag from './alarm-host-history-diag.vue'; +import AlarmHostUpdate from './alarm-host-update.vue'; + +export { AlarmHostCard, AlarmHostCurrentDiag, AlarmHostHistoryDiag, AlarmHostUpdate }; diff --git a/src/components/device/device-card/ndm-camera/camera-card.vue b/src/components/device/device-card/ndm-camera/camera-card.vue new file mode 100644 index 0000000..c0bf10f --- /dev/null +++ b/src/components/device/device-card/ndm-camera/camera-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-camera/camera-current-diag.vue b/src/components/device/device-card/ndm-camera/camera-current-diag.vue new file mode 100644 index 0000000..9688b7d --- /dev/null +++ b/src/components/device/device-card/ndm-camera/camera-current-diag.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/src/components/device/device-card/ndm-camera/camera-history-diag.vue b/src/components/device/device-card/ndm-camera/camera-history-diag.vue new file mode 100644 index 0000000..073be98 --- /dev/null +++ b/src/components/device/device-card/ndm-camera/camera-history-diag.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/components/device/device-card/ndm-camera/camera-update.vue b/src/components/device/device-card/ndm-camera/camera-update.vue new file mode 100644 index 0000000..9816117 --- /dev/null +++ b/src/components/device/device-card/ndm-camera/camera-update.vue @@ -0,0 +1,133 @@ + + + + + diff --git a/src/components/device/device-card/ndm-camera/index.ts b/src/components/device/device-card/ndm-camera/index.ts new file mode 100644 index 0000000..759cb97 --- /dev/null +++ b/src/components/device/device-card/ndm-camera/index.ts @@ -0,0 +1,6 @@ +import CameraCard from './camera-card.vue'; +import CameraCurrentDiag from './camera-current-diag.vue'; +import CameraHistoryDiag from './camera-history-diag.vue'; +import CameraUpdate from './camera-update.vue'; + +export { CameraCard, CameraCurrentDiag, CameraHistoryDiag, CameraUpdate }; diff --git a/src/components/device/device-card/ndm-decoder/decoder-card.vue b/src/components/device/device-card/ndm-decoder/decoder-card.vue new file mode 100644 index 0000000..5fe4b34 --- /dev/null +++ b/src/components/device/device-card/ndm-decoder/decoder-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-decoder/decoder-current-diag.vue b/src/components/device/device-card/ndm-decoder/decoder-current-diag.vue new file mode 100644 index 0000000..0ae489f --- /dev/null +++ b/src/components/device/device-card/ndm-decoder/decoder-current-diag.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/src/components/device/device-card/ndm-decoder/decoder-history-diag.vue b/src/components/device/device-card/ndm-decoder/decoder-history-diag.vue new file mode 100644 index 0000000..86e6489 --- /dev/null +++ b/src/components/device/device-card/ndm-decoder/decoder-history-diag.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/src/components/device/device-card/ndm-decoder/decoder-update.vue b/src/components/device/device-card/ndm-decoder/decoder-update.vue new file mode 100644 index 0000000..7b5640a --- /dev/null +++ b/src/components/device/device-card/ndm-decoder/decoder-update.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/src/components/device/device-card/ndm-decoder/index.ts b/src/components/device/device-card/ndm-decoder/index.ts new file mode 100644 index 0000000..baa3540 --- /dev/null +++ b/src/components/device/device-card/ndm-decoder/index.ts @@ -0,0 +1,6 @@ +import DecoderCard from './decoder-card.vue'; +import DecoderCurrentDiag from './decoder-current-diag.vue'; +import DecoderHistoryDiag from './decoder-history-diag.vue'; +import DecoderUpdate from './decoder-update.vue'; + +export { DecoderCard, DecoderCurrentDiag, DecoderHistoryDiag, DecoderUpdate }; diff --git a/src/components/device/device-card/ndm-keyboard/index.ts b/src/components/device/device-card/ndm-keyboard/index.ts new file mode 100644 index 0000000..991009b --- /dev/null +++ b/src/components/device/device-card/ndm-keyboard/index.ts @@ -0,0 +1,6 @@ +import KeyboardCard from './keyboard-card.vue'; +import KeyboardCurrentDiag from './keyboard-current-diag.vue'; +import KeyboardHistoryDiag from './keyboard-history-diag.vue'; +import KeyboardUpdate from './keyboard-update.vue'; + +export { KeyboardCard, KeyboardCurrentDiag, KeyboardHistoryDiag, KeyboardUpdate }; diff --git a/src/components/device/device-card/ndm-keyboard/keyboard-card.vue b/src/components/device/device-card/ndm-keyboard/keyboard-card.vue new file mode 100644 index 0000000..2f17410 --- /dev/null +++ b/src/components/device/device-card/ndm-keyboard/keyboard-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-keyboard/keyboard-current-diag.vue b/src/components/device/device-card/ndm-keyboard/keyboard-current-diag.vue new file mode 100644 index 0000000..e437122 --- /dev/null +++ b/src/components/device/device-card/ndm-keyboard/keyboard-current-diag.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/src/components/device/device-card/ndm-keyboard/keyboard-history-diag.vue b/src/components/device/device-card/ndm-keyboard/keyboard-history-diag.vue new file mode 100644 index 0000000..f43c07e --- /dev/null +++ b/src/components/device/device-card/ndm-keyboard/keyboard-history-diag.vue @@ -0,0 +1,76 @@ + + + + + diff --git a/src/components/device/device-card/ndm-keyboard/keyboard-update.vue b/src/components/device/device-card/ndm-keyboard/keyboard-update.vue new file mode 100644 index 0000000..dae572c --- /dev/null +++ b/src/components/device/device-card/ndm-keyboard/keyboard-update.vue @@ -0,0 +1,142 @@ + + + + + diff --git a/src/components/device/device-card/ndm-nvr/index.ts b/src/components/device/device-card/ndm-nvr/index.ts new file mode 100644 index 0000000..417c2f7 --- /dev/null +++ b/src/components/device/device-card/ndm-nvr/index.ts @@ -0,0 +1,6 @@ +import NvrCard from './nvr-card.vue'; +import NvrCurrentDiag from './nvr-current-diag.vue'; +import NvrHistoryDiag from './nvr-history-diag.vue'; +import NvrUpdate from './nvr-update.vue'; + +export { NvrCard, NvrCurrentDiag, NvrHistoryDiag, NvrUpdate }; diff --git a/src/components/device/device-card/ndm-nvr/nvr-card.vue b/src/components/device/device-card/ndm-nvr/nvr-card.vue new file mode 100644 index 0000000..2cc200e --- /dev/null +++ b/src/components/device/device-card/ndm-nvr/nvr-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-nvr/nvr-current-diag.vue b/src/components/device/device-card/ndm-nvr/nvr-current-diag.vue new file mode 100644 index 0000000..0b1b540 --- /dev/null +++ b/src/components/device/device-card/ndm-nvr/nvr-current-diag.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/components/device/device-card/ndm-nvr/nvr-history-diag.vue b/src/components/device/device-card/ndm-nvr/nvr-history-diag.vue new file mode 100644 index 0000000..38e7136 --- /dev/null +++ b/src/components/device/device-card/ndm-nvr/nvr-history-diag.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/src/components/device/device-card/ndm-nvr/nvr-update.vue b/src/components/device/device-card/ndm-nvr/nvr-update.vue new file mode 100644 index 0000000..598824e --- /dev/null +++ b/src/components/device/device-card/ndm-nvr/nvr-update.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/src/components/device/device-card/ndm-security-box/index.ts b/src/components/device/device-card/ndm-security-box/index.ts new file mode 100644 index 0000000..eda0ad6 --- /dev/null +++ b/src/components/device/device-card/ndm-security-box/index.ts @@ -0,0 +1,6 @@ +import SecurityBoxCard from './security-box-card.vue'; +import SecurityBoxCurrentDiag from './security-box-current-diag.vue'; +import SecurityBoxHistoryDiag from './security-box-history-diag.vue'; +import SecurityBoxUpdate from './security-box-update.vue'; + +export { SecurityBoxCard, SecurityBoxCurrentDiag, SecurityBoxHistoryDiag, SecurityBoxUpdate }; diff --git a/src/components/device/device-card/ndm-security-box/security-box-card.vue b/src/components/device/device-card/ndm-security-box/security-box-card.vue new file mode 100644 index 0000000..ba81f4b --- /dev/null +++ b/src/components/device/device-card/ndm-security-box/security-box-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-security-box/security-box-current-diag.vue b/src/components/device/device-card/ndm-security-box/security-box-current-diag.vue new file mode 100644 index 0000000..a41d948 --- /dev/null +++ b/src/components/device/device-card/ndm-security-box/security-box-current-diag.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/components/device/device-card/ndm-security-box/security-box-history-diag.vue b/src/components/device/device-card/ndm-security-box/security-box-history-diag.vue new file mode 100644 index 0000000..3df4a57 --- /dev/null +++ b/src/components/device/device-card/ndm-security-box/security-box-history-diag.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/device/device-card/ndm-security-box/security-box-update.vue b/src/components/device/device-card/ndm-security-box/security-box-update.vue new file mode 100644 index 0000000..21d4192 --- /dev/null +++ b/src/components/device/device-card/ndm-security-box/security-box-update.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/components/device/device-card/ndm-server/index.ts b/src/components/device/device-card/ndm-server/index.ts new file mode 100644 index 0000000..5ac4563 --- /dev/null +++ b/src/components/device/device-card/ndm-server/index.ts @@ -0,0 +1,6 @@ +import ServerCard from './server-card.vue'; +import ServerCurrentDiag from './server-current-diag.vue'; +import ServerHistoryDiag from './server-history-diag.vue'; +import ServerUpdate from './server-update.vue'; + +export { ServerCard, ServerCurrentDiag, ServerHistoryDiag, ServerUpdate }; diff --git a/src/components/device/device-card/ndm-server/server-card.vue b/src/components/device/device-card/ndm-server/server-card.vue new file mode 100644 index 0000000..1afa360 --- /dev/null +++ b/src/components/device/device-card/ndm-server/server-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-server/server-current-diag.vue b/src/components/device/device-card/ndm-server/server-current-diag.vue new file mode 100644 index 0000000..0767d56 --- /dev/null +++ b/src/components/device/device-card/ndm-server/server-current-diag.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/src/components/device/device-card/ndm-server/server-history-diag.vue b/src/components/device/device-card/ndm-server/server-history-diag.vue new file mode 100644 index 0000000..137d7cb --- /dev/null +++ b/src/components/device/device-card/ndm-server/server-history-diag.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/src/components/device/device-card/ndm-server/server-update.vue b/src/components/device/device-card/ndm-server/server-update.vue new file mode 100644 index 0000000..ad1701b --- /dev/null +++ b/src/components/device/device-card/ndm-server/server-update.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/components/device/device-card/ndm-switch/index.ts b/src/components/device/device-card/ndm-switch/index.ts new file mode 100644 index 0000000..fa49652 --- /dev/null +++ b/src/components/device/device-card/ndm-switch/index.ts @@ -0,0 +1,6 @@ +import SwitchCard from './switch-card.vue'; +import SwitchCurrentDiag from './switch-current-diag.vue'; +import SwitchHistoryDiag from './switch-history-diag.vue'; +import SwitchUpdate from './switch-update.vue'; + +export { SwitchCard, SwitchCurrentDiag, SwitchHistoryDiag, SwitchUpdate }; diff --git a/src/components/device/device-card/ndm-switch/switch-card.vue b/src/components/device/device-card/ndm-switch/switch-card.vue new file mode 100644 index 0000000..5d34a54 --- /dev/null +++ b/src/components/device/device-card/ndm-switch/switch-card.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/device/device-card/ndm-switch/switch-current-diag.vue b/src/components/device/device-card/ndm-switch/switch-current-diag.vue new file mode 100644 index 0000000..868518f --- /dev/null +++ b/src/components/device/device-card/ndm-switch/switch-current-diag.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/src/components/device/device-card/ndm-switch/switch-history-diag.vue b/src/components/device/device-card/ndm-switch/switch-history-diag.vue new file mode 100644 index 0000000..00d88f6 --- /dev/null +++ b/src/components/device/device-card/ndm-switch/switch-history-diag.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/components/device/device-card/ndm-switch/switch-update.vue b/src/components/device/device-card/ndm-switch/switch-update.vue new file mode 100644 index 0000000..670efac --- /dev/null +++ b/src/components/device/device-card/ndm-switch/switch-update.vue @@ -0,0 +1,154 @@ + + + + + diff --git a/src/components/device/device-renderer/device-renderer.vue b/src/components/device/device-renderer/device-renderer.vue new file mode 100644 index 0000000..ba719ce --- /dev/null +++ b/src/components/device/device-renderer/device-renderer.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/src/components/device/device-renderer/index.ts b/src/components/device/device-renderer/index.ts new file mode 100644 index 0000000..0fb69bd --- /dev/null +++ b/src/components/device/device-renderer/index.ts @@ -0,0 +1,3 @@ +import DeviceRenderer from './device-renderer.vue'; + +export { DeviceRenderer }; diff --git a/src/components/device/device-tree/device-tree.export.vue b/src/components/device/device-tree/device-tree.export.vue new file mode 100644 index 0000000..099b731 --- /dev/null +++ b/src/components/device/device-tree/device-tree.export.vue @@ -0,0 +1,475 @@ + + + + + diff --git a/src/components/device/device-tree/device-tree.vue b/src/components/device/device-tree/device-tree.vue new file mode 100644 index 0000000..1b1965d --- /dev/null +++ b/src/components/device/device-tree/device-tree.vue @@ -0,0 +1,420 @@ + + + + + diff --git a/src/components/device/device-tree/index.ts b/src/components/device/device-tree/index.ts new file mode 100644 index 0000000..121170b --- /dev/null +++ b/src/components/device/device-tree/index.ts @@ -0,0 +1,6 @@ +import type { ComponentInstance } from 'vue'; +import DeviceTree from './device-tree.vue'; + +export type DeviceTreeProps = ComponentInstance['$props']; + +export { DeviceTree }; diff --git a/src/components/device/index.ts b/src/components/device/index.ts new file mode 100644 index 0000000..7edad5e --- /dev/null +++ b/src/components/device/index.ts @@ -0,0 +1,3 @@ +export * from './device-card'; +export * from './device-renderer'; +export * from './device-tree'; diff --git a/src/components/global/global-feedback/global-feedback.vue b/src/components/global/global-feedback/global-feedback.vue new file mode 100644 index 0000000..4bfb97d --- /dev/null +++ b/src/components/global/global-feedback/global-feedback.vue @@ -0,0 +1,12 @@ + + + + + diff --git a/src/components/global/global-feedback/index.ts b/src/components/global/global-feedback/index.ts new file mode 100644 index 0000000..aeca730 --- /dev/null +++ b/src/components/global/global-feedback/index.ts @@ -0,0 +1,3 @@ +import GlobalFeedback from './global-feedback.vue'; + +export { GlobalFeedback }; diff --git a/src/components/global/index.ts b/src/components/global/index.ts new file mode 100644 index 0000000..ffc6f0a --- /dev/null +++ b/src/components/global/index.ts @@ -0,0 +1,3 @@ +export * from './global-feedback'; +export * from './settings-drawer'; +export * from './theme-switch'; diff --git a/src/components/global/settings-drawer/index.ts b/src/components/global/settings-drawer/index.ts new file mode 100644 index 0000000..930686f --- /dev/null +++ b/src/components/global/settings-drawer/index.ts @@ -0,0 +1,3 @@ +import SettingsDrawer from './settings-drawer.vue'; + +export { SettingsDrawer }; diff --git a/src/components/global/settings-drawer/settings-drawer.vue b/src/components/global/settings-drawer/settings-drawer.vue new file mode 100644 index 0000000..67409ed --- /dev/null +++ b/src/components/global/settings-drawer/settings-drawer.vue @@ -0,0 +1,277 @@ + + + + + diff --git a/src/components/global/theme-switch/index.ts b/src/components/global/theme-switch/index.ts new file mode 100644 index 0000000..4565fdc --- /dev/null +++ b/src/components/global/theme-switch/index.ts @@ -0,0 +1,3 @@ +import ThemeSwitch from './theme-switch.vue'; + +export { ThemeSwitch }; diff --git a/src/components/global/theme-switch/theme-switch.vue b/src/components/global/theme-switch/theme-switch.vue new file mode 100644 index 0000000..ecdcdd1 --- /dev/null +++ b/src/components/global/theme-switch/theme-switch.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..5b99575 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,3 @@ +export * from './device'; +export * from './global'; +export * from './station'; diff --git a/src/components/station/alarm-detail-modal/alarm-detail-modal.vue b/src/components/station/alarm-detail-modal/alarm-detail-modal.vue new file mode 100644 index 0000000..59fd09c --- /dev/null +++ b/src/components/station/alarm-detail-modal/alarm-detail-modal.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/components/station/alarm-detail-modal/index.ts b/src/components/station/alarm-detail-modal/index.ts new file mode 100644 index 0000000..022b4f9 --- /dev/null +++ b/src/components/station/alarm-detail-modal/index.ts @@ -0,0 +1,3 @@ +import AlarmDetailModal from './alarm-detail-modal.vue'; + +export { AlarmDetailModal }; diff --git a/src/components/station/device-detail-modal/device-detail-modal.vue b/src/components/station/device-detail-modal/device-detail-modal.vue new file mode 100644 index 0000000..89959fc --- /dev/null +++ b/src/components/station/device-detail-modal/device-detail-modal.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/src/components/station/device-detail-modal/index.ts b/src/components/station/device-detail-modal/index.ts new file mode 100644 index 0000000..003deae --- /dev/null +++ b/src/components/station/device-detail-modal/index.ts @@ -0,0 +1,3 @@ +import DeviceDetailModal from './device-detail-modal.vue'; + +export { DeviceDetailModal }; diff --git a/src/components/station/device-param-config-modal/device-param-config.modal.vue b/src/components/station/device-param-config-modal/device-param-config.modal.vue new file mode 100644 index 0000000..6255904 --- /dev/null +++ b/src/components/station/device-param-config-modal/device-param-config.modal.vue @@ -0,0 +1,258 @@ + + + + + + + diff --git a/src/components/station/device-param-config-modal/index.ts b/src/components/station/device-param-config-modal/index.ts new file mode 100644 index 0000000..57c95da --- /dev/null +++ b/src/components/station/device-param-config-modal/index.ts @@ -0,0 +1,3 @@ +import DeviceParamConfigModal from './device-param-config.modal.vue'; + +export { DeviceParamConfigModal }; diff --git a/src/components/station/icmp-export-modal/icmp-export-modal.vue b/src/components/station/icmp-export-modal/icmp-export-modal.vue new file mode 100644 index 0000000..acd1375 --- /dev/null +++ b/src/components/station/icmp-export-modal/icmp-export-modal.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/src/components/station/icmp-export-modal/index.ts b/src/components/station/icmp-export-modal/index.ts new file mode 100644 index 0000000..f6fe896 --- /dev/null +++ b/src/components/station/icmp-export-modal/index.ts @@ -0,0 +1,3 @@ +import IcmpExportModal from './icmp-export-modal.vue'; + +export { IcmpExportModal }; diff --git a/src/components/station/index.ts b/src/components/station/index.ts new file mode 100644 index 0000000..f42cf12 --- /dev/null +++ b/src/components/station/index.ts @@ -0,0 +1,7 @@ +export * from './alarm-detail-modal'; +export * from './device-detail-modal'; +export * from './device-param-config-modal'; +export * from './icmp-export-modal'; +export * from './record-check-export-modal'; +export * from './station-card'; +export * from './sync-camera-result-modal'; diff --git a/src/components/station/record-check-export-modal/index.ts b/src/components/station/record-check-export-modal/index.ts new file mode 100644 index 0000000..bc1e8ac --- /dev/null +++ b/src/components/station/record-check-export-modal/index.ts @@ -0,0 +1,3 @@ +import RecordCheckExportModal from './record-check-export-modal.vue'; + +export { RecordCheckExportModal }; diff --git a/src/components/station/record-check-export-modal/record-check-export-modal.vue b/src/components/station/record-check-export-modal/record-check-export-modal.vue new file mode 100644 index 0000000..cd6e889 --- /dev/null +++ b/src/components/station/record-check-export-modal/record-check-export-modal.vue @@ -0,0 +1,98 @@ + + + + + diff --git a/src/components/station/station-card/index.ts b/src/components/station/station-card/index.ts new file mode 100644 index 0000000..587b371 --- /dev/null +++ b/src/components/station/station-card/index.ts @@ -0,0 +1,6 @@ +import type { ComponentInstance } from 'vue'; +import StationCard from './station-card.vue'; + +export type StationCardProps = ComponentInstance['$props']; + +export { StationCard }; diff --git a/src/components/station/station-card/station-card.vue b/src/components/station/station-card/station-card.vue new file mode 100644 index 0000000..068f20a --- /dev/null +++ b/src/components/station/station-card/station-card.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/components/station/sync-camera-result-modal/index.ts b/src/components/station/sync-camera-result-modal/index.ts new file mode 100644 index 0000000..04da51a --- /dev/null +++ b/src/components/station/sync-camera-result-modal/index.ts @@ -0,0 +1,3 @@ +import SyncCameraResultModal from './sync-camera-result-modal.vue'; + +export { SyncCameraResultModal }; diff --git a/src/components/station/sync-camera-result-modal/sync-camera-result-modal.vue b/src/components/station/sync-camera-result-modal/sync-camera-result-modal.vue new file mode 100644 index 0000000..475b36a --- /dev/null +++ b/src/components/station/sync-camera-result-modal/sync-camera-result-modal.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/src/composables/alarm/index.ts b/src/composables/alarm/index.ts new file mode 100644 index 0000000..ec28ca3 --- /dev/null +++ b/src/composables/alarm/index.ts @@ -0,0 +1,2 @@ +export * from './use-alarm-action-column'; +export * from './use-camera-snap-column'; diff --git a/src/composables/alarm/use-alarm-action-column.ts b/src/composables/alarm/use-alarm-action-column.ts new file mode 100644 index 0000000..57885a5 --- /dev/null +++ b/src/composables/alarm/use-alarm-action-column.ts @@ -0,0 +1,149 @@ +import { deleteCameraIgnoreApi, pageCameraIgnoreApi, saveCameraIgnoreApi, updateDeviceAlarmLogApi, type NdmDeviceAlarmLogResultVO } from '@/apis'; +import { DEVICE_TYPE_LITERALS, tryGetDeviceType } from '@/enums'; +import { parseErrorFeedback } from '@/utils'; +import { useMutation } from '@tanstack/vue-query'; +import { NButton, NFlex, NPopconfirm, type DataTableColumn, type DataTableRowData } from 'naive-ui'; +import { h, type Ref } from 'vue'; + +export const useAlarmActionColumn = (tableData: Ref) => { + const { mutate: confirmAlarm } = useMutation({ + mutationFn: async (params: { id: string | null }) => { + const { id } = params; + if (!id) return; + const alarmLog = tableData.value.find((item) => item.id === id); + if (alarmLog) { + alarmLog['alarmConfirm'] = '1'; + } + await updateDeviceAlarmLogApi({ id, alarmConfirm: '1' }); + }, + onError: (error, variables) => { + console.error(error); + const errorFeedback = parseErrorFeedback(error); + window.$message.error(errorFeedback); + const { id } = variables; + if (id) { + const alarmLog = tableData.value.find((item) => item.id === id); + if (alarmLog) { + alarmLog['alarmConfirm'] = '2'; + } + } + }, + }); + + const { mutate: ignoreCamera } = useMutation({ + mutationFn: async (params: { id: string | null }) => { + const { id } = params; + if (!id) return; + const alarmLog = tableData.value.find((item) => item.id === id); + if (!alarmLog) return; + const { records } = await pageCameraIgnoreApi({ + model: { deviceId: alarmLog.deviceId }, + extra: {}, + current: 1, + size: 10, + sort: 'id', + order: 'descending', + }); + const ignoredCamera = records.at(0); + if (ignoredCamera) { + window.$message.info('设备已被忽略'); + return; + } + await saveCameraIgnoreApi({ deviceId: alarmLog.deviceId }); + window.$message.success('忽略设备成功'); + }, + onError: (error) => { + console.error(error); + const errorFeedback = parseErrorFeedback(error); + window.$message.error(errorFeedback); + }, + }); + + // const { mutate: noticeCamera } = useMutation({ + // mutationFn: async (params: { id: string | null }) => { + // const { id } = params; + // if (!id) return; + // const alarmLog = tableData.value.find((item) => item.id === id); + // if (!alarmLog) return; + // const { records } = await pageCameraIgnoreApi({ + // model: { deviceId: alarmLog.deviceId }, + // extra: {}, + // current: 1, + // size: 10, + // sort: 'id', + // order: 'descending', + // }); + // if (records.length === 0) { + // window.$message.info('设备未被忽略'); + // return; + // } + // await deleteCameraIgnoreApi([...records.map((record) => record.id ?? '')]); + // window.$message.success('取消忽略设备成功'); + // }, + // onError: (error) => { + // console.error(error); + // const errorFeedback = parseErrorFeedback(error); + // window.$message.error(errorFeedback); + // }, + // }); + + const alarmActionColumn: DataTableColumn = { + title: '操作', + key: 'action', + width: 120, + align: 'center', + render: (rowData) => { + const { id } = rowData; + return h( + NFlex, + { + size: 'small', + justify: 'center', + align: 'center', + }, + { + default: () => [ + rowData.alarmConfirm === '1' + ? h(NButton, { disabled: true, secondary: true, type: 'info', size: 'tiny' }, { default: () => '确认' }) + : h( + NPopconfirm, + { + onPositiveClick: () => confirmAlarm({ id }), + }, + { + trigger: () => h(NButton, { secondary: true, type: 'info', size: 'tiny' }, { default: () => '确认' }), + default: () => '确认告警?', + }, + ), + tryGetDeviceType(rowData.deviceType) === DEVICE_TYPE_LITERALS.ndmCamera && [ + h( + NPopconfirm, + { + onPositiveClick: () => ignoreCamera({ id }), + }, + { + trigger: () => h(NButton, { tertiary: true, type: 'info', size: 'tiny' }, { default: () => '忽略' }), + default: () => '忽略设备?', + }, + ), + // h( + // NPopconfirm, + // { + // onPositiveClick: () => noticeCamera({ id }), + // }, + // { + // trigger: () => h(NButton, { text: true, type: 'info', size: 'small' }, { icon: () => h(EyeOutlined) }), + // default: () => '取消忽略设备?', + // }, + // ), + ], + ], + }, + ); + }, + }; + + return { + alarmActionColumn, + }; +}; diff --git a/src/composables/alarm/use-camera-snap-column.ts b/src/composables/alarm/use-camera-snap-column.ts new file mode 100644 index 0000000..db91e5d --- /dev/null +++ b/src/composables/alarm/use-camera-snap-column.ts @@ -0,0 +1,66 @@ +import { getCameraSnapApi, type NdmDeviceAlarmLogResultVO } from '@/apis'; +import { tryGetDeviceType, DEVICE_TYPE_LITERALS } from '@/enums'; +import { parseErrorFeedback } from '@/utils'; +import { useMutation } from '@tanstack/vue-query'; +import { NButton, NImage, type DataTableColumn, type DataTableRowData } from 'naive-ui'; +import { h, ref, watch, type Ref } from 'vue'; + +export const useCameraSnapColumn = (tableData: Ref) => { + const { mutateAsync: getSnapByDeviceId } = useMutation({ + mutationFn: async (params: { deviceAlarmLog: NdmDeviceAlarmLogResultVO }) => { + const { deviceAlarmLog } = params; + const { deviceId } = deviceAlarmLog; + if (!deviceId) throw new Error('设备ID不能为空'); + const snap = await getCameraSnapApi(deviceId); + return snap; + }, + onError: (error) => { + console.error(error); + const errorFeedback = parseErrorFeedback(error); + window.$message.error(errorFeedback); + }, + }); + + // 控制每一行的查看按钮loading状态 + const loadingMap = ref>({}); + watch(tableData, () => { + loadingMap.value = {}; + }); + + const cameraSnapColumn: DataTableColumn = { + title: '实时画面截图', + key: 'snapUrl', + align: 'center', + render: (rowData) => { + const { deviceType: deviceTypeCode, snapUrl } = rowData; + const deviceType = tryGetDeviceType(deviceTypeCode); + if (deviceType !== DEVICE_TYPE_LITERALS.ndmCamera) return null; + if (!snapUrl) { + const id = rowData.id ?? ''; + return h( + NButton, + { + type: 'info', + size: 'small', + loading: !!loadingMap.value[id], + onClick: async () => { + loadingMap.value[id] = true; + try { + const snap = await getSnapByDeviceId({ deviceAlarmLog: rowData }); + rowData.snapUrl = snap.url; + } finally { + loadingMap.value[id] = false; + } + }, + }, + { default: () => '查看' }, + ); + } else { + return h(NImage, { src: snapUrl, previewDisabled: false, showToolbar: false }); + } + }, + }; + return { + cameraSnapColumn, + }; +}; diff --git a/src/composables/device/index.ts b/src/composables/device/index.ts new file mode 100644 index 0000000..95da067 --- /dev/null +++ b/src/composables/device/index.ts @@ -0,0 +1 @@ +export * from './use-device-tree'; diff --git a/src/composables/device/use-device-tree.ts b/src/composables/device/use-device-tree.ts new file mode 100644 index 0000000..3443606 --- /dev/null +++ b/src/composables/device/use-device-tree.ts @@ -0,0 +1,89 @@ +import type { LineDevices, NdmDeviceResultVO } from '@/apis'; +import { tryGetDeviceType, type DeviceType } from '@/enums'; +import { ref, watch } from 'vue'; +import { useRoute, useRouter } from 'vue-router'; + +export const useDeviceTree = () => { + const route = useRoute(); + const router = useRouter(); + + const selectedStationCode = ref(); + const selectedDeviceType = ref(); + const selectedDevice = ref(); + + const initFromRoute = (lineDevices: LineDevices) => { + const { stationCode, deviceType, deviceDbId } = route.query; + if (stationCode) { + selectedStationCode.value = stationCode as string; + } + if (deviceType) { + selectedDeviceType.value = deviceType as DeviceType; + } + if (deviceDbId && selectedStationCode.value && selectedDeviceType.value) { + const selectedDeviceDbId = deviceDbId as string; + const stationDevices = lineDevices[selectedStationCode.value]; + if (stationDevices) { + const devices = stationDevices[selectedDeviceType.value]; + if (devices) { + const device = devices.find((device) => device.id === selectedDeviceDbId); + if (device) { + selectedDevice.value = device; + } + } + } + } + }; + + const selectDevice = (device: NdmDeviceResultVO, stationCode: string) => { + selectedDevice.value = device; + selectedStationCode.value = stationCode; + const deviceType = tryGetDeviceType(device.deviceType); + if (deviceType) { + selectedDeviceType.value = deviceType; + } + }; + + const routeDevice = (device: NdmDeviceResultVO, stationCode: string, to: { path: string }) => { + const deviceDbId = device.id; + const deviceType = tryGetDeviceType(device.deviceType); + router.push({ + path: to.path, + query: { + stationCode, + deviceType, + deviceDbId, + from: route.path, + }, + }); + }; + + const syncToRoute = () => { + const query = { ...route.query }; + // 当选中的设备发生变化时,删除from参数 + if (selectedDevice.value?.id && route.query.deviceDbId !== selectedDevice.value.id) { + delete query['from']; + } + if (selectedStationCode.value) { + query['stationCode'] = selectedStationCode.value; + } + if (selectedDeviceType.value) { + query['deviceType'] = selectedDeviceType.value; + } + if (selectedDevice.value?.id) { + query['deviceDbId'] = selectedDevice.value.id; + } + router.replace({ query }); + }; + + watch(selectedDevice, syncToRoute); + + return { + selectedStationCode, + selectedDeviceType, + selectedDevice, + + initFromRoute, + selectDevice, + routeDevice, + }; +}; diff --git a/src/composables/index.ts b/src/composables/index.ts new file mode 100644 index 0000000..0e70e34 --- /dev/null +++ b/src/composables/index.ts @@ -0,0 +1,4 @@ +export * from './alarm'; +export * from './device'; +export * from './query'; +export * from './stomp'; diff --git a/src/composables/query/index.ts b/src/composables/query/index.ts new file mode 100644 index 0000000..84f547f --- /dev/null +++ b/src/composables/query/index.ts @@ -0,0 +1,4 @@ +export * from './use-line-alarms-query'; +export * from './use-line-devices-query'; +export * from './use-line-stations-query'; +export * from './use-version-check-query'; diff --git a/src/composables/query/use-line-alarms-query.ts b/src/composables/query/use-line-alarms-query.ts new file mode 100644 index 0000000..3452919 --- /dev/null +++ b/src/composables/query/use-line-alarms-query.ts @@ -0,0 +1,88 @@ +import { initStationAlarms, pageDeviceAlarmLogApi, type Station } from '@/apis'; +import { LINE_ALARMS_QUERY_KEY, STATION_ALARMS_MUTATION_KEY } from '@/constants'; +import { tryGetDeviceType } from '@/enums'; +import { useAlarmStore, useStationStore } from '@/stores'; +import { parseErrorFeedback } from '@/utils'; +import { CancelledError, useMutation, useQuery } from '@tanstack/vue-query'; +import { isCancel } from 'axios'; +import dayjs from 'dayjs'; +import { storeToRefs } from 'pinia'; +import { computed } from 'vue'; + +export const useStationAlarmsMutation = () => { + const alarmStore = useAlarmStore(); + + return useMutation({ + mutationKey: [STATION_ALARMS_MUTATION_KEY], + mutationFn: async (params: { station: Station; signal?: AbortSignal }) => { + const { station, signal } = params; + const stationAlarms = initStationAlarms(); + if (!station.online) { + return stationAlarms; + } + const now = dayjs(); + const todayStart = now.startOf('date').valueOf(); + const todayEnd = now.endOf('date').valueOf(); + const { records } = await pageDeviceAlarmLogApi( + { + model: { + stationCode: station.code, + }, + extra: { + alarmDate_ge: todayStart, + alarmDate_le: todayEnd, + }, + size: 50000, + current: 1, + sort: 'alarmDate', + order: 'descending', + }, + { + stationCode: station.code, + signal, + }, + ); + for (const alarm of records) { + const { deviceType: deviceTypeCode } = alarm; + const deviceType = tryGetDeviceType(deviceTypeCode); + if (!!deviceType) { + stationAlarms[deviceType].unshift(alarm); + } + } + stationAlarms['unclassified'] = records; + return stationAlarms; + }, + onSuccess: (stationAlarms, { station }) => { + alarmStore.setStationAlarms(station.code, stationAlarms); + }, + onError: (error) => { + console.error(error); + if (isCancel(error) || error instanceof CancelledError) return; + const errorFeedback = parseErrorFeedback(error); + window.$message.error(errorFeedback); + }, + }); +}; + +/** + * 由 `useLineStationsQuery` 显式触发 + * @see [use-line-stations-query.ts](./use-line-stations-query.ts) + */ +export const useLineAlarmsQuery = () => { + const stationStore = useStationStore(); + const { stations } = storeToRefs(stationStore); + const { mutateAsync: getStationAlarms } = useStationAlarmsMutation(); + + return useQuery({ + queryKey: computed(() => [LINE_ALARMS_QUERY_KEY]), + enabled: false, + queryFn: async ({ signal }) => { + console.time(LINE_ALARMS_QUERY_KEY); + for (const station of stations.value) { + await getStationAlarms({ station, signal }).catch(() => {}); + } + console.timeEnd(LINE_ALARMS_QUERY_KEY); + return null; + }, + }); +}; diff --git a/src/composables/query/use-line-devices-query.ts b/src/composables/query/use-line-devices-query.ts new file mode 100644 index 0000000..146122f --- /dev/null +++ b/src/composables/query/use-line-devices-query.ts @@ -0,0 +1,55 @@ +import { getAllDevicesApi, initStationDevices, type Station } from '@/apis'; +import { LINE_DEVICES_QUERY_KEY, STATION_DEVICES_MUTATION_KEY } from '@/constants'; +import { useDeviceStore, useStationStore } from '@/stores'; +import { parseErrorFeedback } from '@/utils'; +import { CancelledError, useMutation, useQuery } from '@tanstack/vue-query'; +import { isCancel } from 'axios'; +import { storeToRefs } from 'pinia'; +import { computed } from 'vue'; + +export const useStationDevicesMutation = () => { + const deviceStore = useDeviceStore(); + + return useMutation({ + mutationKey: [STATION_DEVICES_MUTATION_KEY], + mutationFn: async (params: { station: Station; signal?: AbortSignal }) => { + const { station, signal } = params; + if (!station.online) { + return initStationDevices(); + } + return await getAllDevicesApi({ stationCode: station.code, signal }); + }, + onSuccess: (devices, { station }) => { + deviceStore.setStationDevices(station.code, devices); + }, + onError: (error) => { + console.error(error); + if (isCancel(error) || error instanceof CancelledError) return; + const errorFeedback = parseErrorFeedback(error); + window.$message.error(errorFeedback); + }, + }); +}; + +/** + * 由 `useLineStationsQuery` 显式触发 + * @see [use-line-stations-query.ts](./use-line-stations-query.ts) + */ +export const useLineDevicesQuery = () => { + const stationStore = useStationStore(); + const { stations } = storeToRefs(stationStore); + const { mutateAsync: getStationDevices } = useStationDevicesMutation(); + + return useQuery({ + queryKey: computed(() => [LINE_DEVICES_QUERY_KEY]), + enabled: false, + queryFn: async ({ signal }) => { + console.time(LINE_DEVICES_QUERY_KEY); + for (const station of stations.value) { + await getStationDevices({ station, signal }).catch(() => {}); + } + console.timeEnd(LINE_DEVICES_QUERY_KEY); + return null; + }, + }); +}; diff --git a/src/composables/query/use-line-stations-query.ts b/src/composables/query/use-line-stations-query.ts new file mode 100644 index 0000000..4223d67 --- /dev/null +++ b/src/composables/query/use-line-stations-query.ts @@ -0,0 +1,73 @@ +import { batchVerifyApi, type Station } from '@/apis'; +import { LINE_STATIONS_MUTATION_KEY, LINE_STATIONS_QUERY_KEY } from '@/constants'; +import { usePollingStore, useStationStore } from '@/stores'; +import { getAppEnvConfig, parseErrorFeedback } from '@/utils'; +import { CancelledError, useMutation, useQuery } from '@tanstack/vue-query'; +import axios, { isCancel } from 'axios'; +import dayjs from 'dayjs'; +import { storeToRefs } from 'pinia'; +import { computed } from 'vue'; +import { useLineDevicesQuery } from './use-line-devices-query'; +import { useLineAlarmsQuery } from './use-line-alarms-query'; + +export const useLineStationsMutation = () => { + const stationStore = useStationStore(); + + return useMutation({ + mutationKey: [LINE_STATIONS_MUTATION_KEY], + mutationFn: async (params: { signal?: AbortSignal }) => { + const { signal } = params; + const { data: ndmStationList } = await axios.get<{ code: string; name: string }[]>(`/minio/ndm/ndm-stations.json?_t=${dayjs().unix()}`, { signal }); + const stations = ndmStationList.map((station) => ({ + code: station.code ?? '', + name: station.name ?? '', + online: false, + ip: '', + })); + const verifyList = await batchVerifyApi({ signal }); + return stations.map((station) => ({ + ...station, + online: !!verifyList.find((verify) => verify.stationCode === station.code)?.onlineState, + ip: verifyList.find((verify) => verify.stationCode === station.code)?.ipAddress ?? '', + })); + }, + onSuccess: (stations) => { + stationStore.setStations(stations); + }, + onError: (error) => { + console.error(error); + if (isCancel(error) || error instanceof CancelledError) return; + const errorFeedback = parseErrorFeedback(error); + window.$message.error(errorFeedback); + }, + }); +}; + +export const useLineStationsQuery = () => { + const pollingStore = usePollingStore(); + const { pollingEnabled } = storeToRefs(pollingStore); + const { requestInterval } = getAppEnvConfig(); + const { mutateAsync: getLineStations } = useLineStationsMutation(); + const { refetch: refetchLineDevicesQuery } = useLineDevicesQuery(); + const { refetch: refetchLineAlarmsQuery } = useLineAlarmsQuery(); + + return useQuery({ + queryKey: computed(() => [LINE_STATIONS_QUERY_KEY]), + enabled: computed(() => pollingEnabled.value), + refetchInterval: requestInterval * 1000, + staleTime: (requestInterval * 1000) / 2, + queryFn: async ({ signal }) => { + console.time(LINE_STATIONS_QUERY_KEY); + await getLineStations({ signal }).catch(() => {}); + console.timeEnd(LINE_STATIONS_QUERY_KEY); + + if (!pollingEnabled.value) return null; + await refetchLineDevicesQuery(); + + if (!pollingEnabled.value) return null; + await refetchLineAlarmsQuery(); + + return null; + }, + }); +}; diff --git a/src/composables/query/use-version-check-query.ts b/src/composables/query/use-version-check-query.ts new file mode 100644 index 0000000..e952873 --- /dev/null +++ b/src/composables/query/use-version-check-query.ts @@ -0,0 +1,75 @@ +import { verifyApi, type VersionInfo } from '@/apis'; +import { VERSION_CHECK_QUERY_KEY } from '@/constants'; +import { useSettingStore, useUserStore } from '@/stores'; +import { useQuery, useQueryClient } from '@tanstack/vue-query'; +import axios from 'axios'; +import { useThemeVars } from 'naive-ui'; +import { storeToRefs } from 'pinia'; +import { computed, h, ref, watch } from 'vue'; + +export const useVersionCheckQuery = () => { + const localVersionInfo = ref(); + const showDialog = ref(false); + const themeVars = useThemeVars(); + const queryClient = useQueryClient(); + const userStore = useUserStore(); + const { userLoginResult } = storeToRefs(userStore); + const settingStore = useSettingStore(); + const { offlineDev } = storeToRefs(settingStore); + + const { data: remoteVersionInfo, dataUpdatedAt } = useQuery({ + queryKey: [VERSION_CHECK_QUERY_KEY], + enabled: computed(() => !offlineDev.value), + refetchInterval: 10 * 1000, + queryFn: async ({ signal }) => { + if (!!userLoginResult.value?.token) await verifyApi({ signal }); + const { data } = await axios.get(`/manifest.json?t=${Date.now()}`, { signal }); + return data; + }, + }); + + watch(offlineDev, (offline) => { + if (offline) { + queryClient.cancelQueries({ queryKey: [VERSION_CHECK_QUERY_KEY] }); + } + }); + + watch(dataUpdatedAt, () => { + const newVersionInfo = remoteVersionInfo.value; + if (!newVersionInfo) return; + + if (!localVersionInfo.value) { + localVersionInfo.value = newVersionInfo; + return; + } + + const { version: localVersion, buildTime: localBuildTime } = localVersionInfo.value; + const { version: remoteVersion, buildTime: remoteBuildTime } = newVersionInfo; + + if ((localVersion !== remoteVersion || localBuildTime !== remoteBuildTime) && !showDialog.value) { + showDialog.value = true; + window.$dialog.info({ + title: '发现新版本', + content: () => + h('div', {}, [ + h('div', {}, { default: () => `当前版本:${localVersionInfo.value?.version}` }), + h('div', {}, { default: () => `最新版本:${newVersionInfo.version}` }), + h('div', {}, { default: () => '请点击刷新页面以更新' }), + h('div', { style: { marginTop: '8px', fontWeight: '700', color: themeVars.value.warningColor } }, { default: () => '⚠️ 注意,更新后可能需要重新登录或调整系统设置!' }), + ]), + positiveText: '刷新页面', + maskClosable: false, + onPositiveClick: () => { + window.location.reload(); + }, + negativeText: '稍后检查', + onNegativeClick: () => { + showDialog.value = false; + }, + onClose: () => { + showDialog.value = false; + }, + }); + } + }); +}; diff --git a/src/composables/stomp/index.ts b/src/composables/stomp/index.ts new file mode 100644 index 0000000..79f111c --- /dev/null +++ b/src/composables/stomp/index.ts @@ -0,0 +1 @@ +export * from './use-stomp-client'; diff --git a/src/composables/stomp/use-stomp-client.ts b/src/composables/stomp/use-stomp-client.ts new file mode 100644 index 0000000..12533bd --- /dev/null +++ b/src/composables/stomp/use-stomp-client.ts @@ -0,0 +1,123 @@ +import type { NdmDeviceAlarmLogResultVO, Station, SyncCameraResult } from '@/apis'; +import { ALARM_TOPIC, SYNC_CAMERA_STATUS_TOPIC } from '@/constants'; +import { useAlarmStore, useSettingStore, useStationStore } from '@/stores'; +import { Client } from '@stomp/stompjs'; +import { watchDebounced } from '@vueuse/core'; +import destr from 'destr'; +import { storeToRefs } from 'pinia'; +import { onBeforeUnmount, onMounted, ref, watch } from 'vue'; +import { useStationAlarmsMutation } from '../query'; + +const getBrokerUrl = () => { + const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; + const { host } = window.location; + const endpoint = '/ws'; + const brokerURL = `${protocol}//${host}${endpoint}`; + return brokerURL; +}; + +export const useStompClient = () => { + const stationStore = useStationStore(); + const { stations } = storeToRefs(stationStore); + const alarmStore = useAlarmStore(); + const { unreadLineAlarms } = storeToRefs(alarmStore); + const settingStore = useSettingStore(); + const { offlineDev } = storeToRefs(settingStore); + + const { mutate: refreshStationAlarms } = useStationAlarmsMutation(); + + const stompClient = ref(null); + + const syncCameraResult = ref>({}); + + onMounted(() => { + stompClient.value = new Client({ + brokerURL: getBrokerUrl(), + reconnectDelay: 5000, + heartbeatIncoming: 10000, + heartbeatOutgoing: 10000, + onConnect: () => { + console.log('Stomp连接成功'); + stompClient.value?.subscribe(ALARM_TOPIC, (message) => { + const alarm = destr(message.body); + if (alarm.alarmCategory === '1') { + alarmStore.pushUnreadAlarm(alarm); + } + }); + stompClient.value?.subscribe(SYNC_CAMERA_STATUS_TOPIC, (message) => { + const { stationCode, startTime, endTime, insertList, updateList, deleteList } = destr(message.body); + syncCameraResult.value[stationCode] = { stationCode, startTime, endTime, insertList, updateList, deleteList }; + }); + }, + onDisconnect: () => { + console.log('Stomp连接断开'); + stompClient.value?.unsubscribe(ALARM_TOPIC); + stompClient.value?.unsubscribe(SYNC_CAMERA_STATUS_TOPIC); + }, + onStompError: (frame) => { + console.log('Stomp错误', frame); + window.$message.error('Stomp错误'); + }, + onWebSocketError: (event: Event) => { + console.log('WebSocket错误', event); + window.$message.error('WebSocket错误'); + }, + }); + if (!offlineDev.value) { + stompClient.value.activate(); + } + }); + + onBeforeUnmount(() => { + stompClient.value?.deactivate(); + stompClient.value = null; + }); + + watch(offlineDev, (offline) => { + if (offline) { + stompClient.value?.deactivate(); + } else { + stompClient.value?.activate(); + } + }); + + // 当有车站的未读报警变化,即新收到告警时,需要同步告警数据, + // 但告警可能非常频繁,所以需要防抖处理 + const abortControllerMap = ref(new Map()); + watchDebounced( + () => Object.entries(unreadLineAlarms.value).map(([stationCode, stationAlarms]) => ({ stationCode, count: stationAlarms['unclassified'].length })), + (newValue, oldValue) => { + // 启用离线模式时,跳过处理 + if (offlineDev.value) return; + if (newValue.length === 0) return; + const codes: Station['code'][] = []; + newValue.forEach(({ stationCode, count }) => { + const prevState = oldValue.find((stat) => stat.stationCode === stationCode); + if (!prevState || count !== prevState.count) { + codes.push(stationCode); + } + }); + // console.log('以下车站收到新告警:', codes); + for (const stationCode of codes) { + const station = stations.value.find((station) => station.code === stationCode); + if (!station) continue; + abortControllerMap.value.get(stationCode)?.abort(); + abortControllerMap.value.set(stationCode, new AbortController()); + refreshStationAlarms({ station, signal: abortControllerMap.value.get(stationCode)?.signal }); + } + }, + { + debounce: 2500, + maxWait: 5000, + }, + ); + + return { + stompClient, + + syncCameraResult, + afterCheckSyncCameraResult: () => { + syncCameraResult.value = {}; + }, + }; +}; diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..f2a2009 --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,5 @@ +export * from './java'; +export * from './mutation'; +export * from './query'; +export * from './stomp'; +export * from './store'; diff --git a/src/constants/java.ts b/src/constants/java.ts new file mode 100644 index 0000000..ccbb768 --- /dev/null +++ b/src/constants/java.ts @@ -0,0 +1,2 @@ +export const JAVA_INTEGER_MAX_VALUE = 2147483647; +export const JAVA_UNSIGNED_INTEGER_MAX_VALUE = 4294967295; diff --git a/src/constants/mutation.ts b/src/constants/mutation.ts new file mode 100644 index 0000000..42b44db --- /dev/null +++ b/src/constants/mutation.ts @@ -0,0 +1,3 @@ +export const LINE_STATIONS_MUTATION_KEY = 'LINE_STATIONS_MUTATION_KEY'; +export const STATION_ALARMS_MUTATION_KEY = 'STATION_ALARMS_MUTATION_KEY'; +export const STATION_DEVICES_MUTATION_KEY = 'STATION_DEVICES_MUTATION_KEY'; diff --git a/src/constants/query.ts b/src/constants/query.ts new file mode 100644 index 0000000..401b533 --- /dev/null +++ b/src/constants/query.ts @@ -0,0 +1,4 @@ +export const LINE_ALARMS_QUERY_KEY = 'line-alarms'; +export const LINE_DEVICES_QUERY_KEY = 'line-devices'; +export const LINE_STATIONS_QUERY_KEY = 'line-stations'; +export const VERSION_CHECK_QUERY_KEY = 'version-check'; diff --git a/src/constants/stomp.ts b/src/constants/stomp.ts new file mode 100644 index 0000000..50ca2f0 --- /dev/null +++ b/src/constants/stomp.ts @@ -0,0 +1,3 @@ +export const ALARM_TOPIC = '/topic/deviceAlarm'; + +export const SYNC_CAMERA_STATUS_TOPIC = '/topic/syncCameraStatus'; diff --git a/src/constants/store.ts b/src/constants/store.ts new file mode 100644 index 0000000..d78ab37 --- /dev/null +++ b/src/constants/store.ts @@ -0,0 +1,6 @@ +export const NDM_ALARM_STORE_ID = 'ndm-alarm-store'; +export const NDM_DEVICE_STORE_ID = 'ndm-device-store'; +export const NDM_POLLIING_STORE_ID = 'ndm-polling-store'; +export const NDM_SETTING_STORE_ID = 'ndm-setting-store'; +export const NDM_STATION_STORE_ID = 'ndm-station-store'; +export const NDM_USER_STORE_ID = 'ndm-user-store'; diff --git a/src/enums/alarm-type.ts b/src/enums/alarm-type.ts new file mode 100644 index 0000000..97e988b --- /dev/null +++ b/src/enums/alarm-type.ts @@ -0,0 +1,6 @@ +export const ALARM_TYPES: Record = { + '1': '设备告警', + '2': '环境告警', + '3': '性能告警', + '': '-', +}; diff --git a/src/enums/device-type.ts b/src/enums/device-type.ts new file mode 100644 index 0000000..2ba431f --- /dev/null +++ b/src/enums/device-type.ts @@ -0,0 +1,47 @@ +import type { Optional } from '@/types/util-type'; + +// 这个还决定了设备树组件的Tab顺序 +export const DEVICE_TYPE_LITERALS = { + ndmCamera: 'ndmCamera', + ndmNvr: 'ndmNvr', + ndmSwitch: 'ndmSwitch', + ndmDecoder: 'ndmDecoder', + ndmSecurityBox: 'ndmSecurityBox', + ndmMediaServer: 'ndmMediaServer', + ndmVideoServer: 'ndmVideoServer', + ndmKeyboard: 'ndmKeyboard', + ndmAlarmHost: 'ndmAlarmHost', +} as const; + +export type DeviceType = keyof typeof DEVICE_TYPE_LITERALS; + +export const DEVICE_TYPE_CODES: Record = { + [DEVICE_TYPE_LITERALS.ndmAlarmHost]: ['117'], + [DEVICE_TYPE_LITERALS.ndmCamera]: ['131', '132'], + [DEVICE_TYPE_LITERALS.ndmDecoder]: ['114'], + [DEVICE_TYPE_LITERALS.ndmKeyboard]: ['141'], + [DEVICE_TYPE_LITERALS.ndmMediaServer]: ['403'], + [DEVICE_TYPE_LITERALS.ndmNvr]: ['111', '118'], + [DEVICE_TYPE_LITERALS.ndmSecurityBox]: ['222'], + [DEVICE_TYPE_LITERALS.ndmSwitch]: ['220'], + [DEVICE_TYPE_LITERALS.ndmVideoServer]: ['401'], +} as const; + +export const DEVICE_TYPE_NAMES: Record = { + [DEVICE_TYPE_LITERALS.ndmAlarmHost]: '报警主机', + [DEVICE_TYPE_LITERALS.ndmCamera]: '网络摄像机', + [DEVICE_TYPE_LITERALS.ndmDecoder]: '解码器', + [DEVICE_TYPE_LITERALS.ndmKeyboard]: '网络键盘', + [DEVICE_TYPE_LITERALS.ndmMediaServer]: '媒体服务器', + [DEVICE_TYPE_LITERALS.ndmNvr]: '网络录像机', + [DEVICE_TYPE_LITERALS.ndmSecurityBox]: '智能安防箱', + [DEVICE_TYPE_LITERALS.ndmSwitch]: '交换机', + [DEVICE_TYPE_LITERALS.ndmVideoServer]: '视频服务器', +} as const; + +export const tryGetDeviceType = (deviceTypeCode: Optional) => { + if (!deviceTypeCode) return null; + const entry = Object.entries(DEVICE_TYPE_CODES).find(([, codes]) => codes.includes(deviceTypeCode)); + if (!entry) return null; + return entry[0] as DeviceType; +}; diff --git a/src/enums/fault-level.ts b/src/enums/fault-level.ts new file mode 100644 index 0000000..9446044 --- /dev/null +++ b/src/enums/fault-level.ts @@ -0,0 +1,7 @@ +export const FAULT_LEVELS: Record = { + 1: '严重', + 2: '重要', + 3: '一般', + 4: '提示', + '': '-', +}; diff --git a/src/enums/index.ts b/src/enums/index.ts new file mode 100644 index 0000000..ca20593 --- /dev/null +++ b/src/enums/index.ts @@ -0,0 +1,3 @@ +export * from './alarm-type'; +export * from './device-type'; +export * from './fault-level'; diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000..e3f2be9 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,12 @@ +import { useDialog, useLoadingBar, useMessage, useNotification } from 'naive-ui'; +import type { Ref } from 'vue'; + +declare global { + interface Window { + $dialog: ReturnType; + $loadingBar: ReturnType; + $message: ReturnType; + $notification: ReturnType; + $offlineDev: Ref; + } +} diff --git a/src/helpers/device-alarm.ts b/src/helpers/device-alarm.ts new file mode 100644 index 0000000..6971147 --- /dev/null +++ b/src/helpers/device-alarm.ts @@ -0,0 +1,89 @@ +import type { NdmDeviceAlarmLogResultVO, NdmDeviceResultVO, NdmNvrResultVO } from '@/apis'; +import { ALARM_TYPES, DEVICE_TYPE_LITERALS, DEVICE_TYPE_NAMES, FAULT_LEVELS, tryGetDeviceType } from '@/enums'; +import dayjs from 'dayjs'; +import { NButton, NPopover, NScrollbar, NTag, type TagProps } from 'naive-ui'; +import { h } from 'vue'; + +export const renderAlarmDateCell = (rowData: NdmDeviceAlarmLogResultVO) => { + return dayjs(Number(rowData.alarmDate ?? 0)).format('YYYY-MM-DD HH:mm:ss'); +}; + +export const renderDeviceTypeCell = (rowData: NdmDeviceAlarmLogResultVO) => { + const deviceTypeVal = tryGetDeviceType(rowData.deviceType); + if (!deviceTypeVal) return '-'; + return DEVICE_TYPE_NAMES[deviceTypeVal]; +}; + +export const renderAlarmTypeCell = (rowData: NdmDeviceAlarmLogResultVO) => { + const { alarmType } = rowData; + if (!alarmType) { + return ''; + } + return h(NTag, { type: 'default' }, { default: () => ALARM_TYPES[alarmType] }); +}; + +export const renderFaultLevelCell = (rowData: NdmDeviceAlarmLogResultVO) => { + const { faultLevel } = rowData; + if (!faultLevel) { + return ''; + } + let type: TagProps['type'] = 'default'; + if (faultLevel === '1') { + type = 'error'; + } else if (faultLevel === '2') { + type = 'warning'; + } else if (faultLevel === '3') { + type = 'info'; + } + return h(NTag, { type }, { default: () => FAULT_LEVELS[faultLevel] }); +}; + +export const renderFaultDescriptionCell = (rowData: NdmDeviceAlarmLogResultVO, ndmDevice: NdmDeviceResultVO) => { + const isNvrCluster = (ndmDevice: NdmDeviceResultVO) => { + const deviceType = tryGetDeviceType(ndmDevice.deviceType); + if (!deviceType) return false; + const isNvr = deviceType === DEVICE_TYPE_LITERALS.ndmNvr; + if (!isNvr) return false; + const maybeNvrCluster = ndmDevice as NdmNvrResultVO; + return !!maybeNvrCluster.clusterList?.trim() && maybeNvrCluster.clusterList !== maybeNvrCluster.ipAddress; + }; + if (!isNvrCluster(ndmDevice)) { + return rowData.faultDescription; + } + return h( + NPopover, + { + trigger: 'click', + }, + { + trigger: () => { + return h( + NButton, + { + text: true, + type: 'info', + }, + { + default: () => '查看', + }, + ); + }, + default: () => { + return h( + NScrollbar, + { + style: { + width: '800px', + 'max-height': '400px', + }, + }, + { + default: () => { + return h('pre', {}, { default: () => rowData.faultDescription?.split('; ').join('\n') ?? '' }); + }, + }, + ); + }, + }, + ); +}; diff --git a/src/helpers/export-record-diag-csv.ts b/src/helpers/export-record-diag-csv.ts new file mode 100644 index 0000000..26594a7 --- /dev/null +++ b/src/helpers/export-record-diag-csv.ts @@ -0,0 +1,26 @@ +import type { Station } from '@/apis'; +import type { NvrRecordDiag } from './record-check'; +import { downloadByData, formatDuration } from '@/utils'; +import dayjs from 'dayjs'; + +export const exportRecordDiagCsv = (recordDiags: NvrRecordDiag[], stationName: Station['name']) => { + const csvHeader = '通道名称,开始时间,结束时间,持续时长\n'; + const csvRows = recordDiags + .map((channel) => { + if (channel.lostChunks.length === 0) { + return `${channel.channelName},,,`; + } + return channel.lostChunks + .map((loss) => { + const duration = formatDuration(loss.startTime, loss.endTime); + const startTime = dayjs(loss.startTime).format('YYYY-MM-DD HH:mm:ss'); + const endTime = dayjs(loss.endTime).format('YYYY-MM-DD HH:mm:ss'); + return `${channel.channelName},${startTime},${endTime},${duration}`; + }) + .join('\n'); + }) + .join('\n'); + const csvContent = csvHeader.concat(csvRows); + const time = dayjs().format('YYYY-MM-DD_HH-mm-ss'); + downloadByData(csvContent, `${stationName}_录像缺失记录_${time}.csv`, 'text/csv;charset=utf-8', '\ufeff'); +}; diff --git a/src/helpers/index.ts b/src/helpers/index.ts new file mode 100644 index 0000000..f3bdd0b --- /dev/null +++ b/src/helpers/index.ts @@ -0,0 +1,5 @@ +export * from './device-alarm'; +export * from './export-record-diag-csv'; +export * from './nvr-cluster'; +export * from './record-check'; +export * from './switch-port'; diff --git a/src/helpers/nvr-cluster.ts b/src/helpers/nvr-cluster.ts new file mode 100644 index 0000000..fe8f8c6 --- /dev/null +++ b/src/helpers/nvr-cluster.ts @@ -0,0 +1,8 @@ +import type { NdmNvrResultVO } from '@/apis'; + +export const isNvrCluster = (maybeNvrCluster: NdmNvrResultVO) => { + const { ipAddress, clusterList } = maybeNvrCluster; + if (!clusterList?.trim()) return false; + if (clusterList === ipAddress) return false; + return true; +}; diff --git a/src/helpers/record-check.ts b/src/helpers/record-check.ts new file mode 100644 index 0000000..e7f651a --- /dev/null +++ b/src/helpers/record-check.ts @@ -0,0 +1,69 @@ +import type { NdmRecordCheck, RecordInfo, RecordItem } from '@/apis'; +import dayjs from 'dayjs'; +import destr from 'destr'; +import { groupBy } from 'es-toolkit'; + +export type NvrRecordDiag = { + gbCode: string; + channelName: string; + recordDuration: RecordItem; + lostChunks: RecordItem[]; +}; + +// 解析出丢失的录像时间段 +export const transformRecordChecks = (rawRecordChecks: NdmRecordCheck[]): NvrRecordDiag[] => { + // 解析diagInfo + const parsedRecordChecks = rawRecordChecks.map((recordCheck) => ({ + ...recordCheck, + diagInfo: destr(recordCheck.diagInfo), + })); + // 按国标码分组 + const recordChecksByGbCode = groupBy(parsedRecordChecks, (recordCheck) => recordCheck.gbCode); + // 提取分组后的国标码和录像诊断记录 + const channelGbCodes = Object.keys(recordChecksByGbCode); + const recordChecksList = Object.values(recordChecksByGbCode); + // 初始化每个通道的录像诊断数据结构 + const recordDiags = channelGbCodes.map((gbCode, index) => ({ + gbCode, + channelName: recordChecksList.at(index)?.at(-1)?.name ?? '', + records: [] as RecordItem[], + lostChunks: [] as RecordItem[], + })); + // 写入同一gbCode的录像片段 + recordChecksList.forEach((recordChecks, index) => { + recordChecks.forEach((recordCheck) => { + recordDiags.at(index)?.records.push(...recordCheck.diagInfo.recordList); + }); + }); + // 过滤掉没有录像记录的通道 + const filteredRecordDiags = recordDiags.filter((recordDiag) => recordDiag.records.length > 0); + // 计算每个通道丢失的录像时间片段 + filteredRecordDiags.forEach((recordDiag) => { + recordDiag.records.forEach((record, index, records) => { + const nextRecordItem = records.at(index + 1); + if (!!nextRecordItem) { + // 如果下一段录像的开始时间不等于当前录像的结束时间,则判定为丢失 + const nextStartTime = nextRecordItem.startTime; + const currEndTime = record.endTime; + if (nextStartTime !== currEndTime) { + recordDiag.lostChunks.push({ + startTime: currEndTime, + endTime: nextStartTime, + }); + } + } + }); + }); + return recordDiags.map((recordDiag) => { + const firstRecord = recordDiag.records.at(0); + const startTime = firstRecord ? dayjs(firstRecord.startTime).format('YYYY-MM-DD HH:mm:ss') : ''; + const lastRecord = recordDiag.records.at(-1); + const endTime = lastRecord ? dayjs(lastRecord.endTime).format('YYYY-MM-DD HH:mm:ss') : ''; + return { + gbCode: recordDiag.gbCode, + channelName: recordDiag.channelName, + recordDuration: { startTime, endTime }, + lostChunks: recordDiag.lostChunks, + }; + }); +}; diff --git a/src/helpers/switch-port.ts b/src/helpers/switch-port.ts new file mode 100644 index 0000000..432367d --- /dev/null +++ b/src/helpers/switch-port.ts @@ -0,0 +1,26 @@ +import type { NdmSwitchPortInfo } from '@/apis'; + +export const getPortStatusValue = (portInfo: NdmSwitchPortInfo): string => { + const { upDown } = portInfo; + return upDown === 1 ? '已连接' : upDown === 2 ? '未连接' : '-'; +}; + +export const transformPortSpeed = (portInfo: NdmSwitchPortInfo, type: 'in' | 'out' | 'total'): string => { + const units = ['b/s', 'Kb/s', 'Mb/s', 'Gb/s', 'Tb/s']; + const { inFlow, outFlow, flow } = portInfo; + let result: number = 0; + if (type === 'in') { + result = inFlow; + } else if (type === 'out') { + result = outFlow; + } else if (type === 'total') { + result = flow; + } + let unit = 0; + result *= 8; + while (result >= 1024 && unit < units.length - 1) { + result /= 1024; + unit++; + } + return `${result.toFixed(3)} ${units[unit]}`; +}; diff --git a/src/layouts/app-layout.vue b/src/layouts/app-layout.vue new file mode 100644 index 0000000..29d2adf --- /dev/null +++ b/src/layouts/app-layout.vue @@ -0,0 +1,229 @@ + + + + + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..b954af3 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,31 @@ +import App from './App.vue'; +import router from './router'; +import { getAppEnvConfig } from './utils'; +import { persistToIndexedDB } from './plugins'; +import '@/styles/reset.scss'; +import { VueQueryPlugin } from '@tanstack/vue-query'; +import localforage from 'localforage'; +import { createApp } from 'vue'; +import { createPinia } from 'pinia'; +import persist from 'pinia-plugin-persistedstate'; + +const { storageVersion } = getAppEnvConfig(); +const localStorageVersion = window.localStorage.getItem('ndm-storage-version'); +if (localStorageVersion !== storageVersion) { + window.localStorage.clear(); + window.localStorage.setItem('ndm-storage-version', storageVersion); + await localforage.clear(); +} + +document.title = import.meta.env.VITE_APP_TITLE; + +const pinia = createPinia(); +pinia.use(persist); +pinia.use(persistToIndexedDB); + +const app = createApp(App); +app.use(pinia); +app.use(router); +app.use(VueQueryPlugin); + +app.mount('#app'); diff --git a/src/pages/alarm-page.vue b/src/pages/alarm-page.vue new file mode 100644 index 0000000..aeee126 --- /dev/null +++ b/src/pages/alarm-page.vue @@ -0,0 +1,305 @@ + + + + + diff --git a/src/pages/call-log-page.vue b/src/pages/call-log-page.vue new file mode 100644 index 0000000..299369d --- /dev/null +++ b/src/pages/call-log-page.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/src/pages/device-page.vue b/src/pages/device-page.vue new file mode 100644 index 0000000..efc680e --- /dev/null +++ b/src/pages/device-page.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/src/pages/login-page.vue b/src/pages/login-page.vue new file mode 100644 index 0000000..d35ca11 --- /dev/null +++ b/src/pages/login-page.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/pages/not-found-page.vue b/src/pages/not-found-page.vue new file mode 100644 index 0000000..e64aa47 --- /dev/null +++ b/src/pages/not-found-page.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/src/pages/station-page.vue b/src/pages/station-page.vue new file mode 100644 index 0000000..a609e7a --- /dev/null +++ b/src/pages/station-page.vue @@ -0,0 +1,225 @@ + + + + + diff --git a/src/pages/vimp-log-page.vue b/src/pages/vimp-log-page.vue new file mode 100644 index 0000000..20f7868 --- /dev/null +++ b/src/pages/vimp-log-page.vue @@ -0,0 +1,297 @@ + + + + + diff --git a/src/plugins/index.ts b/src/plugins/index.ts new file mode 100644 index 0000000..4882fa5 --- /dev/null +++ b/src/plugins/index.ts @@ -0,0 +1 @@ +export * from './pinia'; diff --git a/src/plugins/pinia/index.ts b/src/plugins/pinia/index.ts new file mode 100644 index 0000000..7552ec7 --- /dev/null +++ b/src/plugins/pinia/index.ts @@ -0,0 +1,8 @@ +declare module 'pinia' { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + export interface DefineStoreOptionsBase { + persistToIndexedDB?: boolean; + } +} + +export * from './persist-to-indexeddb'; diff --git a/src/plugins/pinia/persist-to-indexeddb.ts b/src/plugins/pinia/persist-to-indexeddb.ts new file mode 100644 index 0000000..5d535fd --- /dev/null +++ b/src/plugins/pinia/persist-to-indexeddb.ts @@ -0,0 +1,31 @@ +import { useDebounceFn } from '@vueuse/core'; +import destr from 'destr'; +import localforage from 'localforage'; +import type { PiniaPlugin } from 'pinia'; + +export const persistToIndexedDB: PiniaPlugin = (context) => { + const { options, store } = context; + const { persistToIndexedDB } = options; + + if (!persistToIndexedDB) return; + + localforage.getItem(store.$id).then((value) => { + if (value) { + // store.$patch(value); + store.$state = value; + } + }); + + const setItemToIndexedDB = useDebounceFn((state) => { + localforage.setItem(store.$id, destr(JSON.stringify(state))); + }, 1000); + + store.$subscribe( + (mutation, state) => { + setItemToIndexedDB(state); + }, + { + detached: true, + }, + ); +}; diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..2765563 --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,75 @@ +import { useUserStore } from '@/stores'; +import { createRouter, createWebHistory } from 'vue-router'; + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/login', + component: () => import('@/pages/login-page.vue'), + }, + { + path: '/', + component: () => import('@/layouts/app-layout.vue'), + redirect: '/station', + children: [ + { + path: 'station', + component: () => import('@/pages/station-page.vue'), + }, + { + path: 'device', + component: () => import('@/pages/device-page.vue'), + }, + { + path: 'alarm', + component: () => import('@/pages/alarm-page.vue'), + }, + { + path: 'log', + children: [ + { + path: 'vimp-log', + component: () => import('@/pages/vimp-log-page.vue'), + }, + { + path: 'call-log', + component: () => import('@/pages/call-log-page.vue'), + }, + ], + }, + { + path: '/:pathMatch(.*)*', + component: () => import('@/pages/not-found-page.vue'), + }, + ], + }, + ], +}); + +router.beforeEach((to) => { + const whiteList: string[] = []; + const inWhiteList = whiteList.some((path) => to.path.startsWith(path)); + if (inWhiteList) { + return true; + } + + const userStore = useUserStore(); + const isAuthed = !!userStore.userLoginResult?.token; + + if (to.path === '/login') { + if (isAuthed) { + return { path: '/' }; + } else { + return true; + } + } else { + if (!isAuthed) { + return { path: '/login' }; + } else { + return true; + } + } +}); + +export default router; diff --git a/src/stores/alarm.ts b/src/stores/alarm.ts new file mode 100644 index 0000000..99744c1 --- /dev/null +++ b/src/stores/alarm.ts @@ -0,0 +1,62 @@ +import { initStationAlarms, type LineAlarms, type NdmDeviceAlarmLogResultVO, type Station, type StationAlarms } from '@/apis'; +import { NDM_ALARM_STORE_ID } from '@/constants'; +import { tryGetDeviceType } from '@/enums'; +import { defineStore } from 'pinia'; +import { computed, shallowRef, triggerRef } from 'vue'; + +export const useAlarmStore = defineStore( + NDM_ALARM_STORE_ID, + () => { + // 全线所有车站的告警 + const lineAlarms = shallowRef({}); // 数据量很大所以用shallowRef配合triggerRef优化性能 + const setLineAlarms = (alarms: LineAlarms) => { + lineAlarms.value = alarms; + triggerRef(lineAlarms); + }; + const setStationAlarms = (stationCode: Station['code'], alarms: StationAlarms) => { + lineAlarms.value[stationCode] = alarms; + triggerRef(lineAlarms); + }; + + // 全线所有车站的未读告警 (来自stomp订阅) + const unreadLineAlarms = shallowRef({}); + const unreadAlarmCount = computed(() => { + let count = 0; + Object.values(unreadLineAlarms.value).forEach((stationAlarms) => { + count += stationAlarms['unclassified'].length; + }); + return count; + }); + const pushUnreadAlarm = (alarm: NdmDeviceAlarmLogResultVO) => { + const stationCode = alarm.stationCode; + if (!stationCode) return; + if (!unreadLineAlarms.value[stationCode]) { + unreadLineAlarms.value[stationCode] = initStationAlarms(); + } + const deviceType = tryGetDeviceType(alarm.deviceType); + if (!deviceType) return; + const stationAlarms = unreadLineAlarms.value[stationCode]; + stationAlarms[deviceType].push(alarm); + stationAlarms['unclassified'].push(alarm); + triggerRef(unreadLineAlarms); + }; + const clearUnreadAlarms = () => { + unreadLineAlarms.value = {}; + triggerRef(unreadLineAlarms); + }; + + return { + lineAlarms, + setLineAlarms, + setStationAlarms, + + unreadLineAlarms, + unreadAlarmCount, + pushUnreadAlarm, + clearUnreadAlarms, + }; + }, + { + persistToIndexedDB: true, + }, +); diff --git a/src/stores/device.ts b/src/stores/device.ts new file mode 100644 index 0000000..0885235 --- /dev/null +++ b/src/stores/device.ts @@ -0,0 +1,46 @@ +import type { LineDevices, NdmDeviceResultVO, Station, StationDevices } from '@/apis'; +import { NDM_DEVICE_STORE_ID } from '@/constants'; +import { tryGetDeviceType } from '@/enums'; +import { defineStore } from 'pinia'; +import { shallowRef, triggerRef } from 'vue'; + +export const useDeviceStore = defineStore( + NDM_DEVICE_STORE_ID, + () => { + // 全线所有车站的设备 + const lineDevices = shallowRef({}); // 数据量很大所以用shallowRef配合triggerRef优化性能 + + const setLineDevices = (devices: LineDevices) => { + lineDevices.value = devices; + }; + + const setStationDevices = (stationCode: Station['code'], devices: StationDevices) => { + lineDevices.value[stationCode] = devices; + triggerRef(lineDevices); + }; + + const patchDevice = (stationCode: Station['code'], device: NdmDeviceResultVO) => { + const deviceType = tryGetDeviceType(device.deviceType); + if (!!deviceType) { + if (lineDevices.value[stationCode]) { + const index = lineDevices.value[stationCode][deviceType].findIndex((d) => d.id === device.id); + if (index > -1) { + lineDevices.value[stationCode][deviceType][index] = device; + triggerRef(lineDevices); + } + } + } + }; + + return { + lineDevices, + + setLineDevices, + setStationDevices, + patchDevice, + }; + }, + { + persistToIndexedDB: true, + }, +); diff --git a/src/stores/index.ts b/src/stores/index.ts new file mode 100644 index 0000000..080721b --- /dev/null +++ b/src/stores/index.ts @@ -0,0 +1,6 @@ +export * from './alarm'; +export * from './device'; +export * from './polling'; +export * from './setting'; +export * from './station'; +export * from './user'; diff --git a/src/stores/polling.ts b/src/stores/polling.ts new file mode 100644 index 0000000..eabc7b2 --- /dev/null +++ b/src/stores/polling.ts @@ -0,0 +1,35 @@ +import { LINE_ALARMS_QUERY_KEY, LINE_DEVICES_QUERY_KEY, LINE_STATIONS_QUERY_KEY, NDM_POLLIING_STORE_ID } from '@/constants'; +import { useQueryClient } from '@tanstack/vue-query'; +import { defineStore } from 'pinia'; +import { ref } from 'vue'; + +export const usePollingStore = defineStore( + NDM_POLLIING_STORE_ID, + () => { + const queryClient = useQueryClient(); + + // 允许控制轮询 + const pollingEnabled = ref(true); + const startPolling = () => { + pollingEnabled.value = true; + }; + const stopPolling = () => { + pollingEnabled.value = false; + queryClient.cancelQueries({ queryKey: [LINE_STATIONS_QUERY_KEY] }); + queryClient.cancelQueries({ queryKey: [LINE_DEVICES_QUERY_KEY] }); + queryClient.cancelQueries({ queryKey: [LINE_ALARMS_QUERY_KEY] }); + queryClient.invalidateQueries({ queryKey: [LINE_STATIONS_QUERY_KEY] }); + queryClient.invalidateQueries({ queryKey: [LINE_DEVICES_QUERY_KEY] }); + queryClient.invalidateQueries({ queryKey: [LINE_ALARMS_QUERY_KEY] }); + }; + + return { + pollingEnabled, + startPolling, + stopPolling, + }; + }, + { + persist: true, + }, +); diff --git a/src/stores/setting.ts b/src/stores/setting.ts new file mode 100644 index 0000000..55337af --- /dev/null +++ b/src/stores/setting.ts @@ -0,0 +1,81 @@ +import { NDM_SETTING_STORE_ID } from '@/constants'; +import { darkTheme, lightTheme } from 'naive-ui'; +import { defineStore } from 'pinia'; +import { computed, ref, watch } from 'vue'; +import { useUserStore } from './user'; +import router from '@/router'; + +export const useSettingStore = defineStore( + NDM_SETTING_STORE_ID, + () => { + const darkThemeEnabled = ref(true); + const themeMode = computed(() => { + return darkThemeEnabled.value ? darkTheme : lightTheme; + }); + + const menuCollpased = ref(false); + + const stationGridCols = ref(6); + + const debugModeEnabled = ref(false); + const enableDebugMode = () => { + debugModeEnabled.value = true; + }; + const disableDebugMode = () => { + debugModeEnabled.value = false; + }; + + // 离线开发模式 + // 控制 版本轮询 stomp连接 app-layout中的自动getUserInfo + const offlineDev = ref(false); + watch(offlineDev, (newValue, oldValue) => { + // 如果启用离线开发模式且当前未登录 自动填写token以绕过路由守卫并跳过登录页 + if (!oldValue && newValue) { + const userStore = useUserStore(); + if (!userStore.userLoginResult) { + userStore.userLoginResult = { + tenantId: '', + uuid: '', + token: 'test', + refreshToken: '', + expire: '', + expiration: '', + }; + } + if (!userStore.userLoginResult.token) { + userStore.userLoginResult.token = 'test'; + } + if (router.currentRoute.value.path === '/login') { + router.push({ path: '/' }); + } + } + }); + + return { + darkThemeEnabled, + themeMode, + + menuCollpased, + + stationGridCols, + + debugModeEnabled, + enableDebugMode, + disableDebugMode, + + offlineDev, + }; + }, + { + persist: [ + { + omit: ['debugModeEnabled'], + storage: window.localStorage, + }, + { + pick: ['debugModeEnabled'], + storage: window.sessionStorage, + }, + ], + }, +); diff --git a/src/stores/station.ts b/src/stores/station.ts new file mode 100644 index 0000000..0025ee9 --- /dev/null +++ b/src/stores/station.ts @@ -0,0 +1,28 @@ +import type { Station } from '@/apis'; +import { NDM_STATION_STORE_ID } from '@/constants'; +import { defineStore } from 'pinia'; +import { computed, ref } from 'vue'; + +export const useStationStore = defineStore( + NDM_STATION_STORE_ID, + () => { + const stations = ref([]); + const onlineStations = computed(() => { + return stations.value.filter((station) => station.online); + }); + + const setStations = (newStations: Station[]) => { + stations.value = newStations; + }; + + return { + stations, + onlineStations, + + setStations, + }; + }, + { + persistToIndexedDB: true, + }, +); diff --git a/src/stores/user.ts b/src/stores/user.ts new file mode 100644 index 0000000..4ee9d99 --- /dev/null +++ b/src/stores/user.ts @@ -0,0 +1,142 @@ +import { useStationStore } from './station'; +import { usePollingStore } from './polling'; +import { userClient, type LoginParams, type LoginResult, type Station } from '@/apis'; +import type { Result } from '@/types'; +import { AesEncryption, getAppEnvConfig } from '@/utils'; +import axios, { AxiosError } from 'axios'; +import dayjs from 'dayjs'; +import { defineStore } from 'pinia'; +import { computed, ref } from 'vue'; +import { NDM_USER_STORE_ID } from '@/constants'; + +const getHeaders = () => { + const { lampAuthorization, lampClientId, lampClientSecret } = getAppEnvConfig(); + const newAuthorization = window.btoa(`${lampClientId}:${lampClientSecret}`); + const authorization = lampAuthorization.trim() !== '' ? lampAuthorization : newAuthorization; + return { + 'content-type': 'application/json', + 'accept-language': 'zh-CN,zh;q=0.9', + accept: 'application/json, text/plain, */*', + ApplicationId: '1', + TenantId: '1', + Authorization: authorization, + }; +}; + +const aesEncryption = new AesEncryption(); + +export const useUserStore = defineStore( + NDM_USER_STORE_ID, + () => { + const userLoginResult = ref(null); + const userInfo = ref(null); + const lampLoginResultRecord = ref | null>(null); + + const isLamp = computed(() => userInfo.value?.['id'] === '2'); + + const resetStore = () => { + userLoginResult.value = null; + userInfo.value = null; + lampLoginResultRecord.value = null; + }; + + const userLogin = async (loginParams: LoginParams) => { + const { username, password, code, key, grantType } = loginParams; + const body = { + username: aesEncryption.encryptByAES(username), + password: aesEncryption.encryptByAES(password), + code, + key, + grantType, + }; + const { data: respData } = await axios.post>(`/api/oauth/anyTenant/login`, body, { headers: getHeaders() }); + if (!respData.isSuccess) { + console.error(respData); + window.$dialog.destroyAll(); + window.$dialog.error({ + closable: false, + maskClosable: false, + title: '错误提示', + content: respData.msg, + positiveText: '确认', + onPositiveClick: () => { + window.$message.destroyAll(); + }, + }); + throw new AxiosError(respData.msg, `${respData.code}`); + } else { + userLoginResult.value = respData.data; + } + }; + + const userLogout = async () => { + const [err] = await userClient.post(`/api/oauth/anyUser/logout`, { token: userLoginResult.value?.token }); + if (err) throw err; + resetStore(); + }; + + const userGetInfo = async (options?: { signal?: AbortSignal }) => { + const { signal } = options ?? {}; + const [err, info] = await userClient.get(`/api/oauth/anyone/getUserInfoById`, { signal }); + if (err || !info) { + throw err; + } + userInfo.value = info; + }; + + const lampLogin = async (stationCode: Station['code']) => { + const { data: accountRecord } = await axios.get>(`/minio/ndm/ndm-accounts.json?_t=${dayjs().unix()}`); + const body = { + username: aesEncryption.encryptByAES(accountRecord[stationCode]?.username ?? ''), + password: aesEncryption.encryptByAES(accountRecord[stationCode]?.password ?? ''), + grantType: 'PASSWORD', + }; + const { data: respData } = await axios.post>(`/${stationCode}/api/oauth/anyTenant/login`, body, { headers: getHeaders() }); + // 如果登录返回失败,需要提示用户检查用户名和密码配置,并全局停止轮询 + if (!respData.isSuccess) { + console.error(respData); + const stationStore = useStationStore(); + const stationName = stationStore.stations.find((station) => station.code === stationCode)?.name ?? ''; + window.$dialog.destroyAll(); + window.$dialog.error({ + closable: false, + maskClosable: false, + draggable: true, + title: `${stationName}登录失败`, + content: `请检查该车站的用户名和密码配置,并在确认无误后刷新页面!`, + positiveText: '刷新', + onPositiveClick: () => { + window.$dialog.destroyAll(); + window.location.reload(); + }, + }); + // 登录失败时,需要全局停止轮询 + const pollingStore = usePollingStore(); + pollingStore.stopPolling(); + throw new AxiosError(respData.msg, `${respData.code}`); + } else { + if (lampLoginResultRecord.value === null) { + lampLoginResultRecord.value = {}; + } + lampLoginResultRecord.value[stationCode] = respData.data; + } + }; + + return { + userLoginResult, + userInfo, + lampLoginResultRecord, + + isLamp, + + resetStore, + userLogin, + userLogout, + userGetInfo, + lampLogin, + }; + }, + { + persist: true, + }, +); diff --git a/src/styles/reset.scss b/src/styles/reset.scss new file mode 100644 index 0000000..6e22ed1 --- /dev/null +++ b/src/styles/reset.scss @@ -0,0 +1,68 @@ +/* + Josh's Custom CSS Reset + https://www.joshwcomeau.com/css/custom-css-reset/ +*/ + +*, +*::before, +*::after { + box-sizing: border-box; +} + +* { + margin: 0; +} + +@media (prefers-reduced-motion: no-preference) { + html { + interpolate-size: allow-keywords; + } +} + +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; +} + +input, +button, +textarea, +select { + font: inherit; +} + +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; +} + +p { + text-wrap: pretty; +} +h1, +h2, +h3, +h4, +h5, +h6 { + text-wrap: balance; +} + +#root, +#__next { + isolation: isolate; +} diff --git a/src/types/axios.ts b/src/types/axios.ts new file mode 100644 index 0000000..110cbb4 --- /dev/null +++ b/src/types/axios.ts @@ -0,0 +1,10 @@ +export interface Result { + code: number; + data: T; + errorMsg: string; + extra: unknown; + isSuccess: boolean; + msg: string; + path?: string; + timestamp: string; +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..b6c1910 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,2 @@ +export * from './axios'; +export * from './util-type'; diff --git a/src/types/util-type.ts b/src/types/util-type.ts new file mode 100644 index 0000000..ad501d7 --- /dev/null +++ b/src/types/util-type.ts @@ -0,0 +1,3 @@ +export type Optional = T extends object ? { [P in keyof T]?: T[P] | null } : T | null | undefined; + +export type Nullable = T extends object ? { [P in keyof T]: T[P] | null } : T | null; diff --git a/src/utils/cipher.ts b/src/utils/cipher.ts new file mode 100644 index 0000000..8ef1fb1 --- /dev/null +++ b/src/utils/cipher.ts @@ -0,0 +1,58 @@ +import { decrypt, encrypt } from 'crypto-js/aes'; +import Base64 from 'crypto-js/enc-base64'; +import UTF8, { parse } from 'crypto-js/enc-utf8'; +import md5 from 'crypto-js/md5'; +import ECB from 'crypto-js/mode-ecb'; +import pkcs7 from 'crypto-js/pad-pkcs7'; + +export interface EncryptionParams { + key: string; + iv: string; +} + +export class AesEncryption { + private key; + private iv; + + constructor(opt?: Partial) { + const { key, iv } = opt ?? {}; + if (key) { + this.key = parse(key); + } else { + this.key = parse('_11111000001111@'); + } + if (iv) { + this.iv = parse(iv); + } else { + this.iv = parse('@11111000001111_'); + } + } + + get getOptions() { + return { + mode: ECB, + padding: pkcs7, + iv: this.iv, + }; + } + + encryptByAES(cipherText: string) { + return encrypt(cipherText, this.key, this.getOptions).toString(); + } + + decryptByAES(cipherText: string) { + return decrypt(cipherText, this.key, this.getOptions).toString(UTF8); + } +} + +export function encryptByBase64(cipherText: string) { + return UTF8.parse(cipherText).toString(Base64); +} + +export function decodeByBase64(cipherText: string) { + return Base64.parse(cipherText).toString(UTF8); +} + +export function encryptByMd5(password: string) { + return md5(password).toString(); +} diff --git a/src/utils/download.ts b/src/utils/download.ts new file mode 100644 index 0000000..e5800c8 --- /dev/null +++ b/src/utils/download.ts @@ -0,0 +1,17 @@ +export function downloadByData(data: BlobPart, filename: string, mime?: string, bom?: BlobPart) { + const blobData = typeof bom !== 'undefined' ? [bom, data] : [data]; + const blob = new Blob(blobData, { type: mime || 'application/octet-stream' }); + + const blobURL = window.URL.createObjectURL(blob); + const tempLink = document.createElement('a'); + tempLink.style.display = 'none'; + tempLink.href = blobURL; + tempLink.setAttribute('download', filename); + if (typeof tempLink.download === 'undefined') { + tempLink.setAttribute('target', '_blank'); + } + document.body.appendChild(tempLink); + tempLink.click(); + document.body.removeChild(tempLink); + window.URL.revokeObjectURL(blobURL); +} diff --git a/src/utils/env.ts b/src/utils/env.ts new file mode 100644 index 0000000..bea8522 --- /dev/null +++ b/src/utils/env.ts @@ -0,0 +1,26 @@ +export const getAppEnvConfig = () => { + const env = import.meta.env; + const { + // + VITE_REQUEST_INTERVAL, + VITE_NDM_APP_KEY, + VITE_LAMP_CLIENT_ID, + VITE_LAMP_CLIENT_SECRET, + VITE_LAMP_USERNAME, + VITE_LAMP_PASSWORD, + VITE_LAMP_AUTHORIZATION, + VITE_STORAGE_VERSION, + VITE_DEBUG_CODE, + } = env; + return { + requestInterval: Number.parseInt(VITE_REQUEST_INTERVAL as string), + ndmAppKey: VITE_NDM_APP_KEY as string, + lampClientId: VITE_LAMP_CLIENT_ID as string, + lampClientSecret: VITE_LAMP_CLIENT_SECRET as string, + lampUsername: VITE_LAMP_USERNAME as string, + lampPassword: VITE_LAMP_PASSWORD as string, + lampAuthorization: VITE_LAMP_AUTHORIZATION as string, + storageVersion: VITE_STORAGE_VERSION as string, + debugCode: VITE_DEBUG_CODE as string, + }; +}; diff --git a/src/utils/format-duration.ts b/src/utils/format-duration.ts new file mode 100644 index 0000000..50c2d42 --- /dev/null +++ b/src/utils/format-duration.ts @@ -0,0 +1,23 @@ +import type { Optional } from '@/types'; +import dayjs from 'dayjs'; +import duration from 'dayjs/plugin/duration'; + +dayjs.extend(duration); + +export const formatDuration = (startTime: Optional, endTime: Optional) => { + if (!startTime || !endTime) return ''; + const start = dayjs(startTime); + const end = dayjs(endTime); + const diffSeconds = end.diff(start, 'second'); + const duration = dayjs.duration(Math.abs(diffSeconds), 'second'); + const d = Math.floor(duration.asDays()); + const h = duration.hours(); + const m = duration.minutes(); + const s = duration.seconds(); + let result = ''; + if (d > 0) result += `${d}天`; + if (h > 0) result += `${h}小时`; + if (m > 0) result += `${m}分钟`; + if (s > 0) result += `${s}秒`; + return diffSeconds < 0 ? `-${result}` : result; +}; diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..749d38d --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,7 @@ +export * from './cipher'; +export * from './download'; +export * from './env'; +export * from './format-duration'; +export * from './random-num'; +export * from './request-client'; +export * from './sleep'; diff --git a/src/utils/random-num.ts b/src/utils/random-num.ts new file mode 100644 index 0000000..9904f30 --- /dev/null +++ b/src/utils/random-num.ts @@ -0,0 +1,29 @@ +export function randomNum(len: number, radix: number) { + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split(''); + const uuid: string[] = []; + radix = radix ?? chars.length; + + if (len) { + // Compact form + for (let i = 0; i < len; i++) { + uuid[i] = chars[0 | (Math.random() * radix)] ?? ''; + } + } else { + // rfc4122, version 4 form + let r: number; + + // rfc4122 requires these characters + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'; + uuid[14] = '4'; + + // Fill in random data. At i==19 set the high bits of clock sequence as + // per rfc4122, sec. 4.1.5 + for (let i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | (Math.random() * 16); + uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r] ?? ''; + } + } + } + return uuid.join('') + new Date().getTime(); +} diff --git a/src/utils/request-client.ts b/src/utils/request-client.ts new file mode 100644 index 0000000..a788494 --- /dev/null +++ b/src/utils/request-client.ts @@ -0,0 +1,136 @@ +import type { Result } from '@/types'; +import axios, { isAxiosError, type AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type CreateAxiosDefaults, type InternalAxiosRequestConfig } from 'axios'; + +export type Response = [err: AxiosError | null, data: T | null, resp: Result | null]; + +export interface RequestOptions extends CreateAxiosDefaults { + requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise; + responseInterceptor?: (resp: AxiosResponse) => AxiosResponse | Promise; + responseErrorInterceptor?: (error: any) => any; +} + +export class RequestClient { + private instance: AxiosInstance; + + constructor(config?: RequestOptions) { + this.instance = axios.create(config); + + const requestInterceptor = config?.requestInterceptor ?? RequestClient.defaultRequestInterceptor; + const responseInterceptor = config?.responseInterceptor ?? RequestClient.defaultResponseInterceptor; + const responseErrorInterceptor = config?.responseErrorInterceptor ?? RequestClient.defaultResponseErrorInterceptor; + + this.instance.interceptors.request.use(requestInterceptor); + + this.instance.interceptors.response.use(responseInterceptor, responseErrorInterceptor); + } + + private static defaultRequestInterceptor(config: InternalAxiosRequestConfig) { + return config; + } + + private static defaultResponseInterceptor(response: AxiosResponse) { + return response; + } + + private static defaultResponseErrorInterceptor(error: any) { + const err = error as AxiosError; + if (err.status === 401) { + } + if (err.status === 404) { + } + return Promise.reject(error); + } + + public get requestInstance(): AxiosInstance { + return this.instance; + } + + get(url: string, options?: AxiosRequestConfig & { retRaw?: boolean }): Promise> { + const { retRaw, ...reqConfig } = options ?? {}; + return new Promise((resolve) => { + this.instance + .get(url, { + ...reqConfig, + }) + .then((res) => { + if (retRaw) { + resolve([null, res.data as T, null]); + } else { + const resData = res.data as Result; + resolve([null, resData.data, resData]); + } + }) + .catch((err) => { + resolve([err as AxiosError, null, null]); + }); + }); + } + + post(url: string, data?: AxiosRequestConfig['data'], options?: Partial> & { retRaw?: boolean; upload?: boolean }): Promise> { + const { retRaw, upload, ...reqConfig } = options ?? {}; + return new Promise((resolve) => { + this.instance + .post(url, data, { headers: { 'content-type': upload ? 'multipart/form-data' : 'application/json' }, ...reqConfig }) + .then((res) => { + const resData = res.data; + if (retRaw) { + resolve([null, resData as T, null]); + } else { + resolve([null, resData.data as T, resData as Result]); + } + }) + .catch((err) => { + resolve([err as AxiosError, null, null]); + }); + }); + } + + put(url: string, data?: AxiosRequestConfig['data'], options?: Partial>): Promise> { + const reqConfig = options ?? {}; + return new Promise((resolve) => { + this.instance + .put>(url, data, { ...reqConfig }) + .then((res) => { + resolve([null, res.data.data, res.data]); + }) + .catch((err) => { + resolve([err as AxiosError, null, null]); + }); + }); + } + + delete(url: string, idList: string[], options?: Partial>): Promise> { + const reqConfig = options ?? {}; + return new Promise((resolve) => { + this.instance + .delete>(url, { ...reqConfig, data: idList }) + .then((res) => { + resolve([null, res.data.data, res.data]); + }) + .catch((err) => { + resolve([err as AxiosError, null, null]); + }); + }); + } +} + +export const parseErrorFeedback = (error: Error) => { + let errorFeedback: string; + if (!isAxiosError(error)) { + errorFeedback = error.message; + } else { + const axiosError = error as AxiosError; + const respData = axiosError.response?.data as Record | string | undefined; + if (!respData) { + const { code, message } = axiosError; + errorFeedback = `${code} : ${message}`; + } else { + if (typeof respData === 'string') { + errorFeedback = respData; + } else { + errorFeedback = `${respData['path']}: ${respData['msg'] ?? respData['errorMsg'] ?? respData['error']}`; + } + } + } + return errorFeedback; +}; diff --git a/src/utils/sleep.ts b/src/utils/sleep.ts new file mode 100644 index 0000000..d34f6e7 --- /dev/null +++ b/src/utils/sleep.ts @@ -0,0 +1,3 @@ +export const sleep = (ms: number = 0) => { + return new Promise((resolve) => setTimeout(resolve, ms)); +}; diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..e7b6c33 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,23 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": [ + "env.d.ts", + "src/**/*", + "src/**/*.vue" + ], + "exclude": [ + "src/**/__tests__/*" + ], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "lib": [ + "ESNext", + "DOM" + ], + "paths": { + "@/*": [ + "./src/*" + ] + } + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..66b5e57 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..d5e20e2 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "include": [ + "vite.config.*", + "vitest.config.*", + "cypress.config.*", + "nightwatch.conf.*", + "playwright.config.*", + "eslint.config.*", + "build/**/*" + ], + "compilerOptions": { + "noEmit": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "module": "ESNext", + "moduleResolution": "Bundler", + "types": [ + "node" + ] + } +} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..33f4e66 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,143 @@ +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import { fileURLToPath, URL } from 'node:url'; +import { defineConfig, ProxyOptions } from 'vite'; +import vueDevTools from 'vite-plugin-vue-devtools'; + +type ProxyItem = { + key: string; + target: string; + rewrite?: [string, string]; + ws?: boolean; +}; + +const getRewriteFn = (proxyItem: ProxyItem): ProxyOptions['rewrite'] => { + const { key, rewrite } = proxyItem; + const [rewriteFrom, rewriteTo] = rewrite ?? [key, key]; + return (path) => { + console.log(new Date().toLocaleString()); + console.log(`请求路径: ${path}`); + if (!rewrite) return path; + return path.replace(new RegExp(`^${rewriteFrom}`), `${rewriteTo}`); + }; +}; + +const getConfigureFn = (opts?: { ws?: boolean }): ProxyOptions['configure'] => { + const { ws } = opts ?? {}; + if (!ws) { + return (proxy, options) => { + const { target } = options; + proxy.on('proxyReq', (_, req) => { + console.log(`将代理到: ${target}${req.url}`); + }); + }; + } else { + return (proxy, options) => { + const { target } = options; + proxy.on('proxyReqWs', (_, req) => { + console.log(`将代理到: ${target}${req.url}`); + }); + }; + } +}; + +const line04ApiProxyList: ProxyItem[] = [ + { key: '/0475/api', target: 'http://10.15.128.10:18760', rewrite: ['/0475/api', '/api'] }, + { key: '/0480/api', target: 'http://10.15.244.10:18760', rewrite: ['/0480/api', '/api'] }, + { key: '/0401/api', target: 'http://10.15.129.10:18760', rewrite: ['/0401/api', '/api'] }, + { key: '/0402/api', target: 'http://10.15.131.10:18760', rewrite: ['/0402/api', '/api'] }, + { key: '/0403/api', target: 'http://10.15.133.10:18760', rewrite: ['/0403/api', '/api'] }, + { key: '/0404/api', target: 'http://10.15.135.10:18760', rewrite: ['/0404/api', '/api'] }, + { key: '/0405/api', target: 'http://10.15.137.10:18760', rewrite: ['/0405/api', '/api'] }, + { key: '/0406/api', target: 'http://10.15.139.10:18760', rewrite: ['/0406/api', '/api'] }, + { key: '/0407/api', target: 'http://10.15.141.10:18760', rewrite: ['/0407/api', '/api'] }, + { key: '/0408/api', target: 'http://10.15.143.10:18760', rewrite: ['/0408/api', '/api'] }, + { key: '/0409/api', target: 'http://10.15.145.10:18760', rewrite: ['/0409/api', '/api'] }, + { key: '/0410/api', target: 'http://10.15.147.10:18760', rewrite: ['/0410/api', '/api'] }, + { key: '/0411/api', target: 'http://10.15.149.10:18760', rewrite: ['/0411/api', '/api'] }, + { key: '/0412/api', target: 'http://10.15.151.10:18760', rewrite: ['/0412/api', '/api'] }, + { key: '/0413/api', target: 'http://10.15.153.10:18760', rewrite: ['/0413/api', '/api'] }, + { key: '/0414/api', target: 'http://10.15.155.10:18760', rewrite: ['/0414/api', '/api'] }, + { key: '/0415/api', target: 'http://10.15.157.10:18760', rewrite: ['/0415/api', '/api'] }, + { key: '/0416/api', target: 'http://10.15.159.10:18760', rewrite: ['/0416/api', '/api'] }, + { key: '/0417/api', target: 'http://10.15.161.10:18760', rewrite: ['/0417/api', '/api'] }, + { key: '/0418/api', target: 'http://10.15.163.10:18760', rewrite: ['/0418/api', '/api'] }, + { key: '/0419/api', target: 'http://10.15.165.10:18760', rewrite: ['/0419/api', '/api'] }, + { key: '/0420/api', target: 'http://10.15.167.10:18760', rewrite: ['/0420/api', '/api'] }, +]; + +const line10ApiProxyList: ProxyItem[] = [ + { key: '/1075/api', target: 'http://10.18.128.10:18760', rewrite: ['/1075/api', '/api'] }, + { key: '/1001/api', target: 'http://10.18.129.10:18760', rewrite: ['/1001/api', '/api'] }, + { key: '/1002/api', target: 'http://10.18.131.10:18760', rewrite: ['/1002/api', '/api'] }, + { key: '/1003/api', target: 'http://10.18.133.10:18760', rewrite: ['/1003/api', '/api'] }, + { key: '/1004/api', target: 'http://10.18.135.10:18760', rewrite: ['/1004/api', '/api'] }, + { key: '/1005/api', target: 'http://10.18.137.10:18760', rewrite: ['/1005/api', '/api'] }, + { key: '/1006/api', target: 'http://10.18.139.10:18760', rewrite: ['/1006/api', '/api'] }, + { key: '/1007/api', target: 'http://10.18.141.10:18760', rewrite: ['/1007/api', '/api'] }, + { key: '/1008/api', target: 'http://10.18.143.10:18760', rewrite: ['/1008/api', '/api'] }, + { key: '/1009/api', target: 'http://10.18.145.10:18760', rewrite: ['/1009/api', '/api'] }, + { key: '/1010/api', target: 'http://10.18.147.10:18760', rewrite: ['/1010/api', '/api'] }, + { key: '/1011/api', target: 'http://10.18.149.10:18760', rewrite: ['/1011/api', '/api'] }, + { key: '/1012/api', target: 'http://10.18.151.10:18760', rewrite: ['/1012/api', '/api'] }, + { key: '/1013/api', target: 'http://10.18.153.10:18760', rewrite: ['/1013/api', '/api'] }, + { key: '/1014/api', target: 'http://10.18.155.10:18760', rewrite: ['/1014/api', '/api'] }, + { key: '/1015/api', target: 'http://10.18.157.10:18760', rewrite: ['/1015/api', '/api'] }, + { key: '/1016/api', target: 'http://10.18.159.10:18760', rewrite: ['/1016/api', '/api'] }, + { key: '/1017/api', target: 'http://10.18.161.10:18760', rewrite: ['/1017/api', '/api'] }, + { key: '/1018/api', target: 'http://10.18.163.10:18760', rewrite: ['/1018/api', '/api'] }, + { key: '/1019/api', target: 'http://10.18.165.10:18760', rewrite: ['/1019/api', '/api'] }, + { key: '/1020/api', target: 'http://10.18.167.10:18760', rewrite: ['/1020/api', '/api'] }, + { key: '/1021/api', target: 'http://10.18.169.10:18760', rewrite: ['/1021/api', '/api'] }, + { key: '/1022/api', target: 'http://10.18.171.10:18760', rewrite: ['/1022/api', '/api'] }, + { key: '/1023/api', target: 'http://10.18.173.10:18760', rewrite: ['/1023/api', '/api'] }, + { key: '/1024/api', target: 'http://10.18.175.10:18760', rewrite: ['/1024/api', '/api'] }, + { key: '/1025/api', target: 'http://10.18.177.10:18760', rewrite: ['/1025/api', '/api'] }, + { key: '/1026/api', target: 'http://10.18.179.10:18760', rewrite: ['/1026/api', '/api'] }, + { key: '/1027/api', target: 'http://10.18.181.10:18760', rewrite: ['/1027/api', '/api'] }, + { key: '/1028/api', target: 'http://10.18.183.10:18760', rewrite: ['/1028/api', '/api'] }, + { key: '/1029/api', target: 'http://10.18.185.10:18760', rewrite: ['/1029/api', '/api'] }, + { key: '/1030/api', target: 'http://10.18.187.10:18760', rewrite: ['/1030/api', '/api'] }, + { key: '/1031/api', target: 'http://10.18.189.10:18760', rewrite: ['/1031/api', '/api'] }, + { key: '/1032/api', target: 'http://10.18.244.10:18760', rewrite: ['/1032/api', '/api'] }, +]; + +const apiProxyList: ProxyItem[] = [ + // { key: '/minio', target: 'http://10.15.128.10:9000', rewrite: ['/minio', ''] }, + // { key: '/api', target: 'http://10.15.128.10:18760' }, + { key: '/minio', target: 'http://10.18.128.10:9000', rewrite: ['/minio', ''] }, + { key: '/api', target: 'http://10.18.128.10:18760' }, + ...line04ApiProxyList, + ...line10ApiProxyList, + // { key: '/ws', target: 'ws://10.15.128.10:18103', ws: true }, + { key: '/ws', target: 'ws://10.18.128.10:18103', ws: true }, +]; + +// https://vite.dev/config/ +export default defineConfig((/* { command, mode } */) => { + const viteProxy: Record = {}; + + apiProxyList.forEach((apiProxy) => { + const { key, target, ws } = apiProxy; + viteProxy[key] = { + target, + changeOrigin: true, + ws, + rewrite: getRewriteFn(apiProxy), + configure: getConfigureFn({ ws }), + }; + }); + + return { + plugins: [vue(), vueJsx(), vueDevTools()], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + }, + }, + server: { + port: 9763, + proxy: viteProxy, + }, + }; +});