ソースを参照

重构项目结构,删除旧的部署脚本,更新依赖项,添加系统配置相关API和视图,扩展用户角色和配置类型,完善路由设置。

wuyi 4 ヶ月 前
コミット
1c05924884
10 ファイル変更1459 行追加365 行削除
  1. 0 10
      deploy.sh
  2. 385 166
      package-lock.json
  3. 11 4
      package.json
  4. 18 6
      src/enums/index.js
  5. 5 0
      src/router/index.js
  6. 29 0
      src/services/api.js
  7. 5 1
      src/views/MainView.vue
  8. 632 0
      src/views/SysConfigView.vue
  9. 44 0
      tsconfig.json
  10. 330 178
      yarn.lock

+ 0 - 10
deploy.sh

@@ -1,10 +0,0 @@
-#!/bin/bash
-
-# 设置错误时退出
-set -e
-
-git pull origin main
-yarn install
-rm -rf dist/
-yarn build --mode production
-rsync --exclude='node_modules/' -ravzh --delete -e "ssh -i /Volumes/1TB-SSD/Key/aws6.pem -o StrictHostKeyChecking=no" ./dist/ admin@52.197.128.126:/var/www/tweb-admin/

ファイルの差分が大きいため隠しています
+ 385 - 166
package-lock.json


+ 11 - 4
package.json

@@ -1,5 +1,5 @@
 {
-  "name": "tweb-admin",
+  "name": "base-admin",
   "version": "0.0.0",
   "private": true,
   "type": "module",
@@ -14,16 +14,20 @@
     "@primeuix/themes": "^1.0.0",
     "@primevue/forms": "^4.3.3",
     "@tailwindcss/vite": "^4.0.17",
+    "@vueuse/components": "^13.2.0",
     "@vueuse/core": "^13.0.0",
     "axios": "^1.8.4",
     "chart.js": "^4.4.8",
-    "jszip": "^3.10.1",
+    "decimal.js": "^10.5.0",
     "less": "^4.2.2",
     "pinia": "^3.0.1",
     "primeflex": "^4.0.0",
     "primeicons": "^7.0.0",
-    "primevue": "^4.3.5",
+    "primevue": "^4.3.3",
     "tailwindcss-primeui": "^0.6.1",
+    "url": "^0.11.4",
+    "v-viewer": "^3.0.22",
+    "viewerjs": "^1.11.7",
     "vue": "^3.5.13",
     "vue-router": "^4.5.0",
     "zod": "^3.24.2"
@@ -37,9 +41,12 @@
     "eslint-plugin-vue": "~10.0.0",
     "globals": "^16.0.0",
     "prettier": "3.5.3",
+    "prettier-plugin-organize-imports": "^4.1.0",
     "tailwindcss": "^4.0.17",
+    "typescript": "^5.8.3",
     "vite": "^6.2.1",
-    "vite-plugin-vue-devtools": "^7.7.2"
+    "vite-plugin-vue-devtools": "^7.7.2",
+    "vue-tsc": "^2.2.10"
   },
   "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
 }

+ 18 - 6
src/enums/index.js

@@ -1,6 +1,10 @@
 export const UserRole = {
   user: '普通用户',
-  admin: '管理员'
+  admin: '管理员',
+  channel: '渠道',
+  operator: '运营',
+  mss: 'MSS',
+  show: 'SHOW'
 }
 
 export const ConfigType = {
@@ -14,8 +18,16 @@ export const ConfigType = {
   range: '范围'
 }
 
-export const ResultEnum = {
-  success: '成功',
-  tagged: '已标记',
-  noTag: '未标记'
-}
+export const ChainType = {
+  btc: 'btc',
+  eth: 'eth',
+  bsc: 'bsc',
+  tron: 'tron',
+  sol: 'sol'
+}
+
+export const PlatformType = {
+  Android: 'Android',
+  iOS: 'iOS',
+  PC: 'PC'
+}

+ 5 - 0
src/router/index.js

@@ -30,6 +30,11 @@ const router = createRouter({
           name: 'user',
           component: () => import('@/views/UserView.vue')
         },
+        {
+          path: 'sys-config',
+          name: 'sys-config',
+          component: () => import('@/views/SysConfigView.vue')
+        },
       ]
     },
     {

+ 29 - 0
src/services/api.js

@@ -80,6 +80,35 @@ export const updateUserApi = async (userData) => {
   return response.data
 }
 
+// 系统配置相关API
+export const listSysConfig = async (page = 0, size = 20, type) => {
+  const params = { page, size }
+  if (type) params.type = type
+
+  const response = await api.get('/sys-config', { params })
+  return response.data
+}
+
+export const createSysConfig = async (configData) => {
+  const response = await api.post('/sys-config', configData)
+  return response.data
+}
+
+export const updateSysConfig = async (name, configData) => {
+  const response = await api.post(`/sys-config/update/${name}`, configData)
+  return response.data
+}
+
+export const deleteSysConfig = async (name) => {
+  const response = await api.post(`/sys-config/delete/${name}`)
+  return response.data
+}
+
+export const getSysConfigByName = async (name) => {
+  const response = await api.get(`/sys-config/${name}`)
+  return response.data
+}
+
 
 // 文件上传API
 export const uploadFile = async (file) => {

+ 5 - 1
src/views/MainView.vue

@@ -36,6 +36,11 @@ const navItems = [
     label: '用户管理',
     icon: 'pi pi-fw pi-user',
     name: 'user'
+  },
+  {
+    label: '参数配置',
+    icon: 'pi pi-fw pi-cog',
+    name: 'sys-config'
   }
 ]
 
@@ -204,7 +209,6 @@ const handleResetPassword = async ({ valid, values }) => {
 </template>
 
 <style lang="less" scoped>
-
 .layout-header {
   height: 4rem;
   background-color: var(--p-surface-0);

+ 632 - 0
src/views/SysConfigView.vue

@@ -0,0 +1,632 @@
+<script setup>
+import { ref, onMounted, reactive, computed } from 'vue'
+import {
+  listSysConfig,
+  createSysConfig,
+  updateSysConfig,
+  deleteSysConfig,
+  getSysConfigByName,
+  uploadFile as uploadFileAPI
+} from '@/services/api'
+import { ConfigType } from '@/enums/index'
+import { useToast } from 'primevue/usetoast'
+import { useConfirm } from 'primevue/useconfirm'
+import DataTable from 'primevue/datatable'
+import Column from 'primevue/column'
+import Button from 'primevue/button'
+import InputText from 'primevue/inputtext'
+import Select from 'primevue/select'
+import Dialog from 'primevue/dialog'
+import InputNumber from 'primevue/inputnumber'
+import DatePicker from 'primevue/datepicker'
+import Textarea from 'primevue/textarea'
+import { useDateFormat } from '@vueuse/core'
+import RadioButton from 'primevue/radiobutton'
+import Slider from 'primevue/slider'
+
+const toast = useToast()
+const confirm = useConfirm()
+const tableRef = ref(null)
+const query = ref({})
+const tableData = ref({
+  data: [],
+  meta: {
+    total: 0,
+    page: 0,
+    size: 20
+  }
+})
+const selectedConfig = ref(null)
+const configTypes = ref([])
+const dialogVisible = ref(false)
+const isEditing = ref(false)
+const uploading = ref(false)
+const configModel = reactive({
+  name: '',
+  type: 'string',
+  value: '',
+  remark: ''
+})
+
+// 复杂类型值的临时存储
+const tempValue = ref({
+  object: {},
+  file: '',
+  time_range: [],
+  range: []
+})
+
+const rules = {
+  name: [
+    { required: true, message: '请输入配置名称', trigger: 'blur' },
+    { pattern: /^[a-zA-Z0-9_]+$/, message: '只能输入字母、数字、下划线', trigger: 'blur' }
+  ],
+  type: [{ required: true, message: '请选择配置类型', trigger: 'blur' }],
+  value: [{ required: true, message: '请输入配置值', trigger: 'blur' }],
+  remark: [{ required: true, message: '请输入备注', trigger: 'blur' }]
+}
+
+const fetchData = async (page = 0) => {
+  try {
+    const result = await listSysConfig(page, tableData.value.meta.size)
+    tableData.value = result || {
+      data: [],
+      meta: {
+        total: 0,
+        page: 0,
+        size: 20,
+        totalPages: 0
+      }
+    }
+  } catch (error) {
+    console.error('获取配置列表失败', error)
+    toast.add({ severity: 'error', summary: '错误', detail: '获取配置列表失败', life: 3000 })
+    // 确保即使出错也有有效的数据结构
+    tableData.value = {
+      data: [],
+      meta: {
+        total: 0,
+        page: 0,
+        size: 20,
+        totalPages: 0
+      }
+    }
+  }
+}
+
+const fetchConfigTypes = async () => {
+  configTypes.value = Object.entries(ConfigType).map(([key, value]) => ({
+    label: value,
+    value: key
+  }))
+}
+
+const handlePageChange = (event) => {
+  fetchData(event.page)
+}
+
+const refreshData = () => {
+  // 防止undefined错误
+  const page = tableData.value.meta?.page || 0
+  fetchData(page)
+}
+
+const formatDate = (date) => {
+  if (!date) return '-'
+  return useDateFormat(new Date(date), 'YYYY-MM-DD HH:mm:ss').value
+}
+
+const resetModel = () => {
+  configModel.name = ''
+  configModel.type = 'string'
+  configModel.value = ''
+  configModel.remark = ''
+  tempValue.value = {
+    object: {},
+    file: '',
+    time_range: [],
+    range: [0, 0]
+  }
+}
+
+const onEdit = async (config = null) => {
+  resetModel()
+
+  if (config) {
+    isEditing.value = true
+    selectedConfig.value = config
+    try {
+      const detail = await getSysConfigByName(config.name)
+
+      // 填充表单数据
+      configModel.name = detail.name
+      configModel.type = detail.type
+      configModel.remark = detail.remark
+
+      // 根据类型处理值
+      if (detail.type === 'object') {
+        try {
+          tempValue.value.object = typeof detail.value === 'string' ? JSON.parse(detail.value) : detail.value
+          tempValue.value.object = JSON.stringify(tempValue.value.object, null, 2)
+        } catch (e) {
+          tempValue.value.object = '{}'
+        }
+      } else if (detail.type === 'file') {
+        configModel.value = detail.value
+      } else if (detail.type === 'boolean') {
+        configModel.value = detail.value === true || detail.value === 'true' || detail.value === '1' ? '1' : '0'
+      } else if (detail.type === 'time_range') {
+        if (Array.isArray(detail.value)) {
+          tempValue.value.time_range = detail.value
+        } else if (typeof detail.value === 'string' && detail.value.includes(',')) {
+          // 解析逗号分隔的时间字符串
+          const timeParts = detail.value.split(',')
+          if (timeParts.length === 2) {
+            // 将时间字符串转换为Date对象,设置当前日期但使用字符串中的时间
+            const today = new Date()
+            const startTime = new Date(today)
+            const endTime = new Date(today)
+
+            // 处理时分格式,如果需要还可以添加秒(默认为00)
+            let startParts = timeParts[0].split(':')
+            let endParts = timeParts[1].split(':')
+
+            // 确保我们至少有小时和分钟
+            if (startParts.length >= 2 && endParts.length >= 2) {
+              startTime.setHours(parseInt(startParts[0]), parseInt(startParts[1]), 0)
+              endTime.setHours(parseInt(endParts[0]), parseInt(endParts[1]), 0)
+              tempValue.value.time_range = [startTime, endTime]
+            } else {
+              tempValue.value.time_range = []
+            }
+          } else {
+            tempValue.value.time_range = []
+          }
+        } else {
+          tempValue.value.time_range = []
+        }
+      } else if (detail.type === 'range') {
+        if (Array.isArray(detail.value)) {
+          tempValue.value.range = detail.value
+        } else if (typeof detail.value === 'string' && detail.value.includes(',')) {
+          tempValue.value.range = detail.value.split(',').map(Number)
+        } else {
+          tempValue.value.range = [0, 100]
+        }
+      } else {
+        configModel.value = detail.value
+      }
+    } catch (error) {
+      toast.add({ severity: 'error', summary: '错误', detail: '获取配置详情失败', life: 3000 })
+      return
+    }
+  } else {
+    isEditing.value = false
+  }
+
+  dialogVisible.value = true
+}
+
+const onCancel = () => {
+  dialogVisible.value = false
+}
+
+const validateForm = () => {
+  if (!configModel.name) {
+    toast.add({ severity: 'warn', summary: '警告', detail: '配置名称不能为空', life: 3000 })
+    return false
+  }
+
+  if (!configModel.type) {
+    toast.add({ severity: 'warn', summary: '警告', detail: '配置类型不能为空', life: 3000 })
+    return false
+  }
+
+  if (configModel.type === 'time_range') {
+    if (
+      !Array.isArray(tempValue.value.time_range) ||
+      tempValue.value.time_range.length !== 2 ||
+      !tempValue.value.time_range[0] ||
+      !tempValue.value.time_range[1]
+    ) {
+      toast.add({ severity: 'warn', summary: '警告', detail: '请选择有效的时间范围', life: 3000 })
+      return false
+    }
+  }
+
+  return true
+}
+
+const getValueForSubmit = () => {
+  const type = configModel.type
+
+  if (type === 'object') {
+    try {
+      const parsedObj =
+        typeof tempValue.value.object === 'string' ? JSON.parse(tempValue.value.object) : tempValue.value.object
+      return JSON.stringify(parsedObj)
+    } catch (e) {
+      console.error('JSON解析错误', e)
+      return '{}'
+    }
+  } else if (type === 'time_range') {
+    if (Array.isArray(tempValue.value.time_range) && tempValue.value.time_range.length === 2) {
+      const formattedTimes = tempValue.value.time_range.map((date) => {
+        if (date instanceof Date) {
+          // 使用时分格式,秒固定为00
+          return useDateFormat(date, 'HH:mm').value + ':00'
+        }
+        return date
+      })
+      return formattedTimes.join(',')
+    }
+    return Array.isArray(tempValue.value.time_range) ? tempValue.value.time_range.join(',') : tempValue.value.time_range
+  } else if (type === 'date') {
+    if (configModel.value instanceof Date) {
+      return useDateFormat(configModel.value, 'YYYY-MM-DD').value
+    }
+    return configModel.value
+  } else if (type === 'range') {
+    return Array.isArray(tempValue.value.range) ? tempValue.value.range.join(',') : tempValue.value.range
+  } else if (type === 'boolean') {
+    return configModel.value === '1'
+  } else if (type === 'number') {
+    return Number(configModel.value)
+  } else if (type === 'file') {
+    return configModel.value
+  } else {
+    return configModel.value
+  }
+}
+
+const onSubmit = async () => {
+  if (!validateForm()) return
+
+  try {
+    const configData = {
+      name: configModel.name,
+      type: configModel.type,
+      value: getValueForSubmit(),
+      remark: configModel.remark
+    }
+
+    if (isEditing.value) {
+      await updateSysConfig(configModel.name, configData)
+      toast.add({ severity: 'success', summary: '成功', detail: '更新配置成功', life: 3000 })
+    } else {
+      await createSysConfig(configData)
+      toast.add({ severity: 'success', summary: '成功', detail: '创建配置成功', life: 3000 })
+    }
+
+    dialogVisible.value = false
+    refreshData()
+  } catch (error) {
+    toast.add({
+      severity: 'error',
+      summary: '错误',
+      detail: isEditing.value ? '更新配置失败' : '创建配置失败',
+      life: 3000
+    })
+  }
+}
+
+const onDelete = async (config) => {
+  confirm.require({
+    message: `确定要删除配置 "${config.name}" 吗?`,
+    header: '删除确认',
+    icon: 'pi pi-exclamation-triangle',
+    rejectLabel: '取消',
+    rejectProps: {
+      label: '取消',
+      severity: 'secondary'
+    },
+    acceptLabel: '删除',
+    acceptProps: {
+      label: '删除',
+      severity: 'danger'
+    },
+    accept: async () => {
+      try {
+        await deleteSysConfig(config.name)
+        toast.add({ severity: 'success', summary: '成功', detail: '删除配置成功', life: 3000 })
+        refreshData()
+      } catch (error) {
+        toast.add({ severity: 'error', summary: '错误', detail: '删除配置失败', life: 3000 })
+      }
+    }
+  })
+}
+
+const formatValue = (value, type) => {
+  if (value === null || value === undefined) return '-'
+
+  switch (type) {
+    case 'boolean':
+      return value === true || value === 'true' || value === '1' ? '是' : '否'
+    case 'object':
+      try {
+        const obj = typeof value === 'string' ? JSON.parse(value) : value
+        return JSON.stringify(obj)
+      } catch (e) {
+        return String(value)
+      }
+    case 'time_range':
+      // 如果是字符串,直接显示;如果是数组,格式化为逗号分隔的字符串
+      if (typeof value === 'string') {
+        // 如果是以逗号分隔的字符串,直接返回
+        return value
+      } else if (Array.isArray(value)) {
+        return value
+          .map((time) => {
+            if (time instanceof Date) {
+              return useDateFormat(time, 'HH:mm').value + ':00'
+            }
+            return time
+          })
+          .join(',')
+      }
+      return String(value)
+    case 'range':
+      return Array.isArray(value) ? value.join(',') : String(value)
+    default:
+      return String(value)
+  }
+}
+
+const handleTypeChange = () => {
+  // 当类型改变时,重置值
+  configModel.value = ''
+
+  if (configModel.type === 'boolean') {
+    configModel.value = '0'
+  } else if (configModel.type === 'number') {
+    configModel.value = 0
+  } else if (configModel.type === 'range') {
+    tempValue.value.range = [0, 100]
+  } else if (configModel.type === 'time_range') {
+    // 初始化时间范围为今天的上午8点到下午6点
+    const today = new Date()
+    const startTime = new Date(today)
+    const endTime = new Date(today)
+
+    startTime.setHours(8, 0, 0)
+    endTime.setHours(18, 0, 0)
+
+    tempValue.value.time_range = [startTime, endTime]
+  }
+}
+
+// 添加computed属性配置类型选项
+const configTypeOptions = computed(() => {
+  return Object.entries(ConfigType).map(([key, value]) => ({
+    label: value,
+    value: key
+  }))
+})
+
+const uploadFile = async () => {
+  const input = document.createElement('input')
+  input.type = 'file'
+  input.onchange = async (e) => {
+    const file = e.target.files[0]
+    if (!file) return
+
+    uploading.value = true
+
+    try {
+      // 直接传递文件对象,API内部会创建FormData
+      const result = await uploadFileAPI(file)
+      // 使用API返回的data值作为配置值
+      configModel.value = result.data
+      toast.add({ severity: 'success', summary: '成功', detail: '文件上传成功', life: 3000 })
+    } catch (error) {
+      console.error('文件上传失败', error)
+      toast.add({ severity: 'error', summary: '错误', detail: '文件上传失败: ' + (error.message || error), life: 3000 })
+    } finally {
+      uploading.value = false
+    }
+  }
+
+  input.click()
+}
+
+onMounted(() => {
+  fetchData()
+  fetchConfigTypes()
+})
+</script>
+
+<template>
+  <div class="rounded-lg p-4 bg-[var(--p-content-background)]">
+    <DataTable
+      ref="tableRef"
+      :value="tableData.data"
+      :paginator="true"
+      paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown JumpToPageInput"
+      currentPageReportTemplate="{totalRecords} 条记录 "
+      :rows="tableData.meta.size"
+      :rowsPerPageOptions="[10, 20, 50, 100]"
+      :totalRecords="tableData.meta.total"
+      @page="handlePageChange"
+      lazy
+      scrollable
+      stripedRows
+      showGridlines
+    >
+      <template #header>
+        <div class="flex flex-wrap items-center justify-between gap-2">
+          <div class="flex gap-2">
+            <Button icon="pi pi-refresh" @click="refreshData" size="small" label="刷新" />
+            <Button icon="pi pi-plus" @click="onEdit()" label="添加" size="small" />
+          </div>
+        </div>
+      </template>
+
+      <Column field="id" header="ID" style="min-width: 100px" headerClass="font-bold"></Column>
+      <Column field="name" header="配置名称" style="min-width: 150px" headerClass="font-bold"></Column>
+      <Column field="remark" header="备注" style="min-width: 200px" headerClass="font-bold"></Column>
+      <Column field="value" header="配置值" style="min-width: 250px" headerClass="font-bold">
+        <template #body="slotProps">
+          <div class="max-w-xl truncate">
+            {{ formatValue(slotProps.data.value, slotProps.data.type) }}
+          </div>
+        </template>
+      </Column>
+      <Column field="type" header="配置类型" style="min-width: 100px" headerClass="font-bold">
+        <template #body="slotProps">
+          {{ ConfigType[slotProps.data.type] || slotProps.data.type }}
+        </template>
+      </Column>
+      <Column header="操作" style="min-width: 120px" headerClass="font-bold" align="center">
+        <template #body="slotProps">
+          <div class="flex gap-2 justify-center">
+            <Button icon="pi pi-pencil" @click="onEdit(slotProps.data)" size="small" />
+            <Button icon="pi pi-trash" @click="onDelete(slotProps.data)" size="small" severity="danger" />
+          </div>
+        </template>
+      </Column>
+    </DataTable>
+
+    <!-- 添加/编辑配置对话框 -->
+    <Dialog
+      v-model:visible="dialogVisible"
+      :modal="true"
+      :header="isEditing ? '编辑配置' : '添加配置'"
+      :style="{ width: '550px' }"
+    >
+      <div class="grid grid-cols-1 gap-4 p-4">
+        <div class="flex flex-col gap-2">
+          <label class="font-medium">配置名称</label>
+          <InputText v-model="configModel.name" placeholder="请输入配置名称" :disabled="isEditing" />
+          <small v-if="!configModel.name && configModel.name !== 0" class="p-error">请输入配置名称</small>
+        </div>
+
+        <div class="flex flex-col gap-2">
+          <label class="font-medium">备注</label>
+          <InputText v-model="configModel.remark" placeholder="请输入配置备注" />
+          <small v-if="!configModel.remark && configModel.remark !== 0" class="p-error">请输入备注</small>
+        </div>
+
+        <div class="flex flex-col gap-2">
+          <label class="font-medium">配置类型</label>
+          <Select
+            v-model="configModel.type"
+            :options="configTypeOptions"
+            optionLabel="label"
+            optionValue="value"
+            @change="handleTypeChange"
+            :disabled="isEditing"
+            placeholder="请选择配置类型"
+          />
+          <small v-if="!configModel.type" class="p-error">请选择配置类型</small>
+        </div>
+
+        <!-- 根据类型显示不同的输入控件 -->
+        <div class="flex flex-col gap-2">
+          <label class="font-medium">配置值</label>
+
+          <!-- 文件类型 -->
+          <div v-if="configModel.type === 'file'" class="flex gap-2">
+            <InputText v-model="configModel.value" placeholder="请选择文件" readonly class="flex-1" />
+            <Button type="button" icon="pi pi-upload" @click="uploadFile" :loading="uploading" />
+          </div>
+
+          <!-- 布尔类型 -->
+          <div v-else-if="configModel.type === 'boolean'" class="flex gap-4">
+            <div class="flex items-center gap-2">
+              <RadioButton v-model="configModel.value" value="1" inputId="yes" />
+              <label for="yes">是</label>
+            </div>
+            <div class="flex items-center gap-2">
+              <RadioButton v-model="configModel.value" value="0" inputId="no" />
+              <label for="no">否</label>
+            </div>
+          </div>
+
+          <!-- 时间范围类型 -->
+          <div v-else-if="configModel.type === 'time_range'" class="flex flex-col gap-2">
+            <div class="grid grid-cols-2 gap-4">
+              <div class="flex flex-col gap-1">
+                <label class="text-sm">开始时间</label>
+                <DatePicker
+                  v-model="tempValue.time_range[0]"
+                  timeOnly
+                  showTime
+                  format="HH:mm"
+                  hourFormat="24"
+                  placeholder="开始时间"
+                  :showIcon="true"
+                  :showButtonBar="true"
+                />
+              </div>
+              <div class="flex flex-col gap-1">
+                <label class="text-sm">结束时间</label>
+                <DatePicker
+                  v-model="tempValue.time_range[1]"
+                  timeOnly
+                  showTime
+                  format="HH:mm"
+                  hourFormat="24"
+                  placeholder="结束时间"
+                  :showIcon="true"
+                  :showButtonBar="true"
+                />
+              </div>
+            </div>
+            <div class="flex justify-between text-sm text-gray-500 px-1 mt-1">
+              <span
+                >当前选择:
+                {{ tempValue.time_range[0] ? useDateFormat(tempValue.time_range[0], 'HH:mm').value : '--:--' }}</span
+              >
+              <span>至</span>
+              <span>{{
+                tempValue.time_range[1] ? useDateFormat(tempValue.time_range[1], 'HH:mm').value : '--:--'
+              }}</span>
+            </div>
+          </div>
+
+          <!-- 范围类型 -->
+          <div v-else-if="configModel.type === 'range'" class="flex flex-col gap-2">
+            <Slider v-model="tempValue.range" range :max="500" :step="5" />
+            <div class="flex justify-between">
+              <span>{{ tempValue.range[0] }}</span>
+              <span>{{ tempValue.range[1] }}</span>
+            </div>
+          </div>
+
+          <!-- 数字类型 -->
+          <InputNumber
+            v-else-if="configModel.type === 'number'"
+            v-model="configModel.value"
+            placeholder="请输入数字值"
+          />
+
+          <!-- 日期类型 -->
+          <DatePicker
+            v-else-if="configModel.type === 'date'"
+            v-model="configModel.value"
+            dateFormat="yy-mm-dd"
+            :showIcon="true"
+            :showButtonBar="true"
+            placeholder="请选择日期"
+          />
+
+          <!-- 对象类型 -->
+          <Textarea
+            v-else-if="configModel.type === 'object'"
+            v-model="tempValue.object"
+            placeholder="请输入JSON对象"
+            rows="5"
+          />
+
+          <!-- 字符串类型(默认) -->
+          <Textarea v-else v-model="configModel.value" placeholder="请输入值" rows="3" />
+        </div>
+      </div>
+      <template #footer>
+        <Button label="取消" icon="pi pi-times" @click="onCancel" class="p-button-text" />
+        <Button label="保存" icon="pi pi-check" @click="onSubmit" autofocus />
+      </template>
+    </Dialog>
+  </div>
+</template>

+ 44 - 0
tsconfig.json

@@ -0,0 +1,44 @@
+{
+  "compilerOptions": {
+    "target": "ES2020",
+    "useDefineForClassFields": true,
+    "lib": ["ES2020", "DOM", "DOM.Iterable"],
+    "module": "ESNext",
+    "skipLibCheck": true,
+
+    /* Bundler mode */
+    "moduleResolution": "bundler",
+    "allowImportingTsExtensions": true,
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "noEmit": true,
+    "jsx": "preserve",
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true,
+
+    /* Path mapping */
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  "include": [
+    "src/**/*.ts",
+    "src/**/*.tsx",
+    "src/**/*.vue",
+    "src/**/*.js",
+    "src/**/*.jsx"
+  ],
+  "exclude": [
+    "node_modules",
+    "dist"
+  ],
+  "vueCompilerOptions": {
+    "target": 3.3,
+    "globalTypesPath": "./node_modules/vue/global.d.ts"
+  }
+}

+ 330 - 178
yarn.lock

@@ -517,6 +517,11 @@
   resolved "https://registry.npmmirror.com/@kurkle/color/-/color-0.3.4.tgz"
   integrity sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==
 
+"@noble/hashes@^1.2.0":
+  version "1.8.0"
+  resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz"
+  integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==
+
 "@pkgr/core@^0.2.0":
   version "0.2.0"
   resolved "https://registry.npmmirror.com/@pkgr/core/-/core-0.2.0.tgz"
@@ -527,12 +532,12 @@
   resolved "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.28.tgz"
   integrity sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==
 
-"@primeuix/forms@^0.0.4":
-  version "0.0.4"
-  resolved "https://registry.npmmirror.com/@primeuix/forms/-/forms-0.0.4.tgz"
-  integrity sha512-WKrxZPM9fPAEsM0xcTrOOJn86MbfOEzPwSwpO94Y7RtguWw+1nrvqYNzCcmVqO6zBi0BVMihoWxMKFIRzTOuZg==
+"@primeuix/forms@^0.1.0":
+  version "0.1.0"
+  resolved "https://registry.npmjs.org/@primeuix/forms/-/forms-0.1.0.tgz"
+  integrity sha512-LctcQidb+B5PuvAFWH24YH/SIzmHlOabLHpaTeGY/k51iBv1WyCp+5w9JMYuMB/BplSvV0ZGySxQVkN5Azr/aQ==
   dependencies:
-    "@primeuix/utils" "^0.4.0"
+    "@primeuix/utils" "^0.6.0"
 
 "@primeuix/styled@^0.5.0":
   version "0.5.0"
@@ -541,19 +546,19 @@
   dependencies:
     "@primeuix/utils" "^0.5.0"
 
-"@primeuix/styled@^0.6.1", "@primeuix/styled@^0.6.4":
-  version "0.6.4"
-  resolved "https://registry.npmmirror.com/@primeuix/styled/-/styled-0.6.4.tgz"
-  integrity sha512-7ePLwqazLV0x269YlPMeE4wtQKT0NScY2/gEin0/96krTiGiElmlzKMMbH69bVApm/sfen5DZGuCEEwPiBJJ5g==
+"@primeuix/styled@^0.7.2":
+  version "0.7.2"
+  resolved "https://registry.npmjs.org/@primeuix/styled/-/styled-0.7.2.tgz"
+  integrity sha512-tIJ6byZezTYZ9YUICNSidQHOIQOQL3zeUgjwiX0JnBTK3+WCvy4DyCBcrJ94RtiX0WGFZSYNvaGaFkTo4jU8FQ==
   dependencies:
-    "@primeuix/utils" "^0.5.3"
+    "@primeuix/utils" "^0.6.1"
 
-"@primeuix/styles@^1.1.1":
-  version "1.1.1"
-  resolved "https://registry.npmmirror.com/@primeuix/styles/-/styles-1.1.1.tgz"
-  integrity sha512-oguFY2Rs4ZqdcFqEKxBt2d8trTkAjJ5BGTaDV0zbwdqRCRcZp9+di3K3Wv57CW/+tFDA0z1Dg7Dpm7wmkOII9Q==
+"@primeuix/styles@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.npmmirror.com/@primeuix/styles/-/styles-1.0.0.tgz"
+  integrity sha512-j/TlbqihLNMP37zFNjxac5dTRaQEf5Ldrv0P7NwKigCCc/+MI5j4MddxDw1LnxkGhWCJ1Gjbt9uwyQteWtSv7A==
   dependencies:
-    "@primeuix/styled" "^0.6.1"
+    "@primeuix/styled" "^0.5.0"
 
 "@primeuix/themes@^1.0.0":
   version "1.0.0"
@@ -562,40 +567,48 @@
   dependencies:
     "@primeuix/styled" "^0.5.0"
 
-"@primeuix/utils@^0.4.0":
-  version "0.4.1"
-  resolved "https://registry.npmmirror.com/@primeuix/utils/-/utils-0.4.1.tgz"
-  integrity sha512-5+1NLfyna+gLRPeFTo+xlR0tfPVLuVdidbeahAMLkQga5Rw0LxyUBCyD2/Zv2JkV69o2T+hpEDyddl3VdnYoBw==
+"@primeuix/utils@^0.5.0", "@primeuix/utils@^0.5.1":
+  version "0.5.2"
+  resolved "https://registry.npmmirror.com/@primeuix/utils/-/utils-0.5.2.tgz"
+  integrity sha512-fHL0DGnyhL/9toBoV0cO6L+Xg/uaxmOHJW4SrDNMq6GQ7cDXR3Y0vDLvX5j/8kIsaC7LB3329sQLNHgtEETnWw==
+
+"@primeuix/utils@^0.6.0", "@primeuix/utils@^0.6.1":
+  version "0.6.1"
+  resolved "https://registry.npmjs.org/@primeuix/utils/-/utils-0.6.1.tgz"
+  integrity sha512-tQL/ZOPgCdD+NTimlUmhyD0ey8J1XmpZE4hDHM+/fnuBicVVmlKOd5HpS748LcOVRUKbWjmEPdHX4hi5XZoC1Q==
 
-"@primeuix/utils@^0.5.0", "@primeuix/utils@^0.5.3":
-  version "0.5.4"
-  resolved "https://registry.npmmirror.com/@primeuix/utils/-/utils-0.5.4.tgz"
-  integrity sha512-8LggV3Jz59pymHQD10e/u63z/GemQ22RBeu2Gb1eJgBYVwn1iOb82LR+daeAc/LxrXCC5pHnftnCmnZO6vInLA==
+"@primevue/core@4.3.3":
+  version "4.3.3"
+  resolved "https://registry.npmmirror.com/@primevue/core/-/core-4.3.3.tgz"
+  integrity sha512-kSkN5oourG7eueoFPIqiNX3oDT/f0I5IRK3uOY/ytz+VzTZp5yuaCN0Nt42ZQpVXjDxMxDvUhIdaXVrjr58NhQ==
+  dependencies:
+    "@primeuix/styled" "^0.5.0"
+    "@primeuix/utils" "^0.5.1"
 
-"@primevue/core@4.3.5":
-  version "4.3.5"
-  resolved "https://registry.npmmirror.com/@primevue/core/-/core-4.3.5.tgz"
-  integrity sha512-YBlSr/EbXsnsTOyfgqmbrJQ7AI5EThaeGZvfDFjPIIEpokEK+Q32++9xPn3MH8rcM8zPsfMeBOWi4/OJkOqG4w==
+"@primevue/core@4.3.9":
+  version "4.3.9"
+  resolved "https://registry.npmjs.org/@primevue/core/-/core-4.3.9.tgz"
+  integrity sha512-P08MhVD8WrldbropVuiG25ku6il+v+cKKrspES6RijDc4NE/CrGMAwOlrdpOkpy7pcfTzqC9eIGBx5ifS28S5g==
   dependencies:
-    "@primeuix/styled" "^0.6.4"
-    "@primeuix/utils" "^0.5.3"
+    "@primeuix/styled" "^0.7.2"
+    "@primeuix/utils" "^0.6.1"
 
 "@primevue/forms@^4.3.3":
-  version "4.3.5"
-  resolved "https://registry.npmmirror.com/@primevue/forms/-/forms-4.3.5.tgz"
-  integrity sha512-szMwme/1nCLnIdJDykkxFXtp4hVCxGiX8+EHZ18a0FAEQC6JzyhJ+mHh+S34nqMjtUXJntkAAFW4Jk3uxOqIBg==
+  version "4.3.9"
+  resolved "https://registry.npmjs.org/@primevue/forms/-/forms-4.3.9.tgz"
+  integrity sha512-j/GGxFwpfzP3kdxpfxezmsWohmFjoiNHTZlDxGwrNBGrXfb9GExghgoPPKc0K4OeAX5enufS+g8YGqcglABHAQ==
   dependencies:
-    "@primeuix/forms" "^0.0.4"
-    "@primeuix/utils" "^0.5.3"
-    "@primevue/core" "4.3.5"
+    "@primeuix/forms" "^0.1.0"
+    "@primeuix/utils" "^0.6.1"
+    "@primevue/core" "4.3.9"
 
-"@primevue/icons@4.3.5":
-  version "4.3.5"
-  resolved "https://registry.npmmirror.com/@primevue/icons/-/icons-4.3.5.tgz"
-  integrity sha512-+V8XG6MEvczw3Ufz7+ABSSCaVdFCYKRHvVDmXpS65AUeQTDEqmJz3xx2UiYYdASA6Gb2yIKdVztTcRjHFtiAnw==
+"@primevue/icons@4.3.3":
+  version "4.3.3"
+  resolved "https://registry.npmmirror.com/@primevue/icons/-/icons-4.3.3.tgz"
+  integrity sha512-ouQaxHyeFB6MSfEGGbjaK5Qv9efS1xZGetZoU5jcPm090MSYLFtroP1CuK3lZZAQals06TZ6T6qcoNukSHpK5w==
   dependencies:
-    "@primeuix/utils" "^0.5.3"
-    "@primevue/core" "4.3.5"
+    "@primeuix/utils" "^0.5.1"
+    "@primevue/core" "4.3.3"
 
 "@rollup/pluginutils@^5.1.3":
   version "5.1.4"
@@ -819,7 +832,7 @@
 
 "@types/web-bluetooth@^0.0.21":
   version "0.0.21"
-  resolved "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz"
+  resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz"
   integrity sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==
 
 "@vitejs/plugin-vue-jsx@^4.1.1":
@@ -836,6 +849,27 @@
   resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.3.tgz"
   integrity sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==
 
+"@volar/language-core@2.4.15":
+  version "2.4.15"
+  resolved "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.15.tgz"
+  integrity sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==
+  dependencies:
+    "@volar/source-map" "2.4.15"
+
+"@volar/source-map@2.4.15":
+  version "2.4.15"
+  resolved "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.15.tgz"
+  integrity sha512-CPbMWlUN6hVZJYGcU/GSoHu4EnCHiLaXI9n8c9la6RaI9W5JHX+NqG+GSQcB0JdC2FIBLdZJwGsfKyBB71VlTg==
+
+"@volar/typescript@2.4.15":
+  version "2.4.15"
+  resolved "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.15.tgz"
+  integrity sha512-2aZ8i0cqPGjXb4BhkMsPYDkkuc2ZQ6yOpqwAuNwUoncELqoy5fRgOQtLR9gB0g902iS0NAkvpIzs27geVyVdPg==
+  dependencies:
+    "@volar/language-core" "2.4.15"
+    path-browserify "^1.0.1"
+    vscode-uri "^3.0.8"
+
 "@vue/babel-helper-vue-transform-on@1.4.0":
   version "1.4.0"
   resolved "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.4.0.tgz"
@@ -878,7 +912,7 @@
     estree-walker "^2.0.2"
     source-map-js "^1.2.0"
 
-"@vue/compiler-dom@3.5.13", "@vue/compiler-dom@^3.3.4":
+"@vue/compiler-dom@3.5.13", "@vue/compiler-dom@^3.3.4", "@vue/compiler-dom@^3.5.0":
   version "3.5.13"
   resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz"
   integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==
@@ -909,6 +943,14 @@
     "@vue/compiler-dom" "3.5.13"
     "@vue/shared" "3.5.13"
 
+"@vue/compiler-vue2@^2.7.16":
+  version "2.7.16"
+  resolved "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz"
+  integrity sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==
+  dependencies:
+    de-indent "^1.0.2"
+    he "^1.2.0"
+
 "@vue/devtools-api@^6.6.4":
   version "6.6.4"
   resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz"
@@ -961,6 +1003,20 @@
     eslint-config-prettier "^10.0.1"
     eslint-plugin-prettier "^5.2.2"
 
+"@vue/language-core@2.2.12":
+  version "2.2.12"
+  resolved "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.12.tgz"
+  integrity sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==
+  dependencies:
+    "@volar/language-core" "2.4.15"
+    "@vue/compiler-dom" "^3.5.0"
+    "@vue/compiler-vue2" "^2.7.16"
+    "@vue/shared" "^3.5.0"
+    alien-signals "^1.0.3"
+    minimatch "^9.0.3"
+    muggle-string "^0.4.1"
+    path-browserify "^1.0.1"
+
 "@vue/reactivity@3.5.13":
   version "3.5.13"
   resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz"
@@ -994,29 +1050,37 @@
     "@vue/compiler-ssr" "3.5.13"
     "@vue/shared" "3.5.13"
 
-"@vue/shared@3.5.13", "@vue/shared@^3.5.13":
+"@vue/shared@3.5.13", "@vue/shared@^3.5.0", "@vue/shared@^3.5.13":
   version "3.5.13"
   resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz"
   integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==
 
-"@vueuse/core@^13.0.0":
-  version "13.3.0"
-  resolved "https://registry.npmmirror.com/@vueuse/core/-/core-13.3.0.tgz"
-  integrity sha512-uYRz5oEfebHCoRhK4moXFM3NSCd5vu2XMLOq/Riz5FdqZMy2RvBtazdtL3gEcmDyqkztDe9ZP/zymObMIbiYSg==
+"@vueuse/components@^13.2.0":
+  version "13.9.0"
+  resolved "https://registry.npmjs.org/@vueuse/components/-/components-13.9.0.tgz"
+  integrity sha512-0DDFpjG3hEEK+3YgSzE/OzOGqpo/KmxcXWzW2YdmgahZvaoUdegn68GmbdcHRJE7CH55dDj13Cz47iN8QoI3jQ==
+  dependencies:
+    "@vueuse/core" "13.9.0"
+    "@vueuse/shared" "13.9.0"
+
+"@vueuse/core@13.9.0", "@vueuse/core@^13.0.0":
+  version "13.9.0"
+  resolved "https://registry.npmjs.org/@vueuse/core/-/core-13.9.0.tgz"
+  integrity sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==
   dependencies:
     "@types/web-bluetooth" "^0.0.21"
-    "@vueuse/metadata" "13.3.0"
-    "@vueuse/shared" "13.3.0"
+    "@vueuse/metadata" "13.9.0"
+    "@vueuse/shared" "13.9.0"
 
-"@vueuse/metadata@13.3.0":
-  version "13.3.0"
-  resolved "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-13.3.0.tgz"
-  integrity sha512-42IzJIOYCKIb0Yjv1JfaKpx8JlCiTmtCWrPxt7Ja6Wzoq0h79+YVXmBV03N966KEmDEESTbp5R/qO3AB5BDnGw==
+"@vueuse/metadata@13.9.0":
+  version "13.9.0"
+  resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.9.0.tgz"
+  integrity sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==
 
-"@vueuse/shared@13.3.0":
-  version "13.3.0"
-  resolved "https://registry.npmmirror.com/@vueuse/shared/-/shared-13.3.0.tgz"
-  integrity sha512-L1QKsF0Eg9tiZSFXTgodYnu0Rsa2P0En2LuLrIs/jgrkyiDuJSsPZK+tx+wU0mMsYHUYEjNsuE41uqqkuR8VhA==
+"@vueuse/shared@13.9.0":
+  version "13.9.0"
+  resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-13.9.0.tgz"
+  integrity sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==
 
 acorn-jsx@^5.3.2:
   version "5.3.2"
@@ -1038,6 +1102,11 @@ ajv@^6.12.4:
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
+alien-signals@^1.0.3:
+  version "1.0.13"
+  resolved "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz"
+  integrity sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==
+
 ansi-styles@^4.1.0:
   version "4.3.0"
   resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz"
@@ -1052,16 +1121,16 @@ argparse@^2.0.1:
 
 asynckit@^0.4.0:
   version "0.4.0"
-  resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz"
+  resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
   integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
 
 axios@^1.8.4:
-  version "1.9.0"
-  resolved "https://registry.npmmirror.com/axios/-/axios-1.9.0.tgz"
-  integrity sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==
+  version "1.11.0"
+  resolved "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz"
+  integrity sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==
   dependencies:
     follow-redirects "^1.15.6"
-    form-data "^4.0.0"
+    form-data "^4.0.4"
     proxy-from-env "^1.1.0"
 
 balanced-match@^1.0.0:
@@ -1069,6 +1138,13 @@ balanced-match@^1.0.0:
   resolved "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz"
   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
 
+bip39@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.npmjs.org/bip39/-/bip39-3.1.0.tgz"
+  integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==
+  dependencies:
+    "@noble/hashes" "^1.2.0"
+
 birpc@^0.2.19:
   version "0.2.19"
   resolved "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz"
@@ -1087,6 +1163,13 @@ brace-expansion@^1.1.7:
     balanced-match "^1.0.0"
     concat-map "0.0.1"
 
+brace-expansion@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz"
+  integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
+  dependencies:
+    balanced-match "^1.0.0"
+
 browserslist@^4.24.0:
   version "4.24.4"
   resolved "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.4.tgz"
@@ -1106,12 +1189,20 @@ bundle-name@^4.1.0:
 
 call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
   version "1.0.2"
-  resolved "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
+  resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
   integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
   dependencies:
     es-errors "^1.3.0"
     function-bind "^1.1.2"
 
+call-bound@^1.0.2:
+  version "1.0.4"
+  resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz"
+  integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
+  dependencies:
+    call-bind-apply-helpers "^1.0.2"
+    get-intrinsic "^1.3.0"
+
 callsites@^3.0.0:
   version "3.1.0"
   resolved "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz"
@@ -1151,7 +1242,7 @@ color-name@~1.1.4:
 
 combined-stream@^1.0.8:
   version "1.0.8"
-  resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz"
+  resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz"
   integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
   dependencies:
     delayed-stream "~1.0.0"
@@ -1180,11 +1271,6 @@ copy-anything@^3.0.2:
   dependencies:
     is-what "^4.1.8"
 
-core-util-is@~1.0.0:
-  version "1.0.3"
-  resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz"
-  integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
-
 cross-spawn@^7.0.3, cross-spawn@^7.0.6:
   version "7.0.6"
   resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz"
@@ -1204,6 +1290,11 @@ csstype@^3.1.3:
   resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz"
   integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
 
+de-indent@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz"
+  integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
+
 debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.7:
   version "4.4.0"
   resolved "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz"
@@ -1211,6 +1302,11 @@ debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.7:
   dependencies:
     ms "^2.1.3"
 
+decimal.js@^10.5.0:
+  version "10.6.0"
+  resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz"
+  integrity sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==
+
 deep-is@^0.1.3:
   version "0.1.4"
   resolved "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz"
@@ -1236,7 +1332,7 @@ define-lazy-prop@^3.0.0:
 
 delayed-stream@~1.0.0:
   version "1.0.0"
-  resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz"
+  resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
   integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
 
 detect-libc@^2.0.3:
@@ -1246,7 +1342,7 @@ detect-libc@^2.0.3:
 
 dunder-proto@^1.0.1:
   version "1.0.1"
-  resolved "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz"
+  resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz"
   integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
   dependencies:
     call-bind-apply-helpers "^1.0.1"
@@ -1285,24 +1381,24 @@ error-stack-parser-es@^0.1.5:
 
 es-define-property@^1.0.1:
   version "1.0.1"
-  resolved "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz"
+  resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz"
   integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
 
 es-errors@^1.3.0:
   version "1.3.0"
-  resolved "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz"
+  resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz"
   integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
 
 es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
   version "1.1.1"
-  resolved "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
+  resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
   integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
   dependencies:
     es-errors "^1.3.0"
 
 es-set-tostringtag@^2.1.0:
   version "2.1.0"
-  resolved "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
+  resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
   integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
   dependencies:
     es-errors "^1.3.0"
@@ -1547,14 +1643,14 @@ flatted@^3.2.9:
   integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==
 
 follow-redirects@^1.15.6:
-  version "1.15.9"
-  resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz"
-  integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
+  version "1.15.11"
+  resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz"
+  integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==
 
-form-data@^4.0.0:
-  version "4.0.3"
-  resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.3.tgz"
-  integrity sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==
+form-data@^4.0.4:
+  version "4.0.4"
+  resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz"
+  integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
   dependencies:
     asynckit "^0.4.0"
     combined-stream "^1.0.8"
@@ -1578,7 +1674,7 @@ fsevents@~2.3.2, fsevents@~2.3.3:
 
 function-bind@^1.1.2:
   version "1.1.2"
-  resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz"
+  resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
   integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
 
 gensync@^1.0.0-beta.2:
@@ -1586,9 +1682,9 @@ gensync@^1.0.0-beta.2:
   resolved "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz"
   integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
 
-get-intrinsic@^1.2.6:
+get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0:
   version "1.3.0"
-  resolved "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
+  resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
   integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
   dependencies:
     call-bind-apply-helpers "^1.0.2"
@@ -1604,7 +1700,7 @@ get-intrinsic@^1.2.6:
 
 get-proto@^1.0.1:
   version "1.0.1"
-  resolved "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz"
+  resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz"
   integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
   dependencies:
     dunder-proto "^1.0.1"
@@ -1642,7 +1738,7 @@ globals@^16.0.0:
 
 gopd@^1.2.0:
   version "1.2.0"
-  resolved "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz"
+  resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz"
   integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
 
 graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4:
@@ -1657,23 +1753,28 @@ has-flag@^4.0.0:
 
 has-symbols@^1.0.3, has-symbols@^1.1.0:
   version "1.1.0"
-  resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz"
+  resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz"
   integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
 
 has-tostringtag@^1.0.2:
   version "1.0.2"
-  resolved "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
+  resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
   integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
   dependencies:
     has-symbols "^1.0.3"
 
 hasown@^2.0.2:
   version "2.0.2"
-  resolved "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz"
+  resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz"
   integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
   dependencies:
     function-bind "^1.1.2"
 
+he@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
+  integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+
 hookable@^5.5.3:
   version "5.5.3"
   resolved "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz"
@@ -1701,11 +1802,6 @@ image-size@~0.5.0:
   resolved "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz"
   integrity sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==
 
-immediate@~3.0.5:
-  version "3.0.6"
-  resolved "https://registry.npmmirror.com/immediate/-/immediate-3.0.6.tgz"
-  integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
-
 import-fresh@^3.2.1:
   version "3.3.1"
   resolved "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz"
@@ -1719,11 +1815,6 @@ imurmurhash@^0.1.4:
   resolved "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz"
   integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
 
-inherits@~2.0.3:
-  version "2.0.4"
-  resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz"
-  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
 is-docker@^3.0.0:
   version "3.0.0"
   resolved "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz"
@@ -1780,11 +1871,6 @@ is-wsl@^3.1.0:
   dependencies:
     is-inside-container "^1.0.0"
 
-isarray@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz"
-  integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
-
 isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz"
@@ -1841,16 +1927,6 @@ jsonfile@^6.0.1:
   optionalDependencies:
     graceful-fs "^4.1.6"
 
-jszip@^3.10.1:
-  version "3.10.1"
-  resolved "https://registry.npmmirror.com/jszip/-/jszip-3.10.1.tgz"
-  integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
-  dependencies:
-    lie "~3.3.0"
-    pako "~1.0.2"
-    readable-stream "~2.3.6"
-    setimmediate "^1.0.5"
-
 keyv@^4.5.4:
   version "4.5.4"
   resolved "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz"
@@ -1888,13 +1964,6 @@ levn@^0.4.1:
     prelude-ls "^1.2.1"
     type-check "~0.4.0"
 
-lie@~3.3.0:
-  version "3.3.0"
-  resolved "https://registry.npmmirror.com/lie/-/lie-3.3.0.tgz"
-  integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
-  dependencies:
-    immediate "~3.0.5"
-
 lightningcss-darwin-arm64@1.29.2:
   version "1.29.2"
   resolved "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz"
@@ -1970,6 +2039,11 @@ locate-path@^6.0.0:
   dependencies:
     p-locate "^5.0.0"
 
+lodash-es@^4.17.21:
+  version "4.17.21"
+  resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz"
+  integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
 lodash.merge@^4.6.2:
   version "4.6.2"
   resolved "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz"
@@ -1999,17 +2073,17 @@ make-dir@^2.1.0:
 
 math-intrinsics@^1.1.0:
   version "1.1.0"
-  resolved "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
+  resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
   integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
 
 mime-db@1.52.0:
   version "1.52.0"
-  resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz"
+  resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz"
   integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
 
 mime-types@^2.1.12:
   version "2.1.35"
-  resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz"
+  resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz"
   integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
   dependencies:
     mime-db "1.52.0"
@@ -2026,6 +2100,13 @@ minimatch@^3.1.2:
   dependencies:
     brace-expansion "^1.1.7"
 
+minimatch@^9.0.3:
+  version "9.0.5"
+  resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz"
+  integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
+  dependencies:
+    brace-expansion "^2.0.1"
+
 mitt@^3.0.1:
   version "3.0.1"
   resolved "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz"
@@ -2041,6 +2122,11 @@ ms@^2.1.3:
   resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz"
   integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
 
+muggle-string@^0.4.1:
+  version "0.4.1"
+  resolved "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz"
+  integrity sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==
+
 nanoid@^3.3.8:
   version "3.3.11"
   resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz"
@@ -2084,6 +2170,11 @@ nth-check@^2.1.1:
   dependencies:
     boolbase "^1.0.0"
 
+object-inspect@^1.13.3:
+  version "1.13.4"
+  resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz"
+  integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
+
 open@^10.1.0:
   version "10.1.0"
   resolved "https://registry.npmmirror.com/open/-/open-10.1.0.tgz"
@@ -2120,11 +2211,6 @@ p-locate@^5.0.0:
   dependencies:
     p-limit "^3.0.2"
 
-pako@~1.0.2:
-  version "1.0.11"
-  resolved "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz"
-  integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
-
 parent-module@^1.0.0:
   version "1.0.1"
   resolved "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz"
@@ -2142,6 +2228,11 @@ parse-node-version@^1.0.1:
   resolved "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz"
   integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==
 
+path-browserify@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz"
+  integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
+
 path-exists@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz"
@@ -2218,6 +2309,11 @@ prettier-linter-helpers@^1.0.0:
   dependencies:
     fast-diff "^1.1.2"
 
+prettier-plugin-organize-imports@^4.1.0:
+  version "4.2.0"
+  resolved "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-4.2.0.tgz"
+  integrity sha512-Zdy27UhlmyvATZi67BTnLcKTo8fm6Oik59Sz6H64PgZJVs6NJpPD1mT240mmJn62c98/QaL+r3kx9Q3gRpDajg==
+
 prettier@3.5.3:
   version "3.5.3"
   resolved "https://registry.npmmirror.com/prettier/-/prettier-3.5.3.tgz"
@@ -2240,25 +2336,20 @@ primeicons@^7.0.0:
   resolved "https://registry.npmmirror.com/primeicons/-/primeicons-7.0.0.tgz"
   integrity sha512-jK3Et9UzwzTsd6tzl2RmwrVY/b8raJ3QZLzoDACj+oTJ0oX7L9Hy+XnVwgo4QVKlKpnP/Ur13SXV/pVh4LzaDw==
 
-primevue@^4.3.5:
-  version "4.3.5"
-  resolved "https://registry.npmmirror.com/primevue/-/primevue-4.3.5.tgz"
-  integrity sha512-KYjLrf7W96qVOFdX2nyap5IrJIEF8qEfLaHpMPw+H3SCd7zV6uiIrOYBNvovk677rhjBGpSjEbxTFY/K+i/DMA==
+primevue@^4.3.3:
+  version "4.3.3"
+  resolved "https://registry.npmmirror.com/primevue/-/primevue-4.3.3.tgz"
+  integrity sha512-nooYVoEz5CdP3EhUkD6c3qTdRmpLHZh75fBynkUkl46K8y5rksHTjdSISiDijwTA5STQIOkyqLb+RM+HQ6nC1Q==
   dependencies:
-    "@primeuix/styled" "^0.6.4"
-    "@primeuix/styles" "^1.1.1"
-    "@primeuix/utils" "^0.5.3"
-    "@primevue/core" "4.3.5"
-    "@primevue/icons" "4.3.5"
-
-process-nextick-args@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
-  integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+    "@primeuix/styled" "^0.5.0"
+    "@primeuix/styles" "^1.0.0"
+    "@primeuix/utils" "^0.5.1"
+    "@primevue/core" "4.3.3"
+    "@primevue/icons" "4.3.3"
 
 proxy-from-env@^1.1.0:
   version "1.1.0"
-  resolved "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
+  resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
   integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
 
 prr@~1.0.1:
@@ -2266,23 +2357,22 @@ prr@~1.0.1:
   resolved "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz"
   integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==
 
+punycode@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz"
+  integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==
+
 punycode@^2.1.0:
   version "2.3.1"
   resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz"
   integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
 
-readable-stream@~2.3.6:
-  version "2.3.8"
-  resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz"
-  integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+qs@^6.12.3:
+  version "6.14.0"
+  resolved "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz"
+  integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
   dependencies:
-    core-util-is "~1.0.0"
-    inherits "~2.0.3"
-    isarray "~1.0.0"
-    process-nextick-args "~2.0.0"
-    safe-buffer "~5.1.1"
-    string_decoder "~1.1.1"
-    util-deprecate "~1.0.1"
+    side-channel "^1.1.0"
 
 resolve-from@^4.0.0:
   version "4.0.0"
@@ -2328,11 +2418,6 @@ run-applescript@^7.0.0:
   resolved "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.0.0.tgz"
   integrity sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==
 
-safe-buffer@~5.1.0, safe-buffer@~5.1.1:
-  version "5.1.2"
-  resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz"
-  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
 "safer-buffer@>= 2.1.2 < 3.0.0":
   version "2.1.2"
   resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz"
@@ -2358,11 +2443,6 @@ semver@^7.6.3:
   resolved "https://registry.npmmirror.com/semver/-/semver-7.7.1.tgz"
   integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
 
-setimmediate@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz"
-  integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
-
 shebang-command@^2.0.0:
   version "2.0.0"
   resolved "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz"
@@ -2375,6 +2455,46 @@ shebang-regex@^3.0.0:
   resolved "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz"
   integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
 
+side-channel-list@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz"
+  integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==
+  dependencies:
+    es-errors "^1.3.0"
+    object-inspect "^1.13.3"
+
+side-channel-map@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz"
+  integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==
+  dependencies:
+    call-bound "^1.0.2"
+    es-errors "^1.3.0"
+    get-intrinsic "^1.2.5"
+    object-inspect "^1.13.3"
+
+side-channel-weakmap@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz"
+  integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==
+  dependencies:
+    call-bound "^1.0.2"
+    es-errors "^1.3.0"
+    get-intrinsic "^1.2.5"
+    object-inspect "^1.13.3"
+    side-channel-map "^1.0.1"
+
+side-channel@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz"
+  integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
+  dependencies:
+    es-errors "^1.3.0"
+    object-inspect "^1.13.3"
+    side-channel-list "^1.0.0"
+    side-channel-map "^1.0.1"
+    side-channel-weakmap "^1.0.2"
+
 signal-exit@^4.1.0:
   version "4.1.0"
   resolved "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz"
@@ -2404,13 +2524,6 @@ speakingurl@^14.0.1:
   resolved "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz"
   integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==
 
-string_decoder@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz"
-  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
-  dependencies:
-    safe-buffer "~5.1.0"
-
 strip-final-newline@^4.0.0:
   version "4.0.0"
   resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz"
@@ -2475,6 +2588,11 @@ type-check@^0.4.0, type-check@~0.4.0:
   dependencies:
     prelude-ls "^1.2.1"
 
+typescript@^5.8.3:
+  version "5.9.2"
+  resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz"
+  integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==
+
 unicorn-magic@^0.3.0:
   version "0.3.0"
   resolved "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz"
@@ -2500,11 +2618,32 @@ uri-js@^4.2.2:
   dependencies:
     punycode "^2.1.0"
 
-util-deprecate@^1.0.2, util-deprecate@~1.0.1:
+url@^0.11.4:
+  version "0.11.4"
+  resolved "https://registry.npmjs.org/url/-/url-0.11.4.tgz"
+  integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==
+  dependencies:
+    punycode "^1.4.1"
+    qs "^6.12.3"
+
+util-deprecate@^1.0.2:
   version "1.0.2"
   resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz"
   integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
 
+v-viewer@^3.0.22:
+  version "3.0.22"
+  resolved "https://registry.npmjs.org/v-viewer/-/v-viewer-3.0.22.tgz"
+  integrity sha512-uYyP5FPT4K/Sd5D1mhB2HMVV8jnf6zYy2HD1PHCNAO6s2Iway+Wls60pwh7y4F3e2Nlc9549Pvy2HXaq8PKrAg==
+  dependencies:
+    lodash-es "^4.17.21"
+    viewerjs "^1.11.6"
+
+viewerjs@^1.11.6, viewerjs@^1.11.7:
+  version "1.11.7"
+  resolved "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.7.tgz"
+  integrity sha512-0JuVqOmL5v1jmEAlG5EBDR3XquxY8DWFQbFMprOXgaBB0F7Q/X9xWdEaQc59D8xzwkdUgXEMSSknTpriq95igg==
+
 vite-hot-client@^0.2.4:
   version "0.2.4"
   resolved "https://registry.npmmirror.com/vite-hot-client/-/vite-hot-client-0.2.4.tgz"
@@ -2564,6 +2703,11 @@ vite@^6.2.1:
   optionalDependencies:
     fsevents "~2.3.3"
 
+vscode-uri@^3.0.8:
+  version "3.1.0"
+  resolved "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz"
+  integrity sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==
+
 vue-router@^4.5.0:
   version "4.5.0"
   resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz"
@@ -2571,6 +2715,14 @@ vue-router@^4.5.0:
   dependencies:
     "@vue/devtools-api" "^6.6.4"
 
+vue-tsc@^2.2.10:
+  version "2.2.12"
+  resolved "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz"
+  integrity sha512-P7OP77b2h/Pmk+lZdJ0YWs+5tJ6J2+uOQPo7tlBnY44QqQSPYvS0qVT4wqDJgwrZaLe47etJLLQRFia71GYITw==
+  dependencies:
+    "@volar/typescript" "2.4.15"
+    "@vue/language-core" "2.2.12"
+
 vue@^3.5.13:
   version "3.5.13"
   resolved "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz"
@@ -2615,6 +2767,6 @@ yoctocolors@^2.0.0:
   integrity sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==
 
 zod@^3.24.2:
-  version "3.25.64"
-  resolved "https://registry.npmmirror.com/zod/-/zod-3.25.64.tgz"
-  integrity sha512-hbP9FpSZf7pkS7hRVUrOjhwKJNyampPgtXKc3AN6DsWtoHsg2Sb4SQaS4Tcay380zSwd2VPo9G9180emBACp5g==
+  version "3.25.76"
+  resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz"
+  integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません