瀏覽代碼

feat: data augmentation

unknown 8 月之前
父節點
當前提交
5bf28cd33f
共有 5 個文件被更改,包括 857 次插入123 次删除
  1. 1 1
      package.json
  2. 185 0
      src/api/interface/demo/dataAugmentation.ts
  3. 87 0
      src/api/modules/demo/dataAugmentation.ts
  4. 450 0
      src/views/demo/dataAugmentation/index.vue
  5. 134 122
      yarn.lock

+ 1 - 1
package.json

@@ -99,7 +99,7 @@
     "stylelint-config-standard-scss": "^12.0.0",
     "typescript": "4.9.5",
     "unplugin-vue-setup-extend-plus": "^1.0.0",
-    "vite": "^5.0.8",
+    "vite": "^5.4.8",
     "vite-plugin-compression": "^0.5.1",
     "vite-plugin-eslint": "^1.8.1",
     "vite-plugin-prismjs": "^0.0.8",

+ 185 - 0
src/api/interface/demo/dataAugmentation.ts

@@ -0,0 +1,185 @@
+import { PageQuery, BaseEntity } from '@/api/interface/index'
+export interface DataAugmentationVO extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id: string | number
+
+  /**
+   * 视频名称
+   */
+  name: string
+
+  /**
+   * 任务状态 0未开始 1进行中 2已结束
+   */
+  status: string
+
+  /**
+   * 输入图片集路径
+   */
+  inputPath: string
+
+  /**
+   * 去抖动的图片集路径
+   */
+  outPath: string
+
+  /**
+   * 开始时间
+   */
+  startTime: string
+
+  /**
+   * 结束时间
+   */
+  endTime: string
+
+  /**
+   * 耗时
+   */
+  costSecond: number
+
+  /**
+   * 日志
+   */
+  log: string
+
+  /**
+   * 备注
+   */
+  remarks: string
+  /**
+   * 算法路径
+   */
+  algorithmPath: string
+  /**
+   * 超参配置
+   */
+  hyperparameterConfiguration: string
+}
+
+export interface DataAugmentationForm {
+  /**
+   * 主键ID
+   */
+  id?: string | number
+
+  /**
+   * 视频名称
+   */
+  name?: string
+
+  /**
+   * 任务状态 0未开始 1进行中 2已结束
+   */
+  status?: string
+
+  /**
+   * 输入图片集路径
+   */
+  inputPath?: string
+
+  /**
+   * 去抖动的图片集路径
+   */
+  outPath?: string
+
+  /**
+   * 开始时间
+   */
+  startTime?: string
+
+  /**
+   * 结束时间
+   */
+  endTime?: string
+
+  /**
+   * 耗时
+   */
+  costSecond?: number
+
+  /**
+   * 日志
+   */
+  log?: string
+
+  /**
+   * 备注
+   */
+  remarks?: string
+
+  /**
+   * 乐观锁
+   */
+  version?: number
+  /**
+   * 算法路径
+   */
+  algorithmPath: string
+  /**
+   * 超参配置
+   */
+  hyperparameterConfiguration: string
+}
+
+export interface DataAugmentationQuery extends PageQuery {
+  /**
+   * 视频名称
+   */
+  name?: string
+
+  /**
+   * 任务状态 0未开始 1进行中 2已结束
+   */
+  status?: string
+
+  /**
+   * 输入图片集路径
+   */
+  inputPath?: string
+
+  /**
+   * 去抖动的图片集路径
+   */
+  outPath?: string
+
+  /**
+   * 开始时间
+   */
+  startTime?: string
+
+  /**
+   * 结束时间
+   */
+  endTime?: string
+
+  /**
+   * 耗时
+   */
+  costSecond?: number
+
+  /**
+   * 日志
+   */
+  log?: string
+
+  /**
+   * 备注
+   */
+  remarks?: string
+
+  /**
+   * 日期范围参数
+   */
+  params?: any
+  /**
+   * 算法路径
+   */
+  algorithmPath: string
+  /**
+   * 超参配置
+   */
+  hyperparameterConfiguration: string
+}

+ 87 - 0
src/api/modules/demo/dataAugmentation.ts

@@ -0,0 +1,87 @@
+import http from '@/api'
+import { DataAugmentationVO, DataAugmentationForm, DataAugmentationQuery } from '@/api/interface/demo/dataAugmentation'
+
+/**
+ * @name 查询视频去抖动列表
+ * @param query 参数
+ * @returns 返回列表
+ */
+export const listDataAugmentationApi = (query: DataAugmentationQuery) => {
+  return http.get<DataAugmentationVO[]>('/demo/dataAugmentation/list', query, { loading: true })
+}
+
+/**
+ * @name 查询视频去抖动详细
+ * @param id id
+ * @returns returns
+ */
+export const getDataAugmentationApi = (id: string | number) => {
+  return http.get<DataAugmentationVO>(`/demo/dataAugmentation/${id}`)
+}
+
+/**
+ * @name 新增视频去抖动
+ * @param data data
+ * @returns returns
+ */
+export const addDataAugmentationApi = (data: DataAugmentationForm) => {
+  return http.post<any>('/demo/dataAugmentation', data, { loading: false })
+}
+
+/**
+ * @name 修改视频去抖动
+ * @param data data
+ * @returns returns
+ */
+export const updateDataAugmentationApi = (data: DataAugmentationForm) => {
+  return http.put<any>('/demo/dataAugmentation', data, { loading: false })
+}
+
+/**
+ * @name 删除视频去抖动
+ * @param id id
+ * @returns returns
+ */
+export const delDataAugmentationApi = (id: string | number | Array<string | number>) => {
+  return http.delete<any>(`/demo/dataAugmentation/${id}`)
+}
+
+/**
+ * @name 下载模板
+ * @returns returns
+ */
+export const importTemplateApi = () => {
+  return http.downloadPost('/demo/dataAugmentation/importTemplate', {})
+}
+
+/**
+ * @name 导入数据
+ * @returns returns
+ */
+export const importDataAugmentationDataApi = (data: any) => {
+  return http.post('/demo/dataAugmentation/importData', data)
+}
+
+/**
+ * @name 导出数据
+ * @returns returns
+ */
+export const exportDataAugmentationApi = (data: any) => {
+  return http.downloadPost('/demo/dataAugmentation/export', data)
+}
+
+export const startDataAugmentationApi = (id: String | Number) => {
+  return http.get('/demo/dataAugmentation/start/' + id)
+}
+
+export const stopDataAugmentationApi = (id: String | Number) => {
+  return http.get('/demo/dataAugmentation/stop/' + id)
+}
+
+export const getCompareImageApi = (taskId: String, idx: String | Number) => {
+  return http.get('/demo/dataAugmentation/compare/' + taskId + '/' + idx)
+}
+
+export const getCompareImageCountApi = (taskId: String | Number) => {
+  return http.get('/demo/dataAugmentation/compare/num/' + taskId)
+}

+ 450 - 0
src/views/demo/dataAugmentation/index.vue

@@ -0,0 +1,450 @@
+<template>
+  <div class="table-box">
+    <ProTable ref="proTable" :columns="columns" row-key="id" :request-api="listDataAugmentationApi">
+      <!-- 表格 header 按钮 -->
+      <template #tableHeader="scope">
+        <el-button type="primary" v-auth="['demo:DataAugmentation:add']" icon="CirclePlus" @click="openDialog(1, '视频去抖动新增')"> 新增 </el-button>
+        <!--        <el-button type="primary" v-auth="['demo:DataAugmentation:import']" icon="Upload" plain @click="batchAdd"> 导入</el-button>-->
+        <!--        <el-button type="primary" v-auth="['demo:DataAugmentation:export']" icon="Download" plain @click="downloadFile"> 导出 </el-button>-->
+        <el-button
+          type="danger"
+          v-auth="['demo:DataAugmentation:remove']"
+          icon="Delete"
+          plain
+          :disabled="!scope.isSelected"
+          @click="batchDelete(scope.selectedListIds)"
+        >
+          批量删除
+        </el-button>
+      </template>
+      <!-- 表格操作 -->
+      <template #operation="scope">
+        <el-button
+          type="primary"
+          link
+          icon="View"
+          @click="startDataAugmentation(scope.row)"
+          v-if="scope.row.status == '0' || scope.row.status == '3' || scope.row.status == '4'"
+        >
+          开始
+        </el-button>
+        <el-popconfirm title="确定终止此任务吗?" @confirm="stopDataAugmentation(scope.row)" v-if="scope.row.status == '1'">
+          <template #reference>
+            <el-button type="primary" link icon="View"> 终止 </el-button>
+          </template>
+        </el-popconfirm>
+        <el-button type="primary" link icon="View" @click="compareDataAugmentation(scope.row)" v-if="scope.row.status == '2'"> 预览 </el-button>
+        <el-button type="primary" link icon="View" v-auth="['demo:DataAugmentation:query']" @click="openDialog(3, '视频去抖动查看', scope.row)">
+          查看
+        </el-button>
+        <!-- <el-button type="primary" link icon="EditPen" v-auth="['demo:DataAugmentation:edit']" @click="openDialog(2, '视频去抖动编辑', scope.row)">
+            编辑
+          </el-button> -->
+        <el-button type="primary" link icon="Delete" v-auth="['demo:DataAugmentation:remove']" @click="deleteDataAugmentation(scope.row)">
+          删除
+        </el-button>
+      </template>
+    </ProTable>
+    <FormDialog ref="formDialogRef" />
+    <ImportExcel ref="dialogRef" />
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="80%">
+      <el-form>
+        <el-form-item label="帧率">
+          <el-select v-model="imageFps" placeholder="选择帧率" style="width: 200px" @change="changeFps">
+            <el-option label="0" value="0"></el-option>
+            <el-option label="5" value="5"></el-option>
+            <el-option label="15" value="15"></el-option>
+            <el-option label="30" value="30"></el-option>
+            <el-option label="60" value="60"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div class="image-dialog" v-if="imageIdx > 0">
+        <el-image :src="'data:image/png;base64,' + cacheImages[imageIdx].origin" style="width: 45%"></el-image>
+        <el-image :src="'data:image/png;base64,' + cacheImages[imageIdx].stable" style="width: 45%"></el-image>
+      </div>
+      <div class="image-dialog-btn" v-if="imageFps == 0">
+        <el-button type="primary" @click="pre_picture" :disabled="imageIdx <= 1">上一个</el-button>
+        <el-button type="primary" @click="next_picture" :disabled="imageIdx >= fileCount">下一个</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup lang="tsx" name="DataAugmentation">
+import { ref, reactive } from 'vue'
+import { useHandleData } from '@/hooks/useHandleData'
+import { useDownload } from '@/hooks/useDownload'
+import { ElMessageBox, ElMessage } from 'element-plus'
+import ProTable from '@/components/ProTable/index.vue'
+import ImportExcel from '@/components/ImportExcel/index.vue'
+import FormDialog from '@/components/FormDialog/index.vue'
+import { ProTableInstance, ColumnProps, EnumProps } from '@/components/ProTable/interface'
+import {
+  listDataAugmentationApi,
+  delDataAugmentationApi,
+  addDataAugmentationApi,
+  updateDataAugmentationApi,
+  importTemplateApi,
+  importDataAugmentationDataApi,
+  exportDataAugmentationApi,
+  getDataAugmentationApi,
+  startDataAugmentationApi,
+  stopDataAugmentationApi,
+  getCompareImageApi,
+  getCompareImageCountApi
+} from '@/api/modules/demo/dataAugmentation'
+
+const dialogVisible = ref(false)
+const taskId = ref('')
+const imageIdx = ref(0)
+const imageBase64List = ref({
+  origin: '',
+  stable: ''
+})
+const inFileCount = ref(0)
+const outFileCount = ref(0)
+// 直接缓存所有图片
+const cacheImages = ref({ 0: { origin: '', stable: '' } })
+const dialogTitle = ref('')
+const fileCount = ref(0)
+const imageFps = ref(0)
+const intervalChangeFps: any = ref()
+
+const changeFps = () => {
+  console.log('changeFps')
+  if (intervalChangeFps.value) {
+    clearInterval(intervalChangeFps.value)
+  }
+
+  if (imageFps.value == 0) {
+    return
+  }
+  imageIdx.value = 1
+  intervalChangeFps.value = setInterval(() => {
+    next_picture()
+  }, 1000 / imageFps.value)
+}
+
+const startDataAugmentation = async (params: any) => {
+  const res = await startDataAugmentationApi(params.id)
+  if (res.code === 200) {
+    ElMessage.success('任务已经开始,请等待')
+  } else {
+    ElMessage.error('任务开始失败,请检查!')
+  }
+  proTable.value?.getTableList()
+}
+
+const stopDataAugmentation = async (params: any) => {
+  const res = await stopDataAugmentationApi(params.id)
+  if (res.code === 200) {
+    ElMessage.success('任务终止成功')
+  } else {
+    ElMessage.error('任务终止失败!')
+  }
+  proTable.value?.getTableList()
+}
+
+const loadImageData = async (taskId: string, imageIdx: number) => {
+  const res: any = await getCompareImageApi(taskId, imageIdx)
+  imageBase64List.value.origin = res.origin
+  imageBase64List.value.stable = res.stable
+}
+const compareDataAugmentation = async (params: any) => {
+  taskId.value = params.id
+  imageIdx.value = 0
+
+  const resCount: any = await getCompareImageCountApi(params.id)
+  if (resCount.code === 200) {
+    inFileCount.value = resCount.data.inFileCount
+    outFileCount.value = resCount.data.outFileCount
+  } else {
+    ElMessage.error('获取图片对比数量失败')
+    return
+  }
+  dialogVisible.value = true
+
+  dialogTitle.value = '缓存图片中'
+  fileCount.value = Math.min(inFileCount.value, outFileCount.value)
+  for (let idx = 1; idx <= fileCount.value; idx++) {
+    dialogTitle.value = '缓存图片中: 第' + idx + '张图片 共' + fileCount.value + '张图片'
+    if (cacheImages.value[idx]) {
+      continue
+    }
+    const res: any = await getCompareImageApi(taskId.value, idx)
+    cacheImages.value[idx] = {
+      origin: res.origin,
+      stable: res.stable
+    }
+  }
+  next_picture()
+}
+const next_picture = async () => {
+  if (imageIdx.value < fileCount.value) {
+    if (!cacheImages.value[imageIdx.value + 1]) {
+      await loadImageData(taskId.value, imageIdx.value + 1)
+    }
+    imageIdx.value = imageIdx.value + 1
+  }
+  dialogTitle.value = '预览: 第' + imageIdx.value + '张图片 共' + fileCount.value + '张图片'
+}
+const pre_picture = async () => {
+  if (imageIdx.value > 1) {
+    if (!cacheImages.value[imageIdx.value - 1]) {
+      await loadImageData(taskId.value, imageIdx.value - 1)
+    }
+    imageIdx.value = imageIdx.value - 1
+  }
+  dialogTitle.value = '预览: 第' + imageIdx.value + '张图片 共' + fileCount.value + '张图片'
+}
+
+// ProTable 实例
+const proTable = ref<ProTableInstance>()
+
+// 删除视频去抖动信息
+const deleteDataAugmentation = async (params: any) => {
+  await useHandleData(delDataAugmentationApi, params.id, '删除任务【' + params.name + '】?')
+  proTable.value?.getTableList()
+}
+
+// 批量删除视频去抖动信息
+const batchDelete = async (ids: string[]) => {
+  await useHandleData(delDataAugmentationApi, ids, '删除所选任务?')
+  proTable.value?.clearSelection()
+  proTable.value?.getTableList()
+}
+
+// 导出视频去抖动列表
+const downloadFile = async () => {
+  ElMessageBox.confirm('确认导出视频去抖动数据?', '温馨提示', { type: 'warning' }).then(() =>
+    useDownload(exportDataAugmentationApi, '视频去抖动列表', proTable.value?.searchParam)
+  )
+}
+
+// 批量添加视频去抖动
+const dialogRef = ref<InstanceType<typeof ImportExcel> | null>(null)
+const batchAdd = () => {
+  const params = {
+    title: '视频去抖动',
+    tempApi: importTemplateApi,
+    importApi: importDataAugmentationDataApi,
+    getTableList: proTable.value?.getTableList
+  }
+  dialogRef.value?.acceptParams(params)
+}
+
+const formDialogRef = ref<InstanceType<typeof FormDialog> | null>(null)
+// 打开弹框的功能
+const openDialog = async (type: number, title: string, row?: any) => {
+  let res = { data: {} }
+  if (row?.id) {
+    res = await getDataAugmentationApi(row?.id || null)
+  }
+  // 重置表单
+  setItemsOptions()
+  const params = {
+    title,
+    width: 580,
+    isEdit: type !== 3,
+    itemsOptions: itemsOptions,
+    model: type == 1 ? {} : res.data,
+    api: type == 1 ? addDataAugmentationApi : updateDataAugmentationApi,
+    getTableList: proTable.value?.getTableList
+  }
+  formDialogRef.value?.openDialog(params)
+}
+const statusEnums: EnumProps[] = [
+  {
+    label: '未开始',
+    value: '0',
+    disabled: false,
+    tagType: 'default'
+  },
+  {
+    label: '进行中',
+    value: '1',
+    disabled: false,
+    tagType: 'primary'
+  },
+  {
+    label: '完成',
+    value: '2',
+    disabled: false,
+    tagType: 'success'
+  },
+  {
+    label: '失败',
+    value: '3',
+    disabled: false,
+    tagType: 'danger'
+  },
+  {
+    label: '已中断',
+    value: '4',
+    disabled: false,
+    tagType: 'default'
+  }
+]
+
+// 表格配置项
+const columns = reactive<ColumnProps<any>[]>([
+  { type: 'selection', fixed: 'left', width: 70 },
+  { prop: 'id', label: '主键ID', width: 180 },
+  {
+    prop: 'name',
+    label: '视频名称',
+    search: {
+      el: 'input'
+    },
+    width: 150
+  },
+  {
+    prop: 'status',
+    label: '任务状态',
+    search: {
+      el: 'select'
+    },
+    width: 100,
+    tag: true,
+    enum: statusEnums
+  },
+  {
+    prop: 'startTime',
+    label: '开始时间',
+    // search: {
+    //   el: 'date-picker',
+    //   props: {
+    //     type: 'datetimerange',
+    //     valueFormat: 'YYYY-MM-DD HH:mm:ss'
+    //   }
+    // },
+    width: 180
+  },
+  {
+    prop: 'endTime',
+    label: '结束时间',
+    // search: {
+    //   el: 'date-picker',
+    //   props: {
+    //     type: 'datetimerange',
+    //     valueFormat: 'YYYY-MM-DD HH:mm:ss'
+    //   }
+    // },
+    width: 180
+  },
+  {
+    prop: 'costSecond',
+    label: '耗时',
+    search: {
+      el: 'input'
+    },
+    width: 80
+  },
+  {
+    prop: 'log',
+    label: '日志',
+    width: 120
+  },
+
+  {
+    prop: 'algorithmPath',
+    label: '算法路径',
+    width: 120
+  },
+  {
+    prop: 'hyperparameterConfiguration',
+    label: '超参配置',
+    width: 120
+  },
+  {
+    prop: 'remarks',
+    label: '备注',
+    search: {
+      el: 'input'
+    },
+    width: 120
+  },
+  {
+    prop: 'operation',
+    label: '操作',
+    width: 230,
+    fixed: 'right'
+  }
+])
+// 表单配置项
+let itemsOptions: ProForm.ItemsOptions[] = []
+const setItemsOptions = () => {
+  itemsOptions = [
+    {
+      label: '任务名称',
+      prop: 'name',
+      rules: [{ required: true, message: '任务名称不能为空', trigger: 'blur' }],
+      compOptions: {
+        placeholder: '请输入任务名称'
+      }
+    },
+    {
+      label: '图片集压缩包',
+      prop: 'uploadPath',
+      rules: [{ required: true, message: '图片集压缩包不能为空', trigger: 'blur' }],
+      compOptions: {
+        elTagName: 'file-upload',
+        fileSize: 4096,
+        fileType: ['zip'],
+        placeholder: '请上传图片集压缩包'
+      }
+    },
+    {
+      label: '算法路径',
+      prop: 'algorithmPath',
+      rules: [],
+      compOptions: {
+        type: 'input',
+        clearable: true,
+        placeholder: ''
+      }
+    },
+    {
+      label: '超参配置',
+      prop: 'hyperparameterConfiguration',
+      rules: [],
+      compOptions: {
+        type: 'input',
+        clearable: true,
+        placeholder: ''
+      }
+    },
+    {
+      label: '备注',
+      prop: 'remarks',
+      rules: [
+        {
+          required: false,
+          message: '备注不能为空',
+          trigger: 'blur'
+        }
+      ],
+      compOptions: {
+        placeholder: '请输入备注'
+      }
+    }
+  ]
+}
+</script>
+
+<style lang="scss" scoped>
+.image-dialog {
+  display: flex;
+  justify-content: center;
+  .el-image {
+    margin-right: 20px;
+    margin-bottom: 20px;
+  }
+}
+.image-dialog-btn {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+</style>

+ 134 - 122
yarn.lock

@@ -1599,85 +1599,85 @@
     estree-walker "^2.0.2"
     picomatch "^2.3.1"
 
-"@rollup/rollup-android-arm-eabi@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz#bbd0e616b2078cd2d68afc9824d1fadb2f2ffd27"
-  integrity sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==
-
-"@rollup/rollup-android-arm64@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz#97255ef6384c5f73f4800c0de91f5f6518e21203"
-  integrity sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==
-
-"@rollup/rollup-darwin-arm64@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz#b6dd74e117510dfe94541646067b0545b42ff096"
-  integrity sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==
-
-"@rollup/rollup-darwin-x64@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz#e07d76de1cec987673e7f3d48ccb8e106d42c05c"
-  integrity sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==
-
-"@rollup/rollup-linux-arm-gnueabihf@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz#9f1a6d218b560c9d75185af4b8bb42f9f24736b8"
-  integrity sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==
-
-"@rollup/rollup-linux-arm-musleabihf@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz#53618b92e6ffb642c7b620e6e528446511330549"
-  integrity sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==
-
-"@rollup/rollup-linux-arm64-gnu@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz#99a7ba5e719d4f053761a698f7b52291cefba577"
-  integrity sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==
-
-"@rollup/rollup-linux-arm64-musl@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz#f53db99a45d9bc00ce94db8a35efa7c3c144a58c"
-  integrity sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==
-
-"@rollup/rollup-linux-powerpc64le-gnu@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz#cbb0837408fe081ce3435cf3730e090febafc9bf"
-  integrity sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==
-
-"@rollup/rollup-linux-riscv64-gnu@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz#8ed09c1d1262ada4c38d791a28ae0fea28b80cc9"
-  integrity sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==
-
-"@rollup/rollup-linux-s390x-gnu@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz#938138d3c8e0c96f022252a28441dcfb17afd7ec"
-  integrity sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==
-
-"@rollup/rollup-linux-x64-gnu@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz#1a7481137a54740bee1ded4ae5752450f155d942"
-  integrity sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==
-
-"@rollup/rollup-linux-x64-musl@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz#f1186afc601ac4f4fc25fac4ca15ecbee3a1874d"
-  integrity sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==
-
-"@rollup/rollup-win32-arm64-msvc@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz#ed6603e93636a96203c6915be4117245c1bd2daf"
-  integrity sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==
-
-"@rollup/rollup-win32-ia32-msvc@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz#14e0b404b1c25ebe6157a15edb9c46959ba74c54"
-  integrity sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==
-
-"@rollup/rollup-win32-x64-msvc@4.18.0":
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz#5d694d345ce36b6ecf657349e03eb87297e68da4"
-  integrity sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==
+"@rollup/rollup-android-arm-eabi@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54"
+  integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==
+
+"@rollup/rollup-android-arm64@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e"
+  integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==
+
+"@rollup/rollup-darwin-arm64@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f"
+  integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==
+
+"@rollup/rollup-darwin-x64@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724"
+  integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==
+
+"@rollup/rollup-linux-arm-gnueabihf@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb"
+  integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==
+
+"@rollup/rollup-linux-arm-musleabihf@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3"
+  integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==
+
+"@rollup/rollup-linux-arm64-gnu@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496"
+  integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==
+
+"@rollup/rollup-linux-arm64-musl@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065"
+  integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==
+
+"@rollup/rollup-linux-powerpc64le-gnu@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d"
+  integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==
+
+"@rollup/rollup-linux-riscv64-gnu@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983"
+  integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==
+
+"@rollup/rollup-linux-s390x-gnu@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58"
+  integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==
+
+"@rollup/rollup-linux-x64-gnu@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b"
+  integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==
+
+"@rollup/rollup-linux-x64-musl@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127"
+  integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==
+
+"@rollup/rollup-win32-arm64-msvc@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5"
+  integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==
+
+"@rollup/rollup-win32-ia32-msvc@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2"
+  integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==
+
+"@rollup/rollup-win32-x64-msvc@4.24.0":
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818"
+  integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==
 
 "@surma/rollup-plugin-off-main-thread@^2.2.3":
   version "2.2.3"
@@ -1712,7 +1712,7 @@
     "@types/estree" "*"
     "@types/json-schema" "*"
 
-"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0":
+"@types/estree@*", "@types/estree@^1.0.0":
   version "1.0.5"
   resolved "https://registry.npmmirror.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
   integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
@@ -1722,6 +1722,11 @@
   resolved "https://registry.npmmirror.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
   integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
 
+"@types/estree@1.0.6":
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
+  integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
+
 "@types/event-emitter@^0.3.3":
   version "0.3.5"
   resolved "https://registry.npmmirror.com/@types/event-emitter/-/event-emitter-0.3.5.tgz#ce9b513f72c50dcf0443a12165a93a79ba7a7092"
@@ -2039,7 +2044,7 @@
     "@babel/parser" "^7.23.5"
     "@vue/shared" "3.3.13"
     estree-walker "^2.0.2"
-    source-map-js "^1.2.0"
+    source-map-js "^1.0.2"
 
 "@vue/compiler-core@3.4.29":
   version "3.4.29"
@@ -2080,9 +2085,9 @@
     "@vue/reactivity-transform" "3.3.13"
     "@vue/shared" "3.3.13"
     estree-walker "^2.0.2"
-    magic-string "^0.30.10"
-    postcss "^8.4.38"
-    source-map-js "^1.2.0"
+    magic-string "^0.30.5"
+    postcss "^8.4.32"
+    source-map-js "^1.0.2"
 
 "@vue/compiler-sfc@^3.2.37", "@vue/compiler-sfc@^3.4.15":
   version "3.4.29"
@@ -4300,13 +4305,6 @@ fill-range@^7.1.1:
   dependencies:
     to-regex-range "^5.0.1"
 
-fill-range@^7.1.1:
-  version "7.1.1"
-  resolved "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
-  integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
-  dependencies:
-    to-regex-range "^5.0.1"
-
 find-up@^2.0.0:
   version "2.1.0"
   resolved "https://registry.npmmirror.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
@@ -6447,10 +6445,10 @@ picocolors@^1.0.0, picocolors@^1.0.1:
   resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
   integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
 
-picocolors@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
-  integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
+picocolors@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59"
+  integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==
 
 picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.1:
   version "2.3.1"
@@ -6572,6 +6570,15 @@ postcss@^8.4.0, postcss@^8.4.32, postcss@^8.4.38:
     picocolors "^1.0.0"
     source-map-js "^1.2.0"
 
+postcss@^8.4.43:
+  version "8.4.47"
+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365"
+  integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
+  dependencies:
+    nanoid "^3.3.7"
+    picocolors "^1.1.0"
+    source-map-js "^1.2.1"
+
 posthtml-parser@^0.2.0, posthtml-parser@^0.2.1:
   version "0.2.1"
   resolved "https://registry.npmmirror.com/posthtml-parser/-/posthtml-parser-0.2.1.tgz#35d530de386740c2ba24ff2eb2faf39ccdf271dd"
@@ -6951,29 +6958,29 @@ rollup@^2.43.1, rollup@^2.77.2:
   optionalDependencies:
     fsevents "~2.3.2"
 
-rollup@^4.13.0:
-  version "4.18.0"
-  resolved "https://registry.npmmirror.com/rollup/-/rollup-4.18.0.tgz#497f60f0c5308e4602cf41136339fbf87d5f5dda"
-  integrity sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==
+rollup@^4.20.0:
+  version "4.24.0"
+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05"
+  integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==
   dependencies:
-    "@types/estree" "1.0.5"
+    "@types/estree" "1.0.6"
   optionalDependencies:
-    "@rollup/rollup-android-arm-eabi" "4.18.0"
-    "@rollup/rollup-android-arm64" "4.18.0"
-    "@rollup/rollup-darwin-arm64" "4.18.0"
-    "@rollup/rollup-darwin-x64" "4.18.0"
-    "@rollup/rollup-linux-arm-gnueabihf" "4.18.0"
-    "@rollup/rollup-linux-arm-musleabihf" "4.18.0"
-    "@rollup/rollup-linux-arm64-gnu" "4.18.0"
-    "@rollup/rollup-linux-arm64-musl" "4.18.0"
-    "@rollup/rollup-linux-powerpc64le-gnu" "4.18.0"
-    "@rollup/rollup-linux-riscv64-gnu" "4.18.0"
-    "@rollup/rollup-linux-s390x-gnu" "4.18.0"
-    "@rollup/rollup-linux-x64-gnu" "4.18.0"
-    "@rollup/rollup-linux-x64-musl" "4.18.0"
-    "@rollup/rollup-win32-arm64-msvc" "4.18.0"
-    "@rollup/rollup-win32-ia32-msvc" "4.18.0"
-    "@rollup/rollup-win32-x64-msvc" "4.18.0"
+    "@rollup/rollup-android-arm-eabi" "4.24.0"
+    "@rollup/rollup-android-arm64" "4.24.0"
+    "@rollup/rollup-darwin-arm64" "4.24.0"
+    "@rollup/rollup-darwin-x64" "4.24.0"
+    "@rollup/rollup-linux-arm-gnueabihf" "4.24.0"
+    "@rollup/rollup-linux-arm-musleabihf" "4.24.0"
+    "@rollup/rollup-linux-arm64-gnu" "4.24.0"
+    "@rollup/rollup-linux-arm64-musl" "4.24.0"
+    "@rollup/rollup-linux-powerpc64le-gnu" "4.24.0"
+    "@rollup/rollup-linux-riscv64-gnu" "4.24.0"
+    "@rollup/rollup-linux-s390x-gnu" "4.24.0"
+    "@rollup/rollup-linux-x64-gnu" "4.24.0"
+    "@rollup/rollup-linux-x64-musl" "4.24.0"
+    "@rollup/rollup-win32-arm64-msvc" "4.24.0"
+    "@rollup/rollup-win32-ia32-msvc" "4.24.0"
+    "@rollup/rollup-win32-x64-msvc" "4.24.0"
     fsevents "~2.3.2"
 
 run-parallel@^1.1.9:
@@ -7265,6 +7272,11 @@ sortablejs@^1.15.1:
   resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
   integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
 
+source-map-js@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
+  integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
+
 source-map-resolve@^0.5.0:
   version "0.5.3"
   resolved "https://registry.npmmirror.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
@@ -8261,14 +8273,14 @@ vite-plugin-svg-icons@^2.0.1:
     svg-baker "1.7.0"
     svgo "^2.8.0"
 
-vite@^5.0.8:
-  version "5.3.1"
-  resolved "https://registry.npmmirror.com/vite/-/vite-5.3.1.tgz#bb2ca6b5fd7483249d3e86b25026e27ba8a663e6"
-  integrity sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==
+vite@^5.4.8:
+  version "5.4.8"
+  resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.8.tgz#af548ce1c211b2785478d3ba3e8da51e39a287e8"
+  integrity sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==
   dependencies:
     esbuild "^0.21.3"
-    postcss "^8.4.38"
-    rollup "^4.13.0"
+    postcss "^8.4.43"
+    rollup "^4.20.0"
   optionalDependencies:
     fsevents "~2.3.3"