diff --git a/.vscode/settings.json b/.vscode/settings.json
index 2744752..6efd8fd 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -25,7 +25,7 @@
     "editor.defaultFormatter": "esbenp.prettier-vscode"
   },
   "editor.codeActionsOnSave": {
-    "source.fixAll.eslint": true
+    "source.fixAll.eslint": "explicit"
   },
   "iconify.excludes": ["el"]
 }
diff --git a/dist.rar b/dist.rar
new file mode 100644
index 0000000..5e7594a
Binary files /dev/null and b/dist.rar differ
diff --git a/mock/asyncRoutes.ts b/mock/asyncRoutes.ts
index 09bf932..c40fbd9 100644
--- a/mock/asyncRoutes.ts
+++ b/mock/asyncRoutes.ts
@@ -7,175 +7,78 @@ import { MockMethod } from "vite-plugin-mock";
  * common:普通角色
  */
 
-// const permissionRouter = {
-//   path: "/permission",
-//   meta: {
-//     title: "用户管理",
-//     icon: "lollipop",
-//     rank: 10
-//   },
-//   children: [
-//     {
-//       path: "/permission/page/index",
-//       name: "PermissionPage",
-//       meta: {
-//         title: "页面权限",
-//         roles: ["admin", "common"]
-//       }
-//     },
-//     {
-//       path: "/permission/button/index",
-//       name: "PermissionButton",
-//       meta: {
-//         title: "按钮权限",
-//         roles: ["admin", "common"],
-//         auths: ["btn_add", "btn_edit", "btn_delete"]
-//       }
-//     }
-//   ]
-// };
-
-// const projectRouter = {
-//   path: "/project",
-//   meta: {
-//     title: "项目管理",
-//     icon: "lollipop",
-//     rank: 11
-//   },
-//   children: [
-//     {
-//       path: "/project/list/index",
-//       name: "ProjectList",
-//       meta: {
-//         title: "项目列表",
-//         roles: ["admin", "common"]
-//       }
-//     },
-//     {
-//       path: "/project/details/index",
-//       name: "ProjectDetails",
-//       meta: {
-//         title: "项目详情",
-//         roles: ["admin", "common"]
-//       }
-//     }
-//   ]
-// };
-
-// const modelRouter = {
-//   path: "/aiModel",
-//   meta: {
-//     title: "模型管理",
-//     icon: "lollipop",
-//     rank: 12
-//   },
-//   children: [
-//     {
-//       path: "/aiModel",
-//       name: "AiModelPage",
-//       meta: {
-//         title: "模型管理",
-//         roles: ["admin", "common"]
-//       }
-//     }
-//   ]
-// };
-
-// const deviceRouter = {
-//   path: "/device",
-//   meta: {
-//     title: "设备管理",
-//     icon: "lollipop",
-//     rank: 13
-//   },
-//   children: [
-//     {
-//       path: "/device",
-//       name: "DevicePage",
-//       meta: {
-//         title: "设备管理",
-//         roles: ["admin", "common"]
-//       }
-//     }
-//   ]
-// };
-
-// const warningRouter = {
-//   path: "/warning",
-//   meta: {
-//     title: "告警管理",
-//     icon: "Alarm",
-//     rank: 14
-//   },
-//   children: [
-//     {
-//       path: "/warning/list/index",
-//       name: "WarningList",
-//       meta: {
-//         title: "告警列表",
-//         roles: ["admin", "common"]
-//       }
-//     }
-//   ]
-// };
-
-const enterpriseRouter = {
-  path: "/enterprise",
+const inquiryManagementRouter = {
+  path: "/inquiryManagement",
   meta: {
-    title: "企业管理",
-    icon: "buildingOne",
-    rank: 16
+    title: "问诊管理",
+    icon: "projectIcon",
+    rank: 11
   },
   children: [
     {
-      path: "/enterprise/index",
-      name: "EnterpriseList",
+      path: "/inquiryManagement/bodyInspect",
+      name: "BodyInspect",
       meta: {
-        title: "企业管理",
-        roles: ["admin"]
+        title: "体格检查",
+        roles: ["admin", "common"]
       }
-    }
-  ]
-};
-
-const myAlgorithmRouter = {
-  path: "/myAlgorithm",
-  meta: {
-    title: "我的算法库",
-    icon: "terminal",
-    rank: 17
-  },
-  children: [
+    },
     {
-      path: "/myAlgorithm/index",
-      name: "myAlgorithm",
+      path: "/inquiryManagement/supportInspect",
+      name: "SupportInspect",
       meta: {
-        title: "我的算法库",
+        title: "辅助检查",
+        roles: ["admin", "common"]
+      }
+    },
+    {
+      path: "/inquiryManagement/disposalPlan",
+      name: "DisposalPlan",
+      meta: {
+        title: "处置计划",
         roles: ["admin", "common"]
       }
     }
   ]
 };
 
-const algorithmTestingRouter = {
-  path: "/algorithmTesting",
+const caseManagement = {
+  path: "/caseManagement",
+  redirect: "/caseManagement/list",
   meta: {
-    title: "算法实测",
-    icon: "camera",
-    rank: 18
+    title: "病历管理",
+    icon: "projectIcon",
+    rank: 11
   },
   children: [
     {
-      path: "/algorithmTesting/index",
-      name: "algorithmTesting",
+      path: "/caseManagement/diseaseType",
+      name: "DiseaseType",
       meta: {
-        title: "算法实测",
+        title: "疾病分类",
+        roles: ["admin", "common"]
+      }
+    },
+    {
+      path: "/caseManagement/list",
+      name: "CaseManagement",
+      meta: {
+        title: "病历管理",
+        showLink: true,
+        roles: ["admin", "common"]
+      }
+    },
+    {
+      path: "/caseManagement/add",
+      name: "caseManagementAdd",
+      meta: {
+        title: "新建病历",
+        showLink: false,
         roles: ["admin", "common"]
       }
     }
   ]
 };
-
 export default [
   {
     url: "/getAsyncRoutes",
@@ -183,7 +86,8 @@ export default [
     response: () => {
       return {
         success: true,
-        data: [enterpriseRouter, myAlgorithmRouter, algorithmTestingRouter]
+        code: 200,
+        data: [inquiryManagementRouter, caseManagement]
       };
     }
   }
diff --git a/package.json b/package.json
index 4c444b9..b2d2b59 100644
--- a/package.json
+++ b/package.json
@@ -29,21 +29,23 @@
     "not op_mini all"
   ],
   "dependencies": {
+    "@antv/g6": "^4.8.24",
     "@pureadmin/descriptions": "^1.1.1",
     "@pureadmin/table": "^2.3.2",
     "@pureadmin/utils": "^1.9.6",
     "@vue/composition-api": "^1.7.2",
     "@vueuse/core": "^10.2.0",
     "@vueuse/motion": "^2.0.0",
+    "@wangeditor/editor-for-vue": "^5.1.12",
     "animate.css": "^4.1.1",
     "axios": "^1.4.0",
     "dayjs": "^1.11.8",
+    "echarts": "^5.5.0",
     "element-plus": "2.3.6",
     "js-audio-recorder": "^1.0.7",
     "js-cookie": "^3.0.5",
     "lodash.debounce": "^4.0.8",
     "mitt": "^3.0.0",
-    "mockjs": "^1.1.0",
     "nprogress": "^0.2.0",
     "path": "^0.12.7",
     "pinia": "^2.1.4",
@@ -55,9 +57,11 @@
     "sortablejs": "^1.15.0",
     "uuid": "^9.0.1",
     "vue": "^3.3.4",
+    "vue-echarts": "^6.6.9",
     "vue-router": "^4.2.2",
     "vue-types": "^5.1.0",
-    "vue3-seamless-scroll": "^2.0.1"
+    "vue3-seamless-scroll": "^2.0.1",
+    "wangeditor": "^4.7.15"
   },
   "devDependencies": {
     "@commitlint/cli": "^17.6.6",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1bf5084..6d9af6b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,28 +1,34 @@
-lockfileVersion: '6.0'
+lockfileVersion: "6.0"
 
 settings:
   autoInstallPeers: true
   excludeLinksFromLockfile: false
 
 dependencies:
-  '@pureadmin/descriptions':
+  "@antv/g6":
+    specifier: ^4.8.24
+    version: 4.8.24
+  "@pureadmin/descriptions":
     specifier: ^1.1.1
     version: 1.2.0(element-plus@2.3.6)(typescript@5.0.4)
-  '@pureadmin/table':
+  "@pureadmin/table":
     specifier: ^2.3.2
     version: 2.3.4(element-plus@2.3.6)(typescript@5.0.4)
-  '@pureadmin/utils':
+  "@pureadmin/utils":
     specifier: ^1.9.6
-    version: 1.9.10(vue@3.3.5)
-  '@vue/composition-api':
+    version: 1.9.10(echarts@5.5.0)(vue@3.3.5)
+  "@vue/composition-api":
     specifier: ^1.7.2
     version: 1.7.2(vue@3.3.5)
-  '@vueuse/core':
+  "@vueuse/core":
     specifier: ^10.2.0
     version: 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
-  '@vueuse/motion':
+  "@vueuse/motion":
     specifier: ^2.0.0
     version: 2.0.0(@vue/composition-api@1.7.2)(vue@3.3.5)
+  "@wangeditor/editor-for-vue":
+    specifier: ^5.1.12
+    version: 5.1.12(@wangeditor/editor@5.1.23)(vue@3.3.5)
   animate.css:
     specifier: ^4.1.1
     version: 4.1.1
@@ -32,6 +38,9 @@ dependencies:
   dayjs:
     specifier: ^1.11.8
     version: 1.11.10
+  echarts:
+    specifier: ^5.5.0
+    version: 5.5.0
   element-plus:
     specifier: 2.3.6
     version: 2.3.6(@vue/composition-api@1.7.2)(vue@3.3.5)
@@ -47,9 +56,6 @@ dependencies:
   mitt:
     specifier: ^3.0.0
     version: 3.0.1
-  mockjs:
-    specifier: ^1.1.0
-    version: 1.1.0
   nprogress:
     specifier: ^0.2.0
     version: 0.2.0
@@ -83,6 +89,9 @@ dependencies:
   vue:
     specifier: ^3.3.4
     version: 3.3.5(typescript@5.0.4)
+  vue-echarts:
+    specifier: ^6.6.9
+    version: 6.6.9(@vue/composition-api@1.7.2)(echarts@5.5.0)(vue@3.3.5)
   vue-router:
     specifier: ^4.2.2
     version: 4.2.5(vue@3.3.5)
@@ -92,66 +101,69 @@ dependencies:
   vue3-seamless-scroll:
     specifier: ^2.0.1
     version: 2.0.1
+  wangeditor:
+    specifier: ^4.7.15
+    version: 4.7.15
 
 devDependencies:
-  '@commitlint/cli':
+  "@commitlint/cli":
     specifier: ^17.6.6
     version: 17.8.0
-  '@commitlint/config-conventional':
+  "@commitlint/config-conventional":
     specifier: ^17.6.6
     version: 17.8.0
-  '@iconify-icons/ant-design':
+  "@iconify-icons/ant-design":
     specifier: ^1.2.7
     version: 1.2.7
-  '@iconify-icons/ep':
+  "@iconify-icons/ep":
     specifier: ^1.2.12
     version: 1.2.12
-  '@iconify-icons/icon-park-outline':
+  "@iconify-icons/icon-park-outline":
     specifier: ^1.2.11
     version: 1.2.11
-  '@iconify-icons/ri':
+  "@iconify-icons/ri":
     specifier: ^1.2.9
     version: 1.2.10
-  '@iconify/vue':
+  "@iconify/vue":
     specifier: ^4.1.1
     version: 4.1.1(vue@3.3.5)
-  '@pureadmin/theme':
+  "@pureadmin/theme":
     specifier: ^3.1.0
     version: 3.1.0
-  '@types/js-cookie':
+  "@types/js-cookie":
     specifier: ^3.0.3
     version: 3.0.5
-  '@types/mockjs':
+  "@types/mockjs":
     specifier: ^1.0.7
     version: 1.0.9
-  '@types/node':
+  "@types/node":
     specifier: ^20.3.1
     version: 20.8.7
-  '@types/nprogress':
+  "@types/nprogress":
     specifier: 0.2.0
     version: 0.2.0
-  '@types/qs':
+  "@types/qs":
     specifier: ^6.9.7
     version: 6.9.9
-  '@types/sortablejs':
+  "@types/sortablejs":
     specifier: ^1.15.1
     version: 1.15.4
-  '@typescript-eslint/eslint-plugin':
+  "@typescript-eslint/eslint-plugin":
     specifier: ^5.60.0
     version: 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.0.4)
-  '@typescript-eslint/parser':
+  "@typescript-eslint/parser":
     specifier: ^5.60.0
     version: 5.62.0(eslint@8.51.0)(typescript@5.0.4)
-  '@vitejs/plugin-vue':
+  "@vitejs/plugin-vue":
     specifier: ^4.2.3
     version: 4.4.0(vite@4.5.0)(vue@3.3.5)
-  '@vitejs/plugin-vue-jsx':
+  "@vitejs/plugin-vue-jsx":
     specifier: ^3.0.1
     version: 3.0.2(vite@4.5.0)(vue@3.3.5)
-  '@vue/eslint-config-prettier':
+  "@vue/eslint-config-prettier":
     specifier: ^7.1.0
     version: 7.1.0(eslint@8.51.0)(prettier@2.8.8)
-  '@vue/eslint-config-typescript':
+  "@vue/eslint-config-typescript":
     specifier: ^11.0.3
     version: 11.0.3(eslint-plugin-vue@9.17.0)(eslint@8.51.0)(typescript@5.0.4)
   autoprefixer:
@@ -282,49 +294,389 @@ devDependencies:
     version: 1.8.19(typescript@5.0.4)
 
 packages:
-
   /@aashutoshrathi/word-wrap@1.2.6:
-    resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /@alloc/quick-lru@5.2.0:
-    resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /@ampproject/remapping@2.2.1:
-    resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==
+      }
+    engines: { node: ">=6.0.0" }
+    dependencies:
+      "@jridgewell/gen-mapping": 0.3.3
+      "@jridgewell/trace-mapping": 0.3.20
+
+  /@ant-design/colors@4.0.5:
+    resolution:
+      {
+        integrity: sha512-3mnuX2prnWOWvpFTS2WH2LoouWlOgtnIpc6IarWN6GOzzLF8dW/U8UctuvIPhoboETehZfJ61XP+CGakBEPJ3Q==
+      }
+    dependencies:
+      tinycolor2: 1.6.0
+    dev: false
+
+  /@antv/algorithm@0.1.26:
+    resolution:
+      {
+        integrity: sha512-DVhcFSQ8YQnMNW34Mk8BSsfc61iC1sAnmcfYoXTAshYHuU50p/6b7x3QYaGctDNKWGvi1ub7mPcSY0bK+aN0qg==
+      }
+    dependencies:
+      "@antv/util": 2.0.17
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/dom-util@2.0.4:
+    resolution:
+      {
+        integrity: sha512-2shXUl504fKwt82T3GkuT4Uoc6p9qjCKnJ8gXGLSW4T1W37dqf9AV28aCfoVPHp2BUXpSsB+PAJX2rG/jLHsLQ==
+      }
+    dependencies:
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/event-emitter@0.1.3:
+    resolution:
+      {
+        integrity: sha512-4ddpsiHN9Pd4UIlWuKVK1C4IiZIdbwQvy9i7DUSI3xNJ89FPUFt8lxDYj8GzzfdllV0NkJTRxnG+FvLk0llidg==
+      }
+    dev: false
+
+  /@antv/g-base@0.5.15:
+    resolution:
+      {
+        integrity: sha512-QOtq50QpnKez9J75/Z8j2yZ7QDQdk8R8mVQJiHtaEO5eI7DM4ZbrsWff/Ew26JYmPWdq7nbRuARMAD4PX9uuLA==
+      }
+    dependencies:
+      "@antv/event-emitter": 0.1.3
+      "@antv/g-math": 0.1.9
+      "@antv/matrix-util": 3.1.0-beta.3
+      "@antv/path-util": 2.0.15
+      "@antv/util": 2.0.17
+      "@types/d3-timer": 2.0.3
+      d3-ease: 1.0.7
+      d3-interpolate: 3.0.1
+      d3-timer: 1.0.10
+      detect-browser: 5.3.0
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/g-canvas@0.5.14:
+    resolution:
+      {
+        integrity: sha512-IUGLEMIMAUYgaBMT8h3FTmYQYz7sjQkKWwh6Psqx+UPK86fySa+G8fMRrh1EqAL07jVB+GRnn6Ym+3FoFUgeFg==
+      }
+    dependencies:
+      "@antv/g-base": 0.5.15
+      "@antv/g-math": 0.1.9
+      "@antv/matrix-util": 3.1.0-beta.3
+      "@antv/path-util": 2.0.15
+      "@antv/util": 2.0.17
+      gl-matrix: 3.4.3
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/g-math@0.1.9:
+    resolution:
+      {
+        integrity: sha512-KHMSfPfZ5XHM1PZnG42Q2gxXfOitYveNTA7L61lR6mhZ8Y/aExsYmHqaKBsSarU0z+6WLrl9C07PQJZaw0uljQ==
+      }
+    dependencies:
+      "@antv/util": 2.0.17
+      gl-matrix: 3.4.3
+    dev: false
+
+  /@antv/g-svg@0.5.7:
+    resolution:
+      {
+        integrity: sha512-jUbWoPgr4YNsOat2Y/rGAouNQYGpw4R0cvlN0YafwOyacFFYy2zC8RslNd6KkPhhR3XHNSqJOuCYZj/YmLUwYw==
+      }
+    dependencies:
+      "@antv/g-base": 0.5.15
+      "@antv/g-math": 0.1.9
+      "@antv/util": 2.0.17
+      detect-browser: 5.3.0
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/g-webgpu-core@0.7.2:
+    resolution:
+      {
+        integrity: sha512-xUMmop7f3Rs34zFYKXLqHhDR1CQTeDl/7vI7Sn3X/73BqJc3X3HIIRvm83Fg2CjVACaOzw4WeLRXNaOCp9fz9w==
+      }
+    dependencies:
+      eventemitter3: 4.0.7
+      gl-matrix: 3.4.3
+      lodash: 4.17.21
+      probe.gl: 3.6.0
+    dev: false
+
+  /@antv/g-webgpu-engine@0.7.2:
+    resolution:
+      {
+        integrity: sha512-lx8Y93IW2cnJvdoDRKyMmTdYqSC1pOmF0nyG3PGGyA0NI9vBYVgO0KTF6hkyWjdTWVq7XDZyf/h8CJridLh3lg==
+      }
+    dependencies:
+      "@antv/g-webgpu-core": 0.7.2
+      gl-matrix: 3.4.3
+      lodash: 4.17.21
+      regl: 1.7.0
+    dev: false
+
+  /@antv/g-webgpu@0.7.2:
+    resolution:
+      {
+        integrity: sha512-kw+oYGsdvj5qeUfy5DPb/jztZBV+2fmqBd3Vv8NlKatfBmv8AirYX/CCW74AUSdWm99rEiLyxFB1VdRZ6b/wnQ==
+      }
+    dependencies:
+      "@antv/g-webgpu-core": 0.7.2
+      "@antv/g-webgpu-engine": 0.7.2
+      gl-matrix: 3.4.3
+      gl-vec2: 1.3.0
+      lodash: 4.17.21
+    dev: false
+
+  /@antv/g6-core@0.8.24:
+    resolution:
+      {
+        integrity: sha512-rgI3dArAD8uoSz2+skS4ctN4x/Of33ivTIKaEYYvClxgkLZWVz9zvocy+5AWcVPBHZsAXkZcdh9zndIoWY/33A==
+      }
+    dependencies:
+      "@antv/algorithm": 0.1.26
+      "@antv/dom-util": 2.0.4
+      "@antv/event-emitter": 0.1.3
+      "@antv/g-base": 0.5.15
+      "@antv/g-math": 0.1.9
+      "@antv/matrix-util": 3.1.0-beta.3
+      "@antv/path-util": 2.0.15
+      "@antv/util": 2.0.17
+      ml-matrix: 6.11.0
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/g6-element@0.8.24(@antv/g6@4.8.24):
+    resolution:
+      {
+        integrity: sha512-61FXkt9LY+6EOUtSam1iFTOW2AM59sPVcV1BuPj4dXiD0dluLE+R7d8B/94g1tKDw9tsjhfUQGC7hTXscJRJFw==
+      }
+    peerDependencies:
+      "@antv/g6": 4.8.24
+    dependencies:
+      "@antv/g-base": 0.5.15
+      "@antv/g6": 4.8.24
+      "@antv/g6-core": 0.8.24
+      "@antv/util": 2.0.17
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/g6-pc@0.8.24(@antv/g6@4.8.24):
+    resolution:
+      {
+        integrity: sha512-nf0y1lrp8J5DotqRryXd2S/J30COW8spVcLF9gUqywGqQAHfE00Ywkqr+PZBnsfCZXsXCi9o0+CE9NrkWs4SBQ==
+      }
+    dependencies:
+      "@ant-design/colors": 4.0.5
+      "@antv/algorithm": 0.1.26
+      "@antv/dom-util": 2.0.4
+      "@antv/event-emitter": 0.1.3
+      "@antv/g-base": 0.5.15
+      "@antv/g-canvas": 0.5.14
+      "@antv/g-math": 0.1.9
+      "@antv/g-svg": 0.5.7
+      "@antv/g6-core": 0.8.24
+      "@antv/g6-element": 0.8.24(@antv/g6@4.8.24)
+      "@antv/g6-plugin": 0.8.24(@antv/g6@4.8.24)
+      "@antv/hierarchy": 0.6.11
+      "@antv/layout": 0.3.25(dagre@0.8.5)
+      "@antv/matrix-util": 3.1.0-beta.3
+      "@antv/path-util": 2.0.15
+      "@antv/util": 2.0.17
+      color: 3.2.1
+      d3-force: 2.1.1
+      dagre: 0.8.5
+      insert-css: 2.0.0
+      ml-matrix: 6.11.0
+      tslib: 2.6.2
+    transitivePeerDependencies:
+      - "@antv/g6"
+    dev: false
+
+  /@antv/g6-plugin@0.8.24(@antv/g6@4.8.24):
+    resolution:
+      {
+        integrity: sha512-ZIOnwLTC7SM2bFiJZ3vYFWnkyOCWKqnU96i/fBh1qAoY5slDS3hatenZWEXUtOcqaKw1h+5A5f72MRXqBBVn0g==
+      }
+    peerDependencies:
+      "@antv/g6": 4.8.24
+    dependencies:
+      "@antv/dom-util": 2.0.4
+      "@antv/g-base": 0.5.15
+      "@antv/g-canvas": 0.5.14
+      "@antv/g-svg": 0.5.7
+      "@antv/g6": 4.8.24
+      "@antv/g6-core": 0.8.24
+      "@antv/g6-element": 0.8.24(@antv/g6@4.8.24)
+      "@antv/matrix-util": 3.1.0-beta.3
+      "@antv/path-util": 2.0.15
+      "@antv/scale": 0.3.18
+      "@antv/util": 2.0.17
+      insert-css: 2.0.0
+    dev: false
+
+  /@antv/g6@4.8.24:
+    resolution:
+      {
+        integrity: sha512-bgj7sZ+z45JmOngIpYpwmSIg7SboMLZBoAlX0+RoAETZB3/xvZO0MXT3lCSyAhIgm5Sb68pekKi7OStuo04NyQ==
+      }
+    dependencies:
+      "@antv/g6-pc": 0.8.24(@antv/g6@4.8.24)
+    dev: false
+
+  /@antv/graphlib@1.2.0:
+    resolution:
+      {
+        integrity: sha512-hhJOMThec51nU4Fe5p/viLlNIL71uDEgYFzKPajWjr2715SFG1HAgiP6AVylIeqBcAZ04u3Lw7usjl/TuI5RuQ==
+      }
+    dev: false
+
+  /@antv/hierarchy@0.6.11:
+    resolution:
+      {
+        integrity: sha512-RJVhEMCuu4vj+Dt25lXIiNdd7jaqm/fqWGYikiELha4S5tnzdJoTUaUvvpfWlxLx4B0RsS9XRwBs1bOKN71TKg==
+      }
+    dependencies:
+      "@antv/util": 2.0.17
+    dev: false
+
+  /@antv/layout@0.3.25(dagre@0.8.5):
+    resolution:
+      {
+        integrity: sha512-d29Aw1PXoAavMRZy7iTB9L5rMBeChFEX0BJ9ELP4TI35ySdCu07YbmPo9ju9OH/6sG2/NB3o85Ayxrre3iwX/g==
+      }
+    dependencies:
+      "@antv/g-webgpu": 0.7.2
+      "@antv/graphlib": 1.2.0
+      "@antv/util": 3.3.6
+      d3-force: 2.1.1
+      d3-quadtree: 2.0.0
+      dagre-compound: 0.0.11(dagre@0.8.5)
+      ml-matrix: 6.5.0
+    transitivePeerDependencies:
+      - dagre
+    dev: false
+
+  /@antv/matrix-util@3.0.4:
+    resolution:
+      {
+        integrity: sha512-BAPyu6dUliHcQ7fm9hZSGKqkwcjEDVLVAstlHULLvcMZvANHeLXgHEgV7JqcAV/GIhIz8aZChIlzM1ZboiXpYQ==
+      }
+    dependencies:
+      "@antv/util": 2.0.17
+      gl-matrix: 3.4.3
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/matrix-util@3.1.0-beta.3:
+    resolution:
+      {
+        integrity: sha512-W2R6Za3A6CmG51Y/4jZUM/tFgYSq7vTqJL1VD9dKrvwxS4sE0ZcXINtkp55CdyBwJ6Cwm8pfoRpnD4FnHahN0A==
+      }
+    dependencies:
+      "@antv/util": 2.0.17
+      gl-matrix: 3.4.3
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/path-util@2.0.15:
+    resolution:
+      {
+        integrity: sha512-R2VLZ5C8PLPtr3VciNyxtjKqJ0XlANzpFb5sE9GE61UQqSRuSVSzIakMxjEPrpqbgc+s+y8i+fmc89Snu7qbNw==
+      }
+    dependencies:
+      "@antv/matrix-util": 3.0.4
+      "@antv/util": 2.0.17
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/scale@0.3.18:
+    resolution:
+      {
+        integrity: sha512-GHwE6Lo7S/Q5fgaLPaCsW+CH+3zl4aXpnN1skOiEY0Ue9/u+s2EySv6aDXYkAqs//i0uilMDD/0/4n8caX9U9w==
+      }
+    dependencies:
+      "@antv/util": 2.0.17
+      fecha: 4.2.3
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/util@2.0.17:
+    resolution:
+      {
+        integrity: sha512-o6I9hi5CIUvLGDhth0RxNSFDRwXeywmt6ExR4+RmVAzIi48ps6HUy+svxOCayvrPBN37uE6TAc2KDofRo0nK9Q==
+      }
     dependencies:
-      '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.20
+      csstype: 3.1.2
+      tslib: 2.6.2
+    dev: false
+
+  /@antv/util@3.3.6:
+    resolution:
+      {
+        integrity: sha512-Oj2uAwBWEpEKbYcYgSJ/B6zv7t515L+JZzSpnkZeez/qwvDbS6s80lQRuzWzVhWCTHKSPLkgImxhkV9nzLmv4Q==
+      }
+    dependencies:
+      fast-deep-equal: 3.1.3
+      gl-matrix: 3.4.3
+      tslib: 2.6.2
+    dev: false
 
   /@babel/code-frame@7.22.13:
-    resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/highlight': 7.22.20
+      "@babel/highlight": 7.22.20
       chalk: 2.4.2
 
   /@babel/compat-data@7.23.2:
-    resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==
+      }
+    engines: { node: ">=6.9.0" }
 
   /@babel/core@7.23.2:
-    resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@ampproject/remapping': 2.2.1
-      '@babel/code-frame': 7.22.13
-      '@babel/generator': 7.23.0
-      '@babel/helper-compilation-targets': 7.22.15
-      '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
-      '@babel/helpers': 7.23.2
-      '@babel/parser': 7.23.0
-      '@babel/template': 7.22.15
-      '@babel/traverse': 7.23.2
-      '@babel/types': 7.23.0
+    resolution:
+      {
+        integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      "@ampproject/remapping": 2.2.1
+      "@babel/code-frame": 7.22.13
+      "@babel/generator": 7.23.0
+      "@babel/helper-compilation-targets": 7.22.15
+      "@babel/helper-module-transforms": 7.23.0(@babel/core@7.23.2)
+      "@babel/helpers": 7.23.2
+      "@babel/parser": 7.23.0
+      "@babel/template": 7.22.15
+      "@babel/traverse": 7.23.2
+      "@babel/types": 7.23.0
       convert-source-map: 2.0.0
       debug: 4.3.4
       gensync: 1.0.0-beta.2
@@ -334,292 +686,405 @@ packages:
       - supports-color
 
   /@babel/generator@7.23.0:
-    resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.23.0
-      '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.20
+    resolution:
+      {
+        integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      "@babel/types": 7.23.0
+      "@jridgewell/gen-mapping": 0.3.3
+      "@jridgewell/trace-mapping": 0.3.20
       jsesc: 2.5.2
 
   /@babel/helper-annotate-as-pure@7.22.5:
-    resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
     dev: true
 
   /@babel/helper-compilation-targets@7.22.15:
-    resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/compat-data': 7.23.2
-      '@babel/helper-validator-option': 7.22.15
+    resolution:
+      {
+        integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      "@babel/compat-data": 7.23.2
+      "@babel/helper-validator-option": 7.22.15
       browserslist: 4.22.1
       lru-cache: 5.1.1
       semver: 6.3.1
 
   /@babel/helper-create-class-features-plugin@7.22.15(@babel/core@7.23.2):
-    resolution: {integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-member-expression-to-functions': 7.23.0
-      '@babel/helper-optimise-call-expression': 7.22.5
-      '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.2)
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
+    resolution:
+      {
+        integrity: sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==
+      }
+    engines: { node: ">=6.9.0" }
+    peerDependencies:
+      "@babel/core": ^7.0.0
+    dependencies:
+      "@babel/core": 7.23.2
+      "@babel/helper-annotate-as-pure": 7.22.5
+      "@babel/helper-environment-visitor": 7.22.20
+      "@babel/helper-function-name": 7.23.0
+      "@babel/helper-member-expression-to-functions": 7.23.0
+      "@babel/helper-optimise-call-expression": 7.22.5
+      "@babel/helper-replace-supers": 7.22.20(@babel/core@7.23.2)
+      "@babel/helper-skip-transparent-expression-wrappers": 7.22.5
+      "@babel/helper-split-export-declaration": 7.22.6
       semver: 6.3.1
     dev: true
 
   /@babel/helper-environment-visitor@7.22.20:
-    resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==
+      }
+    engines: { node: ">=6.9.0" }
 
   /@babel/helper-function-name@7.23.0:
-    resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/template': 7.22.15
-      '@babel/types': 7.23.0
+      "@babel/template": 7.22.15
+      "@babel/types": 7.23.0
 
   /@babel/helper-hoist-variables@7.22.5:
-    resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
 
   /@babel/helper-member-expression-to-functions@7.23.0:
-    resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
     dev: true
 
   /@babel/helper-module-imports@7.22.15:
-    resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
 
   /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2):
-    resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==
+      }
+    engines: { node: ">=6.9.0" }
     peerDependencies:
-      '@babel/core': ^7.0.0
+      "@babel/core": ^7.0.0
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-module-imports': 7.22.15
-      '@babel/helper-simple-access': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/helper-validator-identifier': 7.22.20
+      "@babel/core": 7.23.2
+      "@babel/helper-environment-visitor": 7.22.20
+      "@babel/helper-module-imports": 7.22.15
+      "@babel/helper-simple-access": 7.22.5
+      "@babel/helper-split-export-declaration": 7.22.6
+      "@babel/helper-validator-identifier": 7.22.20
 
   /@babel/helper-optimise-call-expression@7.22.5:
-    resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
     dev: true
 
   /@babel/helper-plugin-utils@7.22.5:
-    resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==
+      }
+    engines: { node: ">=6.9.0" }
     dev: true
 
   /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.2):
-    resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==
+      }
+    engines: { node: ">=6.9.0" }
     peerDependencies:
-      '@babel/core': ^7.0.0
+      "@babel/core": ^7.0.0
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-member-expression-to-functions': 7.23.0
-      '@babel/helper-optimise-call-expression': 7.22.5
+      "@babel/core": 7.23.2
+      "@babel/helper-environment-visitor": 7.22.20
+      "@babel/helper-member-expression-to-functions": 7.23.0
+      "@babel/helper-optimise-call-expression": 7.22.5
     dev: true
 
   /@babel/helper-simple-access@7.22.5:
-    resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
 
   /@babel/helper-skip-transparent-expression-wrappers@7.22.5:
-    resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
     dev: true
 
   /@babel/helper-split-export-declaration@7.22.6:
-    resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
 
   /@babel/helper-string-parser@7.22.5:
-    resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==
+      }
+    engines: { node: ">=6.9.0" }
 
   /@babel/helper-validator-identifier@7.22.20:
-    resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==
+      }
+    engines: { node: ">=6.9.0" }
 
   /@babel/helper-validator-option@7.22.15:
-    resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==
+      }
+    engines: { node: ">=6.9.0" }
 
   /@babel/helpers@7.23.2:
-    resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/template': 7.22.15
-      '@babel/traverse': 7.23.2
-      '@babel/types': 7.23.0
+    resolution:
+      {
+        integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      "@babel/template": 7.22.15
+      "@babel/traverse": 7.23.2
+      "@babel/types": 7.23.0
     transitivePeerDependencies:
       - supports-color
 
   /@babel/highlight@7.22.20:
-    resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/helper-validator-identifier': 7.22.20
+      "@babel/helper-validator-identifier": 7.22.20
       chalk: 2.4.2
       js-tokens: 4.0.0
 
   /@babel/parser@7.23.0:
-    resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
+      }
+    engines: { node: ">=6.0.0" }
     hasBin: true
     dependencies:
-      '@babel/types': 7.23.0
+      "@babel/types": 7.23.0
 
   /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.2):
-    resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==
+      }
+    engines: { node: ">=6.9.0" }
     peerDependencies:
-      '@babel/core': ^7.0.0-0
+      "@babel/core": ^7.0.0-0
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-plugin-utils': 7.22.5
+      "@babel/core": 7.23.2
+      "@babel/helper-plugin-utils": 7.22.5
     dev: true
 
   /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.2):
-    resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==
+      }
+    engines: { node: ">=6.9.0" }
     peerDependencies:
-      '@babel/core': ^7.0.0-0
+      "@babel/core": ^7.0.0-0
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-plugin-utils': 7.22.5
+      "@babel/core": 7.23.2
+      "@babel/helper-plugin-utils": 7.22.5
     dev: true
 
   /@babel/plugin-transform-typescript@7.22.15(@babel/core@7.23.2):
-    resolution: {integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA==
+      }
+    engines: { node: ">=6.9.0" }
     peerDependencies:
-      '@babel/core': ^7.0.0-0
+      "@babel/core": ^7.0.0-0
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.2)
-      '@babel/helper-plugin-utils': 7.22.5
-      '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2)
+      "@babel/core": 7.23.2
+      "@babel/helper-annotate-as-pure": 7.22.5
+      "@babel/helper-create-class-features-plugin": 7.22.15(@babel/core@7.23.2)
+      "@babel/helper-plugin-utils": 7.22.5
+      "@babel/plugin-syntax-typescript": 7.22.5(@babel/core@7.23.2)
     dev: true
 
+  /@babel/runtime-corejs3@7.23.4:
+    resolution:
+      {
+        integrity: sha512-zQyB4MJGM+rvd4pM58n26kf3xbiitw9MHzL8oLiBMKb8MCtVDfV5nDzzJWWzLMtbvKI9wN6XwJYl479qF4JluQ==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      core-js-pure: 3.33.3
+      regenerator-runtime: 0.14.0
+    dev: false
+
   /@babel/runtime@7.23.2:
-    resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
       regenerator-runtime: 0.14.0
     dev: false
 
   /@babel/standalone@7.23.2:
-    resolution: {integrity: sha512-VJNw7OS26JvB6rE9XpbT6uQeQIEBWU5eeHGS4VR/+/4ZoKdLBXLcy66ZVJ/9IBkK1RMp8B0cohvhzdKWtJAGmg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-VJNw7OS26JvB6rE9XpbT6uQeQIEBWU5eeHGS4VR/+/4ZoKdLBXLcy66ZVJ/9IBkK1RMp8B0cohvhzdKWtJAGmg==
+      }
+    engines: { node: ">=6.9.0" }
     requiresBuild: true
     dev: false
     optional: true
 
   /@babel/template@7.22.15:
-    resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==
+      }
+    engines: { node: ">=6.9.0" }
     dependencies:
-      '@babel/code-frame': 7.22.13
-      '@babel/parser': 7.23.0
-      '@babel/types': 7.23.0
+      "@babel/code-frame": 7.22.13
+      "@babel/parser": 7.23.0
+      "@babel/types": 7.23.0
 
   /@babel/traverse@7.23.2:
-    resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.22.13
-      '@babel/generator': 7.23.0
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-hoist-variables': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/parser': 7.23.0
-      '@babel/types': 7.23.0
+    resolution:
+      {
+        integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      "@babel/code-frame": 7.22.13
+      "@babel/generator": 7.23.0
+      "@babel/helper-environment-visitor": 7.22.20
+      "@babel/helper-function-name": 7.23.0
+      "@babel/helper-hoist-variables": 7.22.5
+      "@babel/helper-split-export-declaration": 7.22.6
+      "@babel/parser": 7.23.0
+      "@babel/types": 7.23.0
       debug: 4.3.4
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
 
   /@babel/types@7.23.0:
-    resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-string-parser': 7.22.5
-      '@babel/helper-validator-identifier': 7.22.20
+    resolution:
+      {
+        integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==
+      }
+    engines: { node: ">=6.9.0" }
+    dependencies:
+      "@babel/helper-string-parser": 7.22.5
+      "@babel/helper-validator-identifier": 7.22.20
       to-fast-properties: 2.0.0
 
   /@commitlint/cli@17.8.0:
-    resolution: {integrity: sha512-D3LdyZYbiRyAChfJMNlAd9f2P9vNQ7GWbI9gN2o7L5hF07QJDqj4z/pcJF3PjDbJWOaUUXla287RdDmmKqH2WQ==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-D3LdyZYbiRyAChfJMNlAd9f2P9vNQ7GWbI9gN2o7L5hF07QJDqj4z/pcJF3PjDbJWOaUUXla287RdDmmKqH2WQ==
+      }
+    engines: { node: ">=v14" }
     hasBin: true
     dependencies:
-      '@commitlint/format': 17.4.4
-      '@commitlint/lint': 17.8.0
-      '@commitlint/load': 17.8.0
-      '@commitlint/read': 17.5.1
-      '@commitlint/types': 17.4.4
+      "@commitlint/format": 17.4.4
+      "@commitlint/lint": 17.8.0
+      "@commitlint/load": 17.8.0
+      "@commitlint/read": 17.5.1
+      "@commitlint/types": 17.4.4
       execa: 5.1.1
       lodash.isfunction: 3.0.9
       resolve-from: 5.0.0
       resolve-global: 1.0.0
       yargs: 17.7.2
     transitivePeerDependencies:
-      - '@swc/core'
-      - '@swc/wasm'
+      - "@swc/core"
+      - "@swc/wasm"
     dev: true
 
   /@commitlint/config-conventional@17.8.0:
-    resolution: {integrity: sha512-MgiFXujmqAvi7M33C7OSMTznwrVkckrbXe/aZWQ/+KFGLLF6IE50XIcjGrW0/uiDGb/im5qbqF2dh1dCFNa+sQ==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-MgiFXujmqAvi7M33C7OSMTznwrVkckrbXe/aZWQ/+KFGLLF6IE50XIcjGrW0/uiDGb/im5qbqF2dh1dCFNa+sQ==
+      }
+    engines: { node: ">=v14" }
     dependencies:
       conventional-changelog-conventionalcommits: 6.1.0
     dev: true
 
   /@commitlint/config-validator@17.6.7:
-    resolution: {integrity: sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-vJSncmnzwMvpr3lIcm0I8YVVDJTzyjy7NZAeXbTXy+MPUdAr9pKyyg7Tx/ebOQ9kqzE6O9WT6jg2164br5UdsQ==
+      }
+    engines: { node: ">=v14" }
     dependencies:
-      '@commitlint/types': 17.4.4
+      "@commitlint/types": 17.4.4
       ajv: 8.12.0
     dev: true
 
   /@commitlint/ensure@17.6.7:
-    resolution: {integrity: sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-mfDJOd1/O/eIb/h4qwXzUxkmskXDL9vNPnZ4AKYKiZALz4vHzwMxBSYtyL2mUIDeU9DRSpEUins8SeKtFkYHSw==
+      }
+    engines: { node: ">=v14" }
     dependencies:
-      '@commitlint/types': 17.4.4
+      "@commitlint/types": 17.4.4
       lodash.camelcase: 4.3.0
       lodash.kebabcase: 4.1.1
       lodash.snakecase: 4.1.1
@@ -628,45 +1093,60 @@ packages:
     dev: true
 
   /@commitlint/execute-rule@17.4.0:
-    resolution: {integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-LIgYXuCSO5Gvtc0t9bebAMSwd68ewzmqLypqI2Kke1rqOqqDbMpYcYfoPfFlv9eyLIh4jocHWwCK5FS7z9icUA==
+      }
+    engines: { node: ">=v14" }
     dev: true
 
   /@commitlint/format@17.4.4:
-    resolution: {integrity: sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==
+      }
+    engines: { node: ">=v14" }
     dependencies:
-      '@commitlint/types': 17.4.4
+      "@commitlint/types": 17.4.4
       chalk: 4.1.2
     dev: true
 
   /@commitlint/is-ignored@17.8.0:
-    resolution: {integrity: sha512-8bR6rxNcWaNprPBdE4ePIOwbxutTQGOsRPYWssX+zjGxnEljzaZSGzFUOMxapYILlf8Tts/O1wPQgG549Rdvdg==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-8bR6rxNcWaNprPBdE4ePIOwbxutTQGOsRPYWssX+zjGxnEljzaZSGzFUOMxapYILlf8Tts/O1wPQgG549Rdvdg==
+      }
+    engines: { node: ">=v14" }
     dependencies:
-      '@commitlint/types': 17.4.4
+      "@commitlint/types": 17.4.4
       semver: 7.5.4
     dev: true
 
   /@commitlint/lint@17.8.0:
-    resolution: {integrity: sha512-4ihwnqOY4TcJN6iz5Jv1LeYavvBllONwFyGxOIWmCT5s4PNMb43cws2TUdbXTZL1Vq59etGKd5LWYDFPVbs5EA==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-4ihwnqOY4TcJN6iz5Jv1LeYavvBllONwFyGxOIWmCT5s4PNMb43cws2TUdbXTZL1Vq59etGKd5LWYDFPVbs5EA==
+      }
+    engines: { node: ">=v14" }
     dependencies:
-      '@commitlint/is-ignored': 17.8.0
-      '@commitlint/parse': 17.7.0
-      '@commitlint/rules': 17.7.0
-      '@commitlint/types': 17.4.4
+      "@commitlint/is-ignored": 17.8.0
+      "@commitlint/parse": 17.7.0
+      "@commitlint/rules": 17.7.0
+      "@commitlint/types": 17.4.4
     dev: true
 
   /@commitlint/load@17.8.0:
-    resolution: {integrity: sha512-9VnGXYJCP4tXmR4YrwP8n5oX6T5ZsHfPQq6WuUQOvAI+QsDQMaTGgTRXr7us+xsjz+b+mMBSagogqfUx2aixyw==}
-    engines: {node: '>=v14'}
-    dependencies:
-      '@commitlint/config-validator': 17.6.7
-      '@commitlint/execute-rule': 17.4.0
-      '@commitlint/resolve-extends': 17.6.7
-      '@commitlint/types': 17.4.4
-      '@types/node': 20.5.1
+    resolution:
+      {
+        integrity: sha512-9VnGXYJCP4tXmR4YrwP8n5oX6T5ZsHfPQq6WuUQOvAI+QsDQMaTGgTRXr7us+xsjz+b+mMBSagogqfUx2aixyw==
+      }
+    engines: { node: ">=v14" }
+    dependencies:
+      "@commitlint/config-validator": 17.6.7
+      "@commitlint/execute-rule": 17.4.0
+      "@commitlint/resolve-extends": 17.6.7
+      "@commitlint/types": 17.4.4
+      "@types/node": 20.5.1
       chalk: 4.1.2
       cosmiconfig: 8.3.6(typescript@5.0.4)
       cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6)(ts-node@10.9.1)(typescript@5.0.4)
@@ -677,41 +1157,53 @@ packages:
       ts-node: 10.9.1(@types/node@20.8.7)(typescript@5.0.4)
       typescript: 5.0.4
     transitivePeerDependencies:
-      - '@swc/core'
-      - '@swc/wasm'
+      - "@swc/core"
+      - "@swc/wasm"
     dev: true
 
   /@commitlint/message@17.4.2:
-    resolution: {integrity: sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-3XMNbzB+3bhKA1hSAWPCQA3lNxR4zaeQAQcHj0Hx5sVdO6ryXtgUBGGv+1ZCLMgAPRixuc6en+iNAzZ4NzAa8Q==
+      }
+    engines: { node: ">=v14" }
     dev: true
 
   /@commitlint/parse@17.7.0:
-    resolution: {integrity: sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-dIvFNUMCUHqq5Abv80mIEjLVfw8QNuA4DS7OWip4pcK/3h5wggmjVnlwGCDvDChkw2TjK1K6O+tAEV78oxjxag==
+      }
+    engines: { node: ">=v14" }
     dependencies:
-      '@commitlint/types': 17.4.4
+      "@commitlint/types": 17.4.4
       conventional-changelog-angular: 6.0.0
       conventional-commits-parser: 4.0.0
     dev: true
 
   /@commitlint/read@17.5.1:
-    resolution: {integrity: sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==}
-    engines: {node: '>=v14'}
-    dependencies:
-      '@commitlint/top-level': 17.4.0
-      '@commitlint/types': 17.4.4
+    resolution:
+      {
+        integrity: sha512-7IhfvEvB//p9aYW09YVclHbdf1u7g7QhxeYW9ZHSO8Huzp8Rz7m05aCO1mFG7G8M+7yfFnXB5xOmG18brqQIBg==
+      }
+    engines: { node: ">=v14" }
+    dependencies:
+      "@commitlint/top-level": 17.4.0
+      "@commitlint/types": 17.4.4
       fs-extra: 11.1.1
       git-raw-commits: 2.0.11
       minimist: 1.2.8
     dev: true
 
   /@commitlint/resolve-extends@17.6.7:
-    resolution: {integrity: sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==}
-    engines: {node: '>=v14'}
-    dependencies:
-      '@commitlint/config-validator': 17.6.7
-      '@commitlint/types': 17.4.4
+    resolution:
+      {
+        integrity: sha512-PfeoAwLHtbOaC9bGn/FADN156CqkFz6ZKiVDMjuC2N5N0740Ke56rKU7Wxdwya8R8xzLK9vZzHgNbuGhaOVKIg==
+      }
+    engines: { node: ">=v14" }
+    dependencies:
+      "@commitlint/config-validator": 17.6.7
+      "@commitlint/types": 17.4.4
       import-fresh: 3.3.0
       lodash.mergewith: 4.6.2
       resolve-from: 5.0.0
@@ -719,70 +1211,97 @@ packages:
     dev: true
 
   /@commitlint/rules@17.7.0:
-    resolution: {integrity: sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==}
-    engines: {node: '>=v14'}
-    dependencies:
-      '@commitlint/ensure': 17.6.7
-      '@commitlint/message': 17.4.2
-      '@commitlint/to-lines': 17.4.0
-      '@commitlint/types': 17.4.4
+    resolution:
+      {
+        integrity: sha512-J3qTh0+ilUE5folSaoK91ByOb8XeQjiGcdIdiB/8UT1/Rd1itKo0ju/eQVGyFzgTMYt8HrDJnGTmNWwcMR1rmA==
+      }
+    engines: { node: ">=v14" }
+    dependencies:
+      "@commitlint/ensure": 17.6.7
+      "@commitlint/message": 17.4.2
+      "@commitlint/to-lines": 17.4.0
+      "@commitlint/types": 17.4.4
       execa: 5.1.1
     dev: true
 
   /@commitlint/to-lines@17.4.0:
-    resolution: {integrity: sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-LcIy/6ZZolsfwDUWfN1mJ+co09soSuNASfKEU5sCmgFCvX5iHwRYLiIuoqXzOVDYOy7E7IcHilr/KS0e5T+0Hg==
+      }
+    engines: { node: ">=v14" }
     dev: true
 
   /@commitlint/top-level@17.4.0:
-    resolution: {integrity: sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-/1loE/g+dTTQgHnjoCy0AexKAEFyHsR2zRB4NWrZ6lZSMIxAhBJnmCqwao7b4H8888PsfoTBCLBYIw8vGnej8g==
+      }
+    engines: { node: ">=v14" }
     dependencies:
       find-up: 5.0.0
     dev: true
 
   /@commitlint/types@17.4.4:
-    resolution: {integrity: sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==}
-    engines: {node: '>=v14'}
+    resolution:
+      {
+        integrity: sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==
+      }
+    engines: { node: ">=v14" }
     dependencies:
       chalk: 4.1.2
     dev: true
 
   /@cspotcode/source-map-support@0.8.1:
-    resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==
+      }
+    engines: { node: ">=12" }
     dependencies:
-      '@jridgewell/trace-mapping': 0.3.9
+      "@jridgewell/trace-mapping": 0.3.9
     dev: true
 
   /@csstools/css-parser-algorithms@2.3.2(@csstools/css-tokenizer@2.2.1):
-    resolution: {integrity: sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==}
-    engines: {node: ^14 || ^16 || >=18}
+    resolution:
+      {
+        integrity: sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==
+      }
+    engines: { node: ^14 || ^16 || >=18 }
     peerDependencies:
-      '@csstools/css-tokenizer': ^2.2.1
+      "@csstools/css-tokenizer": ^2.2.1
     dependencies:
-      '@csstools/css-tokenizer': 2.2.1
+      "@csstools/css-tokenizer": 2.2.1
     dev: true
 
   /@csstools/css-tokenizer@2.2.1:
-    resolution: {integrity: sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==}
-    engines: {node: ^14 || ^16 || >=18}
+    resolution:
+      {
+        integrity: sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==
+      }
+    engines: { node: ^14 || ^16 || >=18 }
     dev: true
 
   /@csstools/media-query-list-parser@2.1.5(@csstools/css-parser-algorithms@2.3.2)(@csstools/css-tokenizer@2.2.1):
-    resolution: {integrity: sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==}
-    engines: {node: ^14 || ^16 || >=18}
+    resolution:
+      {
+        integrity: sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==
+      }
+    engines: { node: ^14 || ^16 || >=18 }
     peerDependencies:
-      '@csstools/css-parser-algorithms': ^2.3.2
-      '@csstools/css-tokenizer': ^2.2.1
+      "@csstools/css-parser-algorithms": ^2.3.2
+      "@csstools/css-tokenizer": ^2.2.1
     dependencies:
-      '@csstools/css-parser-algorithms': 2.3.2(@csstools/css-tokenizer@2.2.1)
-      '@csstools/css-tokenizer': 2.2.1
+      "@csstools/css-parser-algorithms": 2.3.2(@csstools/css-tokenizer@2.2.1)
+      "@csstools/css-tokenizer": 2.2.1
     dev: true
 
   /@csstools/selector-specificity@3.0.0(postcss-selector-parser@6.0.13):
-    resolution: {integrity: sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==}
-    engines: {node: ^14 || ^16 || >=18}
+    resolution:
+      {
+        integrity: sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==
+      }
+    engines: { node: ^14 || ^16 || >=18 }
     peerDependencies:
       postcss-selector-parser: ^6.0.13
     dependencies:
@@ -790,12 +1309,18 @@ packages:
     dev: true
 
   /@ctrl/tinycolor@3.6.1:
-    resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
+      }
+    engines: { node: ">=10" }
     dev: false
 
   /@element-plus/icons-vue@2.1.0(vue@3.3.5):
-    resolution: {integrity: sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==}
+    resolution:
+      {
+        integrity: sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==
+      }
     peerDependencies:
       vue: ^3.2.0
     dependencies:
@@ -803,8 +1328,11 @@ packages:
     dev: false
 
   /@esbuild/android-arm64@0.18.20:
-    resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
+      }
+    engines: { node: ">=12" }
     cpu: [arm64]
     os: [android]
     requiresBuild: true
@@ -812,8 +1340,11 @@ packages:
     optional: true
 
   /@esbuild/android-arm@0.18.20:
-    resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
+      }
+    engines: { node: ">=12" }
     cpu: [arm]
     os: [android]
     requiresBuild: true
@@ -821,8 +1352,11 @@ packages:
     optional: true
 
   /@esbuild/android-x64@0.18.20:
-    resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [android]
     requiresBuild: true
@@ -830,8 +1364,11 @@ packages:
     optional: true
 
   /@esbuild/darwin-arm64@0.18.20:
-    resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
+      }
+    engines: { node: ">=12" }
     cpu: [arm64]
     os: [darwin]
     requiresBuild: true
@@ -839,8 +1376,11 @@ packages:
     optional: true
 
   /@esbuild/darwin-x64@0.18.20:
-    resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [darwin]
     requiresBuild: true
@@ -848,8 +1388,11 @@ packages:
     optional: true
 
   /@esbuild/freebsd-arm64@0.18.20:
-    resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
+      }
+    engines: { node: ">=12" }
     cpu: [arm64]
     os: [freebsd]
     requiresBuild: true
@@ -857,8 +1400,11 @@ packages:
     optional: true
 
   /@esbuild/freebsd-x64@0.18.20:
-    resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [freebsd]
     requiresBuild: true
@@ -866,8 +1412,11 @@ packages:
     optional: true
 
   /@esbuild/linux-arm64@0.18.20:
-    resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
+      }
+    engines: { node: ">=12" }
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
@@ -875,8 +1424,11 @@ packages:
     optional: true
 
   /@esbuild/linux-arm@0.18.20:
-    resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
+      }
+    engines: { node: ">=12" }
     cpu: [arm]
     os: [linux]
     requiresBuild: true
@@ -884,8 +1436,11 @@ packages:
     optional: true
 
   /@esbuild/linux-ia32@0.18.20:
-    resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
+      }
+    engines: { node: ">=12" }
     cpu: [ia32]
     os: [linux]
     requiresBuild: true
@@ -893,8 +1448,11 @@ packages:
     optional: true
 
   /@esbuild/linux-loong64@0.18.20:
-    resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
+      }
+    engines: { node: ">=12" }
     cpu: [loong64]
     os: [linux]
     requiresBuild: true
@@ -902,8 +1460,11 @@ packages:
     optional: true
 
   /@esbuild/linux-mips64el@0.18.20:
-    resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
+      }
+    engines: { node: ">=12" }
     cpu: [mips64el]
     os: [linux]
     requiresBuild: true
@@ -911,8 +1472,11 @@ packages:
     optional: true
 
   /@esbuild/linux-ppc64@0.18.20:
-    resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
+      }
+    engines: { node: ">=12" }
     cpu: [ppc64]
     os: [linux]
     requiresBuild: true
@@ -920,8 +1484,11 @@ packages:
     optional: true
 
   /@esbuild/linux-riscv64@0.18.20:
-    resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
+      }
+    engines: { node: ">=12" }
     cpu: [riscv64]
     os: [linux]
     requiresBuild: true
@@ -929,8 +1496,11 @@ packages:
     optional: true
 
   /@esbuild/linux-s390x@0.18.20:
-    resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
+      }
+    engines: { node: ">=12" }
     cpu: [s390x]
     os: [linux]
     requiresBuild: true
@@ -938,8 +1508,11 @@ packages:
     optional: true
 
   /@esbuild/linux-x64@0.18.20:
-    resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [linux]
     requiresBuild: true
@@ -947,8 +1520,11 @@ packages:
     optional: true
 
   /@esbuild/netbsd-x64@0.18.20:
-    resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [netbsd]
     requiresBuild: true
@@ -956,8 +1532,11 @@ packages:
     optional: true
 
   /@esbuild/openbsd-x64@0.18.20:
-    resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [openbsd]
     requiresBuild: true
@@ -965,8 +1544,11 @@ packages:
     optional: true
 
   /@esbuild/sunos-x64@0.18.20:
-    resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [sunos]
     requiresBuild: true
@@ -974,8 +1556,11 @@ packages:
     optional: true
 
   /@esbuild/win32-arm64@0.18.20:
-    resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
+      }
+    engines: { node: ">=12" }
     cpu: [arm64]
     os: [win32]
     requiresBuild: true
@@ -983,8 +1568,11 @@ packages:
     optional: true
 
   /@esbuild/win32-ia32@0.18.20:
-    resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
+      }
+    engines: { node: ">=12" }
     cpu: [ia32]
     os: [win32]
     requiresBuild: true
@@ -992,8 +1580,11 @@ packages:
     optional: true
 
   /@esbuild/win32-x64@0.18.20:
-    resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
+      }
+    engines: { node: ">=12" }
     cpu: [x64]
     os: [win32]
     requiresBuild: true
@@ -1001,8 +1592,11 @@ packages:
     optional: true
 
   /@eslint-community/eslint-utils@4.4.0(eslint@8.51.0):
-    resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
     dependencies:
@@ -1011,13 +1605,19 @@ packages:
     dev: true
 
   /@eslint-community/regexpp@4.9.1:
-    resolution: {integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==}
-    engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==
+      }
+    engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 }
     dev: true
 
   /@eslint/eslintrc@2.1.2:
-    resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dependencies:
       ajv: 6.12.6
       debug: 4.3.4
@@ -1033,32 +1633,47 @@ packages:
     dev: true
 
   /@eslint/js@8.51.0:
-    resolution: {integrity: sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dev: true
 
   /@floating-ui/core@1.5.0:
-    resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==}
+    resolution:
+      {
+        integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==
+      }
     dependencies:
-      '@floating-ui/utils': 0.1.6
+      "@floating-ui/utils": 0.1.6
     dev: false
 
   /@floating-ui/dom@1.5.3:
-    resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==}
+    resolution:
+      {
+        integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==
+      }
     dependencies:
-      '@floating-ui/core': 1.5.0
-      '@floating-ui/utils': 0.1.6
+      "@floating-ui/core": 1.5.0
+      "@floating-ui/utils": 0.1.6
     dev: false
 
   /@floating-ui/utils@0.1.6:
-    resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==}
+    resolution:
+      {
+        integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==
+      }
     dev: false
 
   /@humanwhocodes/config-array@0.11.12:
-    resolution: {integrity: sha512-NlGesA1usRNn6ctHCZ21M4/dKPgW9Nn1FypRdIKKgZOKzkVV4T1FlK5mBiLhHBCDmEbdQG0idrcXlbZfksJ+RA==}
-    engines: {node: '>=10.10.0'}
+    resolution:
+      {
+        integrity: sha512-NlGesA1usRNn6ctHCZ21M4/dKPgW9Nn1FypRdIKKgZOKzkVV4T1FlK5mBiLhHBCDmEbdQG0idrcXlbZfksJ+RA==
+      }
+    engines: { node: ">=10.10.0" }
     dependencies:
-      '@humanwhocodes/object-schema': 2.0.0
+      "@humanwhocodes/object-schema": 2.0.0
       debug: 4.3.4
       minimatch: 3.1.2
     transitivePeerDependencies:
@@ -1066,54 +1681,81 @@ packages:
     dev: true
 
   /@humanwhocodes/module-importer@1.0.1:
-    resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
-    engines: {node: '>=12.22'}
+    resolution:
+      {
+        integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+      }
+    engines: { node: ">=12.22" }
     dev: true
 
   /@humanwhocodes/object-schema@2.0.0:
-    resolution: {integrity: sha512-9S9QrXY2K0L4AGDcSgTi9vgiCcG8VcBv4Mp7/1hDPYoswIy6Z6KO5blYto82BT8M0MZNRWmCFLpCs3HlpYGGdw==}
+    resolution:
+      {
+        integrity: sha512-9S9QrXY2K0L4AGDcSgTi9vgiCcG8VcBv4Mp7/1hDPYoswIy6Z6KO5blYto82BT8M0MZNRWmCFLpCs3HlpYGGdw==
+      }
     dev: true
 
   /@iconify-icons/ant-design@1.2.7:
-    resolution: {integrity: sha512-PEQPQMX0TiSGTyUqBv7c3f+bzQqDSpsEwSSh0XFjDd6SnVjE0AoZTl2NYEUADsbTgnPXAH9YM9AF4GdtkiyJ2Q==}
+    resolution:
+      {
+        integrity: sha512-PEQPQMX0TiSGTyUqBv7c3f+bzQqDSpsEwSSh0XFjDd6SnVjE0AoZTl2NYEUADsbTgnPXAH9YM9AF4GdtkiyJ2Q==
+      }
     dependencies:
-      '@iconify/types': 2.0.0
+      "@iconify/types": 2.0.0
     dev: true
 
   /@iconify-icons/ep@1.2.12:
-    resolution: {integrity: sha512-8EJULn048sQq3fvytpQ5j40omnVOdBKpo+sXdYM35NRrqCe1BihxBesMcCOLWaocqkWia6uTQ3cnRHff4ZA11w==}
+    resolution:
+      {
+        integrity: sha512-8EJULn048sQq3fvytpQ5j40omnVOdBKpo+sXdYM35NRrqCe1BihxBesMcCOLWaocqkWia6uTQ3cnRHff4ZA11w==
+      }
     dependencies:
-      '@iconify/types': 2.0.0
+      "@iconify/types": 2.0.0
     dev: true
 
   /@iconify-icons/icon-park-outline@1.2.11:
-    resolution: {integrity: sha512-YfdXTQJNqHsmtwrYCRHQu3TfyB7ybT27rZj668ZLjRxWBW3QEVDnvIGkNWgCiMYVOxlZJHOidke33MvfFmcNhw==}
+    resolution:
+      {
+        integrity: sha512-YfdXTQJNqHsmtwrYCRHQu3TfyB7ybT27rZj668ZLjRxWBW3QEVDnvIGkNWgCiMYVOxlZJHOidke33MvfFmcNhw==
+      }
     dependencies:
-      '@iconify/types': 2.0.0
+      "@iconify/types": 2.0.0
     dev: true
 
   /@iconify-icons/ri@1.2.10:
-    resolution: {integrity: sha512-wNaXsQYK55WDUWCbcjvnwnODV4Jtsp+VC0duPanibEVu876TUYf6kdgTGtH7/GErBCNdJuJJbncG7vbOaeQi7w==}
+    resolution:
+      {
+        integrity: sha512-wNaXsQYK55WDUWCbcjvnwnODV4Jtsp+VC0duPanibEVu876TUYf6kdgTGtH7/GErBCNdJuJJbncG7vbOaeQi7w==
+      }
     dependencies:
-      '@iconify/types': 2.0.0
+      "@iconify/types": 2.0.0
     dev: true
 
   /@iconify/types@2.0.0:
-    resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+    resolution:
+      {
+        integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==
+      }
     dev: true
 
   /@iconify/vue@4.1.1(vue@3.3.5):
-    resolution: {integrity: sha512-RL85Bm/DAe8y6rT6pux7D2FJSiUEM/TPfyK7GrbAOfTSwrhvwJW+S5yijdGcmtXouA8MtuH9C7l4hiSE4mLMjg==}
+    resolution:
+      {
+        integrity: sha512-RL85Bm/DAe8y6rT6pux7D2FJSiUEM/TPfyK7GrbAOfTSwrhvwJW+S5yijdGcmtXouA8MtuH9C7l4hiSE4mLMjg==
+      }
     peerDependencies:
-      vue: '>=3'
+      vue: ">=3"
     dependencies:
-      '@iconify/types': 2.0.0
+      "@iconify/types": 2.0.0
       vue: 3.3.5(typescript@5.0.4)
     dev: true
 
   /@isaacs/cliui@8.0.2:
-    resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
+      }
+    engines: { node: ">=12" }
     dependencies:
       string-width: 5.1.2
       string-width-cjs: /string-width@4.2.3
@@ -1124,68 +1766,101 @@ packages:
     dev: true
 
   /@jridgewell/gen-mapping@0.3.3:
-    resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==
+      }
+    engines: { node: ">=6.0.0" }
     dependencies:
-      '@jridgewell/set-array': 1.1.2
-      '@jridgewell/sourcemap-codec': 1.4.15
-      '@jridgewell/trace-mapping': 0.3.20
+      "@jridgewell/set-array": 1.1.2
+      "@jridgewell/sourcemap-codec": 1.4.15
+      "@jridgewell/trace-mapping": 0.3.20
 
   /@jridgewell/resolve-uri@3.1.1:
-    resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
+      }
+    engines: { node: ">=6.0.0" }
 
   /@jridgewell/set-array@1.1.2:
-    resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
+      }
+    engines: { node: ">=6.0.0" }
 
   /@jridgewell/source-map@0.3.5:
-    resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
+    resolution:
+      {
+        integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==
+      }
     dependencies:
-      '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.20
+      "@jridgewell/gen-mapping": 0.3.3
+      "@jridgewell/trace-mapping": 0.3.20
     dev: true
 
   /@jridgewell/sourcemap-codec@1.4.15:
-    resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+    resolution:
+      {
+        integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
+      }
 
   /@jridgewell/trace-mapping@0.3.20:
-    resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==}
+    resolution:
+      {
+        integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==
+      }
     dependencies:
-      '@jridgewell/resolve-uri': 3.1.1
-      '@jridgewell/sourcemap-codec': 1.4.15
+      "@jridgewell/resolve-uri": 3.1.1
+      "@jridgewell/sourcemap-codec": 1.4.15
 
   /@jridgewell/trace-mapping@0.3.9:
-    resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
+    resolution:
+      {
+        integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==
+      }
     dependencies:
-      '@jridgewell/resolve-uri': 3.1.1
-      '@jridgewell/sourcemap-codec': 1.4.15
+      "@jridgewell/resolve-uri": 3.1.1
+      "@jridgewell/sourcemap-codec": 1.4.15
     dev: true
 
   /@nodelib/fs.scandir@2.1.5:
-    resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
+      }
+    engines: { node: ">= 8" }
     dependencies:
-      '@nodelib/fs.stat': 2.0.5
+      "@nodelib/fs.stat": 2.0.5
       run-parallel: 1.2.0
 
   /@nodelib/fs.stat@2.0.5:
-    resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
+      }
+    engines: { node: ">= 8" }
 
   /@nodelib/fs.walk@1.2.8:
-    resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
+      }
+    engines: { node: ">= 8" }
     dependencies:
-      '@nodelib/fs.scandir': 2.1.5
+      "@nodelib/fs.scandir": 2.1.5
       fastq: 1.15.0
 
   /@nuxt/kit@3.8.0:
-    resolution: {integrity: sha512-oIthQxeMIVs4ESVP5FqLYn8tj0S1sLd+eYreh+dNYgnJ2pTi7+THR12ONBNHjk668jqEe7ErUJ8UlGwqBzgezg==}
-    engines: {node: ^14.18.0 || >=16.10.0}
+    resolution:
+      {
+        integrity: sha512-oIthQxeMIVs4ESVP5FqLYn8tj0S1sLd+eYreh+dNYgnJ2pTi7+THR12ONBNHjk668jqEe7ErUJ8UlGwqBzgezg==
+      }
+    engines: { node: ^14.18.0 || >=16.10.0 }
     requiresBuild: true
     dependencies:
-      '@nuxt/schema': 3.8.0
+      "@nuxt/schema": 3.8.0
       c12: 1.5.1
       consola: 3.2.3
       defu: 6.1.2
@@ -1210,11 +1885,14 @@ packages:
     optional: true
 
   /@nuxt/schema@3.8.0:
-    resolution: {integrity: sha512-VEDVeCjdVowhoY5vIBSz94+SSwmM204jN6TNe/ShBJ2d/vZiy9EtLbhOwqaPNFHwnN1fl/XFHThwJiexdB9D1w==}
-    engines: {node: ^14.18.0 || >=16.10.0}
+    resolution:
+      {
+        integrity: sha512-VEDVeCjdVowhoY5vIBSz94+SSwmM204jN6TNe/ShBJ2d/vZiy9EtLbhOwqaPNFHwnN1fl/XFHThwJiexdB9D1w==
+      }
+    engines: { node: ^14.18.0 || >=16.10.0 }
     requiresBuild: true
     dependencies:
-      '@nuxt/ui-templates': 1.3.1
+      "@nuxt/ui-templates": 1.3.1
       consola: 3.2.3
       defu: 6.1.2
       hookable: 5.5.3
@@ -1232,24 +1910,61 @@ packages:
     optional: true
 
   /@nuxt/ui-templates@1.3.1:
-    resolution: {integrity: sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA==}
+    resolution:
+      {
+        integrity: sha512-5gc02Pu1HycOVUWJ8aYsWeeXcSTPe8iX8+KIrhyEtEoOSkY0eMBuo0ssljB8wALuEmepv31DlYe5gpiRwkjESA==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /@pkgjs/parseargs@0.11.0:
-    resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
+      }
+    engines: { node: ">=14" }
     requiresBuild: true
     dev: true
     optional: true
 
+  /@probe.gl/env@3.6.0:
+    resolution:
+      {
+        integrity: sha512-4tTZYUg/8BICC3Yyb9rOeoKeijKbZHRXBEKObrfPmX4sQmYB15ZOUpoVBhAyJkOYVAM8EkPci6Uw5dLCwx2BEQ==
+      }
+    dependencies:
+      "@babel/runtime": 7.23.2
+    dev: false
+
+  /@probe.gl/log@3.6.0:
+    resolution:
+      {
+        integrity: sha512-hjpyenpEvOdowgZ1qMeCJxfRD4JkKdlXz0RC14m42Un62NtOT+GpWyKA4LssT0+xyLULCByRAtG2fzZorpIAcA==
+      }
+    dependencies:
+      "@babel/runtime": 7.23.2
+      "@probe.gl/env": 3.6.0
+    dev: false
+
+  /@probe.gl/stats@3.6.0:
+    resolution:
+      {
+        integrity: sha512-JdALQXB44OP4kUBN/UrQgzbJe4qokbVF4Y8lkIA8iVCFnjVowWIgkD/z/0QO65yELT54tTrtepw1jScjKB+rhQ==
+      }
+    dependencies:
+      "@babel/runtime": 7.23.2
+    dev: false
+
   /@pureadmin/descriptions@1.2.0(element-plus@2.3.6)(typescript@5.0.4):
-    resolution: {integrity: sha512-k2A3SGGKf0eKrSQB3hXzgGlAz7DKSM31WN/QGBn37UCIHfQlIVrvSPEAF2omHlukQT2Artap6veCqBcJ9dGAKQ==}
+    resolution:
+      {
+        integrity: sha512-k2A3SGGKf0eKrSQB3hXzgGlAz7DKSM31WN/QGBn37UCIHfQlIVrvSPEAF2omHlukQT2Artap6veCqBcJ9dGAKQ==
+      }
     peerDependencies:
       element-plus: ^2.0.0
     dependencies:
-      '@element-plus/icons-vue': 2.1.0(vue@3.3.5)
+      "@element-plus/icons-vue": 2.1.0(vue@3.3.5)
       element-plus: 2.3.6(@vue/composition-api@1.7.2)(vue@3.3.5)
       vue: 3.3.5(typescript@5.0.4)
     transitivePeerDependencies:
@@ -1257,7 +1972,10 @@ packages:
     dev: false
 
   /@pureadmin/table@2.3.4(element-plus@2.3.6)(typescript@5.0.4):
-    resolution: {integrity: sha512-Po8fsrxXCdiOlLyftjDuiBBK4rhu3EtXZr0cnHO3fS0K2d2VHj49wxE11bB5VG7xhAbfrIn+mh5h+IHOPiRE+A==}
+    resolution:
+      {
+        integrity: sha512-Po8fsrxXCdiOlLyftjDuiBBK4rhu3EtXZr0cnHO3fS0K2d2VHj49wxE11bB5VG7xhAbfrIn+mh5h+IHOPiRE+A==
+      }
     peerDependencies:
       element-plus: ^2.0.0
     dependencies:
@@ -1268,38 +1986,48 @@ packages:
     dev: false
 
   /@pureadmin/theme@3.1.0:
-    resolution: {integrity: sha512-3kBbqB6Uua096w91w1SrGna0dM8AYO5HFk/HU8G0DsEaijgRrm+dYIJUrqbv+stLUxlYPNVXpDS/APZjF0cOAg==}
+    resolution:
+      {
+        integrity: sha512-3kBbqB6Uua096w91w1SrGna0dM8AYO5HFk/HU8G0DsEaijgRrm+dYIJUrqbv+stLUxlYPNVXpDS/APZjF0cOAg==
+      }
     dependencies:
-      '@zougt/some-loader-utils': 1.4.3
+      "@zougt/some-loader-utils": 1.4.3
       fs-extra: 11.1.1
       string-hash: 1.1.3
     dev: true
 
-  /@pureadmin/utils@1.9.10(vue@3.3.5):
-    resolution: {integrity: sha512-hNg6u6nltvvO9U+QEKbDbXzky2kP3rP9sw2yvQc0fCObq73/mZ+PfKEr5HLmuze/1LYEUnz3koqpgfuyWBswVw==}
+  /@pureadmin/utils@1.9.10(echarts@5.5.0)(vue@3.3.5):
+    resolution:
+      {
+        integrity: sha512-hNg6u6nltvvO9U+QEKbDbXzky2kP3rP9sw2yvQc0fCObq73/mZ+PfKEr5HLmuze/1LYEUnz3koqpgfuyWBswVw==
+      }
     peerDependencies:
-      echarts: '*'
-      vue: '*'
+      echarts: "*"
+      vue: "*"
     peerDependenciesMeta:
       echarts:
         optional: true
       vue:
         optional: true
     dependencies:
+      echarts: 5.5.0
       vue: 3.3.5(typescript@5.0.4)
     dev: false
 
   /@rollup/plugin-node-resolve@13.3.0:
-    resolution: {integrity: sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==}
-    engines: {node: '>= 10.0.0'}
+    resolution:
+      {
+        integrity: sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==
+      }
+    engines: { node: ">= 10.0.0" }
     peerDependencies:
       rollup: ^2.42.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 3.1.0
-      '@types/resolve': 1.17.1
+      "@rollup/pluginutils": 3.1.0
+      "@types/resolve": 1.17.1
       deepmerge: 4.3.1
       is-builtin-module: 3.2.1
       is-module: 1.0.0
@@ -1307,30 +2035,39 @@ packages:
     dev: true
 
   /@rollup/pluginutils@3.1.0:
-    resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
-    engines: {node: '>= 8.0.0'}
+    resolution:
+      {
+        integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==
+      }
+    engines: { node: ">= 8.0.0" }
     peerDependencies:
       rollup: ^1.20.0||^2.0.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@types/estree': 0.0.39
+      "@types/estree": 0.0.39
       estree-walker: 1.0.1
       picomatch: 2.3.1
     dev: true
 
   /@rollup/pluginutils@4.2.1:
-    resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
-    engines: {node: '>= 8.0.0'}
+    resolution:
+      {
+        integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==
+      }
+    engines: { node: ">= 8.0.0" }
     dependencies:
       estree-walker: 2.0.2
       picomatch: 2.3.1
     dev: true
 
   /@rollup/pluginutils@5.0.5:
-    resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
-    engines: {node: '>=14.0.0'}
+    resolution:
+      {
+        integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==
+      }
+    engines: { node: ">=14.0.0" }
     requiresBuild: true
     peerDependencies:
       rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
@@ -1338,134 +2075,233 @@ packages:
       rollup:
         optional: true
     dependencies:
-      '@types/estree': 1.0.3
+      "@types/estree": 1.0.3
       estree-walker: 2.0.2
       picomatch: 2.3.1
     dev: false
     optional: true
 
   /@sxzz/popperjs-es@2.11.7:
-    resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
+    resolution:
+      {
+        integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==
+      }
+    dev: false
+
+  /@transloadit/prettier-bytes@0.0.7:
+    resolution:
+      {
+        integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==
+      }
     dev: false
 
   /@trysound/sax@0.2.0:
-    resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
-    engines: {node: '>=10.13.0'}
+    resolution:
+      {
+        integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
+      }
+    engines: { node: ">=10.13.0" }
     dev: true
 
   /@tsconfig/node10@1.0.9:
-    resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==}
+    resolution:
+      {
+        integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==
+      }
     dev: true
 
   /@tsconfig/node12@1.0.11:
-    resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
+    resolution:
+      {
+        integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==
+      }
     dev: true
 
   /@tsconfig/node14@1.0.3:
-    resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
+    resolution:
+      {
+        integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==
+      }
     dev: true
 
   /@tsconfig/node16@1.0.4:
-    resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
+    resolution:
+      {
+        integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==
+      }
     dev: true
 
+  /@types/d3-timer@2.0.3:
+    resolution:
+      {
+        integrity: sha512-jhAJzaanK5LqyLQ50jJNIrB8fjL9gwWZTgYjevPvkDLMU+kTAZkYsobI59nYoeSrH1PucuyJEi247Pb90t6XUg==
+      }
+    dev: false
+
   /@types/estree@0.0.39:
-    resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
+    resolution:
+      {
+        integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
+      }
     dev: true
 
   /@types/estree@1.0.3:
-    resolution: {integrity: sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==}
+    resolution:
+      {
+        integrity: sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ==
+      }
+
+  /@types/event-emitter@0.3.5:
+    resolution:
+      {
+        integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==
+      }
+    dev: false
 
   /@types/js-cookie@3.0.5:
-    resolution: {integrity: sha512-dtLshqoiGRDHbHueIT9sjkd2F4tW1qPSX2xKAQK8p1e6pM+Z913GM1shv7dOqqasEMYbC5zEaClJomQe8OtQLA==}
+    resolution:
+      {
+        integrity: sha512-dtLshqoiGRDHbHueIT9sjkd2F4tW1qPSX2xKAQK8p1e6pM+Z913GM1shv7dOqqasEMYbC5zEaClJomQe8OtQLA==
+      }
     dev: true
 
   /@types/json-schema@7.0.14:
-    resolution: {integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==}
+    resolution:
+      {
+        integrity: sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==
+      }
     dev: true
 
   /@types/lodash-es@4.17.10:
-    resolution: {integrity: sha512-YJP+w/2khSBwbUSFdGsSqmDvmnN3cCKoPOL7Zjle6s30ZtemkkqhjVfFqGwPN7ASil5VyjE2GtyU/yqYY6mC0A==}
+    resolution:
+      {
+        integrity: sha512-YJP+w/2khSBwbUSFdGsSqmDvmnN3cCKoPOL7Zjle6s30ZtemkkqhjVfFqGwPN7ASil5VyjE2GtyU/yqYY6mC0A==
+      }
     dependencies:
-      '@types/lodash': 4.14.200
+      "@types/lodash": 4.14.200
     dev: false
 
   /@types/lodash@4.14.200:
-    resolution: {integrity: sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==}
+    resolution:
+      {
+        integrity: sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==
+      }
     dev: false
 
   /@types/minimatch@3.0.5:
-    resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==}
+    resolution:
+      {
+        integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
+      }
     dev: true
 
   /@types/minimist@1.2.4:
-    resolution: {integrity: sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==}
+    resolution:
+      {
+        integrity: sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ==
+      }
     dev: true
 
   /@types/mockjs@1.0.9:
-    resolution: {integrity: sha512-WvvMpV85bREBPdzaRjHhQ2z8Ji4E6DHaQ8tIBHAqk5+ZYGKQdsEs25/ZXx46H1Z5wvXK33Y5z2A5wDlxn7vHXw==}
+    resolution:
+      {
+        integrity: sha512-WvvMpV85bREBPdzaRjHhQ2z8Ji4E6DHaQ8tIBHAqk5+ZYGKQdsEs25/ZXx46H1Z5wvXK33Y5z2A5wDlxn7vHXw==
+      }
     dev: true
 
   /@types/node@20.5.1:
-    resolution: {integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==}
+    resolution:
+      {
+        integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==
+      }
     dev: true
 
   /@types/node@20.8.7:
-    resolution: {integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==}
+    resolution:
+      {
+        integrity: sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==
+      }
     dependencies:
       undici-types: 5.25.3
     dev: true
 
   /@types/normalize-package-data@2.4.3:
-    resolution: {integrity: sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==}
+    resolution:
+      {
+        integrity: sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg==
+      }
     dev: true
 
   /@types/nprogress@0.2.0:
-    resolution: {integrity: sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==}
+    resolution:
+      {
+        integrity: sha512-1cYJrqq9GezNFPsWTZpFut/d4CjpZqA0vhqDUPFWYKF1oIyBz5qnoYMzR+0C/T96t3ebLAC1SSnwrVOm5/j74A==
+      }
     dev: true
 
   /@types/qs@6.9.9:
-    resolution: {integrity: sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==}
+    resolution:
+      {
+        integrity: sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg==
+      }
     dev: true
 
   /@types/resolve@1.17.1:
-    resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
+    resolution:
+      {
+        integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==
+      }
     dependencies:
-      '@types/node': 20.8.7
+      "@types/node": 20.8.7
     dev: true
 
   /@types/semver@7.5.4:
-    resolution: {integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==}
+    resolution:
+      {
+        integrity: sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==
+      }
     dev: true
 
   /@types/sortablejs@1.15.4:
-    resolution: {integrity: sha512-7oL7CcPSfoyoNx3Ba1+79ykJzpEKVhHUyfAiN5eT/FoeDXOR3eBDLXf9ndDNuxaExmjpI+zVi2dMMuaoXUOzNA==}
+    resolution:
+      {
+        integrity: sha512-7oL7CcPSfoyoNx3Ba1+79ykJzpEKVhHUyfAiN5eT/FoeDXOR3eBDLXf9ndDNuxaExmjpI+zVi2dMMuaoXUOzNA==
+      }
     dev: true
 
   /@types/web-bluetooth@0.0.16:
-    resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
+    resolution:
+      {
+        integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==
+      }
     dev: false
 
   /@types/web-bluetooth@0.0.18:
-    resolution: {integrity: sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw==}
+    resolution:
+      {
+        integrity: sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw==
+      }
     dev: false
 
   /@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     peerDependencies:
-      '@typescript-eslint/parser': ^5.0.0
+      "@typescript-eslint/parser": ^5.0.0
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-      typescript: '*'
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@eslint-community/regexpp': 4.9.1
-      '@typescript-eslint/parser': 5.62.0(eslint@8.51.0)(typescript@5.0.4)
-      '@typescript-eslint/scope-manager': 5.62.0
-      '@typescript-eslint/type-utils': 5.62.0(eslint@8.51.0)(typescript@5.0.4)
-      '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.0.4)
+      "@eslint-community/regexpp": 4.9.1
+      "@typescript-eslint/parser": 5.62.0(eslint@8.51.0)(typescript@5.0.4)
+      "@typescript-eslint/scope-manager": 5.62.0
+      "@typescript-eslint/type-utils": 5.62.0(eslint@8.51.0)(typescript@5.0.4)
+      "@typescript-eslint/utils": 5.62.0(eslint@8.51.0)(typescript@5.0.4)
       debug: 4.3.4
       eslint: 8.51.0
       graphemer: 1.4.0
@@ -1479,18 +2315,21 @@ packages:
     dev: true
 
   /@typescript-eslint/parser@5.62.0(eslint@8.51.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-      typescript: '*'
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/scope-manager': 5.62.0
-      '@typescript-eslint/types': 5.62.0
-      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4)
+      "@typescript-eslint/scope-manager": 5.62.0
+      "@typescript-eslint/types": 5.62.0
+      "@typescript-eslint/typescript-estree": 5.62.0(typescript@5.0.4)
       debug: 4.3.4
       eslint: 8.51.0
       typescript: 5.0.4
@@ -1499,25 +2338,31 @@ packages:
     dev: true
 
   /@typescript-eslint/scope-manager@5.62.0:
-    resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dependencies:
-      '@typescript-eslint/types': 5.62.0
-      '@typescript-eslint/visitor-keys': 5.62.0
+      "@typescript-eslint/types": 5.62.0
+      "@typescript-eslint/visitor-keys": 5.62.0
     dev: true
 
   /@typescript-eslint/type-utils@5.62.0(eslint@8.51.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
-    peerDependencies:
-      eslint: '*'
-      typescript: '*'
+    resolution:
+      {
+        integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
+    peerDependencies:
+      eslint: "*"
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4)
-      '@typescript-eslint/utils': 5.62.0(eslint@8.51.0)(typescript@5.0.4)
+      "@typescript-eslint/typescript-estree": 5.62.0(typescript@5.0.4)
+      "@typescript-eslint/utils": 5.62.0(eslint@8.51.0)(typescript@5.0.4)
       debug: 4.3.4
       eslint: 8.51.0
       tsutils: 3.21.0(typescript@5.0.4)
@@ -1527,21 +2372,27 @@ packages:
     dev: true
 
   /@typescript-eslint/types@5.62.0:
-    resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dev: true
 
   /@typescript-eslint/typescript-estree@5.62.0(typescript@5.0.4):
-    resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     peerDependencies:
-      typescript: '*'
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/types': 5.62.0
-      '@typescript-eslint/visitor-keys': 5.62.0
+      "@typescript-eslint/types": 5.62.0
+      "@typescript-eslint/visitor-keys": 5.62.0
       debug: 4.3.4
       globby: 11.1.0
       is-glob: 4.0.3
@@ -1553,17 +2404,20 @@ packages:
     dev: true
 
   /@typescript-eslint/utils@5.62.0(eslint@8.51.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
-      '@types/json-schema': 7.0.14
-      '@types/semver': 7.5.4
-      '@typescript-eslint/scope-manager': 5.62.0
-      '@typescript-eslint/types': 5.62.0
-      '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4)
+      "@eslint-community/eslint-utils": 4.4.0(eslint@8.51.0)
+      "@types/json-schema": 7.0.14
+      "@types/semver": 7.5.4
+      "@typescript-eslint/scope-manager": 5.62.0
+      "@typescript-eslint/types": 5.62.0
+      "@typescript-eslint/typescript-estree": 5.62.0(typescript@5.0.4)
       eslint: 8.51.0
       eslint-scope: 5.1.1
       semver: 7.5.4
@@ -1573,23 +2427,85 @@ packages:
     dev: true
 
   /@typescript-eslint/visitor-keys@5.62.0:
-    resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dependencies:
-      '@typescript-eslint/types': 5.62.0
+      "@typescript-eslint/types": 5.62.0
       eslint-visitor-keys: 3.4.3
     dev: true
 
+  /@uppy/companion-client@2.2.2:
+    resolution:
+      {
+        integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==
+      }
+    dependencies:
+      "@uppy/utils": 4.1.3
+      namespace-emitter: 2.0.1
+    dev: false
+
+  /@uppy/core@2.3.4:
+    resolution:
+      {
+        integrity: sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==
+      }
+    dependencies:
+      "@transloadit/prettier-bytes": 0.0.7
+      "@uppy/store-default": 2.1.1
+      "@uppy/utils": 4.1.3
+      lodash.throttle: 4.1.1
+      mime-match: 1.0.2
+      namespace-emitter: 2.0.1
+      nanoid: 3.3.6
+      preact: 10.19.2
+    dev: false
+
+  /@uppy/store-default@2.1.1:
+    resolution:
+      {
+        integrity: sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==
+      }
+    dev: false
+
+  /@uppy/utils@4.1.3:
+    resolution:
+      {
+        integrity: sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==
+      }
+    dependencies:
+      lodash.throttle: 4.1.1
+    dev: false
+
+  /@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4):
+    resolution:
+      {
+        integrity: sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==
+      }
+    peerDependencies:
+      "@uppy/core": ^2.3.3
+    dependencies:
+      "@uppy/companion-client": 2.2.2
+      "@uppy/core": 2.3.4
+      "@uppy/utils": 4.1.3
+      nanoid: 3.3.6
+    dev: false
+
   /@vitejs/plugin-vue-jsx@3.0.2(vite@4.5.0)(vue@3.3.5):
-    resolution: {integrity: sha512-obF26P2Z4Ogy3cPp07B4VaW6rpiu0ue4OT2Y15UxT5BZZ76haUY9guOsZV3uWh/I6xc+VeiW+ZVabRE82FyzWw==}
-    engines: {node: ^14.18.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-obF26P2Z4Ogy3cPp07B4VaW6rpiu0ue4OT2Y15UxT5BZZ76haUY9guOsZV3uWh/I6xc+VeiW+ZVabRE82FyzWw==
+      }
+    engines: { node: ^14.18.0 || >=16.0.0 }
     peerDependencies:
       vite: ^4.0.0
       vue: ^3.0.0
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.23.2)
-      '@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.23.2)
+      "@babel/core": 7.23.2
+      "@babel/plugin-transform-typescript": 7.22.15(@babel/core@7.23.2)
+      "@vue/babel-plugin-jsx": 1.1.5(@babel/core@7.23.2)
       vite: 4.5.0(@types/node@20.8.7)(sass@1.69.4)(terser@5.22.0)
       vue: 3.3.5(typescript@5.0.4)
     transitivePeerDependencies:
@@ -1597,8 +2513,11 @@ packages:
     dev: true
 
   /@vitejs/plugin-vue@4.4.0(vite@4.5.0)(vue@3.3.5):
-    resolution: {integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==}
-    engines: {node: ^14.18.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==
+      }
+    engines: { node: ^14.18.0 || >=16.0.0 }
     peerDependencies:
       vite: ^4.0.0
       vue: ^3.2.25
@@ -1608,39 +2527,54 @@ packages:
     dev: true
 
   /@volar/language-core@1.10.4:
-    resolution: {integrity: sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==}
+    resolution:
+      {
+        integrity: sha512-Na69qA6uwVIdA0rHuOc2W3pHtVQQO8hCNim7FOaKNpRJh0oAFnu5r9i7Oopo5C4cnELZkPNjTrbmpcCTiW+CMQ==
+      }
     dependencies:
-      '@volar/source-map': 1.10.4
+      "@volar/source-map": 1.10.4
     dev: true
 
   /@volar/source-map@1.10.4:
-    resolution: {integrity: sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==}
+    resolution:
+      {
+        integrity: sha512-RxZdUEL+pV8p+SMqnhVjzy5zpb1QRZTlcwSk4bdcBO7yOu4rtEWqDGahVCEj4CcXour+0yJUMrMczfSCpP9Uxg==
+      }
     dependencies:
       muggle-string: 0.3.1
     dev: true
 
   /@volar/typescript@1.10.4:
-    resolution: {integrity: sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==}
+    resolution:
+      {
+        integrity: sha512-BCCUEBASBEMCrz7qmNSi2hBEWYsXD0doaktRKpmmhvb6XntM2sAWYu6gbyK/MluLDgluGLFiFRpWgobgzUqolg==
+      }
     dependencies:
-      '@volar/language-core': 1.10.4
+      "@volar/language-core": 1.10.4
     dev: true
 
   /@vue/babel-helper-vue-transform-on@1.1.5:
-    resolution: {integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==}
+    resolution:
+      {
+        integrity: sha512-SgUymFpMoAyWeYWLAY+MkCK3QEROsiUnfaw5zxOVD/M64KQs8D/4oK6Q5omVA2hnvEOE0SCkH2TZxs/jnnUj7w==
+      }
     dev: true
 
   /@vue/babel-plugin-jsx@1.1.5(@babel/core@7.23.2):
-    resolution: {integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.23.2
-      '@babel/helper-module-imports': 7.22.15
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
-      '@babel/template': 7.22.15
-      '@babel/traverse': 7.23.2
-      '@babel/types': 7.23.0
-      '@vue/babel-helper-vue-transform-on': 1.1.5
+    resolution:
+      {
+        integrity: sha512-nKs1/Bg9U1n3qSWnsHhCVQtAzI6aQXqua8j/bZrau8ywT1ilXQbK4FwEJGmU8fV7tcpuFvWmmN7TMmV1OBma1g==
+      }
+    peerDependencies:
+      "@babel/core": ^7.0.0-0
+    dependencies:
+      "@babel/core": 7.23.2
+      "@babel/helper-module-imports": 7.22.15
+      "@babel/plugin-syntax-jsx": 7.22.5(@babel/core@7.23.2)
+      "@babel/template": 7.22.15
+      "@babel/traverse": 7.23.2
+      "@babel/types": 7.23.0
+      "@vue/babel-helper-vue-transform-on": 1.1.5
       camelcase: 6.3.0
       html-tags: 3.3.1
       svg-tags: 1.0.0
@@ -1649,56 +2583,77 @@ packages:
     dev: true
 
   /@vue/compiler-core@3.3.5:
-    resolution: {integrity: sha512-S8Ma+eICI40Y4UotR+iKR729Bma+wERn/xLc+Jz203s5WIW1Sx3qoiONqXGg3Q4vBMa+QHDncULya19ZSJuhog==}
+    resolution:
+      {
+        integrity: sha512-S8Ma+eICI40Y4UotR+iKR729Bma+wERn/xLc+Jz203s5WIW1Sx3qoiONqXGg3Q4vBMa+QHDncULya19ZSJuhog==
+      }
     dependencies:
-      '@babel/parser': 7.23.0
-      '@vue/shared': 3.3.5
+      "@babel/parser": 7.23.0
+      "@vue/shared": 3.3.5
       estree-walker: 2.0.2
       source-map-js: 1.0.2
 
   /@vue/compiler-dom@3.3.5:
-    resolution: {integrity: sha512-dxt6QntN9T/NtnV6Pz+/nmcoo3ULnsYCnRpvEyY73wbk1tzzx7dnwngUN1cXkyGNu9c3UE7llhq/5T54lKwyhQ==}
+    resolution:
+      {
+        integrity: sha512-dxt6QntN9T/NtnV6Pz+/nmcoo3ULnsYCnRpvEyY73wbk1tzzx7dnwngUN1cXkyGNu9c3UE7llhq/5T54lKwyhQ==
+      }
     dependencies:
-      '@vue/compiler-core': 3.3.5
-      '@vue/shared': 3.3.5
+      "@vue/compiler-core": 3.3.5
+      "@vue/shared": 3.3.5
 
   /@vue/compiler-sfc@3.3.5:
-    resolution: {integrity: sha512-M6ys4iReSbrF4NTcMCnJiBioCpzXjfkfXwkdziknRyps+pG0DkwpDfQT7zQ0q91/rCR/Ejz64b5H6C4HBhX41w==}
-    dependencies:
-      '@babel/parser': 7.23.0
-      '@vue/compiler-core': 3.3.5
-      '@vue/compiler-dom': 3.3.5
-      '@vue/compiler-ssr': 3.3.5
-      '@vue/reactivity-transform': 3.3.5
-      '@vue/shared': 3.3.5
+    resolution:
+      {
+        integrity: sha512-M6ys4iReSbrF4NTcMCnJiBioCpzXjfkfXwkdziknRyps+pG0DkwpDfQT7zQ0q91/rCR/Ejz64b5H6C4HBhX41w==
+      }
+    dependencies:
+      "@babel/parser": 7.23.0
+      "@vue/compiler-core": 3.3.5
+      "@vue/compiler-dom": 3.3.5
+      "@vue/compiler-ssr": 3.3.5
+      "@vue/reactivity-transform": 3.3.5
+      "@vue/shared": 3.3.5
       estree-walker: 2.0.2
       magic-string: 0.30.5
       postcss: 8.4.31
       source-map-js: 1.0.2
 
   /@vue/compiler-ssr@3.3.5:
-    resolution: {integrity: sha512-v7p2XuEpOcgjd6c49NqOnq3UTJOv5Uo9tirOyGnEadwxTov2O1J3/TUt4SgAAnwA+9gcUyH5c3lIOFsBe+UIyw==}
+    resolution:
+      {
+        integrity: sha512-v7p2XuEpOcgjd6c49NqOnq3UTJOv5Uo9tirOyGnEadwxTov2O1J3/TUt4SgAAnwA+9gcUyH5c3lIOFsBe+UIyw==
+      }
     dependencies:
-      '@vue/compiler-dom': 3.3.5
-      '@vue/shared': 3.3.5
+      "@vue/compiler-dom": 3.3.5
+      "@vue/shared": 3.3.5
 
   /@vue/composition-api@1.7.2(vue@3.3.5):
-    resolution: {integrity: sha512-M8jm9J/laYrYT02665HkZ5l2fWTK4dcVg3BsDHm/pfz+MjDYwX+9FUaZyGwEyXEDonQYRCo0H7aLgdklcIELjw==}
+    resolution:
+      {
+        integrity: sha512-M8jm9J/laYrYT02665HkZ5l2fWTK4dcVg3BsDHm/pfz+MjDYwX+9FUaZyGwEyXEDonQYRCo0H7aLgdklcIELjw==
+      }
     peerDependencies:
-      vue: '>= 2.5 < 2.7'
+      vue: ">= 2.5 < 2.7"
     dependencies:
       vue: 3.3.5(typescript@5.0.4)
     dev: false
 
   /@vue/devtools-api@6.5.1:
-    resolution: {integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==}
+    resolution:
+      {
+        integrity: sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==
+      }
     dev: false
 
   /@vue/eslint-config-prettier@7.1.0(eslint@8.51.0)(prettier@2.8.8):
-    resolution: {integrity: sha512-Pv/lVr0bAzSIHLd9iz0KnvAr4GKyCEl+h52bc4e5yWuDVtLgFwycF7nrbWTAQAS+FU6q1geVd07lc6EWfJiWKQ==}
+    resolution:
+      {
+        integrity: sha512-Pv/lVr0bAzSIHLd9iz0KnvAr4GKyCEl+h52bc4e5yWuDVtLgFwycF7nrbWTAQAS+FU6q1geVd07lc6EWfJiWKQ==
+      }
     peerDependencies:
-      eslint: '>= 7.28.0'
-      prettier: '>= 2.0.0'
+      eslint: ">= 7.28.0"
+      prettier: ">= 2.0.0"
     dependencies:
       eslint: 8.51.0
       eslint-config-prettier: 8.10.0(eslint@8.51.0)
@@ -1707,18 +2662,21 @@ packages:
     dev: true
 
   /@vue/eslint-config-typescript@11.0.3(eslint-plugin-vue@9.17.0)(eslint@8.51.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-dkt6W0PX6H/4Xuxg/BlFj5xHvksjpSlVjtkQCpaYJBIEuKj2hOVU7r+TIe+ysCwRYFz/lGqvklntRkCAibsbPw==}
-    engines: {node: ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-dkt6W0PX6H/4Xuxg/BlFj5xHvksjpSlVjtkQCpaYJBIEuKj2hOVU7r+TIe+ysCwRYFz/lGqvklntRkCAibsbPw==
+      }
+    engines: { node: ^14.17.0 || >=16.0.0 }
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
       eslint-plugin-vue: ^9.0.0
-      typescript: '*'
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.0.4)
-      '@typescript-eslint/parser': 5.62.0(eslint@8.51.0)(typescript@5.0.4)
+      "@typescript-eslint/eslint-plugin": 5.62.0(@typescript-eslint/parser@5.62.0)(eslint@8.51.0)(typescript@5.0.4)
+      "@typescript-eslint/parser": 5.62.0(eslint@8.51.0)(typescript@5.0.4)
       eslint: 8.51.0
       eslint-plugin-vue: 9.17.0(eslint@8.51.0)
       typescript: 5.0.4
@@ -1728,18 +2686,21 @@ packages:
     dev: true
 
   /@vue/language-core@1.8.19(typescript@5.0.4):
-    resolution: {integrity: sha512-nt3dodGs97UM6fnxeQBazO50yYCKBK53waFWB3qMbLmR6eL3aUryZgQtZoBe1pye17Wl8fs9HysV3si6xMgndQ==}
+    resolution:
+      {
+        integrity: sha512-nt3dodGs97UM6fnxeQBazO50yYCKBK53waFWB3qMbLmR6eL3aUryZgQtZoBe1pye17Wl8fs9HysV3si6xMgndQ==
+      }
     peerDependencies:
-      typescript: '*'
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@volar/language-core': 1.10.4
-      '@volar/source-map': 1.10.4
-      '@vue/compiler-dom': 3.3.5
-      '@vue/reactivity': 3.3.5
-      '@vue/shared': 3.3.5
+      "@volar/language-core": 1.10.4
+      "@volar/source-map": 1.10.4
+      "@vue/compiler-dom": 3.3.5
+      "@vue/reactivity": 3.3.5
+      "@vue/shared": 3.3.5
       minimatch: 9.0.3
       muggle-string: 0.3.1
       typescript: 5.0.4
@@ -1747,126 +2708,384 @@ packages:
     dev: true
 
   /@vue/reactivity-transform@3.3.5:
-    resolution: {integrity: sha512-OhpBD1H32pIapRzqy31hWwTFLf9STP+0uk5bVOQWXACTa2Rt/RPhvX4zixbPgMGo6iP+S+tFpZzUdcG8AASn8A==}
-    dependencies:
-      '@babel/parser': 7.23.0
-      '@vue/compiler-core': 3.3.5
-      '@vue/shared': 3.3.5
+    resolution:
+      {
+        integrity: sha512-OhpBD1H32pIapRzqy31hWwTFLf9STP+0uk5bVOQWXACTa2Rt/RPhvX4zixbPgMGo6iP+S+tFpZzUdcG8AASn8A==
+      }
+    dependencies:
+      "@babel/parser": 7.23.0
+      "@vue/compiler-core": 3.3.5
+      "@vue/shared": 3.3.5
       estree-walker: 2.0.2
       magic-string: 0.30.5
 
   /@vue/reactivity@3.3.5:
-    resolution: {integrity: sha512-P7OBfPjsbV5lDCwZQDtWFqPh3uAP3Q6bRqYVgsYr6ki7jiaiHGSLmeaevUi+Nkev8nhublUpApnWevNiACN3sw==}
+    resolution:
+      {
+        integrity: sha512-P7OBfPjsbV5lDCwZQDtWFqPh3uAP3Q6bRqYVgsYr6ki7jiaiHGSLmeaevUi+Nkev8nhublUpApnWevNiACN3sw==
+      }
     dependencies:
-      '@vue/shared': 3.3.5
+      "@vue/shared": 3.3.5
 
   /@vue/runtime-core@3.3.5:
-    resolution: {integrity: sha512-kxAW3fTzwzZQqiHV1SndTtLMlNfJ/bsvcYku6NDuPzTeG6sMOAIXvuz6N5NUox+P7sNCInESbSOrPMMvtWx3vA==}
+    resolution:
+      {
+        integrity: sha512-kxAW3fTzwzZQqiHV1SndTtLMlNfJ/bsvcYku6NDuPzTeG6sMOAIXvuz6N5NUox+P7sNCInESbSOrPMMvtWx3vA==
+      }
     dependencies:
-      '@vue/reactivity': 3.3.5
-      '@vue/shared': 3.3.5
+      "@vue/reactivity": 3.3.5
+      "@vue/shared": 3.3.5
 
   /@vue/runtime-dom@3.3.5:
-    resolution: {integrity: sha512-seYSeHmBNlTrR0eFyQFocEBtzljNlKzC2JfdebfBqoEmikyNYzLWTouv71DignLFXEXZKWNTqCIs4d7dk5Q3Ng==}
+    resolution:
+      {
+        integrity: sha512-seYSeHmBNlTrR0eFyQFocEBtzljNlKzC2JfdebfBqoEmikyNYzLWTouv71DignLFXEXZKWNTqCIs4d7dk5Q3Ng==
+      }
     dependencies:
-      '@vue/runtime-core': 3.3.5
-      '@vue/shared': 3.3.5
+      "@vue/runtime-core": 3.3.5
+      "@vue/shared": 3.3.5
       csstype: 3.1.2
 
   /@vue/server-renderer@3.3.5(vue@3.3.5):
-    resolution: {integrity: sha512-7VIZkohYn8GAnNT9chrm0vDpHJ6mWPL+TmUBKtDWcWxYcq33YJP/VHCPQN5TazkxXCtv3c1KfXAMZowX4giLoQ==}
+    resolution:
+      {
+        integrity: sha512-7VIZkohYn8GAnNT9chrm0vDpHJ6mWPL+TmUBKtDWcWxYcq33YJP/VHCPQN5TazkxXCtv3c1KfXAMZowX4giLoQ==
+      }
     peerDependencies:
       vue: 3.3.5
     dependencies:
-      '@vue/compiler-ssr': 3.3.5
-      '@vue/shared': 3.3.5
+      "@vue/compiler-ssr": 3.3.5
+      "@vue/shared": 3.3.5
       vue: 3.3.5(typescript@5.0.4)
 
   /@vue/shared@3.3.5:
-    resolution: {integrity: sha512-oNJN1rCtkqm1cIxU1BuZVEVRWIp4DhaxXucEzzZ/iDKHP71ZxhkBPNK+URySiECH6aiOZzC60PS2bd6JFznvNA==}
+    resolution:
+      {
+        integrity: sha512-oNJN1rCtkqm1cIxU1BuZVEVRWIp4DhaxXucEzzZ/iDKHP71ZxhkBPNK+URySiECH6aiOZzC60PS2bd6JFznvNA==
+      }
 
   /@vue/typescript@1.8.19(typescript@5.0.4):
-    resolution: {integrity: sha512-k/SHeeQROUgqsxyHQ8Cs3Zz5TnX57p7BcBDVYR2E0c61QL2DJ2G8CsaBremmNGuGE6o1R5D50IHIxFmroMz8iw==}
+    resolution:
+      {
+        integrity: sha512-k/SHeeQROUgqsxyHQ8Cs3Zz5TnX57p7BcBDVYR2E0c61QL2DJ2G8CsaBremmNGuGE6o1R5D50IHIxFmroMz8iw==
+      }
     dependencies:
-      '@volar/typescript': 1.10.4
-      '@vue/language-core': 1.8.19(typescript@5.0.4)
+      "@volar/typescript": 1.10.4
+      "@vue/language-core": 1.8.19(typescript@5.0.4)
     transitivePeerDependencies:
       - typescript
     dev: true
 
   /@vueuse/core@10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==}
-    dependencies:
-      '@types/web-bluetooth': 0.0.18
-      '@vueuse/metadata': 10.5.0
-      '@vueuse/shared': 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
+    resolution:
+      {
+        integrity: sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==
+      }
+    dependencies:
+      "@types/web-bluetooth": 0.0.18
+      "@vueuse/metadata": 10.5.0
+      "@vueuse/shared": 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
       vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.5)
     transitivePeerDependencies:
-      - '@vue/composition-api'
+      - "@vue/composition-api"
       - vue
     dev: false
 
   /@vueuse/core@9.13.0(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
-    dependencies:
-      '@types/web-bluetooth': 0.0.16
-      '@vueuse/metadata': 9.13.0
-      '@vueuse/shared': 9.13.0(@vue/composition-api@1.7.2)(vue@3.3.5)
+    resolution:
+      {
+        integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==
+      }
+    dependencies:
+      "@types/web-bluetooth": 0.0.16
+      "@vueuse/metadata": 9.13.0
+      "@vueuse/shared": 9.13.0(@vue/composition-api@1.7.2)(vue@3.3.5)
       vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.5)
     transitivePeerDependencies:
-      - '@vue/composition-api'
+      - "@vue/composition-api"
       - vue
     dev: false
 
   /@vueuse/metadata@10.5.0:
-    resolution: {integrity: sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw==}
+    resolution:
+      {
+        integrity: sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw==
+      }
     dev: false
 
   /@vueuse/metadata@9.13.0:
-    resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
+    resolution:
+      {
+        integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==
+      }
     dev: false
 
   /@vueuse/motion@2.0.0(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-V3TAlbt1OPmb9DZFoFCz9WC3Oue54t9VHlavSWm+VU1JNimYcd+pc6aGR/hgaHUAU9tOPRHoDTleSrv2zrdIsw==}
+    resolution:
+      {
+        integrity: sha512-V3TAlbt1OPmb9DZFoFCz9WC3Oue54t9VHlavSWm+VU1JNimYcd+pc6aGR/hgaHUAU9tOPRHoDTleSrv2zrdIsw==
+      }
     peerDependencies:
-      vue: '>=3.0.0'
+      vue: ">=3.0.0"
     dependencies:
-      '@vueuse/core': 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
-      '@vueuse/shared': 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
+      "@vueuse/core": 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
+      "@vueuse/shared": 10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5)
       csstype: 3.1.2
       framesync: 6.1.2
       popmotion: 11.0.5
       style-value-types: 5.1.2
       vue: 3.3.5(typescript@5.0.4)
     optionalDependencies:
-      '@nuxt/kit': 3.8.0
+      "@nuxt/kit": 3.8.0
     transitivePeerDependencies:
-      - '@vue/composition-api'
+      - "@vue/composition-api"
       - rollup
       - supports-color
     dev: false
 
   /@vueuse/shared@10.5.0(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==}
+    resolution:
+      {
+        integrity: sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==
+      }
     dependencies:
       vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.5)
     transitivePeerDependencies:
-      - '@vue/composition-api'
+      - "@vue/composition-api"
       - vue
     dev: false
 
   /@vueuse/shared@9.13.0(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
+    resolution:
+      {
+        integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==
+      }
     dependencies:
       vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.5)
     transitivePeerDependencies:
-      - '@vue/composition-api'
+      - "@vue/composition-api"
       - vue
     dev: false
 
+  /@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==
+      }
+    peerDependencies:
+      "@wangeditor/core": 1.x
+      dom7: ^3.0.0
+      lodash.throttle: ^4.1.1
+      nanoid: ^3.2.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      is-url: 1.2.4
+      lodash.throttle: 4.1.1
+      nanoid: 3.3.6
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==
+      }
+    peerDependencies:
+      "@wangeditor/core": 1.x
+      dom7: ^3.0.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      prismjs: 1.29.0
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==
+      }
+    peerDependencies:
+      "@uppy/core": ^2.1.1
+      "@uppy/xhr-upload": ^2.0.3
+      dom7: ^3.0.0
+      is-hotkey: ^0.2.0
+      lodash.camelcase: ^4.3.0
+      lodash.clonedeep: ^4.5.0
+      lodash.debounce: ^4.0.8
+      lodash.foreach: ^4.5.0
+      lodash.isequal: ^4.5.0
+      lodash.throttle: ^4.1.1
+      lodash.toarray: ^4.4.0
+      nanoid: ^3.2.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@types/event-emitter": 0.3.5
+      "@uppy/core": 2.3.4
+      "@uppy/xhr-upload": 2.1.3(@uppy/core@2.3.4)
+      dom7: 3.0.0
+      event-emitter: 0.3.5
+      html-void-elements: 2.0.1
+      i18next: 20.6.1
+      is-hotkey: 0.2.0
+      lodash.camelcase: 4.3.0
+      lodash.clonedeep: 4.5.0
+      lodash.debounce: 4.0.8
+      lodash.foreach: 4.5.0
+      lodash.isequal: 4.5.0
+      lodash.throttle: 4.1.1
+      lodash.toarray: 4.4.0
+      nanoid: 3.3.6
+      scroll-into-view-if-needed: 2.2.31
+      slate: 0.72.8
+      slate-history: 0.66.0(slate@0.72.8)
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/editor-for-vue@5.1.12(@wangeditor/editor@5.1.23)(vue@3.3.5):
+    resolution:
+      {
+        integrity: sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==
+      }
+    peerDependencies:
+      "@wangeditor/editor": ">=5.1.0"
+      vue: ^3.0.5
+    dependencies:
+      "@wangeditor/editor": 5.1.23
+      vue: 3.3.5(typescript@5.0.4)
+    dev: false
+
+  /@wangeditor/editor@5.1.23:
+    resolution:
+      {
+        integrity: sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==
+      }
+    dependencies:
+      "@uppy/core": 2.3.4
+      "@uppy/xhr-upload": 2.1.3(@uppy/core@2.3.4)
+      "@wangeditor/basic-modules": 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/code-highlight": 1.0.3(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/list-module": 1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/table-module": 1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/upload-image-module": 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/video-module": 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      is-hotkey: 0.2.0
+      lodash.camelcase: 4.3.0
+      lodash.clonedeep: 4.5.0
+      lodash.debounce: 4.0.8
+      lodash.foreach: 4.5.0
+      lodash.isequal: 4.5.0
+      lodash.throttle: 4.1.1
+      lodash.toarray: 4.4.0
+      nanoid: 3.3.6
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19)(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==
+      }
+    peerDependencies:
+      "@wangeditor/core": 1.x
+      dom7: ^3.0.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==
+      }
+    peerDependencies:
+      "@wangeditor/core": 1.x
+      dom7: ^3.0.0
+      lodash.isequal: ^4.5.0
+      lodash.throttle: ^4.1.1
+      nanoid: ^3.2.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      lodash.isequal: 4.5.0
+      lodash.throttle: 4.1.1
+      nanoid: 3.3.6
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/basic-modules@1.1.7)(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==
+      }
+    peerDependencies:
+      "@uppy/core": ^2.0.3
+      "@uppy/xhr-upload": ^2.0.3
+      "@wangeditor/basic-modules": 1.x
+      "@wangeditor/core": 1.x
+      dom7: ^3.0.0
+      lodash.foreach: ^4.5.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@uppy/core": 2.3.4
+      "@uppy/xhr-upload": 2.1.3(@uppy/core@2.3.4)
+      "@wangeditor/basic-modules": 1.1.7(@wangeditor/core@1.1.19)(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      lodash.foreach: 4.5.0
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
+  /@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(@wangeditor/core@1.1.19)(dom7@3.0.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1):
+    resolution:
+      {
+        integrity: sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==
+      }
+    peerDependencies:
+      "@uppy/core": ^2.1.4
+      "@uppy/xhr-upload": ^2.0.7
+      "@wangeditor/core": 1.x
+      dom7: ^3.0.0
+      nanoid: ^3.2.0
+      slate: ^0.72.0
+      snabbdom: ^3.1.0
+    dependencies:
+      "@uppy/core": 2.3.4
+      "@uppy/xhr-upload": 2.1.3(@uppy/core@2.3.4)
+      "@wangeditor/core": 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3)(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.6)(slate@0.72.8)(snabbdom@3.5.1)
+      dom7: 3.0.0
+      nanoid: 3.3.6
+      slate: 0.72.8
+      snabbdom: 3.5.1
+    dev: false
+
   /@zougt/some-loader-utils@1.4.3:
-    resolution: {integrity: sha512-0FsoqSTQ+qOyp6x5Q6LZQ7xVwquEgLYiIStG3L8p0Q2GsGGYKDkOZ0mIpMt67aNdr8XLsbxXjzTl/iHtTz5zcA==}
-    engines: {node: '>= 10.13.0'}
+    resolution:
+      {
+        integrity: sha512-0FsoqSTQ+qOyp6x5Q6LZQ7xVwquEgLYiIStG3L8p0Q2GsGGYKDkOZ0mIpMt67aNdr8XLsbxXjzTl/iHtTz5zcA==
+      }
+    engines: { node: ">= 10.13.0" }
     hasBin: true
     dependencies:
       cac: 6.7.14
@@ -1880,7 +3099,10 @@ packages:
     dev: true
 
   /JSONStream@1.3.5:
-    resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==}
+    resolution:
+      {
+        integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
+      }
     hasBin: true
     dependencies:
       jsonparse: 1.3.1
@@ -1888,7 +3110,10 @@ packages:
     dev: true
 
   /acorn-jsx@5.3.2(acorn@8.10.0):
-    resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+    resolution:
+      {
+        integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+      }
     peerDependencies:
       acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
@@ -1896,18 +3121,27 @@ packages:
     dev: true
 
   /acorn-walk@8.2.0:
-    resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
-    engines: {node: '>=0.4.0'}
+    resolution:
+      {
+        integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
+      }
+    engines: { node: ">=0.4.0" }
     dev: true
 
   /acorn@8.10.0:
-    resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
-    engines: {node: '>=0.4.0'}
+    resolution:
+      {
+        integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
+      }
+    engines: { node: ">=0.4.0" }
     hasBin: true
 
   /agent-base@7.1.0:
-    resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
-    engines: {node: '>= 14'}
+    resolution:
+      {
+        integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==
+      }
+    engines: { node: ">= 14" }
     requiresBuild: true
     dependencies:
       debug: 4.3.4
@@ -1917,7 +3151,10 @@ packages:
     optional: true
 
   /ajv@6.12.6:
-    resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+    resolution:
+      {
+        integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
+      }
     dependencies:
       fast-deep-equal: 3.1.3
       fast-json-stable-stringify: 2.1.0
@@ -1926,7 +3163,10 @@ packages:
     dev: true
 
   /ajv@8.12.0:
-    resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
+    resolution:
+      {
+        integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
+      }
     dependencies:
       fast-deep-equal: 3.1.3
       json-schema-traverse: 1.0.0
@@ -1935,107 +3175,170 @@ packages:
     dev: true
 
   /animate.css@4.1.1:
-    resolution: {integrity: sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==}
+    resolution:
+      {
+        integrity: sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ==
+      }
     dev: false
 
   /ansi-escapes@5.0.0:
-    resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==
+      }
+    engines: { node: ">=12" }
     dependencies:
       type-fest: 1.4.0
     dev: true
 
   /ansi-regex@5.0.1:
-    resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /ansi-regex@6.0.1:
-    resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /ansi-styles@3.2.1:
-    resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+      }
+    engines: { node: ">=4" }
     dependencies:
       color-convert: 1.9.3
 
   /ansi-styles@4.3.0:
-    resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+      }
+    engines: { node: ">=8" }
     dependencies:
       color-convert: 2.0.1
     dev: true
 
   /ansi-styles@6.2.1:
-    resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /any-promise@1.3.0:
-    resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+    resolution:
+      {
+        integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
+      }
     dev: true
 
   /anymatch@3.1.3:
-    resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
+      }
+    engines: { node: ">= 8" }
     dependencies:
       normalize-path: 3.0.0
       picomatch: 2.3.1
 
   /arg@4.1.3:
-    resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+    resolution:
+      {
+        integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
+      }
     dev: true
 
   /arg@5.0.2:
-    resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+    resolution:
+      {
+        integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
+      }
     dev: true
 
   /argparse@2.0.1:
-    resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+    resolution:
+      {
+        integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+      }
     dev: true
 
   /array-differ@3.0.0:
-    resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /array-ify@1.0.0:
-    resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
+    resolution:
+      {
+        integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==
+      }
     dev: true
 
   /array-union@2.1.0:
-    resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /arrify@1.0.1:
-    resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /arrify@2.0.1:
-    resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /astral-regex@2.0.0:
-    resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /async-validator@4.2.5:
-    resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+    resolution:
+      {
+        integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
+      }
     dev: false
 
   /asynckit@0.4.0:
-    resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+    resolution:
+      {
+        integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
+      }
     dev: false
 
   /autoprefixer@10.4.16(postcss@8.4.31):
-    resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==}
-    engines: {node: ^10 || ^12 || >=14}
+    resolution:
+      {
+        integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==
+      }
+    engines: { node: ^10 || ^12 || >=14 }
     hasBin: true
     peerDependencies:
       postcss: ^8.1.0
@@ -2050,7 +3353,10 @@ packages:
     dev: true
 
   /axios@1.5.1:
-    resolution: {integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==}
+    resolution:
+      {
+        integrity: sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==
+      }
     dependencies:
       follow-redirects: 1.15.3
       form-data: 4.0.0
@@ -2060,43 +3366,67 @@ packages:
     dev: false
 
   /balanced-match@1.0.2:
-    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+    resolution:
+      {
+        integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+      }
     dev: true
 
   /balanced-match@2.0.0:
-    resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
+    resolution:
+      {
+        integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
+      }
     dev: true
 
   /binary-extensions@2.2.0:
-    resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+      }
+    engines: { node: ">=8" }
 
   /boolbase@1.0.0:
-    resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+    resolution:
+      {
+        integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
+      }
     dev: true
 
   /brace-expansion@1.1.11:
-    resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+    resolution:
+      {
+        integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
+      }
     dependencies:
       balanced-match: 1.0.2
       concat-map: 0.0.1
     dev: true
 
   /brace-expansion@2.0.1:
-    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+    resolution:
+      {
+        integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
+      }
     dependencies:
       balanced-match: 1.0.2
     dev: true
 
   /braces@3.0.2:
-    resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+      }
+    engines: { node: ">=8" }
     dependencies:
       fill-range: 7.0.1
 
   /browserslist@4.22.1:
-    resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
-    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+    resolution:
+      {
+        integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==
+      }
+    engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 }
     hasBin: true
     dependencies:
       caniuse-lite: 1.0.30001551
@@ -2105,16 +3435,25 @@ packages:
       update-browserslist-db: 1.0.13(browserslist@4.22.1)
 
   /buffer-from@1.1.2:
-    resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
+    resolution:
+      {
+        integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+      }
     dev: true
 
   /builtin-modules@3.3.0:
-    resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /c12@1.5.1:
-    resolution: {integrity: sha512-BWZRJgDEveT8uI+cliCwvYSSSSvb4xKoiiu5S0jaDbKBopQLQF7E+bq9xKk1pTcG+mUa3yXuFO7bD9d8Lr9Xxg==}
+    resolution:
+      {
+        integrity: sha512-BWZRJgDEveT8uI+cliCwvYSSSSvb4xKoiiu5S0jaDbKBopQLQF7E+bq9xKk1pTcG+mUa3yXuFO7bD9d8Lr9Xxg==
+      }
     requiresBuild: true
     dependencies:
       chokidar: 3.5.3
@@ -2134,12 +3473,18 @@ packages:
     optional: true
 
   /cac@6.7.14:
-    resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /call-bind@1.0.5:
-    resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==}
+    resolution:
+      {
+        integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==
+      }
     dependencies:
       function-bind: 1.1.2
       get-intrinsic: 1.2.1
@@ -2147,18 +3492,27 @@ packages:
     dev: false
 
   /callsites@3.1.0:
-    resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /camelcase-css@2.0.1:
-    resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
+      }
+    engines: { node: ">= 6" }
     dev: true
 
   /camelcase-keys@6.2.2:
-    resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==
+      }
+    engines: { node: ">=8" }
     dependencies:
       camelcase: 5.3.1
       map-obj: 4.3.0
@@ -2166,8 +3520,11 @@ packages:
     dev: true
 
   /camelcase-keys@7.0.2:
-    resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==
+      }
+    engines: { node: ">=12" }
     dependencies:
       camelcase: 6.3.0
       map-obj: 4.3.0
@@ -2176,17 +3533,26 @@ packages:
     dev: true
 
   /camelcase@5.3.1:
-    resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /camelcase@6.3.0:
-    resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /caniuse-api@3.0.0:
-    resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
+    resolution:
+      {
+        integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==
+      }
     dependencies:
       browserslist: 4.22.1
       caniuse-lite: 1.0.30001551
@@ -2195,40 +3561,58 @@ packages:
     dev: true
 
   /caniuse-lite@1.0.30001551:
-    resolution: {integrity: sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==}
+    resolution:
+      {
+        integrity: sha512-vtBAez47BoGMMzlbYhfXrMV1kvRF2WP/lqiMuDu1Sb4EE4LKEgjopFDSRtZfdVnslNRpOqV/woE+Xgrwj6VQlg==
+      }
 
   /chalk@2.4.2:
-    resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+      }
+    engines: { node: ">=4" }
     dependencies:
       ansi-styles: 3.2.1
       escape-string-regexp: 1.0.5
       supports-color: 5.5.0
 
   /chalk@3.0.0:
-    resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
+      }
+    engines: { node: ">=8" }
     dependencies:
       ansi-styles: 4.3.0
       supports-color: 7.2.0
     dev: true
 
   /chalk@4.1.2:
-    resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
+      }
+    engines: { node: ">=10" }
     dependencies:
       ansi-styles: 4.3.0
       supports-color: 7.2.0
     dev: true
 
   /chalk@5.3.0:
-    resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
-    engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==
+      }
+    engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 }
     dev: true
 
   /chokidar@3.5.3:
-    resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
-    engines: {node: '>= 8.10.0'}
+    resolution:
+      {
+        integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+      }
+    engines: { node: ">= 8.10.0" }
     dependencies:
       anymatch: 3.1.3
       braces: 3.0.2
@@ -2241,30 +3625,42 @@ packages:
       fsevents: 2.3.3
 
   /chownr@2.0.0:
-    resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
+      }
+    engines: { node: ">=10" }
     requiresBuild: true
     dev: false
     optional: true
 
   /cli-cursor@4.0.0:
-    resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dependencies:
       restore-cursor: 4.0.0
     dev: true
 
   /cli-truncate@3.1.0:
-    resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dependencies:
       slice-ansi: 5.0.0
       string-width: 5.1.2
     dev: true
 
   /cliui@8.0.1:
-    resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       string-width: 4.2.3
       strip-ansi: 6.0.1
@@ -2272,95 +3668,165 @@ packages:
     dev: true
 
   /cloc@2.11.0:
-    resolution: {integrity: sha512-+mxuCHo7ESOQadlsyMjmPZ4hGBtvQzmNGHfLdBNvXKbnRhtmOTslU4XF2cyFSaOCHaaF26ba2CGjU6lpeIFB0w==}
+    resolution:
+      {
+        integrity: sha512-+mxuCHo7ESOQadlsyMjmPZ4hGBtvQzmNGHfLdBNvXKbnRhtmOTslU4XF2cyFSaOCHaaF26ba2CGjU6lpeIFB0w==
+      }
     hasBin: true
     dev: true
 
   /color-convert@1.9.3:
-    resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+    resolution:
+      {
+        integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+      }
     dependencies:
       color-name: 1.1.3
 
   /color-convert@2.0.1:
-    resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
-    engines: {node: '>=7.0.0'}
+    resolution:
+      {
+        integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+      }
+    engines: { node: ">=7.0.0" }
     dependencies:
       color-name: 1.1.4
     dev: true
 
   /color-name@1.1.3:
-    resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+    resolution:
+      {
+        integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
+      }
 
   /color-name@1.1.4:
-    resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-    dev: true
+    resolution:
+      {
+        integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+      }
 
   /color-string@1.9.1:
-    resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+    resolution:
+      {
+        integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==
+      }
     dependencies:
       color-name: 1.1.4
       simple-swizzle: 0.2.2
-    dev: true
+
+  /color@3.2.1:
+    resolution:
+      {
+        integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==
+      }
+    dependencies:
+      color-convert: 1.9.3
+      color-string: 1.9.1
+    dev: false
 
   /color@4.2.3:
-    resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
-    engines: {node: '>=12.5.0'}
+    resolution:
+      {
+        integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==
+      }
+    engines: { node: ">=12.5.0" }
     dependencies:
       color-convert: 2.0.1
       color-string: 1.9.1
     dev: true
 
   /colord@2.9.3:
-    resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
+    resolution:
+      {
+        integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
+      }
     dev: true
 
   /colorette@2.0.20:
-    resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
+    resolution:
+      {
+        integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
+      }
 
   /combined-stream@1.0.8:
-    resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
-    engines: {node: '>= 0.8'}
+    resolution:
+      {
+        integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
+      }
+    engines: { node: ">= 0.8" }
     dependencies:
       delayed-stream: 1.0.0
     dev: false
 
   /commander@11.0.0:
-    resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==}
-    engines: {node: '>=16'}
+    resolution:
+      {
+        integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==
+      }
+    engines: { node: ">=16" }
     dev: true
 
   /commander@11.1.0:
-    resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
-    engines: {node: '>=16'}
+    resolution:
+      {
+        integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==
+      }
+    engines: { node: ">=16" }
+    dev: true
 
   /commander@2.20.3:
-    resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
+    resolution:
+      {
+        integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+      }
     dev: true
 
   /commander@4.1.1:
-    resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
+      }
+    engines: { node: ">= 6" }
     dev: true
 
   /commander@7.2.0:
-    resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
-    engines: {node: '>= 10'}
+    resolution:
+      {
+        integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
+      }
+    engines: { node: ">= 10" }
     dev: true
 
   /compare-func@2.0.0:
-    resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==}
+    resolution:
+      {
+        integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==
+      }
     dependencies:
       array-ify: 1.0.0
       dot-prop: 5.3.0
     dev: true
 
+  /compute-scroll-into-view@1.0.20:
+    resolution:
+      {
+        integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==
+      }
+    dev: false
+
   /concat-map@0.0.1:
-    resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+    resolution:
+      {
+        integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+      }
     dev: true
 
   /connect@3.7.0:
-    resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==}
-    engines: {node: '>= 0.10.0'}
+    resolution:
+      {
+        integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==
+      }
+    engines: { node: ">= 0.10.0" }
     dependencies:
       debug: 2.6.9
       finalhandler: 1.1.2
@@ -2371,29 +3837,41 @@ packages:
     dev: true
 
   /consola@3.2.3:
-    resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
-    engines: {node: ^14.18.0 || >=16.10.0}
+    resolution:
+      {
+        integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==
+      }
+    engines: { node: ^14.18.0 || >=16.10.0 }
     requiresBuild: true
     dev: false
     optional: true
 
   /conventional-changelog-angular@6.0.0:
-    resolution: {integrity: sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==
+      }
+    engines: { node: ">=14" }
     dependencies:
       compare-func: 2.0.0
     dev: true
 
   /conventional-changelog-conventionalcommits@6.1.0:
-    resolution: {integrity: sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==
+      }
+    engines: { node: ">=14" }
     dependencies:
       compare-func: 2.0.0
     dev: true
 
   /conventional-commits-parser@4.0.0:
-    resolution: {integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==
+      }
+    engines: { node: ">=14" }
     hasBin: true
     dependencies:
       JSONStream: 1.3.5
@@ -2403,34 +3881,54 @@ packages:
     dev: true
 
   /convert-source-map@2.0.0:
-    resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+    resolution:
+      {
+        integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
+      }
+
+  /core-js-pure@3.33.3:
+    resolution:
+      {
+        integrity: sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ==
+      }
+    requiresBuild: true
+    dev: false
 
   /core-util-is@1.0.3:
-    resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
+    resolution:
+      {
+        integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6)(ts-node@10.9.1)(typescript@5.0.4):
-    resolution: {integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==}
-    engines: {node: '>=v14.21.3'}
-    peerDependencies:
-      '@types/node': '*'
-      cosmiconfig: '>=7'
-      ts-node: '>=10'
-      typescript: '>=4'
-    dependencies:
-      '@types/node': 20.5.1
+    resolution:
+      {
+        integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==
+      }
+    engines: { node: ">=v14.21.3" }
+    peerDependencies:
+      "@types/node": "*"
+      cosmiconfig: ">=7"
+      ts-node: ">=10"
+      typescript: ">=4"
+    dependencies:
+      "@types/node": 20.5.1
       cosmiconfig: 8.3.6(typescript@5.0.4)
       ts-node: 10.9.1(@types/node@20.8.7)(typescript@5.0.4)
       typescript: 5.0.4
     dev: true
 
   /cosmiconfig@8.3.6(typescript@5.0.4):
-    resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==
+      }
+    engines: { node: ">=14" }
     peerDependencies:
-      typescript: '>=4.9.5'
+      typescript: ">=4.9.5"
     peerDependenciesMeta:
       typescript:
         optional: true
@@ -2443,12 +3941,18 @@ packages:
     dev: true
 
   /create-require@1.1.1:
-    resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
+    resolution:
+      {
+        integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
+      }
     dev: true
 
   /cross-spawn@7.0.3:
-    resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
+      }
+    engines: { node: ">= 8" }
     dependencies:
       path-key: 3.1.1
       shebang-command: 2.0.0
@@ -2456,8 +3960,11 @@ packages:
     dev: true
 
   /css-declaration-sorter@6.4.1(postcss@8.4.31):
-    resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==}
-    engines: {node: ^10 || ^12 || >=14}
+    resolution:
+      {
+        integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==
+      }
+    engines: { node: ^10 || ^12 || >=14 }
     peerDependencies:
       postcss: ^8.0.9
     dependencies:
@@ -2465,12 +3972,18 @@ packages:
     dev: true
 
   /css-functions-list@3.2.1:
-    resolution: {integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==}
-    engines: {node: '>=12 || >=16'}
+    resolution:
+      {
+        integrity: sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==
+      }
+    engines: { node: ">=12 || >=16" }
     dev: true
 
   /css-select@4.3.0:
-    resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==}
+    resolution:
+      {
+        integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
+      }
     dependencies:
       boolbase: 1.0.0
       css-what: 6.1.0
@@ -2480,7 +3993,10 @@ packages:
     dev: true
 
   /css-select@5.1.0:
-    resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==}
+    resolution:
+      {
+        integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
+      }
     dependencies:
       boolbase: 1.0.0
       css-what: 6.1.0
@@ -2490,43 +4006,61 @@ packages:
     dev: true
 
   /css-tree@1.1.3:
-    resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==}
-    engines: {node: '>=8.0.0'}
+    resolution:
+      {
+        integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
+      }
+    engines: { node: ">=8.0.0" }
     dependencies:
       mdn-data: 2.0.14
       source-map: 0.6.1
     dev: true
 
   /css-tree@2.2.1:
-    resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
-    engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+    resolution:
+      {
+        integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==
+      }
+    engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: ">=7.0.0" }
     dependencies:
       mdn-data: 2.0.28
       source-map-js: 1.0.2
     dev: true
 
   /css-tree@2.3.1:
-    resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
-    engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+    resolution:
+      {
+        integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==
+      }
+    engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0 }
     dependencies:
       mdn-data: 2.0.30
       source-map-js: 1.0.2
     dev: true
 
   /css-what@6.1.0:
-    resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
+      }
+    engines: { node: ">= 6" }
     dev: true
 
   /cssesc@3.0.0:
-    resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+      }
+    engines: { node: ">=4" }
     hasBin: true
     dev: true
 
   /cssnano-preset-default@5.2.14(postcss@8.4.31):
-    resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2563,8 +4097,11 @@ packages:
     dev: true
 
   /cssnano-preset-default@6.0.1(postcss@8.4.31):
-    resolution: {integrity: sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2601,8 +4138,11 @@ packages:
     dev: true
 
   /cssnano-preset-lite@2.1.3(postcss@8.4.31):
-    resolution: {integrity: sha512-samvnCll/DUVZu0Qc+JH36nt7dlaOT7WjOgg8SbLJ78sp51JZ12s2hyerxrarjPBG4O53rErUtOY2IYLYgBGEQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-samvnCll/DUVZu0Qc+JH36nt7dlaOT7WjOgg8SbLJ78sp51JZ12s2hyerxrarjPBG4O53rErUtOY2IYLYgBGEQ==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2614,8 +4154,11 @@ packages:
     dev: true
 
   /cssnano-utils@3.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2623,8 +4166,11 @@ packages:
     dev: true
 
   /cssnano-utils@4.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2632,8 +4178,11 @@ packages:
     dev: true
 
   /cssnano@5.1.15(postcss@8.4.31):
-    resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2644,8 +4193,11 @@ packages:
     dev: true
 
   /cssnano@6.0.1(postcss@8.4.31):
-    resolution: {integrity: sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -2655,39 +4207,156 @@ packages:
     dev: true
 
   /csso@4.2.0:
-    resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==}
-    engines: {node: '>=8.0.0'}
+    resolution:
+      {
+        integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
+      }
+    engines: { node: ">=8.0.0" }
     dependencies:
       css-tree: 1.1.3
     dev: true
 
   /csso@5.0.5:
-    resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
-    engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+    resolution:
+      {
+        integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==
+      }
+    engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: ">=7.0.0" }
     dependencies:
       css-tree: 2.2.1
     dev: true
 
   /csstype@3.1.2:
-    resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+    resolution:
+      {
+        integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
+      }
+
+  /d3-color@3.1.0:
+    resolution:
+      {
+        integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
+      }
+    engines: { node: ">=12" }
+    dev: false
+
+  /d3-dispatch@2.0.0:
+    resolution:
+      {
+        integrity: sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==
+      }
+    dev: false
+
+  /d3-ease@1.0.7:
+    resolution:
+      {
+        integrity: sha512-lx14ZPYkhNx0s/2HX5sLFUI3mbasHjSSpwO/KaaNACweVwxUruKyWVcb293wMv1RqTPZyZ8kSZ2NogUZNcLOFQ==
+      }
+    dev: false
+
+  /d3-force@2.1.1:
+    resolution:
+      {
+        integrity: sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==
+      }
+    dependencies:
+      d3-dispatch: 2.0.0
+      d3-quadtree: 2.0.0
+      d3-timer: 2.0.0
+    dev: false
+
+  /d3-interpolate@3.0.1:
+    resolution:
+      {
+        integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
+      }
+    engines: { node: ">=12" }
+    dependencies:
+      d3-color: 3.1.0
+    dev: false
+
+  /d3-quadtree@2.0.0:
+    resolution:
+      {
+        integrity: sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==
+      }
+    dev: false
+
+  /d3-timer@1.0.10:
+    resolution:
+      {
+        integrity: sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw==
+      }
+    dev: false
+
+  /d3-timer@2.0.0:
+    resolution:
+      {
+        integrity: sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==
+      }
+    dev: false
+
+  /d@1.0.1:
+    resolution:
+      {
+        integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
+      }
+    dependencies:
+      es5-ext: 0.10.62
+      type: 1.2.0
+    dev: false
+
+  /dagre-compound@0.0.11(dagre@0.8.5):
+    resolution:
+      {
+        integrity: sha512-UrSgRP9LtOZCYb9e5doolZXpc7xayyszgyOs7uakTK4n4KsLegLVTRRtq01GpQd/iZjYw5fWMapx9ed+c80MAQ==
+      }
+    engines: { node: ">=6.0.0" }
+    peerDependencies:
+      dagre: ^0.8.5
+    dependencies:
+      dagre: 0.8.5
+    dev: false
+
+  /dagre@0.8.5:
+    resolution:
+      {
+        integrity: sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
+      }
+    dependencies:
+      graphlib: 2.1.8
+      lodash: 4.17.21
+    dev: false
 
   /dargs@7.0.0:
-    resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /dayjs@1.11.10:
-    resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
+    resolution:
+      {
+        integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
+      }
     dev: false
 
   /de-indent@1.0.2:
-    resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
+    resolution:
+      {
+        integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==
+      }
     dev: true
 
   /debug@2.6.9:
-    resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
+    resolution:
+      {
+        integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
+      }
     peerDependencies:
-      supports-color: '*'
+      supports-color: "*"
     peerDependenciesMeta:
       supports-color:
         optional: true
@@ -2696,10 +4365,13 @@ packages:
     dev: true
 
   /debug@4.3.4:
-    resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
-    engines: {node: '>=6.0'}
+    resolution:
+      {
+        integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
+      }
+    engines: { node: ">=6.0" }
     peerDependencies:
-      supports-color: '*'
+      supports-color: "*"
     peerDependenciesMeta:
       supports-color:
         optional: true
@@ -2707,35 +4379,53 @@ packages:
       ms: 2.1.2
 
   /decamelize-keys@1.1.1:
-    resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==
+      }
+    engines: { node: ">=0.10.0" }
     dependencies:
       decamelize: 1.2.0
       map-obj: 1.0.1
     dev: true
 
   /decamelize@1.2.0:
-    resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /decamelize@5.0.1:
-    resolution: {integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /deep-is@0.1.4:
-    resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+    resolution:
+      {
+        integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
+      }
     dev: true
 
   /deepmerge@4.3.1:
-    resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /define-data-property@1.1.1:
-    resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==}
-    engines: {node: '>= 0.4'}
+    resolution:
+      {
+        integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==
+      }
+    engines: { node: ">= 0.4" }
     dependencies:
       get-intrinsic: 1.2.1
       gopd: 1.0.1
@@ -2743,55 +4433,92 @@ packages:
     dev: false
 
   /define-lazy-prop@2.0.0:
-    resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /defu@6.1.2:
-    resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==}
+    resolution:
+      {
+        integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /delayed-stream@1.0.0:
-    resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
-    engines: {node: '>=0.4.0'}
+    resolution:
+      {
+        integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
+      }
+    engines: { node: ">=0.4.0" }
     dev: false
 
   /destr@2.0.1:
-    resolution: {integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==}
+    resolution:
+      {
+        integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
+  /detect-browser@5.3.0:
+    resolution:
+      {
+        integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==
+      }
+    dev: false
+
   /didyoumean@1.2.2:
-    resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+    resolution:
+      {
+        integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
+      }
     dev: true
 
   /diff@4.0.2:
-    resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
-    engines: {node: '>=0.3.1'}
+    resolution:
+      {
+        integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
+      }
+    engines: { node: ">=0.3.1" }
     dev: true
 
   /dir-glob@3.0.1:
-    resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
+      }
+    engines: { node: ">=8" }
     dependencies:
       path-type: 4.0.0
 
   /dlv@1.1.3:
-    resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+    resolution:
+      {
+        integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
+      }
     dev: true
 
   /doctrine@3.0.0:
-    resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==
+      }
+    engines: { node: ">=6.0.0" }
     dependencies:
       esutils: 2.0.3
     dev: true
 
   /dom-serializer@1.4.1:
-    resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
+    resolution:
+      {
+        integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
+      }
     dependencies:
       domelementtype: 2.3.0
       domhandler: 4.3.1
@@ -2799,33 +4526,57 @@ packages:
     dev: true
 
   /dom-serializer@2.0.0:
-    resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+    resolution:
+      {
+        integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
+      }
     dependencies:
       domelementtype: 2.3.0
       domhandler: 5.0.3
       entities: 4.5.0
     dev: true
 
+  /dom7@3.0.0:
+    resolution:
+      {
+        integrity: sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==
+      }
+    dependencies:
+      ssr-window: 3.0.0
+    dev: false
+
   /domelementtype@2.3.0:
-    resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+    resolution:
+      {
+        integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
+      }
     dev: true
 
   /domhandler@4.3.1:
-    resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==}
-    engines: {node: '>= 4'}
+    resolution:
+      {
+        integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
+      }
+    engines: { node: ">= 4" }
     dependencies:
       domelementtype: 2.3.0
     dev: true
 
   /domhandler@5.0.3:
-    resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
-    engines: {node: '>= 4'}
+    resolution:
+      {
+        integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
+      }
+    engines: { node: ">= 4" }
     dependencies:
       domelementtype: 2.3.0
     dev: true
 
   /domutils@2.8.0:
-    resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==}
+    resolution:
+      {
+        integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
+      }
     dependencies:
       dom-serializer: 1.4.1
       domelementtype: 2.3.0
@@ -2833,7 +4584,10 @@ packages:
     dev: true
 
   /domutils@3.1.0:
-    resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==}
+    resolution:
+      {
+        integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==
+      }
     dependencies:
       dom-serializer: 2.0.0
       domelementtype: 2.3.0
@@ -2841,42 +4595,70 @@ packages:
     dev: true
 
   /dot-prop@5.3.0:
-    resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
+      }
+    engines: { node: ">=8" }
     dependencies:
       is-obj: 2.0.0
     dev: true
 
   /dotenv@16.3.1:
-    resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
+      }
+    engines: { node: ">=12" }
     requiresBuild: true
     dev: false
     optional: true
 
   /eastasianwidth@0.2.0:
-    resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+    resolution:
+      {
+        integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
+      }
     dev: true
 
+  /echarts@5.5.0:
+    resolution:
+      {
+        integrity: sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==
+      }
+    dependencies:
+      tslib: 2.3.0
+      zrender: 5.5.0
+    dev: false
+
   /ee-first@1.1.1:
-    resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+    resolution:
+      {
+        integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
+      }
     dev: true
 
   /electron-to-chromium@1.4.561:
-    resolution: {integrity: sha512-eS5t4ulWOBfVHdq9SW2dxEaFarj1lPjvJ8PaYMOjY0DecBaj/t4ARziL2IPpDr4atyWwjLFGQ2vo/VCgQFezVQ==}
+    resolution:
+      {
+        integrity: sha512-eS5t4ulWOBfVHdq9SW2dxEaFarj1lPjvJ8PaYMOjY0DecBaj/t4ARziL2IPpDr4atyWwjLFGQ2vo/VCgQFezVQ==
+      }
 
   /element-plus@2.3.6(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-GLz0pXUYI2zRfIgyI6W7SWmHk6dSEikP9yR++hsQUyy63+WjutoiGpA3SZD4cGPSXUzRFeKfVr8CnYhK5LqXZw==}
+    resolution:
+      {
+        integrity: sha512-GLz0pXUYI2zRfIgyI6W7SWmHk6dSEikP9yR++hsQUyy63+WjutoiGpA3SZD4cGPSXUzRFeKfVr8CnYhK5LqXZw==
+      }
     peerDependencies:
       vue: ^3.2.0
     dependencies:
-      '@ctrl/tinycolor': 3.6.1
-      '@element-plus/icons-vue': 2.1.0(vue@3.3.5)
-      '@floating-ui/dom': 1.5.3
-      '@popperjs/core': /@sxzz/popperjs-es@2.11.7
-      '@types/lodash': 4.14.200
-      '@types/lodash-es': 4.17.10
-      '@vueuse/core': 9.13.0(@vue/composition-api@1.7.2)(vue@3.3.5)
+      "@ctrl/tinycolor": 3.6.1
+      "@element-plus/icons-vue": 2.1.0(vue@3.3.5)
+      "@floating-ui/dom": 1.5.3
+      "@popperjs/core": /@sxzz/popperjs-es@2.11.7
+      "@types/lodash": 4.14.200
+      "@types/lodash-es": 4.17.10
+      "@vueuse/core": 9.13.0(@vue/composition-api@1.7.2)(vue@3.3.5)
       async-validator: 4.2.5
       dayjs: 1.11.10
       escape-html: 1.0.3
@@ -2887,31 +4669,46 @@ packages:
       normalize-wheel-es: 1.2.0
       vue: 3.3.5(typescript@5.0.4)
     transitivePeerDependencies:
-      - '@vue/composition-api'
+      - "@vue/composition-api"
     dev: false
 
   /emoji-regex@8.0.0:
-    resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+    resolution:
+      {
+        integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+      }
     dev: true
 
   /emoji-regex@9.2.2:
-    resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+    resolution:
+      {
+        integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+      }
     dev: true
 
   /encodeurl@1.0.2:
-    resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
-    engines: {node: '>= 0.8'}
+    resolution:
+      {
+        integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
+      }
+    engines: { node: ">= 0.8" }
     dev: true
 
   /end-of-stream@1.4.4:
-    resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+    resolution:
+      {
+        integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
+      }
     dependencies:
       once: 1.4.0
     dev: true
 
   /enhanced-resolve@4.5.0:
-    resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==
+      }
+    engines: { node: ">=6.9.0" }
     requiresBuild: true
     dependencies:
       graceful-fs: 4.2.11
@@ -2921,16 +4718,25 @@ packages:
     optional: true
 
   /entities@2.2.0:
-    resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
+    resolution:
+      {
+        integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
+      }
     dev: true
 
   /entities@4.5.0:
-    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
-    engines: {node: '>=0.12'}
+    resolution:
+      {
+        integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+      }
+    engines: { node: ">=0.12" }
     dev: true
 
   /errno@0.1.8:
-    resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==}
+    resolution:
+      {
+        integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
+      }
     hasBin: true
     requiresBuild: true
     dependencies:
@@ -2939,86 +4745,150 @@ packages:
     optional: true
 
   /error-ex@1.3.2:
-    resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
+    resolution:
+      {
+        integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
+      }
     dependencies:
       is-arrayish: 0.2.1
     dev: true
 
+  /es5-ext@0.10.62:
+    resolution:
+      {
+        integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
+      }
+    engines: { node: ">=0.10" }
+    requiresBuild: true
+    dependencies:
+      es6-iterator: 2.0.3
+      es6-symbol: 3.1.3
+      next-tick: 1.1.0
+    dev: false
+
+  /es6-iterator@2.0.3:
+    resolution:
+      {
+        integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==
+      }
+    dependencies:
+      d: 1.0.1
+      es5-ext: 0.10.62
+      es6-symbol: 3.1.3
+    dev: false
+
+  /es6-symbol@3.1.3:
+    resolution:
+      {
+        integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
+      }
+    dependencies:
+      d: 1.0.1
+      ext: 1.7.0
+    dev: false
+
   /esbuild@0.11.3:
-    resolution: {integrity: sha512-BzVRHcCtFepjS9WcqRjqoIxLqgpK21a8J4Zi4msSGxDxiXVO1IbcqT1KjhdDDnJxKfe7bvzZrvMEX+bVO0Elcw==}
+    resolution:
+      {
+        integrity: sha512-BzVRHcCtFepjS9WcqRjqoIxLqgpK21a8J4Zi4msSGxDxiXVO1IbcqT1KjhdDDnJxKfe7bvzZrvMEX+bVO0Elcw==
+      }
     hasBin: true
     requiresBuild: true
     dev: true
 
   /esbuild@0.18.20:
-    resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
+      }
+    engines: { node: ">=12" }
     hasBin: true
     requiresBuild: true
     optionalDependencies:
-      '@esbuild/android-arm': 0.18.20
-      '@esbuild/android-arm64': 0.18.20
-      '@esbuild/android-x64': 0.18.20
-      '@esbuild/darwin-arm64': 0.18.20
-      '@esbuild/darwin-x64': 0.18.20
-      '@esbuild/freebsd-arm64': 0.18.20
-      '@esbuild/freebsd-x64': 0.18.20
-      '@esbuild/linux-arm': 0.18.20
-      '@esbuild/linux-arm64': 0.18.20
-      '@esbuild/linux-ia32': 0.18.20
-      '@esbuild/linux-loong64': 0.18.20
-      '@esbuild/linux-mips64el': 0.18.20
-      '@esbuild/linux-ppc64': 0.18.20
-      '@esbuild/linux-riscv64': 0.18.20
-      '@esbuild/linux-s390x': 0.18.20
-      '@esbuild/linux-x64': 0.18.20
-      '@esbuild/netbsd-x64': 0.18.20
-      '@esbuild/openbsd-x64': 0.18.20
-      '@esbuild/sunos-x64': 0.18.20
-      '@esbuild/win32-arm64': 0.18.20
-      '@esbuild/win32-ia32': 0.18.20
-      '@esbuild/win32-x64': 0.18.20
+      "@esbuild/android-arm": 0.18.20
+      "@esbuild/android-arm64": 0.18.20
+      "@esbuild/android-x64": 0.18.20
+      "@esbuild/darwin-arm64": 0.18.20
+      "@esbuild/darwin-x64": 0.18.20
+      "@esbuild/freebsd-arm64": 0.18.20
+      "@esbuild/freebsd-x64": 0.18.20
+      "@esbuild/linux-arm": 0.18.20
+      "@esbuild/linux-arm64": 0.18.20
+      "@esbuild/linux-ia32": 0.18.20
+      "@esbuild/linux-loong64": 0.18.20
+      "@esbuild/linux-mips64el": 0.18.20
+      "@esbuild/linux-ppc64": 0.18.20
+      "@esbuild/linux-riscv64": 0.18.20
+      "@esbuild/linux-s390x": 0.18.20
+      "@esbuild/linux-x64": 0.18.20
+      "@esbuild/netbsd-x64": 0.18.20
+      "@esbuild/openbsd-x64": 0.18.20
+      "@esbuild/sunos-x64": 0.18.20
+      "@esbuild/win32-arm64": 0.18.20
+      "@esbuild/win32-ia32": 0.18.20
+      "@esbuild/win32-x64": 0.18.20
     dev: true
 
   /escalade@3.1.1:
-    resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+      }
+    engines: { node: ">=6" }
 
   /escape-html@1.0.3:
-    resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+    resolution:
+      {
+        integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
+      }
 
   /escape-string-regexp@1.0.5:
-    resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
-    engines: {node: '>=0.8.0'}
+    resolution:
+      {
+        integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
+      }
+    engines: { node: ">=0.8.0" }
 
   /escape-string-regexp@4.0.0:
-    resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /escape-string-regexp@5.0.0:
-    resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
+      }
+    engines: { node: ">=12" }
     requiresBuild: true
     dev: false
     optional: true
 
   /eslint-config-prettier@8.10.0(eslint@8.51.0):
-    resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==}
+    resolution:
+      {
+        integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==
+      }
     hasBin: true
     peerDependencies:
-      eslint: '>=7.0.0'
+      eslint: ">=7.0.0"
     dependencies:
       eslint: 8.51.0
     dev: true
 
   /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.51.0)(prettier@2.8.8):
-    resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
-    engines: {node: '>=12.0.0'}
-    peerDependencies:
-      eslint: '>=7.28.0'
-      eslint-config-prettier: '*'
-      prettier: '>=2.0.0'
+    resolution:
+      {
+        integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==
+      }
+    engines: { node: ">=12.0.0" }
+    peerDependencies:
+      eslint: ">=7.28.0"
+      eslint-config-prettier: "*"
+      prettier: ">=2.0.0"
     peerDependenciesMeta:
       eslint-config-prettier:
         optional: true
@@ -3030,12 +4900,15 @@ packages:
     dev: true
 
   /eslint-plugin-vue@9.17.0(eslint@8.51.0):
-    resolution: {integrity: sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==}
-    engines: {node: ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==
+      }
+    engines: { node: ^14.17.0 || >=16.0.0 }
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
+      "@eslint-community/eslint-utils": 4.4.0(eslint@8.51.0)
       eslint: 8.51.0
       natural-compare: 1.4.0
       nth-check: 2.1.1
@@ -3048,38 +4921,50 @@ packages:
     dev: true
 
   /eslint-scope@5.1.1:
-    resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
-    engines: {node: '>=8.0.0'}
+    resolution:
+      {
+        integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
+      }
+    engines: { node: ">=8.0.0" }
     dependencies:
       esrecurse: 4.3.0
       estraverse: 4.3.0
     dev: true
 
   /eslint-scope@7.2.2:
-    resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dependencies:
       esrecurse: 4.3.0
       estraverse: 5.3.0
     dev: true
 
   /eslint-visitor-keys@3.4.3:
-    resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dev: true
 
   /eslint@8.51.0:
-    resolution: {integrity: sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     hasBin: true
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0)
-      '@eslint-community/regexpp': 4.9.1
-      '@eslint/eslintrc': 2.1.2
-      '@eslint/js': 8.51.0
-      '@humanwhocodes/config-array': 0.11.12
-      '@humanwhocodes/module-importer': 1.0.1
-      '@nodelib/fs.walk': 1.2.8
+      "@eslint-community/eslint-utils": 4.4.0(eslint@8.51.0)
+      "@eslint-community/regexpp": 4.9.1
+      "@eslint/eslintrc": 2.1.2
+      "@eslint/js": 8.51.0
+      "@humanwhocodes/config-array": 0.11.12
+      "@humanwhocodes/module-importer": 1.0.1
+      "@nodelib/fs.walk": 1.2.8
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
@@ -3115,8 +5000,11 @@ packages:
     dev: true
 
   /espree@9.6.1:
-    resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
-    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==
+      }
+    engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
     dependencies:
       acorn: 8.10.0
       acorn-jsx: 5.3.2(acorn@8.10.0)
@@ -3124,56 +5012,103 @@ packages:
     dev: true
 
   /esquery@1.5.0:
-    resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==}
-    engines: {node: '>=0.10'}
+    resolution:
+      {
+        integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
+      }
+    engines: { node: ">=0.10" }
     dependencies:
       estraverse: 5.3.0
     dev: true
 
   /esrecurse@4.3.0:
-    resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
-    engines: {node: '>=4.0'}
+    resolution:
+      {
+        integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
+      }
+    engines: { node: ">=4.0" }
     dependencies:
       estraverse: 5.3.0
     dev: true
 
   /estraverse@4.3.0:
-    resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
-    engines: {node: '>=4.0'}
+    resolution:
+      {
+        integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+      }
+    engines: { node: ">=4.0" }
     dev: true
 
   /estraverse@5.3.0:
-    resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
-    engines: {node: '>=4.0'}
+    resolution:
+      {
+        integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
+      }
+    engines: { node: ">=4.0" }
     dev: true
 
   /estree-walker@1.0.1:
-    resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
+    resolution:
+      {
+        integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
+      }
     dev: true
 
   /estree-walker@2.0.2:
-    resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+    resolution:
+      {
+        integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
+      }
 
   /estree-walker@3.0.3:
-    resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+    resolution:
+      {
+        integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
+      }
     requiresBuild: true
     dependencies:
-      '@types/estree': 1.0.3
+      "@types/estree": 1.0.3
     dev: false
     optional: true
 
   /esutils@2.0.3:
-    resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
+  /event-emitter@0.3.5:
+    resolution:
+      {
+        integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==
+      }
+    dependencies:
+      d: 1.0.1
+      es5-ext: 0.10.62
+    dev: false
+
+  /eventemitter3@4.0.7:
+    resolution:
+      {
+        integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
+      }
+    dev: false
+
   /eventemitter3@5.0.1:
-    resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+    resolution:
+      {
+        integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==
+      }
     dev: true
 
   /execa@4.1.0:
-    resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
+      }
+    engines: { node: ">=10" }
     dependencies:
       cross-spawn: 7.0.3
       get-stream: 5.2.0
@@ -3187,8 +5122,11 @@ packages:
     dev: true
 
   /execa@5.1.1:
-    resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+      }
+    engines: { node: ">=10" }
     dependencies:
       cross-spawn: 7.0.3
       get-stream: 6.0.1
@@ -3202,8 +5140,11 @@ packages:
     dev: true
 
   /execa@7.2.0:
-    resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==}
-    engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0}
+    resolution:
+      {
+        integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==
+      }
+    engines: { node: ^14.18.0 || ^16.14.0 || >=18.0.0 }
     dependencies:
       cross-spawn: 7.0.3
       get-stream: 6.0.1
@@ -3216,65 +5157,113 @@ packages:
       strip-final-newline: 3.0.0
     dev: true
 
+  /ext@1.7.0:
+    resolution:
+      {
+        integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
+      }
+    dependencies:
+      type: 2.7.2
+    dev: false
+
   /fast-deep-equal@3.1.3:
-    resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
-    dev: true
+    resolution:
+      {
+        integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+      }
 
   /fast-diff@1.3.0:
-    resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
+    resolution:
+      {
+        integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
+      }
     dev: true
 
   /fast-glob@3.3.1:
-    resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==}
-    engines: {node: '>=8.6.0'}
-    dependencies:
-      '@nodelib/fs.stat': 2.0.5
-      '@nodelib/fs.walk': 1.2.8
+    resolution:
+      {
+        integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==
+      }
+    engines: { node: ">=8.6.0" }
+    dependencies:
+      "@nodelib/fs.stat": 2.0.5
+      "@nodelib/fs.walk": 1.2.8
       glob-parent: 5.1.2
       merge2: 1.4.1
       micromatch: 4.0.5
 
   /fast-json-stable-stringify@2.1.0:
-    resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+    resolution:
+      {
+        integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+      }
     dev: true
 
   /fast-levenshtein@2.0.6:
-    resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+    resolution:
+      {
+        integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
+      }
     dev: true
 
   /fastest-levenshtein@1.0.16:
-    resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
-    engines: {node: '>= 4.9.1'}
+    resolution:
+      {
+        integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
+      }
+    engines: { node: ">= 4.9.1" }
     dev: true
 
   /fastq@1.15.0:
-    resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+    resolution:
+      {
+        integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
+      }
     dependencies:
       reusify: 1.0.4
 
+  /fecha@4.2.3:
+    resolution:
+      {
+        integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
+      }
+    dev: false
+
   /file-entry-cache@6.0.1:
-    resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
-    engines: {node: ^10.12.0 || >=12.0.0}
+    resolution:
+      {
+        integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
+      }
+    engines: { node: ^10.12.0 || >=12.0.0 }
     dependencies:
       flat-cache: 3.1.1
     dev: true
 
   /file-entry-cache@7.0.1:
-    resolution: {integrity: sha512-uLfFktPmRetVCbHe5UPuekWrQ6hENufnA46qEGbfACkK5drjTTdQYUragRgMjHldcbYG+nslUerqMPjbBSHXjQ==}
-    engines: {node: '>=12.0.0'}
+    resolution:
+      {
+        integrity: sha512-uLfFktPmRetVCbHe5UPuekWrQ6hENufnA46qEGbfACkK5drjTTdQYUragRgMjHldcbYG+nslUerqMPjbBSHXjQ==
+      }
+    engines: { node: ">=12.0.0" }
     dependencies:
       flat-cache: 3.1.1
     dev: true
 
   /fill-range@7.0.1:
-    resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+      }
+    engines: { node: ">=8" }
     dependencies:
       to-regex-range: 5.0.1
 
   /finalhandler@1.1.2:
-    resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
-    engines: {node: '>= 0.8'}
+    resolution:
+      {
+        integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
+      }
+    engines: { node: ">= 0.8" }
     dependencies:
       debug: 2.6.9
       encodeurl: 1.0.2
@@ -3288,24 +5277,33 @@ packages:
     dev: true
 
   /find-up@4.1.0:
-    resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
+      }
+    engines: { node: ">=8" }
     dependencies:
       locate-path: 5.0.0
       path-exists: 4.0.0
     dev: true
 
   /find-up@5.0.0:
-    resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
+      }
+    engines: { node: ">=10" }
     dependencies:
       locate-path: 6.0.0
       path-exists: 4.0.0
     dev: true
 
   /flat-cache@3.1.1:
-    resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==}
-    engines: {node: '>=12.0.0'}
+    resolution:
+      {
+        integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==
+      }
+    engines: { node: ">=12.0.0" }
     dependencies:
       flatted: 3.2.9
       keyv: 4.5.4
@@ -3313,37 +5311,52 @@ packages:
     dev: true
 
   /flat@5.0.2:
-    resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
+    resolution:
+      {
+        integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
+      }
     hasBin: true
     requiresBuild: true
     dev: false
     optional: true
 
   /flatted@3.2.9:
-    resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==}
+    resolution:
+      {
+        integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==
+      }
     dev: true
 
   /follow-redirects@1.15.3:
-    resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==}
-    engines: {node: '>=4.0'}
+    resolution:
+      {
+        integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
+      }
+    engines: { node: ">=4.0" }
     peerDependencies:
-      debug: '*'
+      debug: "*"
     peerDependenciesMeta:
       debug:
         optional: true
     dev: false
 
   /foreground-child@3.1.1:
-    resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==
+      }
+    engines: { node: ">=14" }
     dependencies:
       cross-spawn: 7.0.3
       signal-exit: 4.1.0
     dev: true
 
   /form-data@4.0.0:
-    resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
+      }
+    engines: { node: ">= 6" }
     dependencies:
       asynckit: 0.4.0
       combined-stream: 1.0.8
@@ -3351,18 +5364,27 @@ packages:
     dev: false
 
   /fraction.js@4.3.7:
-    resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+    resolution:
+      {
+        integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
+      }
     dev: true
 
   /framesync@6.1.2:
-    resolution: {integrity: sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==}
+    resolution:
+      {
+        integrity: sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==
+      }
     dependencies:
       tslib: 2.4.0
     dev: false
 
   /fs-extra@10.1.0:
-    resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       graceful-fs: 4.2.11
       jsonfile: 6.1.0
@@ -3370,8 +5392,11 @@ packages:
     dev: true
 
   /fs-extra@11.1.1:
-    resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==}
-    engines: {node: '>=14.14'}
+    resolution:
+      {
+        integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==
+      }
+    engines: { node: ">=14.14" }
     dependencies:
       graceful-fs: 4.2.11
       jsonfile: 6.1.0
@@ -3379,8 +5404,11 @@ packages:
     dev: true
 
   /fs-minipass@2.1.0:
-    resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
+      }
+    engines: { node: ">= 8" }
     requiresBuild: true
     dependencies:
       minipass: 3.3.6
@@ -3388,31 +5416,49 @@ packages:
     optional: true
 
   /fs.realpath@1.0.0:
-    resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+    resolution:
+      {
+        integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+      }
     dev: true
 
   /fsevents@2.3.3:
-    resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
-    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    resolution:
+      {
+        integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+      }
+    engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 }
     os: [darwin]
     requiresBuild: true
     optional: true
 
   /function-bind@1.1.2:
-    resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+    resolution:
+      {
+        integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
+      }
     dev: false
 
   /gensync@1.0.0-beta.2:
-    resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
-    engines: {node: '>=6.9.0'}
+    resolution:
+      {
+        integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
+      }
+    engines: { node: ">=6.9.0" }
 
   /get-caller-file@2.0.5:
-    resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
-    engines: {node: 6.* || 8.* || >= 10.*}
+    resolution:
+      {
+        integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+      }
+    engines: { node: 6.* || 8.* || >= 10.* }
     dev: true
 
   /get-intrinsic@1.2.1:
-    resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==}
+    resolution:
+      {
+        integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==
+      }
     dependencies:
       function-bind: 1.1.2
       has: 1.0.4
@@ -3421,19 +5467,28 @@ packages:
     dev: false
 
   /get-stream@5.2.0:
-    resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
+      }
+    engines: { node: ">=8" }
     dependencies:
       pump: 3.0.0
     dev: true
 
   /get-stream@6.0.1:
-    resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /giget@1.1.3:
-    resolution: {integrity: sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q==}
+    resolution:
+      {
+        integrity: sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q==
+      }
     hasBin: true
     requiresBuild: true
     dependencies:
@@ -3450,8 +5505,11 @@ packages:
     optional: true
 
   /git-raw-commits@2.0.11:
-    resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==
+      }
+    engines: { node: ">=10" }
     hasBin: true
     dependencies:
       dargs: 7.0.0
@@ -3461,22 +5519,45 @@ packages:
       through2: 4.0.2
     dev: true
 
+  /gl-matrix@3.4.3:
+    resolution:
+      {
+        integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==
+      }
+    dev: false
+
+  /gl-vec2@1.3.0:
+    resolution:
+      {
+        integrity: sha512-YiqaAuNsheWmUV0Sa8k94kBB0D6RWjwZztyO+trEYS8KzJ6OQB/4686gdrf59wld4hHFIvaxynO3nRxpk1Ij/A==
+      }
+    dev: false
+
   /glob-parent@5.1.2:
-    resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
+      }
+    engines: { node: ">= 6" }
     dependencies:
       is-glob: 4.0.3
 
   /glob-parent@6.0.2:
-    resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
-    engines: {node: '>=10.13.0'}
+    resolution:
+      {
+        integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
+      }
+    engines: { node: ">=10.13.0" }
     dependencies:
       is-glob: 4.0.3
     dev: true
 
   /glob@10.3.10:
-    resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
-    engines: {node: '>=16 || 14 >=14.17'}
+    resolution:
+      {
+        integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==
+      }
+    engines: { node: ">=16 || 14 >=14.17" }
     hasBin: true
     dependencies:
       foreground-child: 3.1.1
@@ -3487,7 +5568,10 @@ packages:
     dev: true
 
   /glob@7.1.6:
-    resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
+    resolution:
+      {
+        integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
+      }
     dependencies:
       fs.realpath: 1.0.0
       inflight: 1.0.6
@@ -3498,7 +5582,10 @@ packages:
     dev: true
 
   /glob@7.2.3:
-    resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+    resolution:
+      {
+        integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
+      }
     dependencies:
       fs.realpath: 1.0.0
       inflight: 1.0.6
@@ -3509,22 +5596,31 @@ packages:
     dev: true
 
   /global-dirs@0.1.1:
-    resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==
+      }
+    engines: { node: ">=4" }
     dependencies:
       ini: 1.3.8
     dev: true
 
   /global-modules@2.0.0:
-    resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
+      }
+    engines: { node: ">=6" }
     dependencies:
       global-prefix: 3.0.0
     dev: true
 
   /global-prefix@3.0.0:
-    resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==
+      }
+    engines: { node: ">=6" }
     dependencies:
       ini: 1.3.8
       kind-of: 6.0.3
@@ -3532,19 +5628,28 @@ packages:
     dev: true
 
   /globals@11.12.0:
-    resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
+      }
+    engines: { node: ">=4" }
 
   /globals@13.23.0:
-    resolution: {integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==
+      }
+    engines: { node: ">=8" }
     dependencies:
       type-fest: 0.20.2
     dev: true
 
   /globby@11.1.0:
-    resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
+      }
+    engines: { node: ">=10" }
     dependencies:
       array-union: 2.1.0
       dir-glob: 3.0.1
@@ -3555,8 +5660,11 @@ packages:
     dev: true
 
   /globby@13.2.2:
-    resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     requiresBuild: true
     dependencies:
       dir-glob: 3.0.1
@@ -3568,95 +5676,168 @@ packages:
     optional: true
 
   /globjoin@0.1.4:
-    resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==}
+    resolution:
+      {
+        integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
+      }
     dev: true
 
   /gopd@1.0.1:
-    resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+    resolution:
+      {
+        integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+      }
     dependencies:
       get-intrinsic: 1.2.1
     dev: false
 
   /graceful-fs@4.2.11:
-    resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+    resolution:
+      {
+        integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+      }
 
   /graphemer@1.4.0:
-    resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+    resolution:
+      {
+        integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
+      }
     dev: true
 
+  /graphlib@2.1.8:
+    resolution:
+      {
+        integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
+      }
+    dependencies:
+      lodash: 4.17.21
+    dev: false
+
   /hard-rejection@2.1.0:
-    resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /has-flag@3.0.0:
-    resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
+      }
+    engines: { node: ">=4" }
 
   /has-flag@4.0.0:
-    resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /has-property-descriptors@1.0.0:
-    resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==}
+    resolution:
+      {
+        integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+      }
     dependencies:
       get-intrinsic: 1.2.1
     dev: false
 
   /has-proto@1.0.1:
-    resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==}
-    engines: {node: '>= 0.4'}
+    resolution:
+      {
+        integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==
+      }
+    engines: { node: ">= 0.4" }
     dev: false
 
   /has-symbols@1.0.3:
-    resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
-    engines: {node: '>= 0.4'}
+    resolution:
+      {
+        integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
+      }
+    engines: { node: ">= 0.4" }
     dev: false
 
   /has@1.0.4:
-    resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==}
-    engines: {node: '>= 0.4.0'}
+    resolution:
+      {
+        integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==
+      }
+    engines: { node: ">= 0.4.0" }
 
   /hash-sum@2.0.0:
-    resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
+    resolution:
+      {
+        integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /he@1.2.0:
-    resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
+    resolution:
+      {
+        integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+      }
     hasBin: true
     dev: true
 
   /hey-listen@1.0.8:
-    resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==}
+    resolution:
+      {
+        integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==
+      }
     dev: false
 
   /hookable@5.5.3:
-    resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+    resolution:
+      {
+        integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /hosted-git-info@2.8.9:
-    resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
+    resolution:
+      {
+        integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
+      }
     dev: true
 
   /hosted-git-info@4.1.0:
-    resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==
+      }
+    engines: { node: ">=10" }
     dependencies:
       lru-cache: 6.0.0
     dev: true
 
   /html-tags@3.3.1:
-    resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
+  /html-void-elements@2.0.1:
+    resolution:
+      {
+        integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==
+      }
+    dev: false
+
   /htmlparser2@8.0.2:
-    resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
+    resolution:
+      {
+        integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
+      }
     dependencies:
       domelementtype: 2.3.0
       domhandler: 5.0.3
@@ -3665,8 +5846,11 @@ packages:
     dev: true
 
   /https-proxy-agent@7.0.2:
-    resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==}
-    engines: {node: '>= 14'}
+    resolution:
+      {
+        integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==
+      }
+    engines: { node: ">= 14" }
     requiresBuild: true
     dependencies:
       agent-base: 7.1.0
@@ -3677,278 +5861,486 @@ packages:
     optional: true
 
   /human-signals@1.1.1:
-    resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
-    engines: {node: '>=8.12.0'}
+    resolution:
+      {
+        integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
+      }
+    engines: { node: ">=8.12.0" }
     dev: true
 
   /human-signals@2.1.0:
-    resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
-    engines: {node: '>=10.17.0'}
+    resolution:
+      {
+        integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+      }
+    engines: { node: ">=10.17.0" }
     dev: true
 
   /human-signals@4.3.1:
-    resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==}
-    engines: {node: '>=14.18.0'}
+    resolution:
+      {
+        integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==
+      }
+    engines: { node: ">=14.18.0" }
     dev: true
 
   /husky@8.0.3:
-    resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==
+      }
+    engines: { node: ">=14" }
     hasBin: true
     dev: true
 
+  /i18next@20.6.1:
+    resolution:
+      {
+        integrity: sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==
+      }
+    dependencies:
+      "@babel/runtime": 7.23.2
+    dev: false
+
   /ignore@5.2.4:
-    resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
-    engines: {node: '>= 4'}
+    resolution:
+      {
+        integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
+      }
+    engines: { node: ">= 4" }
+
+  /immer@9.0.21:
+    resolution:
+      {
+        integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==
+      }
+    dev: false
 
   /immutable@4.3.4:
-    resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
+    resolution:
+      {
+        integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
+      }
     dev: true
 
   /import-fresh@3.3.0:
-    resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
+      }
+    engines: { node: ">=6" }
     dependencies:
       parent-module: 1.0.1
       resolve-from: 4.0.0
     dev: true
 
   /import-lazy@4.0.0:
-    resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /imurmurhash@0.1.4:
-    resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
-    engines: {node: '>=0.8.19'}
+    resolution:
+      {
+        integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
+      }
+    engines: { node: ">=0.8.19" }
     dev: true
 
   /indent-string@4.0.0:
-    resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /indent-string@5.0.0:
-    resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /inflight@1.0.6:
-    resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+    resolution:
+      {
+        integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
+      }
     dependencies:
       once: 1.4.0
       wrappy: 1.0.2
     dev: true
 
   /inherits@2.0.3:
-    resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
+    resolution:
+      {
+        integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
+      }
     dev: false
 
   /inherits@2.0.4:
-    resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+    resolution:
+      {
+        integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+      }
 
   /ini@1.3.8:
-    resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+    resolution:
+      {
+        integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
+      }
     dev: true
 
   /inline-worker@1.1.0:
-    resolution: {integrity: sha512-2nlxBGg5Uoop6IRco9wMzlAz62690ylokrUDg3IaCi9bJaq0HykbWlRtRXgvSKiBNmCBGXnOCFBkIFjaSGJocA==}
+    resolution:
+      {
+        integrity: sha512-2nlxBGg5Uoop6IRco9wMzlAz62690ylokrUDg3IaCi9bJaq0HykbWlRtRXgvSKiBNmCBGXnOCFBkIFjaSGJocA==
+      }
+    dev: false
+
+  /insert-css@2.0.0:
+    resolution:
+      {
+        integrity: sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==
+      }
+    dev: false
+
+  /is-any-array@2.0.1:
+    resolution:
+      {
+        integrity: sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ==
+      }
     dev: false
 
   /is-arrayish@0.2.1:
-    resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
+    resolution:
+      {
+        integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
+      }
     dev: true
 
   /is-arrayish@0.3.2:
-    resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
-    dev: true
+    resolution:
+      {
+        integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
+      }
 
   /is-binary-path@2.1.0:
-    resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+      }
+    engines: { node: ">=8" }
     dependencies:
       binary-extensions: 2.2.0
 
   /is-builtin-module@3.2.1:
-    resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==
+      }
+    engines: { node: ">=6" }
     dependencies:
       builtin-modules: 3.3.0
     dev: true
 
   /is-core-module@2.13.0:
-    resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
+    resolution:
+      {
+        integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==
+      }
     dependencies:
       has: 1.0.4
     dev: true
 
   /is-docker@2.2.1:
-    resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
+      }
+    engines: { node: ">=8" }
     hasBin: true
     dev: true
 
   /is-extglob@2.1.1:
-    resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
+      }
+    engines: { node: ">=0.10.0" }
 
   /is-fullwidth-code-point@3.0.0:
-    resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /is-fullwidth-code-point@4.0.0:
-    resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /is-glob@4.0.3:
-    resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
+      }
+    engines: { node: ">=0.10.0" }
     dependencies:
       is-extglob: 2.1.1
 
+  /is-hotkey@0.2.0:
+    resolution:
+      {
+        integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==
+      }
+    dev: false
+
   /is-module@1.0.0:
-    resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
+    resolution:
+      {
+        integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
+      }
     dev: true
 
   /is-number@7.0.0:
-    resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
-    engines: {node: '>=0.12.0'}
+    resolution:
+      {
+        integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+      }
+    engines: { node: ">=0.12.0" }
 
   /is-obj@2.0.0:
-    resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /is-path-inside@3.0.3:
-    resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /is-plain-obj@1.1.0:
-    resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /is-plain-object@5.0.0:
-    resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
+      }
+    engines: { node: ">=0.10.0" }
 
   /is-reference@1.2.1:
-    resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
+    resolution:
+      {
+        integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==
+      }
     dependencies:
-      '@types/estree': 1.0.3
+      "@types/estree": 1.0.3
     dev: true
 
   /is-stream@2.0.1:
-    resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /is-stream@3.0.0:
-    resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dev: true
 
   /is-text-path@1.0.1:
-    resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==
+      }
+    engines: { node: ">=0.10.0" }
     dependencies:
       text-extensions: 1.9.0
     dev: true
 
+  /is-url@1.2.4:
+    resolution:
+      {
+        integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
+      }
+    dev: false
+
   /is-wsl@2.2.0:
-    resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
+      }
+    engines: { node: ">=8" }
     dependencies:
       is-docker: 2.2.1
     dev: true
 
   /isarray@1.0.0:
-    resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+    resolution:
+      {
+        integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /isexe@2.0.0:
-    resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+    resolution:
+      {
+        integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+      }
     dev: true
 
   /jackspeak@2.3.6:
-    resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==
+      }
+    engines: { node: ">=14" }
     dependencies:
-      '@isaacs/cliui': 8.0.2
+      "@isaacs/cliui": 8.0.2
     optionalDependencies:
-      '@pkgjs/parseargs': 0.11.0
+      "@pkgjs/parseargs": 0.11.0
     dev: true
 
   /jiti@1.20.0:
-    resolution: {integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==}
+    resolution:
+      {
+        integrity: sha512-3TV69ZbrvV6U5DfQimop50jE9Dl6J8O1ja1dvBbMba/sZ3YBEQqJ2VZRoQPVnhlzjNtU1vaXRZVrVjU4qtm8yA==
+      }
     hasBin: true
 
   /js-audio-recorder@1.0.7:
-    resolution: {integrity: sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA==}
+    resolution:
+      {
+        integrity: sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA==
+      }
     dev: false
 
   /js-cookie@3.0.5:
-    resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==
+      }
+    engines: { node: ">=14" }
     dev: false
 
   /js-tokens@4.0.0:
-    resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+    resolution:
+      {
+        integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+      }
 
   /js-tokens@8.0.2:
-    resolution: {integrity: sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==}
+    resolution:
+      {
+        integrity: sha512-Olnt+V7xYdvGze9YTbGFZIfQXuGV4R3nQwwl8BrtgaPE/wq8UFpUHWuTNc05saowhSr1ZO6tx+V6RjE9D5YQog==
+      }
     dev: true
 
   /js-yaml@4.1.0:
-    resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+    resolution:
+      {
+        integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+      }
     hasBin: true
     dependencies:
       argparse: 2.0.1
     dev: true
 
   /jsesc@2.5.2:
-    resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+      }
+    engines: { node: ">=4" }
     hasBin: true
 
   /json-buffer@3.0.1:
-    resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+    resolution:
+      {
+        integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
+      }
     dev: true
 
   /json-parse-even-better-errors@2.3.1:
-    resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+    resolution:
+      {
+        integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+      }
     dev: true
 
   /json-schema-traverse@0.4.1:
-    resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+    resolution:
+      {
+        integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+      }
     dev: true
 
   /json-schema-traverse@1.0.0:
-    resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+    resolution:
+      {
+        integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+      }
     dev: true
 
   /json-stable-stringify-without-jsonify@1.0.1:
-    resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+    resolution:
+      {
+        integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
+      }
     dev: true
 
   /json5@2.2.3:
-    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
+      }
+    engines: { node: ">=6" }
     hasBin: true
 
   /jsonc-parser@3.2.0:
-    resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
+    resolution:
+      {
+        integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /jsonfile@6.1.0:
-    resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+    resolution:
+      {
+        integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
+      }
     dependencies:
       universalify: 2.0.0
     optionalDependencies:
@@ -3956,55 +6348,85 @@ packages:
     dev: true
 
   /jsonparse@1.3.1:
-    resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
-    engines: {'0': node >= 0.2.0}
+    resolution:
+      {
+        integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
+      }
+    engines: { "0": node >= 0.2.0 }
     dev: true
 
   /keyv@4.5.4:
-    resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+    resolution:
+      {
+        integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
+      }
     dependencies:
       json-buffer: 3.0.1
     dev: true
 
   /kind-of@6.0.3:
-    resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /knitwork@1.0.0:
-    resolution: {integrity: sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==}
+    resolution:
+      {
+        integrity: sha512-dWl0Dbjm6Xm+kDxhPQJsCBTxrJzuGl0aP9rhr+TG8D3l+GL90N8O8lYUi7dTSAN2uuDqCtNgb6aEuQH5wsiV8Q==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /known-css-properties@0.28.0:
-    resolution: {integrity: sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==}
+    resolution:
+      {
+        integrity: sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==
+      }
     dev: true
 
   /known-css-properties@0.29.0:
-    resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==}
+    resolution:
+      {
+        integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==
+      }
     dev: true
 
   /levn@0.4.1:
-    resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
-    engines: {node: '>= 0.8.0'}
+    resolution:
+      {
+        integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
+      }
+    engines: { node: ">= 0.8.0" }
     dependencies:
       prelude-ls: 1.2.1
       type-check: 0.4.0
     dev: true
 
   /lilconfig@2.1.0:
-    resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /lines-and-columns@1.2.4:
-    resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+    resolution:
+      {
+        integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
+      }
     dev: true
 
   /lint-staged@13.3.0:
-    resolution: {integrity: sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==}
-    engines: {node: ^16.14.0 || >=18.0.0}
+    resolution:
+      {
+        integrity: sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==
+      }
+    engines: { node: ^16.14.0 || >=18.0.0 }
     hasBin: true
     dependencies:
       chalk: 5.3.0
@@ -4023,10 +6445,13 @@ packages:
     dev: true
 
   /listr2@6.6.1:
-    resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==}
-    engines: {node: '>=16.0.0'}
+    resolution:
+      {
+        integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==
+      }
+    engines: { node: ">=16.0.0" }
     peerDependencies:
-      enquirer: '>= 2.3.0 < 3'
+      enquirer: ">= 2.3.0 < 3"
     peerDependenciesMeta:
       enquirer:
         optional: true
@@ -4040,100 +6465,194 @@ packages:
     dev: true
 
   /local-pkg@0.4.3:
-    resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==
+      }
+    engines: { node: ">=14" }
     requiresBuild: true
     dev: false
     optional: true
 
   /locate-path@5.0.0:
-    resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
+      }
+    engines: { node: ">=8" }
     dependencies:
       p-locate: 4.1.0
     dev: true
 
   /locate-path@6.0.0:
-    resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
+      }
+    engines: { node: ">=10" }
     dependencies:
       p-locate: 5.0.0
     dev: true
 
   /lodash-es@4.17.21:
-    resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
+    resolution:
+      {
+        integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+      }
     dev: false
 
   /lodash-unified@1.0.3(@types/lodash-es@4.17.10)(lodash-es@4.17.21)(lodash@4.17.21):
-    resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==}
+    resolution:
+      {
+        integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==
+      }
     peerDependencies:
-      '@types/lodash-es': '*'
-      lodash: '*'
-      lodash-es: '*'
+      "@types/lodash-es": "*"
+      lodash: "*"
+      lodash-es: "*"
     dependencies:
-      '@types/lodash-es': 4.17.10
+      "@types/lodash-es": 4.17.10
       lodash: 4.17.21
       lodash-es: 4.17.21
     dev: false
 
   /lodash.camelcase@4.3.0:
-    resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==}
-    dev: true
+    resolution:
+      {
+        integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==
+      }
+
+  /lodash.clonedeep@4.5.0:
+    resolution:
+      {
+        integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
+      }
+    dev: false
 
   /lodash.debounce@4.0.8:
-    resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
+    resolution:
+      {
+        integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
+      }
+    dev: false
+
+  /lodash.foreach@4.5.0:
+    resolution:
+      {
+        integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==
+      }
+    dev: false
+
+  /lodash.isequal@4.5.0:
+    resolution:
+      {
+        integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==
+      }
     dev: false
 
   /lodash.isfunction@3.0.9:
-    resolution: {integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==}
+    resolution:
+      {
+        integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==
+      }
     dev: true
 
   /lodash.isplainobject@4.0.6:
-    resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
+    resolution:
+      {
+        integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
+      }
     dev: true
 
   /lodash.kebabcase@4.1.1:
-    resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==}
+    resolution:
+      {
+        integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==
+      }
     dev: true
 
   /lodash.memoize@4.1.2:
-    resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
+    resolution:
+      {
+        integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
+      }
     dev: true
 
   /lodash.merge@4.6.2:
-    resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+    resolution:
+      {
+        integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+      }
     dev: true
 
   /lodash.mergewith@4.6.2:
-    resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==}
+    resolution:
+      {
+        integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
+      }
     dev: true
 
   /lodash.snakecase@4.1.1:
-    resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==}
+    resolution:
+      {
+        integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
+      }
     dev: true
 
   /lodash.startcase@4.4.0:
-    resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
+    resolution:
+      {
+        integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==
+      }
     dev: true
 
+  /lodash.throttle@4.1.1:
+    resolution:
+      {
+        integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
+      }
+    dev: false
+
+  /lodash.toarray@4.4.0:
+    resolution:
+      {
+        integrity: sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==
+      }
+    dev: false
+
   /lodash.truncate@4.4.2:
-    resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
+    resolution:
+      {
+        integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
+      }
     dev: true
 
   /lodash.uniq@4.5.0:
-    resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
+    resolution:
+      {
+        integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
+      }
     dev: true
 
   /lodash.upperfirst@4.3.1:
-    resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==}
+    resolution:
+      {
+        integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==
+      }
     dev: true
 
   /lodash@4.17.21:
-    resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+    resolution:
+      {
+        integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+      }
 
   /log-update@5.0.1:
-    resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dependencies:
       ansi-escapes: 5.0.0
       cli-cursor: 4.0.0
@@ -4143,70 +6662,112 @@ packages:
     dev: true
 
   /lru-cache@10.0.1:
-    resolution: {integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==}
-    engines: {node: 14 || >=16.14}
+    resolution:
+      {
+        integrity: sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==
+      }
+    engines: { node: 14 || >=16.14 }
     dev: true
 
   /lru-cache@5.1.1:
-    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+    resolution:
+      {
+        integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
+      }
     dependencies:
       yallist: 3.1.1
 
   /lru-cache@6.0.0:
-    resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
+      }
+    engines: { node: ">=10" }
     dependencies:
       yallist: 4.0.0
 
   /magic-string@0.25.9:
-    resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
+    resolution:
+      {
+        integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==
+      }
     dependencies:
       sourcemap-codec: 1.4.8
     dev: true
 
   /magic-string@0.30.5:
-    resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==
+      }
+    engines: { node: ">=12" }
     dependencies:
-      '@jridgewell/sourcemap-codec': 1.4.15
+      "@jridgewell/sourcemap-codec": 1.4.15
 
   /make-error@1.3.6:
-    resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
+    resolution:
+      {
+        integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+      }
     dev: true
 
   /map-obj@1.0.1:
-    resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /map-obj@4.3.0:
-    resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /mathml-tag-names@2.1.3:
-    resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
+    resolution:
+      {
+        integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
+      }
     dev: true
 
   /mdn-data@2.0.14:
-    resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==}
+    resolution:
+      {
+        integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
+      }
     dev: true
 
   /mdn-data@2.0.28:
-    resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
+    resolution:
+      {
+        integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==
+      }
     dev: true
 
   /mdn-data@2.0.30:
-    resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+    resolution:
+      {
+        integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
+      }
     dev: true
 
   /memoize-one@6.0.0:
-    resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
+    resolution:
+      {
+        integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
+      }
     dev: false
 
   /memory-fs@0.5.0:
-    resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==}
-    engines: {node: '>=4.3.0 <5.0.0 || >=5.10'}
+    resolution:
+      {
+        integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==
+      }
+    engines: { node: ">=4.3.0 <5.0.0 || >=5.10" }
     requiresBuild: true
     dependencies:
       errno: 0.1.8
@@ -4215,10 +6776,13 @@ packages:
     optional: true
 
   /meow@10.1.5:
-    resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dependencies:
-      '@types/minimist': 1.2.4
+      "@types/minimist": 1.2.4
       camelcase-keys: 7.0.2
       decamelize: 5.0.1
       decamelize-keys: 1.1.1
@@ -4233,10 +6797,13 @@ packages:
     dev: true
 
   /meow@8.1.2:
-    resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==
+      }
+    engines: { node: ">=10" }
     dependencies:
-      '@types/minimist': 1.2.4
+      "@types/minimist": 1.2.4
       camelcase-keys: 6.2.2
       decamelize-keys: 1.1.1
       hard-rejection: 2.1.0
@@ -4250,63 +6817,105 @@ packages:
     dev: true
 
   /merge-stream@2.0.0:
-    resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+    resolution:
+      {
+        integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+      }
     dev: true
 
   /merge2@1.4.1:
-    resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
+      }
+    engines: { node: ">= 8" }
 
   /micromatch@4.0.5:
-    resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
-    engines: {node: '>=8.6'}
+    resolution:
+      {
+        integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
+      }
+    engines: { node: ">=8.6" }
     dependencies:
       braces: 3.0.2
       picomatch: 2.3.1
 
   /mime-db@1.52.0:
-    resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
-    engines: {node: '>= 0.6'}
+    resolution:
+      {
+        integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
+      }
+    engines: { node: ">= 0.6" }
+    dev: false
+
+  /mime-match@1.0.2:
+    resolution:
+      {
+        integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==
+      }
+    dependencies:
+      wildcard: 1.1.2
     dev: false
 
   /mime-types@2.1.35:
-    resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
-    engines: {node: '>= 0.6'}
+    resolution:
+      {
+        integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
+      }
+    engines: { node: ">= 0.6" }
     dependencies:
       mime-db: 1.52.0
     dev: false
 
   /mimic-fn@2.1.0:
-    resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /mimic-fn@4.0.0:
-    resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /min-indent@1.0.1:
-    resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==
+      }
+    engines: { node: ">=4" }
     dev: true
 
   /minimatch@3.1.2:
-    resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+    resolution:
+      {
+        integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+      }
     dependencies:
       brace-expansion: 1.1.11
     dev: true
 
   /minimatch@9.0.3:
-    resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
-    engines: {node: '>=16 || 14 >=14.17'}
+    resolution:
+      {
+        integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
+      }
+    engines: { node: ">=16 || 14 >=14.17" }
     dependencies:
       brace-expansion: 2.0.1
     dev: true
 
   /minimist-options@4.1.0:
-    resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==
+      }
+    engines: { node: ">= 6" }
     dependencies:
       arrify: 1.0.1
       is-plain-obj: 1.1.0
@@ -4314,12 +6923,18 @@ packages:
     dev: true
 
   /minimist@1.2.8:
-    resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+    resolution:
+      {
+        integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
+      }
     dev: true
 
   /minipass@3.3.6:
-    resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==
+      }
+    engines: { node: ">=8" }
     requiresBuild: true
     dependencies:
       yallist: 4.0.0
@@ -4327,20 +6942,29 @@ packages:
     optional: true
 
   /minipass@5.0.0:
-    resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
+      }
+    engines: { node: ">=8" }
     requiresBuild: true
     dev: false
     optional: true
 
   /minipass@7.0.4:
-    resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
-    engines: {node: '>=16 || 14 >=14.17'}
+    resolution:
+      {
+        integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==
+      }
+    engines: { node: ">=16 || 14 >=14.17" }
     dev: true
 
   /minizlib@2.1.2:
-    resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
+      }
+    engines: { node: ">= 8" }
     requiresBuild: true
     dependencies:
       minipass: 3.3.6
@@ -4349,19 +6973,76 @@ packages:
     optional: true
 
   /mitt@3.0.1:
-    resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+    resolution:
+      {
+        integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
+      }
     dev: false
 
   /mkdirp@1.0.4:
-    resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
+      }
+    engines: { node: ">=10" }
     hasBin: true
     requiresBuild: true
     dev: false
     optional: true
 
+  /ml-array-max@1.2.4:
+    resolution:
+      {
+        integrity: sha512-BlEeg80jI0tW6WaPyGxf5Sa4sqvcyY6lbSn5Vcv44lp1I2GR6AWojfUvLnGTNsIXrZ8uqWmo8VcG1WpkI2ONMQ==
+      }
+    dependencies:
+      is-any-array: 2.0.1
+    dev: false
+
+  /ml-array-min@1.2.3:
+    resolution:
+      {
+        integrity: sha512-VcZ5f3VZ1iihtrGvgfh/q0XlMobG6GQ8FsNyQXD3T+IlstDv85g8kfV0xUG1QPRO/t21aukaJowDzMTc7j5V6Q==
+      }
+    dependencies:
+      is-any-array: 2.0.1
+    dev: false
+
+  /ml-array-rescale@1.3.7:
+    resolution:
+      {
+        integrity: sha512-48NGChTouvEo9KBctDfHC3udWnQKNKEWN0ziELvY3KG25GR5cA8K8wNVzracsqSW1QEkAXjTNx+ycgAv06/1mQ==
+      }
+    dependencies:
+      is-any-array: 2.0.1
+      ml-array-max: 1.2.4
+      ml-array-min: 1.2.3
+    dev: false
+
+  /ml-matrix@6.11.0:
+    resolution:
+      {
+        integrity: sha512-7jr9NmFRkaUxbKslfRu3aZOjJd2LkSitCGv+QH9PF0eJoEG7jIpjXra1Vw8/kgao8+kHCSsJONG6vfWmXQ+/Eg==
+      }
+    dependencies:
+      is-any-array: 2.0.1
+      ml-array-rescale: 1.3.7
+    dev: false
+
+  /ml-matrix@6.5.0:
+    resolution:
+      {
+        integrity: sha512-sms732Dge+rs5dU4mnjE0oqLWm1WujvR2fr38LgUHRG2cjXjWlO3WJupLYaSz3++2iYr0UrGDK72OAivr3J8dg==
+      }
+    dependencies:
+      ml-array-rescale: 1.3.7
+    dev: false
+
   /mlly@1.4.2:
-    resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==}
+    resolution:
+      {
+        integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==
+      }
     requiresBuild: true
     dependencies:
       acorn: 8.10.0
@@ -4372,31 +7053,50 @@ packages:
     optional: true
 
   /mockjs@1.1.0:
-    resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==}
+    resolution:
+      {
+        integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==
+      }
     hasBin: true
     dependencies:
       commander: 11.1.0
+    dev: true
 
   /mri@1.2.0:
-    resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+      }
+    engines: { node: ">=4" }
 
   /ms@2.0.0:
-    resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
+    resolution:
+      {
+        integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
+      }
     dev: true
 
   /ms@2.1.2:
-    resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
+    resolution:
+      {
+        integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+      }
 
   /muggle-string@0.3.1:
-    resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==}
+    resolution:
+      {
+        integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==
+      }
     dev: true
 
   /multimatch@4.0.0:
-    resolution: {integrity: sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==
+      }
+    engines: { node: ">=8" }
     dependencies:
-      '@types/minimatch': 3.0.5
+      "@types/minimatch": 3.0.5
       array-differ: 3.0.0
       array-union: 2.1.0
       arrify: 2.0.1
@@ -4404,41 +7104,79 @@ packages:
     dev: true
 
   /mz@2.7.0:
-    resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+    resolution:
+      {
+        integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
+      }
     dependencies:
       any-promise: 1.3.0
       object-assign: 4.1.1
       thenify-all: 1.6.0
     dev: true
 
+  /namespace-emitter@2.0.1:
+    resolution:
+      {
+        integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==
+      }
+    dev: false
+
   /nanoid@3.3.6:
-    resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
-    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    resolution:
+      {
+        integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
+      }
+    engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 }
     hasBin: true
 
   /natural-compare-lite@1.4.0:
-    resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
+    resolution:
+      {
+        integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==
+      }
     dev: true
 
   /natural-compare@1.4.0:
-    resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+    resolution:
+      {
+        integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
+      }
     dev: true
 
   /neo-async@2.6.2:
-    resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
+    resolution:
+      {
+        integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+      }
     dev: true
 
+  /next-tick@1.1.0:
+    resolution:
+      {
+        integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
+      }
+    dev: false
+
   /node-fetch-native@1.4.0:
-    resolution: {integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==}
+    resolution:
+      {
+        integrity: sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /node-releases@2.0.13:
-    resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
+    resolution:
+      {
+        integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
+      }
 
   /normalize-package-data@2.5.0:
-    resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
+    resolution:
+      {
+        integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
+      }
     dependencies:
       hosted-git-info: 2.8.9
       resolve: 1.22.8
@@ -4447,8 +7185,11 @@ packages:
     dev: true
 
   /normalize-package-data@3.0.3:
-    resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==
+      }
+    engines: { node: ">=10" }
     dependencies:
       hosted-git-info: 4.1.0
       is-core-module: 2.13.0
@@ -4457,97 +7198,148 @@ packages:
     dev: true
 
   /normalize-path@3.0.0:
-    resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+      }
+    engines: { node: ">=0.10.0" }
 
   /normalize-range@0.1.2:
-    resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /normalize-url@6.1.0:
-    resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /normalize-wheel-es@1.2.0:
-    resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
+    resolution:
+      {
+        integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
+      }
     dev: false
 
   /npm-run-path@4.0.1:
-    resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
+      }
+    engines: { node: ">=8" }
     dependencies:
       path-key: 3.1.1
     dev: true
 
   /npm-run-path@5.1.0:
-    resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dependencies:
       path-key: 4.0.0
     dev: true
 
   /nprogress@0.2.0:
-    resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==}
+    resolution:
+      {
+        integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==
+      }
     dev: false
 
   /nth-check@2.1.1:
-    resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+    resolution:
+      {
+        integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
+      }
     dependencies:
       boolbase: 1.0.0
     dev: true
 
   /object-assign@4.1.1:
-    resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /object-hash@3.0.0:
-    resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
+      }
+    engines: { node: ">= 6" }
     dev: true
 
   /object-inspect@1.13.1:
-    resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
+    resolution:
+      {
+        integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==
+      }
     dev: false
 
   /ohash@1.1.3:
-    resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==}
+    resolution:
+      {
+        integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /on-finished@2.3.0:
-    resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
-    engines: {node: '>= 0.8'}
+    resolution:
+      {
+        integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==
+      }
+    engines: { node: ">= 0.8" }
     dependencies:
       ee-first: 1.1.1
     dev: true
 
   /once@1.4.0:
-    resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+    resolution:
+      {
+        integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+      }
     dependencies:
       wrappy: 1.0.2
     dev: true
 
   /onetime@5.1.2:
-    resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
+      }
+    engines: { node: ">=6" }
     dependencies:
       mimic-fn: 2.1.0
     dev: true
 
   /onetime@6.0.0:
-    resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       mimic-fn: 4.0.0
     dev: true
 
   /open@8.4.2:
-    resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       define-lazy-prop: 2.0.0
       is-docker: 2.2.1
@@ -4555,10 +7347,13 @@ packages:
     dev: true
 
   /optionator@0.9.3:
-    resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==}
-    engines: {node: '>= 0.8.0'}
+    resolution:
+      {
+        integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==
+      }
+    engines: { node: ">= 0.8.0" }
     dependencies:
-      '@aashutoshrathi/word-wrap': 1.2.6
+      "@aashutoshrathi/word-wrap": 1.2.6
       deep-is: 0.1.4
       fast-levenshtein: 2.0.6
       levn: 0.4.1
@@ -4567,167 +7362,248 @@ packages:
     dev: true
 
   /p-limit@2.3.0:
-    resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
+      }
+    engines: { node: ">=6" }
     dependencies:
       p-try: 2.2.0
     dev: true
 
   /p-limit@3.1.0:
-    resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
+      }
+    engines: { node: ">=10" }
     dependencies:
       yocto-queue: 0.1.0
     dev: true
 
   /p-locate@4.1.0:
-    resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
+      }
+    engines: { node: ">=8" }
     dependencies:
       p-limit: 2.3.0
     dev: true
 
   /p-locate@5.0.0:
-    resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
+      }
+    engines: { node: ">=10" }
     dependencies:
       p-limit: 3.1.0
     dev: true
 
   /p-try@2.2.0:
-    resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /parent-module@1.0.1:
-    resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
+      }
+    engines: { node: ">=6" }
     dependencies:
       callsites: 3.1.0
     dev: true
 
   /parse-json@5.2.0:
-    resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
+      }
+    engines: { node: ">=8" }
     dependencies:
-      '@babel/code-frame': 7.22.13
+      "@babel/code-frame": 7.22.13
       error-ex: 1.3.2
       json-parse-even-better-errors: 2.3.1
       lines-and-columns: 1.2.4
     dev: true
 
   /parseurl@1.3.3:
-    resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
-    engines: {node: '>= 0.8'}
+    resolution:
+      {
+        integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
+      }
+    engines: { node: ">= 0.8" }
     dev: true
 
   /path-exists@4.0.0:
-    resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /path-is-absolute@1.0.1:
-    resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /path-key@3.1.1:
-    resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /path-key@4.0.0:
-    resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /path-parse@1.0.7:
-    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+    resolution:
+      {
+        integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+      }
     dev: true
 
   /path-scurry@1.10.1:
-    resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
-    engines: {node: '>=16 || 14 >=14.17'}
+    resolution:
+      {
+        integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==
+      }
+    engines: { node: ">=16 || 14 >=14.17" }
     dependencies:
       lru-cache: 10.0.1
       minipass: 7.0.4
     dev: true
 
   /path-to-regexp@6.2.1:
-    resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==}
+    resolution:
+      {
+        integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==
+      }
     dev: true
 
   /path-type@4.0.0:
-    resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+      }
+    engines: { node: ">=8" }
 
   /path@0.12.7:
-    resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==}
+    resolution:
+      {
+        integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==
+      }
     dependencies:
       process: 0.11.10
       util: 0.10.4
     dev: false
 
   /pathe@1.1.1:
-    resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
+    resolution:
+      {
+        integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /perfect-debounce@1.0.0:
-    resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+    resolution:
+      {
+        integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /picocolors@1.0.0:
-    resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+    resolution:
+      {
+        integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
+      }
 
   /picomatch@2.3.1:
-    resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
-    engines: {node: '>=8.6'}
+    resolution:
+      {
+        integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+      }
+    engines: { node: ">=8.6" }
 
   /pidtree@0.6.0:
-    resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
-    engines: {node: '>=0.10'}
+    resolution:
+      {
+        integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==
+      }
+    engines: { node: ">=0.10" }
     hasBin: true
     dev: true
 
   /pify@2.3.0:
-    resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /pinia@2.1.7(@vue/composition-api@1.7.2)(typescript@5.0.4)(vue@3.3.5):
-    resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==}
+    resolution:
+      {
+        integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
+      }
     peerDependencies:
-      '@vue/composition-api': ^1.4.0
-      typescript: '>=4.4.4'
+      "@vue/composition-api": ^1.4.0
+      typescript: ">=4.4.4"
       vue: ^2.6.14 || ^3.3.0
     peerDependenciesMeta:
-      '@vue/composition-api':
+      "@vue/composition-api":
         optional: true
       typescript:
         optional: true
     dependencies:
-      '@vue/composition-api': 1.7.2(vue@3.3.5)
-      '@vue/devtools-api': 6.5.1
+      "@vue/composition-api": 1.7.2(vue@3.3.5)
+      "@vue/devtools-api": 6.5.1
       typescript: 5.0.4
       vue: 3.3.5(typescript@5.0.4)
       vue-demi: 0.14.6(@vue/composition-api@1.7.2)(vue@3.3.5)
     dev: false
 
   /pinyin-pro@3.17.0:
-    resolution: {integrity: sha512-0R+K1kDl2Fb21nqKjb9hxKHya/fWuOJCSElWqdh17THSL/cgq95PP/QrJINFezFooepCiP+pbUenV2pRloAHHQ==}
+    resolution:
+      {
+        integrity: sha512-0R+K1kDl2Fb21nqKjb9hxKHya/fWuOJCSElWqdh17THSL/cgq95PP/QrJINFezFooepCiP+pbUenV2pRloAHHQ==
+      }
     dev: false
 
   /pirates@4.0.6:
-    resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
+      }
+    engines: { node: ">= 6" }
     dev: true
 
   /pkg-types@1.0.3:
-    resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
+    resolution:
+      {
+        integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==
+      }
     requiresBuild: true
     dependencies:
       jsonc-parser: 3.2.0
@@ -4737,7 +7613,10 @@ packages:
     optional: true
 
   /popmotion@11.0.5:
-    resolution: {integrity: sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==}
+    resolution:
+      {
+        integrity: sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==
+      }
     dependencies:
       framesync: 6.1.2
       hey-listen: 1.0.8
@@ -4746,7 +7625,10 @@ packages:
     dev: false
 
   /postcss-calc@8.2.4(postcss@8.4.31):
-    resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==}
+    resolution:
+      {
+        integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==
+      }
     peerDependencies:
       postcss: ^8.2.2
     dependencies:
@@ -4756,8 +7638,11 @@ packages:
     dev: true
 
   /postcss-calc@9.0.1(postcss@8.4.31):
-    resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.2
     dependencies:
@@ -4767,8 +7652,11 @@ packages:
     dev: true
 
   /postcss-colormin@5.3.1(postcss@8.4.31):
-    resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4780,8 +7668,11 @@ packages:
     dev: true
 
   /postcss-colormin@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4793,8 +7684,11 @@ packages:
     dev: true
 
   /postcss-convert-values@5.1.3(postcss@8.4.31):
-    resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4804,8 +7698,11 @@ packages:
     dev: true
 
   /postcss-convert-values@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4815,8 +7712,11 @@ packages:
     dev: true
 
   /postcss-discard-comments@5.1.2(postcss@8.4.31):
-    resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4824,8 +7724,11 @@ packages:
     dev: true
 
   /postcss-discard-comments@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4833,8 +7736,11 @@ packages:
     dev: true
 
   /postcss-discard-duplicates@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4842,8 +7748,11 @@ packages:
     dev: true
 
   /postcss-discard-duplicates@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4851,8 +7760,11 @@ packages:
     dev: true
 
   /postcss-discard-empty@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4860,8 +7772,11 @@ packages:
     dev: true
 
   /postcss-discard-empty@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4869,8 +7784,11 @@ packages:
     dev: true
 
   /postcss-discard-overridden@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4878,8 +7796,11 @@ packages:
     dev: true
 
   /postcss-discard-overridden@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4887,8 +7808,11 @@ packages:
     dev: true
 
   /postcss-html@1.5.0:
-    resolution: {integrity: sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==}
-    engines: {node: ^12 || >=14}
+    resolution:
+      {
+        integrity: sha512-kCMRWJRHKicpA166kc2lAVUGxDZL324bkj/pVOb6RhjB0Z5Krl7mN0AsVkBhVIRZZirY0lyQXG38HCVaoKVNoA==
+      }
+    engines: { node: ^12 || >=14 }
     dependencies:
       htmlparser2: 8.0.2
       js-tokens: 8.0.2
@@ -4897,7 +7821,10 @@ packages:
     dev: true
 
   /postcss-import-resolver@2.0.0:
-    resolution: {integrity: sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==}
+    resolution:
+      {
+        integrity: sha512-y001XYgGvVwgxyxw9J1a5kqM/vtmIQGzx34g0A0Oy44MFcy/ZboZw1hu/iN3VYFjSTRzbvd7zZJJz0Kh0AGkTw==
+      }
     requiresBuild: true
     dependencies:
       enhanced-resolve: 4.5.0
@@ -4905,8 +7832,11 @@ packages:
     optional: true
 
   /postcss-import@15.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
-    engines: {node: '>=14.0.0'}
+    resolution:
+      {
+        integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==
+      }
+    engines: { node: ">=14.0.0" }
     peerDependencies:
       postcss: ^8.0.0
     dependencies:
@@ -4917,8 +7847,11 @@ packages:
     dev: true
 
   /postcss-js@4.0.1(postcss@8.4.31):
-    resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
-    engines: {node: ^12 || ^14 || >= 16}
+    resolution:
+      {
+        integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
+      }
+    engines: { node: ^12 || ^14 || >= 16 }
     peerDependencies:
       postcss: ^8.4.21
     dependencies:
@@ -4927,11 +7860,14 @@ packages:
     dev: true
 
   /postcss-load-config@4.0.1(postcss@8.4.31)(ts-node@10.9.1):
-    resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
-    engines: {node: '>= 14'}
-    peerDependencies:
-      postcss: '>=8.0.9'
-      ts-node: '>=9.0.0'
+    resolution:
+      {
+        integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==
+      }
+    engines: { node: ">= 14" }
+    peerDependencies:
+      postcss: ">=8.0.9"
+      ts-node: ">=9.0.0"
     peerDependenciesMeta:
       postcss:
         optional: true
@@ -4945,12 +7881,18 @@ packages:
     dev: true
 
   /postcss-media-query-parser@0.2.3:
-    resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
+    resolution:
+      {
+        integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==
+      }
     dev: true
 
   /postcss-merge-longhand@5.1.7(postcss@8.4.31):
-    resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4960,8 +7902,11 @@ packages:
     dev: true
 
   /postcss-merge-longhand@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4971,8 +7916,11 @@ packages:
     dev: true
 
   /postcss-merge-rules@5.1.4(postcss@8.4.31):
-    resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4984,8 +7932,11 @@ packages:
     dev: true
 
   /postcss-merge-rules@6.0.1(postcss@8.4.31):
-    resolution: {integrity: sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -4997,8 +7948,11 @@ packages:
     dev: true
 
   /postcss-minify-font-values@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5007,8 +7961,11 @@ packages:
     dev: true
 
   /postcss-minify-font-values@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5017,8 +7974,11 @@ packages:
     dev: true
 
   /postcss-minify-gradients@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5029,8 +7989,11 @@ packages:
     dev: true
 
   /postcss-minify-gradients@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5041,8 +8004,11 @@ packages:
     dev: true
 
   /postcss-minify-params@5.1.4(postcss@8.4.31):
-    resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5053,8 +8019,11 @@ packages:
     dev: true
 
   /postcss-minify-params@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5065,8 +8034,11 @@ packages:
     dev: true
 
   /postcss-minify-selectors@5.2.1(postcss@8.4.31):
-    resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5075,8 +8047,11 @@ packages:
     dev: true
 
   /postcss-minify-selectors@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5085,8 +8060,11 @@ packages:
     dev: true
 
   /postcss-nested@6.0.1(postcss@8.4.31):
-    resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
-    engines: {node: '>=12.0'}
+    resolution:
+      {
+        integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==
+      }
+    engines: { node: ">=12.0" }
     peerDependencies:
       postcss: ^8.2.14
     dependencies:
@@ -5095,8 +8073,11 @@ packages:
     dev: true
 
   /postcss-normalize-charset@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5104,8 +8085,11 @@ packages:
     dev: true
 
   /postcss-normalize-charset@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5113,8 +8097,11 @@ packages:
     dev: true
 
   /postcss-normalize-display-values@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5123,8 +8110,11 @@ packages:
     dev: true
 
   /postcss-normalize-display-values@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5133,8 +8123,11 @@ packages:
     dev: true
 
   /postcss-normalize-positions@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5143,8 +8136,11 @@ packages:
     dev: true
 
   /postcss-normalize-positions@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5153,8 +8149,11 @@ packages:
     dev: true
 
   /postcss-normalize-repeat-style@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5163,8 +8162,11 @@ packages:
     dev: true
 
   /postcss-normalize-repeat-style@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5173,8 +8175,11 @@ packages:
     dev: true
 
   /postcss-normalize-string@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5183,8 +8188,11 @@ packages:
     dev: true
 
   /postcss-normalize-string@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5193,8 +8201,11 @@ packages:
     dev: true
 
   /postcss-normalize-timing-functions@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5203,8 +8214,11 @@ packages:
     dev: true
 
   /postcss-normalize-timing-functions@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5213,8 +8227,11 @@ packages:
     dev: true
 
   /postcss-normalize-unicode@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5224,8 +8241,11 @@ packages:
     dev: true
 
   /postcss-normalize-unicode@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5235,8 +8255,11 @@ packages:
     dev: true
 
   /postcss-normalize-url@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5246,8 +8269,11 @@ packages:
     dev: true
 
   /postcss-normalize-url@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5256,8 +8282,11 @@ packages:
     dev: true
 
   /postcss-normalize-whitespace@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5266,8 +8295,11 @@ packages:
     dev: true
 
   /postcss-normalize-whitespace@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5276,8 +8308,11 @@ packages:
     dev: true
 
   /postcss-ordered-values@5.1.3(postcss@8.4.31):
-    resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5287,8 +8322,11 @@ packages:
     dev: true
 
   /postcss-ordered-values@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5298,8 +8336,11 @@ packages:
     dev: true
 
   /postcss-reduce-initial@5.1.2(postcss@8.4.31):
-    resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5309,8 +8350,11 @@ packages:
     dev: true
 
   /postcss-reduce-initial@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5320,8 +8364,11 @@ packages:
     dev: true
 
   /postcss-reduce-transforms@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5330,8 +8377,11 @@ packages:
     dev: true
 
   /postcss-reduce-transforms@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5340,12 +8390,18 @@ packages:
     dev: true
 
   /postcss-resolve-nested-selector@0.1.1:
-    resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==}
+    resolution:
+      {
+        integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==
+      }
     dev: true
 
   /postcss-safe-parser@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==}
-    engines: {node: '>=12.0'}
+    resolution:
+      {
+        integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
+      }
+    engines: { node: ">=12.0" }
     peerDependencies:
       postcss: ^8.3.3
     dependencies:
@@ -5353,8 +8409,11 @@ packages:
     dev: true
 
   /postcss-scss@4.0.9(postcss@8.4.31):
-    resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==}
-    engines: {node: '>=12.0'}
+    resolution:
+      {
+        integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==
+      }
+    engines: { node: ">=12.0" }
     peerDependencies:
       postcss: ^8.4.29
     dependencies:
@@ -5362,15 +8421,21 @@ packages:
     dev: true
 
   /postcss-selector-parser@6.0.13:
-    resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==
+      }
+    engines: { node: ">=4" }
     dependencies:
       cssesc: 3.0.0
       util-deprecate: 1.0.2
     dev: true
 
   /postcss-sorting@8.0.2(postcss@8.4.31):
-    resolution: {integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==}
+    resolution:
+      {
+        integrity: sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==
+      }
     peerDependencies:
       postcss: ^8.4.20
     dependencies:
@@ -5378,8 +8443,11 @@ packages:
     dev: true
 
   /postcss-svgo@5.1.0(postcss@8.4.31):
-    resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5389,8 +8457,11 @@ packages:
     dev: true
 
   /postcss-svgo@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw==}
-    engines: {node: ^14 || ^16 || >= 18}
+    resolution:
+      {
+        integrity: sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw==
+      }
+    engines: { node: ^14 || ^16 || >= 18 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5400,8 +8471,11 @@ packages:
     dev: true
 
   /postcss-unique-selectors@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5410,8 +8484,11 @@ packages:
     dev: true
 
   /postcss-unique-selectors@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -5420,41 +8497,66 @@ packages:
     dev: true
 
   /postcss-value-parser@4.2.0:
-    resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+    resolution:
+      {
+        integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
+      }
     dev: true
 
   /postcss@8.4.31:
-    resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
-    engines: {node: ^10 || ^12 || >=14}
+    resolution:
+      {
+        integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
+      }
+    engines: { node: ^10 || ^12 || >=14 }
     dependencies:
       nanoid: 3.3.6
       picocolors: 1.0.0
       source-map-js: 1.0.2
 
+  /preact@10.19.2:
+    resolution:
+      {
+        integrity: sha512-UA9DX/OJwv6YwP9Vn7Ti/vF80XL+YA5H2l7BpCtUr3ya8LWHFzpiO5R+N7dN16ujpIxhekRFuOOF82bXX7K/lg==
+      }
+    dev: false
+
   /prelude-ls@1.2.1:
-    resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
-    engines: {node: '>= 0.8.0'}
+    resolution:
+      {
+        integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+      }
+    engines: { node: ">= 0.8.0" }
     dev: true
 
   /prettier-linter-helpers@1.0.0:
-    resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
-    engines: {node: '>=6.0.0'}
+    resolution:
+      {
+        integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
+      }
+    engines: { node: ">=6.0.0" }
     dependencies:
       fast-diff: 1.3.0
     dev: true
 
   /prettier@2.8.8:
-    resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
-    engines: {node: '>=10.13.0'}
+    resolution:
+      {
+        integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
+      }
+    engines: { node: ">=10.13.0" }
     hasBin: true
     dev: true
 
   /pretty-quick@3.1.3(prettier@2.8.8):
-    resolution: {integrity: sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==}
-    engines: {node: '>=10.13'}
+    resolution:
+      {
+        integrity: sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==
+      }
+    engines: { node: ">=10.13" }
     hasBin: true
     peerDependencies:
-      prettier: '>=2.0.0'
+      prettier: ">=2.0.0"
     dependencies:
       chalk: 3.0.0
       execa: 4.1.0
@@ -5465,61 +8567,114 @@ packages:
       prettier: 2.8.8
     dev: true
 
+  /prismjs@1.29.0:
+    resolution:
+      {
+        integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==
+      }
+    engines: { node: ">=6" }
+    dev: false
+
+  /probe.gl@3.6.0:
+    resolution:
+      {
+        integrity: sha512-19JydJWI7+DtR4feV+pu4Mn1I5TAc0xojuxVgZdXIyfmTLfUaFnk4OloWK1bKbPtkgGKLr2lnbnCXmpZEcEp9g==
+      }
+    dependencies:
+      "@babel/runtime": 7.23.2
+      "@probe.gl/env": 3.6.0
+      "@probe.gl/log": 3.6.0
+      "@probe.gl/stats": 3.6.0
+    dev: false
+
   /process-nextick-args@2.0.1:
-    resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+    resolution:
+      {
+        integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /process@0.11.10:
-    resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
-    engines: {node: '>= 0.6.0'}
+    resolution:
+      {
+        integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
+      }
+    engines: { node: ">= 0.6.0" }
     dev: false
 
   /proxy-from-env@1.1.0:
-    resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+    resolution:
+      {
+        integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
+      }
     dev: false
 
   /prr@1.0.1:
-    resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==}
+    resolution:
+      {
+        integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /pump@3.0.0:
-    resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
+    resolution:
+      {
+        integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
+      }
     dependencies:
       end-of-stream: 1.4.4
       once: 1.4.0
     dev: true
 
   /punycode@2.3.0:
-    resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /qs@6.11.2:
-    resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==}
-    engines: {node: '>=0.6'}
+    resolution:
+      {
+        integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==
+      }
+    engines: { node: ">=0.6" }
     dependencies:
       side-channel: 1.0.4
     dev: false
 
   /queue-microtask@1.2.3:
-    resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+    resolution:
+      {
+        integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+      }
 
   /quick-lru@4.0.1:
-    resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /quick-lru@5.1.1:
-    resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /rc9@2.1.1:
-    resolution: {integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==}
+    resolution:
+      {
+        integrity: sha512-lNeOl38Ws0eNxpO3+wD1I9rkHGQyj1NU1jlzv4go2CtEnEQEUfqnIvZG7W+bC/aXdJ27n5x/yUjb6RoT9tko+Q==
+      }
     requiresBuild: true
     dependencies:
       defu: 6.1.2
@@ -5529,14 +8684,20 @@ packages:
     optional: true
 
   /read-cache@1.0.0:
-    resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+    resolution:
+      {
+        integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==
+      }
     dependencies:
       pify: 2.3.0
     dev: true
 
   /read-pkg-up@7.0.1:
-    resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==
+      }
+    engines: { node: ">=8" }
     dependencies:
       find-up: 4.1.0
       read-pkg: 5.2.0
@@ -5544,8 +8705,11 @@ packages:
     dev: true
 
   /read-pkg-up@8.0.0:
-    resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       find-up: 5.0.0
       read-pkg: 6.0.0
@@ -5553,27 +8717,36 @@ packages:
     dev: true
 
   /read-pkg@5.2.0:
-    resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==
+      }
+    engines: { node: ">=8" }
     dependencies:
-      '@types/normalize-package-data': 2.4.3
+      "@types/normalize-package-data": 2.4.3
       normalize-package-data: 2.5.0
       parse-json: 5.2.0
       type-fest: 0.6.0
     dev: true
 
   /read-pkg@6.0.0:
-    resolution: {integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==
+      }
+    engines: { node: ">=12" }
     dependencies:
-      '@types/normalize-package-data': 2.4.3
+      "@types/normalize-package-data": 2.4.3
       normalize-package-data: 3.0.3
       parse-json: 5.2.0
       type-fest: 1.4.0
     dev: true
 
   /readable-stream@2.3.8:
-    resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
+    resolution:
+      {
+        integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+      }
     requiresBuild: true
     dependencies:
       core-util-is: 1.0.3
@@ -5587,8 +8760,11 @@ packages:
     optional: true
 
   /readable-stream@3.6.2:
-    resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
+      }
+    engines: { node: ">= 6" }
     dependencies:
       inherits: 2.0.4
       string_decoder: 1.3.0
@@ -5596,72 +8772,122 @@ packages:
     dev: true
 
   /readdirp@3.6.0:
-    resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
-    engines: {node: '>=8.10.0'}
+    resolution:
+      {
+        integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+      }
+    engines: { node: ">=8.10.0" }
     dependencies:
       picomatch: 2.3.1
 
   /recorder-js@1.0.7:
-    resolution: {integrity: sha512-jSG4GP1FUV9vGxY9lrvaI2yGq1OwfIvK8MF8qPndODhkwGx+iPBTG7ZhWK8YHt/zT/c88MmFZCntv9G7x1Exxg==}
+    resolution:
+      {
+        integrity: sha512-jSG4GP1FUV9vGxY9lrvaI2yGq1OwfIvK8MF8qPndODhkwGx+iPBTG7ZhWK8YHt/zT/c88MmFZCntv9G7x1Exxg==
+      }
     dependencies:
       inline-worker: 1.1.0
     dev: false
 
   /recorderx@2.0.2:
-    resolution: {integrity: sha512-Np/Ab+9THHbqke5Qn/7ujWU40xT3g7Ir9F7tmL/YIJmzAgmx24kL7OmjcUKRpploxUWJe+3a2QL6xkLVBdCHjQ==}
+    resolution:
+      {
+        integrity: sha512-Np/Ab+9THHbqke5Qn/7ujWU40xT3g7Ir9F7tmL/YIJmzAgmx24kL7OmjcUKRpploxUWJe+3a2QL6xkLVBdCHjQ==
+      }
     dependencies:
-      '@babel/runtime': 7.23.2
+      "@babel/runtime": 7.23.2
     dev: false
 
   /redent@3.0.0:
-    resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==
+      }
+    engines: { node: ">=8" }
     dependencies:
       indent-string: 4.0.0
       strip-indent: 3.0.0
     dev: true
 
   /redent@4.0.0:
-    resolution: {integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==
+      }
+    engines: { node: ">=12" }
     dependencies:
       indent-string: 5.0.0
       strip-indent: 4.0.0
     dev: true
 
   /regenerator-runtime@0.14.0:
-    resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
+    resolution:
+      {
+        integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
+      }
+    dev: false
+
+  /regl@1.7.0:
+    resolution:
+      {
+        integrity: sha512-bEAtp/qrtKucxXSJkD4ebopFZYP0q1+3Vb2WECWv/T8yQEgKxDxJ7ztO285tAMaYZVR6mM1GgI6CCn8FROtL1w==
+      }
     dev: false
 
   /require-directory@2.1.1:
-    resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /require-from-string@2.0.2:
-    resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
+  /resize-detector@0.3.0:
+    resolution:
+      {
+        integrity: sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==
+      }
+    dev: false
+
   /resolve-from@4.0.0:
-    resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
+      }
+    engines: { node: ">=4" }
     dev: true
 
   /resolve-from@5.0.0:
-    resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /resolve-global@1.0.0:
-    resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==
+      }
+    engines: { node: ">=8" }
     dependencies:
       global-dirs: 0.1.1
     dev: true
 
   /resolve@1.22.8:
-    resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+    resolution:
+      {
+        integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
+      }
     hasBin: true
     dependencies:
       is-core-module: 2.13.0
@@ -5670,57 +8896,81 @@ packages:
     dev: true
 
   /responsive-storage@2.2.0:
-    resolution: {integrity: sha512-94W5Chr2F5kDBT6J+OCOeJguEkSTDc3jPOUQXYmzNG64DCNl5p7hoBDF7bx7u6EXAEcpUKF64OZR4b7Nn8h/Gg==}
+    resolution:
+      {
+        integrity: sha512-94W5Chr2F5kDBT6J+OCOeJguEkSTDc3jPOUQXYmzNG64DCNl5p7hoBDF7bx7u6EXAEcpUKF64OZR4b7Nn8h/Gg==
+      }
     dev: false
 
   /restore-cursor@4.0.0:
-    resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
-    engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==
+      }
+    engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 }
     dependencies:
       onetime: 5.1.2
       signal-exit: 3.0.7
     dev: true
 
   /reusify@1.0.4:
-    resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
-    engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
+      }
+    engines: { iojs: ">=1.0.0", node: ">=0.10.0" }
 
   /rfdc@1.3.0:
-    resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==}
+    resolution:
+      {
+        integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
+      }
     dev: true
 
   /rimraf@3.0.2:
-    resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+    resolution:
+      {
+        integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
+      }
     hasBin: true
     dependencies:
       glob: 7.2.3
     dev: true
 
   /rimraf@5.0.5:
-    resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==
+      }
+    engines: { node: ">=14" }
     hasBin: true
     dependencies:
       glob: 10.3.10
     dev: true
 
   /rollup-plugin-external-globals@0.6.1:
-    resolution: {integrity: sha512-mlp3KNa5sE4Sp9UUR2rjBrxjG79OyZAh/QC18RHIjM+iYkbBwNXSo8DHRMZWtzJTrH8GxQ+SJvCTN3i14uMXIA==}
+    resolution:
+      {
+        integrity: sha512-mlp3KNa5sE4Sp9UUR2rjBrxjG79OyZAh/QC18RHIjM+iYkbBwNXSo8DHRMZWtzJTrH8GxQ+SJvCTN3i14uMXIA==
+      }
     peerDependencies:
       rollup: ^2.25.0
     peerDependenciesMeta:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 4.2.1
+      "@rollup/pluginutils": 4.2.1
       estree-walker: 2.0.2
       is-reference: 1.2.1
       magic-string: 0.25.9
     dev: true
 
   /rollup-plugin-visualizer@5.9.2:
-    resolution: {integrity: sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-waHktD5mlWrYFrhOLbti4YgQCn1uR24nYsNuXxg7LkPH8KdTXVWR9DNY1WU0QqokyMixVXJS4J04HNrVTMP01A==
+      }
+    engines: { node: ">=14" }
     hasBin: true
     peerDependencies:
       rollup: 2.x || 3.x
@@ -5735,36 +8985,51 @@ packages:
     dev: true
 
   /rollup@3.29.4:
-    resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
-    engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+    resolution:
+      {
+        integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
+      }
+    engines: { node: ">=14.18.0", npm: ">=8.0.0" }
     hasBin: true
     optionalDependencies:
       fsevents: 2.3.3
     dev: true
 
   /run-parallel@1.2.0:
-    resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+    resolution:
+      {
+        integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
+      }
     dependencies:
       queue-microtask: 1.2.3
 
   /safe-buffer@5.1.2:
-    resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
+    resolution:
+      {
+        integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /safe-buffer@5.2.1:
-    resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+    resolution:
+      {
+        integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+      }
     dev: true
 
   /sass-loader@13.3.2(sass@1.69.4):
-    resolution: {integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==}
-    engines: {node: '>= 14.15.0'}
+    resolution:
+      {
+        integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==
+      }
+    engines: { node: ">= 14.15.0" }
     peerDependencies:
-      fibers: '>= 3.1.0'
+      fibers: ">= 3.1.0"
       node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
       sass: ^1.3.0
-      sass-embedded: '*'
+      sass-embedded: "*"
       webpack: ^5.0.0
     peerDependenciesMeta:
       fibers:
@@ -5783,8 +9048,11 @@ packages:
     dev: true
 
   /sass@1.69.4:
-    resolution: {integrity: sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==}
-    engines: {node: '>=14.0.0'}
+    resolution:
+      {
+        integrity: sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==
+      }
+    engines: { node: ">=14.0.0" }
     hasBin: true
     dependencies:
       chokidar: 3.5.3
@@ -5792,31 +9060,55 @@ packages:
       source-map-js: 1.0.2
     dev: true
 
+  /scroll-into-view-if-needed@2.2.31:
+    resolution:
+      {
+        integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==
+      }
+    dependencies:
+      compute-scroll-into-view: 1.0.20
+    dev: false
+
   /scule@1.0.0:
-    resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==}
+    resolution:
+      {
+        integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /semver@5.7.2:
-    resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
+    resolution:
+      {
+        integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
+      }
     hasBin: true
     dev: true
 
   /semver@6.3.1:
-    resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+    resolution:
+      {
+        integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
+      }
     hasBin: true
 
   /semver@7.5.4:
-    resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
+      }
+    engines: { node: ">=10" }
     hasBin: true
     dependencies:
       lru-cache: 6.0.0
 
   /set-function-length@1.1.1:
-    resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==}
-    engines: {node: '>= 0.4'}
+    resolution:
+      {
+        integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==
+      }
+    engines: { node: ">= 0.4" }
     dependencies:
       define-data-property: 1.1.1
       get-intrinsic: 1.2.1
@@ -5825,19 +9117,28 @@ packages:
     dev: false
 
   /shebang-command@2.0.0:
-    resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+      }
+    engines: { node: ">=8" }
     dependencies:
       shebang-regex: 3.0.0
     dev: true
 
   /shebang-regex@3.0.0:
-    resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /side-channel@1.0.4:
-    resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
+    resolution:
+      {
+        integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
+      }
     dependencies:
       call-bind: 1.0.5
       get-intrinsic: 1.2.1
@@ -5845,35 +9146,75 @@ packages:
     dev: false
 
   /signal-exit@3.0.7:
-    resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+    resolution:
+      {
+        integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+      }
     dev: true
 
   /signal-exit@4.1.0:
-    resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
-    engines: {node: '>=14'}
+    resolution:
+      {
+        integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
+      }
+    engines: { node: ">=14" }
     dev: true
 
   /simple-swizzle@0.2.2:
-    resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+    resolution:
+      {
+        integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==
+      }
     dependencies:
       is-arrayish: 0.3.2
-    dev: true
 
   /slash@3.0.0:
-    resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /slash@4.0.0:
-    resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
+      }
+    engines: { node: ">=12" }
     requiresBuild: true
     dev: false
     optional: true
 
+  /slate-history@0.66.0(slate@0.72.8):
+    resolution:
+      {
+        integrity: sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==
+      }
+    peerDependencies:
+      slate: ">=0.65.3"
+    dependencies:
+      is-plain-object: 5.0.0
+      slate: 0.72.8
+    dev: false
+
+  /slate@0.72.8:
+    resolution:
+      {
+        integrity: sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==
+      }
+    dependencies:
+      immer: 9.0.21
+      is-plain-object: 5.0.0
+      tiny-warning: 1.0.3
+    dev: false
+
   /slice-ansi@4.0.0:
-    resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==
+      }
+    engines: { node: ">=10" }
     dependencies:
       ansi-styles: 4.3.0
       astral-regex: 2.0.0
@@ -5881,99 +9222,168 @@ packages:
     dev: true
 
   /slice-ansi@5.0.0:
-    resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       ansi-styles: 6.2.1
       is-fullwidth-code-point: 4.0.0
     dev: true
 
+  /snabbdom@3.5.1:
+    resolution:
+      {
+        integrity: sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA==
+      }
+    engines: { node: ">=8.3.0" }
+    dev: false
+
   /sortablejs@1.15.0:
-    resolution: {integrity: sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==}
+    resolution:
+      {
+        integrity: sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==
+      }
     dev: false
 
   /source-map-js@1.0.2:
-    resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+      }
+    engines: { node: ">=0.10.0" }
 
   /source-map-support@0.5.21:
-    resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+    resolution:
+      {
+        integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
+      }
     dependencies:
       buffer-from: 1.1.2
       source-map: 0.6.1
     dev: true
 
   /source-map@0.6.1:
-    resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
-    engines: {node: '>=0.10.0'}
+    resolution:
+      {
+        integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+      }
+    engines: { node: ">=0.10.0" }
     dev: true
 
   /source-map@0.7.4:
-    resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==
+      }
+    engines: { node: ">= 8" }
     dev: true
 
   /sourcemap-codec@1.4.8:
-    resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
+    resolution:
+      {
+        integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
+      }
     deprecated: Please use @jridgewell/sourcemap-codec instead
     dev: true
 
   /spdx-correct@3.2.0:
-    resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
+    resolution:
+      {
+        integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==
+      }
     dependencies:
       spdx-expression-parse: 3.0.1
       spdx-license-ids: 3.0.16
     dev: true
 
   /spdx-exceptions@2.3.0:
-    resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==}
+    resolution:
+      {
+        integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
+      }
     dev: true
 
   /spdx-expression-parse@3.0.1:
-    resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
+    resolution:
+      {
+        integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
+      }
     dependencies:
       spdx-exceptions: 2.3.0
       spdx-license-ids: 3.0.16
     dev: true
 
   /spdx-license-ids@3.0.16:
-    resolution: {integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==}
+    resolution:
+      {
+        integrity: sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==
+      }
     dev: true
 
   /split2@3.2.2:
-    resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==}
+    resolution:
+      {
+        integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==
+      }
     dependencies:
       readable-stream: 3.6.2
     dev: true
 
+  /ssr-window@3.0.0:
+    resolution:
+      {
+        integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==
+      }
+    dev: false
+
   /stable@0.1.8:
-    resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
-    deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
+    resolution:
+      {
+        integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
+      }
+    deprecated: "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility"
     dev: true
 
   /statuses@1.5.0:
-    resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
-    engines: {node: '>= 0.6'}
+    resolution:
+      {
+        integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
+      }
+    engines: { node: ">= 0.6" }
     dev: true
 
   /std-env@3.4.3:
-    resolution: {integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==}
+    resolution:
+      {
+        integrity: sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /string-argv@0.3.2:
-    resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
-    engines: {node: '>=0.6.19'}
+    resolution:
+      {
+        integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
+      }
+    engines: { node: ">=0.6.19" }
     dev: true
 
   /string-hash@1.1.3:
-    resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==}
+    resolution:
+      {
+        integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==
+      }
     dev: true
 
   /string-width@4.2.3:
-    resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+      }
+    engines: { node: ">=8" }
     dependencies:
       emoji-regex: 8.0.0
       is-fullwidth-code-point: 3.0.0
@@ -5981,8 +9391,11 @@ packages:
     dev: true
 
   /string-width@5.1.2:
-    resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
+      }
+    engines: { node: ">=12" }
     dependencies:
       eastasianwidth: 0.2.0
       emoji-regex: 9.2.2
@@ -5990,7 +9403,10 @@ packages:
     dev: true
 
   /string_decoder@1.1.1:
-    resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
+    resolution:
+      {
+        integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+      }
     requiresBuild: true
     dependencies:
       safe-buffer: 5.1.2
@@ -5998,56 +9414,83 @@ packages:
     optional: true
 
   /string_decoder@1.3.0:
-    resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+    resolution:
+      {
+        integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+      }
     dependencies:
       safe-buffer: 5.2.1
     dev: true
 
   /strip-ansi@6.0.1:
-    resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+      }
+    engines: { node: ">=8" }
     dependencies:
       ansi-regex: 5.0.1
     dev: true
 
   /strip-ansi@7.1.0:
-    resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       ansi-regex: 6.0.1
     dev: true
 
   /strip-final-newline@2.0.0:
-    resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /strip-final-newline@3.0.0:
-    resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /strip-indent@3.0.0:
-    resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==
+      }
+    engines: { node: ">=8" }
     dependencies:
       min-indent: 1.0.1
     dev: true
 
   /strip-indent@4.0.0:
-    resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==
+      }
+    engines: { node: ">=12" }
     dependencies:
       min-indent: 1.0.1
     dev: true
 
   /strip-json-comments@3.1.1:
-    resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /strip-literal@1.3.0:
-    resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
+    resolution:
+      {
+        integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==
+      }
     requiresBuild: true
     dependencies:
       acorn: 8.10.0
@@ -6055,19 +9498,28 @@ packages:
     optional: true
 
   /style-search@0.1.0:
-    resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==}
+    resolution:
+      {
+        integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==
+      }
     dev: true
 
   /style-value-types@5.1.2:
-    resolution: {integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==}
+    resolution:
+      {
+        integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==
+      }
     dependencies:
       hey-listen: 1.0.8
       tslib: 2.4.0
     dev: false
 
   /stylehacks@5.1.1(postcss@8.4.31):
-    resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==}
-    engines: {node: ^10 || ^12 || >=14.0}
+    resolution:
+      {
+        integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==
+      }
+    engines: { node: ^10 || ^12 || >=14.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -6077,8 +9529,11 @@ packages:
     dev: true
 
   /stylehacks@6.0.0(postcss@8.4.31):
-    resolution: {integrity: sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw==}
-    engines: {node: ^14 || ^16 || >=18.0}
+    resolution:
+      {
+        integrity: sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw==
+      }
+    engines: { node: ^14 || ^16 || >=18.0 }
     peerDependencies:
       postcss: ^8.2.15
     dependencies:
@@ -6088,27 +9543,36 @@ packages:
     dev: true
 
   /stylelint-config-html@1.1.0(postcss-html@1.5.0)(stylelint@15.11.0):
-    resolution: {integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==}
-    engines: {node: ^12 || >=14}
+    resolution:
+      {
+        integrity: sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==
+      }
+    engines: { node: ^12 || >=14 }
     peerDependencies:
       postcss-html: ^1.0.0
-      stylelint: '>=14.0.0'
+      stylelint: ">=14.0.0"
     dependencies:
       postcss-html: 1.5.0
       stylelint: 15.11.0(typescript@5.0.4)
     dev: true
 
   /stylelint-config-recess-order@4.3.0(stylelint@15.11.0):
-    resolution: {integrity: sha512-EWVtxZ8oq4/meTrRNUDrS5TqMz6TX72JjKDwVQq0JJDXE+P/o7UuFw3wWV/0O9yvJfh/da6nJY71ZUn/wSfB4g==}
+    resolution:
+      {
+        integrity: sha512-EWVtxZ8oq4/meTrRNUDrS5TqMz6TX72JjKDwVQq0JJDXE+P/o7UuFw3wWV/0O9yvJfh/da6nJY71ZUn/wSfB4g==
+      }
     peerDependencies:
-      stylelint: '>=15'
+      stylelint: ">=15"
     dependencies:
       stylelint: 15.11.0(typescript@5.0.4)
       stylelint-order: 6.0.3(stylelint@15.11.0)
     dev: true
 
   /stylelint-config-recommended-scss@11.0.0(postcss@8.4.31)(stylelint@15.11.0):
-    resolution: {integrity: sha512-EDghTDU7aOv2LTsRZvcT1w8mcjUaMhuy+t38iV5I/0Qiu6ixdkRwhLEMul3K/fnB2v9Nwqvb3xpvJfPH+HduDw==}
+    resolution:
+      {
+        integrity: sha512-EDghTDU7aOv2LTsRZvcT1w8mcjUaMhuy+t38iV5I/0Qiu6ixdkRwhLEMul3K/fnB2v9Nwqvb3xpvJfPH+HduDw==
+      }
     peerDependencies:
       postcss: ^8.3.3
       stylelint: ^15.5.0
@@ -6124,7 +9588,10 @@ packages:
     dev: true
 
   /stylelint-config-recommended-scss@12.0.0(postcss@8.4.31)(stylelint@15.11.0):
-    resolution: {integrity: sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA==}
+    resolution:
+      {
+        integrity: sha512-5Bb2mlGy6WLa30oNeKpZvavv2lowJUsUJO25+OA68GFTemlwd1zbFsL7q0bReKipOSU3sG47hKneZ6Nd+ctrFA==
+      }
     peerDependencies:
       postcss: ^8.3.3
       stylelint: ^15.5.0
@@ -6140,11 +9607,14 @@ packages:
     dev: true
 
   /stylelint-config-recommended-vue@1.5.0(postcss-html@1.5.0)(stylelint@15.11.0):
-    resolution: {integrity: sha512-65TAK/clUqkNtkZLcuytoxU0URQYlml+30Nhop7sRkCZ/mtWdXt7T+spPSB3KMKlb+82aEVJ4OrcstyDBdbosg==}
-    engines: {node: ^12 || >=14}
+    resolution:
+      {
+        integrity: sha512-65TAK/clUqkNtkZLcuytoxU0URQYlml+30Nhop7sRkCZ/mtWdXt7T+spPSB3KMKlb+82aEVJ4OrcstyDBdbosg==
+      }
+    engines: { node: ^12 || >=14 }
     peerDependencies:
       postcss-html: ^1.0.0
-      stylelint: '>=14.0.0'
+      stylelint: ">=14.0.0"
     dependencies:
       postcss-html: 1.5.0
       semver: 7.5.4
@@ -6154,7 +9624,10 @@ packages:
     dev: true
 
   /stylelint-config-recommended@12.0.0(stylelint@15.11.0):
-    resolution: {integrity: sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==}
+    resolution:
+      {
+        integrity: sha512-x6x8QNARrGO2sG6iURkzqL+Dp+4bJorPMMRNPScdvaUK8PsynriOcMW7AFDKqkWAS5wbue/u8fUT/4ynzcmqdQ==
+      }
     peerDependencies:
       stylelint: ^15.5.0
     dependencies:
@@ -6162,7 +9635,10 @@ packages:
     dev: true
 
   /stylelint-config-standard-scss@9.0.0(postcss@8.4.31)(stylelint@15.11.0):
-    resolution: {integrity: sha512-yPKpJsrZn4ybuQZx/DkEHuCjw7pJginErE/47dFhCnrvD48IJ4UYec8tSiCuJWMA3HRjbIa3nh5ZeSauDGuVAg==}
+    resolution:
+      {
+        integrity: sha512-yPKpJsrZn4ybuQZx/DkEHuCjw7pJginErE/47dFhCnrvD48IJ4UYec8tSiCuJWMA3HRjbIa3nh5ZeSauDGuVAg==
+      }
     peerDependencies:
       postcss: ^8.3.3
       stylelint: ^15.5.0
@@ -6177,7 +9653,10 @@ packages:
     dev: true
 
   /stylelint-config-standard@33.0.0(stylelint@15.11.0):
-    resolution: {integrity: sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==}
+    resolution:
+      {
+        integrity: sha512-eyxnLWoXImUn77+ODIuW9qXBDNM+ALN68L3wT1lN2oNspZ7D9NVGlNHb2QCUn4xDug6VZLsh0tF8NyoYzkgTzg==
+      }
     peerDependencies:
       stylelint: ^15.5.0
     dependencies:
@@ -6186,7 +9665,10 @@ packages:
     dev: true
 
   /stylelint-order@6.0.3(stylelint@15.11.0):
-    resolution: {integrity: sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==}
+    resolution:
+      {
+        integrity: sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==
+      }
     peerDependencies:
       stylelint: ^14.0.0 || ^15.0.0
     dependencies:
@@ -6196,11 +9678,14 @@ packages:
     dev: true
 
   /stylelint-prettier@3.0.0(prettier@2.8.8)(stylelint@15.11.0):
-    resolution: {integrity: sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==}
-    engines: {node: ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-kIks1xw6np0zElokMT2kP6ar3S4MBoj6vUtPJuND1pFELMpZxVS/0uHPR4HDAVn0WAD3I5oF0IA3qBFxBpMkLg==
+      }
+    engines: { node: ^14.17.0 || >=16.0.0 }
     peerDependencies:
-      prettier: '>=2.0.0'
-      stylelint: '>=14.0.0'
+      prettier: ">=2.0.0"
+      stylelint: ">=14.0.0"
     dependencies:
       prettier: 2.8.8
       prettier-linter-helpers: 1.0.0
@@ -6208,7 +9693,10 @@ packages:
     dev: true
 
   /stylelint-scss@4.7.0(stylelint@15.11.0):
-    resolution: {integrity: sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==}
+    resolution:
+      {
+        integrity: sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==
+      }
     peerDependencies:
       stylelint: ^14.5.1 || ^15.0.0
     dependencies:
@@ -6220,7 +9708,10 @@ packages:
     dev: true
 
   /stylelint-scss@5.2.1(stylelint@15.11.0):
-    resolution: {integrity: sha512-ZoTJUM85/qqpQHfEppjW/St//8s6p9Qsg8deWlYlr56F9iUgC9vXeIDQvH4odkRRJLTLFQzYMALSOFCQ3MDkgw==}
+    resolution:
+      {
+        integrity: sha512-ZoTJUM85/qqpQHfEppjW/St//8s6p9Qsg8deWlYlr56F9iUgC9vXeIDQvH4odkRRJLTLFQzYMALSOFCQ3MDkgw==
+      }
     peerDependencies:
       stylelint: ^14.5.1 || ^15.0.0
     dependencies:
@@ -6233,14 +9724,17 @@ packages:
     dev: true
 
   /stylelint@15.11.0(typescript@5.0.4):
-    resolution: {integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==}
-    engines: {node: ^14.13.1 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==
+      }
+    engines: { node: ^14.13.1 || >=16.0.0 }
     hasBin: true
     dependencies:
-      '@csstools/css-parser-algorithms': 2.3.2(@csstools/css-tokenizer@2.2.1)
-      '@csstools/css-tokenizer': 2.2.1
-      '@csstools/media-query-list-parser': 2.1.5(@csstools/css-parser-algorithms@2.3.2)(@csstools/css-tokenizer@2.2.1)
-      '@csstools/selector-specificity': 3.0.0(postcss-selector-parser@6.0.13)
+      "@csstools/css-parser-algorithms": 2.3.2(@csstools/css-tokenizer@2.2.1)
+      "@csstools/css-tokenizer": 2.2.1
+      "@csstools/media-query-list-parser": 2.1.5(@csstools/css-parser-algorithms@2.3.2)(@csstools/css-tokenizer@2.2.1)
+      "@csstools/selector-specificity": 3.0.0(postcss-selector-parser@6.0.13)
       balanced-match: 2.0.0
       colord: 2.9.3
       cosmiconfig: 8.3.6(typescript@5.0.4)
@@ -6283,11 +9777,14 @@ packages:
     dev: true
 
   /sucrase@3.34.0:
-    resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==
+      }
+    engines: { node: ">=8" }
     hasBin: true
     dependencies:
-      '@jridgewell/gen-mapping': 0.3.3
+      "@jridgewell/gen-mapping": 0.3.3
       commander: 4.1.1
       glob: 7.1.6
       lines-and-columns: 1.2.4
@@ -6297,41 +9794,59 @@ packages:
     dev: true
 
   /supports-color@5.5.0:
-    resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+      }
+    engines: { node: ">=4" }
     dependencies:
       has-flag: 3.0.0
 
   /supports-color@7.2.0:
-    resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+      }
+    engines: { node: ">=8" }
     dependencies:
       has-flag: 4.0.0
     dev: true
 
   /supports-hyperlinks@3.0.0:
-    resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==}
-    engines: {node: '>=14.18'}
+    resolution:
+      {
+        integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==
+      }
+    engines: { node: ">=14.18" }
     dependencies:
       has-flag: 4.0.0
       supports-color: 7.2.0
     dev: true
 
   /supports-preserve-symlinks-flag@1.0.0:
-    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
-    engines: {node: '>= 0.4'}
+    resolution:
+      {
+        integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+      }
+    engines: { node: ">= 0.4" }
     dev: true
 
   /svg-tags@1.0.0:
-    resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
+    resolution:
+      {
+        integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==
+      }
     dev: true
 
   /svgo@2.8.0:
-    resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==}
-    engines: {node: '>=10.13.0'}
+    resolution:
+      {
+        integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
+      }
+    engines: { node: ">=10.13.0" }
     hasBin: true
     dependencies:
-      '@trysound/sax': 0.2.0
+      "@trysound/sax": 0.2.0
       commander: 7.2.0
       css-select: 4.3.0
       css-tree: 1.1.3
@@ -6341,11 +9856,14 @@ packages:
     dev: true
 
   /svgo@3.0.2:
-    resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==}
-    engines: {node: '>=14.0.0'}
+    resolution:
+      {
+        integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==
+      }
+    engines: { node: ">=14.0.0" }
     hasBin: true
     dependencies:
-      '@trysound/sax': 0.2.0
+      "@trysound/sax": 0.2.0
       commander: 7.2.0
       css-select: 5.1.0
       css-tree: 2.3.1
@@ -6354,8 +9872,11 @@ packages:
     dev: true
 
   /table@6.8.1:
-    resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==}
-    engines: {node: '>=10.0.0'}
+    resolution:
+      {
+        integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==
+      }
+    engines: { node: ">=10.0.0" }
     dependencies:
       ajv: 8.12.0
       lodash.truncate: 4.4.2
@@ -6365,11 +9886,14 @@ packages:
     dev: true
 
   /tailwindcss@3.3.3(ts-node@10.9.1):
-    resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==}
-    engines: {node: '>=14.0.0'}
+    resolution:
+      {
+        integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==
+      }
+    engines: { node: ">=14.0.0" }
     hasBin: true
     dependencies:
-      '@alloc/quick-lru': 5.2.0
+      "@alloc/quick-lru": 5.2.0
       arg: 5.0.2
       chokidar: 3.5.3
       didyoumean: 1.2.2
@@ -6396,15 +9920,21 @@ packages:
     dev: true
 
   /tapable@1.1.3:
-    resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
+      }
+    engines: { node: ">=6" }
     requiresBuild: true
     dev: false
     optional: true
 
   /tar@6.2.0:
-    resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==
+      }
+    engines: { node: ">=10" }
     requiresBuild: true
     dependencies:
       chownr: 2.0.0
@@ -6417,97 +9947,153 @@ packages:
     optional: true
 
   /terser@5.22.0:
-    resolution: {integrity: sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==
+      }
+    engines: { node: ">=10" }
     hasBin: true
     dependencies:
-      '@jridgewell/source-map': 0.3.5
+      "@jridgewell/source-map": 0.3.5
       acorn: 8.10.0
       commander: 2.20.3
       source-map-support: 0.5.21
     dev: true
 
   /text-extensions@1.9.0:
-    resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==}
-    engines: {node: '>=0.10'}
+    resolution:
+      {
+        integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==
+      }
+    engines: { node: ">=0.10" }
     dev: true
 
   /text-table@0.2.0:
-    resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+    resolution:
+      {
+        integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
+      }
     dev: true
 
   /thenify-all@1.6.0:
-    resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
-    engines: {node: '>=0.8'}
+    resolution:
+      {
+        integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==
+      }
+    engines: { node: ">=0.8" }
     dependencies:
       thenify: 3.3.1
     dev: true
 
   /thenify@3.3.1:
-    resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+    resolution:
+      {
+        integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
+      }
     dependencies:
       any-promise: 1.3.0
     dev: true
 
   /throttle-debounce@5.0.0:
-    resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==}
-    engines: {node: '>=12.22'}
+    resolution:
+      {
+        integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==
+      }
+    engines: { node: ">=12.22" }
     dev: false
 
   /through2@4.0.2:
-    resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
+    resolution:
+      {
+        integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==
+      }
     dependencies:
       readable-stream: 3.6.2
     dev: true
 
   /through@2.3.8:
-    resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
+    resolution:
+      {
+        integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+      }
     dev: true
 
+  /tiny-warning@1.0.3:
+    resolution:
+      {
+        integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
+      }
+    dev: false
+
+  /tinycolor2@1.6.0:
+    resolution:
+      {
+        integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==
+      }
+    dev: false
+
   /to-fast-properties@2.0.0:
-    resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
-    engines: {node: '>=4'}
+    resolution:
+      {
+        integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
+      }
+    engines: { node: ">=4" }
 
   /to-regex-range@5.0.1:
-    resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
-    engines: {node: '>=8.0'}
+    resolution:
+      {
+        integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+      }
+    engines: { node: ">=8.0" }
     dependencies:
       is-number: 7.0.0
 
   /trim-newlines@3.0.1:
-    resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /trim-newlines@4.1.1:
-    resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /ts-interface-checker@0.1.13:
-    resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+    resolution:
+      {
+        integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
+      }
     dev: true
 
   /ts-node@10.9.1(@types/node@20.8.7)(typescript@5.0.4):
-    resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
+    resolution:
+      {
+        integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==
+      }
     hasBin: true
     peerDependencies:
-      '@swc/core': '>=1.2.50'
-      '@swc/wasm': '>=1.2.50'
-      '@types/node': '*'
-      typescript: '>=2.7'
+      "@swc/core": ">=1.2.50"
+      "@swc/wasm": ">=1.2.50"
+      "@types/node": "*"
+      typescript: ">=2.7"
     peerDependenciesMeta:
-      '@swc/core':
+      "@swc/core":
         optional: true
-      '@swc/wasm':
+      "@swc/wasm":
         optional: true
     dependencies:
-      '@cspotcode/source-map-support': 0.8.1
-      '@tsconfig/node10': 1.0.9
-      '@tsconfig/node12': 1.0.11
-      '@tsconfig/node14': 1.0.3
-      '@tsconfig/node16': 1.0.4
-      '@types/node': 20.8.7
+      "@cspotcode/source-map-support": 0.8.1
+      "@tsconfig/node10": 1.0.9
+      "@tsconfig/node12": 1.0.11
+      "@tsconfig/node14": 1.0.3
+      "@tsconfig/node16": 1.0.4
+      "@types/node": 20.8.7
       acorn: 8.10.0
       acorn-walk: 8.2.0
       arg: 4.1.3
@@ -6520,68 +10106,132 @@ packages:
     dev: true
 
   /tslib@1.14.1:
-    resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
+    resolution:
+      {
+        integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
+      }
     dev: true
 
+  /tslib@2.3.0:
+    resolution:
+      {
+        integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
+      }
+    dev: false
+
   /tslib@2.4.0:
-    resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
+    resolution:
+      {
+        integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+      }
+    dev: false
+
+  /tslib@2.6.2:
+    resolution:
+      {
+        integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
+      }
     dev: false
 
   /tsutils@3.21.0(typescript@5.0.4):
-    resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==
+      }
+    engines: { node: ">= 6" }
     peerDependencies:
-      typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
+      typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
     dependencies:
       tslib: 1.14.1
       typescript: 5.0.4
     dev: true
 
   /type-check@0.4.0:
-    resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
-    engines: {node: '>= 0.8.0'}
+    resolution:
+      {
+        integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
+      }
+    engines: { node: ">= 0.8.0" }
     dependencies:
       prelude-ls: 1.2.1
     dev: true
 
   /type-fest@0.18.1:
-    resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /type-fest@0.20.2:
-    resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /type-fest@0.6.0:
-    resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /type-fest@0.8.1:
-    resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
-    engines: {node: '>=8'}
+    resolution:
+      {
+        integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
+      }
+    engines: { node: ">=8" }
     dev: true
 
   /type-fest@1.4.0:
-    resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==
+      }
+    engines: { node: ">=10" }
     dev: true
 
+  /type@1.2.0:
+    resolution:
+      {
+        integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
+      }
+    dev: false
+
+  /type@2.7.2:
+    resolution:
+      {
+        integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
+      }
+    dev: false
+
   /typescript@5.0.4:
-    resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
-    engines: {node: '>=12.20'}
+    resolution:
+      {
+        integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
+      }
+    engines: { node: ">=12.20" }
     hasBin: true
 
   /ufo@1.3.1:
-    resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==}
+    resolution:
+      {
+        integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /unctx@2.3.1:
-    resolution: {integrity: sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==}
+    resolution:
+      {
+        integrity: sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==
+      }
     requiresBuild: true
     dependencies:
       acorn: 8.10.0
@@ -6592,14 +10242,20 @@ packages:
     optional: true
 
   /undici-types@5.25.3:
-    resolution: {integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==}
+    resolution:
+      {
+        integrity: sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==
+      }
     dev: true
 
   /unimport@3.4.0:
-    resolution: {integrity: sha512-M/lfFEgufIT156QAr/jWHLUn55kEmxBBiQsMxvRSIbquwmeJEyQYgshHDEvQDWlSJrVOOTAgnJ3FvlsrpGkanA==}
+    resolution:
+      {
+        integrity: sha512-M/lfFEgufIT156QAr/jWHLUn55kEmxBBiQsMxvRSIbquwmeJEyQYgshHDEvQDWlSJrVOOTAgnJ3FvlsrpGkanA==
+      }
     requiresBuild: true
     dependencies:
-      '@rollup/pluginutils': 5.0.5
+      "@rollup/pluginutils": 5.0.5
       escape-string-regexp: 5.0.0
       fast-glob: 3.3.1
       local-pkg: 0.4.3
@@ -6616,17 +10272,26 @@ packages:
     optional: true
 
   /universalify@2.0.0:
-    resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
-    engines: {node: '>= 10.0.0'}
+    resolution:
+      {
+        integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
+      }
+    engines: { node: ">= 10.0.0" }
     dev: true
 
   /unpipe@1.0.0:
-    resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
-    engines: {node: '>= 0.8'}
+    resolution:
+      {
+        integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
+      }
+    engines: { node: ">= 0.8" }
     dev: true
 
   /unplugin@1.5.0:
-    resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==}
+    resolution:
+      {
+        integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==
+      }
     requiresBuild: true
     dependencies:
       acorn: 8.10.0
@@ -6637,13 +10302,16 @@ packages:
     optional: true
 
   /untyped@1.4.0:
-    resolution: {integrity: sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==}
+    resolution:
+      {
+        integrity: sha512-Egkr/s4zcMTEuulcIb7dgURS6QpN7DyqQYdf+jBtiaJvQ+eRsrtWUoX84SbvQWuLkXsOjM+8sJC9u6KoMK/U7Q==
+      }
     hasBin: true
     requiresBuild: true
     dependencies:
-      '@babel/core': 7.23.2
-      '@babel/standalone': 7.23.2
-      '@babel/types': 7.23.0
+      "@babel/core": 7.23.2
+      "@babel/standalone": 7.23.2
+      "@babel/types": 7.23.0
       defu: 6.1.2
       jiti: 1.20.0
       mri: 1.2.0
@@ -6654,58 +10322,88 @@ packages:
     optional: true
 
   /update-browserslist-db@1.0.13(browserslist@4.22.1):
-    resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
+    resolution:
+      {
+        integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==
+      }
     hasBin: true
     peerDependencies:
-      browserslist: '>= 4.21.0'
+      browserslist: ">= 4.21.0"
     dependencies:
       browserslist: 4.22.1
       escalade: 3.1.1
       picocolors: 1.0.0
 
   /uri-js@4.4.1:
-    resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+    resolution:
+      {
+        integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
+      }
     dependencies:
       punycode: 2.3.0
     dev: true
 
   /util-deprecate@1.0.2:
-    resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+    resolution:
+      {
+        integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+      }
 
   /util@0.10.4:
-    resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==}
+    resolution:
+      {
+        integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==
+      }
     dependencies:
       inherits: 2.0.3
     dev: false
 
   /utils-merge@1.0.1:
-    resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
-    engines: {node: '>= 0.4.0'}
+    resolution:
+      {
+        integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
+      }
+    engines: { node: ">= 0.4.0" }
     dev: true
 
   /uuid@8.3.2:
-    resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
+    resolution:
+      {
+        integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+      }
     hasBin: true
     dev: true
 
   /uuid@9.0.1:
-    resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
+    resolution:
+      {
+        integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
+      }
     hasBin: true
     dev: false
 
   /v8-compile-cache-lib@3.0.1:
-    resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
+    resolution:
+      {
+        integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
+      }
     dev: true
 
   /validate-npm-package-license@3.0.4:
-    resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+    resolution:
+      {
+        integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
+      }
     dependencies:
       spdx-correct: 3.2.0
       spdx-expression-parse: 3.0.1
     dev: true
 
   /vite-plugin-cdn-import@0.3.5:
-    resolution: {integrity: sha512-e1raoalfBiIhv+hnMeSp1UNjloDDBhHpeFxkwRRdPBmTdDRqdEEn8owUmT5u8UBSVCs4xN3n/od4a91vXEhXPQ==}
+    resolution:
+      {
+        integrity: sha512-e1raoalfBiIhv+hnMeSp1UNjloDDBhHpeFxkwRRdPBmTdDRqdEEn8owUmT5u8UBSVCs4xN3n/od4a91vXEhXPQ==
+      }
     dependencies:
       rollup-plugin-external-globals: 0.6.1
     transitivePeerDependencies:
@@ -6713,9 +10411,12 @@ packages:
     dev: true
 
   /vite-plugin-compression@0.5.1(vite@4.5.0):
-    resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
+    resolution:
+      {
+        integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==
+      }
     peerDependencies:
-      vite: '>=2.0.0'
+      vite: ">=2.0.0"
     dependencies:
       chalk: 4.1.2
       debug: 4.3.4
@@ -6726,14 +10427,17 @@ packages:
     dev: true
 
   /vite-plugin-mock@2.9.6(mockjs@1.1.0)(vite@4.5.0):
-    resolution: {integrity: sha512-/Rm59oPppe/ncbkSrUuAxIQihlI2YcBmnbR4ST1RA2VzM1C0tEQc1KlbQvnUGhXECAGTaQN2JyasiwXP6EtKgg==}
-    engines: {node: '>=12.0.0'}
+    resolution:
+      {
+        integrity: sha512-/Rm59oPppe/ncbkSrUuAxIQihlI2YcBmnbR4ST1RA2VzM1C0tEQc1KlbQvnUGhXECAGTaQN2JyasiwXP6EtKgg==
+      }
+    engines: { node: ">=12.0.0" }
     peerDependencies:
-      mockjs: '>=1.1.0'
-      vite: '>=2.0.0'
+      mockjs: ">=1.1.0"
+      vite: ">=2.0.0"
     dependencies:
-      '@rollup/plugin-node-resolve': 13.3.0
-      '@types/mockjs': 1.0.9
+      "@rollup/plugin-node-resolve": 13.3.0
+      "@types/mockjs": 1.0.9
       chalk: 4.1.2
       chokidar: 3.5.3
       connect: 3.7.0
@@ -6749,30 +10453,39 @@ packages:
     dev: true
 
   /vite-plugin-remove-console@2.1.1:
-    resolution: {integrity: sha512-AQOsKl9+1YO82otwSchf+P8SRo4RhMvPjOvjm9DXOnkff0SBwBPAzazEn06IUjhsm/zX4miMgicCQH1hPdktrw==}
+    resolution:
+      {
+        integrity: sha512-AQOsKl9+1YO82otwSchf+P8SRo4RhMvPjOvjm9DXOnkff0SBwBPAzazEn06IUjhsm/zX4miMgicCQH1hPdktrw==
+      }
     dev: true
 
   /vite-svg-loader@4.0.0:
-    resolution: {integrity: sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==}
+    resolution:
+      {
+        integrity: sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==
+      }
     dependencies:
-      '@vue/compiler-sfc': 3.3.5
+      "@vue/compiler-sfc": 3.3.5
       svgo: 3.0.2
     dev: true
 
   /vite@4.5.0(@types/node@20.8.7)(sass@1.69.4)(terser@5.22.0):
-    resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
-    engines: {node: ^14.18.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==
+      }
+    engines: { node: ^14.18.0 || >=16.0.0 }
     hasBin: true
     peerDependencies:
-      '@types/node': '>= 14'
-      less: '*'
+      "@types/node": ">= 14"
+      less: "*"
       lightningcss: ^1.21.0
-      sass: '*'
-      stylus: '*'
-      sugarss: '*'
+      sass: "*"
+      stylus: "*"
+      sugarss: "*"
       terser: ^5.4.0
     peerDependenciesMeta:
-      '@types/node':
+      "@types/node":
         optional: true
       less:
         optional: true
@@ -6787,7 +10500,7 @@ packages:
       terser:
         optional: true
     dependencies:
-      '@types/node': 20.8.7
+      "@types/node": 20.8.7
       esbuild: 0.18.20
       postcss: 8.4.31
       rollup: 3.29.4
@@ -6797,27 +10510,76 @@ packages:
       fsevents: 2.3.3
     dev: true
 
+  /vue-demi@0.13.11(@vue/composition-api@1.7.2)(vue@3.3.5):
+    resolution:
+      {
+        integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
+      }
+    engines: { node: ">=12" }
+    hasBin: true
+    requiresBuild: true
+    peerDependencies:
+      "@vue/composition-api": ^1.0.0-rc.1
+      vue: ^3.0.0-0 || ^2.6.0
+    peerDependenciesMeta:
+      "@vue/composition-api":
+        optional: true
+    dependencies:
+      "@vue/composition-api": 1.7.2(vue@3.3.5)
+      vue: 3.3.5(typescript@5.0.4)
+    dev: false
+
   /vue-demi@0.14.6(@vue/composition-api@1.7.2)(vue@3.3.5):
-    resolution: {integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
+      }
+    engines: { node: ">=12" }
     hasBin: true
     requiresBuild: true
     peerDependencies:
-      '@vue/composition-api': ^1.0.0-rc.1
+      "@vue/composition-api": ^1.0.0-rc.1
       vue: ^3.0.0-0 || ^2.6.0
     peerDependenciesMeta:
-      '@vue/composition-api':
+      "@vue/composition-api":
+        optional: true
+    dependencies:
+      "@vue/composition-api": 1.7.2(vue@3.3.5)
+      vue: 3.3.5(typescript@5.0.4)
+    dev: false
+
+  /vue-echarts@6.6.9(@vue/composition-api@1.7.2)(echarts@5.5.0)(vue@3.3.5):
+    resolution:
+      {
+        integrity: sha512-mojIq3ZvsjabeVmDthhAUDV8Kgf2Rr/X4lV4da7gEFd1fP05gcSJ0j7wa7HQkW5LlFmF2gdCJ8p4Chas6NNIQQ==
+      }
+    requiresBuild: true
+    peerDependencies:
+      "@vue/composition-api": ^1.0.5
+      "@vue/runtime-core": ^3.0.0
+      echarts: ^5.4.1
+      vue: ^2.6.12 || ^3.1.1
+    peerDependenciesMeta:
+      "@vue/composition-api":
+        optional: true
+      "@vue/runtime-core":
         optional: true
     dependencies:
-      '@vue/composition-api': 1.7.2(vue@3.3.5)
+      "@vue/composition-api": 1.7.2(vue@3.3.5)
+      echarts: 5.5.0
+      resize-detector: 0.3.0
       vue: 3.3.5(typescript@5.0.4)
+      vue-demi: 0.13.11(@vue/composition-api@1.7.2)(vue@3.3.5)
     dev: false
 
   /vue-eslint-parser@9.3.2(eslint@8.51.0):
-    resolution: {integrity: sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==}
-    engines: {node: ^14.17.0 || >=16.0.0}
+    resolution:
+      {
+        integrity: sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==
+      }
+    engines: { node: ^14.17.0 || >=16.0.0 }
     peerDependencies:
-      eslint: '>=6.0.0'
+      eslint: ">=6.0.0"
     dependencies:
       debug: 4.3.4
       eslint: 8.51.0
@@ -6832,36 +10594,48 @@ packages:
     dev: true
 
   /vue-router@4.2.5(vue@3.3.5):
-    resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==}
+    resolution:
+      {
+        integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==
+      }
     peerDependencies:
       vue: ^3.2.0
     dependencies:
-      '@vue/devtools-api': 6.5.1
+      "@vue/devtools-api": 6.5.1
       vue: 3.3.5(typescript@5.0.4)
     dev: false
 
   /vue-template-compiler@2.7.14:
-    resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==}
+    resolution:
+      {
+        integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==
+      }
     dependencies:
       de-indent: 1.0.2
       he: 1.2.0
     dev: true
 
   /vue-tsc@1.8.19(typescript@5.0.4):
-    resolution: {integrity: sha512-tacMQLQ0CXAfbhRycCL5sWIy1qujXaIEtP1hIQpzHWOUuICbtTj9gJyFf91PvzG5KCNIkA5Eg7k2Fmgt28l5DQ==}
+    resolution:
+      {
+        integrity: sha512-tacMQLQ0CXAfbhRycCL5sWIy1qujXaIEtP1hIQpzHWOUuICbtTj9gJyFf91PvzG5KCNIkA5Eg7k2Fmgt28l5DQ==
+      }
     hasBin: true
     peerDependencies:
-      typescript: '*'
+      typescript: "*"
     dependencies:
-      '@vue/language-core': 1.8.19(typescript@5.0.4)
-      '@vue/typescript': 1.8.19(typescript@5.0.4)
+      "@vue/language-core": 1.8.19(typescript@5.0.4)
+      "@vue/typescript": 1.8.19(typescript@5.0.4)
       semver: 7.5.4
       typescript: 5.0.4
     dev: true
 
   /vue-types@5.1.1(vue@3.3.5):
-    resolution: {integrity: sha512-FMY/JCLWePXgGIcMDqYdJsQm1G0CDxEjq6W0+tZMJZlX37q/61eSGSIa/XFRwa9T7kkKXuxxl94/2kgxyWQqKw==}
-    engines: {node: '>=14.0.0'}
+    resolution:
+      {
+        integrity: sha512-FMY/JCLWePXgGIcMDqYdJsQm1G0CDxEjq6W0+tZMJZlX37q/61eSGSIa/XFRwa9T7kkKXuxxl94/2kgxyWQqKw==
+      }
+    engines: { node: ">=14.0.0" }
     peerDependencies:
       vue: ^2.0.0 || ^3.0.0
     peerDependenciesMeta:
@@ -6873,57 +10647,96 @@ packages:
     dev: false
 
   /vue3-seamless-scroll@2.0.1:
-    resolution: {integrity: sha512-mI3BaDU3pjcPUhVSw3/xNKdfPBDABTi/OdZaZqKysx4cSdNfGRbVvGNDzzptBbJ5S7imv5T55l6x/SqgnxKreg==}
+    resolution:
+      {
+        integrity: sha512-mI3BaDU3pjcPUhVSw3/xNKdfPBDABTi/OdZaZqKysx4cSdNfGRbVvGNDzzptBbJ5S7imv5T55l6x/SqgnxKreg==
+      }
     dependencies:
       throttle-debounce: 5.0.0
     dev: false
 
   /vue@3.3.5(typescript@5.0.4):
-    resolution: {integrity: sha512-xYpLEGb25yYU1ul9ZhCcavNZ4YW6PS7YTDdDAd0yc/3w69Tra2BwY4EpKguKddfD56QApXQ17XHq+fJJwEP+UQ==}
+    resolution:
+      {
+        integrity: sha512-xYpLEGb25yYU1ul9ZhCcavNZ4YW6PS7YTDdDAd0yc/3w69Tra2BwY4EpKguKddfD56QApXQ17XHq+fJJwEP+UQ==
+      }
     peerDependencies:
-      typescript: '*'
+      typescript: "*"
     peerDependenciesMeta:
       typescript:
         optional: true
     dependencies:
-      '@vue/compiler-dom': 3.3.5
-      '@vue/compiler-sfc': 3.3.5
-      '@vue/runtime-dom': 3.3.5
-      '@vue/server-renderer': 3.3.5(vue@3.3.5)
-      '@vue/shared': 3.3.5
+      "@vue/compiler-dom": 3.3.5
+      "@vue/compiler-sfc": 3.3.5
+      "@vue/runtime-dom": 3.3.5
+      "@vue/server-renderer": 3.3.5(vue@3.3.5)
+      "@vue/shared": 3.3.5
       typescript: 5.0.4
 
+  /wangeditor@4.7.15:
+    resolution:
+      {
+        integrity: sha512-aPTdREd8BxXVyJ5MI+LU83FQ7u1EPd341iXIorRNYSOvoimNoZ4nPg+yn3FGbB93/owEa6buLw8wdhYnMCJQLg==
+      }
+    dependencies:
+      "@babel/runtime": 7.23.2
+      "@babel/runtime-corejs3": 7.23.4
+      tslib: 2.4.0
+    dev: false
+
   /webpack-sources@3.2.3:
-    resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
-    engines: {node: '>=10.13.0'}
+    resolution:
+      {
+        integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
+      }
+    engines: { node: ">=10.13.0" }
     requiresBuild: true
     dev: false
     optional: true
 
   /webpack-virtual-modules@0.5.0:
-    resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
+    resolution:
+      {
+        integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==
+      }
     requiresBuild: true
     dev: false
     optional: true
 
   /which@1.3.1:
-    resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
+    resolution:
+      {
+        integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
+      }
     hasBin: true
     dependencies:
       isexe: 2.0.0
     dev: true
 
   /which@2.0.2:
-    resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
-    engines: {node: '>= 8'}
+    resolution:
+      {
+        integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+      }
+    engines: { node: ">= 8" }
     hasBin: true
     dependencies:
       isexe: 2.0.0
     dev: true
 
+  /wildcard@1.1.2:
+    resolution:
+      {
+        integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==
+      }
+    dev: false
+
   /wrap-ansi@7.0.0:
-    resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+      }
+    engines: { node: ">=10" }
     dependencies:
       ansi-styles: 4.3.0
       string-width: 4.2.3
@@ -6931,8 +10744,11 @@ packages:
     dev: true
 
   /wrap-ansi@8.1.0:
-    resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
+      }
+    engines: { node: ">=12" }
     dependencies:
       ansi-styles: 6.2.1
       string-width: 5.1.2
@@ -6940,61 +10756,97 @@ packages:
     dev: true
 
   /wrappy@1.0.2:
-    resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+    resolution:
+      {
+        integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+      }
     dev: true
 
   /write-file-atomic@5.0.1:
-    resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
-    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+    resolution:
+      {
+        integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==
+      }
+    engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 }
     dependencies:
       imurmurhash: 0.1.4
       signal-exit: 4.1.0
     dev: true
 
   /xml-name-validator@4.0.0:
-    resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /y18n@5.0.8:
-    resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /yallist@3.1.1:
-    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+    resolution:
+      {
+        integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
+      }
 
   /yallist@4.0.0:
-    resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+    resolution:
+      {
+        integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
+      }
 
   /yaml@1.10.2:
-    resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
-    engines: {node: '>= 6'}
+    resolution:
+      {
+        integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
+      }
+    engines: { node: ">= 6" }
     dev: true
 
   /yaml@2.3.1:
-    resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==}
-    engines: {node: '>= 14'}
+    resolution:
+      {
+        integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==
+      }
+    engines: { node: ">= 14" }
     dev: true
 
   /yaml@2.3.3:
-    resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==}
-    engines: {node: '>= 14'}
+    resolution:
+      {
+        integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==
+      }
+    engines: { node: ">= 14" }
     dev: true
 
   /yargs-parser@20.2.9:
-    resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
+      }
+    engines: { node: ">=10" }
     dev: true
 
   /yargs-parser@21.1.1:
-    resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+      }
+    engines: { node: ">=12" }
     dev: true
 
   /yargs@17.7.2:
-    resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
-    engines: {node: '>=12'}
+    resolution:
+      {
+        integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
+      }
+    engines: { node: ">=12" }
     dependencies:
       cliui: 8.0.1
       escalade: 3.1.1
@@ -7006,11 +10858,26 @@ packages:
     dev: true
 
   /yn@3.1.1:
-    resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
-    engines: {node: '>=6'}
+    resolution:
+      {
+        integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
+      }
+    engines: { node: ">=6" }
     dev: true
 
   /yocto-queue@0.1.0:
-    resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
-    engines: {node: '>=10'}
+    resolution:
+      {
+        integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+      }
+    engines: { node: ">=10" }
     dev: true
+
+  /zrender@5.5.0:
+    resolution:
+      {
+        integrity: sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==
+      }
+    dependencies:
+      tslib: 2.3.0
+    dev: false
diff --git a/public/favicon.ico b/public/favicon.ico
index bef93d4..fddf9ae 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/people.mp4 b/public/people.mp4
new file mode 100644
index 0000000..e67802d
Binary files /dev/null and b/public/people.mp4 differ
diff --git a/public/serverConfig.json b/public/serverConfig.json
index 01a0853..3a7b551 100644
--- a/public/serverConfig.json
+++ b/public/serverConfig.json
@@ -12,7 +12,7 @@
   "Weak": false,
   "HideTabs": true,
   "SidebarStatus": true,
-  "EpThemeColor": "rgba(28, 13, 130)",
+  "EpThemeColor": "#4287ff",
   "ShowLogo": true,
   "ShowModel": "smart",
   "MenuArrowIconNoTransition": true,
diff --git a/src/api/consultation.ts b/src/api/consultation.ts
new file mode 100644
index 0000000..5677a99
--- /dev/null
+++ b/src/api/consultation.ts
@@ -0,0 +1,238 @@
+import { http } from "@/utils/http";
+
+/** 分页查询问诊流程列表 */
+export const queryDiagnoseProcessPageList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/diagnoseHall/queryDiagnoseProcessPageList",
+    {
+      params: data
+    }
+  );
+};
+/** 分页查询病例信息列表 */
+export const queryMedicalRecPageList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/diagnoseHall/queryMedicalRecPageList",
+    {
+      params: data
+    }
+  );
+};
+/** 通过流程id查询电子病例信息 */
+export const findByProcessId = (data?: object) => {
+  return http.request("get", "/virtual-patient/medicalRecord/findByProcessId", {
+    params: data
+  });
+};
+
+/** 更新电子病例信息*/
+
+export const updateCase = (data?: object) => {
+  return http.request("put", "/virtual-patient//medicalRecord/update", {
+    data
+  });
+};
+
+/** 查询选择初步诊断关联的问诊记录 */
+export const queryRecordForPrimaryChoose = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/askPrimary/queryRecordForPrimaryChoose",
+    {
+      params: data
+    }
+  );
+};
+/** 新增初步诊断*/
+
+export const savePrimary = (data?: object) => {
+  return http.request("post", "/virtual-patient/askPrimary/savePrimary", {
+    data
+  });
+};
+/** 批量进行辅助检查*/
+export const execAskAncillaryBatch = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient/askAncillary/execAskAncillaryBatch",
+    {
+      data
+    }
+  );
+};
+
+/** 查询初步诊断需要填写的诊断依据 */
+export const queryDiagnosticBasisListForPrimary = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/askPrimary/queryDiagnosticBasisListForPrimary",
+    {
+      params: data
+    }
+  );
+};
+/** 保存初步诊断以及鉴别依据 */
+export const confirmPrimaryByAskEnd = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient/askPrimary/confirmPrimaryByAskEnd",
+    {
+      data
+    }
+  );
+};
+/** 查询处置计划树 */
+export const queryTree = (data?: object) => {
+  return http.request("get", "/virtual-patient/treatmentPlan/queryTree", {
+    params: data
+  });
+};
+
+/** 新增处置计划记录 */
+export const savePlan = (data?: object) => {
+  return http.request("post", "/virtual-patient/treatmentPlan/record/save", {
+    data
+  });
+};
+/** 查询处置计划记录列表 */
+export const queryPlanRecord = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/treatmentPlan/record/queryRecord",
+    {
+      params: data
+    }
+  );
+};
+/** 查询药品列表 */
+export const getDrugList = (data?: object) => {
+  return http.request("get", "/virtual-patient/treatmentPlan/getDrugList", {
+    params: data
+  });
+};
+// 删除处置计划记录;
+export const deleteRecord = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient/treatmentPlan/record/delete",
+    {
+      params: data
+    }
+  );
+};
+/** 修改处置计划记录 */
+export const updateRecord = (data?: object) => {
+  return http.request("put", "/virtual-patient/treatmentPlan/record/update", {
+    data
+  });
+};
+/** 查询处置计划详情 */
+export const queryDetails = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/treatmentPlan/record/queryDetails",
+    {
+      params: data
+    }
+  );
+};
+/** 新增处置计划记录 */
+export const confirmPlan = (data?: object) => {
+  return http.request("post", "/virtual-patient/treatmentPlan/confirm", {
+    data
+  });
+};
+/** 查看资源是否有剩余
+ */
+export const resourceIsFree = (data?: object) => {
+  return http.request("get", "/virtual-patient//user/resourceIsFree", {
+    params: data
+  });
+};
+/** 获取本机IP地址,用来给websocket使用
+ */
+export const queryWebSocketUrl = (data?: object) => {
+  return http.request("get", "/virtual-patient/user/queryWebSocketUrl", {
+    params: data
+  });
+};
+/** 保存辅助检查判读结果
+ */
+export const saveAncillaryAssessmentResult = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient/askAncillary/saveAncillaryAssessmentResult",
+    {
+      data
+    }
+  );
+};
+/** 获取单个初步诊断详细信息
+ */
+export const queryPrimaryDetailInfo = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/askPrimary/queryPrimaryDetailInfo",
+    {
+      params: data
+    }
+  );
+};
+/** 使用本地视频的形式来做
+ */
+export const talkByVideo = (data?: object) => {
+  return http.request("post", "/virtual-patient/ask/talkByVideoAndTts", {
+    data
+  });
+};
+/** 查询诊断结果的雷达图
+ */
+export const queryRadarChart = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/askDiagnosisResult/queryRadarChart",
+    {
+      params: data
+    }
+  );
+};
+/** 查询树形结构图
+ */
+export const queryTreeGraph = (data?: object) => {
+  return http.request("get", "/virtual-patient-graph/queryTreeGraph", {
+    params: data
+  });
+};
+/** 查询图谱
+ */
+export const queryGraph = (data?: object) => {
+  return http.request("get", "/virtual-patient-graph/queryGraph", {
+    params: data
+  });
+};
+// 删除问诊实例;
+export const deleteProcess = (data?: object) => {
+  return http.request("delete", "/virtual-patient/askProcess/delete", {
+    params: data
+  });
+};
+/** 查询问答记录
+ */
+export const queryQaRecordForFeedback = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/feedback/queryQaRecordForFeedback",
+    {
+      params: data
+    }
+  );
+};
+/** 保存反馈
+ */
+export const saveFeedback = (data?: object) => {
+  return http.request("post", "/virtual-patient/feedback/saveFeedback", {
+    data
+  });
+};
diff --git a/src/api/disease.ts b/src/api/disease.ts
new file mode 100644
index 0000000..ce94d2f
--- /dev/null
+++ b/src/api/disease.ts
@@ -0,0 +1,236 @@
+import { http } from "@/utils/http";
+
+/** 查询分页疾病列表 */
+export const queryPageList = (data?: object) => {
+  return http.request("get", "/virtual-patient-manage/disease/queryPageList", {
+    params: data
+  });
+};
+/** 新增疾病 */
+export const addSave = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/disease/save", {
+    data
+  });
+};
+
+/** 修改疾病信息 */
+export const update = (data?: object) => {
+  return http.request("put", "/virtual-patient-manage/disease/update", {
+    data
+  });
+};
+/** 删除疾病信息 */
+export const deleteItem = (data?: object) => {
+  return http.request("delete", "/virtual-patient-manage/disease/delete", {
+    params: data
+  });
+};
+/** 根据疾病id查询问题库信息列表 */
+export const queryListByDiseaseId = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseaseQuestion/queryListByDiseaseId",
+    {
+      params: data
+    }
+  );
+};
+export const diseaseQuestionDel = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/diseaseQuestion/delete",
+    {
+      params: data
+    }
+  );
+};
+/** 查询问题库列表 */
+
+export const queryListAqLibrary = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage//aqLibrary/queryPageList",
+    {
+      params: data
+    }
+  );
+};
+/** 保存疾病问题信息 */
+export const questionBatchSave = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/diseaseQuestion/batchSave",
+    {
+      data
+    }
+  );
+};
+/** 查询问题类目编码列表 */
+export const queryItemList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/aqLibrary/queryItemList",
+    {
+      params: data
+    }
+  );
+};
+/** 查询体格检查的工具列表 */
+export const queryPhysicalToolList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage//physicalTool/queryPhysicalToolList",
+    {
+      params: data
+    }
+  );
+};
+/** 根据疾病id查询体格检查列表 */
+export const queryBodyListByDiseaseId = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseasePhysical/queryListByDiseaseId",
+    {
+      params: data
+    }
+  );
+};
+/** 新增体格检查信息 */
+export const addBodyInspect = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/diseasePhysical/save", {
+    data
+  });
+};
+/** 修改体格检查信息 */
+export const updateBodyInspect = (data?: object) => {
+  return http.request("put", "/virtual-patient-manage/diseasePhysical/update", {
+    data
+  });
+};
+/** 删除体格检查 */
+export const deleteBodyItem = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/diseasePhysical/delete",
+    {
+      params: data
+    }
+  );
+};
+/** 根据疾病id查询疾病处置信息列表 */
+export const queryListBiseaseTreatmentPlan = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseaseTreatmentPlan/queryListByDiseaseId",
+    {
+      params: data
+    }
+  );
+};
+/** 保存处置信息 */
+export const addDiseaseTreatmentPlan = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/diseaseTreatmentPlan/batchSave",
+    {
+      data
+    }
+  );
+};
+/** 查询处置计划树 */
+export const queryTreeTreatmentPlan = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseaseTreatmentPlan/queryTree",
+    {
+      params: data
+    }
+  );
+};
+/** 删除疾病处置计划 */
+export const deleteTreatmentPlan = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/diseaseTreatmentPlan/delete",
+    {
+      params: data
+    }
+  );
+};
+/** 查询疾病身体部位树 */
+export const queryTreeDiseasePhysical = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseasePhysical/queryTree",
+    {
+      params: data
+    }
+  );
+};
+/** 新增辅助检查信息 */
+export const addSupportInspect = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/diseaseAncillary/save", {
+    data
+  });
+};
+/** 修改体格检查信息 */
+export const updateSupportInspect = (data?: object) => {
+  return http.request(
+    "put",
+    "/virtual-patient-manage/diseaseAncillary/update",
+    {
+      data
+    }
+  );
+};
+/** 删除体格检查 */
+export const deleteSupportItem = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/diseaseAncillary/delete",
+    {
+      params: data
+    }
+  );
+};
+/** 查询疾病辅助检查项目列表 */
+export const queryAncillaryItemList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseaseAncillary/queryAncillaryItemList",
+    {
+      params: data
+    }
+  );
+};
+/** 根据疾病id查询疾病辅助检查信息列表 */
+export const querySupportLsit = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/diseaseAncillary/queryListByDiseaseId",
+    {
+      params: data
+    }
+  );
+};
+/** 保存处置信息 */
+export const saveDiseaseTreatmentPlan = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/diseaseTreatmentPlan/save",
+    {
+      data
+    }
+  );
+};
+/** 修改处置计划
+ */
+export const updateDiseaseTreatmentPlann = (data?: object) => {
+  return http.request(
+    "put",
+    "/virtual-patient-manage/diseaseTreatmentPlan/update",
+    {
+      data
+    }
+  );
+};
diff --git a/src/api/generalRules.ts b/src/api/generalRules.ts
new file mode 100644
index 0000000..0ae4c85
--- /dev/null
+++ b/src/api/generalRules.ts
@@ -0,0 +1,129 @@
+import { http } from "@/utils/http";
+
+/** 分页查询问题库列表 */
+export const queryPageList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/aqLibrary/queryPageList",
+    {
+      params: data
+    }
+  );
+};
+
+/** 保存问题库信息 */
+export const saveQuestionLibrary = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/aqLibrary/saveQuestionLibrary",
+    {
+      data
+    }
+  );
+};
+/** 更新问题库信息 */
+export const updateQuestionLibrary = (data?: object) => {
+  return http.request(
+    "put",
+    "/virtual-patient-manage/aqLibrary/updateQuestionLibrary",
+    {
+      data
+    }
+  );
+};
+/** 删除问题库信息 */
+export const deleteQuestionLibrary = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/aqLibrary/deleteQuestionLibrary",
+    {
+      data
+    }
+  );
+};
+/** 新增文件目录 */
+export const addDirectory = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/directoryManage/addDirectory",
+    {
+      data
+    }
+  );
+};
+/** 修改文件目录 */
+export const updateDirectory = (data?: object) => {
+  return http.request(
+    "put",
+    "/virtual-patient-manage/directoryManage/updateDirectory",
+    {
+      data
+    }
+  );
+};
+/** 查询文件目录 */
+export const getFileDirectory = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/directoryManage/getFileDirectory",
+    {
+      params: data
+    }
+  );
+};
+/** 上传素材 */
+export const uploadMaterial = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/materialLibrary/uploadMaterial",
+    {
+      data
+    }
+  );
+};
+/** 素材管理分页查询 */
+export const queryMedicalRecPage = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/materialLibrary/queryMedicalRecPage",
+    {
+      params: data
+    }
+  );
+};
+/** 修改素材 */
+export const updateMaterial = (data?: object) => {
+  return http.request(
+    "put",
+    "/virtual-patient-manage/materialLibrary/updateMaterial",
+    {
+      data
+    }
+  );
+};
+/** 删除素材 */
+export const deleteMaterial = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/materialLibrary/deleteMaterial",
+    {
+      params: data
+    }
+  );
+};
+/** 查询病例默认问题 */
+export const queryMedicalDefaultAnswer = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryMedicalDefaultAnswer",
+    {
+      params: data
+    }
+  );
+};
+/** 对话服务 */
+export const talkRasa = (data?: object) => {
+  return http.request("post", "/virtual-patient-rasa/rasaCmd/deploy", {
+    data
+  });
+};
diff --git a/src/api/inquiry.ts b/src/api/inquiry.ts
index 6614014..c25e550 100644
--- a/src/api/inquiry.ts
+++ b/src/api/inquiry.ts
@@ -88,10 +88,10 @@ export const queryPhysicalToolList = (data?: object) => {
 /** 查询体格检查的结果(执行体格检查) */
 export const queryAskPhysicalResult = (data?: object) => {
   return http.request(
-    "get",
+    "post",
     "/virtual-patient/askPhysical/queryAskPhysicalResult",
     {
-      params: data
+      data
     }
   );
 };
diff --git a/src/api/inquiryCase.ts b/src/api/inquiryCase.ts
new file mode 100644
index 0000000..32797dd
--- /dev/null
+++ b/src/api/inquiryCase.ts
@@ -0,0 +1,52 @@
+import { http } from "@/utils/http";
+
+/** 分页查询病案管理 */
+export const queryProcessRecordPage = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/processRecord/queryProcessRecordPage",
+    {
+      params: data
+    }
+  );
+};
+/** 电子病例视图 */
+export const queryViewDetails = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient/medicalRecord/queryViewDetails",
+    {
+      params: data
+    }
+  );
+};
+/** 保存或更新考核病案评估 */
+export const saveProcessEvaluation = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/processRecord/saveProcessEvaluation",
+    {
+      data
+    }
+  );
+};
+/** 查询考核病案评估 */
+export const queryProcessEvaluation = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/processRecord/queryProcessEvaluation",
+    {
+      params: data
+    }
+  );
+};
+
+export const querySingleDiseaseListByDropList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/querySingleDiseaseListByDropList",
+    {
+      params: data
+    }
+  );
+};
diff --git a/src/api/inquiryManagement.ts b/src/api/inquiryManagement.ts
new file mode 100644
index 0000000..8d57510
--- /dev/null
+++ b/src/api/inquiryManagement.ts
@@ -0,0 +1,175 @@
+import { http } from "@/utils/http";
+
+/** 分页查询药物信息 */
+export const queryDrugManagePageList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/drugManage/queryPageList",
+    {
+      params: data
+    }
+  );
+};
+/** 新增药物信息 */
+export const addDrugManage = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/drugManage/save", {
+    data
+  });
+};
+/** 修改药物信息 */
+export const edtDrugManage = (data?: object) => {
+  return http.request("put", "/virtual-patient-manage/drugManage/update", {
+    data
+  });
+};
+/** 删除药物信息 */
+export const delDrugManage = (data?: object) => {
+  return http.request("delete", "/virtual-patient-manage/drugManage/delete", {
+    params: data
+  });
+};
+/** 保存处置计划 */
+export const saveTreatmentPlan = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/treatmentPlan/save", {
+    data
+  });
+};
+/** 分页查询处置计划列表 */
+export const queryTreatmentPlanList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/treatmentPlan/queryPageList",
+    {
+      params: data
+    }
+  );
+};
+
+/** 修改 */
+export const updateTreatmentPlan = (data?: object) => {
+  return http.request("put", "/virtual-patient-manage/treatmentPlan/update", {
+    data
+  });
+};
+/** 删除处置计划 */
+export const delTreatmentPlan = (data?: object) => {
+  return http.request(
+    "delete",
+    "/virtual-patient-manage/treatmentPlan/delete",
+    {
+      params: data
+    }
+  );
+};
+
+/** 体格检查分页查询 */
+export const queryPhysicalPage = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/physicalTool/queryPhysicalPage",
+    {
+      params: data
+    }
+  );
+};
+
+/** 删除体格工具 */
+export const deleteConfigPhysicalTool = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/physicalTool/deleteConfigPhysicalTool",
+    {
+      params: data
+    }
+  );
+};
+/** 保存体格工具 */
+export const saveConfigPhysicalTool = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/physicalTool/saveConfigPhysicalTool",
+    {
+      data
+    }
+  );
+};
+/** 修改体格工具 */
+export const modifyConfigPhysicalTool = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/physicalTool/modifyConfigPhysicalTool",
+    {
+      data
+    }
+  );
+};
+/** 查询身体部位树 */
+export const queryPhysicalLocation = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/physicalLocation/queryTree",
+    {
+      params: data
+    }
+  );
+};
+
+export const queryConfigPhysicalToolDetail = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/physicalTool/queryConfigPhysicalToolDetail",
+    {
+      params: data
+    }
+  );
+};
+/** 查询辅助检查项目列表 */
+export const queryAncillaryItemList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/ancillaryItem/queryAncillaryItemList",
+    {
+      params: data
+    }
+  );
+};
+/** 分页查询辅助检查 */
+export const queryAncillaryPage = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/ancillaryItem/queryAncillaryPage",
+    {
+      params: data
+    }
+  );
+};
+/** 保存辅助检查项 */
+export const saveAncillaryItem = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/ancillaryItem/saveAncillaryItem",
+    {
+      data
+    }
+  );
+};
+/** 修改辅助检查项 */
+export const modifyAncillaryItem = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/ancillaryItem/modifyAncillaryItem",
+    {
+      data
+    }
+  );
+};
+/** 删除辅助检查项 */
+export const deleteAncillaryItem = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/ancillaryItem/deleteAncillaryItem",
+    {
+      params: data
+    }
+  );
+};
diff --git a/src/api/medicalRecord.ts b/src/api/medicalRecord.ts
new file mode 100644
index 0000000..19d7512
--- /dev/null
+++ b/src/api/medicalRecord.ts
@@ -0,0 +1,112 @@
+import { http } from "@/utils/http";
+
+/** 初步诊断下拉列表联想 */
+export const queryDiseaseListByDropList = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryDiseaseListByDropList",
+    {
+      params: data
+    }
+  );
+};
+/** 病历管理分页查询 */
+export const queryMedicalRecPage = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryMedicalRecPage",
+    {
+      params: data
+    }
+  );
+};
+/** 创建疾病时的疾病列表 */
+export const queryDiseaseListByCreat = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryDiseaseListByCreat",
+    {
+      params: data
+    }
+  );
+};
+/** 创建病历时查看配置的体格检查项 */
+export const queryDiseasePhysicalByCreat = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryDiseasePhysicalByCreat",
+    {
+      params: data
+    }
+  );
+};
+/** 创建病历时查看配置的辅助检查项 */
+export const queryDiseaseAncillaryByCreat = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryDiseaseAncillaryByCreat",
+    {
+      params: data
+    }
+  );
+};
+/** 新增病历*/
+export const createMedicalRec = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/medicalRecManage/createMedicalRec",
+    {
+      data
+    }
+  );
+};
+/** 创建病历时, 应答策略查询问题(目前只支持单一疾病) */
+export const queryQuestionListByCreat = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryQuestionListByCreat",
+    {
+      params: data
+    }
+  );
+};
+/** 创建病历时查看配置的处置计划 */
+export const queryDiseaseTreatmentPlanByCreat = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryDiseaseTreatmentPlanByCreat",
+    {
+      params: data
+    }
+  );
+};
+/** 删除病历 */
+export const deleteMedicalRec = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/deleteMedicalRec",
+    {
+      params: data
+    }
+  );
+};
+/** 查询病例详细信息 */
+export const queryMedicalRecInfo = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/medicalRecManage/queryMedicalRecInfo",
+    {
+      params: data
+    }
+  );
+};
+/** 修改病历 */
+export const modifyMedicalRec = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/medicalRecManage/modifyMedicalRec",
+    {
+      data
+    }
+  );
+};
diff --git a/src/api/systemManagement.ts b/src/api/systemManagement.ts
new file mode 100644
index 0000000..aecec7f
--- /dev/null
+++ b/src/api/systemManagement.ts
@@ -0,0 +1,34 @@
+import { http } from "@/utils/http";
+
+/** 查询用户列表 */
+export const queryUserPage = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/userManage/queryUserPage",
+    {
+      params: data
+    }
+  );
+};
+/** 停用用户 */
+export const deactivateUser = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/userManage/deactivateUser",
+    {
+      params: data
+    }
+  );
+};
+/** 保存用户 */
+export const saveUser = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/userManage/saveUser", {
+    data
+  });
+};
+/** 更新用户 */
+export const updateUser = (data?: object) => {
+  return http.request("post", "/virtual-patient-manage/userManage/updateUser", {
+    data
+  });
+};
diff --git a/src/api/user.ts b/src/api/user.ts
index f5b444d..a72733c 100644
--- a/src/api/user.ts
+++ b/src/api/user.ts
@@ -33,3 +33,19 @@ export const getLogin = (data?: object) => {
 export const refreshTokenApi = (data?: object) => {
   return http.request<RefreshTokenResult>("post", "/refreshToken", { data });
 };
+/** 用户注册 */
+export const getRegister = (data?: object) => {
+  return http.request<UserResult>("post", "/virtual-patient/user/register", {
+    data
+  });
+};
+/** 修改密码 */
+export const changePassWord = (data?: object) => {
+  return http.request<UserResult>(
+    "post",
+    "/virtual-patient/user/changePassWord",
+    {
+      data
+    }
+  );
+};
diff --git a/src/api/utils.ts b/src/api/utils.ts
new file mode 100644
index 0000000..382baa7
--- /dev/null
+++ b/src/api/utils.ts
@@ -0,0 +1,32 @@
+import { http } from "@/utils/http";
+
+/** 查询字典树 */
+export const queryCommonDictTree = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/commonDic/queryCommonDictTree",
+    {
+      params: data
+    }
+  );
+};
+/** 上传文件*/
+
+export const uploadFile = (data?: object) => {
+  return http.request(
+    "post",
+    "/virtual-patient-manage/fileManage/uploadFile",
+    { data },
+    { headers: { "Content-Type": "multipart/form-data" } }
+  );
+};
+
+export const loadFileBase64 = (data?: object) => {
+  return http.request(
+    "get",
+    "/virtual-patient-manage/fileManage/loadFileBase64",
+    {
+      params: data
+    }
+  );
+};
diff --git a/src/assets/inquiry/people/abdomen_detail.png b/src/assets/inquiry/people/abdomen_detail.png
index 10efa8b..be7dd77 100644
Binary files a/src/assets/inquiry/people/abdomen_detail.png and b/src/assets/inquiry/people/abdomen_detail.png differ
diff --git a/src/assets/inquiry/people/back.png b/src/assets/inquiry/people/back.png
index a5ff5a4..0fdaef9 100644
Binary files a/src/assets/inquiry/people/back.png and b/src/assets/inquiry/people/back.png differ
diff --git a/src/assets/inquiry/people/back_detail.png b/src/assets/inquiry/people/back_detail.png
index 5d631cc..29f9d05 100644
Binary files a/src/assets/inquiry/people/back_detail.png and b/src/assets/inquiry/people/back_detail.png differ
diff --git a/src/assets/inquiry/people/chest_detail.png b/src/assets/inquiry/people/chest_detail.png
index 94185ff..111c1f4 100644
Binary files a/src/assets/inquiry/people/chest_detail.png and b/src/assets/inquiry/people/chest_detail.png differ
diff --git a/src/assets/inquiry/people/header_detail.png b/src/assets/inquiry/people/header_detail.png
index d6a5953..067c50b 100644
Binary files a/src/assets/inquiry/people/header_detail.png and b/src/assets/inquiry/people/header_detail.png differ
diff --git a/src/assets/inquiry/people/left_hand_detail.png b/src/assets/inquiry/people/left_hand_detail.png
index 59756d6..f24b886 100644
Binary files a/src/assets/inquiry/people/left_hand_detail.png and b/src/assets/inquiry/people/left_hand_detail.png differ
diff --git a/src/assets/inquiry/people/left_leg_detail.png b/src/assets/inquiry/people/left_leg_detail.png
index c811a04..e549d9a 100644
Binary files a/src/assets/inquiry/people/left_leg_detail.png and b/src/assets/inquiry/people/left_leg_detail.png differ
diff --git a/src/assets/inquiry/people/right_hand_detail.png b/src/assets/inquiry/people/right_hand_detail.png
index 9a645e1..8d3c622 100644
Binary files a/src/assets/inquiry/people/right_hand_detail.png and b/src/assets/inquiry/people/right_hand_detail.png differ
diff --git a/src/assets/inquiry/people/right_leg_detail.png b/src/assets/inquiry/people/right_leg_detail.png
index 1091308..56a01ec 100644
Binary files a/src/assets/inquiry/people/right_leg_detail.png and b/src/assets/inquiry/people/right_leg_detail.png differ
diff --git a/src/assets/inquiry/renti.png b/src/assets/inquiry/renti.png
new file mode 100644
index 0000000..26b4d9f
Binary files /dev/null and b/src/assets/inquiry/renti.png differ
diff --git a/src/assets/inquiry/toke.gif b/src/assets/inquiry/toke.gif
index 264bb92..9c79881 100644
Binary files a/src/assets/inquiry/toke.gif and b/src/assets/inquiry/toke.gif differ
diff --git a/src/assets/inquiry/voice.gif b/src/assets/inquiry/voice.gif
deleted file mode 100644
index 52a0231..0000000
Binary files a/src/assets/inquiry/voice.gif and /dev/null differ
diff --git a/src/assets/login/register.png b/src/assets/login/register.png
new file mode 100644
index 0000000..a67ac28
Binary files /dev/null and b/src/assets/login/register.png differ
diff --git a/src/assets/newInquiry/add.png b/src/assets/newInquiry/add.png
new file mode 100644
index 0000000..456c412
Binary files /dev/null and b/src/assets/newInquiry/add.png differ
diff --git a/src/assets/newInquiry/add_tab.png b/src/assets/newInquiry/add_tab.png
new file mode 100644
index 0000000..f56c061
Binary files /dev/null and b/src/assets/newInquiry/add_tab.png differ
diff --git a/src/assets/newInquiry/audio.png b/src/assets/newInquiry/audio.png
new file mode 100644
index 0000000..d187653
Binary files /dev/null and b/src/assets/newInquiry/audio.png differ
diff --git a/src/assets/newInquiry/audio_img.png b/src/assets/newInquiry/audio_img.png
new file mode 100644
index 0000000..e77c1e1
Binary files /dev/null and b/src/assets/newInquiry/audio_img.png differ
diff --git a/src/assets/newInquiry/body_title.png b/src/assets/newInquiry/body_title.png
new file mode 100644
index 0000000..8a3d021
Binary files /dev/null and b/src/assets/newInquiry/body_title.png differ
diff --git a/src/assets/newInquiry/down.png b/src/assets/newInquiry/down.png
new file mode 100644
index 0000000..8a3523c
Binary files /dev/null and b/src/assets/newInquiry/down.png differ
diff --git a/src/assets/newInquiry/edit.png b/src/assets/newInquiry/edit.png
new file mode 100644
index 0000000..51cc55f
Binary files /dev/null and b/src/assets/newInquiry/edit.png differ
diff --git a/src/assets/newInquiry/empty.png b/src/assets/newInquiry/empty.png
new file mode 100644
index 0000000..834f71d
Binary files /dev/null and b/src/assets/newInquiry/empty.png differ
diff --git a/src/assets/newInquiry/empty_res.png b/src/assets/newInquiry/empty_res.png
new file mode 100644
index 0000000..039db29
Binary files /dev/null and b/src/assets/newInquiry/empty_res.png differ
diff --git a/src/assets/newInquiry/empty_table.png b/src/assets/newInquiry/empty_table.png
new file mode 100644
index 0000000..c318e9c
Binary files /dev/null and b/src/assets/newInquiry/empty_table.png differ
diff --git a/src/assets/newInquiry/evaluate/bodyInspect.png b/src/assets/newInquiry/evaluate/bodyInspect.png
new file mode 100644
index 0000000..b0873d6
Binary files /dev/null and b/src/assets/newInquiry/evaluate/bodyInspect.png differ
diff --git a/src/assets/newInquiry/evaluate/clinicalThinking.png b/src/assets/newInquiry/evaluate/clinicalThinking.png
new file mode 100644
index 0000000..6944dd3
Binary files /dev/null and b/src/assets/newInquiry/evaluate/clinicalThinking.png differ
diff --git a/src/assets/newInquiry/evaluate/disposalPlan.png b/src/assets/newInquiry/evaluate/disposalPlan.png
new file mode 100644
index 0000000..19f9155
Binary files /dev/null and b/src/assets/newInquiry/evaluate/disposalPlan.png differ
diff --git a/src/assets/newInquiry/evaluate/inquiry.png b/src/assets/newInquiry/evaluate/inquiry.png
new file mode 100644
index 0000000..a9926b9
Binary files /dev/null and b/src/assets/newInquiry/evaluate/inquiry.png differ
diff --git a/src/assets/newInquiry/evaluate/support.png b/src/assets/newInquiry/evaluate/support.png
new file mode 100644
index 0000000..63b6b9f
Binary files /dev/null and b/src/assets/newInquiry/evaluate/support.png differ
diff --git a/src/assets/newInquiry/file.png b/src/assets/newInquiry/file.png
new file mode 100644
index 0000000..9d73327
Binary files /dev/null and b/src/assets/newInquiry/file.png differ
diff --git a/src/assets/newInquiry/folder.png b/src/assets/newInquiry/folder.png
new file mode 100644
index 0000000..a9d32d7
Binary files /dev/null and b/src/assets/newInquiry/folder.png differ
diff --git a/src/assets/newInquiry/go_back.png b/src/assets/newInquiry/go_back.png
new file mode 100644
index 0000000..5e5bd5c
Binary files /dev/null and b/src/assets/newInquiry/go_back.png differ
diff --git a/src/assets/newInquiry/inspect_icon.png b/src/assets/newInquiry/inspect_icon.png
new file mode 100644
index 0000000..b2edea7
Binary files /dev/null and b/src/assets/newInquiry/inspect_icon.png differ
diff --git a/src/assets/newInquiry/main_bg.png b/src/assets/newInquiry/main_bg.png
new file mode 100644
index 0000000..4a3eaf3
Binary files /dev/null and b/src/assets/newInquiry/main_bg.png differ
diff --git a/src/assets/newInquiry/people.jpg b/src/assets/newInquiry/people.jpg
new file mode 100644
index 0000000..9ebcca5
Binary files /dev/null and b/src/assets/newInquiry/people.jpg differ
diff --git a/src/assets/newInquiry/plan_tip.png b/src/assets/newInquiry/plan_tip.png
new file mode 100644
index 0000000..741679c
Binary files /dev/null and b/src/assets/newInquiry/plan_tip.png differ
diff --git a/src/assets/newInquiry/play.png b/src/assets/newInquiry/play.png
new file mode 100644
index 0000000..2aa2bf3
Binary files /dev/null and b/src/assets/newInquiry/play.png differ
diff --git a/src/assets/newInquiry/select_bg.png b/src/assets/newInquiry/select_bg.png
new file mode 100644
index 0000000..914bdc8
Binary files /dev/null and b/src/assets/newInquiry/select_bg.png differ
diff --git a/src/assets/newInquiry/spirit_icon.png b/src/assets/newInquiry/spirit_icon.png
new file mode 100644
index 0000000..b0b0c1e
Binary files /dev/null and b/src/assets/newInquiry/spirit_icon.png differ
diff --git a/src/assets/newInquiry/success.png b/src/assets/newInquiry/success.png
new file mode 100644
index 0000000..f65123b
Binary files /dev/null and b/src/assets/newInquiry/success.png differ
diff --git a/src/assets/newInquiry/support_icon.png b/src/assets/newInquiry/support_icon.png
new file mode 100644
index 0000000..36f8232
Binary files /dev/null and b/src/assets/newInquiry/support_icon.png differ
diff --git a/src/assets/newInquiry/tab/act_assist.png b/src/assets/newInquiry/tab/act_assist.png
new file mode 100644
index 0000000..3958d1c
Binary files /dev/null and b/src/assets/newInquiry/tab/act_assist.png differ
diff --git a/src/assets/newInquiry/tab/act_body_inspect.png b/src/assets/newInquiry/tab/act_body_inspect.png
new file mode 100644
index 0000000..d2f3ba4
Binary files /dev/null and b/src/assets/newInquiry/tab/act_body_inspect.png differ
diff --git a/src/assets/newInquiry/tab/act_case_icon.png b/src/assets/newInquiry/tab/act_case_icon.png
new file mode 100644
index 0000000..9ad115b
Binary files /dev/null and b/src/assets/newInquiry/tab/act_case_icon.png differ
diff --git a/src/assets/newInquiry/tab/act_confirm.png b/src/assets/newInquiry/tab/act_confirm.png
new file mode 100644
index 0000000..debef2d
Binary files /dev/null and b/src/assets/newInquiry/tab/act_confirm.png differ
diff --git a/src/assets/newInquiry/tab/act_confirm_icon.png b/src/assets/newInquiry/tab/act_confirm_icon.png
new file mode 100644
index 0000000..07ee99b
Binary files /dev/null and b/src/assets/newInquiry/tab/act_confirm_icon.png differ
diff --git a/src/assets/newInquiry/tab/act_ev_detai.png b/src/assets/newInquiry/tab/act_ev_detai.png
new file mode 100644
index 0000000..e9826e5
Binary files /dev/null and b/src/assets/newInquiry/tab/act_ev_detai.png differ
diff --git a/src/assets/newInquiry/tab/act_evaluate.png b/src/assets/newInquiry/tab/act_evaluate.png
new file mode 100644
index 0000000..4ec68f7
Binary files /dev/null and b/src/assets/newInquiry/tab/act_evaluate.png differ
diff --git a/src/assets/newInquiry/tab/act_first_icon.png b/src/assets/newInquiry/tab/act_first_icon.png
new file mode 100644
index 0000000..93aa7e2
Binary files /dev/null and b/src/assets/newInquiry/tab/act_first_icon.png differ
diff --git a/src/assets/newInquiry/tab/act_graph.png b/src/assets/newInquiry/tab/act_graph.png
new file mode 100644
index 0000000..13ed998
Binary files /dev/null and b/src/assets/newInquiry/tab/act_graph.png differ
diff --git a/src/assets/newInquiry/tab/act_history_icon.png b/src/assets/newInquiry/tab/act_history_icon.png
new file mode 100644
index 0000000..6617e9e
Binary files /dev/null and b/src/assets/newInquiry/tab/act_history_icon.png differ
diff --git a/src/assets/newInquiry/tab/act_plan.png b/src/assets/newInquiry/tab/act_plan.png
new file mode 100644
index 0000000..4a4464a
Binary files /dev/null and b/src/assets/newInquiry/tab/act_plan.png differ
diff --git a/src/assets/newInquiry/tab/act_record.png b/src/assets/newInquiry/tab/act_record.png
new file mode 100644
index 0000000..e939610
Binary files /dev/null and b/src/assets/newInquiry/tab/act_record.png differ
diff --git a/src/assets/newInquiry/tab/act_support_icon.png b/src/assets/newInquiry/tab/act_support_icon.png
new file mode 100644
index 0000000..fade3c1
Binary files /dev/null and b/src/assets/newInquiry/tab/act_support_icon.png differ
diff --git a/src/assets/newInquiry/tab/body_inspect.png b/src/assets/newInquiry/tab/body_inspect.png
new file mode 100644
index 0000000..fa96fcc
Binary files /dev/null and b/src/assets/newInquiry/tab/body_inspect.png differ
diff --git a/src/assets/newInquiry/tab/case.png b/src/assets/newInquiry/tab/case.png
new file mode 100644
index 0000000..dfc72da
Binary files /dev/null and b/src/assets/newInquiry/tab/case.png differ
diff --git a/src/assets/newInquiry/tab/case_icon.png b/src/assets/newInquiry/tab/case_icon.png
new file mode 100644
index 0000000..106b189
Binary files /dev/null and b/src/assets/newInquiry/tab/case_icon.png differ
diff --git a/src/assets/newInquiry/tab/confirm.png b/src/assets/newInquiry/tab/confirm.png
new file mode 100644
index 0000000..6c60ff2
Binary files /dev/null and b/src/assets/newInquiry/tab/confirm.png differ
diff --git a/src/assets/newInquiry/tab/confirm_icon.png b/src/assets/newInquiry/tab/confirm_icon.png
new file mode 100644
index 0000000..0a1a1f3
Binary files /dev/null and b/src/assets/newInquiry/tab/confirm_icon.png differ
diff --git a/src/assets/newInquiry/tab/ev_detail.png b/src/assets/newInquiry/tab/ev_detail.png
new file mode 100644
index 0000000..229b517
Binary files /dev/null and b/src/assets/newInquiry/tab/ev_detail.png differ
diff --git a/src/assets/newInquiry/tab/evaluate.png b/src/assets/newInquiry/tab/evaluate.png
new file mode 100644
index 0000000..ce738c0
Binary files /dev/null and b/src/assets/newInquiry/tab/evaluate.png differ
diff --git a/src/assets/newInquiry/tab/fast_inspect.png b/src/assets/newInquiry/tab/fast_inspect.png
new file mode 100644
index 0000000..5802faa
Binary files /dev/null and b/src/assets/newInquiry/tab/fast_inspect.png differ
diff --git a/src/assets/newInquiry/tab/first_icon.png b/src/assets/newInquiry/tab/first_icon.png
new file mode 100644
index 0000000..9e650c7
Binary files /dev/null and b/src/assets/newInquiry/tab/first_icon.png differ
diff --git a/src/assets/newInquiry/tab/first_inspect.png b/src/assets/newInquiry/tab/first_inspect.png
new file mode 100644
index 0000000..5e2778a
Binary files /dev/null and b/src/assets/newInquiry/tab/first_inspect.png differ
diff --git a/src/assets/newInquiry/tab/graph.png b/src/assets/newInquiry/tab/graph.png
new file mode 100644
index 0000000..e8053e2
Binary files /dev/null and b/src/assets/newInquiry/tab/graph.png differ
diff --git a/src/assets/newInquiry/tab/history_icon.png b/src/assets/newInquiry/tab/history_icon.png
new file mode 100644
index 0000000..3623b0b
Binary files /dev/null and b/src/assets/newInquiry/tab/history_icon.png differ
diff --git a/src/assets/newInquiry/tab/plan.png b/src/assets/newInquiry/tab/plan.png
new file mode 100644
index 0000000..1b922eb
Binary files /dev/null and b/src/assets/newInquiry/tab/plan.png differ
diff --git a/src/assets/newInquiry/tab/record.png b/src/assets/newInquiry/tab/record.png
new file mode 100644
index 0000000..b74518c
Binary files /dev/null and b/src/assets/newInquiry/tab/record.png differ
diff --git a/src/assets/newInquiry/tab/support_icon.png b/src/assets/newInquiry/tab/support_icon.png
new file mode 100644
index 0000000..23623e2
Binary files /dev/null and b/src/assets/newInquiry/tab/support_icon.png differ
diff --git a/src/assets/newInquiry/text_icon.png b/src/assets/newInquiry/text_icon.png
new file mode 100644
index 0000000..2597e36
Binary files /dev/null and b/src/assets/newInquiry/text_icon.png differ
diff --git a/src/assets/newInquiry/title_icon.png b/src/assets/newInquiry/title_icon.png
new file mode 100644
index 0000000..d22baf8
Binary files /dev/null and b/src/assets/newInquiry/title_icon.png differ
diff --git a/src/assets/newInquiry/upload.png b/src/assets/newInquiry/upload.png
new file mode 100644
index 0000000..f004414
Binary files /dev/null and b/src/assets/newInquiry/upload.png differ
diff --git a/src/assets/newInquiry/video_icon.png b/src/assets/newInquiry/video_icon.png
new file mode 100644
index 0000000..d7f478a
Binary files /dev/null and b/src/assets/newInquiry/video_icon.png differ
diff --git a/src/assets/newInquiry/viedo.png b/src/assets/newInquiry/viedo.png
new file mode 100644
index 0000000..92db79f
Binary files /dev/null and b/src/assets/newInquiry/viedo.png differ
diff --git a/src/assets/newInquiry/view_icon.png b/src/assets/newInquiry/view_icon.png
new file mode 100644
index 0000000..21386ea
Binary files /dev/null and b/src/assets/newInquiry/view_icon.png differ
diff --git a/src/assets/newInquiry/work_icon.png b/src/assets/newInquiry/work_icon.png
new file mode 100644
index 0000000..08874b7
Binary files /dev/null and b/src/assets/newInquiry/work_icon.png differ
diff --git a/src/assets/svg/add_item.svg b/src/assets/svg/add_item.svg
new file mode 100644
index 0000000..1d23691
--- /dev/null
+++ b/src/assets/svg/add_item.svg
@@ -0,0 +1,8 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="tianjia">
+<rect id="Rectangle 1949" x="0.5" y="0.5" width="19" height="19" rx="3.5" fill="white" stroke="#D9D9D9"/>
+<g id="&#230;&#183;&#187;&#229;&#138;&#160; 1">
+<path id="Vector" d="M13.9926 9.39973H10.5945V6.00168C10.5945 5.84262 10.5313 5.69008 10.4189 5.57761C10.3064 5.46514 10.1539 5.40195 9.99481 5.40195C9.83576 5.40195 9.68321 5.46514 9.57074 5.57761C9.45828 5.69008 9.39509 5.84262 9.39509 6.00168V9.39973H5.99704C5.83798 9.39973 5.68544 9.46291 5.57297 9.57538C5.4605 9.68785 5.39731 9.84039 5.39731 9.99945C5.39731 10.1585 5.4605 10.311 5.57297 10.4235C5.68544 10.536 5.83798 10.5992 5.99704 10.5992H9.39509V13.9972C9.39509 14.1563 9.45828 14.3088 9.57074 14.4213C9.68321 14.5338 9.83576 14.5969 9.99481 14.5969C10.1539 14.5969 10.3064 14.5338 10.4189 14.4213C10.5313 14.3088 10.5945 14.1563 10.5945 13.9972V10.5992H13.9926C14.1516 10.5992 14.3042 10.536 14.4167 10.4235C14.5291 10.311 14.5923 10.1585 14.5923 9.99945C14.5923 9.84039 14.5291 9.68785 14.4167 9.57538C14.3042 9.46291 14.1516 9.39973 13.9926 9.39973Z" fill="#D9D9D9" stroke="#D9D9D9" stroke-width="0.2"/>
+</g>
+</g>
+</svg>
diff --git a/src/assets/svg/consultation/check.svg b/src/assets/svg/consultation/check.svg
new file mode 100644
index 0000000..ce1e920
--- /dev/null
+++ b/src/assets/svg/consultation/check.svg
@@ -0,0 +1,11 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="zhengque" clip-path="url(#clip0_351_1042)">
+<path id="Vector" d="M9 16.5C11.071 16.5 12.946 15.6605 14.3033 14.3033C15.6605 12.946 16.5 11.071 16.5 9C16.5 6.92895 15.6605 5.05395 14.3033 3.6967C12.946 2.33947 11.071 1.5 9 1.5C6.92895 1.5 5.05395 2.33947 3.6967 3.6967C2.33947 5.05395 1.5 6.92895 1.5 9C1.5 11.071 2.33947 12.946 3.6967 14.3033C5.05395 15.6605 6.92895 16.5 9 16.5Z" fill="#0DB274" stroke="#0DB274" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M6 9L8.25 11.25L12.75 6.75" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_351_1042">
+<rect width="18" height="18" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/close.svg b/src/assets/svg/consultation/close.svg
new file mode 100644
index 0000000..fa8c10f
--- /dev/null
+++ b/src/assets/svg/consultation/close.svg
@@ -0,0 +1,10 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="guanbi" clip-path="url(#clip0_311_6682)">
+<path id="Vector" d="M8.5 7L13.7 1.8C14.1 1.4 14.1 0.7 13.7 0.3C13.3 -0.1 12.6 -0.1 12.2 0.3L7 5.5L1.8 0.3C1.4 -0.1 0.7 -0.1 0.3 0.3C-0.1 0.7 -0.1 1.4 0.3 1.8L5.5 7L0.3 12.2C-0.1 12.6 -0.1 13.3 0.3 13.7C0.7 14.1 1.4 14.1 1.8 13.7L7 8.5L12.2 13.7C12.6 14.1 13.3 14.1 13.7 13.7C14.1 13.3 14.1 12.6 13.7 12.2L8.5 7Z" fill="#999999"/>
+</g>
+<defs>
+<clipPath id="clip0_311_6682">
+<rect width="14" height="14" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/del.svg b/src/assets/svg/consultation/del.svg
new file mode 100644
index 0000000..6fda081
--- /dev/null
+++ b/src/assets/svg/consultation/del.svg
@@ -0,0 +1,11 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="shanchu" clip-path="url(#clip0_351_973)">
+<path id="Vector" d="M13.9465 4.01804H10.6743V3.23136C10.6743 2.27681 9.92672 1.5 9.0081 1.5H6.78521C5.86659 1.5 5.11903 2.27681 5.11903 3.23136V4.01804H2.05434C1.74787 4.01804 1.5 4.2756 1.5 4.59406C1.5 4.91252 1.74787 5.17008 2.05434 5.17008H2.96187V12.149C2.96187 13.4459 3.9771 14.5 5.22435 14.5H10.58C11.8281 14.5 12.8425 13.4451 12.8425 12.149V5.17008H13.9457C14.2521 5.17008 14.5 4.91252 14.5 4.59406C14.5 4.2756 14.2529 4.01804 13.9465 4.01804ZM6.2277 3.23136C6.2277 2.91208 6.47795 2.65204 6.78521 2.65204H9.00889C9.31615 2.65204 9.5664 2.91208 9.5664 3.23136V4.01804H6.2277V3.23136ZM11.7346 12.1482C11.7346 12.8098 11.2167 13.3471 10.5808 13.3471H5.22515C4.58845 13.3471 4.07133 12.809 4.07133 12.1482V5.17008H11.7354V12.1482H11.7346Z" fill="#FF3B39"/>
+<path id="Vector_2" d="M6.55096 7C6.24636 7 6 7.27543 6 7.61598V11.384C6 11.7246 6.24636 12 6.55096 12C6.85557 12 7.10193 11.7246 7.10193 11.384V7.61598C7.10193 7.27543 6.85557 7 6.55096 7ZM9.44904 7C9.14443 7 8.89807 7.27543 8.89807 7.61598V11.384C8.89807 11.7246 9.14443 12 9.44904 12C9.75364 12 10 11.7246 10 11.384V7.61598C10 7.27543 9.75285 7 9.44904 7Z" fill="#FF3B39"/>
+</g>
+<defs>
+<clipPath id="clip0_351_973">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/down.svg b/src/assets/svg/consultation/down.svg
new file mode 100644
index 0000000..60e0d89
--- /dev/null
+++ b/src/assets/svg/consultation/down.svg
@@ -0,0 +1,5 @@
+<svg width="11" height="6" viewBox="0 0 11 6" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="xiala">
+<path id="xiala_2" d="M0.142313 0.827435L5.14686 5.85395C5.34073 6.04868 5.65927 6.04868 5.85315 5.85395L10.8577 0.827435C11.1644 0.51942 10.9427 0 10.5045 0H0.495464C0.0573317 0 -0.164358 0.51942 0.142313 0.827435Z" fill="#2B3F54"/>
+</g>
+</svg>
diff --git a/src/assets/svg/consultation/download.svg b/src/assets/svg/consultation/download.svg
new file mode 100644
index 0000000..cd6d708
--- /dev/null
+++ b/src/assets/svg/consultation/download.svg
@@ -0,0 +1,13 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="xiazai" clip-path="url(#clip0_1507_5683)">
+<path id="Vector" d="M16.375 2.5H3.625C3.00368 2.5 2.5 3.00368 2.5 3.625V16.375C2.5 16.9963 3.00368 17.5 3.625 17.5H16.375C16.9963 17.5 17.5 16.9963 17.5 16.375V3.625C17.5 3.00368 16.9963 2.5 16.375 2.5Z" stroke="#333333" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M13.3333 2.5V10H6.25V2.5H13.3333Z" stroke="#333333" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_3" d="M10.833 5.41602V7.08268" stroke="#333333" stroke-width="1.5" stroke-linecap="round"/>
+<path id="Vector_4" d="M4.58203 2.5H14.9993" stroke="#333333" stroke-width="1.5" stroke-linecap="round"/>
+</g>
+<defs>
+<clipPath id="clip0_1507_5683">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/edit.svg b/src/assets/svg/consultation/edit.svg
new file mode 100644
index 0000000..91145c3
--- /dev/null
+++ b/src/assets/svg/consultation/edit.svg
@@ -0,0 +1,12 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="bianji">
+<g id="xiugai" clip-path="url(#clip0_351_961)">
+<path id="Vector" d="M0.924731 15.067L0.924392 15.0665L0.924395 15.0665C0.867743 14.9761 0.837695 14.8716 0.837695 14.7649C0.837695 14.6582 0.867743 14.5537 0.924395 14.4633L0.924468 14.4632C0.983266 14.37 1.06488 14.2933 1.16159 14.2404C1.25826 14.1876 1.36682 14.1602 1.47699 14.161H1.47676V14.211L1.47713 14.161L0.924731 15.067ZM0.924731 15.067C0.984177 15.1592 1.06605 15.2349 1.16269 15.2869C1.25925 15.3389 1.3674 15.3655 1.47705 15.3643M0.924731 15.067L1.47676 15.3143M14.7131 15.3643C14.8228 15.3655 14.9309 15.3389 15.0275 15.2869C15.1241 15.2349 15.206 15.1592 15.2655 15.067L15.2234 15.0399L15.2656 15.0667C15.3234 14.9757 15.354 14.8702 15.3537 14.7624C15.3535 14.6547 15.3225 14.5492 15.2644 14.4585L15.2644 14.4584C15.205 14.3661 15.1231 14.2903 15.0265 14.2383C14.9299 14.1863 14.8217 14.1597 14.712 14.161L1.47676 15.3143M14.7131 15.3643C14.7131 15.3643 14.713 15.3643 14.7129 15.3643L14.7134 15.3143V15.3643H14.7131ZM14.7131 15.3643H1.47705M1.47705 15.3643C1.47713 15.3643 1.47722 15.3643 1.47731 15.3643L1.47676 15.3143M1.47705 15.3643H1.47676V15.3143M8.50934 10.7868L8.50938 10.7869L8.51099 10.7853L13.791 5.50859L13.7911 5.50853C14.1093 5.18944 14.2879 4.7572 14.2879 4.30656C14.2879 3.85593 14.1093 3.42368 13.7911 3.10459L13.791 3.10453L12.0054 1.32008L12.0055 1.32007L12.0045 1.31917C11.6792 1.01065 11.2479 0.838672 10.7995 0.838672C10.3512 0.838672 9.91991 1.01065 9.59458 1.31917L9.59457 1.31916L9.59365 1.32008L4.31365 6.59452L4.31361 6.59448L4.31205 6.59619C3.74161 7.22119 3.37721 8.00653 3.26829 8.84568L3.26824 8.84567L3.26805 8.84795L3.14805 10.2813L3.14804 10.2813L3.14723 10.2911C3.09185 10.9595 3.0636 11.3004 3.07321 11.4964C3.0781 11.5962 3.09291 11.6641 3.12226 11.7205C3.15053 11.7749 3.19063 11.8148 3.23531 11.8592L3.23818 11.862L3.23829 11.8621C3.35271 11.9751 3.507 12.0386 3.66781 12.0388H3.66787C3.73193 12.0388 4.02332 12.015 4.53964 11.9728C4.62727 11.9656 4.72137 11.9579 4.82193 11.9497L4.82204 11.9497L6.25759 11.8297L6.2576 11.8298L6.25984 11.8295C7.09888 11.7209 7.88423 11.3569 8.50934 10.7868ZM4.7226 10.749L4.31692 10.782L4.34992 10.3763L4.34993 10.3762L4.4709 8.94555C4.55122 8.38617 4.79384 7.86263 5.16872 7.43976L10.4451 2.16782C10.4451 2.16777 10.4452 2.16771 10.4453 2.16766C10.5397 2.07513 10.6667 2.02331 10.799 2.02331C10.9312 2.02331 11.0582 2.07514 11.1527 2.16768C11.1528 2.16773 11.1528 2.16778 11.1529 2.16782L12.8669 3.87975L12.9378 3.95166C13.0307 4.0459 13.083 4.17281 13.0833 4.30514C13.0837 4.43736 13.0323 4.56447 12.9401 4.65921C12.94 4.65929 12.9399 4.65936 12.9398 4.65944L7.66248 9.93124C7.23936 10.3057 6.71593 10.5483 6.15667 10.6291L4.72271 10.7489L4.7226 10.749Z" fill="#4287FF" stroke="#4287FF" stroke-width="0.1"/>
+</g>
+</g>
+<defs>
+<clipPath id="clip0_351_961">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/more.svg b/src/assets/svg/consultation/more.svg
new file mode 100644
index 0000000..326a465
--- /dev/null
+++ b/src/assets/svg/consultation/more.svg
@@ -0,0 +1,8 @@
+<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="gengduo">
+<rect id="Rectangle 1973" width="30" height="30" rx="4" fill="#666666"/>
+<circle id="Ellipse 357" cx="7" cy="15" r="2" fill="white"/>
+<circle id="Ellipse 358" cx="15" cy="15" r="2" fill="white"/>
+<circle id="Ellipse 359" cx="23" cy="15" r="2" fill="white"/>
+</g>
+</svg>
diff --git a/src/assets/svg/consultation/record/act_reasonable.svg b/src/assets/svg/consultation/record/act_reasonable.svg
new file mode 100644
index 0000000..c70011a
--- /dev/null
+++ b/src/assets/svg/consultation/record/act_reasonable.svg
@@ -0,0 +1,11 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="heli-xuanzhong" clip-path="url(#clip0_542_564)">
+<path id="Vector" d="M10 18.3337C12.3012 18.3337 14.3845 17.4009 15.8925 15.8929C17.4006 14.3848 18.3333 12.3015 18.3333 10.0003C18.3333 7.69916 17.4006 5.61583 15.8925 4.10777C14.3845 2.59973 12.3012 1.66699 10 1.66699C7.69884 1.66699 5.6155 2.59973 4.10745 4.10777C2.59941 5.61583 1.66667 7.69916 1.66667 10.0003C1.66667 12.3015 2.59941 14.3848 4.10745 15.8929C5.6155 17.4009 7.69884 18.3337 10 18.3337Z" stroke="#00975E" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M6.66667 10L9.16667 12.5L14.1667 7.5" stroke="#00975E" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_542_564">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/record/act_unreasonable.svg b/src/assets/svg/consultation/record/act_unreasonable.svg
new file mode 100644
index 0000000..cda04e2
--- /dev/null
+++ b/src/assets/svg/consultation/record/act_unreasonable.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="buheli-xuanzhong" clip-path="url(#clip0_542_568)">
+<path id="Vector" d="M10 18.3337C14.6024 18.3337 18.3333 14.6027 18.3333 10.0003C18.3333 5.39795 14.6024 1.66699 10 1.66699C5.39762 1.66699 1.66666 5.39795 1.66666 10.0003C1.66666 14.6027 5.39762 18.3337 10 18.3337Z" stroke="#FF3429" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M12.357 7.64258L7.64291 12.3566" stroke="#FF3429" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M7.64304 7.64258L12.3571 12.3566" stroke="#FF3429" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_542_568">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/record/reasonable.svg b/src/assets/svg/consultation/record/reasonable.svg
new file mode 100644
index 0000000..71643a3
--- /dev/null
+++ b/src/assets/svg/consultation/record/reasonable.svg
@@ -0,0 +1,11 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="heli" clip-path="url(#clip0_542_573)">
+<path id="Vector" d="M10 18.3337C12.3012 18.3337 14.3845 17.4009 15.8925 15.8929C17.4006 14.3848 18.3333 12.3015 18.3333 10.0003C18.3333 7.69916 17.4006 5.61583 15.8925 4.10777C14.3845 2.59973 12.3012 1.66699 10 1.66699C7.69884 1.66699 5.6155 2.59973 4.10745 4.10777C2.59941 5.61583 1.66667 7.69916 1.66667 10.0003C1.66667 12.3015 2.59941 14.3848 4.10745 15.8929C5.6155 17.4009 7.69884 18.3337 10 18.3337Z" stroke="#999999" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M6.66667 10L9.16667 12.5L14.1667 7.5" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_542_573">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/record/unreasonable.svg b/src/assets/svg/consultation/record/unreasonable.svg
new file mode 100644
index 0000000..93d0534
--- /dev/null
+++ b/src/assets/svg/consultation/record/unreasonable.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="buheli" clip-path="url(#clip0_542_577)">
+<path id="Vector" d="M10 18.3337C14.6024 18.3337 18.3333 14.6027 18.3333 10.0003C18.3333 5.39795 14.6024 1.66699 10 1.66699C5.39762 1.66699 1.66666 5.39795 1.66666 10.0003C1.66666 14.6027 5.39762 18.3337 10 18.3337Z" stroke="#999999" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M12.357 7.64258L7.64291 12.3566" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M7.64304 7.64258L12.3571 12.3566" stroke="#999999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_542_577">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/success.svg b/src/assets/svg/consultation/success.svg
new file mode 100644
index 0000000..52ae496
--- /dev/null
+++ b/src/assets/svg/consultation/success.svg
@@ -0,0 +1,13 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="tishi" clip-path="url(#clip0_1492_1598)">
+<path id="Vector" d="M7 0C3.1 0 0 3.1 0 7C0 10.9 3.1 14 7 14C10.9 14 14 10.9 14 7C14 3.1 10.9 0 7 0Z" fill="#00975E"/>
+<g id="&#229;&#175;&#185;&#229;&#143;&#183; 2">
+<path id="Vector_2" d="M4.14564 6.15296C3.8463 5.85206 3.36038 5.85226 3.06059 6.15282L3.06046 6.15296C2.76162 6.45335 2.76162 6.9404 3.06046 7.24079L3.06052 7.24085L5.52864 9.71898L5.52886 9.71919L4.0393 6.25875M4.14564 6.15296L4.0393 6.25875M4.14564 6.15296L4.14557 6.1529L4.0393 6.25875M4.14564 6.15296L6.07117 8.08619M4.0393 6.25875L5.96532 8.19247L6.07117 8.08619M6.07117 8.08619L6.17703 8.19247L6.07117 8.29875L9.84735 4.29481L9.84739 4.29477L9.95367 4.40062L9.8472 4.29497L6.07117 8.08619Z" fill="white" stroke="white" stroke-width="0.3"/>
+</g>
+</g>
+<defs>
+<clipPath id="clip0_1492_1598">
+<rect width="14" height="14" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/consultation/warn.svg b/src/assets/svg/consultation/warn.svg
new file mode 100644
index 0000000..1acbcd1
--- /dev/null
+++ b/src/assets/svg/consultation/warn.svg
@@ -0,0 +1,10 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="tishi" clip-path="url(#clip0_1507_5706)">
+<path id="Vector" d="M7 0C3.1 0 0 3.1 0 7C0 10.9 3.1 14 7 14C10.9 14 14 10.9 14 7C14 3.1 10.9 0 7 0ZM7.8 11.2C7.8 11.7 7.5 12 7 12C6.5 12 6.2 11.7 6.2 11.2V6.6C6.2 6.1 6.5 5.8 7 5.8C7.5 5.8 7.8 6.1 7.8 6.6V11.2ZM8.2 3.6C8.2 4.3 7.6 4.8 7 4.8C6.4 4.8 5.8 4.3 5.8 3.6C5.8 2.9 6.3 2.3 7 2.3C7.7 2.3 8.2 2.9 8.2 3.6Z" fill="#FFA700"/>
+</g>
+<defs>
+<clipPath id="clip0_1507_5706">
+<rect width="14" height="14" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_confirm.svg b/src/assets/svg/evaluate/act_confirm.svg
new file mode 100644
index 0000000..18e8bf2
--- /dev/null
+++ b/src/assets/svg/evaluate/act_confirm.svg
@@ -0,0 +1,13 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="zhengshi" clip-path="url(#clip0_200_661)">
+<path id="Vector" d="M3.5 2.8C3.5 2.35817 3.91572 2 4.42857 2H15.5714C16.0843 2 16.5 2.35817 16.5 2.8V18L13.25 16L10 18L6.75 16L3.5 18V2.8Z" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M7.5 9.16699H12.5" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M7.5 12.5H12.5" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_4" d="M7.5 5.83301H12.5" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_661">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_discern.svg b/src/assets/svg/evaluate/act_discern.svg
new file mode 100644
index 0000000..775b831
--- /dev/null
+++ b/src/assets/svg/evaluate/act_discern.svg
@@ -0,0 +1,11 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="jianbie" clip-path="url(#clip0_200_697)">
+<path id="Vector" d="M3.3335 18.3332V2.49984C3.3335 2.0396 3.70659 1.6665 4.16683 1.6665H15.8335C16.2937 1.6665 16.6668 2.0396 16.6668 2.49984V18.3332L10.0002 14.8862L3.3335 18.3332Z" stroke="#4287FF" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M6.6665 7.5H13.3332" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_697">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_disposalPlan.svg b/src/assets/svg/evaluate/act_disposalPlan.svg
new file mode 100644
index 0000000..c53a26b
--- /dev/null
+++ b/src/assets/svg/evaluate/act_disposalPlan.svg
@@ -0,0 +1,15 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="chuzhi" clip-path="url(#clip0_200_746)">
+<path id="Vector" d="M16.25 2.5H3.75C3.05964 2.5 2.5 3.05964 2.5 3.75V16.25C2.5 16.9404 3.05964 17.5 3.75 17.5H16.25C16.9404 17.5 17.5 16.9404 17.5 16.25V3.75C17.5 3.05964 16.9404 2.5 16.25 2.5Z" stroke="#4287FF" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M1.66699 12.9165H6.25033L7.08366 14.5832H12.917L13.7503 12.9165H18.3337" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M17.5 15.0002V10.8335" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_4" d="M2.5 15.0002V10.8335" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_5" d="M7.08301 6.25H12.9163" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_6" d="M7.08301 9.5835H12.9163" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_746">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_history.svg b/src/assets/svg/evaluate/act_history.svg
new file mode 100644
index 0000000..b1be3a4
--- /dev/null
+++ b/src/assets/svg/evaluate/act_history.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="wenzhenlishi" clip-path="url(#clip0_200_804)">
+<path id="Vector" d="M2.4248 2.80322V5.83352H5.45511" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M1.66699 9.99984C1.66699 14.6022 5.39795 18.3332 10.0003 18.3332C14.6027 18.3332 18.3337 14.6022 18.3337 9.99984C18.3337 5.39746 14.6027 1.6665 10.0003 1.6665C6.91616 1.6665 4.22328 3.34197 2.78231 5.83238" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M10.0025 5L10.002 10.0037L13.535 13.5368" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_804">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_people.svg b/src/assets/svg/evaluate/act_people.svg
new file mode 100644
index 0000000..f0723cf
--- /dev/null
+++ b/src/assets/svg/evaluate/act_people.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="biaozhun" clip-path="url(#clip0_200_809)">
+<path id="Vector" d="M7.93163 18.3332C7.52334 17.0017 6.90738 16.009 6.08375 15.3553C4.84829 14.3747 2.88531 14.9841 2.1602 13.9726C1.4351 12.9612 2.66822 11.101 3.10094 10.0035C3.53365 8.906 1.44237 8.51792 1.68653 8.20638C1.8493 7.99863 2.90609 7.39925 4.85692 6.40817C5.41121 3.24705 7.45863 1.6665 10.9992 1.6665C16.31 1.6665 18.3333 6.16896 18.3333 9.03271C18.3333 11.8964 15.8833 14.9816 12.3933 15.6468C12.0813 16.1013 12.5314 16.9968 13.7436 18.3332" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M8.75904 1.9126C8.26408 4.09118 8.26408 5.78629 8.75904 6.998C9.50154 8.8155 12.7836 8.53625 12.7836 10.232C12.7836 11.9277 10.8712 12.2537 11.1264 13.4301C11.2965 14.2144 11.675 15.2316 12.2616 16.4817" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round"/>
+<path id="Vector_3" d="M7.08337 12.7293C7.18146 12.7293 8.08354 12.6717 8.73292 11.9995C9.16583 11.5514 9.38225 11.0237 9.38225 10.4165" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_809">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_result.svg b/src/assets/svg/evaluate/act_result.svg
new file mode 100644
index 0000000..997b540
--- /dev/null
+++ b/src/assets/svg/evaluate/act_result.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="chubu" clip-path="url(#clip0_200_616)">
+<path id="Vector" d="M4.16659 18.3332C3.70635 18.3332 3.33325 17.9601 3.33325 17.4998V2.49984C3.33325 2.0396 3.70635 1.6665 4.16659 1.6665H15.8333C16.2935 1.6665 16.6666 2.0396 16.6666 2.49984V17.4998C16.6666 17.9601 16.2935 18.3332 15.8333 18.3332H4.16659Z" stroke="#4287FF" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" fill-rule="evenodd" clip-rule="evenodd" d="M8.75 9.1665V1.6665H13.75V9.1665L11.25 6.55288L8.75 9.1665Z" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M4.16675 1.6665H15.8334" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_616">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/act_score.svg b/src/assets/svg/evaluate/act_score.svg
new file mode 100644
index 0000000..0855972
--- /dev/null
+++ b/src/assets/svg/evaluate/act_score.svg
@@ -0,0 +1,11 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="pingfen" clip-path="url(#clip0_200_527)">
+<path id="Vector" d="M3.33337 18.3332V1.6665H12.9167L16.6667 6.0415V18.3332H3.33337Z" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M9.99999 6.25L11.285 9.06463L14.359 9.417L12.0792 11.5089L12.694 14.5413L9.99999 13.0196L7.30599 14.5413L7.92074 11.5089L5.64099 9.417L8.71495 9.06463L9.99999 6.25Z" stroke="#4287FF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_527">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/amplify.svg b/src/assets/svg/evaluate/amplify.svg
new file mode 100644
index 0000000..9a057f5
--- /dev/null
+++ b/src/assets/svg/evaluate/amplify.svg
@@ -0,0 +1,13 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="fangda" clip-path="url(#clip0_371_98)">
+<path id="Vector" d="M8.75 15.8332C12.662 15.8332 15.8333 12.6618 15.8333 8.74984C15.8333 4.83784 12.662 1.6665 8.75 1.6665C4.838 1.6665 1.66667 4.83784 1.66667 8.74984C1.66667 12.6618 4.838 15.8332 8.75 15.8332Z" stroke="#333333" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M8.75 6.25V11.25" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M6.2565 8.7565L11.25 8.75" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_4" d="M13.8423 13.8423L17.3779 17.3778" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_371_98">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/confirm.svg b/src/assets/svg/evaluate/confirm.svg
new file mode 100644
index 0000000..d1113d6
--- /dev/null
+++ b/src/assets/svg/evaluate/confirm.svg
@@ -0,0 +1,13 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="zhengshi" clip-path="url(#clip0_200_621)">
+<path id="Vector" d="M3.5 2.8C3.5 2.35817 3.91572 2 4.42857 2H15.5714C16.0843 2 16.5 2.35817 16.5 2.8V18L13.25 16L10 18L6.75 16L3.5 18V2.8Z" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M7.5 9.16699H12.5" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M7.5 12.5H12.5" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_4" d="M7.5 5.83301H12.5" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_621">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/del.svg b/src/assets/svg/evaluate/del.svg
new file mode 100644
index 0000000..93a5f7e
--- /dev/null
+++ b/src/assets/svg/evaluate/del.svg
@@ -0,0 +1,12 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="shanchu" clip-path="url(#clip0_200_899)">
+<path id="Vector" d="M4.66666 3.66699L1.33333 8.00033L4.66666 12.3337H14.6667V3.66699H4.66666Z" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M7 6.33301L10.3333 9.66634" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M10.3333 6.33301L7 9.66634" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_899">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/discern.svg b/src/assets/svg/evaluate/discern.svg
new file mode 100644
index 0000000..b0b70b3
--- /dev/null
+++ b/src/assets/svg/evaluate/discern.svg
@@ -0,0 +1,11 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="jianbie" clip-path="url(#clip0_200_667)">
+<path id="Vector" d="M3.3335 18.3332V2.49984C3.3335 2.0396 3.70659 1.6665 4.16683 1.6665H15.8335C16.2937 1.6665 16.6668 2.0396 16.6668 2.49984V18.3332L10.0002 14.8862L3.3335 18.3332Z" stroke="#2B3F54" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M6.6665 7.5H13.3332" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_667">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/disposalPlan.svg b/src/assets/svg/evaluate/disposalPlan.svg
new file mode 100644
index 0000000..e158287
--- /dev/null
+++ b/src/assets/svg/evaluate/disposalPlan.svg
@@ -0,0 +1,15 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="chuzhi" clip-path="url(#clip0_200_689)">
+<path id="Vector" d="M16.25 2.5H3.75C3.05964 2.5 2.5 3.05964 2.5 3.75V16.25C2.5 16.9404 3.05964 17.5 3.75 17.5H16.25C16.9404 17.5 17.5 16.9404 17.5 16.25V3.75C17.5 3.05964 16.9404 2.5 16.25 2.5Z" stroke="#2B3F54" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M1.66699 12.9165H6.25033L7.08366 14.5832H12.917L13.7503 12.9165H18.3337" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M17.5 15.0002V10.8335" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_4" d="M2.5 15.0002V10.8335" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_5" d="M7.08301 6.25H12.9163" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_6" d="M7.08301 9.5835H12.9163" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_689">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/down.svg b/src/assets/svg/evaluate/down.svg
new file mode 100644
index 0000000..24abb64
--- /dev/null
+++ b/src/assets/svg/evaluate/down.svg
@@ -0,0 +1,12 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="shouqi" clip-path="url(#clip0_200_894)">
+<path id="Vector" d="M2 3H14" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M2 6.33301H14" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M2 8.66699L8 13.3337L14 8.66699" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_894">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/history.svg b/src/assets/svg/evaluate/history.svg
new file mode 100644
index 0000000..6694c71
--- /dev/null
+++ b/src/assets/svg/evaluate/history.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="wenzhenlishi" clip-path="url(#clip0_200_741)">
+<path id="Vector" d="M2.4248 2.80322V5.83352H5.45511" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M1.66699 9.99984C1.66699 14.6022 5.39795 18.3332 10.0003 18.3332C14.6027 18.3332 18.3337 14.6022 18.3337 9.99984C18.3337 5.39746 14.6027 1.6665 10.0003 1.6665C6.91616 1.6665 4.22328 3.34197 2.78231 5.83238" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M10.0025 5L10.002 10.0037L13.535 13.5368" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_741">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/inquiry.svg b/src/assets/svg/evaluate/inquiry.svg
new file mode 100644
index 0000000..d70603d
--- /dev/null
+++ b/src/assets/svg/evaluate/inquiry.svg
@@ -0,0 +1,14 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="wenzhen" clip-path="url(#clip0_200_814)">
+<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M3.33337 3.33333C3.33337 2.8731 3.70647 2.5 4.16671 2.5H11.25V7.5H16.6667V16.6667C16.6667 17.1269 16.2936 17.5 15.8334 17.5H4.16671C3.70647 17.5 3.33337 17.1269 3.33337 16.6667V3.33333Z" stroke="#2B3F54" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M11.25 2.5L16.6667 7.5" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M11.2601 2.5V7.53408H16.6665" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_4" d="M5.83337 12.5H10.8334" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round"/>
+<path id="Vector_5" d="M8.33337 10V15" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_814">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/reduce.svg b/src/assets/svg/evaluate/reduce.svg
new file mode 100644
index 0000000..692dd9b
--- /dev/null
+++ b/src/assets/svg/evaluate/reduce.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="suoxiao" clip-path="url(#clip0_371_104)">
+<path id="Vector" d="M8.75 15.8332C12.662 15.8332 15.8333 12.6618 15.8333 8.74984C15.8333 4.83784 12.662 1.6665 8.75 1.6665C4.838 1.6665 1.66667 4.83784 1.66667 8.74984C1.66667 12.6618 4.838 15.8332 8.75 15.8332Z" stroke="#333333" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" d="M6.25 8.75H11.25" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M13.8423 13.8423L17.3779 17.3778" stroke="#333333" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_371_104">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/result.svg b/src/assets/svg/evaluate/result.svg
new file mode 100644
index 0000000..9b2f41f
--- /dev/null
+++ b/src/assets/svg/evaluate/result.svg
@@ -0,0 +1,12 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="yuqi" clip-path="url(#clip0_200_531)">
+<path id="Vector" d="M4.16671 18.3332C3.70647 18.3332 3.33337 17.9601 3.33337 17.4998V2.49984C3.33337 2.0396 3.70647 1.6665 4.16671 1.6665H15.8334C16.2936 1.6665 16.6667 2.0396 16.6667 2.49984V17.4998C16.6667 17.9601 16.2936 18.3332 15.8334 18.3332H4.16671Z" stroke="#2B3F54" stroke-width="1.5" stroke-linejoin="round"/>
+<path id="Vector_2" fill-rule="evenodd" clip-rule="evenodd" d="M8.75 9.1665V1.6665H13.75V9.1665L11.25 6.55288L8.75 9.1665Z" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M4.16663 1.6665H15.8333" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_531">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/score.svg b/src/assets/svg/evaluate/score.svg
new file mode 100644
index 0000000..94b7e75
--- /dev/null
+++ b/src/assets/svg/evaluate/score.svg
@@ -0,0 +1,11 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="pingfen" clip-path="url(#clip0_200_607)">
+<path id="Vector" d="M3.33325 18.3332V1.6665H12.9166L16.6666 6.0415V18.3332H3.33325Z" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M10.0001 6.25L11.2852 9.06463L14.3591 9.417L12.0794 11.5089L12.6941 14.5413L10.0001 13.0196L7.30611 14.5413L7.92086 11.5089L5.64111 9.417L8.71507 9.06463L10.0001 6.25Z" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_607">
+<rect width="20" height="20" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/evaluate/select.svg b/src/assets/svg/evaluate/select.svg
new file mode 100644
index 0000000..dad4e5a
--- /dev/null
+++ b/src/assets/svg/evaluate/select.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="10" viewBox="0 0 16 10" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="xiala">
+<path id="xiala_2" d="M7.26545 9.20482C7.66137 9.63342 8.33863 9.63342 8.73455 9.20482L13.3776 4.17855C13.9693 3.53807 13.515 2.5 12.6431 2.5H3.35693C2.485 2.5 2.03073 3.53807 2.62238 4.17855L7.26545 9.20482Z" fill="#2B3F54"/>
+</g>
+</svg>
diff --git a/src/assets/svg/evaluate/up.svg b/src/assets/svg/evaluate/up.svg
new file mode 100644
index 0000000..a465abd
--- /dev/null
+++ b/src/assets/svg/evaluate/up.svg
@@ -0,0 +1,12 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="zhankai" clip-path="url(#clip0_200_919)">
+<path id="Vector" d="M2 13H14" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_2" d="M2 9.66699H14" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path id="Vector_3" d="M2 7.33301L8 2.66634L14 7.33301" stroke="#2B3F54" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_200_919">
+<rect width="16" height="16" fill="white" transform="matrix(1 0 0 -1 0 16)"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/svg/folder.svg b/src/assets/svg/folder.svg
new file mode 100644
index 0000000..7170395
--- /dev/null
+++ b/src/assets/svg/folder.svg
@@ -0,0 +1,14 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="xinjianwenjian" clip-path="url(#clip0_1507_5744)">
+<path id="Vector" d="M22.0311 22H1.96886C1.43305 22 1 21.561 1 21.0179V4.98208C1 4.43896 1.43305 4 1.96886 4H22.0311C22.5669 4 23 4.43896 23 4.98208V21.0179C23 21.5586 22.5645 22 22.0311 22Z" fill="#FFE9B4"/>
+<path id="Vector_2" d="M12.429 8.13636H1V3.00662C1 2.44992 1.44995 2 2.00664 2H9.82846C10.2733 2 10.6648 2.28979 10.7919 2.71683L12.429 8.13636Z" fill="#FFB02C"/>
+<path id="Vector_3" d="M22.0311 22H1.96886C1.43305 22 1 21.4909 1 20.8609V6.13909C1 5.50913 1.43305 5 1.96886 5H22.0311C22.5669 5 23 5.50913 23 6.13909V20.8609C23 21.488 22.5645 22 22.0311 22Z" fill="#FFCA28"/>
+<rect id="Rectangle 1968" x="7.25" y="12.5" width="9" height="1.5" fill="#FFAA0F"/>
+<rect id="Rectangle 1969" x="11" y="17.75" width="9" height="1.5" transform="rotate(-90 11 17.75)" fill="#FFAA0F"/>
+</g>
+<defs>
+<clipPath id="clip0_1507_5744">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/src/assets/tip.png b/src/assets/tip.png
new file mode 100644
index 0000000..526efc5
Binary files /dev/null and b/src/assets/tip.png differ
diff --git a/src/components/MaterialLibrary/index.vue b/src/components/MaterialLibrary/index.vue
new file mode 100644
index 0000000..2e43f63
--- /dev/null
+++ b/src/components/MaterialLibrary/index.vue
@@ -0,0 +1,511 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import videoImg from "@/assets/newInquiry/viedo.png";
+import playImg from "@/assets/newInquiry/play.png";
+import { downLoadUrl } from "@/utils/auth";
+import folderImg from "@/assets/newInquiry/folder.png";
+import { getFileDirectory, queryMedicalRecPage } from "@/api/generalRules";
+import { ArrowLeft } from "@element-plus/icons-vue";
+import PlayVideo from "@/components/PlayVideo/index.vue";
+import router from "@/router";
+defineOptions({
+  name: "MaterialLibrary"
+});
+
+const dialogVisible = ref(false);
+const seachName = ref("");
+const type = ref(1);
+const fileList = ref([]);
+const selectFileId = ref("");
+const selectId = ref("");
+const detailFlag = ref(false);
+const tableList = ref([]);
+const selectName = ref("");
+const selectFileName = ref("");
+const fileId = ref("");
+const PlayVideoRef = ref();
+defineExpose({
+  async open(val) {
+    dialogVisible.value = true;
+    type.value = val;
+    if (val === 1) {
+      getTableData();
+    } else {
+      search();
+    }
+  }
+});
+const page = reactive<any>({
+  total: 0,
+  pageSize: 999,
+  pageNum: 1
+});
+const getTableData = async () => {
+  const res: any = await getFileDirectory({
+    fileName: seachName.value
+  });
+  tableList.value = res.data;
+};
+const getData = async () => {
+  const res: any = await queryMedicalRecPage({
+    materialName: seachName.value,
+    materialType: type.value,
+    pageNum: page.pageNum,
+    pageSize: page.pageSize,
+    directoryId: type.value === 1 ? selectId.value : ""
+  });
+  fileList.value = res.data.records;
+  page.total = res.data.total;
+};
+const resetForm = () => {
+  seachName.value = "";
+  selectFileId.value = "";
+  detailFlag.value = false;
+  selectName.value = "";
+  fileId.value = "";
+  selectId.value = "";
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["select"]);
+const search = () => {
+  page.pageNum = 1;
+  if (type.value === 1 && !detailFlag.value) {
+    getTableData();
+  } else {
+    getData();
+  }
+};
+const selectImg = item => {
+  selectFileId.value = item.fileResourceId;
+  fileId.value = item.id;
+};
+const selectVideo = item => {
+  selectFileId.value = item.fileResourceId;
+  fileId.value = item.id;
+  selectFileName.value = item.materialName;
+};
+const openDetail = item => {
+  selectName.value = item.directoryName;
+  detailFlag.value = true;
+  selectId.value = item.id;
+  getData();
+};
+const submit = () => {
+  emit("select", selectFileId.value, selectFileName.value);
+  dialogVisible.value = false;
+  resetForm();
+};
+const goBack = () => {
+  selectName.value = "";
+  detailFlag.value = false;
+};
+const openVideo = id => {
+  PlayVideoRef.value.open(id, 1);
+};
+const goMaterialCenter = () => {
+  router.push("/generalRules/materialCenter");
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>素材库</span>
+        </div>
+        <div class="line" />
+        <div>
+          <el-input
+            style="width: 600px"
+            v-model="seachName"
+            clearable
+            size="large"
+            placeholder="请输入"
+          >
+            <template #prepend>
+              <el-select
+                disabled
+                size="large"
+                v-model="type"
+                placeholder="Select"
+                style="width: 85px"
+              >
+                <el-option label="图片" :value="0" />
+                <el-option label="视频" :value="1" />
+                <el-option label="音频" :value="2" />
+              </el-select>
+            </template>
+          </el-input>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+        </div>
+        <!-- 图片列表 -->
+        <div v-show="fileList.length > 0 && type === 0" class="img_card_list">
+          <div
+            class="img_card_item"
+            v-for="(item, index) in fileList"
+            :key="index"
+            @click="selectImg(item)"
+            :class="fileId === item.id ? 'actived' : ''"
+          >
+            <img :src="downLoadUrl(item.fileResourceId)" alt="" />
+
+            <div class="name">{{ item.materialName }}</div>
+          </div>
+        </div>
+        <!-- 文件夹列表 -->
+        <div
+          v-show="tableList.length > 0 && !detailFlag"
+          class="folder_card_list"
+        >
+          <div
+            class="folder_card_item"
+            v-for="(item, index) in tableList"
+            :key="index"
+            @click="openDetail(item)"
+          >
+            <div class="folder_img">
+              <img :src="folderImg" alt="" />
+            </div>
+            <div class="name">{{ item.directoryName }}</div>
+          </div>
+        </div>
+        <!-- 视频列表 -->
+        <div class="video_top" v-show="detailFlag">
+          <div @click="goBack" class="back_icon">
+            <el-icon><ArrowLeft /></el-icon>
+            <span>返回</span>
+          </div>
+
+          <span style="margin-left: 24px" class="name">{{ selectName }}</span>
+        </div>
+        <div class="video_list" v-show="detailFlag">
+          <div
+            v-for="(item, index) in fileList"
+            class="video_list_item"
+            @click="selectVideo(item)"
+            :class="fileId === item.id ? 'actived' : ''"
+            :key="index"
+          >
+            <div class="left">
+              <img :src="videoImg" alt="" />
+              <span>{{ item.materialName }}</span>
+            </div>
+            <div @click="openVideo(item.fileResourceId)" class="right">
+              <img :src="playImg" alt="" />
+              <span>点击播放</span>
+            </div>
+          </div>
+        </div>
+        <div
+          v-show="fileList.length === 0 && tableList.length === 0"
+          class="empty_list"
+        >
+          <img :src="emptyImg" alt="" />
+          <div @click="goMaterialCenter">
+            <span>暂无可用素材,可前往【</span>
+            <span style="color: #4287ff">通用规则-素材中心</span>
+            <span>】进行设置</span>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit()">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+    <PlayVideo ref="PlayVideoRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .back_icon {
+    display: flex;
+    align-items: center;
+    color: #999;
+    cursor: pointer;
+  }
+
+  .video_list {
+    display: flex;
+    flex-direction: column;
+
+    .actived {
+      border: 2px solid #4287ff;
+    }
+
+    .video_list_item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      height: 56px;
+      padding: 0 16px;
+      margin-top: 8px;
+      cursor: pointer;
+      border-radius: 6px;
+
+      .left {
+        display: flex;
+
+        img {
+          width: 24px;
+          height: 24px;
+          margin-right: 12px;
+        }
+
+        span {
+          width: 400px;
+          overflow: hidden;
+          color: #666;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+      }
+
+      .right {
+        display: flex;
+        align-items: center;
+        color: #4287ff;
+        cursor: pointer;
+
+        img {
+          width: 16px;
+          height: 16px;
+          margin-right: 12px;
+        }
+      }
+    }
+
+    .video_list_item:hover {
+      border: 2px solid #4287ff;
+    }
+  }
+
+  .video_top {
+    display: flex;
+    margin-top: 16px;
+  }
+
+  .folder_card_list {
+    display: flex;
+    flex-wrap: wrap;
+    margin-top: 16px;
+
+    .folder_card_item {
+      width: 190px;
+      height: 230px;
+      margin-right: 16px;
+      margin-bottom: 16px;
+      cursor: pointer;
+      background: #fff;
+      border-radius: 0 0 12px 12px;
+      box-shadow: 0 2px 4px 0 rgb(0 0 0 / 8%);
+
+      .folder_img {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 190px;
+        background: #f5f5f5;
+
+        img {
+          width: 130px;
+          height: 130px;
+        }
+      }
+
+      .name {
+        width: 200px;
+        padding: 8px 16px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+
+  .img_card_list {
+    display: flex;
+    flex-wrap: wrap;
+    margin-top: 24px;
+
+    .actived {
+      border: 2px solid #4287ff;
+    }
+
+    .img_card_item {
+      width: 190px;
+      height: 230px;
+      margin-right: 16px;
+      cursor: pointer;
+      background: #fff;
+      border-radius: 12px;
+      box-shadow: 0 2px 4px 0 rgb(0 0 0 / 8%);
+
+      img {
+        width: 190px;
+        height: 190px;
+        border-radius: 12px 12px 0 0;
+      }
+
+      .name {
+        width: 200px;
+        padding: 8px 16px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+
+    .img_card_item:hover {
+      border: 2px solid #4287ff;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    margin-top: 200px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+
+    span {
+      cursor: pointer;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .normal_list {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+
+    .normal_list_item {
+      margin-bottom: 12px;
+      border: 1px solid #d9d9d9;
+
+      .top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 36px;
+        padding: 0 12px;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #333;
+        background: #f5f7f9;
+
+        .icon {
+          font-size: 16px;
+          cursor: pointer;
+        }
+      }
+    }
+
+    :deep(.el-textarea__inner) {
+      box-shadow: none;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+}
+</style>
diff --git a/src/components/NavBar/index.vue b/src/components/NavBar/index.vue
new file mode 100644
index 0000000..fadc3f7
--- /dev/null
+++ b/src/components/NavBar/index.vue
@@ -0,0 +1,110 @@
+<script setup lang="ts">
+import { useNav } from "@/layout/hooks/useNav";
+import IconParkOutline from "@iconify-icons/icon-park-outline/logout";
+import { computed, onMounted, ref } from "vue";
+import downImg from "@/assets/newInquiry/down.png";
+const { logout, userAvatar, avatarsStyle } = useNav();
+import { getUserInfo } from "@/utils/auth";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import router from "@/router";
+import { useRoute } from "vue-router";
+const route = useRoute();
+const userName = ref("");
+const inspectSatus = computed(() => {
+  return useConsultationStoreHooks().inspectSatus;
+});
+onMounted(() => {
+  const userInfo: any = getUserInfo();
+  userName.value = JSON.parse(userInfo).name;
+});
+const changeCase = () => {
+  router.push({
+    path: "/selectCase"
+  });
+};
+</script>
+<template>
+  <div class="NavBar">
+    <div class="btn" @click="changeCase" v-if="inspectSatus === '2'">
+      更换病历
+    </div>
+    <!-- 退出登录 -->
+    <el-dropdown trigger="click" class="mr-6">
+      <span class="el-dropdown-link navbar-bg-hover select-none">
+        <img class="head" :src="userAvatar" :style="avatarsStyle" />
+        <p>{{ userName }}</p>
+        <img :src="downImg" alt="" />
+      </span>
+      <template #dropdown>
+        <el-dropdown-menu class="logout">
+          <el-dropdown-item
+            v-if="route.name !== 'SelectCase'"
+            @click="changeCase"
+          >
+            <IconifyIconOffline :icon="IconParkOutline" style="margin: 5px" />
+            返回问诊大厅
+          </el-dropdown-item>
+          <el-dropdown-item @click="logout">
+            <IconifyIconOffline :icon="IconParkOutline" style="margin: 5px" />
+            退出系统
+          </el-dropdown-item>
+        </el-dropdown-menu>
+      </template>
+    </el-dropdown>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.NavBar {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  min-width: 280px;
+  height: 48px;
+  margin-top: 22px;
+  color: #000000d9;
+
+  .btn {
+    width: 80px;
+    height: 32px;
+    font-size: 14px;
+    // font-family: Inter, Inter;
+    font-weight: 400;
+    line-height: 32px;
+    color: #fff;
+    text-align: center;
+    cursor: pointer;
+    background: #4287ff;
+    border-radius: 6px;
+  }
+
+  .el-dropdown-link {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    height: 48px;
+    padding: 10px;
+    color: #000000d9;
+    cursor: pointer;
+
+    p {
+      margin-left: 8px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #2b3f54;
+    }
+
+    .head {
+      width: 36px;
+      height: 36px;
+      border-radius: 50%;
+    }
+
+    img {
+      width: 11px;
+      height: 6px;
+      margin-left: 8px;
+    }
+  }
+}
+</style>
diff --git a/src/components/PlayVideo/index.vue b/src/components/PlayVideo/index.vue
new file mode 100644
index 0000000..24888a4
--- /dev/null
+++ b/src/components/PlayVideo/index.vue
@@ -0,0 +1,45 @@
+<script setup lang="ts">
+import { ref, nextTick } from "vue";
+
+defineOptions({
+  name: "PlayVideo"
+});
+const videoUrl = ref("");
+const type = ref(1);
+const titleList = ["图片", "播放视频", "播放音频"];
+defineExpose({
+  async open(id, val) {
+    videoUrl.value = "";
+    type.value = val;
+    dialogVisible.value = true;
+    await nextTick;
+    videoUrl.value = `/virtual-patient-manage/fileManage/downloadFile?fileId=${id}`;
+  }
+});
+const closed = () => {
+  videoUrl.value = "";
+  dialogVisible.value = false;
+};
+const dialogVisible = ref(false);
+</script>
+
+<template>
+  <div>
+    <el-dialog
+      width="600"
+      :title="titleList[type]"
+      append-to-body
+      v-model="dialogVisible"
+      :before-close="closed"
+      custom-class="PlayVideo"
+    >
+      <div v-if="videoUrl && type === 1">
+        <video ref="videoPlayer" :src="videoUrl" type="video/mp4" controls />
+      </div>
+
+      <audio v-if="videoUrl && type === 2" id="myAudio" controls>
+        <source :src="videoUrl" type="audio/mpeg" />
+      </audio>
+    </el-dialog>
+  </div>
+</template>
diff --git a/src/components/ReIcon/src/offlineIcon.ts b/src/components/ReIcon/src/offlineIcon.ts
index 1997c05..9cf5904 100644
--- a/src/components/ReIcon/src/offlineIcon.ts
+++ b/src/components/ReIcon/src/offlineIcon.ts
@@ -16,6 +16,8 @@ import WeixinFavorites from "@iconify-icons/icon-park-outline/weixin-favorites";
 import BuildingOne from "@iconify-icons/icon-park-outline/building-one";
 import Alarm from "@iconify-icons/icon-park-outline/alarm";
 import Camera from "@iconify-icons/icon-park-outline/camera";
+import BarChartOutlined from "@iconify-icons/ant-design/bar-chart-outlined";
+import UserOutlined from "@iconify-icons/ant-design/user-outlined";
 
 addIcon("homeFilled", HomeFilled);
 addIcon("informationLine", InformationLine);
@@ -28,3 +30,5 @@ addIcon("weixinFavorites", WeixinFavorites);
 addIcon("buildingOne", BuildingOne);
 addIcon("alarm", Alarm);
 addIcon("camera", Camera);
+addIcon("barChartOutlined", BarChartOutlined);
+addIcon("userOutlined", UserOutlined);
diff --git a/src/components/WangEditor/index.vue b/src/components/WangEditor/index.vue
new file mode 100644
index 0000000..6ffdbaf
--- /dev/null
+++ b/src/components/WangEditor/index.vue
@@ -0,0 +1,196 @@
+<template>
+  <div>
+    <div style="margin-top: 10px; border: 1px solid #ccc">
+      <Toolbar
+        :editor="editorRef"
+        :defaultConfig="toolbarConfig"
+        :mode="mode"
+        style="border-bottom: 1px solid #ccc"
+      />
+      <Editor
+        :defaultConfig="editorConfig"
+        :mode="mode"
+        v-model="valueHtml"
+        style="height: 400px; overflow-y: auto"
+        @onCreated="handleCreated"
+        @onChange="handleChange"
+        @onDestroyed="handleDestroyed"
+        @onFocus="handleFocus"
+        @onBlur="handleBlur"
+        @customAlert="customAlert"
+        @customPaste="customPaste"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import "@wangeditor/editor/dist/css/style.css";
+import { onBeforeUnmount, ref, shallowRef, onMounted, nextTick } from "vue";
+import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
+import { uploadFile } from "@/api/utils";
+export default {
+  components: { Editor, Toolbar },
+
+  setup() {
+    // 编辑器实例,必须用 shallowRef,重要!
+    const editorRef = shallowRef();
+
+    // 内容 HTML
+    const valueHtml = ref("");
+
+    // 模拟 ajax 异步获取内容
+    onMounted(() => {
+      nextTick(() => {
+        // const editor = editorRef.value;
+      });
+    });
+
+    // 工具栏配置
+    const toolbarConfig = {
+      toolbarKeys: [
+        // 菜单 key
+        "headerSelect",
+        "bold", // 加粗
+        "italic", // 斜体
+        "through", // 删除线
+        "underline", // 下划线
+        "bulletedList", // 无序列表
+        "numberedList", // 有序列表
+        "color", // 文字颜色
+        "insertLink", // 插入链接
+        "fontSize", // 字体大小
+        "lineHeight", // 行高
+        "uploadImage", // 上传图片
+        "delIndent", // 缩进
+        "indent", // 增进
+        "deleteImage", //删除图片
+        "divider", // 分割线
+        "insertTable", // 插入表格
+        "justifyCenter", // 居中对齐
+        "justifyJustify", // 两端对齐
+        "justifyLeft", // 左对齐
+        "justifyRight", // 右对齐
+        "undo", // 撤销
+        "redo", // 重做
+        "clearStyle", // 清除格式
+        "fullScreen" // 全屏
+      ]
+    };
+    const editorConfig = {
+      placeholder: "请输入内容...",
+      MENU_CONF: {
+        uploadImage: {
+          // server: "/virtual-patient-manage/fileManage/uploadFile",
+          // headers: { token: getToken() },
+          // fieldName: "file", // 这里有个坑,如果返回的响应结果是没有上传文件,跟这里关系很大
+          // customInsert(res, insertFn) {
+          //   if (res.code == 200) {
+          //     insertFn(
+          //       `/virtual-patient-manage/fileManage/downloadFile?fileId=${res.data}`,
+          //       "",
+          //       ""
+          //     );
+          //   }
+          // }
+          async customUpload(file, insertFn) {
+            // file 即选中的文件
+            // 自己实现上传,并得到图片 url alt href
+            const form = new FormData();
+            form.append("file", file);
+
+            uploadFile(form).then(res => {
+              if (res.code === 200) {
+                insertFn(
+                  `/virtual-patient-manage/fileManage/downloadFile?fileId=${res.data.id}`,
+                  "",
+                  ""
+                );
+              }
+            });
+          }
+        }
+      }
+    };
+
+    // 组件销毁时,也及时销毁编辑器,重要!
+    onBeforeUnmount(() => {
+      const editor = editorRef.value;
+      if (editor == null) return;
+
+      editor.destroy();
+    });
+
+    // 编辑器回调函数
+    const handleCreated = editor => {
+      console.log("created", editor);
+      editorRef.value = editor; // 记录 editor 实例,重要!
+    };
+    const handleChange = editor => {
+      console.log("change:", editor.getHtml());
+    };
+    const handleDestroyed = editor => {
+      console.log("destroyed", editor);
+    };
+    const handleFocus = editor => {
+      console.log("focus", editor);
+    };
+    const handleBlur = editor => {
+      console.log("blur", editor);
+    };
+    const customAlert = (info, type) => {
+      alert(`【自定义提示】${type} - ${info}`);
+    };
+    const customPaste = (editor, event, callback) => {
+      console.log("ClipboardEvent 粘贴事件对象", event);
+
+      // 自定义插入内容
+      // editor.insertText("xxx");
+
+      // 返回值(注意,vue 事件的返回值,不能用 return)
+      // callback(false); // 返回 false ,阻止默认粘贴行为
+      callback(true); // 返回 true ,继续默认的粘贴行为
+    };
+    const insertText = val => {
+      const editor = editorRef.value;
+      if (editor == null) return;
+      editor.insertText(val);
+    };
+
+    const printHtml = () => {
+      const editor = editorRef.value;
+      if (editor == null) return;
+      console.log(editor.getHtml());
+    };
+
+    const disable = () => {
+      const editor = editorRef.value;
+      if (editor == null) return;
+      editor.disable();
+    };
+    const initText = val => {
+      const editor = editorRef.value;
+      if (editor == null) return;
+      valueHtml.value = val;
+    };
+    return {
+      editorRef,
+      mode: "simple",
+      valueHtml,
+      toolbarConfig,
+      editorConfig,
+      handleCreated,
+      handleChange,
+      handleDestroyed,
+      handleFocus,
+      handleBlur,
+      customAlert,
+      customPaste,
+      insertText,
+      printHtml,
+      disable,
+      initText
+    };
+  }
+};
+</script>
diff --git a/src/layout/components/appMain.vue b/src/layout/components/appMain.vue
index 3f2a244..31721cb 100644
--- a/src/layout/components/appMain.vue
+++ b/src/layout/components/appMain.vue
@@ -134,6 +134,8 @@ const transitionMain = defineComponent({
   width: 100%;
   height: 100vh;
   overflow-x: hidden;
+
+  /* background: #fff; */
 }
 
 .app-main-nofixed-header {
@@ -143,6 +145,8 @@ const transitionMain = defineComponent({
 }
 
 .main-content {
-  margin: 24px;
+  display: flex;
+  flex-direction: column;
+  margin: 16px;
 }
 </style>
diff --git a/src/layout/components/navbar.vue b/src/layout/components/navbar.vue
index e811f1d..4880ee6 100644
--- a/src/layout/components/navbar.vue
+++ b/src/layout/components/navbar.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
-import Search from "./search/index.vue";
-import Notice from "./notice/index.vue";
+// import Search from "./search/index.vue";
+// import Notice from "./notice/index.vue";
 import mixNav from "./sidebar/mixNav.vue";
 import { useNav } from "@/layout/hooks/useNav";
 import Breadcrumb from "./sidebar/breadCrumb.vue";
@@ -42,11 +42,11 @@ const {
 
     <div v-if="layout === 'vertical'" class="vertical-header-right">
       <!-- 菜单搜索 -->
-      <Search />
+      <!-- <Search /> -->
       <!-- 通知 -->
-      <Notice id="header-notice" />
+      <!-- <Notice id="header-notice" /> -->
       <!-- 退出登录 -->
-      <el-dropdown trigger="click" class="mr-6">
+      <el-dropdown style="width: 50px" trigger="click" class="mr-6">
         <span class="el-dropdown-link navbar-bg-hover select-none">
           <img :src="userAvatar" :style="avatarsStyle" />
           <p v-if="username" class="dark:text-white">{{ username }}</p>
@@ -121,7 +121,7 @@ const {
 }
 
 .logout {
-  max-width: 120px;
+  // max-width: 120px;
 
   ::v-deep(.el-dropdown-menu__item) {
     display: inline-flex;
diff --git a/src/layout/components/sidebar/breadCrumb.vue b/src/layout/components/sidebar/breadCrumb.vue
index d3bbf20..973ca9c 100644
--- a/src/layout/components/sidebar/breadCrumb.vue
+++ b/src/layout/components/sidebar/breadCrumb.vue
@@ -1,35 +1,36 @@
 <script setup lang="ts">
-import { isEqual } from "@pureadmin/utils";
-import { ref, watch, onMounted, toRaw } from "vue";
+// import { isEqual } from "@pureadmin/utils";
+import { ref, watch, onMounted } from "vue";
 import { getParentPaths, findRouteByPath } from "@/router/utils";
-import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
+// import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 import { useRoute, useRouter, RouteLocationMatched } from "vue-router";
 
 const route = useRoute();
 const levelList = ref([]);
 const router = useRouter();
 const routes: any = router.options.routes;
-const multiTags: any = useMultiTagsStoreHook().multiTags;
+// const multiTags: any = useMultiTagsStoreHook().multiTags;
 
 const getBreadcrumb = (): void => {
   // 当前路由信息
   let currentRoute;
 
-  if (Object.keys(route.query).length > 0) {
-    multiTags.forEach(item => {
-      if (isEqual(route.query, item?.query)) {
-        currentRoute = toRaw(item);
-      }
-    });
-  } else if (Object.keys(route.params).length > 0) {
-    multiTags.forEach(item => {
-      if (isEqual(route.params, item?.params)) {
-        currentRoute = toRaw(item);
-      }
-    });
-  } else {
-    currentRoute = findRouteByPath(router.currentRoute.value.path, routes);
-  }
+  // if (Object.keys(route.query).length > 0) {
+  //   multiTags.forEach(item => {
+  //     if (isEqual(route.query, item?.query)) {
+  //       currentRoute = toRaw(item);
+  //     }
+  //   });
+  // } else if (Object.keys(route.params).length > 0) {
+  //   multiTags.forEach(item => {
+  //     if (isEqual(route.params, item?.params)) {
+  //       currentRoute = toRaw(item);
+  //     }
+  //   });
+  // } else {
+  // }
+  // eslint-disable-next-line prefer-const
+  currentRoute = findRouteByPath(router.currentRoute.value.path, routes);
 
   // 当前路由的父级路径组成的数组
   const parentRoutes = getParentPaths(
@@ -46,7 +47,6 @@ const getBreadcrumb = (): void => {
   });
 
   matched.push(currentRoute);
-
   matched.forEach((item, index) => {
     if (currentRoute?.query || currentRoute?.params) return;
     if (item?.children) {
diff --git a/src/layout/components/sidebar/vertical.vue b/src/layout/components/sidebar/vertical.vue
index b2ce4f2..985675e 100644
--- a/src/layout/components/sidebar/vertical.vue
+++ b/src/layout/components/sidebar/vertical.vue
@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import Logo from "./logo.vue";
 import { useRoute } from "vue-router";
 import { emitter } from "@/utils/mitt";
 import SidebarItem from "./sidebarItem.vue";
@@ -23,9 +22,7 @@ const { device, pureApp, isCollapse, menuSelect, toggleSideBar } = useNav();
 const subMenuData = ref([]);
 
 const menuData = computed(() => {
-  return pureApp.layout === "mix" && device.value !== "mobile"
-    ? subMenuData.value
-    : usePermissionStoreHook().wholeMenus;
+  return usePermissionStoreHook().wholeMenus;
 });
 
 const loading = computed(() =>
@@ -82,11 +79,8 @@ onBeforeUnmount(() => {
     v-loading="loading"
     :class="['sidebar-container', showLogo ? 'has-logo' : '']"
   >
-    <Logo v-if="showLogo" :collapse="isCollapse" />
-    <el-scrollbar
-      wrap-class="scrollbar-wrapper"
-      :class="[device === 'mobile' ? 'mobile' : 'pc']"
-    >
+    <!-- <Logo v-if="showLogo" :collapse="isCollapse" /> -->
+    <el-scrollbar wrap-class="scrollbar-wrapper" class="pc">
       <el-menu
         router
         unique-opened
diff --git a/src/router/index.ts b/src/router/index.ts
index ac023e5..7fed786 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -1,7 +1,7 @@
 // import "@/utils/sso";
 import { getConfig } from "@/config";
 import NProgress from "@/utils/progress";
-import { sessionKey, type DataInfo } from "@/utils/auth";
+// import { getToken } from "@/utils/auth";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 import { usePermissionStoreHook } from "@/store/modules/permission";
 import {
@@ -36,7 +36,6 @@ const modules: Record<string, any> = import.meta.glob(
     eager: true
   }
 );
-
 /** 原始静态路由(未做任何处理) */
 const routes = [];
 
@@ -58,7 +57,6 @@ export const constantMenus: Array<RouteComponent> = ascending(
 export const remainingPaths = Object.keys(remainingRouter).map(v => {
   return remainingRouter[v].path;
 });
-
 /** 创建路由实例 */
 export const router: Router = createRouter({
   history: getHistoryMode(import.meta.env.VITE_ROUTER_HISTORY),
@@ -101,97 +99,99 @@ const whiteList = ["/login"];
 const { VITE_HIDE_HOME } = import.meta.env;
 
 router.beforeEach((to: ToRouteType, _from, next) => {
-  // if (to.meta?.keepAlive) {
-  //   handleAliveRoute(to, "add");
-  //   // 页面整体刷新和点击标签页刷新
-  //   if (_from.name === undefined || _from.name === "Redirect") {
-  //     handleAliveRoute(to);
-  //   }
-  // }
-  // const userInfo = storageSession().getItem<DataInfo<number>>(sessionKey);
-  // NProgress.start();
-  // const externalLink = isUrl(to?.name as string);
-  // if (!externalLink) {
-  //   to.matched.some(item => {
-  //     if (!item.meta.title) return "";
-  //     const Title = getConfig().Title;
-  //     if (Title) document.title = `${item.meta.title} | ${Title}`;
-  //     else document.title = item.meta.title as string;
-  //   });
-  // }
-  // /** 如果已经登录并存在登录信息后不能跳转到路由白名单,而是继续保持在当前页面 */
-  // function toCorrectRoute() {
-  //   whiteList.includes(to.fullPath) ? next(_from.fullPath) : next();
-  // }
-  // if (userInfo) {
-  //   // 无权限跳转403页面
-  //   if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) {
-  //     next({ path: "/error/403" });
-  //   }
-  //   // 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
-  //   if (VITE_HIDE_HOME === "true" && to.fullPath === "/welcome") {
-  //     next({ path: "/error/404" });
-  //   }
-  //   if (_from?.name) {
-  //     // name为超链接
-  //     if (externalLink) {
-  //       openLink(to?.name as string);
-  //       NProgress.done();
-  //     } else {
-  //       toCorrectRoute();
-  //     }
-  //   } else {
-  //     // 刷新
-  //     if (
-  //       usePermissionStoreHook().wholeMenus.length === 0 &&
-  //       to.path !== "/login"
-  //     ) {
-  //       initRouter().then((router: Router) => {
-  //         if (!useMultiTagsStoreHook().getMultiTagsCache) {
-  //           const { path } = to;
-  //           const route = findRouteByPath(
-  //             path,
-  //             router.options.routes[0].children
-  //           );
-  //           getTopMenu(true);
-  //           // query、params模式路由传参数的标签页不在此处处理
-  //           if (route && route.meta?.title) {
-  //             if (isAllEmpty(route.parentId) && route.meta?.backstage) {
-  //               // 此处为动态顶级路由(目录)
-  //               const { path, name, meta } = route.children[0];
-  //               useMultiTagsStoreHook().handleTags("push", {
-  //                 path,
-  //                 name,
-  //                 meta
-  //               });
-  //             } else {
-  //               const { path, name, meta } = route;
-  //               useMultiTagsStoreHook().handleTags("push", {
-  //                 path,
-  //                 name,
-  //                 meta
-  //               });
-  //             }
-  //           }
-  //         }
-  //         // 确保动态路由完全加入路由列表并且不影响静态路由(注意:动态路由刷新时router.beforeEach可能会触发两次,第一次触发动态路由还未完全添加,第二次动态路由才完全添加到路由列表,如果需要在router.beforeEach做一些判断可以在to.name存在的条件下去判断,这样就只会触发一次)
-  //         if (isAllEmpty(to.name)) router.push(to.fullPath);
-  //       });
-  //     }
-  //     toCorrectRoute();
-  //   }
-  // } else {
-  //   if (to.path !== "/login") {
-  //     if (whiteList.indexOf(to.path) !== -1) {
-  //       next();
-  //     } else {
-  //       next({ path: "/login" });
-  //     }
-  //   } else {
-  //     next();
-  //   }
-  // }
-  next();
+  if (to.meta?.keepAlive) {
+    handleAliveRoute(to, "add");
+    // 页面整体刷新和点击标签页刷新
+    if (_from.name === undefined || _from.name === "Redirect") {
+      handleAliveRoute(to);
+    }
+  }
+  const userInfoStr = storageSession().getItem("userInfo");
+
+  const userInfo = JSON.parse(userInfoStr);
+  // const token = getToken();
+  NProgress.start();
+  const externalLink = isUrl(to?.name as string);
+  if (!externalLink) {
+    to.matched.some(item => {
+      if (!item.meta.title) return "";
+      const Title = getConfig().Title;
+      if (Title) document.title = `${item.meta.title} | ${Title}`;
+      else document.title = item.meta.title as string;
+    });
+  }
+  /** 如果已经登录并存在登录信息后不能跳转到路由白名单,而是继续保持在当前页面 */
+  function toCorrectRoute() {
+    whiteList.includes(to.fullPath) ? next(_from.fullPath) : next();
+  }
+  if (userInfo?.roleCode) {
+    // 无权限跳转403页面
+    if (to.meta?.roles && !isOneOfArray(to.meta?.roles, userInfo?.roles)) {
+      next({ path: "/error/403" });
+    }
+    // 开启隐藏首页后在浏览器地址栏手动输入首页welcome路由则跳转到404页面
+    if (VITE_HIDE_HOME === "true" && to.fullPath === "/welcome") {
+      next({ path: "/error/404" });
+    }
+    if (_from?.name) {
+      // name为超链接
+      if (externalLink) {
+        openLink(to?.name as string);
+        NProgress.done();
+      } else {
+        toCorrectRoute();
+      }
+    } else {
+      // 刷新
+      if (
+        usePermissionStoreHook().wholeMenus.length === 0 &&
+        to.path !== "/login"
+      ) {
+        initRouter().then((router: Router) => {
+          if (!useMultiTagsStoreHook().getMultiTagsCache) {
+            const { path } = to;
+            const route = findRouteByPath(
+              path,
+              router.options.routes[0].children
+            );
+            getTopMenu(true);
+            // query、params模式路由传参数的标签页不在此处处理
+            if (route && route.meta?.title) {
+              if (isAllEmpty(route.parentId) && route.meta?.backstage) {
+                // 此处为动态顶级路由(目录)
+                const { path, name, meta } = route.children[0];
+                useMultiTagsStoreHook().handleTags("push", {
+                  path,
+                  name,
+                  meta
+                });
+              } else {
+                const { path, name, meta } = route;
+                useMultiTagsStoreHook().handleTags("push", {
+                  path,
+                  name,
+                  meta
+                });
+              }
+            }
+          }
+          // 确保动态路由完全加入路由列表并且不影响静态路由(注意:动态路由刷新时router.beforeEach可能会触发两次,第一次触发动态路由还未完全添加,第二次动态路由才完全添加到路由列表,如果需要在router.beforeEach做一些判断可以在to.name存在的条件下去判断,这样就只会触发一次)
+          if (isAllEmpty(to.name)) router.push(to.fullPath);
+        });
+      }
+      toCorrectRoute();
+    }
+  } else {
+    if (to.path !== "/login") {
+      if (whiteList.indexOf(to.path) !== -1) {
+        next();
+      } else {
+        next({ path: "/login" });
+      }
+    } else {
+      next();
+    }
+  }
 });
 
 router.afterEach(() => {
diff --git a/src/router/modules/caseManagement.ts b/src/router/modules/caseManagement.ts
new file mode 100644
index 0000000..b432624
--- /dev/null
+++ b/src/router/modules/caseManagement.ts
@@ -0,0 +1,121 @@
+export default {
+  path: "/caseManagement",
+  redirect: "/caseManagement/diseaseType",
+  meta: {
+    title: "病例管理",
+    icon: "barChartOutlined",
+    rank: 12
+  },
+  children: [
+    {
+      path: "/caseManagement/diseaseType",
+      name: "DiseaseType",
+      component: () => import("@/views/caseManagement/diseaseType/index.vue"),
+      meta: {
+        title: "疾病分类",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      },
+      children: [
+        {
+          path: "/caseManagement/diseaseType/inquiry",
+          name: "diseaseTypeInquiry",
+          component: () =>
+            import("@/views/caseManagement/diseaseType/inquiry/index.vue"),
+          meta: {
+            title: "问诊",
+            showLink: false,
+            activePath: "/caseManagement/diseaseType",
+            roles: ["admin", "common"]
+          }
+        },
+        {
+          path: "/caseManagement/diseaseType/bodyInspect",
+          name: "diseaseTypeBodyInspect",
+          component: () =>
+            import("@/views/caseManagement/diseaseType/bodyInspect/index.vue"),
+          meta: {
+            title: "体格检查",
+            showLink: false,
+            activePath: "/caseManagement/diseaseType",
+            roles: ["admin", "common"]
+          }
+        },
+        {
+          path: "/caseManagement/diseaseType/supportInspect",
+          name: "diseaseTypeSupportInspect",
+          component: () =>
+            import(
+              "@/views/caseManagement/diseaseType/supportInspect/index.vue"
+            ),
+          meta: {
+            title: "辅助检查",
+            showLink: false,
+            activePath: "/caseManagement/diseaseType",
+            roles: ["admin", "common"]
+          }
+        },
+        {
+          path: "/caseManagement/diseaseType/disposalPlan",
+          name: "diseaseTypeDisposalPlan",
+          component: () =>
+            import("@/views/caseManagement/diseaseType/disposalPlan/index.vue"),
+          meta: {
+            title: "处置计划",
+            showLink: false,
+            activePath: "/caseManagement/diseaseType",
+            roles: ["admin", "common"]
+          }
+        }
+      ]
+    },
+    {
+      path: "/caseManagement/list",
+      name: "CaseManagement",
+      component: () => import("@/views/caseManagement/list/index.vue"),
+      meta: {
+        title: "病历管理",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      },
+      children: [
+        {
+          path: "/caseManagement/add",
+          name: "caseManagementAdd",
+          component: () => import("@/views/caseManagement/list/add.vue"),
+          meta: {
+            title: "新建病历",
+            showLink: false,
+            activePath: "/caseManagement/list",
+            roles: ["admin", "common"]
+          }
+        },
+        {
+          path: "/caseManagement/edit",
+          name: "caseManagementEdit",
+          component: () => import("@/views/caseManagement/list/edit.vue"),
+          meta: {
+            title: "编辑病历",
+            showLink: false,
+            activePath: "/caseManagement/list",
+            roles: ["admin", "common"]
+          }
+        },
+        {
+          path: "/caseManagement/detail",
+          name: "caseManagementDetail",
+          component: () =>
+            import("@/views/caseManagement/list/details/index.vue"),
+          meta: {
+            title: "病历详情",
+            showLink: false,
+            activePath: "/caseManagement/list",
+            roles: ["admin", "common"]
+          }
+        }
+      ]
+    }
+  ]
+} as RouteConfigsTable;
diff --git a/src/router/modules/generalRules.ts b/src/router/modules/generalRules.ts
new file mode 100644
index 0000000..bc99e99
--- /dev/null
+++ b/src/router/modules/generalRules.ts
@@ -0,0 +1,34 @@
+export default {
+  path: "/generalRules",
+  redirect: "/generalRules/responseStrategy",
+  meta: {
+    title: "通用规则",
+    icon: "weixinFavorites",
+    rank: 14
+  },
+  children: [
+    {
+      path: "/generalRules/responseStrategy",
+      name: "ResponseStrategy",
+      component: () =>
+        import("@/views/generalRules/responseStrategy/index.vue"),
+      meta: {
+        title: "应答策略 ",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+    },
+    {
+      path: "/generalRules/materialCenter",
+      name: "MaterialCenter",
+      component: () => import("@/views/generalRules/materialCenter/index.vue"),
+      meta: {
+        title: "素材中心 ",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+    }
+  ]
+} as RouteConfigsTable;
diff --git a/src/router/modules/home.ts b/src/router/modules/home.ts
new file mode 100644
index 0000000..52d1e6f
--- /dev/null
+++ b/src/router/modules/home.ts
@@ -0,0 +1,26 @@
+const { VITE_HIDE_HOME } = import.meta.env;
+const Layout = () => import("@/layout/index.vue");
+import HomeFill from "@/assets/svg/home.svg?component";
+export default {
+  path: "/",
+  name: "Home",
+  component: Layout,
+  redirect: "/welcome",
+  meta: {
+    icon: HomeFill,
+    title: "首页",
+    showLink: false
+    // rank: 0
+  },
+  children: [
+    {
+      path: "/welcome",
+      name: "Welcome",
+      component: () => import("@/views/welcome/index.vue"),
+      meta: {
+        title: "首页",
+        showLink: VITE_HIDE_HOME === "true" ? false : true
+      }
+    }
+  ]
+} as RouteConfigsTable;
diff --git a/src/router/modules/inquiryCase.ts b/src/router/modules/inquiryCase.ts
new file mode 100644
index 0000000..9c6f360
--- /dev/null
+++ b/src/router/modules/inquiryCase.ts
@@ -0,0 +1,35 @@
+export default {
+  path: "/inquiryCase",
+  redirect: "/inquiryCase/list",
+  meta: {
+    title: "问诊病历",
+    icon: "terminal",
+    rank: 13
+  },
+  children: [
+    {
+      path: "/inquiryCase/list",
+      name: "InquiryCase",
+      component: () => import("@/views/inquiryCase/list/index.vue"),
+      meta: {
+        title: "问诊病历 ",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      },
+      children: [
+        {
+          path: "/inquiryCase/estimate",
+          name: "Estimate",
+          component: () => import("@/views/inquiryCase/estimate/index.vue"),
+          meta: {
+            title: "评估",
+            showLink: false,
+            activePath: "/inquiryCase/list",
+            roles: ["admin", "common"]
+          }
+        }
+      ]
+    }
+  ]
+} as RouteConfigsTable;
diff --git a/src/router/modules/inquiryManagement.ts b/src/router/modules/inquiryManagement.ts
new file mode 100644
index 0000000..4eef89c
--- /dev/null
+++ b/src/router/modules/inquiryManagement.ts
@@ -0,0 +1,85 @@
+export default {
+  path: "/inquiryManagement",
+  redirect: "/inquiryManagement/list",
+  meta: {
+    title: "问诊管理",
+    icon: "projectIcon",
+    rank: 11
+  },
+  children: [
+    {
+      path: "/inquiryManagement/bodyInspect",
+      name: "BodyInspect",
+      component: () =>
+        import("@/views/inquiryManagement/bodyInspect/list/index.vue"),
+      meta: {
+        title: "体格检查",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+      // children: [
+      //   {
+      //     path: "/inquiryManagement/bodyInspect/add",
+      //     name: "BodyInspectAdd",
+      //     component: () =>
+      //       import("@/views/inquiryManagement/bodyInspect/list/add.vue"),
+      //     meta: {
+      //       title: "新建体格检查",
+      //       showLink: false,
+      //       activePath: "/inquiryManagement/list",
+      //       roles: ["admin", "common"]
+      //     }
+      //   },
+      //   {
+      //     path: "/inquiryManagement/bodyInspect/edit",
+      //     name: "BodyInspectEdit",
+      //     component: () =>
+      //       import("@/views/inquiryManagement/bodyInspect/list/edit.vue"),
+      //     meta: {
+      //       title: "编辑体格检查",
+      //       showLink: false,
+      //       activePath: "/inquiryManagement/list",
+      //       roles: ["admin", "common"]
+      //     }
+      //   }
+      // ]
+    },
+    {
+      path: "/inquiryManagement/disposalPlan",
+      name: "DisposalPlan",
+      component: () =>
+        import("@/views/inquiryManagement/disposalPlan/list/index.vue"),
+      meta: {
+        title: "处置计划",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+    },
+    {
+      path: "/inquiryManagement/medicationManagement",
+      name: "MedicationManagement",
+      component: () =>
+        import("@/views/inquiryManagement/medicationManagement/list/index.vue"),
+      meta: {
+        title: "药物管理",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+    },
+    {
+      path: "/inquiryManagement/supportInspect",
+      name: "InquiryManagementSupportInspect",
+      component: () =>
+        import("@/views/inquiryManagement/supportInspect/list/index.vue"),
+      meta: {
+        title: "辅助检查",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+    }
+  ]
+} as RouteConfigsTable;
diff --git a/src/router/modules/remaining.ts b/src/router/modules/remaining.ts
index 192feec..52a15bf 100644
--- a/src/router/modules/remaining.ts
+++ b/src/router/modules/remaining.ts
@@ -28,24 +28,23 @@ export default [
     ]
   },
   {
-    path: "/inquiry",
-    name: "Inquiry",
+    path: "/selectCase",
+    name: "SelectCase",
+    component: () => import("@/views/selectCase/index.vue"),
     meta: {
-      title: "问诊",
-      icon: "computer",
-      // showLink: true,
-      rank: 1
-    },
-    children: [
-      {
-        path: "/inquiry",
-        name: "Inquiry",
-        component: () => import("@/views/inquiry/index.vue"),
-        meta: {
-          title: "问诊",
-          roles: ["admin"]
-        }
-      }
-    ]
+      title: "选择实例",
+      showLink: false,
+      rank: 101
+    }
+  },
+  {
+    path: "/consultation",
+    name: "Consultation",
+    component: () => import("@/views/consultation/index.vue"),
+    meta: {
+      title: "问诊大厅",
+      showLink: false,
+      rank: 103
+    }
   }
 ] as Array<RouteConfigsTable>;
diff --git a/src/router/modules/systemManagement.ts b/src/router/modules/systemManagement.ts
new file mode 100644
index 0000000..80be298
--- /dev/null
+++ b/src/router/modules/systemManagement.ts
@@ -0,0 +1,33 @@
+export default {
+  path: "/systemManagement",
+  redirect: "/systemManagement/accountManagement",
+  meta: {
+    title: "系统管理",
+    icon: "userOutlined",
+    rank: 15
+  },
+  children: [
+    {
+      path: "/systemManagement/accountManagement",
+      name: "systemManagement",
+      component: () =>
+        import("@/views/systemManagement/accountManagement/index.vue"),
+      meta: {
+        title: "账号管理",
+        showLink: true,
+        showParent: true,
+        roles: ["admin", "common"]
+      }
+    }
+    // {
+    //   path: "/systemManagement/loginStatus",
+    //   name: "LoginStatus",
+    //   component: () => import("@/views/systemManagement/loginStatus/index.vue"),
+    //   meta: {
+    //     title: "登录状态",
+    //     showLink: true,
+    //     roles: ["admin", "common"]
+    //   }
+    // }
+  ]
+} as RouteConfigsTable;
diff --git a/src/router/utils.ts b/src/router/utils.ts
index 2436e2b..8aa92fa 100644
--- a/src/router/utils.ts
+++ b/src/router/utils.ts
@@ -158,7 +158,7 @@ function handleAsyncRoutes(routeList) {
       (v: RouteRecordRaw) => {
         // 防止重复添加路由
         if (
-          router.options.routes[0].children.findIndex(
+          router.options.routes[0].children?.findIndex(
             value => value.path === v.path
           ) !== -1
         ) {
diff --git a/src/store/modules/caseManagement.ts b/src/store/modules/caseManagement.ts
new file mode 100644
index 0000000..d582901
--- /dev/null
+++ b/src/store/modules/caseManagement.ts
@@ -0,0 +1,58 @@
+import { defineStore } from "pinia";
+import { store } from "@/store";
+export const useCaseStore = defineStore({
+  id: "case",
+  state: () => ({
+    activedStep: 0, // 当前步骤
+    basicInfo: {
+      patientName: "",
+      patientGender: "",
+      patientAge: "",
+      diseaseName: "",
+      diseaseId: "",
+      patientSelfDesc: "",
+      address: "",
+      nativePlace: "",
+      patientNation: "",
+      patientPostcode: "",
+      patientBirthplace: "",
+      patientPhone: "",
+      digitalHumanType: "",
+      patientHeadPic: ""
+    },
+    diagnosticBasisInfo: {
+      primarilyDiagnosisCriteria: "",
+      confirmDiagnosisCriteria: "",
+      differentialDiagnosisCriteria: "",
+      fullCheck: ""
+    },
+    qaList: [],
+    defaultQaList: [],
+    patientId: "",
+    isEditFlag: false
+  }),
+  actions: {
+    changeActivedStep(data) {
+      this.activedStep = data;
+    },
+    changeBasicInfo(data) {
+      this.basicInfo = data;
+    },
+    changeDiagnosticBasisInfo(data) {
+      this.diagnosticBasisInfo = data;
+    },
+    changeQaList(data) {
+      this.qaList = data;
+    },
+    changeDefaultQaList(data) {
+      this.defaultQaList = data;
+    },
+    changeIsEditFlag(data) {
+      this.isEditFlag = data;
+    }
+  }
+});
+
+export function useCaseStoreHooks() {
+  return useCaseStore(store);
+}
diff --git a/src/store/modules/consultation.ts b/src/store/modules/consultation.ts
new file mode 100644
index 0000000..0cff4cb
--- /dev/null
+++ b/src/store/modules/consultation.ts
@@ -0,0 +1,156 @@
+import { defineStore } from "pinia";
+import { store } from "@/store";
+import {
+  queryAskPrimaryList,
+  queryAskPhysicalHistory,
+  queryAskAncillaryHistory
+} from "@/api/inquiry";
+import { clearObject } from "@/utils/auth";
+export const useConsultationStore = defineStore({
+  id: "consultation",
+  state: () => ({
+    activedKey: 0, // 选中的tab
+    activedTabKey: 0,
+    inspectSatus: "", //诊断状态
+    processId: "", //流程id
+    // 选中的工具
+    selectToolInfo: {
+      toolName: "",
+      img: "",
+      id: "",
+      requireLocation: 0
+    },
+    bodyPositionType: "", // 身体部位类别
+    // 体格检查结果
+    bodyResultInfo: {
+      name: "",
+      label: "",
+      value: "",
+      postion: ""
+    },
+    primaryIdList: [], //初步诊断id
+    selectSupportId: "", // 选中的辅助检查id
+    firstInspectList: [], // 初步检查列表
+    bodyInspectList: [], // 体格检查列表
+    suppertInspectList: [], // 辅助检查列表
+    uuid: "",
+    exhalationFlag: false, //呼出服务
+    voiceFlag: true,
+    planTypeFlag: "", // 处置计划类型
+    supportActionId: [], // 呼出辅助检查
+    voiceStartFlag: false //是否开始语音问诊
+  }),
+  actions: {
+    changeVoiceFlag(data) {
+      this.voiceStartFlag = data;
+    },
+    changeActivedKey(data) {
+      this.activedKey = data;
+      if (data !== 1) {
+        clearObject(this.selectToolInfo);
+        clearObject(this.bodyResultInfo);
+      }
+      if (data === 0) {
+        this.exhalationFlag = false;
+        this.voiceFlag = true;
+      } else {
+        this.voiceFlag = false;
+      }
+    },
+    changeActivedTabKey(data) {
+      this.activedTabKey = data;
+      if (data !== 1) {
+        clearObject(this.selectToolInfo);
+        clearObject(this.bodyResultInfo);
+      }
+      if (data === 0) {
+        this.exhalationFlag = false;
+        this.voiceFlag = true;
+      } else {
+        this.voiceFlag = false;
+      }
+    },
+    changeSelectToolInfo(data) {
+      this.selectToolInfo = data;
+    },
+    changeBodyPositionType(data) {
+      this.bodyPositionType = data;
+    },
+    changeBodyResultInfo(data) {
+      this.bodyResultInfo = data;
+    },
+    changeProcessId(data) {
+      this.processId = data;
+    },
+    changeSelectSupportId(data) {
+      this.selectSupportId = data;
+    },
+    changeUUID(data) {
+      this.uuid = data;
+    },
+    changeExhalationFlag(data) {
+      this.exhalationFlag = data;
+    },
+    changeInspectSatus(data) {
+      this.inspectSatus = data;
+    },
+    changePrimaryIdList(data) {
+      this.primaryIdList = data;
+    },
+    /** 获取初步诊断列表 */
+    async getAskPrimaryList(id) {
+      return new Promise((resolve, reject) => {
+        queryAskPrimaryList({
+          processId: id
+        })
+          .then((res: any) => {
+            if (res.code === 200) {
+              this.firstInspectList = res.data;
+              resolve(res);
+            }
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    /** 获取体格检查列表 */
+    async getyAskPhysicalHistory(id) {
+      return new Promise((resolve, reject) => {
+        queryAskPhysicalHistory({
+          processId: id
+        })
+          .then((res: any) => {
+            if (res.code === 200) {
+              this.bodyInspectList = res.data;
+              resolve(res);
+            }
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    },
+    /** 获取辅助检查列表 */
+    async getAskAncillaryHistory() {
+      return new Promise((resolve, reject) => {
+        queryAskAncillaryHistory({
+          processId: this.processId
+        })
+          .then((res: any) => {
+            if (res.code === 200) {
+              this.suppertInspectList = res.data;
+              resolve(res);
+            }
+          })
+          .catch(error => {
+            reject(error);
+          });
+      });
+    }
+  }
+});
+
+export function useConsultationStoreHooks() {
+  return useConsultationStore(store);
+}
diff --git a/src/store/modules/disease.ts b/src/store/modules/disease.ts
new file mode 100644
index 0000000..92488a7
--- /dev/null
+++ b/src/store/modules/disease.ts
@@ -0,0 +1,20 @@
+import { defineStore } from "pinia";
+import { store } from "@/store";
+export const useDiseaseStore = defineStore({
+  id: "disease",
+  state: () => ({
+    diseaseInfo: {
+      id: "",
+      diseaseName: ""
+    }
+  }),
+  actions: {
+    changeDiseaseInfo(data) {
+      this.diseaseInfo = data;
+    }
+  }
+});
+
+export function useDiseaseStoreHooks() {
+  return useDiseaseStore(store);
+}
diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts
index 33fd0dd..1a3c3c1 100644
--- a/src/store/modules/permission.ts
+++ b/src/store/modules/permission.ts
@@ -4,7 +4,7 @@ import { cacheType } from "./types";
 import { constantMenus } from "@/router";
 import { useMultiTagsStoreHook } from "./multiTags";
 import { debounce, getKeyList } from "@pureadmin/utils";
-import { ascending, filterTree, filterNoPermissionTree } from "@/router/utils";
+import { ascending, filterTree } from "@/router/utils";
 
 export const usePermissionStore = defineStore({
   id: "pure-permission",
@@ -18,10 +18,11 @@ export const usePermissionStore = defineStore({
   }),
   actions: {
     /** 组装整体路由生成的菜单 */
-    handleWholeMenus(routes: any[]) {
-      this.wholeMenus = filterNoPermissionTree(
-        filterTree(ascending(this.constantMenus.concat(routes)))
-      );
+    handleWholeMenus() {
+      this.wholeMenus = filterTree(ascending(this.constantMenus));
+
+      // this.wholeMenus = routes;
+      console.log("2323", this.wholeMenus);
     },
     cacheOperate({ mode, name }: cacheType) {
       const delIndex = this.cachePageList.findIndex(v => v === name);
diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts
index 2221ad3..7f15cf7 100644
--- a/src/store/modules/user.ts
+++ b/src/store/modules/user.ts
@@ -5,9 +5,15 @@ import { routerArrays } from "@/layout/types";
 import { router, resetRouter } from "@/router";
 import { storageSession } from "@pureadmin/utils";
 import { getLogin, refreshTokenApi } from "@/api/user";
-import { UserResult, RefreshTokenResult } from "@/api/user";
+import { RefreshTokenResult } from "@/api/user";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
-import { type DataInfo, setToken, removeToken, sessionKey } from "@/utils/auth";
+import {
+  type DataInfo,
+  setToken,
+  removeToken,
+  sessionKey,
+  setUserInfo
+} from "@/utils/auth";
 
 export const useUserStore = defineStore({
   id: "pure-user",
@@ -39,7 +45,8 @@ export const useUserStore = defineStore({
         getLogin(data)
           .then(data => {
             if (data) {
-              setToken(data.data);
+              setToken(data.data.token);
+              setUserInfo(data.data);
               resolve(data);
             }
           })
diff --git a/src/style/login.css b/src/style/login.css
index 5680aaf..a1e810c 100644
--- a/src/style/login.css
+++ b/src/style/login.css
@@ -71,16 +71,16 @@
 
 .login-box {
   width: 500px;
-height: 546px;
-background: #FFFFFF;
-border-radius: 10px 10px 10px 10px;
+  height: 546px;
+  background: #ffffff;
+  border-radius: 10px 10px 10px 10px;
   display: flex;
   flex-direction: column;
   justify-content: space-between;
   align-items: center;
   text-align: center;
-  margin-left:160px;
-  padding-top:50px
+  margin-left: 160px;
+  padding-top: 65px;
 }
 
 .login-form {
diff --git a/src/style/reset.scss b/src/style/reset.scss
index 1458afb..3d00a18 100644
--- a/src/style/reset.scss
+++ b/src/style/reset.scss
@@ -258,8 +258,8 @@ div:focus {
 }
 .footer-btn {
   width: 188px;
-height: 48px;
-margin-bottom: 24px;
+  height: 48px;
+  margin-bottom: 24px;
 }
 .el-dialog {
   border-radius: 20px 20px 20px 20px !important;
@@ -269,4 +269,144 @@ margin-bottom: 24px;
 }
 .el-dialog__footer {
   text-align: center !important;
-}
\ No newline at end of file
+}
+.step-footer-btn {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+  margin-top: 24px;
+}
+.el-form-item__label {
+  // font-weight: 700;
+}
+.header_title {
+  display: flex;
+  align-items: center;
+  border-bottom: 1px solid rgba(91, 139, 255, 0.3);
+  .title {
+    border-bottom: 4px solid #4287ff;
+    display: flex;
+    padding-bottom: 8px;
+    img {
+      width: 20px;
+      height: 20px;
+      margin-right: 8px;
+    }
+    font-size: 16px;
+    font-weight: bold;
+    color: #2b3f54;
+  }
+}
+.el-table__row {
+  cursor: pointer;
+}
+.app-main-content {
+  .el-table__row {
+    height: 75px !important;
+  }
+}
+.app-main-content {
+  // background-color: #fff;
+  height: calc(100vh - 80px);
+  .seach {
+    margin-bottom: 16px;
+    padding: 24px;
+    background-color: #fff;
+  }
+}
+.el-drawer__title {
+  font-weight: bold;
+  color: #666;
+}
+.main-table {
+  background-color: #fff;
+  padding: 24px;
+  height: calc(100vh - 85px);
+  .main-table-title {
+    .title {
+      display: flex;
+      margin-bottom: 24px;
+      .line {
+        width: 6px;
+        height: 20px;
+        background: #4287ff;
+        position: relative;
+        top: 5px;
+        margin-right: 12px;
+      }
+      span {
+        font-size: 20px;
+      }
+    }
+  }
+}
+.el-form-item {
+  align-items: center;
+}
+.seach {
+  .el-form-item {
+    margin-bottom: 0;
+  }
+}
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
diff --git a/src/style/sidebar.scss b/src/style/sidebar.scss
index e2f7274..27d7927 100644
--- a/src/style/sidebar.scss
+++ b/src/style/sidebar.scss
@@ -35,6 +35,7 @@
 
   .main-container {
     position: relative;
+    min-width: 1500px;
     height: 100vh;
     min-height: 100%;
     margin-left: $sideBarWidth;
diff --git a/src/utils/auth.ts b/src/utils/auth.ts
index ed29613..779361b 100644
--- a/src/utils/auth.ts
+++ b/src/utils/auth.ts
@@ -1,6 +1,6 @@
 import Cookies from "js-cookie";
 import { storageSession } from "@pureadmin/utils";
-import { useUserStoreHook } from "@/store/modules/user";
+// import { useUserStoreHook } from "@/store/modules/user";
 
 export interface DataInfo<T> {
   /** token */
@@ -37,6 +37,13 @@ export function setToken(data: any) {
   storageSession().setItem("token", data);
 }
 
+export function setUserInfo(data: any) {
+  storageSession().setItem("userInfo", JSON.stringify(data));
+}
+export function getUserInfo() {
+  const data = storageSession().getItem("userInfo");
+  return data;
+}
 /** 删除`token`以及key值为`user-info`的session信息 */
 export function removeToken() {
   Cookies.remove(TokenKey);
@@ -53,3 +60,6 @@ export function clearObject(obj) {
     obj[key] = null; // 或者 obj[key] = undefined;
   });
 }
+export function downLoadUrl(id) {
+  return `/virtual-patient-manage/fileManage/downloadFile?fileId=${id}`;
+}
diff --git a/src/utils/http/index.ts b/src/utils/http/index.ts
index e930b5e..a75a1bb 100644
--- a/src/utils/http/index.ts
+++ b/src/utils/http/index.ts
@@ -14,12 +14,12 @@ import NProgress from "../progress";
 import { getToken, formatToken } from "@/utils/auth";
 import { useUserStoreHook } from "@/store/modules/user";
 import { message } from "../message";
-import router from "@/router";
+// import router from "@/router";
 
 // 相关配置请参考:www.axios-js.com/zh-cn/docs/#axios-request-config-1
 const defaultConfig: AxiosRequestConfig = {
   // 请求超时时间
-  timeout: 10000,
+  timeout: 100000,
   headers: {
     Accept: "application/json, text/plain, */*",
     "Content-Type": "application/json",
@@ -125,11 +125,11 @@ class PureHttp {
     instance.interceptors.response.use(
       (response: PureHttpResponse) => {
         if (response.data.code === 401) {
-          router.push("/login");
+          useUserStoreHook().logOut();
           return;
         }
         if (response.data.code !== 200) {
-          message(response.data.msg, { type: "error" });
+          message(response.data.data, { type: "error" });
         }
 
         const $config = response.config;
@@ -201,6 +201,22 @@ class PureHttp {
   ): Promise<P> {
     return this.request<P>("get", url, params, config);
   }
+  /** 单独抽离的put工具函数 */
+  public put<T, P>(
+    url: string,
+    params?: AxiosRequestConfig<T>,
+    config?: PureHttpRequestConfig
+  ): Promise<P> {
+    return this.request<P>("post", url, params, config);
+  }
+  /** 单独抽离的delete工具函数 */
+  public delete<T, P>(
+    url: string,
+    params?: AxiosRequestConfig<T>,
+    config?: PureHttpRequestConfig
+  ): Promise<P> {
+    return this.request<P>("delete", url, params, config);
+  }
 }
 
 export const http = new PureHttp();
diff --git a/src/views/caseManagement/diseaseType/bodyInspect/addEdit.vue b/src/views/caseManagement/diseaseType/bodyInspect/addEdit.vue
new file mode 100644
index 0000000..be2fa6d
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/bodyInspect/addEdit.vue
@@ -0,0 +1,376 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import {
+  addBodyInspect,
+  queryPhysicalToolList,
+  queryTreeDiseasePhysical,
+  updateBodyInspect
+} from "@/api/disease";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "AddEdit"
+});
+const props = {
+  value: "id",
+  label: "toolName",
+  children: "toolList",
+  disabled: "flag",
+
+  expandTrigger: "hover" as const
+};
+const bodyProps = {
+  value: "id",
+  checkStrictly: true,
+  label: "locationName",
+  children: "child",
+  disabled: "flag"
+};
+const bodyTreeList = ref([]);
+const route = useRoute();
+const isEditFlag = ref(false);
+const requireLocationFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  toolIdPath: [],
+  diagnosticCriteria: [],
+  locationId: "",
+  locationIdPath: [],
+  expectedDiagnosisResult: undefined,
+  diagnosticRes: "",
+  result: "",
+  requireCheckFlag: "",
+  toolId: "",
+  normalResult: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const bodyToolList = ref([]);
+const cascaderRef = ref();
+const locationIdPathRef = ref();
+const handleChange = item => {
+  const dataInfo = cascaderRef.value.getCheckedNodes();
+  if (dataInfo && dataInfo.length > 0) {
+    if (dataInfo[0].data.requireLocation === 1) {
+      requireLocationFlag.value = true;
+    } else {
+      requireLocationFlag.value = false;
+    }
+  }
+
+  formData.toolId = item[item.length - 1];
+  getBodyTree();
+  formData.locationIdPath = [];
+  formData.locationId = "";
+  formData.result = "";
+  formData.normalResult = "";
+  formData.expectedDiagnosisResult = undefined;
+};
+const handleLocationChange = item => {
+  formData.locationId = item[item.length - 1];
+  formData.result = "";
+  formData.expectedDiagnosisResult = undefined;
+  const dataInfo = locationIdPathRef.value.getCheckedNodes();
+  if (dataInfo && dataInfo.length > 0 && dataInfo[0].data.indicatorValue) {
+    formData.normalResult = dataInfo[0].data.indicatorValue;
+  }
+};
+const rules = {
+  toolIdPath: [
+    { required: true, message: "请选择体格检查项", trigger: "change" }
+  ],
+  requireCheckFlag: [
+    { required: true, message: "请选择是否必查", trigger: "change" }
+  ],
+  expectedDiagnosisResult: [
+    { required: true, message: "请选择预期诊断结果", trigger: "change" }
+  ],
+  result: [{ required: true, message: "请输入异常结果", trigger: "change" }]
+};
+const getPhysicalToolList = async () => {
+  const res: any = await queryPhysicalToolList();
+  bodyToolList.value = res.data;
+};
+defineExpose({
+  async open(item) {
+    getPhysicalToolList();
+    dialogVisible.value = true;
+    await nextTick;
+    isEditFlag.value = false;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      if (item.locationIdPath && item.locationIdPath.length > 0) {
+        requireLocationFlag.value = true;
+      } else {
+        requireLocationFlag.value = false;
+      }
+      getBodyTree();
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+  formData.result = "";
+  formData.expectedDiagnosisResult = "";
+};
+const reset = () => {
+  if (isEditFlag.value) {
+    ruleFormRef.value.resetFields([
+      "expectedDiagnosisResult",
+      "normalResult",
+      "result",
+      "diagnosticCriteria",
+      "requireCheckFlag"
+    ]);
+  } else {
+    ruleFormRef.value.resetFields();
+  }
+  formData.result = "";
+  formData.expectedDiagnosisResult = "";
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+
+// 查询部位树
+const getBodyTree = async () => {
+  const res: any = await queryTreeDiseasePhysical({
+    diseaseId: route.query.id,
+    toolId: formData.toolId
+  });
+  bodyTreeList.value = res.data;
+};
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const params = {
+        ...formData,
+        diseaseId: route.query.id
+      };
+      if (isEditFlag.value) {
+        const res: any = await updateBodyInspect({
+          ...params,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+          dialogVisible.value = false;
+          id.value = "";
+          emit("update");
+        }
+      } else {
+        const res: any = await addBodyInspect(params);
+        if (res.code === 200) {
+          dialogVisible.value = false;
+          message("新增成功", { type: "success" });
+          emit("update");
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>体格检查</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item label="疾病名称:" prop="code">
+            <!-- <span>{{ route.query.diseaseName }}</span> -->
+            <el-input size="large" readonly v-model="route.query.diseaseName" />
+          </el-form-item>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="体格检查项:" prop="toolIdPath">
+                <el-cascader
+                  :disabled="isEditFlag"
+                  ref="cascaderRef"
+                  style="width: 100%"
+                  size="large"
+                  v-model="formData.toolIdPath"
+                  :options="bodyToolList"
+                  :props="props"
+                  @change="handleChange"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-row v-if="requireLocationFlag">
+            <el-col :span="24">
+              <el-form-item label="检查部位:" prop="locationIdPath">
+                <el-cascader
+                  :disabled="isEditFlag"
+                  ref="locationIdPathRef"
+                  size="large"
+                  style="width: 100%"
+                  v-model="formData.locationIdPath"
+                  :options="bodyTreeList"
+                  :props="bodyProps"
+                  @change="handleLocationChange"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="预期结果:" prop="expectedDiagnosisResult">
+                <el-radio-group
+                  @change="formData.result = ''"
+                  v-model="formData.expectedDiagnosisResult"
+                >
+                  <el-radio :label="0" size="large">正常</el-radio>
+                  <el-radio :label="1" size="large">异常</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="正常结果:" prop="normalResult">
+                <el-input
+                  size="large"
+                  v-model="formData.normalResult"
+                  placeholder="请输入正常结果"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row v-if="formData.expectedDiagnosisResult === 1">
+            <el-col :span="24">
+              <el-form-item label="异常结果:" prop="result">
+                <el-input
+                  size="large"
+                  v-model="formData.result"
+                  placeholder="请输入异常结果"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-form-item label="诊断依据:" prop="diagnosticCriteria">
+            <el-checkbox-group v-model="formData.diagnosticCriteria">
+              <el-checkbox :label="0">初步诊断依据</el-checkbox>
+              <el-checkbox :label="1">证实诊断依据</el-checkbox>
+              <el-checkbox :label="2">鉴别依据</el-checkbox>
+              <el-checkbox :label="3">全面依据</el-checkbox>
+            </el-checkbox-group>
+          </el-form-item>
+          <el-row>
+            <el-form-item label="是否必查:" prop="requireCheckFlag">
+              <el-radio-group v-model="formData.requireCheckFlag">
+                <el-radio :label="0" size="large">否</el-radio>
+                <el-radio :label="1" size="large">是</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-row>
+
+          <!-- <el-form-item label="诊断结果:" prop="trait">
+            <WangEditor ref="refWangEditor" />
+          </el-form-item> -->
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="reset()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/diseaseType/bodyInspect/index.vue b/src/views/caseManagement/diseaseType/bodyInspect/index.vue
new file mode 100644
index 0000000..1fd66de
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/bodyInspect/index.vue
@@ -0,0 +1,131 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+
+import { queryBodyListByDiseaseId, deleteBodyItem } from "@/api/disease";
+import { ElMessageBox } from "element-plus";
+import { message } from "@/utils/message";
+import { useRoute } from "vue-router";
+import AddEdit from "./addEdit.vue";
+
+const route = useRoute();
+const selectBodyInspectList = ref([]);
+const AddEditRef = ref();
+const columns: TableColumnList = [
+  {
+    label: "体格检查项目",
+    prop: "toolName"
+  },
+  {
+    label: "固定检查位",
+    prop: "locationName"
+  },
+  // {
+  //   label: "诊断判读",
+  //   prop: "diagnosisAssessmentFlag",
+  //   formatter: ({ diagnosisAssessmentFlag }) => {
+  //     return diagnosisAssessmentFlag === 0 ? "不需要" : "需要";
+  //   }
+  // },
+  {
+    label: "是否必查",
+    prop: "requireCheckFlag",
+    formatter: ({ requireCheckFlag }) => {
+      return requireCheckFlag === 0 ? "否" : "是";
+    }
+  },
+  {
+    label: "预期诊断结果",
+    prop: "expectedDiagnosisResult",
+    formatter: ({ expectedDiagnosisResult }) => {
+      return expectedDiagnosisResult === 0 ? "正常" : "异常";
+    }
+  },
+  {
+    label: "操作",
+    width: 150,
+    slot: "operation"
+  }
+];
+defineOptions({
+  name: "BodyInspect"
+});
+
+onMounted(() => {
+  getBodyListByDiseaseId();
+});
+
+const getBodyListByDiseaseId = async () => {
+  const res: any = await queryBodyListByDiseaseId({
+    diseaseId: route.query.id
+  });
+  selectBodyInspectList.value = res.data;
+};
+
+const del = item => {
+  ElMessageBox.confirm(item ? `是否删除` : "", "提示", {
+    type: "warning"
+  })
+    .then(async () => {
+      const res = await deleteBodyItem({ id: item.id });
+      if (res.code === 200) {
+        getBodyListByDiseaseId();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = row => {
+  AddEditRef.value.open(row);
+};
+</script>
+
+<template>
+  <div class="body-inspect main-table">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>
+          {{ `已选体格检查项目【${selectBodyInspectList.length}个】` }}
+        </span>
+      </div>
+      <el-row class="mb-6">
+        <el-button size="large" class="btn" @click="add" type="primary"
+          >新建</el-button
+        >
+      </el-row>
+    </div>
+
+    <pure-table
+      adaptive
+      ref="tableRef"
+      align-whole="center"
+      showOverflowTooltip
+      :data="selectBodyInspectList"
+      :columns="columns"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+    >
+      <template #operation="{ row }">
+        <el-button link type="primary" @click="edit(row)">编辑</el-button>
+        <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+      </template></pure-table
+    >
+    <AddEdit @update="getBodyListByDiseaseId" ref="AddEditRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.body-inspect {
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+
+  .footer {
+    flex: 1;
+  }
+}
+</style>
diff --git a/src/views/caseManagement/diseaseType/compontents/addComplexDiseases.vue b/src/views/caseManagement/diseaseType/compontents/addComplexDiseases.vue
new file mode 100644
index 0000000..d38aaea
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/compontents/addComplexDiseases.vue
@@ -0,0 +1,197 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { addSave, update, queryPageList } from "@/api/disease";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { nextTick } from "vue";
+defineOptions({
+  name: "AddComplexDiseases"
+});
+const dialogVisible = ref(false);
+const title = ref("");
+const formData = reactive({
+  diseaseName: "",
+  diseaseNameAlias: "",
+  symptom: "",
+  containDiseaseIds: [],
+  id: undefined
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  diseaseNameAlias: [{ required: true, message: "请选择", trigger: "change" }],
+  diseaseName: [
+    { required: true, message: "请输入疾病分类名称", trigger: "change" }
+  ]
+};
+
+const diseaseList = ref([]);
+defineExpose({
+  async open(type, item) {
+    dialogVisible.value = true;
+    await nextTick();
+    getDiseaseList();
+    if (type === "add") {
+      title.value = "新增复合疾病";
+    } else {
+      title.value = "编辑复合疾病";
+      // formData = JSON.parse(JSON.stringify(item));
+      formData.diseaseNameAlias = item.diseaseNameAlias;
+      formData.diseaseName = item.diseaseName;
+      formData.containDiseaseIds = item.containDiseaseIds;
+      formData.symptom = item.symptom;
+      formData.id = item.id;
+    }
+  }
+});
+const getDiseaseList = async () => {
+  const params = {
+    pageNum: 1,
+    pageSize: 99999,
+    diseaseName: ""
+  };
+  const res: any = await queryPageList(params);
+  diseaseList.value = res.data.records;
+};
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const selectDisease = val => {
+  const list = [];
+  for (const item of val) {
+    diseaseList.value.forEach(res => {
+      if (res.id === item) {
+        list.push(res.diseaseNameAlias);
+      }
+    });
+  }
+  formData.diseaseNameAlias = list.join(",");
+};
+const emit = defineEmits(["update"]);
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (title.value === "编辑复合疾病") {
+        const {
+          containDiseaseIds,
+          diseaseName,
+          diseaseNameAlias,
+          symptom,
+          id
+        } = formData;
+
+        const res: any = await update({
+          containDiseaseIds,
+          diseaseName,
+          diseaseNameAlias,
+          symptom,
+          id
+        });
+        if (res.code === 200) {
+          closeDialog();
+          emit("update");
+          message("编辑成功", { type: "success" });
+        }
+      } else {
+        const { containDiseaseIds, diseaseName, diseaseNameAlias, symptom } =
+          formData;
+        const res: any = await addSave({
+          containDiseaseIds,
+          diseaseName,
+          diseaseNameAlias,
+          symptom
+        });
+        if (res.code === 200) {
+          closeDialog();
+          emit("update");
+          message("新增成功", { type: "success" });
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      width="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>{{ title }}</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="疾病分类:" prop="containDiseaseIds">
+            <el-select
+              style="width: 100%"
+              size="large"
+              filterable
+              multiple
+              v-model="formData.containDiseaseIds"
+              placeholder="请选择"
+              @change="selectDisease"
+            >
+              <el-option
+                v-for="item in diseaseList"
+                :key="item.id"
+                :label="item.diseaseName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="疾病分类别名:" prop="diseaseNameAlias">
+            <el-input
+              readonly
+              v-model="formData.diseaseNameAlias"
+              size="large"
+              placeholder="请输入疾病分类别名"
+            />
+          </el-form-item>
+          <el-form-item label="疾病分类名称:" prop="diseaseName">
+            <el-input
+              size="large"
+              maxlength="20"
+              show-word-limit
+              v-model="formData.diseaseName"
+              placeholder="请输入疾病分类名称"
+            />
+          </el-form-item>
+          <el-form-item label="症状:" prop="symptom">
+            <el-input
+              size="large"
+              maxlength="20"
+              show-word-limit
+              v-model="formData.symptom"
+              placeholder="请输入症状"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
diff --git a/src/views/caseManagement/diseaseType/compontents/addEdit.vue b/src/views/caseManagement/diseaseType/compontents/addEdit.vue
new file mode 100644
index 0000000..57d2642
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/compontents/addEdit.vue
@@ -0,0 +1,158 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { addSave, update } from "@/api/disease";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { nextTick } from "vue";
+defineOptions({
+  name: "AddEdit"
+});
+const dialogVisible = ref(false);
+const title = ref("");
+const formData = reactive({
+  diseaseName: "",
+  diseaseNameAlias: "",
+  code: "",
+  symptom: "",
+  id: undefined
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  code: [{ required: true, message: "请输入类目编码", trigger: "change" }],
+  diseaseNameAlias: [
+    { required: true, message: "请输入疾病分类别名", trigger: "change" }
+  ],
+  diseaseName: [
+    { required: true, message: "请输入疾病分类名称", trigger: "change" }
+  ]
+};
+defineExpose({
+  async open(type, item) {
+    dialogVisible.value = true;
+    await nextTick();
+    if (type === "add") {
+      title.value = "新增单一疾病";
+    } else {
+      title.value = "编辑单一疾病";
+      // formData = JSON.parse(JSON.stringify(item));
+      formData.diseaseName = item.diseaseName;
+      formData.diseaseNameAlias = item.diseaseNameAlias;
+      formData.code = item.code;
+      formData.symptom = item.symptom;
+      formData.id = item.id;
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (title.value === "编辑单一疾病") {
+        const { code, diseaseName, diseaseNameAlias, symptom, id } = formData;
+
+        const res: any = await update({
+          code,
+          diseaseName,
+          diseaseNameAlias,
+          symptom,
+          id
+        });
+        if (res.code === 200) {
+          closeDialog();
+          emit("update");
+          message("编辑成功", { type: "success" });
+        }
+      } else {
+        const { code, diseaseName, diseaseNameAlias, symptom } = formData;
+        const res: any = await addSave({
+          code,
+          diseaseName,
+          diseaseNameAlias,
+          symptom
+        });
+        if (res.code === 200) {
+          closeDialog();
+          emit("update");
+          message("新增成功", { type: "success" });
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      width="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>{{ title }}</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="类目编码:" prop="code">
+            <el-input
+              size="large"
+              v-model="formData.code"
+              maxlength="20"
+              placeholder="请输入类目编码"
+            />
+          </el-form-item>
+          <el-form-item label="疾病分类别名:" prop="diseaseNameAlias">
+            <el-input
+              maxlength="20"
+              v-model="formData.diseaseNameAlias"
+              size="large"
+              placeholder="请输入疾病分类别名"
+            />
+          </el-form-item>
+          <el-form-item label="疾病分类名称:" prop="diseaseName">
+            <el-input
+              size="large"
+              maxlength="20"
+              v-model="formData.diseaseName"
+              placeholder="请输入疾病分类名称"
+            />
+          </el-form-item>
+          <el-form-item label="症状:" prop="symptom">
+            <el-input
+              size="large"
+              maxlength="20"
+              v-model="formData.symptom"
+              placeholder="请输入症状"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
diff --git a/src/views/caseManagement/diseaseType/compontents/problemBase.vue b/src/views/caseManagement/diseaseType/compontents/problemBase.vue
new file mode 100644
index 0000000..d34b74b
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/compontents/problemBase.vue
@@ -0,0 +1,186 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { PaginationProps } from "@pureadmin/table";
+import { queryListAqLibrary } from "@/api/disease";
+import { message } from "@/utils/message";
+import { queryCommonDictTree } from "@/api/utils";
+defineOptions({
+  name: "ProblemBase"
+});
+const dialogVisible = ref(false);
+const seachForm = reactive({
+  dictId: "",
+  dicIdPath: []
+});
+const multipleSelection = ref([]);
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const props = {
+  value: "id",
+  label: "nameZh",
+  children: "childDictTreeList",
+  expandTrigger: "hover" as const
+};
+const handleChange = item => {
+  seachForm.dictId = item[item.length - 1];
+};
+const selectColumns: TableColumnList = [
+  {
+    type: "selection",
+    align: "left"
+  },
+
+  {
+    label: "问题类目",
+    prop: "nameZhPath"
+  },
+  {
+    label: "问题",
+    prop: "question"
+  },
+  {
+    label: "回复",
+    prop: "defaultAnswer"
+  }
+];
+const dataList = ref([
+  {
+    question: "dsdsdsdsd"
+  },
+  {
+    question: "dsdsdsdsd"
+  }
+]);
+
+const dictList = ref([]);
+const getCommonDictTree = async () => {
+  const res: any = await queryCommonDictTree({
+    groupCode: "AQT"
+  });
+  dictList.value = res.data;
+};
+defineExpose({
+  open() {
+    dialogVisible.value = true;
+    getData();
+    getCommonDictTree();
+  }
+});
+const getData = async () => {
+  const res: any = await queryListAqLibrary({
+    dictId: seachForm.dictId,
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize
+  });
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+function handleSelectionChange(val) {
+  multipleSelection.value = val;
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.dictId = "";
+  seachForm.dicIdPath = [];
+  search();
+};
+const emit = defineEmits(["select"]);
+const save = () => {
+  if (multipleSelection.value.length > 0) {
+    emit("select", multipleSelection.value);
+    dialogVisible.value = false;
+  } else {
+    message("请至少选择一条数据", { type: "warning" });
+  }
+};
+</script>
+
+<template>
+  <div>
+    <el-dialog
+      width="1200"
+      append-to-body
+      title="问题库"
+      v-model="dialogVisible"
+      custom-class="ProblemBase"
+    >
+      <div>
+        <div class="seach">
+          <el-form :model="seachForm">
+            <el-row class="mb-4">
+              <el-form-item label="类目:">
+                <el-cascader
+                  style="width: 100%"
+                  size="large"
+                  v-model="seachForm.dicIdPath"
+                  :options="dictList"
+                  :props="props"
+                  @change="handleChange"
+                />
+              </el-form-item>
+              <el-button
+                size="large"
+                class="ml-4"
+                @click="search"
+                type="primary"
+                >搜索</el-button
+              >
+              <el-button size="large" @click="reset">重置</el-button>
+            </el-row>
+            <!-- <el-row class="mb-4">
+              <el-button size="large" @click="save" type="primary"
+                >保存</el-button
+              >
+            </el-row> -->
+          </el-form>
+        </div>
+        <pure-table
+          align-whole="center"
+          showOverflowTooltip
+          table-layout="auto"
+          row-key="id"
+          adaptive
+          :data="dataList"
+          :columns="selectColumns"
+          :pagination="pagination"
+          :header-cell-style="{
+            background: 'var(--el-table-row-hover-bg-color)',
+            color: 'var(--el-text-color-primary)'
+          }"
+          @selection-change="handleSelectionChange"
+          @page-size-change="handleSizeChange"
+          @page-current-change="handleCurrentChange"
+        />
+      </div>
+      <template #footer>
+        <el-button
+          size="large"
+          class="footer-btn"
+          @click="dialogVisible = false"
+          >取消</el-button
+        >
+        <el-button size="large" @click="save" class="footer-btn" type="primary"
+          >确定</el-button
+        >
+      </template>
+    </el-dialog>
+  </div>
+</template>
diff --git a/src/views/caseManagement/diseaseType/disposalPlan/addEdit.vue b/src/views/caseManagement/diseaseType/disposalPlan/addEdit.vue
new file mode 100644
index 0000000..082a769
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/disposalPlan/addEdit.vue
@@ -0,0 +1,371 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import {
+  saveDiseaseTreatmentPlan,
+  updateDiseaseTreatmentPlann,
+  queryTreeTreatmentPlan
+} from "@/api/disease";
+import { queryDrugManagePageList } from "@/api/inquiryManagement";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { useRoute } from "vue-router";
+
+defineOptions({
+  name: "AddEdit"
+});
+import { queryCommonDictTree } from "@/api/utils";
+const route = useRoute();
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  id: "",
+  disposalPlanId: "",
+  firstMeasuresId: "",
+  disposalMethod: "",
+  drugIds: []
+});
+const dosageFormList = ref([]);
+const ruleFormRef = ref<FormInstance>();
+const firstMeasuresList = ref([]);
+const medicationList = ref([]);
+const rules = {
+  disposalMethod: [{ required: true, message: "请选择", trigger: "change" }],
+  disposalPlanId: [{ required: true, message: "请选择", trigger: "change" }],
+  drugIds: [{ required: true, message: "请选择", trigger: "change" }]
+};
+const disposalMethodFlag = ref(false);
+defineExpose({
+  async add(val) {
+    dialogVisible.value = true;
+    await nextTick;
+    isEditFlag.value = false;
+    getDosageFormList();
+    if (val !== null) {
+      formData.disposalMethod = val;
+      getTree(val);
+      disposalMethodFlag.value = true;
+    } else {
+      disposalMethodFlag.value = false;
+    }
+  },
+  async edit(item) {
+    getDosageFormList();
+    disposalMethodFlag.value = true;
+    dialogVisible.value = true;
+    await nextTick;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+    getDrugList(formData.firstMeasuresId);
+    const res: any = await queryTreeTreatmentPlan({
+      diseaseId: route.query.id,
+      disposalMethod: formData.disposalMethod
+    });
+    disposalPlanList.value = res.data;
+    if (formData.disposalPlanId) {
+      disposalPlanList.value.forEach(res => {
+        if (res.id === formData.disposalPlanId) {
+          firstMeasuresList.value = res.child;
+        }
+      });
+    }
+  }
+});
+const resetForm = () => {
+  if (disposalMethodFlag.value) {
+    ruleFormRef.value.resetFields([
+      "disposalPlanId",
+      "firstMeasuresId",
+      "drugIds"
+    ]);
+  } else {
+    ruleFormRef.value.resetFields();
+  }
+
+  firstMeasuresList.value = [];
+  formData.firstMeasuresId = "";
+  isEditFlag.value = false;
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const disposalPlanList = ref([]);
+const handleChange = val => {
+  disposalPlanList.value.forEach(res => {
+    if (res.id === val) {
+      firstMeasuresList.value = res.child;
+    }
+  });
+  formData.drugIds = [];
+  formData.firstMeasuresId = "";
+};
+const getDosageFormList = async () => {
+  const res: any = await queryCommonDictTree({ groupCode: "DOSE" });
+  dosageFormList.value = res.data;
+};
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (isEditFlag.value) {
+        const res: any = await updateDiseaseTreatmentPlann({
+          ...formData,
+          diseaseId: route.query.id
+        });
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+          formData.disposalMethod = "";
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      } else {
+        const res: any = await saveDiseaseTreatmentPlan({
+          ...formData,
+          diseaseId: route.query.id,
+          id: undefined
+        });
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+          formData.disposalMethod = "";
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const selectType = val => {
+  getTree(val);
+};
+const getDrugList = async val => {
+  if (formData.disposalPlanId === "8") {
+    const res: any = await queryDrugManagePageList({
+      pageNum: 1,
+      pageSize: 99999,
+      dosageForm: val
+    });
+    medicationList.value = res.data.records;
+  }
+};
+const getTree = async val => {
+  const res: any = await queryTreeTreatmentPlan({
+    diseaseId: route.query.id,
+    disposalMethod: val
+  });
+  disposalPlanList.value = res.data;
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>处置计划</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item
+            label="处置方式:"
+            style="margin-bottom: 0"
+            prop="disposalMethod"
+          >
+            <el-radio-group
+              :disabled="disposalMethodFlag"
+              v-model="formData.disposalMethod"
+              @change="selectType"
+            >
+              <el-radio :label="0" size="large">门诊收治</el-radio>
+              <el-radio :label="1" size="large">入院治疗</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <div class="add_tip">该疾病处置方式配置后不支持修改</div>
+          <el-form-item label="处置计划:" prop="disposalPlanId">
+            <el-select
+              filterable
+              size="large"
+              v-model="formData.disposalPlanId"
+              style="width: 100%"
+              placeholder="请选择"
+              @change="handleChange"
+            >
+              <el-option
+                v-for="item in disposalPlanList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            v-if="formData.disposalPlanId !== '8'"
+            label="一级措施"
+            prop="firstMeasuresId"
+          >
+            <el-select
+              filterable
+              size="large"
+              v-model="formData.firstMeasuresId"
+              style="width: 100%"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in firstMeasuresList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            v-if="formData.disposalPlanId === '8'"
+            label="一级措施"
+            prop="firstMeasuresId"
+          >
+            <el-select
+              filterable
+              size="large"
+              v-model="formData.firstMeasuresId"
+              style="width: 100%"
+              placeholder="请选择"
+              @change="getDrugList"
+            >
+              <el-option
+                v-for="item in dosageFormList"
+                :key="item.code"
+                :label="item.nameZh"
+                :value="item.code"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            v-if="formData.disposalPlanId === '8'"
+            label="选择药品"
+            prop="drugIds"
+          >
+            <el-select
+              filterable
+              size="large"
+              multiple
+              v-model="formData.drugIds"
+              style="width: 100%"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in medicationList"
+                :key="item.id"
+                :label="item.drugName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .add_tip {
+    margin-bottom: 12px;
+    margin-left: 100px;
+    font-size: 12px;
+    color: #999;
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/diseaseType/disposalPlan/index.vue b/src/views/caseManagement/diseaseType/disposalPlan/index.vue
new file mode 100644
index 0000000..80ed392
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/disposalPlan/index.vue
@@ -0,0 +1,186 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+import {
+  queryListBiseaseTreatmentPlan,
+  deleteTreatmentPlan
+} from "@/api/disease";
+import { useRoute } from "vue-router";
+import { ElMessageBox } from "element-plus";
+import { message } from "@/utils/message";
+import AddEdit from "./addEdit.vue";
+const route = useRoute();
+
+const AddEditRef = ref();
+
+const columns: TableColumnList = [
+  {
+    label: "处置方式",
+    prop: "disposalMethod",
+    formatter: ({ disposalMethod }) => {
+      return disposalMethod === 0 ? "门诊收治" : "入院治疗";
+    }
+  },
+  {
+    label: "处置计划",
+    prop: "disposalPlan"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+
+  {
+    label: "操作",
+    width: 150,
+    slot: "operation"
+  }
+];
+defineOptions({
+  name: "DisposalPlan"
+});
+const selectDisposalPlanList = ref([]);
+const getData = async () => {
+  const res: any = await queryListBiseaseTreatmentPlan({
+    diseaseId: route.query.id
+  });
+  selectDisposalPlanList.value = res.data;
+};
+onMounted(() => {
+  getData();
+});
+
+const add = () => {
+  let flag = true;
+  if (selectDisposalPlanList.value.length === 0) {
+    flag = true;
+  } else {
+    flag = false;
+  }
+  if (flag) {
+    AddEditRef.value.add(null);
+  } else {
+    AddEditRef.value.add(selectDisposalPlanList.value[0].disposalMethod);
+  }
+};
+const edit = row => {
+  AddEditRef.value.edit(row);
+};
+const del = item => {
+  ElMessageBox.confirm(item ? `是否删除` : "", "提示", {
+    type: "warning"
+  })
+    .then(async () => {
+      const res = await deleteTreatmentPlan({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        // getTree(formData.disposalMethod);
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+</script>
+
+<template>
+  <div class="disposal-plan main-table">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>
+          {{ `已选处置计划【${selectDisposalPlanList.length}个】` }}
+        </span>
+      </div>
+      <el-row class="mb-6">
+        <el-button size="large" class="btn" @click="add" type="primary"
+          >新建</el-button
+        >
+      </el-row>
+    </div>
+    <div>
+      <pure-table
+        border
+        align-whole="center"
+        showOverflowTooltip
+        :data="selectDisposalPlanList"
+        :columns="columns"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+      >
+        <template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+          <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+        </template></pure-table
+      >
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+    <!-- <div class="btn-list">
+      <el-button size="large" @click="submit(ruleFormRef)" type="primary"
+        >确定</el-button
+      >
+      <el-button size="large" @click="resetForm(ruleFormRef)">重置</el-button>
+    </div> -->
+    <!-- 处置计划详情 -->
+    <!-- <el-dialog
+      width="800"
+      append-to-body
+      v-model="visible"
+      :center="true"
+      :show-close="false"
+      custom-class="disposal-plan-dialog"
+    >
+      <template v-slot:header>
+        <custom-dialog-header title="处置计划详情" />
+      </template>
+      <div class="disposal-plan-dialog">
+        <el-row>
+          <el-col class="mb-10" :span="12">
+            <label>处置计划:</label>
+            <span>{{ disposalPlanInfo.disposalPlan }}</span>
+          </el-col>
+          <el-col class="mb-10" :span="12">
+            <label>处置方式:</label>
+            <span>{{
+              disposalPlanInfo.disposalMethod === 1 ? "入院治疗" : "门诊收治"
+            }}</span>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col class="mb-10" :span="12">
+            <label>一级措施:</label>
+            <span>{{ disposalPlanInfo.firstMeasures }}</span>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col class="mb-10" :span="24">
+            <label>说明:</label>
+            <span>{{ disposalPlanInfo.description }}</span>
+          </el-col>
+        </el-row>
+        <div style="text-align: center">
+          <el-button
+            class="footer_btn"
+            size="large"
+            @click="visible = false"
+            type="primary"
+            >知道了</el-button
+          >
+        </div>
+      </div>
+    </el-dialog> -->
+  </div>
+</template>
+<style lang="scss" scoped>
+.disposal-plan {
+  .btn-list {
+    margin-top: 16px;
+  }
+}
+
+.disposal-plan-dialo {
+  .dialog-item {
+    height: 40px;
+  }
+}
+</style>
diff --git a/src/views/caseManagement/diseaseType/index.vue b/src/views/caseManagement/diseaseType/index.vue
new file mode 100644
index 0000000..97c9173
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/index.vue
@@ -0,0 +1,232 @@
+<script setup lang="ts">
+import router from "@/router";
+import { PaginationProps } from "@pureadmin/table";
+import AddEdit from "./compontents/addEdit.vue";
+import ProblemBase from "./compontents/problemBase.vue";
+import { reactive, ref } from "vue";
+import { queryPageList, deleteItem } from "@/api/disease";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import { ElMessageBox } from "element-plus";
+import AddComplexDiseases from "./compontents/addComplexDiseases.vue";
+defineOptions({
+  name: "DiseaseType"
+});
+
+const dataList = ref([{}]);
+const loading = ref(false);
+const addEditRef = ref(null);
+const AddComplexDiseasesRef = ref();
+const problemBaseRef = ref(null);
+const seachForm = reactive({
+  diseaseName: "",
+  diseaseType: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns: TableColumnList = [
+  {
+    label: "类目编码",
+    prop: "code",
+    minWidth: 150
+  },
+  {
+    label: "疾病分类名称",
+    prop: "diseaseName",
+    minWidth: 240
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    width: 400,
+    slot: "operation"
+  }
+];
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    diseaseName: seachForm.diseaseName,
+    diseaseType: seachForm.diseaseType
+  };
+  const res: any = await queryPageList(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.diseaseName = "";
+  seachForm.diseaseType = "";
+  search();
+};
+const add = () => {
+  addEditRef.value.open("add");
+};
+const addComplex = () => {
+  AddComplexDiseasesRef.value.open("add");
+};
+const edit = item => {
+  if (item.diseaseType === 0) {
+    addEditRef.value.open("edit", JSON.parse(JSON.stringify(item)));
+  } else {
+    AddComplexDiseasesRef.value.open("edit", JSON.parse(JSON.stringify(item)));
+  }
+};
+// 问诊
+// const inspect = item => {
+//   router.push({
+//     name: "diseaseTypeInquiry",
+//     query: {
+//       id: item.id
+//     }
+//   });
+// };
+const openBodyInspect = item => {
+  router.push({
+    path: "/caseManagement/diseaseType/bodyInspect",
+    query: {
+      id: item.id,
+      diseaseName: item.diseaseName
+    }
+  });
+};
+const openSupportInspect = item => {
+  router.push({
+    path: "/caseManagement/diseaseType/supportInspect",
+    query: {
+      id: item.id,
+      diseaseName: item.diseaseName
+    }
+  });
+};
+const openDisposalPlan = item => {
+  router.push({
+    name: "diseaseTypeDisposalPlan",
+    query: {
+      id: item.id
+    }
+  });
+};
+const handleDelete = item => {
+  ElMessageBox.confirm(
+    item ? `确认删除后${item.diseaseName}的所有信息将被清空, 且无法恢复` : "",
+    "提示",
+    {
+      type: "warning"
+    }
+  )
+    .then(async () => {
+      const res = await deleteItem({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="diseaseType app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="疾病分类:">
+            <el-input size="large" v-model="seachForm.diseaseName" />
+          </el-form-item>
+          <el-form-item class="ml-4" label="类型:">
+            <el-select
+              size="large"
+              clearable
+              v-model="seachForm.diseaseType"
+              placeholder="请选择性别"
+            >
+              <el-option label="全部" value="" />
+              <el-option label="单一" :value="0" />
+              <el-option label="复合" :value="1" />
+            </el-select>
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>疾病分类列表</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary"
+            >新增单一疾病</el-button
+          >
+          <el-button size="large" @click="addComplex" type="primary"
+            >新增复合疾病</el-button
+          >
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)"> 编辑 </el-button>
+          <!-- <el-button link type="primary" @click="inspect(row)">
+            问诊
+          </el-button> -->
+          <el-button link type="primary" @click="openBodyInspect(row)">
+            体格检查
+          </el-button>
+          <el-button link type="primary" @click="openSupportInspect(row)">
+            辅助检查
+          </el-button>
+          <el-button link type="primary" @click="openDisposalPlan(row)">
+            处置计划
+          </el-button>
+          <el-button link type="danger" @click="handleDelete(row)">
+            删除
+          </el-button>
+        </template>
+      </pure-table>
+    </div>
+
+    <AddEdit @update="getData" ref="addEditRef" />
+    <ProblemBase ref="problemBaseRef" />
+    <AddComplexDiseases @update="getData" ref="AddComplexDiseasesRef" />
+  </div>
+</template>
diff --git a/src/views/caseManagement/diseaseType/inquiry/index.vue b/src/views/caseManagement/diseaseType/inquiry/index.vue
new file mode 100644
index 0000000..064e657
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/inquiry/index.vue
@@ -0,0 +1,122 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+import {
+  queryListByDiseaseId,
+  diseaseQuestionDel,
+  questionBatchSave
+} from "@/api/disease";
+import { ElMessageBox } from "element-plus";
+import { message } from "@/utils/message";
+import ProblemBase from "../compontents/problemBase.vue";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "DiseaseTypeInquiry"
+});
+const columns: TableColumnList = [
+  {
+    label: "序号",
+    type: "index",
+    width: 80
+  },
+  {
+    label: "问题类目",
+    prop: "itemName"
+  },
+  {
+    label: "问题",
+    prop: "questionList",
+    formatter: ({ questionList }) => `${questionList[0]}`
+  },
+  {
+    label: "回复",
+    prop: "answer"
+  },
+  {
+    label: "操作",
+    width: 150,
+    slot: "operation"
+  }
+];
+const route = useRoute();
+const selectDataList = ref([]);
+const problemBaseRef = ref(null);
+const add = () => {
+  problemBaseRef.value.open();
+};
+onMounted(() => {
+  getData();
+});
+const getData = async () => {
+  const res: any = await queryListByDiseaseId({
+    diseaseId: route.query.id
+  });
+  selectDataList.value = res.data;
+};
+const handleDelete = item => {
+  ElMessageBox.confirm(item ? `是否删除` : "", "提示", {
+    type: "warning"
+  })
+    .then(async () => {
+      const res = await diseaseQuestionDel({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+const selectOk = async (data: any) => {
+  const arry = [];
+  data.forEach(e => {
+    arry.push({
+      diseaseId: route.query.id,
+      questionId: e.id
+    });
+  });
+  await questionBatchSave(arry);
+  getData();
+};
+</script>
+
+<template>
+  <div class="diseaseType-inquiry main-table">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>{{ `已选疾病补充问题【${selectDataList.length}】` }}</span>
+      </div>
+      <el-row class="mb-6">
+        <el-button size="large" class="btn" @click="add" type="primary"
+          >问题库</el-button
+        >
+      </el-row>
+    </div>
+
+    <pure-table
+      border
+      align-whole="center"
+      showOverflowTooltip
+      :data="selectDataList"
+      :columns="columns"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+    >
+      <template #operation="{ row }">
+        <el-button link type="danger" @click="handleDelete(row)">
+          删除
+        </el-button>
+      </template></pure-table
+    >
+    <ProblemBase @select="selectOk" ref="problemBaseRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.diseaseType-inquiry {
+  // height: calc(100vh - 85px);
+  .btn {
+    width: 150px;
+  }
+}
+</style>
diff --git a/src/views/caseManagement/diseaseType/supportInspect/addEdit.vue b/src/views/caseManagement/diseaseType/supportInspect/addEdit.vue
new file mode 100644
index 0000000..d75cc6f
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/supportInspect/addEdit.vue
@@ -0,0 +1,316 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import {
+  addSupportInspect,
+  queryAncillaryItemList,
+  updateSupportInspect
+} from "@/api/disease";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import WangEditor from "@/components/WangEditor/index.vue";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "AddEdit"
+});
+const props = {
+  value: "id",
+  label: "itemName",
+  children: "itemList",
+  disabled: "flag",
+  expandTrigger: "hover" as const
+};
+const refWangEditor = ref();
+const route = useRoute();
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+
+const formData = reactive({
+  itemIdPath: [],
+  diagnosticCriteria: [],
+  locationDiagnosisFlag: "",
+  result: "",
+  requireCheckFlag: "",
+  diagnosisAssessmentFlag: "",
+  expectedDiagnosisResult: null,
+  itemId: "",
+  normalResult: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const supportToolList = ref([]);
+const handleChange = item => {
+  formData.itemId = item[item.length - 1];
+};
+
+const rules = {
+  itemIdPath: [
+    { required: true, message: "请选择辅助检查项", trigger: "change" }
+  ],
+  diagnosisAssessmentFlag: [
+    { required: true, message: "请选择诊断判读", trigger: "change" }
+  ],
+  requireCheckFlag: [
+    { required: true, message: "请选择是否必查", trigger: "change" }
+  ],
+  expectedDiagnosisResult: [
+    { required: true, message: "请选择预期诊断结果", trigger: "change" }
+  ]
+};
+const getPhysicalToolList = async () => {
+  const res: any = await queryAncillaryItemList({
+    diseaseId: route.query.id
+  });
+  supportToolList.value = res.data;
+};
+defineExpose({
+  async open(item) {
+    getPhysicalToolList();
+    dialogVisible.value = true;
+    await nextTick();
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      isEditFlag.value = true;
+      id.value = item.id;
+
+      nextTick(() => {
+        setTimeout(() => {
+          refWangEditor.value.initText(item.result);
+        }, 200);
+      });
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  isEditFlag.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const reset = () => {
+  if (isEditFlag.value) {
+    ruleFormRef.value.resetFields([
+      "diagnosticCriteria",
+      "diagnosisAssessmentFlag",
+      "requireCheckFlag",
+      "expectedDiagnosisResult",
+      "normalResult"
+    ]);
+  } else {
+    ruleFormRef.value.resetFields();
+  }
+
+  // refWangEditor.value.valueHtml = "";
+};
+const changeResult = val => {
+  if (val === 0) {
+    formData.normalResult = "";
+  }
+};
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      // formData.result = refWangEditor.value.valueHtml;
+      const params = {
+        ...formData,
+        result: refWangEditor.value.valueHtml,
+        diseaseId: route.query.id
+      };
+      if (isEditFlag.value) {
+        const res: any = await updateSupportInspect({
+          ...params,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+          id.value = "";
+        }
+      } else {
+        const res: any = await addSupportInspect(params);
+        if (res.code === 200) {
+          message("新增成功", { type: "success" });
+        }
+      }
+      dialogVisible.value = false;
+      emit("update");
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>辅助检查</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="疾病名称:" prop="code">
+            <span>{{ route.query.diseaseName }}</span>
+          </el-form-item>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="辅助查项:" prop="itemIdPath">
+                <el-cascader
+                  :disabled="isEditFlag"
+                  style="width: 100%"
+                  size="large"
+                  v-model="formData.itemIdPath"
+                  :options="supportToolList"
+                  :props="props"
+                  @change="handleChange"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-form-item label="诊断依据:" prop="diagnosticCriteria">
+            <el-checkbox-group v-model="formData.diagnosticCriteria">
+              <el-checkbox :label="0">初步诊断依据</el-checkbox>
+              <el-checkbox :label="1">证实诊断依据</el-checkbox>
+              <el-checkbox :label="2">鉴别依据</el-checkbox>
+              <el-checkbox :label="3">全面依据</el-checkbox>
+            </el-checkbox-group>
+          </el-form-item>
+
+          <el-form-item label="诊断判读:" prop="diagnosisAssessmentFlag">
+            <el-radio-group v-model="formData.diagnosisAssessmentFlag">
+              <el-radio :label="0" size="large">不需要</el-radio>
+              <el-radio :label="1" size="large">需要</el-radio>
+            </el-radio-group>
+          </el-form-item>
+
+          <el-form-item label="是否必查:" prop="requireCheckFlag">
+            <el-radio-group v-model="formData.requireCheckFlag">
+              <el-radio :label="0" size="large">否</el-radio>
+              <el-radio :label="1" size="large">是</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="预期诊断结果:" prop="expectedDiagnosisResult">
+            <el-radio-group
+              @change="changeResult"
+              v-model="formData.expectedDiagnosisResult"
+            >
+              <el-radio :label="0" size="large">正常</el-radio>
+              <el-radio :label="1" size="large">异常</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item
+            v-if="formData.expectedDiagnosisResult === 1"
+            label="正常结果:"
+            prop="normalResult"
+          >
+            <el-input
+              size="large"
+              v-model="formData.normalResult"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <el-form-item label="诊断结果:" prop="result">
+            <WangEditor v-if="dialogVisible" ref="refWangEditor" />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="reset()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  :deep(.el-form-item__label) {
+    font-weight: 700;
+  }
+
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/diseaseType/supportInspect/index.vue b/src/views/caseManagement/diseaseType/supportInspect/index.vue
new file mode 100644
index 0000000..6d161d2
--- /dev/null
+++ b/src/views/caseManagement/diseaseType/supportInspect/index.vue
@@ -0,0 +1,123 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+import { querySupportLsit, deleteSupportItem } from "@/api/disease";
+import { ElMessageBox } from "element-plus";
+import { message } from "@/utils/message";
+import { useRoute } from "vue-router";
+import AddEdit from "./addEdit.vue";
+const route = useRoute();
+const selectSupportInspectList = ref([]);
+const columns: TableColumnList = [
+  {
+    label: "辅助检查项目",
+    prop: "itemName"
+  },
+
+  {
+    label: "诊断判读",
+    prop: "diagnosisAssessmentFlag",
+    formatter: ({ diagnosisAssessmentFlag }) => {
+      return diagnosisAssessmentFlag === 0 ? "不需要" : "需要";
+    }
+  },
+  {
+    label: "是否必查",
+    prop: "requireCheckFlag",
+    formatter: ({ requireCheckFlag }) => {
+      return requireCheckFlag === 0 ? "否" : "是";
+    }
+  },
+  {
+    label: "预期诊断结果",
+    prop: "expectedDiagnosisResult",
+    formatter: ({ expectedDiagnosisResult }) => {
+      return expectedDiagnosisResult === 0 ? "正常" : "异常";
+    }
+  },
+  {
+    label: "操作",
+    width: 150,
+    slot: "operation"
+  }
+];
+defineOptions({
+  name: "SupportInspect"
+});
+const AddEditRef = ref();
+onMounted(() => {
+  getsupportListByDiseaseId();
+});
+const getsupportListByDiseaseId = async () => {
+  const res: any = await querySupportLsit({
+    diseaseId: route.query.id
+  });
+  selectSupportInspectList.value = res.data;
+};
+
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = row => {
+  AddEditRef.value.open(row);
+};
+const del = item => {
+  ElMessageBox.confirm(item ? `是否删除` : "", "提示", {
+    type: "warning"
+  })
+    .then(async () => {
+      const res = await deleteSupportItem({ id: item.id });
+      if (res.code === 200) {
+        getsupportListByDiseaseId();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+</script>
+
+<template>
+  <div class="support-inspect main-table">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>
+          {{ `已选辅助检查项目【${selectSupportInspectList.length}个】` }}
+        </span>
+      </div>
+      <el-row class="mb-6">
+        <el-button size="large" class="btn" @click="add" type="primary"
+          >新建</el-button
+        >
+      </el-row>
+    </div>
+
+    <pure-table
+      adaptive
+      align-whole="center"
+      showOverflowTooltip
+      :data="selectSupportInspectList"
+      :columns="columns"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+    >
+      <template #operation="{ row }">
+        <el-button link type="primary" @click="edit(row)">编辑</el-button>
+        <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+      </template></pure-table
+    >
+    <AddEdit @update="getsupportListByDiseaseId" ref="AddEditRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.support-inspect {
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+
+  .footer {
+    flex: 1;
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/add.vue b/src/views/caseManagement/list/add.vue
new file mode 100644
index 0000000..b7e5c08
--- /dev/null
+++ b/src/views/caseManagement/list/add.vue
@@ -0,0 +1,247 @@
+<!-- <script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+// import { useRoute } from "vue-router";
+defineOptions({
+  name: "AddEdit"
+});
+const isEditFlag = ref(false);
+const diseaseList = ref([]);
+const id = ref("");
+const dialogVisible = ref(false);
+
+const formData = reactive({
+  patientGender: "",
+  directoryDesc: "",
+  patientSelfDesc: "",
+  patientAge: "",
+  diseaseId: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  patientGender: [{ required: true, message: "请选择", trigger: "change" }],
+  directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
+};
+defineExpose({
+  async open(item) {
+    dialogVisible.value = true;
+    await nextTick();
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  isEditFlag.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const reset = () => {
+  ruleFormRef.value.resetFields();
+};
+
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      // formData.result = refWangEditor.value.valueHtml;
+      // const params = {
+      //   ...formData,
+      //   result: refWangEditor.value.valueHtml,
+      //   diseaseId: route.query.id
+      // };
+      if (isEditFlag.value) {
+        // const res: any = await updateSupportInspect({
+        //   ...params,
+        //   id: id.value
+        // });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+          id.value = "";
+        }
+      } else {
+        // const res: any = await addSupportInspect(params);
+        // if (res.code === 200) {
+        //   message("新增成功", { type: "success" });
+        // }
+      }
+      dialogVisible.value = false;
+      emit("update");
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="650"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>新建病历</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="80px"
+        >
+          <el-form-item label="姓名" prop="directoryDesc">
+            <el-input
+              size="large"
+              placeholder="请输入"
+              v-model="formData.directoryDesc"
+            />
+          </el-form-item>
+          <el-form-item label="性别" prop="patientGender">
+            <el-radio-group size="large" v-model="formData.patientGender">
+              <el-radio label="男" />
+              <el-radio label="女" />
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="主诉" prop="patientSelfDesc">
+            <el-input size="large" v-model="formData.patientSelfDesc" />
+          </el-form-item>
+          <el-form-item label="年龄" prop="patientAge">
+            <el-input
+              size="large"
+              maxLength="3"
+              v-model="formData.patientAge"
+            />
+          </el-form-item>
+          <el-form-item label="初步诊断:" prop="diseaseId">
+            <el-select
+              size="large"
+              filterable
+              clearable
+              v-model="formData.diseaseId"
+              class="form_select"
+              style="width: 100%"
+              placeholder="请选择初步诊断"
+            >
+              <el-option
+                v-for="item in diseaseList"
+                :key="item.id"
+                :label="item.diseaseName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="reset()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  :deep(.el-form-item__label) {
+    font-weight: 400;
+    color: #333;
+  }
+
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 605px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style> -->
+<script setup lang="ts">
+import { onMounted } from "vue";
+import MainView from "./page/index.vue";
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+
+onMounted(() => {
+  useCaseStoreHooks().changeIsEditFlag(false);
+});
+</script>
+
+<template>
+  <div>
+    <MainView />
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/details/compontents/DisposalPlan.vue b/src/views/caseManagement/list/details/compontents/DisposalPlan.vue
new file mode 100644
index 0000000..f48e9f8
--- /dev/null
+++ b/src/views/caseManagement/list/details/compontents/DisposalPlan.vue
@@ -0,0 +1,46 @@
+<script setup lang="ts">
+defineOptions({
+  name: "DisposalPlan"
+});
+defineProps({
+  dataList: {
+    type: Array,
+    default: () => []
+  }
+});
+const columns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlan"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+  {
+    label: "二级措施",
+    prop: "secondMeasures"
+  },
+  {
+    label: "处置方式",
+    prop: "disposalMethod",
+    formatter: ({ disposalMethod }) => {
+      return disposalMethod === 0 ? "门诊收治" : "入院治疗";
+    }
+  }
+];
+</script>
+
+<template>
+  <div class="DisposalPlan">
+    <div class="title">{{ `处置计划【${dataList.length}】` }}</div>
+    <pure-table
+      border
+      style="width: 1000px"
+      align-whole="center"
+      showOverflowTooltip
+      :data="dataList"
+      :columns="columns"
+    />
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/details/compontents/askInquiry.vue b/src/views/caseManagement/list/details/compontents/askInquiry.vue
new file mode 100644
index 0000000..e7a64c0
--- /dev/null
+++ b/src/views/caseManagement/list/details/compontents/askInquiry.vue
@@ -0,0 +1,97 @@
+<script setup lang="ts">
+import InspectTable from "../../../list/page/compontents/inspectTable.vue";
+import { ref } from "vue";
+import type { TabsPaneContext } from "element-plus";
+defineOptions({
+  name: "AskInquiry"
+});
+defineProps({
+  bodyList: {
+    type: Array,
+    default: () => []
+  },
+  supportList: {
+    type: Array,
+    default: () => []
+  }
+});
+const activeName = ref("body");
+
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event);
+};
+
+const bodyColumns: TableColumnList = [
+  {
+    label: "检查项目",
+    prop: "toolName"
+  },
+  {
+    label: "检查部位",
+    prop: "locationName"
+  },
+  {
+    label: "初步诊断依据",
+    slot: "slot0"
+  },
+  {
+    label: "证实诊断依据",
+    slot: "slot1"
+  },
+  {
+    label: "鉴别依据",
+    slot: "slot2"
+  },
+  {
+    label: "全面依据",
+    slot: "slot3"
+  },
+  {
+    label: "是否必查",
+    prop: "requireCheckFlag",
+    slot: "requireCheckFlag"
+  }
+];
+const supportColumns: TableColumnList = [
+  {
+    label: "检查项目",
+    prop: "itemName",
+    width: 300
+  },
+  {
+    label: "初步诊断依据",
+    slot: "slot0"
+  },
+  {
+    label: "证实诊断依据",
+    slot: "slot1"
+  },
+  {
+    label: "鉴别依据",
+    slot: "slot2"
+  },
+  {
+    label: "全面依据",
+    slot: "slot3"
+  },
+  {
+    label: "是否必查",
+    prop: "requireCheckFlag",
+    minWidth: 150,
+    slot: "requireCheckFlag"
+  }
+];
+</script>
+
+<template>
+  <div class="AskInquiry">
+    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+      <el-tab-pane label="体格检查" name="body">
+        <InspectTable :columns="bodyColumns" :dataList="bodyList" />
+      </el-tab-pane>
+      <el-tab-pane label="辅助检查" name="support">
+        <InspectTable :columns="supportColumns" :dataList="supportList" />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/details/compontents/basicInfo.vue b/src/views/caseManagement/list/details/compontents/basicInfo.vue
new file mode 100644
index 0000000..3cf004d
--- /dev/null
+++ b/src/views/caseManagement/list/details/compontents/basicInfo.vue
@@ -0,0 +1,123 @@
+<script setup lang="ts">
+defineOptions({
+  name: "BasicInfo"
+});
+defineProps({
+  dataInfo: {
+    type: Object,
+    default: () => ({
+      patientName: "",
+      patientGender: "",
+      patientAge: "",
+      patientProfession: "",
+      patientSelfDesc: "",
+      patientMarriage: "",
+      diseaseId: "",
+      diseaseName: "",
+      patientHabitation: ""
+    })
+  },
+  diseaseName: {
+    type: String,
+    default: ""
+  }
+});
+</script>
+
+<template>
+  <div class="basicInfo-detail">
+    <el-form :model="dataInfo" label-width="100px">
+      <el-row>
+        <el-col :span="3">
+          <el-form-item label="姓名:" prop="patientName">
+            <span>{{ dataInfo.patientName }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="年龄:" prop="patientAge">
+            <span>{{ dataInfo.patientAge }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="婚姻状态:" prop="patientMarriage">
+            <span>{{ dataInfo.patientMarriage }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="邮编:" prop="patientPostcode">
+            <span>{{ dataInfo.patientPostcode }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="初步诊断:" prop="diseaseName">
+            <span>{{ diseaseName }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="3">
+          <el-form-item label="性别:" prop="patientGender">
+            <span>{{ dataInfo.patientGender }}</span>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="3">
+          <el-form-item label="职业:" prop="patientProfession">
+            <span>{{ dataInfo.patientProfession }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="主诉:" prop="patientSelfDesc">
+            <span :title="dataInfo.patientSelfDesc" class="longText">{{
+              dataInfo.patientSelfDesc
+            }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="现住址:" prop="patientHabitation">
+            <span>{{ dataInfo.patientHabitation }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="3">
+          <el-form-item label="电话:" prop="patientPhone">
+            <span>{{ dataInfo.patientPhone }}</span>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="3">
+          <el-form-item label="籍贯:" prop="nativePlace">
+            <span>{{ dataInfo.nativePlace }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="民族:" prop="patientNation">
+            <span>{{ dataInfo.patientNation }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="出生地:" prop="patientBirthplace">
+            <span>{{ dataInfo.patientBirthplace }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+<style lang="scss" scoped>
+.basicInfo-detail {
+  :deep(.el-form-item__label) {
+    font-size: 14px;
+    font-weight: 400;
+    color: #333;
+  }
+
+  .longText {
+    width: 200px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/details/index.vue b/src/views/caseManagement/list/details/index.vue
new file mode 100644
index 0000000..d01b5bc
--- /dev/null
+++ b/src/views/caseManagement/list/details/index.vue
@@ -0,0 +1,261 @@
+<script setup lang="ts">
+import { queryMedicalRecInfo } from "@/api/medicalRecord";
+import BasicInfo from "./compontents/basicInfo.vue";
+import AskInquiry from "./compontents/askInquiry.vue";
+import { ref } from "vue";
+import { reactive, onMounted } from "vue";
+import { useRoute } from "vue-router";
+
+const showFlag = ref(false);
+let detailInfo = reactive({
+  patient: {
+    patientSelfDesc: ""
+  },
+  physicalList: [],
+  ancillaryList: [],
+  qaList: [],
+  diseaseName: "",
+  treatmentPlanList: [],
+  patientSelfDesc: "",
+  primarilyDiagnosisCriteria: "",
+  confirmDiagnosisCriteria: "",
+  differentialDiagnosisCriteria: "",
+  fullCheck: ""
+});
+const columns: TableColumnList = [
+  {
+    label: "问题类目",
+    prop: "dictNamePath"
+  },
+
+  {
+    label: "问题",
+    prop: "questionList",
+    formatter: ({ questionList }) => `${questionList[0]}`
+  },
+  {
+    label: "回复",
+    prop: "medicalRecAnswer"
+  }
+];
+const planColumns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlan"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  }
+];
+const route = useRoute();
+const getDetail = async () => {
+  const res: any = await queryMedicalRecInfo({
+    id: route.query.id
+  });
+  detailInfo = res.data;
+  // detailInfo.patient.patientSelfDesc = detailInfo.patientSelfDesc;
+  showFlag.value = true;
+};
+onMounted(() => {
+  getDetail();
+});
+</script>
+
+<template>
+  <div v-if="showFlag" class="case_detail">
+    <div class="case_detail_card">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>基础信息</span>
+        </div>
+      </div>
+      <BasicInfo :dataInfo="detailInfo" :diseaseName="detailInfo.diseaseName" />
+    </div>
+    <div class="case_detail_card">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>临床诊断</span>
+        </div>
+      </div>
+      <AskInquiry
+        :bodyList="detailInfo?.physicalList"
+        :supportList="detailInfo?.ancillaryList"
+      />
+    </div>
+    <div class="case_detail_card">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>诊断依据</span>
+        </div>
+      </div>
+      <div class="text_item">
+        <div class="left">初步诊断依据</div>
+        <div class="right">{{ detailInfo.primarilyDiagnosisCriteria }}</div>
+      </div>
+      <div class="text_item">
+        <div class="left">证实诊断依据</div>
+        <div class="right">{{ detailInfo.confirmDiagnosisCriteria }}</div>
+      </div>
+      <div class="text_item">
+        <div class="left">鉴别依据</div>
+        <div class="right">{{ detailInfo.differentialDiagnosisCriteria }}</div>
+      </div>
+      <div class="text_item">
+        <div class="left">全面检查</div>
+        <div class="right">{{ detailInfo.fullCheck }}</div>
+      </div>
+    </div>
+    <div class="case_detail_card">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>应答策略</span>
+        </div>
+      </div>
+      <pure-table
+        style="width: 100%; height: 500px"
+        align-whole="center"
+        showOverflowTooltip
+        adaptive
+        :data="detailInfo.qaList"
+        :columns="columns"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+      />
+    </div>
+    <div class="case_detail_card">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>处置计划</span>
+        </div>
+      </div>
+      <pure-table
+        style="width: 100%; height: 500px"
+        align-whole="center"
+        showOverflowTooltip
+        adaptive
+        :data="detailInfo.treatmentPlanList"
+        :columns="planColumns"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+      />
+    </div>
+    <!-- <el-collapse v-if="showFlag" class="case_detail_main" v-model="activeName">
+      <el-collapse-item name="1">
+        <template #title>
+          <div class="title">
+            <span>病历信息</span>
+          </div>
+        </template>
+      
+      </el-collapse-item>
+      <el-collapse-item name="2">
+        <template #title>
+          <div class="title">
+            <span>问诊检查</span>
+          </div>
+        </template>
+        <AskInquiry
+          :bodyList="detailInfo?.physicalList"
+          :supportList="detailInfo?.ancillaryList"
+        />
+      </el-collapse-item>
+      <el-collapse-item name="3">
+        <template #title>
+          <div class="title">
+            <span>问诊问题</span>
+          </div>
+        </template>
+        <div class="question_list">
+          <div v-for="(item, index) in detailInfo.qaList" :key="index">
+            {{ item.questionList[0] }}
+          </div>
+        </div>
+      </el-collapse-item>
+      <el-collapse-item name="4">
+        <template #title>
+          <div class="title">
+            <span>处置计划</span>
+          </div>
+        </template>
+        <DisposalPlan :dataList="detailInfo.treatmentPlanList" />
+      </el-collapse-item>
+    </el-collapse> -->
+  </div>
+</template>
+<style lang="scss" scoped>
+.case_detail {
+  :deep(.el-collapse-item__header) {
+    width: 100%;
+    height: 40px;
+    background: rgb(0 127 245 / 9%);
+  }
+
+  :deep(.el-collapse-item) {
+    margin-bottom: 16px;
+  }
+
+  .title {
+    width: 100%;
+    // padding-left: 16px;
+  }
+
+  .case_detail_card {
+    padding: 24px;
+    margin-bottom: 16px;
+    background-color: #fff;
+
+    .main-table-title {
+      .title {
+        display: flex;
+        margin-bottom: 24px;
+
+        .line {
+          position: relative;
+          top: 5px;
+          width: 6px;
+          height: 20px;
+          margin-right: 12px;
+          background: #4287ff;
+        }
+
+        span {
+          font-size: 20px;
+        }
+      }
+    }
+
+    .text_item {
+      display: flex;
+      margin-bottom: 24px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #333;
+
+      .left {
+        width: 100px;
+        text-align: right;
+      }
+
+      .right {
+        flex: 1;
+        // line-height: 32px;
+        padding: 2px 12px;
+        margin-left: 16px;
+        // height: 32px;
+        background: #f8f8f8;
+        border-radius: 6px;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/edit.vue b/src/views/caseManagement/list/edit.vue
new file mode 100644
index 0000000..2347710
--- /dev/null
+++ b/src/views/caseManagement/list/edit.vue
@@ -0,0 +1,89 @@
+<script setup lang="ts">
+import { onMounted, reactive, ref } from "vue";
+import { queryMedicalRecInfo } from "@/api/medicalRecord";
+import MainView from "./page/index.vue";
+import { useRoute } from "vue-router";
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+
+let detailInfo = reactive({
+  patientName: "",
+  patientGender: "",
+  patientAge: "",
+  patientProfession: "",
+  patientSelfDesc: "",
+  patientMarriage: "",
+  diseaseId: "",
+  diseaseName: "",
+  patientHabitation: "",
+  physicalList: [],
+  ancillaryList: [],
+  qaList: [],
+  defaultQaList: [],
+  treatmentPlanList: [],
+  primarilyDiagnosisCriteria: "",
+  confirmDiagnosisCriteria: "",
+  differentialDiagnosisCriteria: "",
+  fullCheck: "",
+  patientId: "",
+  nativePlace: "",
+  patientNation: "",
+  patientPostcode: "",
+  patientBirthplace: "",
+  patientPhone: "",
+  digitalHumanType: "",
+  patientHeadPic: ""
+});
+const route = useRoute();
+const showFlag = ref(false);
+const getDetail = async () => {
+  const res: any = await queryMedicalRecInfo({
+    id: route.query.id
+  });
+  detailInfo = res.data;
+
+  useCaseStoreHooks().changeBasicInfo({
+    patientName: detailInfo.patientName,
+    patientGender: detailInfo.patientGender,
+    patientAge: detailInfo.patientAge,
+    patientProfession: detailInfo.patientProfession,
+    patientMarriage: detailInfo.patientMarriage,
+    patientHabitation: detailInfo.patientHabitation,
+    diseaseName: detailInfo.diseaseName,
+    patientSelfDesc: detailInfo.patientSelfDesc,
+    diseaseId: detailInfo.diseaseId,
+    nativePlace: detailInfo.nativePlace,
+    patientNation: detailInfo.patientNation,
+    patientPostcode: detailInfo.patientPostcode,
+    patientBirthplace: detailInfo.patientBirthplace,
+    patientPhone: detailInfo.patientPhone,
+    digitalHumanType: detailInfo.digitalHumanType,
+    patientHeadPic: detailInfo.patientHeadPic
+  });
+  const {
+    primarilyDiagnosisCriteria,
+    confirmDiagnosisCriteria,
+    differentialDiagnosisCriteria,
+    fullCheck
+  } = detailInfo;
+  useCaseStoreHooks().changeDiagnosticBasisInfo({
+    primarilyDiagnosisCriteria,
+    confirmDiagnosisCriteria,
+    differentialDiagnosisCriteria,
+    fullCheck
+  });
+  useCaseStoreHooks().changeQaList(detailInfo.qaList);
+  useCaseStoreHooks().changeDefaultQaList(detailInfo.defaultQaList);
+  useCaseStoreHooks().patientId = detailInfo.patientId;
+  showFlag.value = true;
+};
+onMounted(() => {
+  getDetail();
+  useCaseStoreHooks().changeIsEditFlag(true);
+});
+</script>
+
+<template>
+  <div>
+    <MainView v-if="showFlag" />
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/edit/compontents/ElectronicCase/AddCase.vue b/src/views/caseManagement/list/edit/compontents/ElectronicCase/AddCase.vue
new file mode 100644
index 0000000..4aea99b
--- /dev/null
+++ b/src/views/caseManagement/list/edit/compontents/ElectronicCase/AddCase.vue
@@ -0,0 +1,215 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+// import { useRoute } from "vue-router";
+defineOptions({
+  name: "AddCase"
+});
+const isEditFlag = ref(false);
+const diseaseList = ref([]);
+const id = ref("");
+const dialogVisible = ref(false);
+
+const formData = reactive({
+  patientGender: "",
+  directoryDesc: "",
+  patientSelfDesc: "",
+  patientAge: "",
+  diseaseId: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  patientGender: [{ required: true, message: "请选择", trigger: "change" }],
+  directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
+};
+defineExpose({
+  async open(item) {
+    dialogVisible.value = true;
+    await nextTick();
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  isEditFlag.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const reset = () => {
+  ruleFormRef.value.resetFields();
+};
+
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      // formData.result = refWangEditor.value.valueHtml;
+      // const params = {
+      //   ...formData,
+      //   result: refWangEditor.value.valueHtml,
+      //   diseaseId: route.query.id
+      // };
+      if (isEditFlag.value) {
+        // const res: any = await updateSupportInspect({
+        //   ...params,
+        //   id: id.value
+        // });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+          id.value = "";
+        }
+      } else {
+        // const res: any = await addSupportInspect(params);
+        // if (res.code === 200) {
+        //   message("新增成功", { type: "success" });
+        // }
+      }
+      dialogVisible.value = false;
+      emit("update");
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="650"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>添加电子病历项</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="80px"
+        >
+          <el-form-item label="选择类目" prop="directoryDesc">
+            <el-select
+              size="large"
+              filterable
+              clearable
+              v-model="formData.diseaseId"
+              class="form_select"
+              style="width: 100%"
+              placeholder="请选择选择类目"
+            >
+              <el-option
+                v-for="item in diseaseList"
+                :key="item.id"
+                :label="item.diseaseName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="名称" prop="patientGender">
+            <el-input size="large" v-model="formData.patientSelfDesc" />
+          </el-form-item>
+          <el-form-item label="内容" prop="patientSelfDesc">
+            <el-input size="large" v-model="formData.patientSelfDesc" />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="reset()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  :deep(.el-form-item__label) {
+    font-weight: 400;
+    color: #333;
+  }
+
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 605px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/edit/compontents/ElectronicCase/index.vue b/src/views/caseManagement/list/edit/compontents/ElectronicCase/index.vue
new file mode 100644
index 0000000..544383c
--- /dev/null
+++ b/src/views/caseManagement/list/edit/compontents/ElectronicCase/index.vue
@@ -0,0 +1,129 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import AddCase from "./AddCase.vue";
+
+const AddCaseRef = ref();
+const formData = reactive({
+  patientGender: "",
+  directoryDesc: "",
+  patientSelfDesc: "",
+  patientAge: "",
+  diseaseId: ""
+});
+const caseTypeList = ref([]);
+const rules = {
+  patientGender: [{ required: true, message: "请选择", trigger: "change" }],
+  directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
+};
+const add = () => {
+  AddCaseRef.value.open();
+};
+</script>
+<template>
+  <div class="ElectronicCase">
+    <div class="header">
+      <div class="header_left">
+        <span>电子病历</span>
+      </div>
+      <div class="header_right">
+        <el-button size="large" class="btn" @click="add" type="primary"
+          >添加病例项</el-button
+        >
+      </div>
+    </div>
+    <el-form
+      ref="ruleFormRef"
+      :model="formData"
+      :rules="rules"
+      label-width="80px"
+    >
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="类型" prop="patientGender">
+            <span>在线(默认)</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="虚拟人" prop="patientGender">
+            <el-button type="primary" link> 请选择数字人 </el-button>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="病历类型" prop="patientGender">
+            <el-select
+              size="large"
+              filterable
+              clearable
+              v-model="formData.diseaseId"
+              class="form_select"
+              style="width: 100%"
+              placeholder="请选择选择类目"
+            >
+              <el-option
+                v-for="item in caseTypeList"
+                :key="item.id"
+                :label="item.diseaseName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="姓名" prop="directoryDesc">
+            <el-input
+              size="large"
+              placeholder="请输入"
+              v-model="formData.directoryDesc"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="性别" prop="directoryDesc">
+            <el-input
+              size="large"
+              placeholder="请输入"
+              v-model="formData.directoryDesc"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+          <el-form-item label="年龄" prop="directoryDesc">
+            <el-input
+              size="large"
+              placeholder="请输入"
+              v-model="formData.directoryDesc"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <AddCase ref="AddCaseRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.ElectronicCase {
+  flex: 1;
+
+  .header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 88px;
+    padding: 0 40px;
+    margin-bottom: 24px;
+    border-bottom: 1px solid #d9d9d9;
+
+    .header_left {
+      font-size: 20px;
+      color: #333;
+
+      span {
+        padding-left: 8px;
+        border-left: 6px solid #4287ff;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/edit/index.vue b/src/views/caseManagement/list/edit/index.vue
new file mode 100644
index 0000000..bf44147
--- /dev/null
+++ b/src/views/caseManagement/list/edit/index.vue
@@ -0,0 +1,87 @@
+<script setup lang="ts">
+import ElectronicCase from "./compontents/ElectronicCase/index.vue";
+import { ref } from "vue";
+const activedIndex = ref(0);
+const navList = ref([
+  {
+    name: "电子病历"
+  },
+  {
+    name: "临床问诊"
+  },
+  {
+    name: "临床诊断"
+  },
+  {
+    name: "诊断依据"
+  },
+  {
+    name: "处置计划"
+  }
+]);
+</script>
+
+<template>
+  <div class="editCase main-table">
+    <div class="editCase_nav">
+      <div
+        class="editCase_nav_item"
+        :class="[activedIndex === index ? 'actived' : '']"
+        v-for="(item, index) in navList"
+        :key="index"
+      >
+        <div class="line" />
+        <span>{{ item.name }}</span>
+      </div>
+    </div>
+    <ElectronicCase v-if="activedIndex === 0" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.editCase {
+  display: flex;
+  flex-direction: row !important;
+  width: 100%;
+  padding: 0;
+
+  .editCase_nav {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 168px;
+    // justify-content: center;
+    height: 100%;
+    padding-top: 24px;
+    border-right: 1px solid #d9d9d9;
+
+    .editCase_nav_item {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 120px;
+      height: 53px;
+      font-size: 16px;
+      color: #999;
+      cursor: pointer;
+      border-radius: 8px;
+
+      .line {
+        width: 4px;
+        height: 17px;
+        margin-right: 12px;
+        background: #999;
+        border-radius: 2px;
+      }
+    }
+
+    .actived {
+      color: #4287ff;
+      background: linear-gradient(90deg, rgb(66 135 255 / 10%) 0%, #fff 100%);
+
+      .line {
+        background: #4287ff;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/index.vue b/src/views/caseManagement/list/index.vue
new file mode 100644
index 0000000..a4cecd8
--- /dev/null
+++ b/src/views/caseManagement/list/index.vue
@@ -0,0 +1,232 @@
+<script setup lang="ts">
+import router from "@/router";
+import { PaginationProps } from "@pureadmin/table";
+import { reactive, ref } from "vue";
+import {
+  queryDiseaseListByDropList,
+  queryMedicalRecPage
+} from "@/api/medicalRecord";
+import { onMounted } from "vue";
+import { clearObject } from "@/utils/auth";
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+
+defineOptions({
+  name: "CaseManagement"
+});
+
+const dataList = ref([]);
+const loading = ref(false);
+
+const seachForm = reactive({
+  gender: "",
+  diseaseId: "",
+  selfDescKeyword: ""
+});
+const diseaseList = ref([]);
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns: TableColumnList = [
+  {
+    label: "病历编号",
+    prop: "no",
+    minWidth: 150
+  },
+  {
+    label: "姓名",
+    prop: "name",
+    minWidth: 120
+  },
+  {
+    label: "年龄",
+    prop: "age",
+    minWidth: 150
+  },
+  {
+    label: "性别",
+    prop: "gender",
+    minWidth: 150
+  },
+  {
+    label: "初步诊断",
+    prop: "diagnosisPrimaryStr",
+    minWidth: 150
+  },
+  {
+    label: "机构",
+    prop: "alarmTask"
+  },
+  {
+    label: "更新时间",
+    prop: "time"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    width: 240,
+    slot: "operation"
+  }
+];
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  clearObject(seachForm);
+  search();
+};
+const add = () => {
+  router.push("/caseManagement/add");
+  useCaseStoreHooks().changeIsEditFlag(false);
+};
+const getDiseaseListByDropList = async () => {
+  const res: any = await queryDiseaseListByDropList();
+  diseaseList.value = res.data;
+};
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    ...seachForm
+  };
+  const res: any = await queryMedicalRecPage(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+const openDetail = item => {
+  router.push({
+    path: "/caseManagement/detail",
+    query: {
+      id: item.medicalId
+    }
+  });
+};
+const handleEdit = item => {
+  router.push({
+    path: "/caseManagement/edit",
+    query: {
+      id: item.medicalId
+    }
+  });
+};
+// const handleDelete = item => {
+//   ElMessageBox.confirm(
+//     item ? `确认删除后所有信息将被清空, 且无法恢复` : "",
+//     "提示",
+//     {
+//       type: "warning"
+//     }
+//   )
+//     .then(async () => {
+//       const res = await deleteMedicalRec({ id: item.medicalId });
+//       if (res.code === 200) {
+//         getData();
+//         message("删除成功", { type: "success" });
+//       }
+//     })
+//     .catch(() => {});
+// };
+onMounted(() => {
+  getDiseaseListByDropList();
+  getData();
+  useCaseStoreHooks().changeActivedStep(0);
+});
+</script>
+
+<template>
+  <div class="caseManagement app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <!-- <el-form-item label="主诉:">
+            <el-input size="large" v-model="seachForm.selfDescKeyword" />
+          </el-form-item>
+          <el-form-item label="性别:" class="ml-4" prop="gender">
+            <el-select
+              size="large"
+              clearable
+              v-model="seachForm.gender"
+              placeholder="请选择性别"
+            >
+              <el-option label="男" value="男" />
+              <el-option label="女" value="女" />
+            </el-select>
+          </el-form-item> -->
+          <el-form-item label="初步诊断:" class="ml-4" prop="diseaseId">
+            <el-select
+              size="large"
+              filterable
+              clearable
+              v-model="seachForm.diseaseId"
+              class="form_select"
+              placeholder="请选择初步诊断"
+            >
+              <el-option
+                v-for="item in diseaseList"
+                :key="item.id"
+                :label="item.diseaseName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>病历列表</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新增</el-button>
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="openDetail(row)">
+            详情
+          </el-button>
+          <el-button link type="primary" @click="handleEdit(row)">
+            编辑
+          </el-button>
+          <!-- <el-button link type="danger" @click="handleDelete(row)">
+            删除
+          </el-button> -->
+        </template>
+      </pure-table>
+    </div>
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/page/compontents/DisposalPlan.vue b/src/views/caseManagement/list/page/compontents/DisposalPlan.vue
new file mode 100644
index 0000000..65af479
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/DisposalPlan.vue
@@ -0,0 +1,134 @@
+<script setup lang="ts">
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import Header from "./header.vue";
+import { computed, onMounted, ref } from "vue";
+import {
+  queryDiseaseTreatmentPlanByCreat,
+  createMedicalRec,
+  modifyMedicalRec
+} from "@/api/medicalRecord";
+import { message } from "@/utils/message";
+import router from "@/router";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "DisposalPlan"
+});
+const route = useRoute();
+const dataList = ref([]);
+const columns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlan"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+
+  {
+    label: "处置方式",
+    prop: "disposalMethod",
+    formatter: ({ disposalMethod }) => {
+      return disposalMethod === 0 ? "门诊收治" : "入院治疗";
+    }
+  }
+];
+const isEditFlag = computed(() => {
+  return useCaseStoreHooks().isEditFlag;
+});
+const save = async () => {
+  const qaList = [];
+  const defaultQaList = [];
+  useCaseStoreHooks().qaList.forEach(e => {
+    qaList.push({
+      id: e.id,
+      answerResourceId: e.answerResourceId,
+      libraryQuestionId: e.libraryQuestionId,
+      questionList: e.questionList,
+      medicalRecAnswer: e.medicalRecAnswer
+    });
+  });
+  useCaseStoreHooks().defaultQaList.forEach(e => {
+    defaultQaList.push({
+      id: e.id,
+      answerResourceId: e.answerResourceId,
+      libraryQuestionId: e.libraryQuestionId,
+      medicalRecAnswer: e.medicalRecAnswer
+    });
+  });
+  const params = {
+    // patient: {
+    //   ...useCaseStoreHooks().basicInfo,
+    //   id: isEditFlag.value ? useCaseStoreHooks().patientId : undefined
+    // },
+    id: isEditFlag.value ? useCaseStoreHooks().patientId : undefined,
+    ...useCaseStoreHooks().basicInfo,
+    ...useCaseStoreHooks().diagnosticBasisInfo,
+    diseaseId: useCaseStoreHooks().basicInfo.diseaseId,
+    patientSelfDesc: useCaseStoreHooks().basicInfo.patientSelfDesc,
+    // symptoms: useCaseStoreHooks().basicInfo.symptoms,
+    qaList,
+    defaultQaList
+  };
+  if (isEditFlag.value) {
+    const res: any = await modifyMedicalRec({
+      ...params,
+      id: route.query.id,
+      patientId: useCaseStoreHooks().patientId
+    });
+    if (res.code === 200) {
+      message("编辑成功", { type: "success" });
+      router.push("/caseManagement/list");
+    }
+  } else {
+    const res: any = await createMedicalRec(params);
+    if (res.code === 200) {
+      message("创建成功", { type: "success" });
+      router.push("/caseManagement/list");
+    }
+  }
+};
+onMounted(() => {
+  getData();
+});
+const getData = async () => {
+  const res: any = await queryDiseaseTreatmentPlanByCreat({
+    diseaseId: useCaseStoreHooks().basicInfo.diseaseId
+  });
+  dataList.value = res.data;
+};
+const goBack = () => {
+  useCaseStoreHooks().changeActivedStep(3);
+};
+</script>
+
+<template>
+  <div class="DisposalPlan">
+    <Header />
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>{{ `处置计划【${dataList.length}】` }}</span>
+      </div>
+    </div>
+
+    <pure-table
+      style="width: 1000px; height: 500px"
+      align-whole="center"
+      showOverflowTooltip
+      adaptive
+      :data="dataList"
+      :columns="columns"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+    />
+    <div class="step-footer-btn">
+      <el-button size="large" @click="goBack">上一步</el-button>
+      <el-button size="large" @click="save" type="primary">{{
+        isEditFlag ? "修改病历" : "创建病历"
+      }}</el-button>
+    </div>
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/page/compontents/basicInfo.vue b/src/views/caseManagement/list/page/compontents/basicInfo.vue
new file mode 100644
index 0000000..69c1814
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/basicInfo.vue
@@ -0,0 +1,333 @@
+<script setup lang="ts">
+import { ref, computed, onMounted, reactive } from "vue";
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import router from "@/router";
+import { FormInstance } from "element-plus";
+import { queryDiseaseListByCreat } from "@/api/medicalRecord";
+import MaterialLibrary from "@/components/MaterialLibrary/index.vue";
+import { Plus } from "@element-plus/icons-vue";
+import { downLoadUrl } from "@/utils/auth";
+defineOptions({
+  name: "BasicInfo"
+});
+defineProps({
+  diseaseName: {
+    type: String,
+    default: ""
+  }
+});
+const marriageList = ref(["已婚", "未婚"]);
+const diseaseList = ref([]);
+const MaterialLibraryRef = ref();
+const dataInfo = reactive({
+  patientName: "",
+  patientGender: "",
+  patientAge: "",
+  patientProfession: "",
+  patientSelfDesc: "",
+  patientMarriage: "",
+  diseaseId: "",
+  diseaseName: "",
+  patientHabitation: "",
+  nativePlace: "",
+  patientNation: "",
+  patientPostcode: "",
+  patientBirthplace: "",
+  patientPhone: "",
+  digitalHumanType: "",
+  patientHeadPic: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  patientName: [{ required: true, message: "请输入姓名", trigger: "change" }],
+  patientGender: [{ required: true, message: "请选择性别", trigger: "change" }],
+  patientAge: [
+    { required: true, message: "请输入年龄", trigger: "change" },
+    {
+      pattern: /(^((1[0-5])|[1-9])?\d$)/,
+      message: "请输入正确格式",
+      trigger: "change"
+    }
+  ],
+  patientProfession: [
+    { required: true, message: "请输入职业", trigger: "change" }
+  ],
+  patientSelfDesc: [
+    { required: true, message: "请输入主诉", trigger: "change" }
+  ],
+  patientHabitation: [
+    { required: true, message: "请输入地址", trigger: "change" }
+  ],
+  nativePlace: [{ required: true, message: "请输入籍贯", trigger: "change" }],
+  patientNation: [{ required: true, message: "请输入民族", trigger: "change" }],
+  patientPostcode: [
+    { required: true, message: "请输入邮编", trigger: "change" },
+    {
+      pattern: /^\d{6}$/,
+      message: "请输入正确格式",
+      trigger: "blur"
+    }
+  ],
+  patientBirthplace: [
+    { required: true, message: "请输入出生地", trigger: "change" }
+  ],
+  patientPhone: [
+    { required: true, message: "请输入电话", trigger: "change" },
+    {
+      pattern: /^1[3456789]\d{9}$/,
+      message: "请输入正确格式",
+      trigger: "blur"
+    }
+  ],
+  patientMarriage: [{ required: true, message: "请选择", trigger: "change" }],
+  diseaseId: [{ required: true, message: "请选择", trigger: "change" }],
+  digitalHumanType: [{ required: true, message: "请选择", trigger: "change" }],
+  patientHeadPic: [{ required: true, message: "请选择", trigger: "change" }]
+};
+const isEditFlag = computed(() => {
+  return useCaseStoreHooks().isEditFlag;
+});
+const next = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      useCaseStoreHooks().changeActivedStep(1);
+      useCaseStoreHooks().changeBasicInfo(dataInfo);
+    } else {
+      return fields;
+    }
+  });
+};
+const goBack = () => {
+  router.go(-1);
+};
+onMounted(() => {
+  if (isEditFlag.value) {
+    // dataInfo = useCaseStoreHooks().basicInfo;
+    for (const key in useCaseStoreHooks().basicInfo) {
+      // eslint-disable-next-line no-prototype-builtins
+      if (dataInfo.hasOwnProperty(key)) {
+        dataInfo[key] = useCaseStoreHooks().basicInfo[key];
+      }
+    }
+  }
+  getDiseaseList();
+});
+const getDiseaseList = async () => {
+  const res: any = await queryDiseaseListByCreat();
+  diseaseList.value = res.data;
+};
+// 选择疾病
+const selectDisease = val => {
+  const selectedOption = diseaseList.value.find(option => option.id === val);
+  dataInfo.diseaseName = selectedOption.diseaseName;
+};
+//选择头像
+const uploadImg = () => {
+  MaterialLibraryRef.value.open(0);
+};
+const getImg = id => {
+  dataInfo.patientHeadPic = id;
+};
+</script>
+
+<template>
+  <div class="BasicInfo">
+    <el-form
+      :model="dataInfo"
+      ref="ruleFormRef"
+      style="display: flex; justify-content: center; width: 100%"
+      :rules="rules"
+      label-width="280px"
+    >
+      <div class="content">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item
+              label="虚拟人:"
+              style="font-weight: 700"
+              prop="patientHeadPic"
+            >
+              <div v-if="dataInfo.patientHeadPic" class="uoloadImg">
+                <img :src="downLoadUrl(dataInfo.patientHeadPic)" alt="" />
+              </div>
+              <div @click="uploadImg" class="uoloadImg">
+                <el-icon><Plus /></el-icon>
+                <span>点击选择虚拟人</span>
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="类型:" prop="digitalHumanType">
+              <el-radio-group v-model="dataInfo.digitalHumanType">
+                <el-radio :label="0">离线</el-radio>
+                <el-radio :label="1">在线</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="电话:" prop="patientPhone">
+              <el-input size="large" v-model="dataInfo.patientPhone" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="姓名:" prop="patientName">
+              <el-input
+                size="large"
+                maxLength="5"
+                v-model="dataInfo.patientName"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="性别:" prop="patientGender">
+              <el-radio-group v-model="dataInfo.patientGender">
+                <el-radio label="男" />
+                <el-radio label="女" />
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="年龄:" prop="patientAge">
+              <el-input
+                size="large"
+                maxLength="3"
+                v-model="dataInfo.patientAge"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="职业:" prop="patientProfession">
+              <el-input size="large" v-model="dataInfo.patientProfession" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="籍贯:" prop="nativePlace">
+              <el-input size="large" v-model="dataInfo.nativePlace" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="民族:" prop="patientNation">
+              <el-input size="large" v-model="dataInfo.patientNation" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="主诉:" prop="patientSelfDesc">
+              <el-input size="large" v-model="dataInfo.patientSelfDesc" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="婚姻状态:" prop="patientMarriage">
+              <el-select
+                size="large"
+                style="width: 100%"
+                filterable
+                v-model="dataInfo.patientMarriage"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in marriageList"
+                  :key="item"
+                  :label="item"
+                  :value="item"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="邮编:" prop="patientPostcode">
+              <el-input size="large" v-model="dataInfo.patientPostcode" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="初步诊断:" prop="diseaseId">
+              <el-select
+                style="width: 100%"
+                size="large"
+                filterable
+                v-model="dataInfo.diseaseId"
+                @change="selectDisease"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in diseaseList"
+                  :key="item.id"
+                  :label="item.diseaseName"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="出生地:" prop="patientBirthplace">
+              <el-input size="large" v-model="dataInfo.patientBirthplace" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="现住地:" prop="patientHabitation">
+              <el-input size="large" v-model="dataInfo.patientHabitation" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </div>
+    </el-form>
+    <div class="step-footer-btn">
+      <el-button size="large" @click="goBack">返回</el-button>
+      <el-button size="large" @click="next(ruleFormRef)" type="primary"
+        >下一步</el-button
+      >
+    </div>
+    <MaterialLibrary @select="getImg" ref="MaterialLibraryRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.BasicInfo {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+
+  .content {
+    width: 80%;
+  }
+
+  .uoloadImg {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 120px;
+    height: 120px;
+    margin-right: 8px;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+
+    img {
+      width: 118px;
+      height: 118px;
+    }
+
+    span {
+      font-size: 12px;
+      font-weight: 400;
+      color: #666;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/page/compontents/collarbedDiagnosis.vue b/src/views/caseManagement/list/page/compontents/collarbedDiagnosis.vue
new file mode 100644
index 0000000..9f55570
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/collarbedDiagnosis.vue
@@ -0,0 +1,122 @@
+<script setup lang="ts">
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import InspectTable from "./inspectTable.vue";
+import { ref } from "vue";
+import type { TabsPaneContext } from "element-plus";
+import {
+  queryDiseasePhysicalByCreat,
+  queryDiseaseAncillaryByCreat
+} from "@/api/medicalRecord";
+import Header from "./header.vue";
+import { onMounted } from "vue";
+defineOptions({
+  name: "CollarbedDiagnosis"
+});
+const activeName = ref("body");
+
+const bodyList = ref([]);
+const supportList = ref([]);
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event);
+};
+const next = () => {
+  useCaseStoreHooks().changeActivedStep(2);
+};
+const goBack = () => {
+  useCaseStoreHooks().changeActivedStep(0);
+};
+const getBodyList = async () => {
+  const res: any = await queryDiseasePhysicalByCreat({
+    diseaseId: useCaseStoreHooks().basicInfo.diseaseId
+  });
+  bodyList.value = res.data;
+};
+const getSupportList = async () => {
+  const res: any = await queryDiseaseAncillaryByCreat({
+    diseaseId: useCaseStoreHooks().basicInfo.diseaseId
+  });
+  supportList.value = res.data;
+};
+const bodyColumns: TableColumnList = [
+  {
+    label: "检查项目",
+    prop: "toolName"
+  },
+  {
+    label: "检查部位",
+    prop: "locationName"
+  },
+  {
+    label: "初步诊断依据",
+    slot: "slot0"
+  },
+  {
+    label: "证实诊断依据",
+    slot: "slot1"
+  },
+  {
+    label: "鉴别依据",
+    slot: "slot2"
+  },
+  {
+    label: "全面依据",
+    slot: "slot3"
+  },
+  {
+    label: "是否必查",
+    prop: "requireCheckFlag",
+    slot: "requireCheckFlag"
+  }
+];
+const supportColumns: TableColumnList = [
+  {
+    label: "检查项目",
+    prop: "itemName",
+    width: 300
+  },
+  {
+    label: "初步诊断依据",
+    slot: "slot0"
+  },
+  {
+    label: "证实诊断依据",
+    slot: "slot1"
+  },
+  {
+    label: "鉴别依据",
+    slot: "slot2"
+  },
+  {
+    label: "全面依据",
+    slot: "slot3"
+  },
+  {
+    label: "是否必查",
+    prop: "requireCheckFlag",
+    minWidth: 150,
+    slot: "requireCheckFlag"
+  }
+];
+onMounted(() => {
+  getBodyList();
+  getSupportList();
+});
+</script>
+
+<template>
+  <div class="CollarbedDiagnosis" style="padding-bottom: 16px">
+    <Header />
+    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+      <el-tab-pane label="体格检查" name="body">
+        <InspectTable :columns="bodyColumns" :dataList="bodyList" />
+      </el-tab-pane>
+      <el-tab-pane label="辅助检查" name="support">
+        <InspectTable :columns="supportColumns" :dataList="supportList" />
+      </el-tab-pane>
+    </el-tabs>
+    <div class="step-footer-btn" style="position: relative; top: -12px">
+      <el-button size="large" @click="goBack">上一步</el-button>
+      <el-button size="large" @click="next" type="primary">下一步</el-button>
+    </div>
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/page/compontents/diagnosticBasis.vue b/src/views/caseManagement/list/page/compontents/diagnosticBasis.vue
new file mode 100644
index 0000000..e5ca8d7
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/diagnosticBasis.vue
@@ -0,0 +1,96 @@
+<script setup lang="ts">
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import Header from "./header.vue";
+import { computed, reactive } from "vue";
+import { onMounted } from "vue";
+defineOptions({
+  name: "DiagnosticBasis"
+});
+const diagnosticBasisInfo = reactive({
+  primarilyDiagnosisCriteria: "",
+  confirmDiagnosisCriteria: "",
+  differentialDiagnosisCriteria: "",
+  fullCheck: ""
+});
+const isEditFlag = computed(() => {
+  return useCaseStoreHooks().isEditFlag;
+});
+const next = () => {
+  useCaseStoreHooks().changeDiagnosticBasisInfo(diagnosticBasisInfo);
+  useCaseStoreHooks().changeActivedStep(3);
+};
+const goBack = () => {
+  useCaseStoreHooks().changeActivedStep(1);
+};
+onMounted(() => {
+  if (isEditFlag.value) {
+    // dataInfo = useCaseStoreHooks().basicInfo;
+    for (const key in useCaseStoreHooks().diagnosticBasisInfo) {
+      // eslint-disable-next-line no-prototype-builtins
+      if (diagnosticBasisInfo.hasOwnProperty(key)) {
+        diagnosticBasisInfo[key] = useCaseStoreHooks().diagnosticBasisInfo[key];
+      }
+    }
+  }
+});
+</script>
+
+<template>
+  <div class="diagnosticBasis">
+    <Header />
+    <el-form class="mt-4" :model="diagnosticBasisInfo" label-width="180px">
+      <el-row>
+        <el-form-item label="初步诊断依据:" prop="primarilyDiagnosisCriteria">
+          <el-input
+            style="width: 500px"
+            :rows="4"
+            type="textarea"
+            :maxLength="500"
+            placeholder="请输入初步诊断依据"
+            v-model="diagnosticBasisInfo.primarilyDiagnosisCriteria"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="证实诊断依据:" prop="confirmDiagnosisCriteria">
+          <el-input
+            :rows="4"
+            style="width: 500px"
+            type="textarea"
+            :maxLength="500"
+            placeholder="请输入证实诊断依据"
+            v-model="diagnosticBasisInfo.confirmDiagnosisCriteria"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="鉴别依据:" prop="differentialDiagnosisCriteria">
+          <el-input
+            :rows="4"
+            style="width: 500px"
+            type="textarea"
+            :maxLength="500"
+            placeholder="请输入鉴别依据"
+            v-model="diagnosticBasisInfo.differentialDiagnosisCriteria"
+          />
+        </el-form-item>
+      </el-row>
+      <el-row>
+        <el-form-item label="全面检查:" prop="fullCheck">
+          <el-input
+            :rows="4"
+            style="width: 500px"
+            type="textarea"
+            :maxLength="500"
+            placeholder="请输入全面检查"
+            v-model="diagnosticBasisInfo.fullCheck"
+          />
+        </el-form-item>
+      </el-row>
+    </el-form>
+    <div class="step-footer-btn">
+      <el-button size="large" @click="goBack">上一步</el-button>
+      <el-button size="large" @click="next" type="primary">下一步</el-button>
+    </div>
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/page/compontents/header.vue b/src/views/caseManagement/list/page/compontents/header.vue
new file mode 100644
index 0000000..f206f73
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/header.vue
@@ -0,0 +1,55 @@
+<script setup lang="ts">
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import { computed } from "vue";
+
+const basicInfo = computed(() => {
+  return useCaseStoreHooks().basicInfo;
+});
+</script>
+
+<template>
+  <div class="Header">
+    <label>姓名:</label>
+    <span>{{ basicInfo.patientName }}</span>
+    <label>性别:</label>
+    <span>{{ basicInfo.patientGender }}</span>
+    <label>年龄:</label>
+    <span>{{ basicInfo.patientAge }}</span>
+    <label>初步诊断:</label>
+    <span :title="basicInfo.diseaseName" class="text" style="width: 150px">{{
+      basicInfo.diseaseName
+    }}</span>
+    <label>主诉:</label>
+    <span :title="basicInfo.patientSelfDesc" class="text">{{
+      basicInfo.patientSelfDesc
+    }}</span>
+  </div>
+</template>
+<style lang="scss" scoped>
+.Header {
+  display: flex;
+  width: 1500px;
+  height: 53px;
+  margin: 0 auto;
+  margin-bottom: 24px;
+  font-size: 16px;
+  font-weight: 400;
+  line-height: 53px;
+  color: #4287ff;
+  background: rgb(66 135 255 / 6%);
+  border-radius: 6px;
+
+  label {
+    margin-right: 12px;
+    margin-left: 110px;
+    font-weight: 400;
+  }
+
+  .text {
+    width: 400px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/page/compontents/inspectTable.vue b/src/views/caseManagement/list/page/compontents/inspectTable.vue
new file mode 100644
index 0000000..61d7a74
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/inspectTable.vue
@@ -0,0 +1,66 @@
+<script setup lang="ts">
+defineOptions({
+  name: "InspectTable"
+});
+defineProps({
+  dataList: {
+    type: Array,
+    default: () => []
+  },
+  columns: {
+    type: Array,
+    default: () => []
+  }
+});
+</script>
+
+<template>
+  <div>
+    <pure-table
+      align-whole="center"
+      showOverflowTooltip
+      adaptive
+      :data="dataList"
+      :columns="columns"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+      ><template #requireCheckFlag="{ row }">
+        <el-checkbox
+          disabled
+          :checked="row.requireCheckFlag === 1 ? true : false"
+          size="large"
+        />
+      </template>
+      <template #slot0="{ row }">
+        <el-checkbox
+          disabled
+          :checked="row.diagnosticCriteria.includes(0) === true ? true : false"
+          size="large"
+        />
+      </template>
+      <template #slot1="{ row }">
+        <el-checkbox
+          disabled
+          :checked="row.diagnosticCriteria.includes(1) === true ? true : false"
+          size="large"
+        />
+      </template>
+      <template #slot2="{ row }">
+        <el-checkbox
+          disabled
+          :checked="row.diagnosticCriteria.includes(2) === true ? true : false"
+          size="large"
+        />
+      </template>
+      <template #slot3="{ row }">
+        <el-checkbox
+          disabled
+          :checked="row.diagnosticCriteria.includes(3) === true ? true : false"
+          size="large"
+        />
+      </template>
+    </pure-table>
+  </div>
+</template>
diff --git a/src/views/caseManagement/list/page/compontents/responseStrategy.vue b/src/views/caseManagement/list/page/compontents/responseStrategy.vue
new file mode 100644
index 0000000..29bc68e
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/responseStrategy.vue
@@ -0,0 +1,494 @@
+<script setup lang="ts">
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import { queryQuestionListByCreat } from "@/api/medicalRecord";
+import Header from "./header.vue";
+import { ref } from "vue";
+import { reactive } from "vue";
+import { onMounted } from "vue";
+import { computed } from "vue";
+import { FormInstance } from "element-plus";
+import ProblemBase from "../../../diseaseType/compontents/problemBase.vue";
+import UploadFile from "./uploadFile.vue";
+import videoImg from "@/assets/newInquiry/video_icon.png";
+import { queryMedicalDefaultAnswer } from "@/api/generalRules";
+import MaterialLibrary from "@/components/MaterialLibrary/index.vue";
+import PlayVideo from "@/components/PlayVideo/index.vue";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "ResponseStrategy"
+});
+const next = () => {
+  useCaseStoreHooks().changeQaList(dataList);
+  useCaseStoreHooks().changeDefaultQaList(defaultQaList);
+  useCaseStoreHooks().changeActivedStep(4);
+};
+const activeName = ref("1");
+const goBack = () => {
+  useCaseStoreHooks().changeActivedStep(2);
+};
+const MaterialLibraryRef = ref();
+const dataList = ref([]);
+const defaultQaList = ref([]);
+const answerVisible = ref(false);
+const PlayVideoRef = ref();
+const selectIndex = ref<number>(0);
+const selectColumns: TableColumnList = [
+  {
+    label: "序号",
+    type: "index",
+    width: 80
+  },
+
+  {
+    label: "问题类目",
+    prop: "dictNamePath"
+  },
+  {
+    label: "问题",
+    prop: "questionList",
+    formatter: ({ questionList }) =>
+      questionList?.length > 0 ? `${questionList[0]}` : ""
+  },
+  {
+    label: "回复",
+    prop: "medicalRecAnswer"
+  },
+  {
+    label: "视频",
+    slot: "video"
+  },
+  {
+    label: "操作",
+    width: 200,
+    slot: "operation"
+  }
+];
+const ruleFormRef = ref<FormInstance>();
+const problemBaseRef = ref(null);
+const UploadFileRef = ref();
+const rules = {
+  answer: [{ required: true, message: "请输入回答", trigger: "change" }]
+};
+const answerForm = reactive({
+  answer: ""
+});
+
+const selectQuestion = () => {
+  problemBaseRef.value.open();
+};
+// 回答
+const answer = (item, index) => {
+  answerVisible.value = true;
+  selectIndex.value = index;
+  answerForm.answer = item.defaultAnswer;
+};
+const getData = async () => {
+  const res: any = await queryQuestionListByCreat({
+    diseaseId: useCaseStoreHooks().basicInfo.diseaseId
+  });
+  dataList.value = res.data;
+};
+const basicInfo = computed(() => {
+  return useCaseStoreHooks().basicInfo;
+});
+const isEditFlag = computed(() => {
+  return useCaseStoreHooks().isEditFlag;
+});
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      answerVisible.value = false;
+      if (activeName.value === "1") {
+        dataList.value[selectIndex.value].medicalRecAnswer = answerForm.answer;
+      } else {
+        defaultQaList.value[selectIndex.value].medicalRecAnswer =
+          answerForm.answer;
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const selectOk = async (data: any) => {
+  let flag = true;
+  data.forEach(e => {
+    for (const item of dataList.value) {
+      if (item.libraryQuestionId === e.libraryQuestionId) {
+        message("不能选择重复数据", { type: "error" });
+        flag = false;
+        return;
+      }
+    }
+    if (flag) {
+      dataList.value.push({
+        defaultAnswer: e.defaultAnswer,
+        dictNamePath: e.nameZhPath,
+        medicalRecAnswer: e.defaultAnswer,
+        libraryQuestionId: e.libraryQuestionId,
+        questionList: e.question,
+        answerResourceId: e.answerResourceId
+      });
+    }
+  });
+};
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+onMounted(() => {
+  if (isEditFlag.value) {
+    dataList.value = useCaseStoreHooks().qaList;
+    defaultQaList.value = useCaseStoreHooks().defaultQaList;
+  } else {
+    getData();
+    getMedicalDefaultAnswer();
+  }
+});
+const del = index => {
+  dataList.value.splice(index, 1);
+};
+const upload = () => {
+  UploadFileRef.value.open();
+};
+const getMedicalDefaultAnswer = async () => {
+  const res: any = await queryMedicalDefaultAnswer();
+  defaultQaList.value = res.data;
+};
+const getFileList = async (data: any) => {
+  if (data.length > 0) {
+    dataList.value = [];
+    data.forEach(e => {
+      dataList.value.push({
+        libraryQuestionId: e.libraryQuestionId,
+        defaultAnswer: e.defaultAnswer,
+        dictNamePath: e.dictNamePath,
+        medicalRecAnswer: e.medicalRecAnswer,
+        questionList: e.questionList,
+        answerResourceId: e.answerResourceId,
+        answerResourceName: e.answerResourceName
+      });
+    });
+  }
+};
+// 选择视频
+const selectVideo = index => {
+  selectIndex.value = index;
+  MaterialLibraryRef.value.open(1);
+};
+const changeTab = val => {
+  activeName.value = val;
+};
+const getVideo = (id, name) => {
+  if (activeName.value === "1") {
+    dataList.value[selectIndex.value].answerResourceId = id;
+    dataList.value[selectIndex.value].answerResourceName = name;
+  } else {
+    defaultQaList.value[selectIndex.value].answerResourceId = id;
+    defaultQaList.value[selectIndex.value].answerResourceName = name;
+  }
+};
+const openVideo = id => {
+  PlayVideoRef.value.open(id, 1);
+};
+</script>
+
+<template>
+  <div class="responseStrategy">
+    <Header />
+
+    <!-- <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>{{ `病历问诊问题【${dataList.length}】` }}</span>
+      </div>
+      <el-row class="mb-6">
+        <el-button
+          size="large"
+          class="btn"
+          @click="selectQuestion"
+          type="primary"
+          >选择问题</el-button
+        >
+      </el-row>
+    </div> -->
+    <el-tabs
+      style="width: 80%"
+      v-model="activeName"
+      class="demo-tabs"
+      @tab-change="changeTab"
+    >
+      <el-tab-pane label="疾病问题" name="1">
+        <pure-table
+          align-whole="center"
+          adaptive
+          style="height: calc(100vh - 400px)"
+          showOverflowTooltip
+          :data="dataList"
+          :columns="selectColumns"
+          :header-cell-style="{
+            background: 'var(--el-table-row-hover-bg-color)',
+            color: 'var(--el-text-color-primary)'
+          }"
+        >
+          <template #video="{ row }">
+            <div
+              @click="openVideo(row.answerResourceId)"
+              v-if="row.answerResourceName"
+              class="video_item"
+            >
+              <img :src="videoImg" alt="" />
+              <span>{{ row.answerResourceName }}</span>
+            </div>
+            <div v-if="!row.answerResourceName" style="color: #b4b4b4">
+              未上传
+            </div>
+          </template>
+          <template #operation="{ row, index }">
+            <el-button link type="primary" @click="answer(row, index)">
+              回答
+            </el-button>
+            <el-button link type="primary" @click="selectVideo(index)">
+              视频
+            </el-button>
+            <el-button link type="danger" @click="del(index)"> 删除 </el-button>
+          </template></pure-table
+        >
+      </el-tab-pane>
+      <el-tab-pane label="默认问题" name="2">
+        <pure-table
+          align-whole="center"
+          showOverflowTooltip
+          :data="defaultQaList"
+          :columns="selectColumns"
+          :header-cell-style="{
+            background: 'var(--el-table-row-hover-bg-color)',
+            color: 'var(--el-text-color-primary)'
+          }"
+        >
+          <template #video="{ row }">
+            <div
+              @click="openVideo(row.answerResourceId)"
+              v-if="row.answerResourceId"
+              class="video_item"
+            >
+              <img :src="videoImg" alt="" />
+              <span>{{ row.answerResourceName }}</span>
+            </div>
+            <div v-if="!row.answerResourceName" style="color: #b4b4b4">
+              未上传
+            </div>
+          </template>
+          <template #operation="{ row, index }">
+            <el-button link type="primary" @click="answer(row, index)">
+              回答
+            </el-button>
+            <el-button link type="primary" @click="selectVideo(index)">
+              视频
+            </el-button>
+          </template></pure-table
+        >
+      </el-tab-pane>
+    </el-tabs>
+    <div class="btn_list" v-if="activeName === '1'">
+      <el-button size="large" class="btn" @click="selectQuestion" type="primary"
+        >选择问题</el-button
+      >
+      <el-button size="large" class="btn" @click="upload" type="primary"
+        >上传数据</el-button
+      >
+    </div>
+    <div class="step-footer-btn mb-4">
+      <el-button size="large" @click="goBack">上一步</el-button>
+      <el-button size="large" @click="next" type="primary">下一步</el-button>
+    </div>
+    <!-- 回答问题 -->
+    <el-drawer
+      :size="800"
+      title="回答问题"
+      append-to-body
+      v-model="answerVisible"
+      :show-close="false"
+      :with-header="false"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>回答问题</span>
+        </div>
+        <div class="line" />
+        <div class="seach">
+          <el-form
+            :rules="rules"
+            ref="ruleFormRef"
+            :model="answerForm"
+            label-width="120px"
+          >
+            <el-row class="mt-4">
+              <el-col :span="8">
+                <el-form-item label="姓名:">
+                  <span>{{ basicInfo.patientName }}</span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="性别:">
+                  <span>{{ basicInfo.patientGender }}</span>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="年龄:">
+                  <span>{{ basicInfo.patientAge }}</span>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row class="mt-4">
+              <!-- <el-col :span="12">
+                <el-form-item label="疾病分类:">
+                  <span>{{ basicInfo.name }}</span>
+                </el-form-item>
+              </el-col> -->
+              <el-col :span="12">
+                <el-form-item label="疾病名称:">
+                  <span>{{ basicInfo.diseaseName }}</span>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row class="mt-4">
+              <el-col :span="12">
+                <el-form-item label="问题:">
+                  <span>{{
+                    activeName === "1"
+                      ? dataList[selectIndex].questionList[0]
+                      : defaultQaList[selectIndex].questionList[0]
+                  }}</span>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row class="mt-4">
+              <el-form-item
+                style="font-weight: 400"
+                label="回答:"
+                prop="answer"
+              >
+                <el-input
+                  :rows="4"
+                  style="width: 500px"
+                  type="textarea"
+                  :maxLength="500"
+                  placeholder="请输入回答"
+                  v-model="answerForm.answer"
+                />
+              </el-form-item>
+            </el-row>
+          </el-form>
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+    <ProblemBase @select="selectOk" ref="problemBaseRef" />
+    <UploadFile @update="getFileList" ref="UploadFileRef" />
+    <MaterialLibrary @select="getVideo" ref="MaterialLibraryRef" />
+    <PlayVideo ref="PlayVideoRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.responseStrategy {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+
+  :deep(.el-form-item__label) {
+    font-weight: 700;
+  }
+
+  :deep(.el-tabs__item) {
+    height: 60px;
+    font-size: 18px;
+  }
+
+  .btn_list {
+    position: absolute;
+    top: 183px;
+    right: 12%;
+  }
+
+  .video_item {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    img {
+      width: 16px;
+      height: 16px;
+      margin-right: 6px;
+    }
+  }
+
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/page/compontents/uploadFile.vue b/src/views/caseManagement/list/page/compontents/uploadFile.vue
new file mode 100644
index 0000000..71c605a
--- /dev/null
+++ b/src/views/caseManagement/list/page/compontents/uploadFile.vue
@@ -0,0 +1,362 @@
+<script setup lang="ts">
+import { nextTick, ref } from "vue";
+import { ElMessage, UploadProps } from "element-plus";
+import UploadImg from "@/assets/newInquiry/upload.png";
+import fileImg from "@/assets/newInquiry/file.png";
+import { getToken, downLoadUrl } from "@/utils/auth";
+import downloadIcon from "@/assets/svg/consultation/download.svg?component";
+import warnIcon from "@/assets/svg/consultation/warn.svg?component";
+import successIcon from "@/assets/newInquiry/success.png";
+import { message } from "@/utils/message";
+import { reactive } from "vue";
+defineOptions({
+  name: "UploadFile"
+});
+
+const dialogVisible = ref(false);
+const fileList = ref([]);
+const fileInfo = reactive({
+  failCount: 0,
+  fileId: "",
+  totalCount: 0,
+  fileName: ""
+});
+defineExpose({
+  async open() {
+    dialogVisible.value = true;
+    await nextTick;
+  }
+});
+
+const resetForm = () => {
+  fileInfo.fileId = "";
+  fileInfo.fileName = "";
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+  emit("update");
+};
+const emit = defineEmits(["update"]);
+const handleSuccess: UploadProps["onSuccess"] = response => {
+  if (response.code === 200) {
+    fileInfo.failCount = response.data.failCount;
+    fileInfo.fileId = response.data.fileId;
+    fileInfo.totalCount = response.data.totalCount;
+    fileList.value = response.data.qaList;
+  } else {
+    message(response.data, { type: "error" });
+  }
+};
+const downloadFile = (url, fileName) => {
+  const link = document.createElement("a");
+  link.href = url;
+  link.download = fileName;
+  link.click();
+};
+const download = () => {
+  downloadFile(
+    "/virtual-patient-manage/medicalRecManage/downloadMedicalAnswerTemplate",
+    "导入模版"
+  );
+};
+const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
+  //上传图片格式和大小要求  png|jpg  10M
+
+  const type = rawFile.name.split(".")[rawFile.name.split(".").length - 1];
+  if (!["xls", "xlsx"].includes(type)) {
+    ElMessage.error("上传文件格式不正确");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 10) {
+    ElMessage.error("大小不能大于10M");
+    return false;
+  }
+  fileInfo.fileName = rawFile.name;
+  return true;
+};
+const downErrorFile = () => {
+  downloadFile(downLoadUrl(fileInfo.fileId), "错误报告");
+};
+const submit = () => {
+  dialogVisible.value = false;
+  emit("update", fileList.value);
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="820"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>上传数据</span>
+        </div>
+        <div class="line" />
+        <div class="download_card">
+          <p>1.下载导入模板,根据模板提示完善内容</p>
+          <div @click="download" class="download_btn">
+            <downloadIcon />
+            <span>下载模板</span>
+          </div>
+        </div>
+        <div class="upload_card">
+          <span class="title">2.上传完善好的表格</span>
+          <div class="main">
+            <img v-if="!fileInfo.fileName" :src="UploadImg" alt="" />
+            <img v-if="fileInfo.fileName" :src="fileImg" alt="" />
+            <span v-if="fileInfo.fileName">{{ fileInfo.fileName }}</span>
+            <el-upload
+              :limit="5"
+              multiple
+              :show-file-list="false"
+              :headers="{
+                token: getToken()
+              }"
+              action="/virtual-patient-manage/medicalRecManage/preUploadMedicalAnswer"
+              :on-success="handleSuccess"
+              :before-upload="beforeUpload"
+            >
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  align-items: center;
+                  justify-content: center;
+                "
+              >
+                <div class="upload_btn">
+                  {{ fileInfo.fileName ? "重新选择" : "选择文件" }}
+                </div>
+                <p>
+                  按下载模板完善信息后,可直接点击选择文件,选取本地文件进行上传,支持格式:
+                  xls,xlsx
+                </p>
+              </div>
+            </el-upload>
+          </div>
+          <div v-if="fileInfo.failCount > 0" class="tip">
+            <warnIcon class="mr-2" />
+            <span>{{
+              `共导入数据${fileInfo.totalCount}条,失败${fileInfo.failCount}条。可`
+            }}</span>
+            <span @click="downErrorFile" style="color: #6196cc; cursor: pointer"
+              >下载错误报告</span
+            >
+            <span>,修改后重新导入</span>
+          </div>
+          <div
+            class="tip"
+            v-if="fileInfo.failCount == 0 && fileList.length > 0"
+          >
+            <img :src="successIcon" alt="" class="mr-2" />
+            <span>数据格式正确,无错误数据</span>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <!-- <div class="reset" @click="resetForm()">重置</div> -->
+          <div class="main" @click="submit()">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 800px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+
+  .download_card {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    width: 100%;
+    padding: 24px;
+    margin-bottom: 24px;
+    font-size: 16px;
+    font-weight: 400;
+    color: #333;
+    background: #f8f9fa;
+    border: 1px solid #ebedee;
+    border-radius: 6px;
+
+    .download_btn {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 140px;
+      height: 40px;
+      margin-top: 24px;
+      line-height: 40px;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #d1d3d6;
+      border-radius: 6px;
+      opacity: 1;
+
+      span {
+        margin-left: 8px;
+      }
+    }
+  }
+
+  .upload_card {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    padding: 24px;
+    margin-bottom: 24px;
+    background: #f8f9fa;
+    border: 1px solid #ebedee;
+    border-radius: 6px;
+    opacity: 1;
+
+    .tip {
+      display: flex;
+      align-items: center;
+      width: 100%;
+      margin-top: 24px;
+      font-size: 14px;
+      color: #333;
+
+      img {
+        width: 14px;
+        height: 14px;
+      }
+    }
+
+    .main {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      padding: 32px;
+      background: #fff;
+      border: 1px dashed #bcbfc3;
+    }
+
+    .title {
+      width: 100%;
+      margin-bottom: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      color: #333 !important;
+    }
+
+    img {
+      width: 76px;
+      height: 76px;
+    }
+
+    .upload_btn {
+      width: 112px;
+      height: 40px;
+      margin-top: 16px;
+      font-size: 16px;
+      line-height: 40px;
+      color: #333;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #d1d3d6;
+      border-radius: 6px;
+      opacity: 1;
+    }
+
+    p {
+      margin-top: 16px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #b4b4b4;
+    }
+  }
+}
+</style>
diff --git a/src/views/caseManagement/list/page/index.vue b/src/views/caseManagement/list/page/index.vue
new file mode 100644
index 0000000..1463fad
--- /dev/null
+++ b/src/views/caseManagement/list/page/index.vue
@@ -0,0 +1,41 @@
+<script setup lang="ts">
+import BasicInfo from "./compontents/basicInfo.vue";
+import CollarbedDiagnosis from "./compontents/collarbedDiagnosis.vue";
+import DiagnosticBasis from "./compontents/diagnosticBasis.vue";
+import ResponseStrategy from "./compontents/responseStrategy.vue";
+import { useCaseStoreHooks } from "@/store/modules/caseManagement";
+import DisposalPlan from "./compontents/DisposalPlan.vue";
+import { computed } from "vue";
+const active = computed(() => {
+  return useCaseStoreHooks().activedStep;
+});
+</script>
+
+<template>
+  <div class="main-table">
+    <el-steps
+      class="head_step"
+      :active="active"
+      finish-status="success"
+      align-center
+    >
+      <el-step title="基础信息" />
+      <el-step title="临床诊断" />
+      <el-step title="诊断依据" />
+      <el-step title="应答策略" />
+      <el-step title="处置计划" />
+    </el-steps>
+    <BasicInfo v-show="active === 0" />
+    <div v-if="active > 0">
+      <CollarbedDiagnosis v-show="active === 1" />
+      <DiagnosticBasis v-show="active === 2" />
+      <ResponseStrategy v-show="active === 3" />
+      <DisposalPlan v-show="active === 4" />
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.head_step {
+  margin-bottom: 24px;
+}
+</style>
diff --git a/src/views/consultation/AssistInspect/AssistInspectResult.vue b/src/views/consultation/AssistInspect/AssistInspectResult.vue
new file mode 100644
index 0000000..bbaa6f2
--- /dev/null
+++ b/src/views/consultation/AssistInspect/AssistInspectResult.vue
@@ -0,0 +1,126 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/support_icon.png";
+import emptyImg from "@/assets/newInquiry/empty_res.png";
+import { ref, watch } from "vue";
+import { saveAncillaryAssessmentResult } from "@/api/consultation";
+import { message } from "@/utils/message";
+
+defineOptions({
+  name: "AssistInspectResult"
+});
+
+const props = defineProps({
+  rowItem: {
+    type: Object,
+    default: () => {}
+  },
+  isEnd: {
+    type: Boolean,
+    default: false
+  }
+});
+const dataInfo = ref({
+  result: "",
+  assessmentResult: "",
+  diagnosisAssessmentFlag: 0,
+  id: ""
+});
+watch(
+  () => props.rowItem,
+  val => {
+    dataInfo.value = JSON.parse(JSON.stringify(val || {}));
+  }
+);
+const emit = defineEmits(["save"]);
+const save = async () => {
+  const res: any = await saveAncillaryAssessmentResult({
+    recordId: dataInfo.value.id,
+    result: dataInfo.value.assessmentResult
+  });
+  if (res.code === 200) {
+    message("判读成功", { type: "success" });
+    emit("save");
+    dataInfo.value = JSON.parse(JSON.stringify({}));
+  }
+};
+</script>
+
+<template>
+  <div class="AssistInspectResult">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>辅助检查结果</span>
+      </div>
+    </div>
+    <div
+      v-show="dataInfo.result"
+      class="mt-4 result"
+      v-html="dataInfo.result"
+    />
+    <div v-if="dataInfo.diagnosisAssessmentFlag === 1" class="footer_btn">
+      <el-input
+        class="inp"
+        placeholder="可输入判读结果"
+        v-model="dataInfo.assessmentResult"
+      />
+      <div class="main" @click="save">保存</div>
+    </div>
+    <div v-show="!dataInfo.result" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span v-show="!isEnd">未开具检查申请,请开具</span>
+      <span v-show="isEnd"
+        >在“已开具辅助检查”列表中选择检查项查看辅助检查结果</span
+      >
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AssistInspectResult {
+  flex: 1;
+  padding: 24px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .result {
+    height: calc(100vh - 380px);
+    overflow-y: auto;
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: calc(100vh - 421px);
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .footer_btn {
+    display: flex;
+
+    .inp {
+      flex: 1;
+    }
+
+    .main {
+      width: 144px;
+      height: 48px;
+      margin-left: 24px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/AssistInspect/AssistTable.vue b/src/views/consultation/AssistInspect/AssistTable.vue
new file mode 100644
index 0000000..850463b
--- /dev/null
+++ b/src/views/consultation/AssistInspect/AssistTable.vue
@@ -0,0 +1,450 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/support_icon.png";
+import emptyImg from "@/assets/newInquiry/empty_table.png";
+import { ref, watch, computed, onMounted } from "vue";
+import downImg from "@/assets/newInquiry/down.png";
+import AddIcon from "@/assets/svg/add_item.svg?component";
+import DelIcon from "@/assets/svg/consultation/del.svg?component";
+import {
+  queryAncillaryItemList,
+  queryAskAncillaryHistory
+} from "@/api/inquiry";
+import { execAskAncillaryBatch } from "@/api/consultation";
+import { useRoute } from "vue-router";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { message } from "@/utils/message";
+import PrimaryDiagnosis from "../components/PrimaryDiagnosis/index.vue";
+defineOptions({
+  name: "AssistTable"
+});
+const selectItems = ref([]);
+const supportToolList = ref([]);
+const supportResList = ref([]);
+const isEnd = computed(() => {
+  return supportResList.value.length > 0 ? true : false;
+});
+const props = {
+  value: "id",
+  label: "itemName",
+  children: "itemList",
+  disabled: "flag",
+  multiple: true,
+  expandTrigger: "hover" as const
+};
+const PrimaryDiagnosisRef = ref();
+const route = useRoute();
+const getPhysicalToolList = async () => {
+  const res: any = await queryAncillaryItemList({
+    processId: route.query.processId
+  });
+  supportToolList.value = res.data;
+};
+const getValue = (type, id) => {
+  let value = undefined;
+  for (const item of selectDataList.value) {
+    if (item.id === id) {
+      value = item[type];
+    }
+  }
+  return value;
+};
+const getDataList = data => {
+  const arry = [];
+  for (const item of data) {
+    for (const items of supportToolList.value) {
+      if (items.id === item[0]) {
+        items.itemList.forEach(e => {
+          if (e.id === item[1]) {
+            arry.push({
+              ...e,
+              // firstType: items.itemName
+              primaryId: getValue("primaryId", e.id),
+              primaryNames: getValue("primaryNames", e.id)
+            });
+          }
+        });
+      }
+    }
+  }
+  selectDataList.value = arry;
+};
+const handleChange = item => {
+  getDataList(item);
+};
+const selectDataList = ref([]);
+const columns: TableColumnList = [
+  {
+    label: "类目",
+    prop: "type",
+    width: 150
+  },
+  {
+    label: "辅助诊断",
+    prop: "itemName",
+    width: 200
+  },
+  {
+    label: "身体部位",
+    prop: "locationName",
+    formatter: ({ locationName }) => {
+      return locationName || "无";
+    },
+    width: 150
+  },
+  {
+    label: "初步诊断",
+    prop: "primaryNames",
+    slot: "select"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    slot: "operation",
+    width: 100
+  }
+];
+const supportColumns: TableColumnList = [
+  {
+    label: "类目",
+    prop: "type",
+    width: 150
+  },
+  {
+    label: "辅助诊断",
+    prop: "itemName"
+  },
+  {
+    label: "身体部位",
+    prop: "locationName",
+    formatter: ({ locationName }) => {
+      return locationName || "无";
+    },
+    width: 150
+  },
+  {
+    label: "初步诊断",
+    slot: "inspect",
+    width: 150
+  }
+];
+const askPrimaryList = ref([]);
+watch(
+  () => useConsultationStoreHooks().firstInspectList,
+  val => {
+    askPrimaryList.value = val;
+  }
+);
+watch(
+  () => useConsultationStoreHooks().supportActionId,
+  val => {
+    if (val.length === 0) return;
+    let flag = true;
+    for (const item of selectItems.value) {
+      if (item[1] === val[1]) {
+        flag = false;
+        return;
+      }
+    }
+    if (!flag) return;
+    const arry = [...selectItems.value];
+    arry.push(val);
+    selectItems.value = arry;
+    getDataList(selectItems.value);
+  }
+);
+const del = index => {
+  selectDataList.value.splice(index, 1);
+  const list = [...selectItems.value];
+  list.splice(index, 1);
+  selectItems.value = list;
+};
+const getAskAncillaryHistory = async () => {
+  const res: any = await queryAskAncillaryHistory({
+    processId: route.query.processId
+  });
+  if (res.data.length > 0) {
+    emit("inspectOk");
+  }
+  supportResList.value = res.data;
+};
+const getInspectText = list => {
+  const arry = [];
+
+  list.forEach(e => {
+    arry.push(e.primaryDiseaseName);
+  });
+  return arry.join(",");
+};
+const getName = list => {
+  const arry = [];
+  for (const item of list) {
+    askPrimaryList.value.forEach(e => {
+      if (item === e.id) {
+        arry.push(e.primaryDiseaseName);
+      }
+    });
+  }
+  return arry.join(",");
+};
+const handleCheckboxChange = index => {
+  const text = getName(selectDataList.value[index].primaryId);
+  selectDataList.value[index].primaryNames = text;
+};
+// 开具检查
+const submit = async () => {
+  const arry = [];
+  for (const item of selectDataList.value) {
+    if (!item.primaryId || item.primaryId.length === 0) {
+      message("存在未配置的初步诊断", { type: "warning" });
+      return;
+    }
+    arry.push({
+      ancillaryItemId: item.id,
+      primaryId: item.primaryId,
+      processId: route.query.processId
+    });
+  }
+  const res: any = await execAskAncillaryBatch(arry);
+  if (res.code === 200) {
+    message("提交成功", { type: "success" });
+    getAskAncillaryHistory();
+    emit("inspectOk");
+  }
+};
+const emit = defineEmits(["selectOne", "inspectOk"]);
+const openDetail = item => {
+  emit("selectOne", item);
+};
+const add = () => {
+  PrimaryDiagnosisRef.value.open();
+};
+defineExpose({
+  refresh() {
+    getAskAncillaryHistory();
+  }
+});
+onMounted(() => {
+  getPhysicalToolList();
+  getAskAncillaryHistory();
+  useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+});
+</script>
+
+<template>
+  <div class="AssistTable">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>{{ isEnd ? "已开具辅助检查" : "辅助检查申请" }} </span>
+      </div>
+    </div>
+    <el-cascader
+      popper-class="custom-cascader"
+      v-if="!isEnd"
+      :show-all-levels="false"
+      collapse-tags
+      :max-collapse-tags="5"
+      filterable
+      style="width: 100%"
+      class="mt-4 mb-4"
+      size="large"
+      v-model="selectItems"
+      :options="supportToolList"
+      :props="props"
+      :emitPath="false"
+      @change="handleChange"
+    />
+    <div v-if="!isEnd">
+      <pure-table
+        v-show="selectDataList.length > 0"
+        align-whole="center"
+        showOverflowTooltip
+        class="mt-4"
+        style="height: calc(100vh - 520px)"
+        :data="selectDataList"
+        :columns="columns"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+      >
+        <template #select="{ row, index }">
+          <el-dropdown>
+            <div v-if="!row.primaryNames" class="slect">
+              <span>请选择</span>
+              <img :src="downImg" alt="" />
+            </div>
+            <div v-if="row.primaryNames" class="slect">
+              <span style="color: #666">{{ row.primaryNames }}</span>
+              <img :src="downImg" alt="" />
+            </div>
+            <template #dropdown>
+              <el-checkbox-group
+                size="large"
+                class="dropdown_list"
+                v-model="row.primaryId"
+                @change="handleCheckboxChange(index)"
+              >
+                <el-checkbox
+                  size="large"
+                  class="dropdown_list_item"
+                  v-for="(item, index) in askPrimaryList"
+                  :key="index"
+                  :label="item.id"
+                  >{{ item.primaryDiseaseName }}</el-checkbox
+                >
+              </el-checkbox-group>
+              <div @click="add" class="add_drop_item">
+                <AddIcon style="font-size: 12px" />
+                <span style="font-size: 14px">添加初步诊断</span>
+              </div>
+            </template>
+          </el-dropdown>
+          <!-- <div style="position: relative; top: -11px" v-if="row.primaryNames">
+            {{ row.primaryNames }}
+          </div> -->
+        </template>
+        <template #operation="{ index }">
+          <div
+            @click="del(index)"
+            style="display: flex; justify-content: center; cursor: pointer"
+          >
+            <DelIcon />
+          </div>
+        </template>
+      </pure-table>
+      <div v-show="selectDataList.length === 0" class="empty_list">
+        <img :src="emptyImg" alt="" />
+        <span>未选择任何检查项,请选择</span>
+      </div>
+    </div>
+    <div v-if="isEnd">
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        style="height: calc(100vh - 500px)"
+        class="mt-4"
+        :data="supportResList"
+        :columns="supportColumns"
+        highlight-current-row
+        @current-change="openDetail"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+      >
+        <template #inspect="{ row }">
+          <span>{{ getInspectText(row.primaryList) }}</span>
+        </template>
+      </pure-table>
+    </div>
+    <div
+      @click="submit"
+      v-if="!isEnd && selectDataList.length > 0"
+      class="save_btn"
+    >
+      开具检查
+    </div>
+    <PrimaryDiagnosis ref="PrimaryDiagnosisRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.AssistTable {
+  position: relative;
+  width: 50%;
+  padding: 24px;
+  margin-right: 16px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: calc(100vh - 421px);
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .slect {
+    display: flex;
+    padding: 16px 0;
+    font-size: 14px;
+    font-weight: 400;
+    color: #b4b4b4;
+
+    img {
+      position: relative;
+      top: 4px;
+      width: 10px;
+      height: 6px;
+      margin-left: 6px;
+    }
+  }
+
+  .save_btn {
+    position: absolute;
+    right: 24px;
+    bottom: 24px;
+    width: 188px;
+    height: 48px;
+    line-height: 48px;
+    color: #fff;
+    text-align: center;
+    cursor: pointer;
+    background: #4287ff;
+    border-radius: 6px;
+  }
+}
+
+:deep(.el-checkbox__inner) {
+  // border-radius: 20px;
+  width: 18px;
+  height: 18px;
+}
+</style>
+<style lang="scss">
+.dropdown_list {
+  display: flex;
+  flex-direction: column;
+
+  .dropdown_list_item {
+    padding: 16px;
+    // margin-bottom: 8px;
+  }
+
+  .el-checkbox.el-checkbox--large .el-checkbox__inner {
+    width: 18px;
+    height: 18px;
+  }
+
+  .el-checkbox__inner::after {
+    left: 5px;
+    width: 5px;
+    height: 9px;
+    border-width: 2px;
+  }
+}
+
+.add_drop_item {
+  display: flex;
+  padding: 0 16px;
+  margin-top: 8px;
+  margin-bottom: 16px;
+  cursor: pointer;
+
+  span {
+    margin-left: 8px;
+  }
+}
+</style>
+<style lang="scss">
+.custom-cascader .el-scrollbar__wrap {
+  height: 500px; /* 设置下拉框的最大高度 */
+}
+</style>
diff --git a/src/views/consultation/AssistInspect/components/HeaderTitle.vue b/src/views/consultation/AssistInspect/components/HeaderTitle.vue
new file mode 100644
index 0000000..d040dfe
--- /dev/null
+++ b/src/views/consultation/AssistInspect/components/HeaderTitle.vue
@@ -0,0 +1,40 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/inspect_icon.png";
+defineProps({
+  title: {
+    type: String,
+    default: ""
+  }
+});
+</script>
+
+<template>
+  <div class="HeaderTitle">
+    <div class="title">
+      <img :src="titleIcon" alt="" />
+      <span>{{ title }}</span>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.HeaderTitle {
+  display: flex;
+  align-items: center;
+  border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+  .title {
+    display: flex;
+    padding-bottom: 8px;
+    font-size: 16px;
+    font-weight: bold;
+    color: #2b3f54;
+    border-bottom: 4px solid #4287ff;
+
+    img {
+      width: 20px;
+      height: 20px;
+      margin-right: 8px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/AssistInspect/index.vue b/src/views/consultation/AssistInspect/index.vue
new file mode 100644
index 0000000..52eb7fc
--- /dev/null
+++ b/src/views/consultation/AssistInspect/index.vue
@@ -0,0 +1,98 @@
+<script setup lang="ts">
+import AssistTable from "./AssistTable.vue";
+import AssistInspectResult from "./AssistInspectResult.vue";
+import TabTips from "../components/TabTips/index.vue";
+import { ref } from "vue";
+defineOptions({
+  name: "AssistInspect"
+});
+const rowItem = ref();
+const AssistTableRef = ref();
+const isEnd = ref(false);
+const selectOne = val => {
+  rowItem.value = val;
+};
+const inspectOk = () => {
+  isEnd.value = true;
+};
+const save = () => {
+  AssistTableRef.value.refresh();
+};
+</script>
+
+<template>
+  <div class="AssistInspect">
+    <div class="tab_list">
+      <div class="tab_list_item">
+        <div class="content">
+          <div class="tab_case_img tab_img" />
+          <span>辅助检查</span>
+        </div>
+      </div>
+      <TabTips />
+    </div>
+    <div class="content">
+      <AssistTable
+        ref="AssistTableRef"
+        @inspectOk="inspectOk"
+        @selectOne="selectOne"
+      />
+      <AssistInspectResult :rowItem="rowItem" :isEnd="isEnd" @save="save" />
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AssistInspect {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  padding: 40px;
+
+  .tab_list {
+    display: flex;
+    justify-content: space-between;
+    margin-top: 12px;
+    margin-bottom: 24px;
+
+    .tab_list_item {
+      width: 300px;
+      height: 0;
+      margin-right: 6px;
+      font-size: 18px;
+      font-weight: bold;
+      cursor: pointer;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid #4287ff;
+      border-left: 20px solid transparent;
+      border-radius: 6px;
+
+      .content {
+        position: relative;
+        top: 12px;
+        right: 21px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 300px;
+        color: #fff;
+      }
+
+      .tab_img {
+        width: 20px;
+        height: 20px;
+        margin-right: 12px;
+        background-size: 100% 100%;
+      }
+
+      .tab_case_img {
+        background-image: url("../../../assets/newInquiry/tab/act_assist.png");
+      }
+    }
+  }
+
+  .content {
+    display: flex;
+    flex: 1;
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/ConfirmDiagnosisDialog.vue b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/ConfirmDiagnosisDialog.vue
new file mode 100644
index 0000000..06cb1c2
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/ConfirmDiagnosisDialog.vue
@@ -0,0 +1,171 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import { Warning } from "@element-plus/icons-vue";
+import CloseIcon from "@/assets/svg/consultation/close.svg?component";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "ConfirmDiagnosisDialog"
+});
+const dialogVisible = ref(false);
+const diseaseList = ref([]);
+
+defineExpose({
+  open(list) {
+    diseaseList.value = list;
+    dialogVisible.value = true;
+  }
+});
+const closeDialog = () => {
+  dialogVisible.value = false;
+};
+const emit = defineEmits(["save"]);
+const save = () => {
+  closeDialog();
+  emit("save", diseaseList.value);
+};
+const goBack = () => {
+  closeDialog();
+  if (sessionStorage.getItem("inspectSatus") === "1") {
+    useConsultationStoreHooks().changeActivedKey(3);
+  } else {
+    useConsultationStoreHooks().changeActivedKey(0);
+  }
+};
+</script>
+
+<template>
+  <div>
+    <el-dialog
+      width="600"
+      append-to-body
+      v-model="dialogVisible"
+      :before-close="closeDialog"
+      :show-close="false"
+      custom-class="ConfirmDiagnosisDialog"
+    >
+      <div class="ConfirmDiagnosisDialog">
+        <div class="header-title">
+          <div class="tip" />
+          <span>确认诊断 </span>
+          <CloseIcon @click="closeDialog" class="close" />
+        </div>
+        <div class="line" />
+        <div class="tip_info">
+          <el-icon size="16"><Warning /></el-icon>
+          <span class="ml-2">确认诊毕后不支持继续问诊,请谨慎确定诊断结果</span>
+        </div>
+        <p class="title">初步诊断列表</p>
+        <div class="disease_list">
+          <div
+            v-for="(item, index) in diseaseList"
+            :key="index"
+            class="disease_list_item"
+          >
+            <span style="color: #00975e" v-if="item.excludeFlag === 1"
+              >【确诊】</span
+            >
+            <span style="color: #ff3429" v-if="item.excludeFlag === 0"
+              >【排除】</span
+            >
+            <span>{{ item.primaryDiseaseName }}</span>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn_list">
+          <el-button size="large" @click="closeDialog">取消</el-button>
+          <el-button size="large" type="primary" @click="goBack"
+            >诊断回顾</el-button
+          >
+          <el-button size="large" @click="save" type="primary">诊毕</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ConfirmDiagnosisDialog {
+  .header-title {
+    position: relative;
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+
+    .close {
+      position: absolute;
+      top: 6px;
+      right: 0;
+      cursor: pointer;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 600px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .tip_info {
+    display: flex;
+    align-items: center;
+    width: 536px;
+    height: 40px;
+    padding-left: 15px;
+    font-size: 12px;
+    font-weight: 400;
+    color: #4287ff;
+    background: rgb(66 135 255 / 8%);
+    border-radius: 6px;
+  }
+
+  .title {
+    margin-top: 24px;
+    font-size: 16px;
+    font-weight: 400;
+    color: #364c63;
+  }
+
+  .disease_list {
+    display: flex;
+    flex-direction: column;
+    padding: 16px 0 0 16px;
+    margin-top: 16px;
+    background: #f8f8f8;
+    border-radius: 6px;
+
+    .disease_list_item {
+      display: flex;
+      margin-bottom: 16px;
+      color: #364c63;
+    }
+  }
+
+  .footer_btn_list {
+    :deep(.el-button) {
+      width: 160px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.ConfirmDiagnosisDialog {
+  .el-dialog__body {
+    padding-top: 0;
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/IdentificationBasis.vue b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/IdentificationBasis.vue
new file mode 100644
index 0000000..40c6808
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/IdentificationBasis.vue
@@ -0,0 +1,216 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/inspect_icon.png";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import ConfirmDiagnosisDialog from "./ConfirmDiagnosisDialog.vue";
+import { ref } from "vue";
+import { reactive } from "vue";
+import {
+  queryDiagnosticBasisListForPrimary,
+  confirmPrimaryByAskEnd
+} from "@/api/consultation";
+import { onMounted } from "vue";
+import { useRoute } from "vue-router";
+import { message } from "@/utils/message";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "IdentificationBasis"
+});
+const route = useRoute();
+const typeList = ["", "问诊", "体格检查 ", "辅助检查"];
+const itemList = ref([]);
+const idList = ref([]);
+const selectDataList = ref([]);
+const selectDataInfo = reactive({
+  patientDiseaseInfo: "",
+  primaryDiseaseName: "",
+  excludeFlag: ""
+});
+const ConfirmDiagnosisDialogRef = ref();
+const columns: TableColumnList = [
+  {
+    label: "阶段",
+    prop: "type",
+    formatter: ({ type }) => {
+      return typeList[type];
+    }
+  },
+  {
+    label: "检查类目",
+    prop: "category"
+  },
+  {
+    label: "问诊项目",
+    prop: "item"
+  },
+  {
+    label: "身体部位",
+    prop: "locationName"
+  },
+  {
+    label: "初步诊断",
+    prop: "primaryName"
+  },
+  // {
+  //   label: "诊断依据",
+  //   prop: "select"
+  // },
+  {
+    label: "证实诊断依据",
+    slot: "basisConfirm"
+  },
+  {
+    label: "鉴别诊断依据",
+    slot: "basisIdentification"
+  }
+];
+const getDataList = async item => {
+  const res: any = await queryDiagnosticBasisListForPrimary({
+    processId: route.query.processId,
+    primaryId: item.id
+  });
+  selectDataInfo[item.id] = res.data;
+  selectDataList.value = res.data;
+};
+defineExpose({
+  open(item) {
+    selectDataInfo.patientDiseaseInfo = item.patientDiseaseInfo;
+    selectDataInfo.primaryDiseaseName = item.primaryDiseaseName;
+    selectDataInfo.excludeFlag = item.excludeFlag;
+    if (idList.value.includes(item.id)) {
+      selectDataList.value = selectDataInfo[item.id];
+    } else {
+      itemList.value.push(item);
+      idList.value.push(item.id);
+      getDataList(item);
+    }
+  },
+  submit(data) {
+    ConfirmDiagnosisDialogRef.value.open(data);
+  },
+  reset() {
+    for (const item of selectDataList.value) {
+      item.basisConfirmFlag = 0;
+      item.basisIdentificationFlag = 0;
+    }
+    selectDataInfo.excludeFlag = null;
+  },
+  getData(data) {
+    const arry = [];
+    for (let i = 0; i < itemList.value.length; i++) {
+      arry.push({
+        diagnosticBasisList: selectDataInfo[itemList.value[i].id],
+        excludeFlag: data[i].excludeFlag,
+        primaryId: itemList.value[i].id
+      });
+    }
+    return arry;
+  }
+});
+const emit = defineEmits(["save"]);
+const save = async data => {
+  const arry = [];
+  for (let i = 0; i < itemList.value.length; i++) {
+    arry.push({
+      diagnosticBasisList: selectDataInfo[itemList.value[i].id],
+      excludeFlag: data[i].excludeFlag,
+      primaryId: itemList.value[i].id
+    });
+  }
+  const params = {
+    primaryConfirmList: arry,
+    processId: route.query.processId,
+    tempSaveFlag: 0
+  };
+  const res: any = await confirmPrimaryByAskEnd(params);
+  if (res.code === 200) {
+    sessionStorage.setItem("inspectSatus", "1");
+    useConsultationStoreHooks().changeInspectSatus("1");
+    message("请配置处置计划", { type: "success" });
+    emit("save");
+  }
+};
+onMounted(() => {});
+</script>
+
+<template>
+  <div class="IdentificationBasis">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>鉴别依据</span>
+      </div>
+    </div>
+    <div class="desc" v-if="selectDataInfo.primaryDiseaseName">
+      <p>{{ `患者病情依据:${selectDataInfo.patientDiseaseInfo}` }}</p>
+      <p>{{ `初步诊断:${selectDataInfo.primaryDiseaseName}` }}</p>
+      <!-- <p>{{ `最终诊断:${getText(selectDataInfo.excludeFlag)}` }}</p> -->
+    </div>
+    <pure-table
+      ref="tableRef"
+      v-if="selectDataList.length > 0"
+      align-whole="center"
+      style="height: calc(100vh - 485px)"
+      showOverflowTooltip
+      class="mt-4"
+      :data="selectDataList"
+      :columns="columns"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+    >
+      <template #basisConfirm="{ row }">
+        <el-checkbox
+          :true-label="1"
+          :false-label="0"
+          v-model="row.basisConfirmFlag"
+          size="large"
+        />
+      </template>
+      <template #basisIdentification="{ row }">
+        <el-checkbox
+          :true-label="1"
+          :false-label="0"
+          v-model="row.basisIdentificationFlag"
+          size="large"
+        />
+      </template>
+    </pure-table>
+    <div v-show="selectDataList.length === 0" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无相关数据</span>
+    </div>
+    <ConfirmDiagnosisDialog @save="save" ref="ConfirmDiagnosisDialogRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.IdentificationBasis {
+  flex: 1;
+  padding: 24px;
+  margin-left: 16px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .desc {
+    p {
+      margin-top: 16px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/PreliminaryDiagnosis.vue b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/PreliminaryDiagnosis.vue
new file mode 100644
index 0000000..bb2d50f
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/PreliminaryDiagnosis.vue
@@ -0,0 +1,192 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/inspect_icon.png";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import DownIcon from "@/assets/svg/consultation/down.svg?component";
+import { ref, watch } from "vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "PreliminaryDiagnosis"
+});
+const askPrimaryList = ref([]);
+const tableRef = ref();
+
+const columns: TableColumnList = [
+  {
+    label: "诊断项目",
+    prop: "primaryDiseaseName"
+  },
+  {
+    label: "最终诊断",
+    slot: "select"
+  }
+];
+watch(
+  () => useConsultationStoreHooks().firstInspectList,
+  val => {
+    askPrimaryList.value = val;
+    if (askPrimaryList.value.length > 0) {
+      setCurrent(askPrimaryList.value[0]);
+    }
+  }
+);
+
+defineExpose({
+  getFlag() {
+    let flag = true;
+    if (askPrimaryList.value.length === 0) {
+      flag = false;
+      message("请添加初步诊断", { type: "warning" });
+      return;
+    } else {
+      askPrimaryList.value.forEach(e => {
+        if (e.excludeFlag === null) {
+          flag = false;
+        }
+      });
+      if (!flag) {
+        message("存在未配置的最终诊断", { type: "warning" });
+      }
+    }
+
+    return flag;
+  },
+  getData() {
+    return askPrimaryList.value;
+  },
+  reset() {
+    for (const item of askPrimaryList.value) {
+      item.excludeFlag = null;
+    }
+  }
+});
+const emit = defineEmits(["selectOne"]);
+const handleCurrentChange = val => {
+  emit("selectOne", val);
+};
+const changeFlag = (index, val) => {
+  askPrimaryList.value[index].excludeFlag = val;
+  console.log(askPrimaryList.value);
+};
+const setCurrent = (row?: any) => {
+  // 获取表格的方法 tableRef.value.getTableRef()
+  const { setCurrentRow } = tableRef.value.getTableRef();
+  setCurrentRow(row);
+};
+</script>
+
+<template>
+  <div class="PreliminaryDiagnosis">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>初步诊断列表</span>
+      </div>
+    </div>
+    <pure-table
+      ref="tableRef"
+      v-show="askPrimaryList.length > 0"
+      align-whole="center"
+      showOverflowTooltip
+      class="mt-4"
+      :data="askPrimaryList"
+      :columns="columns"
+      highlight-current-row
+      @current-change="handleCurrentChange"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+    >
+      <template #select="{ row, index }">
+        <el-dropdown>
+          <div v-if="row.excludeFlag === 1" class="slect">
+            <span class="confirm">确诊</span>
+            <DownIcon />
+          </div>
+          <div v-else-if="row.excludeFlag === 0" class="slect">
+            <span class="exclude">排除</span>
+            <DownIcon />
+          </div>
+          <div v-else class="slect">
+            <span>请选择</span>
+            <DownIcon />
+            <!-- <div class="triangle" /> -->
+          </div>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item @click="changeFlag(index, 1)"
+                >确诊</el-dropdown-item
+              >
+              <el-dropdown-item @click="changeFlag(index, 0)"
+                >排除</el-dropdown-item
+              >
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </template>
+    </pure-table>
+    <div v-show="askPrimaryList.length === 0" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无相关数据</span>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.PreliminaryDiagnosis {
+  width: 532px;
+  padding: 24px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .slect {
+    display: flex;
+    width: 100%;
+    padding: 16px 0;
+    font-size: 14px;
+    font-weight: 400;
+    color: #b4b4b4;
+
+    svg {
+      position: relative;
+      top: 4px;
+      width: 10px;
+      height: 6px;
+      margin-left: 6px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .confirm {
+    color: #00975e;
+  }
+
+  .exclude {
+    color: #ff3429;
+  }
+
+  .triangle {
+    position: relative;
+    width: 0;
+    height: 0;
+    border-top: 12px solid #000;
+    border-right: 9px solid transparent;
+    border-left: 9px solid transparent;
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/index.vue b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/index.vue
new file mode 100644
index 0000000..2cc20c1
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/ConfirmInspect/index.vue
@@ -0,0 +1,118 @@
+<script setup lang="ts">
+import PreliminaryDiagnosis from "./PreliminaryDiagnosis.vue";
+import IdentificationBasis from "./IdentificationBasis.vue";
+
+import { onMounted, ref } from "vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { useRoute } from "vue-router";
+import { onBeforeUnmount } from "vue";
+import { confirmPrimaryByAskEnd } from "@/api/consultation";
+defineOptions({
+  name: "ConfirmInspect"
+});
+const route = useRoute();
+const processId = ref();
+const IdentificationBasisRef = ref();
+const PreliminaryDiagnosisRef = ref();
+const completed = () => {
+  //
+  const flag = PreliminaryDiagnosisRef.value.getFlag();
+  const data = PreliminaryDiagnosisRef.value.getData();
+  if (flag) {
+    IdentificationBasisRef.value.submit(data);
+  }
+};
+const selectOne = item => {
+  IdentificationBasisRef.value.open(item);
+};
+const reset = () => {
+  // useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+  PreliminaryDiagnosisRef.value.reset();
+  IdentificationBasisRef.value.reset();
+};
+const emit = defineEmits(["saveOk"]);
+// 诊断完成
+const saveOk = () => {
+  emit("saveOk");
+};
+onMounted(() => {
+  processId.value = route.query.processId;
+  useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+});
+// 离开时暂存
+onBeforeUnmount(async () => {
+  const data = PreliminaryDiagnosisRef.value.getData();
+  const list = IdentificationBasisRef.value.getData(data);
+  if (list.length === 0) return;
+  const params = {
+    primaryConfirmList: list,
+    processId: route.query.processId ? route.query.processId : processId.value,
+    tempSaveFlag: 1
+  };
+
+  await confirmPrimaryByAskEnd(params);
+});
+</script>
+
+<template>
+  <div class="ConfirmInspect">
+    <div class="main_content">
+      <PreliminaryDiagnosis
+        ref="PreliminaryDiagnosisRef"
+        @select-one="selectOne"
+      />
+      <IdentificationBasis @save="saveOk" ref="IdentificationBasisRef" />
+    </div>
+    <div class="footer_btn">
+      <div class="reset" @click="reset">重置</div>
+      <div class="main" @click="completed">诊毕</div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ConfirmInspect {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+
+  .main_content {
+    display: flex;
+    flex: 1;
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/DisposalPlan/DetermineDisposal.vue b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/DetermineDisposal.vue
new file mode 100644
index 0000000..41ab0dc
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/DetermineDisposal.vue
@@ -0,0 +1,148 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import planTip from "@/assets/newInquiry/plan_tip.png";
+import CloseIcon from "@/assets/svg/consultation/close.svg?component";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { confirmPlan } from "@/api/consultation";
+import { message } from "@/utils/message";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "DetermineDisposal"
+});
+const dialogVisible = ref(false);
+const route = useRoute();
+defineExpose({
+  open() {
+    dialogVisible.value = true;
+  }
+});
+const closeDialog = () => {
+  dialogVisible.value = false;
+};
+const save = async () => {
+  const res: any = await confirmPlan({
+    processId: route.query.processId,
+    status: "2"
+  });
+  if (res.code === 200) {
+    message("提交成功", { type: "success" });
+    sessionStorage.setItem("inspectSatus", "2");
+    useConsultationStoreHooks().changeInspectSatus("2");
+    useConsultationStoreHooks().changeActivedKey(4);
+    closeDialog();
+  }
+};
+const goBack = () => {
+  closeDialog();
+  useConsultationStoreHooks().changeActivedKey(3);
+};
+</script>
+
+<template>
+  <div>
+    <el-dialog
+      width="600"
+      append-to-body
+      v-model="dialogVisible"
+      :before-close="closeDialog"
+      :show-close="false"
+      custom-class="DetermineDisposal"
+    >
+      <div class="DetermineDisposal">
+        <div class="header-title">
+          <div class="tip" />
+          <span>确认诊断 </span>
+          <CloseIcon @click="closeDialog" class="close" />
+        </div>
+        <div class="line" />
+        <div class="tips">
+          <img :src="planTip" alt="" />
+          <span
+            >是否确认当前处置计划,确定将获得本次问诊评估结果,取消可继续处置</span
+          >
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn_list">
+          <el-button size="large" @click="closeDialog">取消</el-button>
+          <el-button size="large" type="primary" @click="goBack"
+            >诊断回顾</el-button
+          >
+          <el-button size="large" @click="save" type="primary">诊毕</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<style lang="scss" scoped>
+.DetermineDisposal {
+  .header-title {
+    position: relative;
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+
+    .close {
+      position: absolute;
+      top: 6px;
+      right: 0;
+      cursor: pointer;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 600px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .tips {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    margin: 80px 0;
+
+    img {
+      width: 209;
+      height: 102px;
+      margin-bottom: 24px;
+    }
+  }
+
+  .title {
+    margin-top: 24px;
+    font-size: 16px;
+    font-weight: 400;
+    color: #364c63;
+  }
+
+  .footer_btn_list {
+    :deep(.el-button) {
+      width: 160px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.DetermineDisposal {
+  .el-dialog__body {
+    padding-top: 0;
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/DisposalPlan/PlanTable.vue b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/PlanTable.vue
new file mode 100644
index 0000000..33b97d0
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/PlanTable.vue
@@ -0,0 +1,261 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/inspect_icon.png";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import DelIcon from "@/assets/svg/consultation/del.svg?component";
+import EditIcon from "@/assets/svg/consultation/edit.svg?component";
+import { ref } from "vue";
+import { queryDetails, deleteRecord } from "@/api/consultation";
+import { onMounted } from "vue";
+import { useRoute } from "vue-router";
+import { message } from "@/utils/message";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "PlanTable"
+});
+const planDataList = ref([]);
+const drugList = ref([]);
+const route = useRoute();
+const drugRouteList = [
+  {
+    id: 0,
+    name: "口服"
+  },
+  {
+    id: 1,
+    name: "静脉注射"
+  },
+  {
+    id: 2,
+    name: "静脉输液"
+  },
+  {
+    id: 3,
+    name: "皮下注射"
+  },
+  {
+    id: 4,
+    name: "局部用药"
+  },
+  {
+    id: 5,
+    name: "气雾剂/粉雾剂吸入"
+  },
+  {
+    id: 6,
+    name: "雾化吸入"
+  },
+  {
+    id: 7,
+    name: "鞘内注射"
+  }
+];
+const columns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlanName"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+  {
+    label: "说明",
+    prop: "guide"
+  },
+  {
+    label: "操作",
+    slot: "operation"
+  }
+];
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const drugColumns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlanName"
+  },
+  {
+    label: "药物名称",
+    prop: "drugName"
+  },
+  {
+    label: "用药途径",
+    formatter: ({ drugRoute }) => `${drugRouteList[drugRoute]?.name || ""}`
+  },
+  {
+    label: "用药间隔",
+    prop: "select",
+    formatter: ({ intervalDay, intervalHour }) => {
+      return intervalDay !== null
+        ? intervalDayList[intervalDay]?.name
+        : `${intervalHour}小时`;
+    }
+  },
+  {
+    label: "说明",
+    prop: "guide"
+  },
+  {
+    label: "操作",
+    slot: "operation",
+    width: 120
+  }
+];
+const getDetails = async () => {
+  const res: any = await queryDetails({
+    processId: route.query.processId
+  });
+  if (
+    res.data.userTreatmentPlanType === 0 ||
+    res.data.userTreatmentPlanType === 1
+  ) {
+    useConsultationStoreHooks().planTypeFlag = res.data.userTreatmentPlanType;
+  } else {
+    useConsultationStoreHooks().planTypeFlag = "";
+  }
+  planDataList.value = res.data.otherTreatmentPlan;
+  drugList.value = res.data.drugTreatmentPlan;
+};
+onMounted(() => {
+  getDetails();
+});
+defineExpose({
+  reset() {
+    getDetails();
+  }
+});
+const emit = defineEmits(["edit"]);
+const edit = (item: any) => {
+  emit("edit", item);
+};
+const del = async (id: any) => {
+  const res: any = await deleteRecord({ id });
+  if (res.code === 200) {
+    message("删除成功", { type: "success" });
+    getDetails();
+  }
+};
+</script>
+
+<template>
+  <div class="PlanTable">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>处置计划列表</span>
+      </div>
+    </div>
+    <div
+      class="main_table"
+      v-show="planDataList.length > 0 || drugList.length > 0"
+    >
+      <div class="left" v-show="planDataList.length > 0">
+        <pure-table
+          ref="tableRef"
+          align-whole="center"
+          showOverflowTooltip
+          style="height: calc(100vh - 800px)"
+          class="mt-4"
+          :data="planDataList"
+          :columns="columns"
+          :header-cell-style="{
+            background: 'var(--el-table-row-hover-bg-color)',
+            color: 'var(--el-text-color-primary)'
+          }"
+        >
+          <template #operation="{ row }">
+            <div
+              style="display: flex; justify-content: center; cursor: pointer"
+            >
+              <EditIcon @click="edit(row)" class="mr-4" />
+              <DelIcon @click="del(row.id)" />
+            </div>
+          </template>
+        </pure-table>
+      </div>
+      <div class="right" v-show="drugList.length > 0">
+        <pure-table
+          align-whole="center"
+          showOverflowTooltip
+          style="height: calc(100vh - 800px)"
+          class="mt-4"
+          :data="drugList"
+          :columns="drugColumns"
+          :header-cell-style="{
+            background: 'var(--el-table-row-hover-bg-color)',
+            color: 'var(--el-text-color-primary)'
+          }"
+        >
+          <template #operation="{ row }">
+            <div
+              style="display: flex; justify-content: center; cursor: pointer"
+            >
+              <EditIcon @click="edit(row)" class="mr-4" />
+              <DelIcon @click="del(row.id)" />
+            </div>
+          </template>
+        </pure-table>
+      </div>
+    </div>
+    <div
+      v-show="planDataList.length === 0 && drugList.length === 0"
+      class="empty_list"
+    >
+      <img :src="emptyImg" alt="" />
+      <span>暂无相关数据,请在“设置处置计划”中添加</span>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.PlanTable {
+  flex: 1;
+  padding: 24px;
+  margin-top: 16px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .main_table {
+    display: flex;
+    height: calc(100vh - 815px);
+
+    .left {
+      width: 40%;
+    }
+
+    .right {
+      width: 60%;
+      margin-left: 38px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: calc(100vh - 815px);
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/DisposalPlan/SetPlan.vue b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/SetPlan.vue
new file mode 100644
index 0000000..9908167
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/SetPlan.vue
@@ -0,0 +1,435 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/inspect_icon.png";
+import { reactive, ref, watch } from "vue";
+import {
+  queryTree,
+  savePlan,
+  getDrugList,
+  updateRecord
+} from "@/api/consultation";
+import { onMounted } from "vue";
+import { FormInstance } from "element-plus";
+import { useRoute } from "vue-router";
+import { message } from "@/utils/message";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+const formData = reactive({
+  disposalPlan: "",
+  disposalPlanName: "",
+  disposalMethod: "",
+  firstMeasures: "",
+  drugRoute: "",
+  drugId: "",
+  guide: "",
+  intervalDay: "",
+  treatmentPlanId: "",
+  intervalHour: "",
+  id: ""
+});
+const planList = ref([]);
+const firstMeasuresList = ref([]);
+const ruleFormRef = ref<FormInstance>();
+const drugList = ref([]);
+const drugRouteList = [
+  {
+    id: 0,
+    name: "口服"
+  },
+  {
+    id: 1,
+    name: "静脉注射"
+  },
+  {
+    id: 2,
+    name: "静脉输液"
+  },
+  {
+    id: 3,
+    name: "皮下注射"
+  },
+  {
+    id: 4,
+    name: "局部用药"
+  },
+  {
+    id: 5,
+    name: "气雾剂/粉雾剂吸入"
+  },
+  {
+    id: 6,
+    name: "雾化吸入"
+  },
+  {
+    id: 7,
+    name: "鞘内注射"
+  }
+];
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const rules = {
+  disposalMethod: [
+    { required: true, message: "请选择处置方案", trigger: "change" }
+  ],
+  disposalPlan: [
+    { required: true, message: "请选择处置计划", trigger: "change" }
+  ]
+};
+const editFlag = ref(false);
+const route = useRoute();
+const selectItem = item => {
+  if (editFlag.value) return;
+  formData.disposalPlan = item.id;
+  formData.disposalPlanName = item.name;
+  firstMeasuresList.value = item.child;
+  formData.firstMeasures = "";
+  formData.drugId = "";
+  formData.drugRoute = "";
+  formData.intervalDay = "";
+  formData.intervalHour = "";
+  formData.treatmentPlanId = "";
+};
+const clearData = () => {
+  formData.firstMeasures = "";
+  formData.drugId = "";
+  formData.drugRoute = "";
+  formData.intervalDay = "";
+  formData.intervalHour = "";
+  formData.guide = "";
+  formData.treatmentPlanId = "";
+  formData.disposalPlan = "";
+};
+const getTree = async val => {
+  clearData();
+
+  const res: any = await queryTree({
+    disposalMethod: val
+  });
+  planList.value = res.data;
+};
+const queryDrugList = async () => {
+  const res: any = await getDrugList();
+  drugList.value = res.data;
+};
+const emit = defineEmits(["save"]);
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      let params: any = {};
+      if (formData.disposalPlanName === "药物") {
+        const {
+          disposalMethod,
+          disposalPlan,
+          drugId,
+          drugRoute,
+          intervalHour,
+          intervalDay,
+          guide,
+          id
+        } = formData;
+        params = {
+          disposalMethod,
+          disposalPlan,
+          drugId,
+          drugRoute,
+          intervalHour,
+          intervalDay,
+          guide,
+          processId: route.query.processId,
+          id
+        };
+      } else {
+        const { disposalMethod, disposalPlan, treatmentPlanId, guide, id } =
+          formData;
+        params = {
+          disposalMethod,
+          disposalPlan,
+          treatmentPlanId,
+          processId: route.query.processId,
+          guide,
+          id
+        };
+      }
+      if (!editFlag.value) {
+        params.id = undefined;
+        const res: any = await savePlan(params);
+        if (res.code === 200) {
+          if (!ruleFormRef.value) return;
+          ruleFormRef.value.resetFields();
+          cancal();
+          message("新增成功", { type: "success" });
+        }
+      } else {
+        const res: any = await updateRecord(params);
+        if (res.code === 200) {
+          if (!ruleFormRef.value) return;
+          ruleFormRef.value.resetFields();
+          cancal();
+          message("修改成功", { type: "success" });
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const selectInterval = val => {
+  if (val) {
+    formData.intervalHour = "";
+  }
+};
+watch(
+  () => useConsultationStoreHooks().planTypeFlag,
+  val => {
+    if (val !== "") {
+      formData.disposalMethod = val;
+      getTree(formData.disposalMethod);
+    }
+  }
+);
+defineExpose({
+  edit(item) {
+    for (const key in item) {
+      // eslint-disable-next-line no-prototype-builtins
+      if (formData.hasOwnProperty(key)) {
+        formData[key] = item[key];
+      }
+    }
+    planList.value.forEach(e => {
+      if (e.id === item.disposalPlan) {
+        firstMeasuresList.value = e.child;
+      }
+    });
+    editFlag.value = true;
+  },
+  reset() {
+    cancal();
+  }
+});
+const cancal = () => {
+  if (!ruleFormRef.value) return;
+  ruleFormRef.value.resetFields();
+  formData.disposalMethod = useConsultationStoreHooks().planTypeFlag;
+  editFlag.value = false;
+  formData.disposalPlanName = "";
+  emit("save");
+};
+onMounted(() => {
+  if (useConsultationStoreHooks().planTypeFlag !== "") {
+    formData.disposalMethod = useConsultationStoreHooks().planTypeFlag;
+    getTree(formData.disposalMethod);
+  }
+
+  queryDrugList();
+  if (formData.disposalMethod) {
+    getTree(formData.disposalMethod);
+  }
+});
+</script>
+
+<template>
+  <div class="SetPlan">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>设置处置计划</span>
+      </div>
+    </div>
+    <el-form
+      ref="ruleFormRef"
+      :model="formData"
+      class="mt-4"
+      :rules="rules"
+      label-width="120px"
+    >
+      <el-form-item label="处置方案" prop="disposalMethod">
+        <el-radio-group
+          :disabled="useConsultationStoreHooks().planTypeFlag !== ''"
+          v-model="formData.disposalMethod"
+          @change="getTree"
+          class="ml-2"
+        >
+          <el-radio :label="0">门诊治疗</el-radio>
+          <el-radio :label="1">入院治疗</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="请选择处置计划" prop="disposalPlan">
+        <div class="plan_list">
+          <div
+            @click="selectItem(item)"
+            class="plan_item"
+            :class="[item.id === formData.disposalPlan ? 'actived' : '']"
+            v-for="(item, index) in planList"
+            :key="index"
+          >
+            <span>{{ item.name }}</span>
+          </div>
+        </div>
+      </el-form-item>
+      <el-form-item
+        v-if="formData.disposalPlanName !== '药物'"
+        label="一级措施"
+        prop="treatmentPlanId"
+      >
+        <el-select
+          filterable
+          v-model="formData.treatmentPlanId"
+          style="width: 350px"
+          placeholder="请选择"
+        >
+          <el-option
+            v-for="item in firstMeasuresList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id"
+          />
+        </el-select>
+      </el-form-item>
+      <el-row v-show="formData.disposalPlanName === '药物'">
+        <el-form-item label="选择药品" prop="drugId">
+          <el-select
+            filterable
+            v-model="formData.drugId"
+            style="width: 350px"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="item in drugList"
+              :key="item.id"
+              :label="item.drugName"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="用药途径" prop="drugRoute">
+          <el-select
+            filterable
+            v-model="formData.drugRoute"
+            style="width: 350px"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="item in drugRouteList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="用药间隔" prop="intervalDay">
+          <el-select
+            filterable
+            @change="selectInterval"
+            v-model="formData.intervalDay"
+            style="width: 170px"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="item in intervalDayList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <div v-show="formData.intervalDay === ''" class="time ml-1">
+          <span>间隔</span>
+          <el-input
+            class="time_input"
+            :style="{ border: 'none' }"
+            :maxLength="2"
+            placeholder="请输入"
+            v-model="formData.intervalHour"
+          />
+          <span>小时</span>
+        </div>
+      </el-row>
+      <el-form-item label="说明" prop="guide">
+        <el-input
+          style="width: 350px"
+          :rows="2"
+          type="textarea"
+          :maxLength="500"
+          placeholder="请输入"
+          v-model="formData.guide"
+        />
+      </el-form-item>
+    </el-form>
+    <el-button
+      type="primary"
+      @click="save(ruleFormRef)"
+      style="margin-left: 120px"
+      >保存</el-button
+    >
+    <el-button v-if="editFlag" @click="cancal" style="margin-left: 20px"
+      >取消</el-button
+    >
+  </div>
+</template>
+<style lang="scss" scoped>
+.SetPlan {
+  height: 352px;
+  padding: 24px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .plan_list {
+    display: flex;
+
+    .plan_item {
+      height: 36px;
+      padding: 0 16px;
+      margin-right: 10px;
+      font-size: 14px;
+      font-weight: 400;
+      line-height: 36px;
+      color: #b4b4b4;
+      text-align: center;
+      cursor: pointer;
+      background: #f5f5f5;
+      border-radius: 6px;
+    }
+
+    .actived {
+      color: #fff;
+      background: #4287ff;
+    }
+  }
+
+  .time {
+    display: flex;
+    // width: 169px;
+    height: 30px;
+    padding: 0 12px;
+    line-height: 30px;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+
+    .time_input {
+      width: 65px;
+    }
+
+    :deep(.el-input__wrapper) {
+      cursor: default;
+      border: none !important;
+      box-shadow: 0 0 0 0 var(--el-input-border-color, var(--el-border-color))
+        inset;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/DisposalPlan/index.vue b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/index.vue
new file mode 100644
index 0000000..8b05bcf
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/DisposalPlan/index.vue
@@ -0,0 +1,78 @@
+<script setup lang="ts">
+import SetPlan from "./SetPlan.vue";
+import PlanTable from "./PlanTable.vue";
+import DetermineDisposal from "./DetermineDisposal.vue";
+import { ref } from "vue";
+defineOptions({
+  name: "DisposalPlan"
+});
+const DetermineDisposalRef = ref();
+const PlanTableRef = ref();
+const SetPlanRef = ref();
+const save = () => {
+  DetermineDisposalRef.value.open();
+};
+const addPlan = () => {
+  PlanTableRef.value.reset();
+};
+const edit = item => {
+  SetPlanRef.value.edit(item);
+};
+const reset = () => {
+  SetPlanRef.value.reset();
+};
+</script>
+
+<template>
+  <div class="DisposalPlan">
+    <SetPlan ref="SetPlanRef" @save="addPlan" />
+    <PlanTable @edit="edit" ref="PlanTableRef" />
+    <div class="footer_btn">
+      <div class="reset" @click="reset">重置</div>
+      <div class="main" @click="save">确定处置</div>
+    </div>
+    <DetermineDisposal ref="DetermineDisposalRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.DisposalPlan {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConfirmDiagnosis/index.vue b/src/views/consultation/ConfirmDiagnosis/index.vue
new file mode 100644
index 0000000..4e00599
--- /dev/null
+++ b/src/views/consultation/ConfirmDiagnosis/index.vue
@@ -0,0 +1,121 @@
+<script setup lang="ts">
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import ConfirmInspect from "./ConfirmInspect/index.vue";
+import DisposalPlan from "./DisposalPlan/index.vue";
+import { ref } from "vue";
+import { message } from "@/utils/message";
+
+defineOptions({
+  name: "ConfirmDiagnosis"
+});
+const activedKey = ref(0);
+const changeTab = val => {
+  if (val === 1 && useConsultationStoreHooks().inspectSatus === "0") {
+    message("请先确认诊断", { type: "warning" });
+    return;
+  }
+  activedKey.value = val;
+};
+const saveOk = () => {
+  activedKey.value = 1;
+};
+</script>
+
+<template>
+  <div class="ConfirmDiagnosis">
+    <div class="tab_list">
+      <div
+        @click="changeTab(0)"
+        class="tab_list_item"
+        :class="[activedKey === 0 ? 'actived' : '']"
+      >
+        <div class="content">
+          <div class="tab_confirm_img tab_img" />
+          <span>确认诊断</span>
+        </div>
+      </div>
+      <div
+        @click="changeTab(1)"
+        class="tab_list_item"
+        :class="[activedKey === 1 ? 'actived' : '']"
+      >
+        <div class="content">
+          <div class="tab_plan_img tab_img" />
+          <span>处置计划</span>
+        </div>
+      </div>
+    </div>
+    <ConfirmInspect @saveOk="saveOk" v-show="activedKey === 0" />
+    <DisposalPlan v-show="activedKey === 1" />
+    <!-- <CaseWriting v-show="useConsultationStoreHooks().activedKey === 0" />
+    <BodyInspect v-show="useConsultationStoreHooks().activedKey === 1" /> -->
+  </div>
+</template>
+<style lang="scss" scoped>
+.ConfirmDiagnosis {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  padding: 40px 40px 24px;
+
+  .tab_list {
+    display: flex;
+    margin-top: 12px;
+    margin-bottom: 24px;
+
+    .tab_list_item {
+      width: 300px;
+      height: 0;
+      margin-right: 6px;
+      font-size: 18px;
+      font-weight: bold;
+      color: #4287ff;
+      cursor: pointer;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid rgb(66 135 255 / 15%);
+      border-left: 20px solid transparent;
+      border-radius: 6px;
+
+      .content {
+        position: relative;
+        top: 12px;
+        right: 21px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 300px;
+      }
+
+      .tab_img {
+        width: 20px;
+        height: 20px;
+        margin-right: 12px;
+        background-size: 100% 100%;
+      }
+
+      .tab_confirm_img {
+        background-image: url("@/assets/newInquiry/tab/confirm.png");
+      }
+    }
+
+    .actived {
+      color: #fff;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid #4287ff;
+      border-left: 20px solid transparent;
+    }
+
+    .tab_plan_img {
+      background-image: url("@/assets/newInquiry/tab/plan.png");
+    }
+
+    .actived .tab_plan_img {
+      background-image: url("@/assets/newInquiry/tab/act_plan.png");
+    }
+
+    .actived .tab_confirm_img {
+      background-image: url("@/assets/newInquiry/tab/act_confirm.png");
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConsultationEvaluation/components/RatingOverview.vue b/src/views/consultation/ConsultationEvaluation/components/RatingOverview.vue
new file mode 100644
index 0000000..b154a25
--- /dev/null
+++ b/src/views/consultation/ConsultationEvaluation/components/RatingOverview.vue
@@ -0,0 +1,512 @@
+<script setup lang="ts">
+import tipIcon from "@/assets/inquiry/tip.png";
+import inquiryImg from "@/assets/newInquiry/evaluate/inquiry.png";
+import bodyInspectImg from "@/assets/newInquiry/evaluate/bodyInspect.png";
+import supportImg from "@/assets/newInquiry/evaluate/support.png";
+import disposalPlanImg from "@/assets/newInquiry/evaluate/disposalPlan.png";
+import clinicalThinkingImg from "@/assets/newInquiry/evaluate/clinicalThinking.png";
+import { computed, ref } from "vue";
+import VueChart from "./VueChart.vue";
+import { queryRadarChart } from "@/api/consultation";
+import { onMounted } from "vue";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "RatingOverview"
+});
+
+const ancillaryChart = ref(undefined);
+const askChart = ref(undefined);
+const physicalChart = ref(undefined);
+const treatmentPlanChart = ref(undefined);
+const clinicalThinking = ref(undefined);
+const overview = ref("");
+const route = useRoute();
+const chartOption = computed(() => {
+  const data = [
+    { text: "问诊", value: askChart.value.nodePer },
+    { text: "体格检查", value: physicalChart.value.nodePer },
+    { text: "辅助检查", value: ancillaryChart.value.nodePer },
+    { text: "处置计划", value: treatmentPlanChart.value.nodePer },
+    { text: "临床思维", value: clinicalThinking.value.nodePer }
+  ];
+  const valueList = [];
+  data.forEach(e => {
+    valueList.push(e.value);
+  });
+  return {
+    legend: {},
+    radar: [
+      {
+        indicator: data,
+        center: ["45%", "50%"],
+        radius: 120,
+        splitNumber: 4,
+        shape: "circle",
+        axisName: {
+          color: "#2B3F54",
+          fontSize: 16,
+          borderRadius: 3,
+          padding: [3, 5]
+        }
+      }
+    ],
+    series: [
+      {
+        type: "radar",
+        emphasis: {
+          lineStyle: {
+            width: 4
+          }
+        },
+        data: [
+          {
+            value: valueList,
+            name: "",
+            areaStyle: {
+              color: "#4287FF"
+            }
+          }
+        ]
+      }
+    ]
+  };
+});
+const getData = async () => {
+  const res: any = await queryRadarChart({ processId: route.query.processId });
+  ancillaryChart.value = res.data.ancillaryChart;
+  askChart.value = res.data.askChart;
+  physicalChart.value = res.data.physicalChart;
+  treatmentPlanChart.value = res.data.treatmentPlanChart;
+  clinicalThinking.value = res.data.clinicalThinking;
+  overview.value = res.data.processEvaluation.overview;
+};
+const getPercentage = (number1, number2) => {
+  // 计算占比
+  const ratio = (number1 / number2) * 100;
+  // 保留两位小数
+  const formattedRatio = ratio.toFixed(2);
+  return formattedRatio;
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="RatingOverview">
+    <div class="tip">
+      <img :src="tipIcon" alt="" />
+      <span
+        >该初步评估提供了有关您对病历进行诊治的信息,评估类别旁将标记√为本次诊断成功完成的任务。
+      </span>
+    </div>
+    <p>
+      评估类别:包含首次问诊(问诊、体格检查)、辅助检查、确认诊断(确诊、处置计划)三个阶段的诊断评估结果。
+    </p>
+    <p class="mt-2">{{ overview }}</p>
+    <div v-if="ancillaryChart" class="main">
+      <div class="left">
+        <div class="chart-style" style="width: 100%; height: 100%">
+          <vue-chart :option="chartOption" style="width: 100%; height: 100%" />
+        </div>
+      </div>
+      <div class="right">
+        <div class="right_item">
+          <div class="top">
+            <div class="top_left">
+              <img :src="inquiryImg" alt="" />
+              <span>问诊</span>
+            </div>
+            <div class="top_right">
+              <span>{{ askChart.scoreLevel }}</span>
+              <!-- <span class="desc">达成率:</span>
+              <span class="value">{{ `${askChart.nodePer}%` }}</span> -->
+            </div>
+          </div>
+          <div class="line">
+            <div
+              :style="{
+                width: getPercentage(askChart.correct, askChart.total) + '%'
+              }"
+              class="correct"
+            />
+            <div
+              :style="{
+                width: getPercentage(askChart.standard, askChart.total) + '%'
+              }"
+              class="standard"
+            />
+            <div
+              :style="{
+                width: getPercentage(askChart.unCorrect, askChart.total) + '%'
+              }"
+              class="error"
+            />
+          </div>
+          <div class="text">
+            <span class="correct">{{ `正确:${askChart.correct}` }}</span>
+            <span class="standard">{{ `标准:${askChart.standard}` }}</span>
+            <span class="error">{{ `不符合:${askChart.unCorrect}` }}</span>
+            <!-- <span class="all">{{ `全部:${askChart.total}` }}</span> -->
+          </div>
+        </div>
+        <div class="right_item">
+          <div class="top">
+            <div class="top_left">
+              <img :src="bodyInspectImg" alt="" />
+              <span>体格检查</span>
+            </div>
+            <div class="top_right">
+              <span>{{ physicalChart.scoreLevel }}</span>
+              <!-- <span class="desc">达成率:</span>
+              <span class="value">{{ `${physicalChart.nodePer}%` }}</span> -->
+            </div>
+          </div>
+          <div class="line">
+            <div
+              :style="{
+                width:
+                  getPercentage(physicalChart.correct, physicalChart.total) +
+                  '%'
+              }"
+              class="correct"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(physicalChart.standard, physicalChart.total) +
+                  '%'
+              }"
+              class="standard"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(physicalChart.unCorrect, physicalChart.total) +
+                  '%'
+              }"
+              class="error"
+            />
+          </div>
+          <div class="text">
+            <span class="correct">{{ `正确:${physicalChart.correct}` }}</span>
+            <span class="standard">{{
+              `标准:${physicalChart.standard}`
+            }}</span>
+            <span class="error">{{
+              `不符合:${physicalChart.unCorrect}`
+            }}</span>
+            <!-- <span class="all">{{ `全部:${physicalChart.total}` }}</span> -->
+          </div>
+        </div>
+        <div class="right_item" style="border-right: 0">
+          <div class="top">
+            <div class="top_left">
+              <img :src="supportImg" alt="" />
+              <span>辅助检查</span>
+            </div>
+            <div class="top_right">
+              <span>{{ ancillaryChart.scoreLevel }}</span>
+              <!-- <span class="desc">达成率:</span>
+              <span class="value">{{ `${ancillaryChart.nodePer}%` }}</span> -->
+            </div>
+          </div>
+          <div class="line">
+            <div
+              :style="{
+                width:
+                  getPercentage(ancillaryChart.correct, ancillaryChart.total) +
+                  '%'
+              }"
+              class="correct"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(ancillaryChart.standard, ancillaryChart.total) +
+                  '%'
+              }"
+              class="standard"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    ancillaryChart.unCorrect,
+                    ancillaryChart.total
+                  ) + '%'
+              }"
+              class="error"
+            />
+          </div>
+          <div class="text">
+            <span class="correct">{{ `正确:${ancillaryChart.correct}` }}</span>
+            <span class="standard">{{
+              `标准:${ancillaryChart.standard}`
+            }}</span>
+            <span class="error">{{
+              `不符合:${ancillaryChart.unCorrect}`
+            }}</span>
+            <!-- <span class="all">{{ `全部:${ancillaryChart.total}` }}</span> -->
+          </div>
+        </div>
+        <div class="right_item" style="margin-top: -12px">
+          <div class="top">
+            <div class="top_left">
+              <img :src="disposalPlanImg" alt="" />
+              <span>处置计划</span>
+            </div>
+            <div class="top_right">
+              <span>{{ treatmentPlanChart.scoreLevel }}</span>
+              <!-- <span class="desc">达成率:</span>
+              <span class="value">{{ `${treatmentPlanChart.nodePer}%` }}</span> -->
+            </div>
+          </div>
+          <div class="line">
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    treatmentPlanChart.correct,
+                    treatmentPlanChart.total
+                  ) + '%'
+              }"
+              class="correct"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    treatmentPlanChart.standard,
+                    treatmentPlanChart.total
+                  ) + '%'
+              }"
+              class="standard"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    treatmentPlanChart.unCorrect,
+                    treatmentPlanChart.total
+                  ) + '%'
+              }"
+              class="error"
+            />
+          </div>
+          <div class="text">
+            <span class="correct">{{
+              `正确:${treatmentPlanChart.correct}`
+            }}</span>
+            <span class="standard">{{
+              `标准:${treatmentPlanChart.standard}`
+            }}</span>
+            <span class="error">{{
+              `不符合:${treatmentPlanChart.unCorrect}`
+            }}</span>
+            <!-- <span class="all">{{ `全部:${treatmentPlanChart.total}` }}</span> -->
+          </div>
+        </div>
+        <div class="right_item" style="margin-top: -12px">
+          <div class="top">
+            <div class="top_left">
+              <img :src="clinicalThinkingImg" alt="" />
+              <span>临床思维</span>
+            </div>
+            <div class="top_right">
+              <span>{{ clinicalThinking.scoreLevel }}</span>
+              <!-- <span class="desc">达成率:</span>
+              <span class="value">{{ `${clinicalThinking.nodePer}%` }}</span> -->
+            </div>
+          </div>
+          <div class="line">
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    clinicalThinking.correct,
+                    clinicalThinking.total
+                  ) + '%'
+              }"
+              class="correct"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    clinicalThinking.standard,
+                    clinicalThinking.total
+                  ) + '%'
+              }"
+              class="standard"
+            />
+            <div
+              :style="{
+                width:
+                  getPercentage(
+                    clinicalThinking.unCorrect,
+                    clinicalThinking.total
+                  ) + '%'
+              }"
+              class="error"
+            />
+          </div>
+          <div class="text">
+            <span class="correct">{{
+              `正确:${clinicalThinking.correct}`
+            }}</span>
+            <span class="standard">{{
+              `标准:${clinicalThinking.standard}`
+            }}</span>
+            <span class="error">{{
+              `不符合:${clinicalThinking.unCorrect}`
+            }}</span>
+            <!-- <span class="all">{{ `全部:${clinicalThinking.total}` }}</span> -->
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.RatingOverview {
+  .tip {
+    display: flex;
+    align-items: center;
+    height: 32px;
+
+    img {
+      width: 20px;
+      height: 20px;
+    }
+
+    span {
+      margin-left: 8px;
+      font-size: 12px;
+      font-weight: 400;
+      color: #4287ff;
+    }
+  }
+
+  .main {
+    display: flex;
+    height: 455px;
+    padding: 16px;
+    margin-top: 24px;
+    background: rgb(66 135 255 / 5%);
+    border: 1px solid rgb(66 135 255 / 50%);
+    border-radius: 6px;
+
+    .left {
+      width: 512px;
+    }
+
+    .right {
+      display: flex;
+      flex: 1;
+      flex-wrap: wrap;
+      padding: 54px 40px;
+      background: #fff;
+      border-radius: 6px;
+
+      .right_item {
+        width: 33.33%;
+        height: 150px;
+        padding: 20px;
+        border-right: 1px solid #d9d9d9;
+        border-bottom: 1px solid #d9d9d9;
+
+        .top {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+
+          .top_left {
+            display: flex;
+            align-items: center;
+
+            img {
+              width: 40px;
+              height: 40px;
+            }
+
+            span {
+              margin-left: 16px;
+              font-size: 16px;
+              font-weight: 400;
+              color: #2b3f54;
+            }
+          }
+
+          .top_right {
+            .desc {
+              font-size: 14px;
+              color: #2b3f54;
+            }
+
+            .value {
+              font-size: 20px;
+              color: #2b3f54;
+            }
+          }
+        }
+
+        .line {
+          display: flex;
+          width: 100%;
+          height: 8px;
+          margin-top: 24px;
+          background: #9563ff;
+          border-radius: 4px;
+
+          .correct {
+            height: 8px;
+            background: #0db274;
+            border-radius: 4px 0 0 4px;
+          }
+
+          .standard {
+            height: 8px;
+            background: #4287ff;
+            border-radius: 4px 0 0 4px;
+          }
+
+          .error {
+            height: 8px;
+            background: #fea800;
+            border-radius: 4px 0 0 4px;
+          }
+        }
+
+        .text {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          margin-top: 8px;
+
+          span {
+            font-size: 12px;
+          }
+
+          .correct {
+            color: #0db274;
+          }
+
+          .standard {
+            color: #4287ff;
+          }
+
+          .error {
+            color: #fea800;
+          }
+
+          .all {
+            color: #9563ff;
+          }
+        }
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConsultationEvaluation/components/VueChart.vue b/src/views/consultation/ConsultationEvaluation/components/VueChart.vue
new file mode 100644
index 0000000..65b074a
--- /dev/null
+++ b/src/views/consultation/ConsultationEvaluation/components/VueChart.vue
@@ -0,0 +1,36 @@
+<template>
+  <div ref="elChart" style="width: 100%; height: 100%" />
+</template>
+<script lang="ts" setup>
+import { ref, onMounted, onUpdated, onUnmounted } from "vue";
+import * as echarts from "echarts";
+
+const props = defineProps({
+  option: {
+    type: Object
+  },
+  data: {
+    type: Object
+  }
+});
+const elChart = ref();
+let chart: any = null;
+
+function clear() {
+  chart && chart.dispose();
+}
+
+function draw() {
+  if (chart) {
+    chart.setOption(props.option);
+  } else {
+    clear();
+    chart = echarts.init(elChart.value);
+    chart.setOption(props.option);
+  }
+}
+
+onMounted(draw);
+onUpdated(draw);
+onUnmounted(clear);
+</script>
diff --git a/src/views/consultation/ConsultationEvaluation/index.vue b/src/views/consultation/ConsultationEvaluation/index.vue
new file mode 100644
index 0000000..05d6ad2
--- /dev/null
+++ b/src/views/consultation/ConsultationEvaluation/index.vue
@@ -0,0 +1,368 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import score from "@/assets/svg/evaluate/score.svg?component";
+import ActScore from "@/assets/svg/evaluate/act_score.svg?component";
+import result from "@/assets/svg/evaluate/result.svg?component";
+import ActResult from "@/assets/svg/evaluate/act_result.svg?component";
+import confirm from "@/assets/svg/evaluate/confirm.svg?component";
+import ActConfirm from "@/assets/svg/evaluate/act_confirm.svg?component";
+import discern from "@/assets/svg/evaluate/discern.svg?component";
+import ActDiscern from "@/assets/svg/evaluate/act_discern.svg?component";
+import disposalPlan from "@/assets/svg/evaluate/disposalPlan.svg?component";
+import ActDisposalPlan from "@/assets/svg/evaluate/act_disposalPlan.svg?component";
+import history from "@/assets/svg/evaluate/history.svg?component";
+import ActHistory from "@/assets/svg/evaluate/act_history.svg?component";
+import RatingOverview from "./components/RatingOverview.vue";
+import { queryDiagnosisResult } from "@/api/inquiry";
+import { useRoute } from "vue-router";
+import { onMounted } from "vue";
+import CheckIcon from "@/assets/svg/consultation/check.svg?component";
+import InspectHistory from "../Evaluate/InspectHistory.vue";
+defineOptions({
+  name: "ConsultationEvaluation"
+});
+const activeName = ref("0");
+const route = useRoute();
+const state = reactive({
+  dataInfo: undefined
+});
+const drugRouteList = [
+  {
+    id: 0,
+    name: "口服"
+  },
+  {
+    id: 1,
+    name: "静脉注射"
+  },
+  {
+    id: 2,
+    name: "静脉输液"
+  },
+  {
+    id: 3,
+    name: "皮下注射"
+  },
+  {
+    id: 4,
+    name: "局部用药"
+  },
+  {
+    id: 5,
+    name: "气雾剂/粉雾剂吸入"
+  },
+  {
+    id: 6,
+    name: "雾化吸入"
+  },
+  {
+    id: 7,
+    name: "鞘内注射"
+  }
+];
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const planList = ref([]);
+const getDetails = async () => {
+  const { data } = await queryDiagnosisResult({
+    processId: route.query.processId
+  });
+  state.dataInfo = data;
+  if (state.dataInfo.dealPlan.otherTreatmentPlan) {
+    planList.value = state.dataInfo.dealPlan.otherTreatmentPlan.concat(
+      state.dataInfo.dealPlan.drugTreatmentPlan
+    );
+  }
+};
+onMounted(() => {
+  getDetails();
+});
+</script>
+
+<template>
+  <div class="ConsultationEvaluation">
+    <el-tabs v-if="state.dataInfo" v-model="activeName" class="demo-tabs">
+      <el-tab-pane name="0">
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActScore v-if="activeName === '0'" />
+            <score v-else />
+            <span>评分概述</span>
+          </span>
+        </template>
+        <RatingOverview />
+      </el-tab-pane>
+      <el-tab-pane name="1">
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActResult v-if="activeName === '1'" />
+            <result v-else />
+            <span>预期诊断结果</span>
+          </span>
+        </template>
+        <p>
+          {{ `正确诊断:${state.dataInfo.expertDiagnosisResult.diagnosis} ` }}
+        </p>
+        <p>您的诊断结果:</p>
+        <div class="card_list">
+          <div
+            class="card_item"
+            v-for="(item, index) in state.dataInfo.expertDiagnosisResult
+              .userDiagnosisResult"
+            :key="index"
+          >
+            <div v-if="item.correct === 1" class="correct">
+              <CheckIcon />
+              <span style="margin-left: 8px; color: #0db274">{{
+                item.diseaseName
+              }}</span>
+            </div>
+            <div v-else class="error">
+              <span>{{ item.diseaseName }}</span>
+            </div>
+          </div>
+        </div>
+        <p>预期初诊诊断列表:</p>
+        <div
+          class="card_item"
+          v-for="(item, index) in state.dataInfo.expertDiagnosisResult
+            .expertDiagnosisResult"
+          :key="index"
+        >
+          {{ item.diseaseName }}
+        </div>
+      </el-tab-pane>
+      <el-tab-pane name="2">
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActResult v-if="activeName === '2'" />
+            <result v-else />
+            <span>初步诊断依据</span>
+          </span>
+        </template>
+        <p>证实或排除初步诊断的必须项目:</p>
+        <div class="card_list">
+          <div
+            class="card_item"
+            v-for="(item, index) in state.dataInfo.basisPrimaryResultResVO
+              .nodeList"
+            :key="index"
+          >
+            <div v-if="item.correct === 1" class="correct">
+              <CheckIcon />
+              <span style="margin-left: 8px; color: #0db274">{{
+                item.recordName
+              }}</span>
+            </div>
+            <div v-else class="error">
+              <span>{{ item.recordName }}</span>
+            </div>
+          </div>
+        </div>
+        <div
+          class="desc"
+          v-html="state.dataInfo.basisPrimaryResultResVO.preliminaryDiagnosis"
+        />
+      </el-tab-pane>
+      <el-tab-pane>
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActConfirm v-if="activeName === '3'" />
+            <confirm v-else />
+            <span>证实诊断依据</span>
+          </span>
+        </template>
+        <p>证实确诊依据所必须的项目:</p>
+        <div class="card_list">
+          <div
+            class="card_item"
+            v-for="(item, index) in state.dataInfo.basisConfirmResultResVO
+              .nodeList"
+            :key="index"
+          >
+            <div v-if="item.correct === 1" class="correct">
+              <CheckIcon />
+              <span style="margin-left: 8px; color: #0db274">{{
+                item.recordName
+              }}</span>
+            </div>
+            <div v-else class="error">
+              <span>{{ item.recordName }}</span>
+            </div>
+          </div>
+        </div>
+        <div
+          class="desc"
+          v-html="state.dataInfo.basisConfirmResultResVO.confirmingDiagnosis"
+        />
+      </el-tab-pane>
+      <el-tab-pane>
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActDiscern v-if="activeName === '4'" />
+            <discern v-else />
+            <span>鉴别依据</span>
+          </span>
+        </template>
+        <p>鉴别依据所必须的项目:</p>
+        <div class="card_list">
+          <div
+            class="card_item"
+            v-for="(item, index) in state.dataInfo.basisIdentificationResult
+              .nodeList"
+            :key="index"
+          >
+            <div v-if="item.correct === 1" class="correct">
+              <CheckIcon />
+              <span style="margin-left: 8px; color: #0db274">{{
+                item.recordName
+              }}</span>
+            </div>
+            <div v-else class="error">
+              <span>{{ item.recordName }}</span>
+            </div>
+          </div>
+        </div>
+        <div
+          class="desc"
+          v-html="
+            state.dataInfo.basisIdentificationResult.identificationDiagnosis
+          "
+        />
+      </el-tab-pane>
+      <el-tab-pane>
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActDisposalPlan v-if="activeName === '5'" />
+            <disposalPlan v-else />
+            <span>处置方案</span>
+          </span>
+        </template>
+        <p>
+          {{
+            state.dataInfo.dealPlan.userTreatmentPlanType == 1
+              ? `正确处置方案: 入院治疗`
+              : `正确处置方案: 门诊治疗`
+          }}
+        </p>
+        <p>您的处置计划:</p>
+        <div class="card_list">
+          <div class="card_item" v-for="(item, index) in planList" :key="index">
+            <div v-if="item.flag === 1" class="correct mr-2">
+              <CheckIcon />
+              <span style="margin-left: 8px; color: #0db274">{{
+                item.disposalPlanName === "药物"
+                  ? `药物 | ${item.drugName} ,${
+                      drugRouteList[item.drugRoute]?.name || ""
+                    } , ${
+                      item.intervalDay !== null
+                        ? intervalDayList[item.intervalDay]?.name
+                        : `${item.intervalHour}小时`
+                    }`
+                  : `${item.disposalPlanName} |  ${item.firstMeasures}`
+              }}</span>
+            </div>
+            <div v-else class="error">
+              <span>{{
+                item.disposalPlanName === "药物"
+                  ? `药物 | ${item.drugName} ,${
+                      drugRouteList[item.drugRoute]?.name || ""
+                    } , ${
+                      item.intervalDay !== null
+                        ? intervalDayList[item.intervalDay]?.name
+                        : `${item.intervalHour}小时`
+                    }`
+                  : `${item.disposalPlanName} |  ${item.firstMeasures}`
+              }}</span>
+            </div>
+          </div>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane>
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActHistory v-if="activeName === '6'" />
+            <history v-else />
+            <span>问诊历史</span>
+          </span>
+        </template>
+        <InspectHistory />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ConsultationEvaluation {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  padding: 40px;
+  overflow-y: auto;
+
+  :deep(.el-tab-pane) {
+    height: calc(100vh - 220px);
+    overflow: auto;
+  }
+
+  .custom-tabs-label {
+    display: flex;
+
+    span {
+      margin-left: 6px;
+    }
+  }
+
+  p {
+    margin-bottom: 16px;
+  }
+
+  .card_list {
+    display: flex;
+    flex-wrap: wrap;
+  }
+
+  .card_item {
+    display: flex;
+    align-items: center;
+    width: calc(25% - 8px);
+    height: 50px;
+    padding: 0 16px;
+    margin: 0 8px 8px 0;
+    background: rgb(66 135 255 / 5%);
+    border: 1px solid rgb(66 135 255 / 50%);
+    border-radius: 6px;
+
+    .correct {
+      display: flex;
+      align-items: center;
+    }
+  }
+
+  .desc {
+    margin-top: 16px;
+    font-size: 16px;
+    font-weight: 400;
+    color: #2b3f54;
+  }
+
+  :deep(.custom-tabs-label) {
+    font-size: 16px;
+  }
+}
+</style>
diff --git a/src/views/consultation/ConsultationRecords/index.vue b/src/views/consultation/ConsultationRecords/index.vue
new file mode 100644
index 0000000..b125925
--- /dev/null
+++ b/src/views/consultation/ConsultationRecords/index.vue
@@ -0,0 +1,385 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/title_icon.png";
+import textIcon from "@/assets/newInquiry/text_icon.png";
+import actReasonableIcon from "@/assets/svg/consultation/record/act_reasonable.svg";
+import actUnreasonableIcon from "@/assets/svg/consultation/record/act_unreasonable.svg";
+import reasonableIcon from "@/assets/svg/consultation/record/reasonable.svg";
+import unreasonableIcon from "@/assets/svg/consultation/record/unreasonable.svg";
+import { queryQaRecordForFeedback, saveFeedback } from "@/api/consultation";
+import { reactive, ref } from "vue";
+import { onMounted } from "vue";
+import { useRoute } from "vue-router";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+
+const formData = reactive({
+  evaluateLevel: undefined,
+  evaluateRemark: ""
+});
+const route = useRoute();
+const ruleFormRef = ref<FormInstance>();
+// const feedbackList = ref([
+//   {
+//     key: "1",
+//     name: "回答过于冗长"
+//   },
+//   {
+//     key: "2",
+//     name: "答非所问"
+//   },
+//   {
+//     key: "3",
+//     name: "内容不合理"
+//   }
+// ]);
+const dataList = ref([
+  // {
+  //   feedbackType: 1,
+  //   remark: "",
+  //   feedback: [],
+  //   question: "您能描述一下这些症状吗?",
+  //   anser:
+  //     "我一直试图让自己忙碌起来。我一般坚持做家务活和各种事情,但是最近这些天我经常喘不过气来,并且感觉到非常虚弱。"
+  // }
+]);
+const rules = {
+  evaluateLevel: [{ required: true, message: "请选择", trigger: "change" }]
+};
+
+const changeStatus = (index, val) => {
+  const list = [...dataList.value];
+  list[index].feedbackType = val;
+  dataList.value = list;
+};
+const getData = async () => {
+  const res: any = await queryQaRecordForFeedback({
+    processId: route.query.processId
+  });
+  dataList.value = res.data.qaList;
+  if (res.data.evaluateLevel !== null && res.data.evaluateLevel !== undefined) {
+    formData.evaluateLevel = res.data.evaluateLevel;
+  } else {
+    formData.evaluateLevel = "";
+  }
+
+  formData.evaluateRemark = res.data.evaluateRemark;
+};
+const reset = () => {
+  getData();
+};
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const params = {
+        qaList: dataList.value,
+        evaluateLevel: formData.evaluateLevel,
+        evaluateRemark: formData.evaluateRemark,
+        processId: route.query.processId
+      };
+      const res: any = await saveFeedback(params);
+      if (res.code === 200) {
+        message("提交成功", { type: "success" });
+        useConsultationStoreHooks().changeActivedKey(4);
+        getData();
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const submit = () => {
+  console.log("1", dataList.value);
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="ConsultationRecords">
+    <div class="main">
+      <div class="evaluate">
+        <div class="header_title">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>问诊评价</span>
+          </div>
+        </div>
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          class="mt-4"
+          :rules="rules"
+          label-width="90px"
+        >
+          <el-form-item label="预期结果:" prop="evaluateLevel">
+            <el-radio-group v-model="formData.evaluateLevel">
+              <el-radio :label="0" size="large">可靠</el-radio>
+              <el-radio :label="1" size="large">基本可靠</el-radio>
+              <el-radio :label="2" size="large">仅供参考</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="备注:" prop="evaluateRemark">
+            <el-input
+              :rows="4"
+              type="textarea"
+              :maxLength="500"
+              placeholder="请输入"
+              v-model="formData.evaluateRemark"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="main_content">
+        <div class="header_title">
+          <div class="title">
+            <img :src="textIcon" alt="" />
+            <span>临床问诊</span>
+          </div>
+        </div>
+        <div class="main_list">
+          <div class="main_item" v-for="(item, index) in dataList" :key="index">
+            <div class="main_item_left">
+              <p class="mb-1">{{ `问诊:${item.question}` }}</p>
+              <p>{{ `病人:${item.answer}` }}</p>
+            </div>
+            <div class="main_item_right">
+              <div
+                @click="changeStatus(index, 1)"
+                class="main_item_right_item"
+                style="margin-right: 40px"
+                :class="[item.feedbackType === 1 ? 'act_reasonableIcon' : '']"
+              >
+                <actReasonableIcon v-if="item.feedbackType === 1" />
+                <reasonableIcon v-else />
+                <span>合理</span>
+              </div>
+              <el-dropdown>
+                <div
+                  @click="changeStatus(index, 2)"
+                  class="main_item_right_item"
+                  :class="[
+                    item.feedbackType === 2 ? 'act_unreasonableIcon' : ''
+                  ]"
+                >
+                  <actUnreasonableIcon v-if="item.feedbackType === 2" />
+                  <unreasonableIcon v-else />
+                  <span>不合理</span>
+                </div>
+                <template #dropdown>
+                  <div class="drop_content">
+                    <div class="title">临床问诊反馈</div>
+                    <div class="dropdown_list">
+                      <el-checkbox
+                        size="large"
+                        class="dropdown_list_item"
+                        v-model="item.feedbackTooLong"
+                        :true-label="1"
+                        :false-label="0"
+                        >回答过于冗长</el-checkbox
+                      >
+                      <el-checkbox
+                        size="large"
+                        class="dropdown_list_item"
+                        :true-label="1"
+                        :false-label="0"
+                        v-model="item.feedbackError"
+                        >答非所问</el-checkbox
+                      >
+                      <el-checkbox
+                        size="large"
+                        class="dropdown_list_item"
+                        :true-label="1"
+                        :false-label="0"
+                        v-model="item.feedbackTooShort"
+                        >内容不合理</el-checkbox
+                      >
+                    </div>
+                    <el-input
+                      v-model="item.feedbackRemark"
+                      maxlength="100"
+                      placeholder="请输入"
+                      show-word-limit
+                      type="textarea"
+                    />
+                    <div class="drop_content_btn" @click="submit">提交</div>
+                  </div>
+                </template>
+              </el-dropdown>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="footer_btn">
+      <div class="reset" @click="reset">重置</div>
+      <div class="main_btn" @click="save(ruleFormRef)">保存</div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ConsultationRecords {
+  // display: flex;
+  padding: 32px;
+
+  .main {
+    display: flex;
+    flex-direction: row-reverse;
+    width: 100%;
+    margin: 16px;
+
+    .evaluate {
+      width: 441px;
+      height: calc(100vh - 250px);
+      padding: 24px;
+      margin-right: 24px;
+      background: #fff;
+      border-radius: 6px;
+      box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+    }
+
+    .main_content {
+      flex: 1;
+      height: calc(100vh - 250px);
+      padding: 24px;
+      margin-right: 16px;
+      overflow-y: auto;
+      background: #fff;
+      border-radius: 6px;
+      box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+      .main_list {
+        .main_item {
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          padding-bottom: 16px;
+          border-bottom: 1px solid #5b8bff;
+
+          .main_item_left {
+            flex: 1;
+            padding-top: 24px;
+            font-size: 16px;
+            color: #2b3f54;
+          }
+
+          .main_item_right {
+            display: flex;
+            width: 200px;
+
+            .main_item_right_item {
+              display: flex;
+              align-items: center;
+              cursor: pointer;
+
+              span {
+                margin-left: 8px;
+                font-size: 14px;
+                font-weight: 400;
+                color: #999;
+              }
+            }
+
+            .act_reasonableIcon span {
+              color: #00975e;
+            }
+
+            .act_unreasonableIcon span {
+              color: #ff3429;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+    margin-right: 32px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main_btn {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.drop_content {
+  width: 240px;
+  height: 295px;
+  padding: 16px;
+  background: #fff;
+  border-radius: 8px;
+  box-shadow: 0 1px 8px 0 rgb(0 0 0 / 15%);
+
+  .title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #2b3f54;
+  }
+
+  .dropdown_list {
+    display: flex;
+    flex-direction: column;
+
+    .dropdown_list_item {
+      padding: 0;
+      // margin-bottom: 8px;
+    }
+
+    .el-checkbox.el-checkbox--large .el-checkbox__inner {
+      width: 18px;
+      height: 18px;
+    }
+
+    .el-checkbox__inner::after {
+      left: 5px;
+      width: 5px;
+      height: 9px;
+      border-width: 2px;
+    }
+  }
+
+  .drop_content_btn {
+    width: 80px;
+    height: 32px;
+    margin-top: 16px;
+    margin-left: 60px;
+    font-size: 14px;
+    line-height: 32px;
+    color: #fff;
+    text-align: center;
+    cursor: pointer;
+    background: #4287ff;
+    border-radius: 6px;
+  }
+}
+</style>
diff --git a/src/views/consultation/ConsultationReview/ElectronicCase.vue b/src/views/consultation/ConsultationReview/ElectronicCase.vue
new file mode 100644
index 0000000..eca4dc6
--- /dev/null
+++ b/src/views/consultation/ConsultationReview/ElectronicCase.vue
@@ -0,0 +1,303 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { ArrowUp, ArrowDown } from "@element-plus/icons-vue";
+import { findByProcessId } from "@/api/consultation";
+import { useRoute } from "vue-router";
+import { onMounted } from "vue";
+defineOptions({
+  name: "ElectronicCase"
+});
+const showFlag = ref(false);
+const route = useRoute();
+const formData = reactive({
+  familyHistoryFlag: undefined,
+  familyHistory: "",
+  previousHistoryFlag: undefined,
+  previousHistory: "",
+  allergyHistoryFlag: undefined,
+  allergyHistory: "",
+  patientSelfDesc: "",
+  personalHistory: "",
+  operationHistoryFlag: undefined,
+  illnessHistory: "",
+  operationHistory: ""
+});
+const baseInfo = ref({
+  processNo: "",
+  medicalRecNo: "",
+  createTime: "",
+  patientSelfDesc: "",
+  patientName: "",
+  patientGender: "",
+  patientAge: "",
+  patientMarriage: "",
+  patientProfession: "",
+  patientPhone: "",
+  nativePlace: "",
+  patientHabitation: "",
+  patientPostcode: "",
+  patientNation: "",
+  patientBirthplace: ""
+});
+const getDetails = async () => {
+  const res: any = await findByProcessId({
+    processId: route.query.processId
+  });
+  baseInfo.value = res.data.base;
+  // formData = res.data.processMedical;
+  for (const key in res.data.processMedical) {
+    // eslint-disable-next-line no-prototype-builtins
+    if (formData.hasOwnProperty(key)) {
+      formData[key] = res.data.processMedical[key];
+    }
+  }
+};
+const getText = val => {
+  if (val === 1) {
+    return "";
+  } else {
+    return "无";
+  }
+};
+onMounted(() => {
+  getDetails();
+});
+</script>
+
+<template>
+  <div class="ElectronicCase">
+    <div class="ele_case_main">
+      <div class="top">
+        <div class="title">电子病历</div>
+        <div class="top_list">
+          <div class="top_list_item">
+            {{ `问诊编号:${baseInfo.processNo}` }}
+          </div>
+          <div class="top_list_item">
+            {{ `病案号:${baseInfo.medicalRecNo}` }}
+          </div>
+          <div class="top_list_item">
+            {{ `首诊时间:${baseInfo.createTime}` }}
+          </div>
+        </div>
+      </div>
+      <el-form
+        ref="ruleFormRef"
+        :model="baseInfo"
+        class="main_form"
+        label-width="70px"
+      >
+        <div class="basicInfo">
+          <el-row>
+            <el-col :span="8">
+              <el-form-item label="姓名">
+                <span>{{ baseInfo.patientName }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="性别">
+                <span>{{ baseInfo.patientGender }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="年龄">
+                <span>{{ baseInfo.patientAge }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="8">
+              <el-form-item label="婚姻状况">
+                <span>{{ baseInfo.patientMarriage }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="职业">
+                <span>{{ baseInfo.patientProfession }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item v-show="showFlag" label="电话">
+                <span>{{ baseInfo.patientPhone }}</span>
+              </el-form-item>
+              <!-- <el-form-item v-show="!showFlag" label="更多">
+                  <el-icon color="#999999" size="14"><ArrowDown /></el-icon>
+                </el-form-item> -->
+              <div v-show="!showFlag" @click="showFlag = true" class="contract">
+                <span>更多</span>
+                <el-icon color="#999999" size="14"><ArrowDown /></el-icon>
+              </div>
+            </el-col>
+          </el-row>
+          <el-row v-show="showFlag">
+            <el-col :span="8">
+              <el-form-item label="籍贯">
+                <span>{{ baseInfo.nativePlace }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="民族">
+                <span>{{ baseInfo.patientNation }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="邮编">
+                <span>{{ baseInfo.patientPostcode }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row v-show="showFlag">
+            <el-col :span="8">
+              <el-form-item label="出生地">
+                <span>{{ baseInfo.patientBirthplace }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="现住址">
+                <span>{{ baseInfo.patientHabitation }}</span>
+              </el-form-item>
+            </el-col>
+            <div v-show="showFlag" @click="showFlag = false" class="contract">
+              <span>收起</span>
+              <el-icon color="#999999" size="14"><ArrowUp /></el-icon>
+            </div>
+          </el-row>
+        </div>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="主诉 " prop="patientSelfDesc">
+              <span>{{ formData.patientSelfDesc }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="现病史 " prop="illnessHistory">
+              <span>{{ formData.illnessHistory }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="过敏史 " prop="allergyHistoryFlag">
+              <span>{{ getText(formData.allergyHistoryFlag) }}</span>
+              <span class="ml-1" v-if="formData.allergyHistoryFlag === 1">{{
+                formData.allergyHistory
+              }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="个人史 " prop="personalHistory">
+              <span>{{ formData.personalHistory }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="家族史 " prop="familyHistoryFlag">
+              <span>{{ getText(formData.familyHistoryFlag) }}</span>
+
+              <span class="ml-1" v-if="formData.familyHistoryFlag === 1">{{
+                formData.familyHistory
+              }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="既往史 " prop="previousHistoryFlag">
+              <span>{{ getText(formData.previousHistoryFlag) }}</span>
+
+              <span class="ml-1" v-if="formData.previousHistoryFlag === 1">{{
+                formData.previousHistory
+              }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="手术史 " prop="operationHistoryFlag">
+              <span>{{ getText(formData.operationHistoryFlag) }}</span>
+              <span class="ml-1" v-if="formData.operationHistoryFlag === 1">{{
+                formData.operationHistory
+              }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ElectronicCase {
+  width: 50%;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  :deep(.el-form-item__label) {
+    font-size: 14px;
+    font-weight: 400;
+    color: #2b3f54;
+  }
+
+  .el-form-item {
+    margin-bottom: 0;
+  }
+
+  .ele_case_main {
+    padding: 24px;
+
+    .top {
+      padding-bottom: 16px;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+      .top_list {
+        display: flex;
+        justify-content: space-around;
+        font-size: 14px;
+        font-weight: 400;
+        color: #2b3f54;
+
+        .top_list_item {
+          margin-right: 48;
+        }
+      }
+    }
+
+    .main_form {
+      height: calc(100vh - 330px);
+      overflow: auto;
+    }
+
+    .basicInfo {
+      // padding-bottom: 16px;
+      margin-top: 16px;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+    }
+
+    .title {
+      margin-top: 24px;
+      margin-bottom: 24px;
+      font-size: 18px;
+      font-weight: bold;
+      color: #2b3f54;
+      text-align: center;
+    }
+  }
+
+  .contract {
+    padding: 8px 32px;
+    font-size: 14px;
+    font-weight: 400;
+    color: #999;
+    cursor: pointer;
+
+    span {
+      margin-right: 4px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConsultationReview/InspectDetail.vue b/src/views/consultation/ConsultationReview/InspectDetail.vue
new file mode 100644
index 0000000..21d9c1b
--- /dev/null
+++ b/src/views/consultation/ConsultationReview/InspectDetail.vue
@@ -0,0 +1,225 @@
+<script setup lang="ts">
+import supportIcon from "@/assets/newInquiry/support_icon.png";
+import titleIcon from "@/assets/newInquiry/title_icon.png";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import InspectIcon from "@/assets/newInquiry/inspect_icon.png";
+import { ref, watch } from "vue";
+import { onMounted } from "vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { useRoute } from "vue-router";
+import { queryAskAncillaryHistory } from "@/api/inquiry";
+import { queryDetails } from "@/api/consultation";
+defineOptions({
+  name: "InspectDetail"
+});
+const route = useRoute();
+const bodyInspectList = ref([]);
+const supportInspectList = ref([]);
+const diagnosisList = ref([]);
+const planInfo = ref({
+  userTreatmentPlanType: undefined,
+  otherTreatmentPlan: [],
+  drugTreatmentPlan: []
+});
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+watch(
+  () => useConsultationStoreHooks().bodyInspectList,
+  val => {
+    bodyInspectList.value = val;
+  }
+);
+watch(
+  () => useConsultationStoreHooks().firstInspectList,
+  val => {
+    diagnosisList.value = val;
+  }
+);
+const getAskAncillaryHistory = async () => {
+  const res: any = await queryAskAncillaryHistory({
+    processId: route.query.processId
+  });
+  supportInspectList.value = res.data;
+};
+const getPlanDetails = async () => {
+  const res: any = await queryDetails({
+    processId: route.query.processId
+  });
+
+  planInfo.value = res.data;
+};
+onMounted(() => {
+  useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+  useConsultationStoreHooks().getyAskPhysicalHistory(route.query.processId);
+  getAskAncillaryHistory();
+  getPlanDetails();
+});
+</script>
+
+<template>
+  <div class="InspectDetail">
+    <div class="header_title">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>体格检查</span>
+      </div>
+    </div>
+
+    <div class="detail_list">
+      <div
+        class="detail_list_item"
+        v-for="(item, index) in bodyInspectList"
+        :key="index"
+      >
+        <label v-if="item.locationName">{{
+          `${item.toolName} | ${item.locationName} `
+        }}</label>
+        <label v-else>{{ `${item.toolName}` }}</label>
+        <span>{{ item.result }}</span>
+      </div>
+      <div class="empty" v-if="bodyInspectList.length === 0">
+        <img :src="emptyImg" alt="" />
+        <span>暂无数据</span>
+      </div>
+    </div>
+    <div class="header_title">
+      <div class="title">
+        <img :src="supportIcon" alt="" />
+        <span>辅助检查</span>
+      </div>
+    </div>
+    <div class="detail_list">
+      <div
+        class="detail_list_item"
+        v-for="(item, index) in supportInspectList"
+        :key="index"
+      >
+        <label style="width: 180px">{{ `${item.itemName}` }}</label>
+        <span v-html="item.result" />
+      </div>
+    </div>
+    <div class="header_title">
+      <div class="title">
+        <img :src="InspectIcon" alt="" />
+        <span>最终诊断</span>
+      </div>
+    </div>
+    <div class="detail_list">
+      <div
+        class="detail_list_item"
+        v-for="(item, index) in diagnosisList"
+        :key="index"
+      >
+        <label>{{ `${item.primaryDiseaseName}` }}</label>
+        <span style="color: #00975e" v-if="item.excludeFlag === 1"
+          >【确诊】</span
+        >
+        <span style="color: #ff3429" v-else-if="item.excludeFlag === 0"
+          >【排除】</span
+        >
+        <span style="color: #ff3429" v-else>【未确定】</span>
+      </div>
+    </div>
+    <div class="header_title">
+      <div class="title">
+        <img :src="InspectIcon" alt="" />
+        <span>处置计划</span>
+      </div>
+    </div>
+    <div class="detail_list">
+      <div
+        v-if="planInfo.userTreatmentPlanType !== null"
+        class="detail_list_item"
+      >
+        <label>建议</label>
+        <span>{{
+          planInfo.userTreatmentPlanType === 1 ? "入院治疗" : "门诊治疗"
+        }}</span>
+      </div>
+      <div
+        class="detail_list_item"
+        v-for="(item, index) in planInfo.otherTreatmentPlan"
+        :key="index"
+      >
+        <label>{{ `${item.disposalPlanName}` }}</label>
+        <span>{{ item.firstMeasures }}</span>
+      </div>
+      <div
+        class="detail_list_item"
+        v-for="(item, index) in planInfo.drugTreatmentPlan"
+        :key="index"
+      >
+        <label>{{ `${item.drugName}` }}</label>
+        <span v-if="item.intervalDay !== null">{{
+          intervalDayList[item.intervalDay]?.name
+        }}</span>
+        <span v-else>{{ item.intervalHour + "小时" }}</span>
+      </div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.InspectDetail {
+  flex: 1;
+  height: calc(100vh - 170px);
+  padding: 24px;
+  margin-left: 16px;
+  overflow: auto;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .detail_list {
+    display: flex;
+    flex-direction: column;
+    margin-bottom: 24px;
+
+    .detail_list_item {
+      display: flex;
+      margin-top: 16px;
+
+      label {
+        width: 180px;
+        font-size: 14px;
+        font-weight: 400;
+        color: #2b3f54;
+      }
+
+      span {
+        flex: 1;
+        font-size: 14px;
+        font-weight: 400;
+        color: #2b3f54;
+      }
+    }
+  }
+
+  .empty {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+
+    img {
+      width: 200px;
+      height: 100px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/ConsultationReview/index.vue b/src/views/consultation/ConsultationReview/index.vue
new file mode 100644
index 0000000..fee6061
--- /dev/null
+++ b/src/views/consultation/ConsultationReview/index.vue
@@ -0,0 +1,21 @@
+<script setup lang="ts">
+import ElectronicCase from "./ElectronicCase.vue";
+import InspectDetail from "./InspectDetail.vue";
+defineOptions({
+  name: "ConsultationReview"
+});
+</script>
+
+<template>
+  <div class="ConsultationReview">
+    <ElectronicCase />
+    <InspectDetail />
+  </div>
+</template>
+<style lang="scss" scoped>
+.ConsultationReview {
+  display: flex;
+  height: 100%;
+  padding: 40px;
+}
+</style>
diff --git a/src/views/consultation/Evaluate/AssessmentDetails.vue b/src/views/consultation/Evaluate/AssessmentDetails.vue
new file mode 100644
index 0000000..5d1f7d8
--- /dev/null
+++ b/src/views/consultation/Evaluate/AssessmentDetails.vue
@@ -0,0 +1,631 @@
+<script setup lang="ts">
+import { queryDiagnosisResult } from "@/api/inquiry";
+import { nextTick, onMounted, reactive, ref } from "vue";
+import { ArrowRight, ArrowDown, DArrowRight } from "@element-plus/icons-vue";
+import tipIcon from "@/assets/inquiry/tip.png";
+import titleIcon from "@/assets/newInquiry/title_icon.png";
+import CheckIcon from "@/assets/svg/consultation/check.svg?component";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "AssessmentDetails"
+});
+const showList = ref(["1", "1", "1", "1", "1", "1", "1"]);
+const showFlag = index => {
+  return showList.value[index] === "1" ? true : false;
+};
+const state = reactive({
+  dataInfo: undefined
+});
+const route = useRoute();
+const activedIndex = ref(0);
+const contentRef = ref(null);
+const scrollTop = ref(0);
+const navList = ref([
+  { id: "section1", title: "评分概述" },
+  { id: "section2", title: "预期诊断结果" },
+  { id: "section3", title: "初步诊断依据" },
+  { id: "section4", title: "证实诊断依据" },
+  { id: "section5", title: "鉴别依据" },
+  // { id: "section6", title: "全面检查" },
+  { id: "section7", title: "处置方案" }
+]);
+const onScroll = e => {
+  // 获取所有锚点元素
+  const navContents = document.querySelectorAll(".content .content_item");
+  // 所有锚点元素的 offsetTop
+  const offsetTopArr = [];
+  navContents.forEach((item: any) => {
+    offsetTopArr.push(item.offsetTop);
+  });
+  // 获取当前文档流的 scrollTop
+  scrollTop.value = e.scrollTop;
+  // 定义当前点亮的导航下标
+  // let navIndex = 0;
+  for (let n = 0; n < offsetTopArr.length; n++) {
+    // 如果 scrollTop 大于等于第n个元素的 offsetTop 则说明 n-1 的内容已经完全不可见
+    // 那么此时导航索引就应该是n了
+    if (scrollTop.value >= offsetTopArr[n]) {
+      // navIndex = n;
+    }
+  }
+  // activedIndex.value = navIndex;
+};
+// 跳转到指定索引的元素
+function scrollTo(index) {
+  // 获取目标的 offsetTop
+  // css选择器是从 1 开始计数,我们是从 0 开始,所以要 +1
+  const targetOffsetTop = document.querySelector(
+    `.content .content_item:nth-child(${index + 1})`
+  ).offsetTop;
+  // 获取当前 offsetTop
+
+  // 定义一次跳 50 个像素,数字越大跳得越快,但是会有掉帧得感觉,步子迈大了会扯到蛋
+  const STEP = 50;
+  // 判断是往下滑还是往上滑
+  if (scrollTop.value > targetOffsetTop) {
+    // 往上滑
+    smoothUp();
+  } else {
+    // 往下滑
+    smoothDown();
+  }
+  // 定义往下滑函数
+  function smoothDown() {
+    // 如果当前 scrollTop 小于 targetOffsetTop 说明视口还没滑到指定位置
+    if (scrollTop.value < targetOffsetTop) {
+      // 如果和目标相差距离大于等于 STEP 就跳 STEP
+      // 否则直接跳到目标点,目标是为了防止跳过了。
+      if (targetOffsetTop - scrollTop.value >= STEP) {
+        scrollTop.value += STEP;
+      } else {
+        scrollTop.value = targetOffsetTop;
+      }
+      contentRef.value.setScrollTop(scrollTop.value);
+      // 关于 requestAnimationFrame 可以自己查一下,在这种场景下,相比 setInterval 性价比更高
+      requestAnimationFrame(smoothDown);
+    }
+  }
+  // 定义往上滑函数
+  function smoothUp() {
+    if (scrollTop.value > targetOffsetTop) {
+      if (scrollTop.value - targetOffsetTop >= STEP) {
+        scrollTop.value -= STEP;
+      } else {
+        scrollTop.value = targetOffsetTop;
+      }
+      contentRef.value.setScrollTop(scrollTop.value);
+      requestAnimationFrame(smoothUp);
+    }
+  }
+  activedIndex.value = index;
+}
+const showDetail = index => {
+  if (showList.value[index] === "0") {
+    showList.value[index] = "1";
+  } else {
+    showList.value[index] = "0";
+  }
+};
+const getDetails = async () => {
+  const { data } = await queryDiagnosisResult({
+    processId: route.query.processId
+  });
+  state.dataInfo = data;
+};
+const drugRouteList = [
+  {
+    id: 0,
+    name: "口服"
+  },
+  {
+    id: 1,
+    name: "静脉注射"
+  },
+  {
+    id: 2,
+    name: "静脉输液"
+  },
+  {
+    id: 3,
+    name: "皮下注射"
+  },
+  {
+    id: 4,
+    name: "局部用药"
+  },
+  {
+    id: 5,
+    name: "气雾剂/粉雾剂吸入"
+  },
+  {
+    id: 6,
+    name: "雾化吸入"
+  },
+  {
+    id: 7,
+    name: "鞘内注射"
+  }
+];
+const columns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlanName"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+  {
+    label: "说明",
+    prop: "guide"
+  }
+];
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const drugColumns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlanName"
+  },
+  {
+    label: "药物名称",
+    prop: "drugName"
+  },
+  {
+    label: "用药途径",
+    formatter: ({ drugRoute }) => `${drugRouteList[drugRoute]?.name || ""}`
+  },
+  {
+    label: "用药间隔",
+    prop: "select",
+    formatter: ({ intervalDay, intervalHour }) => {
+      return intervalDay !== null
+        ? intervalDayList[intervalDay]?.name
+        : `${intervalHour}小时`;
+    }
+  },
+  {
+    label: "说明",
+    prop: "guide"
+  }
+];
+onMounted(() => {
+  nextTick(() => {
+    getDetails();
+    // document.addEventListener("scroll", onScroll, true);
+  });
+});
+</script>
+
+<template>
+  <div class="AssessmentDetails">
+    <div class="nav_card">
+      <div
+        class="nav_card_item"
+        @click="scrollTo(index)"
+        :class="[activedIndex === index ? 'actived' : '']"
+        v-for="(item, index) in navList"
+        :key="index"
+      >
+        <el-icon><DArrowRight /></el-icon>
+        <span>{{ item.title }}</span>
+      </div>
+    </div>
+    <el-scrollbar
+      v-if="state.dataInfo"
+      @scroll="onScroll"
+      class="content"
+      ref="contentRef"
+    >
+      <div class="content_item">
+        <div @click="showDetail(0)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>评分概述</span>
+          </div>
+          <el-icon v-show="!showFlag(0)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(0)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+        <div v-show="showFlag(0)" class="evaluate_desc evaluate_content">
+          <div class="evaluate_desc_title">
+            <img :src="tipIcon" alt="" />
+            <span
+              >该初步评估提供了有关您对病历进行诊治的信息,评估类别旁将标记√为本次诊断成功完成的任务。
+            </span>
+          </div>
+          <!-- <div class="evaluate_text">评估类别:预期诊断结果/初步诊断</div> -->
+        </div>
+      </div>
+      <div class="content_item">
+        <div @click="showDetail(1)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>预期诊断结果</span>
+          </div>
+          <el-icon v-show="!showFlag(1)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(1)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+        <div
+          v-show="showFlag(1)"
+          class="expertDiagnosisResult evaluate_content"
+        >
+          <el-row class="evaluate_text">
+            {{ `正确诊断:${state.dataInfo.expertDiagnosisResult.diagnosis} ` }}
+          </el-row>
+          <el-row style="margin-top: 16px">您的诊断结果:</el-row>
+          <div class="userDiagnosisResult">
+            <div
+              class="mb-4 userDiagnosisResult_item"
+              v-for="(item, index) in state.dataInfo.expertDiagnosisResult
+                .userDiagnosisResult"
+              :key="index"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.diseaseName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.diseaseName }}</span>
+              </div>
+            </div>
+          </div>
+          <el-row style="margin-top: 16px">预期初诊诊断列表:</el-row>
+          <div
+            class="userDiagnosisResult"
+            v-for="(item, index) in state.dataInfo.expertDiagnosisResult
+              .expertDiagnosisResult"
+            :key="index"
+          >
+            {{ item.diseaseName }}
+          </div>
+        </div>
+      </div>
+      <div class="content_item">
+        <div @click="showDetail(2)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>初步诊断依据</span>
+          </div>
+          <el-icon v-show="!showFlag(2)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(2)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+        <div class="evaluate_content" v-show="showFlag(2)">
+          <div>证实或排除初步诊断的必须项目:</div>
+          <div class="userDiagnosisResult">
+            <div
+              v-for="(item, index) in state.dataInfo.basisPrimaryResultResVO
+                .nodeList"
+              :key="index"
+              class="mb-4 userDiagnosisResult_item"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.recordName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.recordName }}</span>
+              </div>
+            </div>
+          </div>
+          <div
+            class="desc"
+            v-html="state.dataInfo.basisPrimaryResultResVO.preliminaryDiagnosis"
+          />
+        </div>
+      </div>
+      <div class="content_item">
+        <div @click="showDetail(3)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>证实诊断依据</span>
+          </div>
+          <el-icon v-show="!showFlag(3)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(3)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+        <div class="evaluate_content" v-show="showFlag(3)">
+          <div>证实或排除初步诊断的必须项目:</div>
+          <div class="userDiagnosisResult">
+            <div
+              v-for="(item, index) in state.dataInfo.basisConfirmResultResVO
+                .nodeList"
+              :key="index"
+              class="mb-4 userDiagnosisResult_item"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.recordName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.recordName }}</span>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div
+          class="desc"
+          v-html="state.dataInfo.basisConfirmResultResVO.confirmingDiagnosis"
+        />
+      </div>
+      <div class="content_item">
+        <div @click="showDetail(4)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>鉴别依据</span>
+          </div>
+          <el-icon v-show="!showFlag(4)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(4)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+        <div class="evaluate_content" v-show="showFlag(4)">
+          <div>鉴别依据所必须的项目:</div>
+          <div class="userDiagnosisResult">
+            <div
+              v-for="(item, index) in state.dataInfo.basisIdentificationResult
+                .nodeList"
+              :key="index"
+              class="mb-4 userDiagnosisResult_item"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.recordName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.recordName }}</span>
+              </div>
+            </div>
+          </div>
+          <div
+            class="desc"
+            v-html="
+              state.dataInfo.basisIdentificationResult.identificationDiagnosis
+            "
+          />
+        </div>
+      </div>
+      <!-- <div class="content_item">
+        <div @click="showDetail(5)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>全面检查</span>
+          </div>
+          <el-icon v-show="!showFlag(5)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(5)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+      </div> -->
+      <div class="content_item">
+        <div @click="showDetail(6)" class="header">
+          <div class="title">
+            <img :src="titleIcon" alt="" />
+            <span>处置方案</span>
+          </div>
+          <el-icon v-show="!showFlag(6)" color="#2B3F54" size="14"
+            ><ArrowRight
+          /></el-icon>
+          <el-icon v-show="showFlag(6)" color="#2B3F54" size="14"
+            ><ArrowDown
+          /></el-icon>
+        </div>
+        <div
+          class="evaluate_content"
+          style="background-color: #fff"
+          v-show="showFlag(6)"
+        >
+          <div class="plan_list">
+            <pure-table
+              border
+              align-whole="center"
+              style="width: 100%"
+              showOverflowTooltip
+              class="mt-4"
+              :data="state.dataInfo.dealPlan.otherTreatmentPlan"
+              :columns="columns"
+              :header-cell-style="{
+                background: 'var(--el-table-row-hover-bg-color)',
+                color: 'var(--el-text-color-primary)'
+              }"
+            />
+            <pure-table
+              border
+              align-whole="center"
+              showOverflowTooltip
+              class="mt-4"
+              style="width: 100%"
+              :data="state.dataInfo.dealPlan.drugTreatmentPlan"
+              :columns="drugColumns"
+              :header-cell-style="{
+                background: 'var(--el-table-row-hover-bg-color)',
+                color: 'var(--el-text-color-primary)'
+              }"
+            />
+          </div>
+        </div>
+      </div>
+    </el-scrollbar>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AssessmentDetails {
+  display: flex;
+  flex-direction: row-reverse;
+  height: 100%;
+
+  .nav_card {
+    display: flex;
+    flex-direction: column;
+    width: 218px;
+    height: calc(100vh - 250px);
+    padding: 32px;
+    background: #fff;
+    border-radius: 6px;
+    box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+    .nav_card_item {
+      display: flex;
+      align-items: center;
+      margin-bottom: 24px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #2b3f54;
+      cursor: pointer;
+
+      span {
+        margin-left: 8px;
+      }
+    }
+
+    .actived {
+      font-weight: bold;
+      color: #4287ff;
+    }
+  }
+
+  .content {
+    flex: 1;
+    height: calc(100vh - 250px);
+    margin-right: 16px;
+    overflow-y: auto;
+
+    .desc {
+      margin-top: 16px;
+      font-size: 12px;
+      font-weight: 400;
+      color: #2b3f54;
+    }
+
+    .header {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      margin-top: 24px;
+      cursor: pointer;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+      .title {
+        display: flex;
+        padding-bottom: 8px;
+        font-size: 16px;
+        font-weight: bold;
+        color: #2b3f54;
+        border-bottom: 4px solid #4287ff;
+
+        img {
+          width: 20px;
+          height: 20px;
+          margin-right: 8px;
+        }
+      }
+    }
+
+    .evaluate_content {
+      padding: 16px;
+      margin-top: 8px;
+      background: rgb(91 139 255 / 5%);
+    }
+
+    .evaluate_text {
+      font-size: 14px;
+      font-weight: 400;
+      color: #364c63;
+    }
+
+    .evaluate_desc {
+      .evaluate_desc_title {
+        display: flex;
+        height: 32px;
+
+        img {
+          width: 20px;
+          height: 20px;
+        }
+
+        span {
+          margin-left: 8px;
+          font-size: 12px;
+          font-weight: 400;
+          color: #4287ff;
+        }
+      }
+    }
+
+    .userDiagnosisResult {
+      display: flex;
+      flex-wrap: wrap;
+      width: 100%;
+      padding: 16px;
+      margin-top: 8px;
+      border: 1px solid rgb(66 135 255 / 30%);
+      border-radius: 6px;
+
+      .userDiagnosisResult_item {
+        width: 50%;
+      }
+
+      .correct {
+        display: flex;
+        font-size: 14px;
+        font-weight: 400;
+        color: #0db274;
+      }
+
+      .error {
+        padding-left: 25px;
+        font-size: 14px;
+        font-weight: 400;
+        color: #2b3f54;
+      }
+
+      .value {
+        font-size: 14px;
+        font-weight: 400;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/Evaluate/InspectHistory.vue b/src/views/consultation/Evaluate/InspectHistory.vue
new file mode 100644
index 0000000..476e979
--- /dev/null
+++ b/src/views/consultation/Evaluate/InspectHistory.vue
@@ -0,0 +1,175 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { queryHistoryList } from "@/api/inquiry";
+import { onMounted } from "vue";
+import CheckIcon from "@/assets/svg/consultation/check.svg?component";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "InspectHistory"
+});
+const recordList = ref([]);
+const route = useRoute();
+const activedIndex = ref<any>("");
+const selectInfo = reactive({
+  question: "",
+  answer: ""
+});
+const getHistory = async () => {
+  const res: any = await queryHistoryList({
+    processId: route.query.processId,
+    pageSize: pagination.pageSize,
+    pageNum: pagination.currentPage
+  });
+  pagination.total = res.data.total;
+  recordList.value = res.data.records;
+};
+const selectItem = (item: any, index) => {
+  selectInfo.question = item.question;
+  selectInfo.answer = item.answer;
+  activedIndex.value = index;
+};
+const pagination = reactive<any>({
+  total: 0,
+  pageSize: 15,
+  currentPage: 1
+});
+const handleUserChange = val => {
+  pagination.currentPage = val;
+  getHistory();
+};
+onMounted(() => {
+  getHistory();
+});
+</script>
+
+<template>
+  <div class="InspectHistory">
+    <div class="record_list">
+      <div
+        class="record_list_item"
+        :class="[activedIndex === index ? 'actived' : '']"
+        v-for="(item, index) in recordList"
+        :key="index"
+        @click="selectItem(item, index)"
+      >
+        <div
+          :class="[item.answerType === 'patient' ? 'check' : '']"
+          class="title"
+        >
+          <span class="type">{{ item.commonDic?.nameZh || "系统状态" }}</span>
+          <span class="name">{{ item.question }}</span>
+          <CheckIcon v-show="item.answerType === 'patient'" class="icon" />
+        </div>
+        <div class="answer">{{ item.answer }}</div>
+        <div class="time">{{ item.createTime }}</div>
+      </div>
+      <div v-if="recordList.length === 0">暂无数据</div>
+    </div>
+    <div class="page_footer">
+      <el-pagination
+        @current-change="handleUserChange"
+        :hide-on-single-page="true"
+        background
+        :default-page-size="15"
+        layout="prev, pager, next"
+        :total="pagination.total"
+        class="mt-4"
+      />
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.InspectHistory {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  background: #fff;
+
+  .record_list {
+    display: flex;
+    flex-direction: column;
+    height: calc(100vh - 330px);
+    padding: 8px;
+    overflow-y: auto;
+
+    .record_list_item {
+      position: relative;
+      padding-left: 24px;
+      margin: 8px 0;
+      // height: 115px;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+      .title {
+        position: relative;
+        display: flex;
+        align-items: center;
+        margin-bottom: 12px;
+        font-size: 14px;
+
+        .type {
+          padding: 2px 8px;
+          margin-right: 8px;
+          color: #fff;
+          background: #4287ff;
+          border-radius: 6px;
+        }
+
+        .name {
+          font-size: 14px;
+          font-weight: bold;
+          color: #2b3f54;
+        }
+
+        .icon {
+          position: absolute;
+          left: -24px;
+        }
+      }
+
+      .check {
+        .type {
+          padding: 2px 8px;
+          margin-right: 8px;
+          color: #fff;
+          background: #00975e;
+          border-radius: 6px;
+        }
+
+        .name {
+          font-size: 14px;
+          font-weight: bold;
+          color: #00975e;
+        }
+      }
+
+      .answer {
+        margin-bottom: 16px;
+        font-size: 14px;
+        font-weight: 400;
+        color: #2b3f54;
+      }
+
+      .time {
+        margin-bottom: 16px;
+        font-size: 10px;
+        font-weight: 400;
+        color: #2b3f54;
+      }
+    }
+
+    .record_list_item:hover {
+      color: #1890ff;
+    }
+
+    .actived {
+      color: #1890ff;
+    }
+  }
+
+  .page_footer {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+}
+</style>
diff --git a/src/views/consultation/Evaluate/index.vue b/src/views/consultation/Evaluate/index.vue
new file mode 100644
index 0000000..9c1d716
--- /dev/null
+++ b/src/views/consultation/Evaluate/index.vue
@@ -0,0 +1,110 @@
+<script setup lang="ts">
+import AssessmentDetails from "./AssessmentDetails.vue";
+import InspectHistory from "./InspectHistory.vue";
+import { ref } from "vue";
+
+defineOptions({
+  name: "Evaluate"
+});
+const activedKey = ref(0);
+const changeTab = val => {
+  activedKey.value = val;
+};
+</script>
+
+<template>
+  <div class="Evaluate">
+    <div class="tab_list">
+      <div
+        @click="changeTab(0)"
+        class="tab_list_item"
+        :class="[activedKey === 0 ? 'actived' : '']"
+      >
+        <div class="content">
+          <div class="tab_eva_img tab_img" />
+          <span>评估详情</span>
+        </div>
+      </div>
+      <div
+        @click="changeTab(1)"
+        class="tab_list_item"
+        :class="[activedKey === 1 ? 'actived' : '']"
+      >
+        <div class="content">
+          <div class="tab_hisory_img tab_img" />
+          <span>问诊历史</span>
+        </div>
+      </div>
+    </div>
+    <AssessmentDetails v-show="activedKey === 0" />
+    <InspectHistory v-show="activedKey === 1" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.Evaluate {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  padding: 40px;
+
+  .tab_list {
+    display: flex;
+    margin-top: 12px;
+    margin-bottom: 24px;
+
+    .tab_list_item {
+      width: 300px;
+      height: 0;
+      margin-right: 6px;
+      font-size: 18px;
+      font-weight: bold;
+      color: #4287ff;
+      cursor: pointer;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid rgb(66 135 255 / 15%);
+      border-left: 20px solid transparent;
+      border-radius: 6px;
+
+      .content {
+        position: relative;
+        top: 12px;
+        right: 21px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 300px;
+      }
+
+      .tab_img {
+        width: 20px;
+        height: 20px;
+        margin-right: 12px;
+        background-size: 100% 100%;
+      }
+
+      .tab_eva_img {
+        background-image: url("../../../assets/newInquiry/tab/ev_detail.png");
+      }
+    }
+
+    .actived {
+      color: #fff;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid #4287ff;
+      border-left: 20px solid transparent;
+    }
+
+    .tab_hisory_img {
+      background-image: url("../../../assets/newInquiry/tab/history_icon.png");
+    }
+
+    .actived .tab_hisory_img {
+      background-image: url("../../../assets/newInquiry/tab/act_history_icon.png");
+    }
+
+    .actived .tab_eva_img {
+      background-image: url("../../../assets/newInquiry/tab/act_ev_detai.png");
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/BodyList.vue b/src/views/consultation/FirstConsultation/BodyInspect/BodyList.vue
new file mode 100644
index 0000000..9c39ee0
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/BodyList.vue
@@ -0,0 +1,264 @@
+<script setup lang="ts">
+import { queryPhysicalToolList } from "@/api/inquiry";
+import { computed, onMounted, ref } from "vue";
+import { ArrowRight, ArrowDown } from "@element-plus/icons-vue";
+import titleIcon from "@/assets/newInquiry/body_title.png";
+import viewIcon from "@/assets/newInquiry/view_icon.png";
+import spiritIcon from "@/assets/newInquiry/spirit_icon.png";
+import workIcon from "@/assets/newInquiry/work_icon.png";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "BodyList"
+});
+const dataList = ref([]);
+const showList = ref(["1", "0", "0", "0"]);
+const activedId = ref("");
+const emit = defineEmits(["selectTool"]);
+const activedToolName = computed(() => {
+  return useConsultationStoreHooks().selectToolInfo.toolName;
+});
+const showDetail = index => {
+  if (showList.value[index] === "0") {
+    showList.value[index] = "1";
+  } else {
+    showList.value[index] = "0";
+  }
+};
+const selectOne = (item: any) => {
+  useConsultationStoreHooks().changeSelectToolInfo({
+    toolName: item.toolName,
+    img: item.iconBase64,
+    id: item.id,
+    requireLocation: item.requireLocation
+  });
+
+  emit("selectTool", item);
+};
+const selectOtherOne = (item: any) => {
+  useConsultationStoreHooks().changeSelectToolInfo({
+    toolName: "",
+    img: "",
+    id: item.id,
+    requireLocation: item.requireLocation
+  });
+  activedId.value = item.id;
+  emit("selectTool", item);
+};
+onMounted(async () => {
+  const res: any = await queryPhysicalToolList();
+  dataList.value = res.data;
+});
+</script>
+
+<template>
+  <div class="BodyList">
+    <div
+      v-for="(item, index) in dataList"
+      :key="index"
+      class="body_inspect_item"
+    >
+      <div @click="showDetail(index)" class="header">
+        <div class="title">
+          <img v-if="index === 0" :src="titleIcon" alt="" />
+          <img v-if="index === 1" :src="viewIcon" alt="" />
+          <img v-if="index === 2" :src="workIcon" alt="" />
+          <img v-if="index === 3" :src="spiritIcon" alt="" />
+          <span>{{ item.toolType }}</span>
+        </div>
+        <el-icon v-if="showList[index] === '0'" color="#2B3F54" size="14"
+          ><ArrowRight
+        /></el-icon>
+        <el-icon v-if="showList[index] === '1'" color="#2B3F54" size="14"
+          ><ArrowDown
+        /></el-icon>
+      </div>
+      <div
+        class="list"
+        v-if="item.toolType === '采集生命体征'"
+        v-show="showList[index] === '1'"
+      >
+        <div
+          @click="selectOne(items)"
+          class="list_item"
+          :class="[items.toolName === activedToolName ? 'actived' : '']"
+          v-for="(items, itemIndex) in item.toolList"
+          :key="itemIndex"
+        >
+          <img class="icon" :src="items.iconBase64" alt="" />
+          <el-tooltip
+            effect="dark"
+            :content="items.toolName"
+            placement="top-start"
+            ><div class="name">
+              {{ items.toolName.substring(0, 4) }}
+            </div></el-tooltip
+          >
+        </div>
+      </div>
+      <div
+        class="other_list"
+        v-if="item.toolType !== '采集生命体征'"
+        v-show="showList[index] === '1'"
+      >
+        <div
+          class="other_list_item"
+          :class="[items.toolName === activedToolName ? 'actived' : '']"
+          v-for="(items, itemIndex) in item.toolList"
+          :key="itemIndex"
+          @click="selectOtherOne(items)"
+        >
+          <div class="name">{{ items.toolName }}</div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.BodyList {
+  display: flex;
+  flex-direction: column;
+  width: 390px;
+  // height: calc(100vh - 200px);
+  padding: 16px;
+  overflow-y: auto;
+  background: rgb(66 135 255 / 5%);
+  border-radius: 6px;
+
+  .body_inspect_item {
+    margin-bottom: 24px;
+
+    .header {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      cursor: pointer;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+      .title {
+        display: flex;
+        padding-bottom: 8px;
+        font-size: 16px;
+        font-weight: bold;
+        color: #2b3f54;
+        border-bottom: 4px solid #4287ff;
+
+        img {
+          width: 20px;
+          height: 20px;
+          margin-right: 8px;
+          background-size: 100% 100%;
+        }
+      }
+    }
+
+    .list {
+      display: flex;
+      flex-wrap: wrap;
+      padding: 16px 8px 16px 16px;
+      margin-top: 8px;
+      background: rgb(91 139 255 / 5%);
+      background-color: unset;
+
+      .list_item {
+        width: calc(25% - 8px); /* 计算每个项目的宽度,减去间距 */
+        height: 94px;
+        padding: 8px;
+        margin-right: 8px;
+        margin-bottom: 8px;
+        cursor: pointer;
+        background: rgb(255 255 255 / 30%);
+        border: 1px solid #fff;
+        border-radius: 4px;
+        opacity: 1;
+
+        .icon {
+          width: 58px;
+          height: 58px;
+          background: #fff;
+          border-radius: 6px;
+        }
+
+        .name {
+          margin-top: 4px;
+          font-size: 12px;
+          font-weight: 400;
+          color: #4287ff;
+          text-align: center;
+        }
+      }
+
+      .list_item:hover {
+        background: #4287ff;
+        border: 1px solid rgb(66 135 255 / 50%);
+
+        .name {
+          color: #fff;
+        }
+      }
+
+      .btn:hover {
+        color: #295889;
+      }
+
+      .actived {
+        background: #4287ff;
+        border: 1px solid rgb(66 135 255 / 50%);
+
+        .name {
+          color: #fff;
+        }
+      }
+    }
+
+    .other_list {
+      display: flex;
+      flex-wrap: wrap;
+
+      .other_list_item {
+        width: calc(33.33% - 8px); /* 计算每个项目的宽度,减去间距 */
+        height: 34px;
+        margin: 8px 8px 0 0;
+        line-height: 34px;
+        text-align: center;
+        cursor: pointer;
+        background: rgb(66 135 255 / 10%);
+        border-radius: 4px;
+
+        .name {
+          overflow: hidden;
+          font-size: 12px;
+          font-weight: 400;
+          color: #4287ff;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+        }
+      }
+
+      .actived {
+        background: #4287ff;
+
+        .name {
+          color: #fff;
+        }
+      }
+
+      .other_list_item:hover {
+        background: #4287ff;
+
+        .name {
+          color: #fff;
+        }
+      }
+    }
+  }
+}
+
+/* 隐藏滚动条(适用于WebKit浏览器,如Chrome和Safari) */
+.BodyList::-webkit-scrollbar {
+  width: 0; /* 设置滚动条宽度 */
+}
+
+.BodyList::-webkit-scrollbar-thumb {
+  background-color: transparent; /* 滚动条颜色,这里设置为透明 */
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/BodyTable.vue b/src/views/consultation/FirstConsultation/BodyInspect/BodyTable.vue
new file mode 100644
index 0000000..901e992
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/BodyTable.vue
@@ -0,0 +1,21 @@
+<script setup lang="ts">
+import FirstInspectTable from "./components/FirstInspectTable.vue";
+import BodyInspectTable from "./components/BodyInspectTable.vue";
+defineOptions({
+  name: "BodyTable"
+});
+</script>
+
+<template>
+  <div class="BodyTable">
+    <FirstInspectTable />
+    <BodyInspectTable />
+  </div>
+</template>
+<style lang="scss" scoped>
+.BodyTable {
+  display: flex;
+  flex-direction: column;
+  width: 562px;
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/abdomenDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/abdomenDetails.vue
new file mode 100644
index 0000000..7742fde
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/abdomenDetails.vue
@@ -0,0 +1,105 @@
+<script setup lang="ts">
+import abdomenDetailImg from "@/assets/inquiry/people/abdomen_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "AbdomenDetails"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const chestList = ref([
+  {
+    key: "abdominal_aorta",
+    name: "腹主动脉",
+    top: 59,
+    left: 352
+  },
+  {
+    key: "right_upper_quadrant",
+    name: "右上腹",
+    top: 128,
+    left: 171
+  },
+  {
+    key: "left_upper_abdomen",
+    name: "左上腹",
+    top: 115,
+    left: 534
+  },
+  {
+    key: "right_lower_quadrant",
+    name: "右下腹",
+    top: 221,
+    left: 92
+  },
+  {
+    key: "left_lower_abdomen",
+    name: "左下腹",
+    top: 218,
+    left: 582
+  },
+  {
+    key: "right_groin",
+    name: "右腹股沟",
+    top: 458,
+    left: 99
+  },
+  {
+    key: "left_groin",
+    name: "左腹股沟",
+    top: 455,
+    left: 576
+  },
+  {
+    key: "right_hip",
+    name: "右髋",
+    top: 558,
+    left: 132
+  },
+  {
+    key: "left_hip",
+    name: "左髋",
+    top: 556,
+    left: 531
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="abdomen_detail">
+    <img class="abdomen_detail_img" :src="abdomenDetailImg" alt="" />
+    <div
+      class="abdomen_detail_item"
+      @click="inpectClick(item)"
+      :style="getPosition(item)"
+      v-for="(item, index) in chestList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.abdomen_detail {
+  position: relative;
+
+  .abdomen_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .abdomen_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/backDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/backDetails.vue
new file mode 100644
index 0000000..df4df8a
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/backDetails.vue
@@ -0,0 +1,87 @@
+<script setup lang="ts">
+import backDetailImg from "@/assets/inquiry/people/back_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "BackDetails"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const backList = ref([
+  {
+    key: "spinal_column",
+    name: "脊椎",
+    top: 63,
+    left: 386
+  },
+  {
+    key: "left_middle_back",
+    name: "左中背 ",
+    top: 176,
+    left: 98
+  },
+  {
+    key: "right_middle_back",
+    name: "右中背",
+    top: 193,
+    left: 593
+  },
+  {
+    key: "right_lower_back",
+    name: "右下背",
+    top: 460,
+    left: 597
+  },
+  {
+    key: "left_lower_back",
+    name: "左下背",
+    top: 491,
+    left: 89
+  },
+  {
+    key: "rectum",
+    name: "直肠",
+    top: 603,
+    left: 523
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="back_detail">
+    <img class="back_detail_img" :src="backDetailImg" alt="" />
+    <div
+      class="back_detail_item"
+      @click="inpectClick(item)"
+      :style="getPosition(item)"
+      v-for="(item, index) in backList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.back_detail {
+  position: relative;
+
+  .back_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .back_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/chestDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/chestDetails.vue
new file mode 100644
index 0000000..da46ee0
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/chestDetails.vue
@@ -0,0 +1,129 @@
+<script setup lang="ts">
+import chestDetailImg from "@/assets/inquiry/people/chest_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "ChestDetails"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const chestList = ref([
+  {
+    key: "neck",
+    name: "颈",
+    top: 58,
+    left: 394
+  },
+  {
+    key: "right_carotid_artery",
+    name: "右颈动脉瓣",
+    top: 114,
+    left: 201
+  },
+  {
+    key: "left_carotid_artery",
+    name: "左颈动脉瓣",
+    top: 114,
+    left: 488
+  },
+  {
+    key: "right_shoulder",
+    name: "右肩",
+    top: 192,
+    left: 89
+  },
+  {
+    key: "left_shoulder",
+    name: "左肩",
+    top: 192,
+    left: 585
+  },
+  {
+    key: "right_breast",
+    name: "右乳",
+    top: 297,
+    left: 70
+  },
+  {
+    key: "left_breast",
+    name: "左乳",
+    top: 302,
+    left: 603
+  },
+  {
+    key: "right_armpit",
+    name: "右腋窝",
+    top: 420,
+    left: 80
+  },
+  {
+    key: "left_axillary_fossa",
+    name: "左腋窝",
+    top: 409,
+    left: 596
+  },
+  {
+    key: "pulmonary_valve",
+    name: "肺动脉瓣",
+    top: 521,
+    left: 116
+  },
+  {
+    key: "aortic_valve",
+    name: "主动脉瓣",
+    top: 513,
+    left: 550
+  },
+  {
+    key: "mitral_valve",
+    name: "二尖瓣",
+    top: 601,
+    left: 222
+  },
+  {
+    key: "tricuspid_valve",
+    name: "三尖瓣",
+    top: 609,
+    left: 514
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="chest_detail">
+    <img class="chest_detail_img" :src="chestDetailImg" alt="" />
+    <div
+      class="chest_detail_item"
+      @click="inpectClick(item)"
+      :style="getPosition(item)"
+      v-for="(item, index) in chestList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.chest_detail {
+  position: relative;
+
+  .chest_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .chest_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/headerDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/headerDetails.vue
new file mode 100644
index 0000000..46dfa5d
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/headerDetails.vue
@@ -0,0 +1,111 @@
+<script setup lang="ts">
+import headerDetailImg from "@/assets/inquiry/people/header_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "HeaderDetails"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const headerList = ref([
+  {
+    key: "scalp",
+    name: "头皮",
+    top: 59,
+    left: 335
+  },
+  {
+    key: "left_eye",
+    name: "左眼",
+    top: 109,
+    left: 495
+  },
+  {
+    key: "right_eye",
+    name: "右眼",
+    top: 140,
+    left: 115
+  },
+  {
+    key: "the_left_ear",
+    name: "左耳",
+    top: 232,
+    left: 586
+  },
+  {
+    key: "right_ear",
+    name: "右耳",
+    top: 244,
+    left: 74
+  },
+  {
+    key: "the_nose",
+    name: "鼻子",
+    top: 370,
+    left: 68
+  },
+  {
+    key: "mouth",
+    name: "口",
+    top: 395,
+    left: 604
+  },
+  {
+    key: "right_side_of_face",
+    name: "右侧面部",
+    top: 477,
+    left: 115
+  },
+  {
+    key: "left_side_of_face",
+    name: "左侧面部",
+    top: 544,
+    left: 502
+  },
+  {
+    key: "lower_jaw",
+    name: "下颌",
+    top: 593,
+    left: 169
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="header_detail">
+    <img class="header_detail_img" :src="headerDetailImg" alt="" />
+    <div
+      @click="inpectClick(item)"
+      class="header_detail_item"
+      :style="getPosition(item)"
+      v-for="(item, index) in headerList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.header_detail {
+  position: relative;
+
+  .header_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .header_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/index.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/index.vue
new file mode 100644
index 0000000..44b390f
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/index.vue
@@ -0,0 +1,64 @@
+<script setup lang="ts">
+import HeaderDetails from "./headerDetails.vue";
+import ChestDetails from "./chestDetails.vue";
+import AbdomenDetails from "./abdomenDetails.vue";
+import LeftHandDetails from "./leftHandDetails.vue";
+import RightHandDetails from "./rightHandDetails.vue";
+import BackDetails from "./backDetails.vue";
+import LeftLegDetail from "./leftLegDetails.vue";
+import RightLegDetail from "./rightLegDetails.vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "PositionDetails"
+});
+const useConsultationStore = useConsultationStoreHooks();
+const emit = defineEmits(["selectPostion"]);
+const selectPostion = val => {
+  emit("selectPostion", val);
+};
+</script>
+
+<template>
+  <div class="positionDetails">
+    <HeaderDetails
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'header'"
+    />
+    <ChestDetails
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'chest'"
+    />
+    <AbdomenDetails
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'abdomen'"
+    />
+    <LeftHandDetails
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'left_hand'"
+    />
+    <RightHandDetails
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'right_hand'"
+    />
+    <BackDetails
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'back'"
+    />
+    <LeftLegDetail
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'left_leg'"
+    />
+    <RightLegDetail
+      @selectPostion="selectPostion"
+      v-show="useConsultationStore.bodyPositionType === 'right_leg'"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.positionDetails {
+  position: relative;
+  width: 720px;
+  height: 790px;
+  margin-left: 20px;
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/leftHandDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/leftHandDetails.vue
new file mode 100644
index 0000000..84e3b8f
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/leftHandDetails.vue
@@ -0,0 +1,81 @@
+<script setup lang="ts">
+import leftHandDetailsImg from "@/assets/inquiry/people/left_hand_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "leftHandDetails"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const chestList = ref([
+  {
+    key: "left_elbow",
+    name: "左肘",
+    top: 60,
+    left: 349
+  },
+  {
+    key: "left_arm",
+    name: "左臂",
+    top: 218,
+    left: 68
+  },
+  {
+    key: "left_wrist",
+    name: "左腕",
+    top: 217,
+    left: 605
+  },
+  {
+    key: "left_forearm",
+    name: "左前臂",
+    top: 535,
+    left: 119
+  },
+  {
+    key: "left_hand",
+    name: "左手",
+    top: 525,
+    left: 599
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="leftHand_detail">
+    <img class="leftHand_detail_img" :src="leftHandDetailsImg" alt="" />
+    <div
+      class="leftHand_detail_item"
+      :style="getPosition(item)"
+      @click="inpectClick(item)"
+      v-for="(item, index) in chestList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.leftHand_detail {
+  position: relative;
+
+  .leftHand_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .leftHand_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/leftLegDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/leftLegDetails.vue
new file mode 100644
index 0000000..20803bd
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/leftLegDetails.vue
@@ -0,0 +1,82 @@
+<script setup lang="ts">
+import leftLegDetailImg from "@/assets/inquiry/people/left_leg_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "LeftLegDetail"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const leftLegList = ref([
+  {
+    key: "left_thigh",
+    name: "左大腿",
+    top: 135,
+    left: 540
+  },
+  {
+    key: "left_lower_leg",
+    name: "左小腿",
+    top: 223,
+    left: 94
+  },
+  {
+    key: "left_knee",
+    name: "左膝",
+    top: 287,
+    left: 603
+  },
+
+  {
+    key: "left_ankle",
+    name: "左踝",
+    top: 473,
+    left: 87
+  },
+  {
+    key: "left_foot",
+    name: "左足",
+    top: 499,
+    left: 569
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="left_leg_detail">
+    <img class="left_leg_detail_img" :src="leftLegDetailImg" alt="" />
+    <div
+      class="left_leg_detail_item"
+      @click="inpectClick(item)"
+      :style="getPosition(item)"
+      v-for="(item, index) in leftLegList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.left_leg_detail {
+  position: relative;
+
+  .left_leg_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .left_leg_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/rightHandDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/rightHandDetails.vue
new file mode 100644
index 0000000..1fd6a02
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/rightHandDetails.vue
@@ -0,0 +1,81 @@
+<script setup lang="ts">
+import rightHandDetailsImg from "@/assets/inquiry/people/right_hand_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "RightHandDetails"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const chestList = ref([
+  {
+    key: "right_wrist",
+    name: "右腕 ",
+    top: 60,
+    left: 349
+  },
+  {
+    key: "right_hand",
+    name: "右手 ",
+    top: 218,
+    left: 68
+  },
+  {
+    key: "right_elbow",
+    name: "右肘",
+    top: 224,
+    left: 593
+  },
+  {
+    key: "right_forearm",
+    name: "右前臂",
+    top: 535,
+    left: 119
+  },
+  {
+    key: "right_arm",
+    name: "右臂",
+    top: 522,
+    left: 594
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="right_hand_detail">
+    <img class="right_hand_detail_img" :src="rightHandDetailsImg" alt="" />
+    <div
+      class="right_hand_detail_item"
+      @click="inpectClick(item)"
+      :style="getPosition(item)"
+      v-for="(item, index) in chestList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.right_hand_detail {
+  position: relative;
+
+  .right_hand_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .right_hand_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/Details/rightLegDetails.vue b/src/views/consultation/FirstConsultation/BodyInspect/Details/rightLegDetails.vue
new file mode 100644
index 0000000..832f23a
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/Details/rightLegDetails.vue
@@ -0,0 +1,82 @@
+<script setup lang="ts">
+import rightLegDetailImg from "@/assets/inquiry/people/right_leg_detail.png";
+import { computed, ref } from "vue";
+defineOptions({
+  name: "RightLegDetail"
+});
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const rightLegDetailList = ref([
+  {
+    key: "right_thigh",
+    name: "右大腿",
+    top: 135,
+    left: 540
+  },
+  {
+    key: "right_calf",
+    name: "右小腿",
+    top: 223,
+    left: 94
+  },
+  {
+    key: "right_knee",
+    name: "右膝",
+    top: 287,
+    left: 603
+  },
+
+  {
+    key: "right_ankle",
+    name: "右踝",
+    top: 473,
+    left: 87
+  },
+  {
+    key: "right_foot",
+    name: "右足",
+    top: 499,
+    left: 569
+  }
+]);
+const emit = defineEmits(["selectPostion"]);
+const inpectClick = item => {
+  emit("selectPostion", item.key);
+};
+</script>
+
+<template>
+  <div class="right_leg_detail">
+    <img class="right_leg_detail_img" :src="rightLegDetailImg" alt="" />
+    <div
+      class="right_leg_detail_item"
+      @click="inpectClick(item)"
+      :style="getPosition(item)"
+      v-for="(item, index) in rightLegDetailList"
+      :key="index"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.right_leg_detail {
+  position: relative;
+
+  .right_leg_detail_img {
+    width: 718px;
+    height: 715px;
+  }
+
+  .right_leg_detail_item {
+    position: absolute;
+    width: 45px;
+    height: 45px;
+    cursor: pointer;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/PeopleBody.vue b/src/views/consultation/FirstConsultation/BodyInspect/PeopleBody.vue
new file mode 100644
index 0000000..ad8ddf7
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/PeopleBody.vue
@@ -0,0 +1,625 @@
+<script setup lang="ts">
+import { computed, ref } from "vue";
+import headerView from "@/assets/inquiry/people/headerView.png";
+import chestView from "@/assets/inquiry/people/chestView.png";
+import abdomenView from "@/assets/inquiry/people/abdomenView.png";
+import leftHandView from "@/assets/inquiry/people/left_hand_view.png";
+import rightHandView from "@/assets/inquiry/people/right_hand_view.png";
+import PositionDetails from "./Details/index.vue";
+import wholeBodyImg from "@/assets/inquiry/people/whole_body.png";
+import bockImg from "@/assets/inquiry/people/back.png";
+import leftLegView from "@/assets/inquiry/people/left_leg_view.png";
+import rightLegView from "@/assets/inquiry/people/right_leg_view.png";
+import { ElMessage } from "element-plus";
+import { queryAskPhysicalResult } from "@/api/inquiry";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "peopleBody"
+});
+const bodyList = ref([
+  {
+    key: "head",
+    name: "头部",
+    top: 33,
+    left: 557
+  },
+  {
+    key: "neck",
+    name: "颈部",
+    top: 124,
+    left: 557
+  },
+  {
+    key: "chest",
+    name: "胸部",
+    top: 183,
+    left: 123
+  },
+  {
+    key: "left_upper_extremity",
+    toolName: "上肢(左)",
+    top: 230,
+    left: 557
+  },
+  {
+    key: "right_upper_extremity",
+    toolName: "上肢(右)",
+    top: 299,
+    left: 123
+  },
+  {
+    key: "abdomen",
+    name: "腹部",
+    top: 305,
+    left: 557
+  },
+  {
+    key: "genitals",
+    name: "生殖器",
+    top: 393,
+    left: 123
+  },
+  {
+    key: "left_lower_extremity",
+    name: "下肢(左)",
+    top: 478,
+    left: 557
+  },
+  {
+    key: "right_lower_extremity",
+    name: "下肢(右)",
+    top: 558,
+    left: 123
+  },
+  {
+    key: "right_hand",
+    name: "足部(右)",
+    top: 657,
+    left: 123
+  },
+
+  {
+    key: "left_foot",
+    name: "足部(左)",
+    top: 672,
+    left: 557
+  }
+]);
+const route = useRoute();
+const viewFlag = ref(false);
+const detailsFlag = ref(false);
+const resultFlag = ref(false);
+// const useInquiryStore = useConsultationStoreHooks();
+// const { bodyResultInfo, selectToolInfo } = useInquiryStore;
+const selectToolInfo = computed(() => {
+  return useConsultationStoreHooks().selectToolInfo;
+});
+const bodyResultInfo = computed(() => {
+  return useConsultationStoreHooks().bodyResultInfo;
+});
+
+const getPosition = computed(() => {
+  return item => {
+    return {
+      top: `${item.top}px`,
+      left: `${item.left}px`
+    };
+  };
+});
+const mouseEnterHandler = val => {
+  viewFlag.value = true;
+  useConsultationStoreHooks().changeBodyPositionType(val);
+};
+const mouseLeaveHandler = () => {
+  viewFlag.value = false;
+  useConsultationStoreHooks().changeBodyPositionType("");
+};
+const openDetails = () => {
+  detailsFlag.value = true;
+  viewFlag.value = false;
+};
+const getInspectResult = item => {
+  resultFlag.value = true;
+  // 判断是否需要点击部位
+  if (item.requireLocation === 1 && !item.key) {
+    useConsultationStoreHooks().changeBodyResultInfo({
+      name: "",
+      value: "",
+      postion: ""
+    });
+    return;
+  }
+  const params = {
+    // primaryId: useConsultationStoreHooks().firstInspectList[0].id,
+    processId: route.query.processId,
+    toolId: item.id,
+    locationCode: item.key || "",
+    primaryIdList: useConsultationStoreHooks().primaryIdList
+  };
+  queryAskPhysicalResult(params).then((res: any) => {
+    if (res.code === 200) {
+      useConsultationStoreHooks().changeBodyResultInfo({
+        name: res.data.toolName,
+        value: res.data.result,
+        postion: res.data.locationName || ""
+      });
+      useConsultationStoreHooks().getyAskPhysicalHistory(route.query.processId);
+    }
+  });
+};
+const inspectBody = (item: any) => {
+  if (!selectToolInfo.value.toolName) {
+    ElMessage({
+      message: "请选择检查工具",
+      type: "warning"
+    });
+  } else {
+    if (selectToolInfo.value.requireLocation === 1) {
+      getInspectResult({
+        id: selectToolInfo.value.id,
+        name: selectToolInfo.value.toolName,
+        key: item.key
+      });
+    }
+  }
+};
+// 打开体格检查结果
+defineExpose({
+  openResult(item) {
+    getInspectResult({
+      id: item.id,
+      name: item.toolName,
+      requireLocation: item.requireLocation,
+      key: ""
+    });
+  }
+});
+const selectPostion = val => {
+  if (!selectToolInfo.value.toolName) {
+    ElMessage({
+      message: "请选择检查工具",
+      type: "warning"
+    });
+  } else {
+    getInspectResult({
+      id: selectToolInfo.value.id,
+      name: selectToolInfo.value.toolName,
+      requireLocation: selectToolInfo.value.requireLocation,
+      key: val
+    });
+  }
+};
+//关闭结果
+// const closedCard = () => {
+//   useConsultationStoreHooks().changeBodyResultInfo({
+//     name: "",
+//     value: "",
+//     postion: ""
+//   });
+// };
+</script>
+
+<template>
+  <div class="peopleBody">
+    <div v-if="!detailsFlag" class="body">
+      <img class="body_img" src="@/assets/inquiry/renti.png" alt="" />
+      <div
+        class="body_item"
+        :style="getPosition(item)"
+        v-for="(item, index) in bodyList"
+        :key="index"
+        @click="inspectBody(item)"
+      />
+      <div
+        class="body_header"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('header')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div
+        class="body_chest"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('chest')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div
+        class="body_abdomen"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('abdomen')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div
+        class="body_left_hand"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('left_hand')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div
+        class="body_right_hand"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('right_hand')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div
+        class="body_left_leg"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('left_leg')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div
+        class="body_right_leg"
+        @click="openDetails()"
+        @mouseover="mouseEnterHandler('right_leg')"
+        @mouseleave="mouseLeaveHandler"
+      />
+      <div v-show="viewFlag" class="view_img">
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'header'"
+          :src="headerView"
+          alt=""
+        />
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'chest'"
+          :src="chestView"
+          alt=""
+        />
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'abdomen'"
+          :src="abdomenView"
+          alt=""
+        />
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'left_hand'"
+          :src="leftHandView"
+          alt=""
+        />
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'right_hand'"
+          :src="rightHandView"
+          alt=""
+        />
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'left_leg'"
+          :src="leftLegView"
+          alt=""
+        />
+        <img
+          v-show="useConsultationStoreHooks().bodyPositionType === 'right_leg'"
+          :src="rightLegView"
+          alt=""
+        />
+      </div>
+    </div>
+    <!-- 部位详情 -->
+    <PositionDetails @selectPostion="selectPostion" v-if="detailsFlag" />
+    <!-- 检查结果 -->
+    <div
+      v-show="selectToolInfo.toolName || bodyResultInfo.value"
+      class="result_card"
+    >
+      <div class="result_card_content">
+        <div v-show="bodyResultInfo.name" class="result_card_left">
+          <span>{{ bodyResultInfo.name }}</span>
+          <span style="margin-top: 16px" v-show="bodyResultInfo.postion">{{
+            bodyResultInfo.postion
+          }}</span>
+        </div>
+        <div v-show="bodyResultInfo.name" class="result_card_right">
+          <span :title="bodyResultInfo.value">{{ bodyResultInfo.value }}</span>
+        </div>
+        <!-- <div v-show="bodyResultInfo.name" class="result_card_item">
+        {{ `体格检查项:${bodyResultInfo.name}` }}
+      </div>
+      <div v-show="bodyResultInfo.value" class="result_card_item">
+        {{ `结果:${bodyResultInfo.value}` }}
+      </div>
+      <div v-show="bodyResultInfo.postion" class="result_card_item">
+        {{ `测量位置:${bodyResultInfo.postion}` }}
+      </div> -->
+        <div v-show="!bodyResultInfo.name" class="result_card_item">
+          请点击需要检查的身体部位
+        </div>
+        <!-- <el-icon class="closed"><Close @click="closedCard" /></el-icon> -->
+      </div>
+    </div>
+
+    <!-- 当前检查工具 -->
+    <!-- <div v-if="selectToolInfo.toolName" class="select_tool">
+      <div class="select_tool_content">
+        <img :src="selectToolInfo.img" alt="" />
+        <span>{{ selectToolInfo.toolName }}</span>
+      </div>
+      <div class="title">当前检查工具</div>
+    </div> -->
+    <!-- 全身切换 -->
+    <div v-if="detailsFlag" @click="detailsFlag = false" class="whole_body">
+      <div class="whole_body_content">
+        <img :src="wholeBodyImg" alt="" />
+      </div>
+      <div class="title">全身</div>
+    </div>
+
+    <!-- 背部 -->
+    <div
+      class="body_back"
+      @click="openDetails()"
+      @mouseover="mouseEnterHandler('back')"
+      v-if="!detailsFlag"
+    >
+      <div class="body_back_content">
+        <img :src="bockImg" alt="" />
+      </div>
+      <div class="title">背部</div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.peopleBody {
+  position: relative;
+  display: flex;
+  flex: 1;
+  // align-items: center;
+  justify-content: center;
+  height: calc(100vh - 250px);
+  margin-left: 24px;
+  overflow-y: auto;
+
+  .body {
+    position: relative;
+    width: 720px;
+    height: 790px;
+    margin-left: 20px;
+
+    .body_img {
+      width: 720px;
+      height: 790px;
+    }
+
+    .body_item {
+      position: absolute;
+      width: 36px;
+      height: 36px;
+      // background-color: red;
+      cursor: pointer;
+    }
+
+    .body_header {
+      position: absolute;
+      top: 39px;
+      left: 340px;
+      width: 65px;
+      height: 87px;
+      cursor: pointer;
+    }
+
+    .body_chest {
+      position: absolute;
+      top: 165px;
+      left: 312px;
+      width: 115px;
+      height: 123px;
+      cursor: pointer;
+    }
+
+    .body_abdomen {
+      position: absolute;
+      top: 293px;
+      left: 312px;
+      width: 115px;
+      height: 121px;
+      cursor: pointer;
+    }
+
+    .body_left_hand {
+      position: absolute;
+      top: 165px;
+      left: 428px;
+      width: 50px;
+      height: 272px;
+      cursor: pointer;
+    }
+
+    .body_right_hand {
+      position: absolute;
+      top: 165px;
+      left: 258px;
+      width: 50px;
+      height: 284px;
+      cursor: pointer;
+    }
+
+    .body_left_leg {
+      position: absolute;
+      top: 430px;
+      left: 376px;
+      width: 64px;
+      height: 340px;
+      cursor: pointer;
+    }
+
+    .body_right_leg {
+      position: absolute;
+      top: 455px;
+      left: 263px;
+      width: 98px;
+      height: 284px;
+      cursor: pointer;
+    }
+
+    .view_img {
+      position: absolute;
+      top: 50%; /* 使子元素顶部位于父元素中垂直居中 */
+      left: 50%; /* 使子元素左侧位于父元素中水平居中 */
+      width: 311px;
+      height: 311px;
+      pointer-events: none; /* 使用transform属性来水平和垂直居中 */
+      transform: translate(-50%, -50%);
+    }
+  }
+
+  .select_tool {
+    position: absolute;
+    top: 0;
+    right: 0;
+    text-align: center;
+
+    .select_tool_content {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 120px;
+      height: 145px;
+      background: rgb(66 135 255 / 5%);
+      border: 1px solid rgb(66 135 255 / 50%);
+      border-radius: 4px;
+      opacity: 1;
+
+      img {
+        width: 80px;
+        height: 80px;
+        background: #fff;
+        border-radius: 6px;
+      }
+
+      span {
+        margin-top: 8px;
+        font-size: 16px;
+        font-weight: 400;
+        color: #4287ff;
+      }
+    }
+
+    .title {
+      margin-top: 8px;
+      font-size: 16px;
+      font-weight: 400;
+      color: #364c63;
+    }
+  }
+
+  .whole_body {
+    position: absolute;
+    top: 0;
+    left: 24px;
+    text-align: center;
+
+    .whole_body_content {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 120px;
+      height: 145px;
+      cursor: pointer;
+      background: rgb(66 135 255 / 5%);
+      border: 1px solid rgb(66 135 255 / 50%);
+      border-radius: 4px;
+
+      img {
+        width: 98px;
+        height: 130px;
+      }
+    }
+
+    .title {
+      margin-top: 8px;
+      font-size: 16px;
+      font-weight: 400;
+      color: #364c63;
+    }
+  }
+
+  .body_back {
+    position: absolute;
+    top: 0;
+    left: 24px;
+    text-align: center;
+
+    .body_back_content {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      cursor: pointer;
+
+      img {
+        width: 98px;
+        height: 130px;
+      }
+    }
+
+    .title {
+      margin-top: 8px;
+      font-size: 16px;
+      font-weight: 400;
+      color: #364c63;
+    }
+  }
+
+  .result_card {
+    position: fixed;
+    bottom: 65px;
+    left: 600px;
+    z-index: 1;
+    display: flex;
+    width: calc(100% - 1220px);
+    min-width: 730px;
+    min-height: 105px;
+    padding: 24px;
+    font-size: 16px;
+    font-weight: 400;
+    color: #283c51;
+    pointer-events: none;
+    background: #f5f9ff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+    .result_card_content {
+      position: relative;
+      display: flex;
+      width: 100%;
+
+      .closed {
+        position: absolute;
+        top: -10px;
+        right: -10px;
+        cursor: pointer;
+      }
+    }
+
+    .result_card_left {
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      width: 64px;
+    }
+
+    .result_card_right {
+      display: flex;
+      flex: 1;
+      flex-wrap: wrap;
+      align-items: center;
+      padding-left: 16px;
+      margin-left: 16px;
+      // height: 52px;
+      border-left: 1px solid rgb(91 139 255 / 20%);
+    }
+
+    .result_card_item {
+      margin-right: 50px;
+    }
+  }
+}
+
+/* 隐藏滚动条(适用于WebKit浏览器,如Chrome和Safari) */
+.peopleBody::-webkit-scrollbar {
+  width: 0; /* 设置滚动条宽度 */
+}
+
+.peopleBody::-webkit-scrollbar-thumb {
+  background-color: transparent; /* 滚动条颜色,这里设置为透明 */
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/components/BodyInspectTable.vue b/src/views/consultation/FirstConsultation/BodyInspect/components/BodyInspectTable.vue
new file mode 100644
index 0000000..8fc94fb
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/components/BodyInspectTable.vue
@@ -0,0 +1,180 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/title_icon.png";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { onMounted, reactive } from "vue";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import { ref, watch } from "vue";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "BodyInspectTable"
+});
+const dataList = ref([]);
+const route = useRoute();
+const bodyVisible = ref(false);
+const bodyInfo = reactive({
+  name: "",
+  typeValue: "",
+  postion: ""
+});
+const columns: TableColumnList = [
+  {
+    label: "类目",
+    prop: "type"
+  },
+  {
+    label: "体格检查",
+    prop: "toolName"
+  },
+  {
+    label: "身体部位",
+    prop: "locationName"
+  },
+  {
+    label: "初步诊断",
+    prop: "diseaseName"
+  },
+  {
+    label: "检查时间",
+    prop: "createTime"
+  }
+  // {
+  //   label: "操作",
+  //   fixed: "right",
+  //   slot: "operation"
+  // }
+];
+watch(
+  () => useConsultationStoreHooks().bodyInspectList,
+  val => {
+    dataList.value = val;
+  }
+);
+const openDetail = items => {
+  if (!items) return;
+  useConsultationStoreHooks().changeBodyResultInfo({
+    name: items?.toolName || "",
+    value: items?.result || "",
+    postion: items?.locationName || ""
+  });
+};
+onMounted(() => {
+  useConsultationStoreHooks().getyAskPhysicalHistory(route.query.processId);
+});
+</script>
+
+<template>
+  <div class="BodyInspectTable">
+    <div class="header">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>体格检查</span>
+      </div>
+    </div>
+    <div v-if="dataList.length > 0">
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        adaptive
+        style="height: calc(100vh - 634px)"
+        class="mt-4"
+        :data="dataList"
+        :columns="columns"
+        highlight-current-row
+        @row-click="openDetail"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+      />
+    </div>
+    <div v-if="dataList.length === 0" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无数据</span>
+    </div>
+    <!-- 体格检查详情 -->
+    <el-dialog
+      width="500"
+      append-to-body
+      v-model="bodyVisible"
+      title="体格检查详情"
+      :center="true"
+      :show-close="false"
+      custom-class="body"
+    >
+      <div class="body_list">
+        <div class="body_item">
+          {{ `体格检查项:${bodyInfo.name}` }}
+        </div>
+        <div class="body_item">
+          {{ `结果:${bodyInfo.typeValue}` }}
+        </div>
+        <div v-show="bodyInfo.postion" class="body_item">
+          {{ `测量位置:${bodyInfo.postion}` }}
+        </div>
+        <div style="text-align: center">
+          <el-button
+            class="footer_btn"
+            size="large"
+            @click="bodyVisible = false"
+            type="primary"
+            >知道了</el-button
+          >
+        </div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<style lang="scss" scoped>
+.BodyInspectTable {
+  flex: 1;
+  width: 562px;
+  padding: 24px;
+  margin-top: 16px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .header {
+    display: flex;
+    align-items: center;
+    border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+    .title {
+      display: flex;
+      padding-bottom: 8px;
+      font-size: 16px;
+      font-weight: bold;
+      color: #2b3f54;
+      border-bottom: 4px solid #4287ff;
+
+      img {
+        width: 20px;
+        height: 20px;
+        margin-right: 8px;
+      }
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: calc(100vh - 634px);
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+}
+
+.body {
+  .body_item {
+    margin-bottom: 8px;
+    font-size: 14px;
+    font-weight: 400;
+    color: #666;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/components/FirstInspectTable.vue b/src/views/consultation/FirstConsultation/BodyInspect/components/FirstInspectTable.vue
new file mode 100644
index 0000000..f7f0bbd
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/components/FirstInspectTable.vue
@@ -0,0 +1,165 @@
+<script setup lang="ts">
+import titleIcon from "@/assets/newInquiry/inspect_icon.png";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import editImg from "@/assets/newInquiry/edit.png";
+import PrimaryDiagnosis from "@/views/consultation/components/PrimaryDiagnosis/index.vue";
+import { ref, watch } from "vue";
+import { onMounted } from "vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "FirstInspectTable"
+});
+const askPrimaryList = ref([]);
+const PrimaryDiagnosisRef = ref();
+const multipleSelection = ref([]);
+const tableRef = ref();
+const route = useRoute();
+
+const columns: TableColumnList = [
+  {
+    type: "selection",
+    align: "left"
+  },
+  {
+    label: "初步诊断列表",
+    prop: "primaryDiseaseName"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    slot: "operation"
+  }
+];
+watch(
+  () => useConsultationStoreHooks().firstInspectList,
+  val => {
+    askPrimaryList.value = val;
+  }
+);
+
+const add = () => {
+  PrimaryDiagnosisRef.value.open();
+};
+const edit = item => {
+  PrimaryDiagnosisRef.value.open(item);
+};
+const handleSelectionChange = val => {
+  multipleSelection.value = val;
+  const arry = [];
+  val.forEach(e => {
+    arry.push(e.id);
+  });
+  useConsultationStoreHooks().changePrimaryIdList(arry);
+};
+onMounted(() => {
+  useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+});
+</script>
+
+<template>
+  <div class="FirstInspectTable">
+    <div class="header">
+      <div class="title">
+        <img :src="titleIcon" alt="" />
+        <span>初步诊断列表</span>
+      </div>
+    </div>
+    <div class="empty">
+      <img v-if="askPrimaryList.length === 0" :src="emptyImg" alt="" />
+      <pure-table
+        ref="tableRef"
+        v-if="askPrimaryList.length > 0"
+        align-whole="center"
+        showOverflowTooltip
+        style="max-height: 120px"
+        adaptive
+        class="mt-4"
+        :data="askPrimaryList"
+        :columns="columns"
+        @selection-change="handleSelectionChange"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        ><template #operation="{ row }">
+          <div class="edit">
+            <img @click="edit(row)" :src="editImg" alt="" />
+          </div>
+        </template>
+      </pure-table>
+      <div @click="add" class="add_btn mt-2">添加初步诊断</div>
+    </div>
+
+    <PrimaryDiagnosis ref="PrimaryDiagnosisRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.FirstInspectTable {
+  width: 562px;
+  height: 261px;
+  padding: 24px;
+  background: #fff;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .header {
+    display: flex;
+    align-items: center;
+    border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+    .title {
+      display: flex;
+      padding-bottom: 8px;
+      font-size: 16px;
+      font-weight: bold;
+      color: #2b3f54;
+      border-bottom: 4px solid #4287ff;
+
+      img {
+        width: 20px;
+        height: 20px;
+        margin-right: 8px;
+      }
+    }
+  }
+
+  .empty {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 180px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .edit {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    img {
+      width: 16px;
+      height: 16px;
+    }
+  }
+
+  .add_btn {
+    width: 224px;
+    height: 40px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 40px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/BodyInspect/index.vue b/src/views/consultation/FirstConsultation/BodyInspect/index.vue
new file mode 100644
index 0000000..a3fbf3a
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/BodyInspect/index.vue
@@ -0,0 +1,46 @@
+<script setup lang="ts">
+import BodyList from "./BodyList.vue";
+import PeopleBody from "./PeopleBody.vue";
+import BodyTable from "./BodyTable.vue";
+import { computed, ref, watch } from "vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "BodyInspect"
+});
+const peopleBodyRef = ref(null);
+const selectTool = (item: any) => {
+  peopleBodyRef.value.openResult(item);
+};
+
+const selectToolInfo = computed(() => {
+  return useConsultationStoreHooks().selectToolInfo;
+});
+watch(
+  () => useConsultationStoreHooks().exhalationFlag,
+  val => {
+    if (val === true) {
+      selectTool({
+        id: selectToolInfo.value.id,
+        name: selectToolInfo.value.toolName,
+        requireLocation: selectToolInfo.value.requireLocation,
+        key: ""
+      });
+    }
+  }
+);
+</script>
+
+<template>
+  <div class="BodyInspect">
+    <BodyList @selectTool="selectTool" />
+    <PeopleBody ref="peopleBodyRef" />
+    <BodyTable />
+  </div>
+</template>
+<style lang="scss" scoped>
+.BodyInspect {
+  display: flex;
+  // flex: 1;
+  height: calc(100vh - 260px);
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/CaseWriting/index.vue b/src/views/consultation/FirstConsultation/CaseWriting/index.vue
new file mode 100644
index 0000000..f78040a
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/CaseWriting/index.vue
@@ -0,0 +1,39 @@
+<script setup lang="ts">
+import VoiceInspect from "@/views/consultation/components/VoiceInspect/index.vue";
+import ElectronicCase from "@/views/consultation/components/ElectronicCase/index.vue";
+defineOptions({
+  name: "CaseWriting"
+});
+</script>
+
+<template>
+  <div class="CaseWriting">
+    <div class="voice_consultation">
+      <VoiceInspect />
+    </div>
+    <ElectronicCase />
+  </div>
+</template>
+<style lang="scss" scoped>
+.CaseWriting {
+  display: flex;
+  flex: 1;
+  flex-direction: row-reverse;
+
+  .voice_consultation {
+    position: relative;
+    width: 500px;
+    margin-left: 16px;
+  }
+
+  :deep(.el-form-item__label) {
+    font-size: 14px;
+    font-weight: 400;
+    color: #2b3f54;
+  }
+
+  .el-form-item {
+    margin-bottom: 0;
+  }
+}
+</style>
diff --git a/src/views/consultation/FirstConsultation/index.vue b/src/views/consultation/FirstConsultation/index.vue
new file mode 100644
index 0000000..f54d4cb
--- /dev/null
+++ b/src/views/consultation/FirstConsultation/index.vue
@@ -0,0 +1,112 @@
+<script setup lang="ts">
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import CaseWriting from "./CaseWriting/index.vue";
+import BodyInspect from "./BodyInspect/index.vue";
+import { computed } from "vue";
+defineOptions({
+  name: "FirstConsultation"
+});
+const changeTab = val => {
+  useConsultationStoreHooks().changeActivedTabKey(val);
+};
+const activedIndex = computed(() => {
+  return useConsultationStoreHooks().activedTabKey;
+});
+</script>
+
+<template>
+  <div class="FirstConsultation">
+    <div class="tab_list">
+      <div
+        @click="changeTab(0)"
+        class="tab_list_item"
+        :class="[activedIndex === 0 ? 'actived' : '']"
+      >
+        <div class="content">
+          <div class="tab_case_img tab_img" />
+          <span>病历书写</span>
+        </div>
+      </div>
+      <div
+        @click="changeTab(1)"
+        class="tab_list_item"
+        :class="[activedIndex === 1 ? 'actived' : '']"
+      >
+        <div class="content">
+          <div class="tab_body_img tab_img" />
+          <span>体格检查</span>
+        </div>
+      </div>
+    </div>
+    <CaseWriting v-show="activedIndex === 0" />
+    <BodyInspect v-show="activedIndex === 1" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.FirstConsultation {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  padding: 40px;
+
+  .tab_list {
+    display: flex;
+    margin-top: 12px;
+    margin-bottom: 24px;
+
+    .tab_list_item {
+      width: 300px;
+      height: 0;
+      margin-right: 6px;
+      font-size: 18px;
+      font-weight: bold;
+      color: #4287ff;
+      cursor: pointer;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid rgb(66 135 255 / 15%);
+      border-left: 20px solid transparent;
+      border-radius: 6px;
+
+      .content {
+        position: relative;
+        top: 12px;
+        right: 21px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 300px;
+      }
+
+      .tab_img {
+        width: 20px;
+        height: 20px;
+        margin-right: 12px;
+        background-size: 100% 100%;
+      }
+
+      .tab_case_img {
+        background-image: url("../../../assets/newInquiry/tab/case_icon.png");
+      }
+    }
+
+    .actived {
+      color: #fff;
+      border-right: 20px solid transparent;
+      border-bottom: 50px solid #4287ff;
+      border-left: 20px solid transparent;
+    }
+
+    .tab_body_img {
+      background-image: url("../../../assets/newInquiry/tab/body_inspect.png");
+    }
+
+    .actived .tab_body_img {
+      background-image: url("../../../assets/newInquiry/tab/act_body_inspect.png");
+    }
+
+    .actived .tab_case_img {
+      background-image: url("../../../assets/newInquiry/tab/act_case_icon.png");
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/KnowledgeGraph/AtlasPage/GraphChart.vue b/src/views/consultation/KnowledgeGraph/AtlasPage/GraphChart.vue
new file mode 100644
index 0000000..6416c95
--- /dev/null
+++ b/src/views/consultation/KnowledgeGraph/AtlasPage/GraphChart.vue
@@ -0,0 +1,259 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+import { queryGraph } from "@/api/consultation";
+import G6 from "@antv/g6";
+import { useRoute } from "vue-router";
+const dataInfo = ref();
+
+const route = useRoute();
+let graph = null;
+const calcStrLen = function calcStrLen(str) {
+  let len = 0;
+  for (let i = 0; i < str.length; i++) {
+    if (str.charCodeAt(i) > 0 && str.charCodeAt(i) < 128) {
+      len++;
+    } else {
+      len += 2;
+    }
+  }
+  return len;
+};
+const fittingString = function fittingString(str, maxWidth, fontSize) {
+  const fontWidth = fontSize * 1.3; //字号+边距
+  maxWidth = maxWidth * 2; // 需要根据自己项目调整
+  const width = calcStrLen(str) * fontWidth;
+  const ellipsis = "…";
+  if (width > maxWidth) {
+    const actualLen = Math.floor((maxWidth - 10) / fontWidth);
+    const result = str.substring(0, actualLen) + ellipsis;
+    return result;
+  }
+  return str;
+};
+function clearAllStats() {
+  graph.setAutoPaint(false);
+  graph.getNodes().forEach(function (node) {
+    graph.clearItemStates(node);
+  });
+  graph.getEdges().forEach(function (edge) {
+    graph.clearItemStates(edge);
+  });
+  graph.paint();
+  graph.setAutoPaint(true);
+}
+const init = () => {
+  const container = document.getElementById("container");
+  const width = container.clientWidth;
+  const height = container.clientHeight || 500;
+
+  graph = new G6.Graph({
+    container: "container",
+    width,
+    height,
+    fitView: false,
+    modes: {
+      default: ["drag-canvas", "drag-node", "zoom-canvas"]
+    },
+    layout: {
+      type: "force",
+      fitView: true,
+      fitViewPadding: 10,
+      maxZoom: 2
+    },
+    animate: true,
+    // nodeStateStyles: {
+    //   highlight: {
+    //     fill: "rgba(47, 124, 255, 1)",
+    //     shadowColor: "#fff",
+    //     stroke: "rgba(47, 124, 255, 1)",
+    //     cursor: "pointer",
+    //     opacity: 1
+    //   }
+    // },
+    edgeStateStyles: {
+      highlight: {
+        fill: "rgba(253, 160, 76)",
+        color: "rgba(253, 160, 76)"
+      }
+    },
+    defaultEdge: {
+      size: 2,
+      color: "rgba(253, 160, 76, 0.4)",
+
+      style: {
+        endArrow: {
+          path: G6.Arrow.triangle(10, 10, 15),
+          fill: "rgba(253, 160, 76, 0.4)",
+          d: 15
+        }
+      },
+      labelCfg: {
+        autoRotate: true,
+        refY: 10
+      }
+    }
+  });
+  graph.node(node => {
+    return {
+      id: node.id,
+      shape: "rect",
+      size: [100, 50],
+      labelCfg: {
+        style: {
+          fill: "#FFFFFF",
+          fontSize: 14
+        }
+      },
+      style: {
+        fill: node.nodeColour,
+        stroke: node.nodeColour,
+        opacity: 0.4
+      },
+      stateStyles: {
+        // 定义高亮状态
+        highlight: {
+          fill: node.nodeColour,
+          stroke: node.nodeColour,
+          opacity: 1
+        }
+      }
+    };
+  });
+  // 设置边的状态配置
+  graph.edge(() => {
+    return {
+      stateStyles: {
+        // 定义高亮状态
+        highlight: {
+          stroke: "rgba(253, 160, 76, 1)",
+          lineWidth: 2
+        }
+      }
+    };
+  });
+  graph.data(dataInfo.value);
+  graph.updateLayout({
+    preventOverlap: true,
+    linkDistance: 250,
+    unitRadius: 250,
+    nodeSize: 150,
+    focusNode: "80"
+  });
+  function refreshDragedNodePosition(e) {
+    const model = e.item.get("model");
+    model.fx = e.x;
+    model.fy = e.y;
+  }
+  graph.on("node:click", function (e) {
+    const itemModel = e.item.getModel();
+    emit("getNodeItem", itemModel);
+  });
+  graph.render();
+  graph.on("node:dragstart", function (e) {
+    graph.layout();
+    refreshDragedNodePosition(e);
+  });
+  graph.on("node:drag", function (e) {
+    const forceLayout = graph.get("layoutController").layoutMethods[0];
+    forceLayout.execute();
+    refreshDragedNodePosition(e);
+  });
+  graph.on("node:dragend", function (e) {
+    e.item.get("model").fx = null;
+    e.item.get("model").fy = null;
+  });
+};
+const emit = defineEmits(["getNodeItem", "getColorList"]);
+const selectItem = e => {
+  const item = graph.findById(e.id);
+  graph.setAutoPaint(false);
+  // graph.getNodes().forEach(function (node) {
+  //   graph.clearItemStates(node);
+  //   graph.setItemState(node, "dark", true);
+  // });
+  graph.setItemState(item, "dark", false);
+  graph.setItemState(item, "highlight", true);
+  graph.getEdges().forEach(function (edge) {
+    if (edge.getSource() === item) {
+      // graph.setItemState(edge.getTarget(), "dark", false);
+      // graph.setItemState(edge.getTarget(), "highlight", true);
+      graph.setItemState(edge, "highlight", true);
+      edge.toFront();
+    } else if (edge.getTarget() === item) {
+      // graph.setItemState(edge.getSource(), "dark", false);
+      // graph.setItemState(edge.getSource(), "highlight", true);
+      graph.setItemState(edge, "highlight", true);
+      edge.toFront();
+    } else {
+      // graph.setItemState(edge, "highlight", false);
+    }
+  });
+  graph.paint();
+  graph.setAutoPaint(true);
+  // graph.render();
+};
+defineExpose({
+  changeSelectItem(data) {
+    clearAllStats();
+    data.forEach(e => {
+      selectItem(e);
+    });
+  },
+  async reset(val) {
+    const res: any = await queryGraph({
+      processId: route.query.processId,
+      level: val
+    });
+    if (res.code === 200) {
+      res.data.nodes.forEach(e => {
+        e.label = fittingString(e.nodeValue, 50, 12);
+      });
+      dataInfo.value = res.data;
+      graph.data(dataInfo.value);
+      graph.render();
+    }
+  },
+  amplify() {
+    graph.zoom(1.2); // 放大到原来的120%
+  },
+  reduce() {
+    graph.zoom(0.8); // 放大到原来的120%
+  }
+});
+const getData = async val => {
+  const res: any = await queryGraph({
+    processId: route.query.processId,
+    level: val
+  });
+  if (res.code === 200) {
+    res.data.nodes.forEach(e => {
+      e.label = fittingString(e.nodeValue, 50, 12);
+    });
+    dataInfo.value = res.data;
+    emit("getColorList", res.data.legendList);
+    init();
+  }
+};
+onMounted(() => {
+  getData(3);
+});
+</script>
+<template>
+  <div class="GraphChart">
+    <div
+      class="chart"
+      ref="container"
+      style="width: 100%; height: 100%"
+      id="container"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.GraphChart {
+  height: 100%;
+
+  .chart {
+    background: rgb(0 0 0 / 2%);
+  }
+}
+</style>
diff --git a/src/views/consultation/KnowledgeGraph/AtlasPage/TreeChart.vue b/src/views/consultation/KnowledgeGraph/AtlasPage/TreeChart.vue
new file mode 100644
index 0000000..253f846
--- /dev/null
+++ b/src/views/consultation/KnowledgeGraph/AtlasPage/TreeChart.vue
@@ -0,0 +1,114 @@
+<script setup lang="ts">
+import { onMounted } from "vue";
+import G6 from "@antv/g6";
+let graph = undefined;
+const props = defineProps({
+  treeData: {
+    type: Array,
+    default: () => []
+  }
+});
+const emit = defineEmits(["getNodeItem"]);
+defineExpose({
+  reset(data) {
+    graph.data(data[0]);
+    graph.render();
+    graph.fitView();
+  }
+});
+const init = () => {
+  const container = document.getElementById("treeChart");
+  const width = container.clientWidth;
+  const height = container.clientHeight || 500;
+  graph = new G6.TreeGraph({
+    container: "treeChart",
+    width,
+    height,
+    pixelRatio: 2,
+    maxZoom: 1,
+    modes: {
+      default: [
+        {
+          type: "collapse-expand",
+          onChange: function onChange(item, collapsed) {
+            const data = item.get("model").data;
+            data.collapsed = collapsed;
+            return true;
+          }
+        },
+        "drag-canvas",
+        "zoom-canvas"
+      ]
+    },
+    defaultNode: {
+      size: 16,
+      anchorPoints: [
+        [0, 0.5],
+        [1, 0.5]
+      ],
+      style: {
+        fill: "#40a9ff",
+        stroke: "#096dd9"
+      }
+    },
+    defaultEdge: {
+      shape: "cubic-horizontal",
+      style: {
+        stroke: "#A3B1BF"
+      }
+    },
+    layout: {
+      type: "dendrogram",
+      direction: "LR", // H / V / LR / RL / TB / BT
+      nodeSep: 30,
+      rankSep: 100
+    }
+  });
+
+  graph.node(function (node) {
+    return {
+      size: 26,
+      style: {
+        fill: "#40a9ff",
+        stroke: "#096dd9"
+      },
+      label: node.nodeValue,
+      labelCfg: {
+        position: node.children && node.children.length > 0 ? "left" : "right"
+      }
+    };
+  });
+
+  graph.on("node:click", function (e) {
+    const itemModel = e.item.getModel();
+    emit("getNodeItem", itemModel);
+  });
+  graph.data(props.treeData[0]);
+
+  graph.render();
+  graph.fitView();
+};
+
+onMounted(() => {
+  init();
+});
+</script>
+<template>
+  <div class="TreeChart">
+    <div
+      class="chart"
+      ref="treeChart"
+      style="width: 100%; height: 100%"
+      id="treeChart"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.TreeChart {
+  height: 100%;
+
+  .chart {
+    background: rgb(0 0 0 / 2%);
+  }
+}
+</style>
diff --git a/src/views/consultation/KnowledgeGraph/AtlasPage/index.vue b/src/views/consultation/KnowledgeGraph/AtlasPage/index.vue
new file mode 100644
index 0000000..0539bb9
--- /dev/null
+++ b/src/views/consultation/KnowledgeGraph/AtlasPage/index.vue
@@ -0,0 +1,530 @@
+<script setup lang="ts">
+import { ref, watch } from "vue";
+import GraphChart from "./GraphChart.vue";
+import TreeChart from "./TreeChart.vue";
+import { Search } from "@element-plus/icons-vue";
+import { queryTreeGraph } from "@/api/consultation";
+import selectIcon from "@/assets/svg/evaluate/select.svg?component";
+import { CircleClose } from "@element-plus/icons-vue";
+import UpIcon from "@/assets/svg/evaluate/up.svg?component";
+import DownIcon from "@/assets/svg/evaluate/down.svg?component";
+import DelIcon from "@/assets/svg/evaluate/del.svg?component";
+import ReduceIcon from "@/assets/svg/evaluate/reduce.svg?component";
+import AmplifyIcon from "@/assets/svg/evaluate/amplify.svg?component";
+import { useRoute } from "vue-router";
+import { onMounted } from "vue";
+import { onClickOutside } from "@vueuse/core";
+import { reactive } from "vue";
+const levelNum = ref(3);
+const selectRef = ref();
+const searchName = ref("");
+const selectName = ref("关系依赖图");
+const chartType = ref("1");
+const cardFlag = ref(true);
+const treeRef = ref();
+const GraphChartRef = ref();
+const TreeChartRef = ref();
+const selectList = ref([]);
+const showFlag = ref(false);
+const colorList = ref([]);
+const detailInfo = reactive({
+  nodeValue: "",
+  nodeDesc: ""
+});
+const treeData = ref([]);
+const defaultProps = {
+  children: "children",
+  label: "nodeValue"
+};
+const route = useRoute();
+const getTreeData = async () => {
+  const res: any = await queryTreeGraph({
+    processId: route.query.processId,
+    level: levelNum.value
+  });
+  treeData.value = res.data;
+  TreeChartRef.value.reset(treeData.value);
+};
+const selectType = val => {
+  if (val === "1") {
+    selectName.value = "关系依赖图";
+  } else {
+    selectName.value = "聚合分析图";
+  }
+  chartType.value = val;
+  showFlag.value = false;
+};
+onClickOutside(selectRef, () => (showFlag.value = false));
+const changeCardFlag = () => {
+  cardFlag.value = !cardFlag.value;
+};
+const handleCheckChange = (data: any) => {
+  detailInfo.nodeDesc = data.nodeDesc;
+  detailInfo.nodeValue = data.nodeValue;
+  selectList.value = treeRef.value.getCheckedNodes();
+  console.log(selectList.value);
+  GraphChartRef.value.changeSelectItem(selectList.value);
+};
+const delItem = index => {
+  // treeRef.value.remove(selectList.value[index].id);
+  selectList.value.splice(index, 1);
+
+  const idList = [];
+  for (const item of selectList.value) {
+    idList.push(item.id);
+  }
+  treeRef.value.setCheckedKeys(idList, true);
+  // selectList.value = treeRef.value.getCheckedNodes();
+
+  GraphChartRef.value.changeSelectItem(selectList.value);
+};
+const clearAll = () => {
+  selectList.value = [];
+  treeRef.value.setCheckedKeys([], true);
+  // selectList.value = treeRef.value.getCheckedNodes();
+
+  GraphChartRef.value?.changeSelectItem(selectList.value);
+};
+watch(searchName, val => {
+  treeRef.value!.filter(val);
+});
+watch(levelNum, val => {
+  getTreeData();
+  for (const item of colorList.value) {
+    item.actived = false;
+  }
+  GraphChartRef.value?.reset(val);
+});
+const filterNode = (value: string, data: any) => {
+  if (!value) return true;
+  return data.nodeValue.includes(value);
+};
+const getNodeItem = item => {
+  detailInfo.nodeDesc = item.nodeDesc;
+  detailInfo.nodeValue = item.nodeValue;
+};
+const amplify = () => {
+  GraphChartRef.value.amplify();
+};
+const reduce = () => {
+  GraphChartRef.value.reduce();
+};
+const getColorList = list => {
+  list.forEach(e => {
+    e.actived = false;
+  });
+  colorList.value = list;
+};
+const selectColor = index => {
+  colorList.value[index].actived = !colorList.value[index].actived;
+  for (const item of colorList.value[index].id) {
+    treeRef.value.setChecked(item, colorList.value[index].actived);
+  }
+};
+onMounted(() => {
+  getTreeData();
+});
+</script>
+<template>
+  <div class="AtlasPage">
+    <div class="sidebar">
+      <!-- <div class="tab_list">
+        <span
+          @click="changeTab(0)"
+          class="tab_item"
+          :class="[activedTab === 0 ? 'actived' : '']"
+          >本体节点</span
+        >
+        <span
+          @click="changeTab(1)"
+          class="tab_item"
+          :class="[activedTab === 1 ? 'actived' : '']"
+          >关系</span
+        >
+      </div> -->
+      <el-input
+        v-model="searchName"
+        style="width: 270px"
+        class="mt-5"
+        size="large"
+        placeholder="搜索名称"
+        :prefix-icon="Search"
+      />
+      <div class="node_level">
+        <span>节点级别</span>
+        <el-input-number
+          size="large"
+          :max="3"
+          :min="1"
+          style="width: 185px"
+          v-model="levelNum"
+          :step="1"
+        />
+      </div>
+      <div class="tree_main">
+        <el-tree
+          ref="treeRef"
+          :data="treeData"
+          show-checkbox
+          node-key="id"
+          default-expand-all
+          :props="defaultProps"
+          :filter-node-method="filterNode"
+          @check-change="handleCheckChange"
+        />
+      </div>
+    </div>
+    <div class="main">
+      <GraphChart
+        @getColorList="getColorList"
+        @getNodeItem="getNodeItem"
+        ref="GraphChartRef"
+        v-show="chartType === '1'"
+      />
+      <TreeChart
+        ref="TreeChartRef"
+        @getNodeItem="getNodeItem"
+        :treeData="treeData"
+        v-if="chartType === '2'"
+      />
+      <div ref="selectRef" class="select">
+        <div @click="showFlag = true" class="select_item">
+          <span>{{ selectName }}</span>
+          <selectIcon />
+        </div>
+        <div v-if="showFlag" class="select_card">
+          <span @click="selectType('1')">关系依赖图</span>
+          <span @click="selectType('2')">聚合分析图</span>
+        </div>
+      </div>
+      <div v-show="chartType === '1'" class="color_list">
+        <span>按颜色筛选:</span>
+        <el-tooltip
+          class="box-item"
+          effect="light"
+          :content="item.legendType"
+          placement="bottom"
+          v-for="(item, index) in colorList"
+          :key="index"
+        >
+          <div
+            @click="selectColor(index)"
+            :class="[
+              item.actived === true ? 'colour_item actived' : 'colour_item'
+            ]"
+            :style="{ background: item.colour }"
+          />
+        </el-tooltip>
+      </div>
+      <div class="btn_chart">
+        <AmplifyIcon @click="amplify" />
+        <ReduceIcon style="margin-left: 24px" @click="reduce" />
+      </div>
+      <div class="select_content">
+        <div class="tip">
+          <div class="del" @click="clearAll">
+            <DelIcon />
+          </div>
+          <div @click="changeCardFlag" class="tip_item">
+            <span>{{ `选中节点${selectList.length}` }}</span>
+            <DownIcon v-show="cardFlag" class="ml-2" />
+            <UpIcon v-show="!cardFlag" class="ml-2" />
+          </div>
+        </div>
+        <div v-show="cardFlag && selectList.length > 0" class="card_list">
+          <div
+            class="card_list_item"
+            v-for="(item, index) in selectList"
+            :key="index"
+          >
+            <span>{{ item.nodeValue }}</span>
+            <el-icon @click="delItem(index)" class="del"
+              ><CircleClose
+            /></el-icon>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="detail">
+      <div class="titel">本体详情</div>
+      <div v-show="detailInfo.nodeValue" class="detail_item">
+        <div class="label">名称</div>
+        <div class="value">{{ detailInfo.nodeValue }}</div>
+      </div>
+      <div v-show="detailInfo.nodeValue" class="detail_item">
+        <div class="label">描述</div>
+        <div class="value" v-html="detailInfo.nodeDesc" />
+      </div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AtlasPage {
+  display: flex;
+  justify-content: center;
+  height: calc(100vh - 220px);
+
+  .sidebar {
+    width: 328px;
+
+    .tab_list {
+      display: flex;
+      align-items: center;
+      width: 272px;
+      height: 44px;
+      padding: 6px;
+      color: #2b3f54;
+      background: #f5f5f5;
+      border-radius: 6px;
+
+      .tab_item {
+        width: 130px;
+        height: 32px;
+        font-size: 16px;
+        line-height: 32px;
+        text-align: center;
+        cursor: pointer;
+        border-radius: 6px;
+      }
+
+      .actived {
+        color: #fff;
+        background: #4287ff;
+      }
+    }
+
+    .node_level {
+      display: flex;
+      align-items: center;
+      margin-top: 16px;
+
+      span {
+        margin-right: 16px;
+        color: #2b3f54;
+      }
+    }
+  }
+
+  .main {
+    position: relative;
+    flex: 1;
+
+    .select {
+      position: absolute;
+      top: 24px;
+      left: 24px;
+
+      .select_item {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        width: 134px;
+        height: 32px;
+        font-size: 16px;
+        // opacity: 0.05;
+        color: #2b3f54;
+        cursor: pointer;
+        background: rgb(66 135 255 / 5%);
+        border-radius: 6px;
+
+        span {
+          margin-right: 6px;
+        }
+      }
+
+      .select_card {
+        display: flex;
+        flex-direction: column;
+        width: 134px;
+        height: 90px;
+        padding: 8px 16px;
+        cursor: pointer;
+        background: #fff;
+        border-radius: 6px;
+        box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+        span {
+          margin: 8px 0;
+          font-size: 16px;
+          color: #2b3f54;
+        }
+
+        span:hover {
+          color: #4287ff;
+        }
+      }
+    }
+
+    .btn_chart {
+      position: absolute;
+      top: 24px;
+      right: 24px;
+      display: flex;
+
+      svg {
+        cursor: pointer;
+      }
+    }
+
+    .color_list {
+      position: absolute;
+      top: 24px;
+      left: 200px;
+      display: flex;
+      height: 32px;
+      padding: 6px 16px;
+      background: rgb(66 135 255 / 5%);
+      border-radius: 6px;
+
+      span {
+        font-size: 16px;
+        color: #2b3f54;
+        // opacity: 1;
+      }
+
+      .colour_item {
+        width: 20px;
+        height: 20px;
+        margin-left: 8px;
+        cursor: pointer;
+        border-radius: 4px;
+      }
+
+      .actived {
+        position: relative;
+        display: inline-block;
+        width: 20px;
+        height: 20px;
+      }
+
+      .actived::after {
+        position: absolute;
+        top: 50%;
+        left: 50%;
+        font-size: 16px;
+        color: #fff;
+        content: "\2713"; /* Unicode 编码,表示打钩符号 */
+        transform: translate(-50%, -50%);
+        // display: none;
+      }
+    }
+
+    .select_content {
+      position: absolute;
+      bottom: 16px;
+      width: calc(100% - 32px);
+      margin: 0 16px;
+
+      .tip {
+        display: flex;
+        flex-direction: row-reverse;
+
+        .del {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          width: 42px;
+          height: 40px;
+          margin-left: 16px;
+          cursor: pointer;
+          background: #fff;
+          border: 1px solid #e9eaec;
+          border-radius: 6px;
+        }
+
+        .tip_item {
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          width: 121px;
+          height: 40px;
+          font-size: 14px;
+          color: #2b3f54;
+          cursor: pointer;
+          background: #fff;
+          border: 1px solid #e9eaec;
+          border-radius: 6px;
+        }
+      }
+
+      .card_list {
+        display: flex;
+        flex-wrap: wrap;
+        padding: 16px;
+        margin-top: 8px;
+        background: #fff;
+        border: 1px solid #e9eaec;
+        border-radius: 6px;
+
+        .card_list_item {
+          display: flex;
+          align-items: center;
+          padding: 2px 8px;
+          margin-right: 12px;
+          margin-bottom: 12px;
+          font-size: 14px;
+          color: #2b3f54;
+          background: #f0f0f0;
+          border-radius: 4px;
+
+          span {
+            margin-right: 12px;
+          }
+
+          .del {
+            cursor: pointer;
+          }
+        }
+      }
+    }
+  }
+
+  .detail {
+    width: 328px;
+    padding: 24px;
+
+    .titel {
+      margin-bottom: 24px;
+      font-size: 16px;
+      font-weight: bold;
+      color: #2b3f54;
+    }
+
+    .detail_item {
+      display: flex;
+      margin-bottom: 16px;
+
+      .label {
+        margin-right: 24px;
+        font-size: 14px;
+        color: #2b3f54;
+        // width: 50px;
+      }
+
+      .value {
+        flex: 1;
+        font-size: 14px;
+        color: rgb(43 63 84 / 70%);
+      }
+    }
+  }
+
+  :deep(.el-tree-node__label) {
+    width: 200px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .tree_main {
+    height: calc(100vh - 350px);
+    overflow-y: auto;
+  }
+}
+</style>
+<style lang="scss">
+.is-light {
+  font-size: 16px !important;
+  color: #2b3f54 !important;
+}
+</style>
diff --git a/src/views/consultation/KnowledgeGraph/index.vue b/src/views/consultation/KnowledgeGraph/index.vue
new file mode 100644
index 0000000..45cf626
--- /dev/null
+++ b/src/views/consultation/KnowledgeGraph/index.vue
@@ -0,0 +1,54 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import ActPeople from "@/assets/svg/evaluate/act_people.svg?component";
+// import Inquiry from "@/assets/svg/evaluate/inquiry.svg?component";
+import AtlasPage from "./AtlasPage/index.vue";
+const activeName = ref("0");
+</script>
+<template>
+  <div class="KnowledgeGraph">
+    <el-tabs v-model="activeName">
+      <el-tab-pane name="0">
+        <template #label>
+          <span class="custom-tabs-label">
+            <ActPeople v-if="activeName === '0'" />
+            <ActPeople v-else />
+            <span>问诊实例</span>
+          </span>
+        </template>
+        <AtlasPage />
+      </el-tab-pane>
+      <!-- <el-tab-pane name="1">
+        <template #label>
+          <span class="custom-tabs-label">
+            <Inquiry v-if="activeName === '1'" />
+            <Inquiry v-else />
+            <span>问诊实例</span>
+          </span>
+        </template>
+      </el-tab-pane> -->
+    </el-tabs>
+  </div>
+</template>
+<style lang="scss" scoped>
+.KnowledgeGraph {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  padding: 40px;
+  overflow-y: auto;
+
+  :deep(.el-tab-pane) {
+    height: calc(100vh - 220px);
+    overflow: auto;
+  }
+
+  .custom-tabs-label {
+    display: flex;
+
+    span {
+      margin-left: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/components/CaseWritingDialog/index.vue b/src/views/consultation/components/CaseWritingDialog/index.vue
new file mode 100644
index 0000000..5e806a2
--- /dev/null
+++ b/src/views/consultation/components/CaseWritingDialog/index.vue
@@ -0,0 +1,109 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import { FormInstance } from "element-plus";
+import ElectronicCase from "../ElectronicCase/index.vue";
+
+defineOptions({
+  name: "CaseWritingDialog"
+});
+const drawer = ref(false);
+
+const ruleFormRef = ref<FormInstance>();
+
+defineExpose({
+  open() {
+    resetForm();
+    drawer.value = true;
+  }
+});
+
+const resetForm = () => {
+  if (!ruleFormRef.value) return;
+  ruleFormRef.value.resetFields();
+};
+</script>
+
+<template>
+  <div class="CaseWritingDialog">
+    <el-drawer
+      size="856"
+      v-model="drawer"
+      :show-close="false"
+      :with-header="false"
+      append-to-body
+    >
+      <div class="CaseWritingDialog">
+        <div class="header-title">
+          <div class="tip" />
+          <span>病历书写</span>
+        </div>
+        <div class="line" />
+        <ElectronicCase v-if="drawer" />
+      </div>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.CaseWritingDialog {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 856px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    justify-content: space-around;
+    height: 50px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/components/ElectronicCase/index.vue b/src/views/consultation/components/ElectronicCase/index.vue
new file mode 100644
index 0000000..12951d2
--- /dev/null
+++ b/src/views/consultation/components/ElectronicCase/index.vue
@@ -0,0 +1,415 @@
+<script setup lang="ts">
+import { reactive, ref, watch } from "vue";
+import { ArrowUp, ArrowDown } from "@element-plus/icons-vue";
+import { findByProcessId, updateCase } from "@/api/consultation";
+import { onMounted } from "vue";
+import { useRoute } from "vue-router";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "ElectronicCase"
+});
+const showFlag = ref(false);
+const formData = reactive({
+  familyHistoryFlag: undefined,
+  familyHistory: "",
+  previousHistoryFlag: undefined,
+  previousHistory: "",
+  allergyHistory: "",
+  allergyHistoryFlag: undefined,
+  patientSelfDesc: "",
+  personalHistory: "",
+  operationHistoryFlag: undefined,
+  illnessHistory: "",
+  operationHistory: ""
+});
+const baseInfo = ref({
+  processNo: "",
+  medicalRecNo: "",
+  createTime: "",
+  patientSelfDesc: "",
+  patientName: "",
+  patientGender: "",
+  patientAge: "",
+  patientMarriage: "",
+  patientProfession: "",
+  patientPhone: "",
+  nativePlace: "",
+  patientHabitation: "",
+  patientPostcode: "",
+  patientNation: "",
+  patientBirthplace: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const route = useRoute();
+const getDetails = async () => {
+  const res: any = await findByProcessId({
+    processId: route.query.processId
+  });
+  baseInfo.value = res.data.base;
+  // formData = res.data.processMedical;
+  for (const key in res.data.processMedical) {
+    // eslint-disable-next-line no-prototype-builtins
+    if (formData.hasOwnProperty(key)) {
+      formData[key] = res.data.processMedical[key];
+    }
+  }
+};
+watch(
+  () => formData.familyHistoryFlag,
+  val => {
+    if (val === 0) {
+      formData.familyHistory = "";
+    }
+  }
+);
+watch(
+  () => formData.previousHistoryFlag,
+  val => {
+    if (val === 0) {
+      formData.previousHistory = "";
+    }
+  }
+);
+watch(
+  () => formData.operationHistoryFlag,
+  val => {
+    if (val === 0) {
+      formData.operationHistory = "";
+    }
+  }
+);
+const reset = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+};
+const save = async () => {
+  const params = {
+    ...formData,
+    processId: route.query.processId
+  };
+  const res: any = await updateCase(params);
+  if (res.code === 200) {
+    message("保存成功", { type: "success" });
+  }
+};
+onMounted(() => {
+  getDetails();
+});
+</script>
+
+<template>
+  <div class="ElectronicCase">
+    <div class="ele_case_main">
+      <div class="top">
+        <div class="title">电子病历</div>
+        <div class="top_list">
+          <div class="top_list_item">
+            {{ `问诊编号:${baseInfo.processNo}` }}
+          </div>
+          <div class="top_list_item">
+            {{ `病案号:${baseInfo.medicalRecNo}` }}
+          </div>
+          <div class="top_list_item">
+            {{ `首诊时间:${baseInfo.createTime}` }}
+          </div>
+        </div>
+      </div>
+      <el-form :model="baseInfo" label-width="70px">
+        <div class="basicInfo">
+          <el-row>
+            <el-col :span="8">
+              <el-form-item label="姓名">
+                <span>{{ baseInfo.patientName }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="性别">
+                <span>{{ baseInfo.patientGender }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="年龄">
+                <span>{{ baseInfo.patientAge }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="8">
+              <el-form-item label="婚姻状况">
+                <span>{{ baseInfo.patientMarriage }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="职业">
+                <span>{{ baseInfo.patientProfession }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item v-show="showFlag" label="电话">
+                <span>{{ baseInfo.patientPhone }}</span>
+              </el-form-item>
+              <!-- <el-form-item v-show="!showFlag" label="更多">
+                  <el-icon color="#999999" size="14"><ArrowDown /></el-icon>
+                </el-form-item> -->
+              <div v-show="!showFlag" @click="showFlag = true" class="contract">
+                <span>更多</span>
+                <el-icon color="#999999" size="14"><ArrowDown /></el-icon>
+              </div>
+            </el-col>
+          </el-row>
+          <el-row v-show="showFlag">
+            <el-col :span="8">
+              <el-form-item label="籍贯">
+                <span>{{ baseInfo.nativePlace }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="民族">
+                <span>{{ baseInfo.patientNation }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="邮编">
+                <span>{{ baseInfo.patientPostcode }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row v-show="showFlag">
+            <el-col :span="8">
+              <el-form-item label="出生地">
+                <span>{{ baseInfo.patientBirthplace }}</span>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="现住址">
+                <span>{{ baseInfo.patientHabitation }}</span>
+              </el-form-item>
+            </el-col>
+            <div v-show="showFlag" @click="showFlag = false" class="contract">
+              <span>收起</span>
+              <el-icon color="#999999" size="14"><ArrowUp /></el-icon>
+            </div>
+          </el-row>
+        </div>
+      </el-form>
+      <el-form ref="ruleFormRef" :model="formData" label-width="60px">
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="主诉 " prop="patientSelfDesc">
+              <el-input
+                :rows="4"
+                type="textarea"
+                :maxLength="500"
+                placeholder="请输入"
+                v-model="formData.patientSelfDesc"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="现病史 " prop="illnessHistory">
+              <el-input
+                :rows="4"
+                type="textarea"
+                :maxLength="500"
+                placeholder="请输入"
+                v-model="formData.illnessHistory"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="过敏史 " prop="allergyHistoryFlag">
+              <el-radio-group
+                v-model="formData.allergyHistoryFlag"
+                class="ml-4"
+              >
+                <el-radio :label="0" size="large">无</el-radio>
+                <el-radio :label="1" size="large">有</el-radio>
+              </el-radio-group>
+              <el-form-item
+                class="ml-1"
+                v-show="formData.allergyHistoryFlag === 1"
+                style="flex: 1"
+                prop="allergyHistory"
+              >
+                <el-input size="large" v-model="formData.allergyHistory" />
+              </el-form-item>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="个人史 " prop="personalHistory">
+              <el-input size="large" v-model="formData.personalHistory" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="家族史 " prop="familyHistoryFlag">
+              <el-radio-group v-model="formData.familyHistoryFlag" class="ml-4">
+                <el-radio :label="0" size="large">无</el-radio>
+                <el-radio :label="1" size="large">有</el-radio>
+              </el-radio-group>
+              <el-form-item
+                class="ml-1"
+                v-show="formData.familyHistoryFlag === 1"
+                style="flex: 1"
+                prop="familyHistory"
+              >
+                <el-input size="large" v-model="formData.familyHistory" />
+              </el-form-item>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="既往史 " prop="previousHistoryFlag">
+              <el-radio-group
+                v-model="formData.previousHistoryFlag"
+                class="ml-4"
+              >
+                <el-radio :label="0" size="large">无</el-radio>
+                <el-radio :label="1" size="large">有</el-radio>
+              </el-radio-group>
+              <el-form-item
+                v-show="formData.previousHistoryFlag === 1"
+                class="ml-1"
+                style="flex: 1"
+                prop="previousHistory"
+              >
+                <el-input size="large" v-model="formData.previousHistory" />
+              </el-form-item>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row class="mt-4">
+          <el-col :span="24">
+            <el-form-item label="手术史 " prop="operationHistoryFlag">
+              <el-radio-group
+                v-model="formData.operationHistoryFlag"
+                class="ml-4"
+              >
+                <el-radio :label="0" size="large">无</el-radio>
+                <el-radio :label="1" size="large">有</el-radio>
+              </el-radio-group>
+              <el-form-item
+                v-show="formData.operationHistoryFlag === 1"
+                class="ml-1"
+                style="flex: 1"
+                prop="operationHistory"
+              >
+                <el-input
+                  class="ml-1"
+                  size="large"
+                  v-model="formData.operationHistory"
+                />
+              </el-form-item>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="footer_btn">
+      <div class="reset" @click="reset(ruleFormRef)">重置</div>
+      <div class="main" @click="save">保存</div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ElectronicCase {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  align-items: center;
+
+  .ele_case_main {
+    width: 90%;
+    height: calc(100vh - 300px);
+    overflow-y: auto;
+
+    .top {
+      padding-bottom: 16px;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+
+      .top_list {
+        display: flex;
+        justify-content: space-around;
+        font-size: 14px;
+        font-weight: 400;
+        color: #2b3f54;
+
+        .top_list_item {
+          margin-right: 48px;
+        }
+      }
+    }
+
+    .basicInfo {
+      // padding-bottom: 16px;
+      margin-top: 16px;
+      border-bottom: 1px solid rgb(91 139 255 / 30%);
+    }
+
+    .title {
+      margin-top: 24px;
+      margin-bottom: 24px;
+      font-size: 18px;
+      font-weight: bold;
+      color: #2b3f54;
+      text-align: center;
+    }
+  }
+
+  .contract {
+    padding: 8px 32px;
+    font-size: 14px;
+    font-weight: 400;
+    color: #999;
+    cursor: pointer;
+
+    span {
+      margin-right: 4px;
+    }
+  }
+
+  .footer_btn {
+    display: flex;
+    justify-content: space-around;
+    height: 50px;
+    margin-top: 8px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/components/PrimaryDiagnosis/index.vue b/src/views/consultation/components/PrimaryDiagnosis/index.vue
new file mode 100644
index 0000000..7c4ea23
--- /dev/null
+++ b/src/views/consultation/components/PrimaryDiagnosis/index.vue
@@ -0,0 +1,477 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import {
+  queryPrimaryCanChooseList,
+  modifyPrimaryDiseaselnfo
+} from "@/api/inquiry";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import {
+  queryRecordForPrimaryChoose,
+  savePrimary,
+  queryPrimaryDetailInfo
+} from "@/api/consultation";
+import { useRoute } from "vue-router";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+
+defineOptions({
+  name: "PrimaryDiagnosis"
+});
+const drawer = ref(false);
+const loading = ref(false);
+const formData = reactive({
+  primaryDiagnosisId: "",
+  patientDiseaseInfo: "",
+  askIdList: [],
+  physicalIdList: [],
+  ancillaryIdList: []
+});
+
+const primaryDiagnosisList = ref([]);
+const route = useRoute();
+const askList = ref([]);
+const displayAskData = ref([]);
+const bodyList = ref([]);
+const displayBodyList = ref<any>([]);
+const supportList = ref([]);
+const displaySupportData = ref<any>([]);
+const id = ref("");
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  primaryDiagnosisId: [
+    { required: true, message: "请选择", trigger: "change" }
+  ],
+  patientDiseaseInfo: [
+    { required: true, message: "请输入患者病情依据", trigger: "change" }
+  ]
+};
+const editAncillaryIdList = ref([]);
+const editPhysicalIdList = ref([]);
+const editAskIdList = ref([]);
+const editFlag = ref(false);
+const getPrimaryDetailInfo = async id => {
+  const res: any = await queryPrimaryDetailInfo({
+    primaryId: id
+  });
+  for (const key in res.data) {
+    // eslint-disable-next-line no-prototype-builtins
+    if (formData.hasOwnProperty(key)) {
+      if (!res.data[key]) {
+        formData[key] = [];
+      } else {
+        formData[key] = res.data[key];
+      }
+    }
+  }
+  editAskIdList.value = [...formData.askIdList];
+  editPhysicalIdList.value = [...formData.physicalIdList];
+
+  editAncillaryIdList.value = [...formData.ancillaryIdList];
+};
+defineExpose({
+  open(item) {
+    reset();
+    getPrimaryCanChooseList();
+    getRecordForPrimaryChoosec();
+    drawer.value = true;
+    if (item) {
+      editFlag.value = true;
+      id.value = item.id;
+      getPrimaryDetailInfo(item.id);
+    } else {
+      editFlag.value = false;
+    }
+  }
+});
+// 获取初步诊断可选的下拉列表
+const getPrimaryCanChooseList = async () => {
+  const { data } = await queryPrimaryCanChooseList();
+  primaryDiagnosisList.value = [];
+  for (const item of data) {
+    primaryDiagnosisList.value.push({
+      value: item.id,
+      label: item.diseaseNameAlias
+    });
+  }
+};
+const showMore = type => {
+  if (type === 1) {
+    displayAskData.value = askList.value;
+  } else if (type === 2) {
+    displayBodyList.value = bodyList.value;
+  } else {
+    displaySupportData.value = supportList.value;
+  }
+};
+// 查询问诊记录
+const getRecordForPrimaryChoosec = async () => {
+  const res: any = await queryRecordForPrimaryChoose({
+    processId: route.query.processId
+  });
+  askList.value = res.data.askList;
+  displayAskData.value = askList.value.slice(0, 2);
+  bodyList.value = res.data.physicalList;
+  displayBodyList.value = bodyList.value.slice(0, 2);
+  supportList.value = res.data.ancillaryList;
+  displaySupportData.value = supportList.value.slice(0, 2);
+};
+const resetForm = () => {
+  if (!ruleFormRef.value) return;
+  ruleFormRef.value.resetFields();
+};
+const reset = () => {
+  formData.askIdList = [];
+  formData.physicalIdList = [];
+  formData.ancillaryIdList = [];
+  resetForm();
+};
+const closeDialog = () => {
+  drawer.value = false;
+  reset();
+};
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      loading.value = true;
+      const res: any = await savePrimary({
+        ...formData,
+        processId: route.query.processId
+      });
+      loading.value = false;
+      if (res.code === 200) {
+        closeDialog();
+        useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+        useConsultationStoreHooks().getyAskPhysicalHistory(
+          route.query.processId
+        );
+        message("新增成功", { type: "success" });
+        useConsultationStoreHooks().changeBodyResultInfo({
+          name: "",
+          value: "",
+          postion: ""
+        });
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const edit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      loading.value = true;
+      const res: any = await modifyPrimaryDiseaselnfo({
+        id: id.value,
+        patientDiseaseInfo: formData.patientDiseaseInfo,
+        ancillaryIdList: formData.ancillaryIdList,
+        askIdList: formData.askIdList,
+        physicalIdList: formData.physicalIdList
+      });
+      loading.value = false;
+      if (res.code === 200) {
+        closeDialog();
+        useConsultationStoreHooks().getAskPrimaryList(route.query.processId);
+        useConsultationStoreHooks().getyAskPhysicalHistory(
+          route.query.processId
+        );
+        message("保存成功", { type: "success" });
+        useConsultationStoreHooks().changeBodyResultInfo({
+          name: "",
+          value: "",
+          postion: ""
+        });
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div class="PrimaryDiagnosis">
+    <el-drawer
+      size="485"
+      v-model="drawer"
+      :show-close="false"
+      :with-header="false"
+      append-to-body
+    >
+      <div v-loading="loading" class="PrimaryDiagnosis">
+        <div class="header-title">
+          <div class="tip" />
+          <span>初步诊断</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="初步诊断" prop="primaryDiagnosisId">
+            <el-select
+              :disabled="editFlag"
+              filterable
+              v-model="formData.primaryDiagnosisId"
+              placeholder="请输入初步诊断"
+              style="width: 100%"
+            >
+              <el-option
+                v-for="item in primaryDiagnosisList"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="患者病情依据:" prop="patientDiseaseInfo">
+            <el-input
+              :rows="2"
+              type="textarea"
+              v-model="formData.patientDiseaseInfo"
+              placeholder="请输入患者病情依据"
+            />
+          </el-form-item>
+        </el-form>
+        <div class="header-title mt-10">
+          <div class="tip" />
+          <span>诊断依据</span>
+        </div>
+        <div class="line" />
+        <div class="main_content">
+          <div class="title">问诊</div>
+          <div class="table_list" v-show="askList.length > 0">
+            <el-checkbox-group
+              class="table_list_box"
+              v-model="formData.askIdList"
+            >
+              <el-checkbox
+                :disabled="editFlag && editAskIdList.includes(item.nodeId)"
+                class="table_list_item"
+                v-for="(item, index) in displayAskData"
+                :key="index"
+                :label="item.nodeId"
+                >{{ item.name }}</el-checkbox
+              >
+            </el-checkbox-group>
+            <div
+              v-if="displayAskData.length < askList.length"
+              @click="showMore(1)"
+              class="more"
+            >
+              点击加载更多
+            </div>
+          </div>
+
+          <div v-show="askList.length === 0" class="empty_list">
+            <img :src="emptyImg" alt="" />
+            <span>暂无相关数据</span>
+          </div>
+          <div class="title">体格检查</div>
+          <div class="table_list" v-show="bodyList.length > 0">
+            <el-checkbox-group
+              v-show="bodyList.length > 0"
+              class="table_list_box"
+              v-model="formData.physicalIdList"
+            >
+              <el-checkbox
+                :disabled="editFlag && editPhysicalIdList.includes(item.nodeId)"
+                class="table_list_item"
+                v-for="(item, index) in displayBodyList"
+                :key="index"
+                :label="item.nodeId"
+                >{{ item.name }}</el-checkbox
+              >
+            </el-checkbox-group>
+            <div
+              v-if="displayBodyList.length < bodyList.length"
+              @click="showMore(2)"
+              class="more"
+            >
+              点击加载更多
+            </div>
+          </div>
+
+          <div v-show="bodyList.length === 0" class="empty_list">
+            <img :src="emptyImg" alt="" />
+            <span>暂无相关数据</span>
+          </div>
+          <div class="title">辅助检查</div>
+          <div class="table_list" v-show="supportList.length > 0">
+            <el-checkbox-group
+              v-show="supportList.length > 0"
+              class="table_list_box"
+              v-model="formData.ancillaryIdList"
+            >
+              <el-checkbox
+                :disabled="
+                  editFlag && editAncillaryIdList.includes(item.nodeId)
+                "
+                class="table_list_item"
+                v-for="(item, index) in displaySupportData"
+                :key="index"
+                :label="item.nodeId"
+                >{{ item.name }}</el-checkbox
+              >
+            </el-checkbox-group>
+            <div
+              v-if="displaySupportData.length < supportList.length"
+              @click="showMore(3)"
+              class="more"
+            >
+              点击加载更多
+            </div>
+          </div>
+
+          <div v-show="supportList.length === 0" class="empty_list">
+            <img :src="emptyImg" alt="" />
+            <span>暂无相关数据</span>
+          </div>
+        </div>
+
+        <div v-if="!editFlag" class="footer_btn">
+          <div class="reset" @click="reset">重置</div>
+          <div class="main" @click="save(ruleFormRef)">添加诊断</div>
+        </div>
+        <div v-if="editFlag" class="footer_btn">
+          <div class="reset" @click="closeDialog">取消</div>
+          <div class="main" @click="edit(ruleFormRef)">保存</div>
+        </div>
+      </div>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.PrimaryDiagnosis {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 485px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 436px;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+    overflow-y: auto;
+    background: #f8f8f8;
+    border-radius: 6px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .table_list {
+    width: 436px;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+    overflow-y: auto;
+    background: #f8f8f8;
+    border-radius: 6px;
+
+    .table_list_box {
+      display: flex;
+      flex-direction: column;
+    }
+
+    .more {
+      font-size: 12px;
+      font-weight: 400;
+      color: rgb(54 76 99 / 50%);
+      text-align: center;
+      cursor: pointer;
+    }
+
+    :deep(.el-checkbox__inner) {
+      width: 18px;
+      height: 18px;
+      border-radius: 20px;
+    }
+
+    :deep(.el-checkbox__inner::after) {
+      left: 5px;
+      width: 5px;
+      height: 9px;
+      border-width: 2px;
+    }
+  }
+
+  .main_content {
+    height: calc(100vh - 400px);
+    overflow: hidden auto;
+  }
+
+  .footer_btn {
+    display: flex;
+    justify-content: space-around;
+    height: 50px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.PrimaryDiagnosis {
+  .el-checkbox__input.is-checked + .el-checkbox__label {
+    color: unset;
+  }
+}
+</style>
diff --git a/src/views/consultation/components/TabTips/index.vue b/src/views/consultation/components/TabTips/index.vue
new file mode 100644
index 0000000..a7ebd67
--- /dev/null
+++ b/src/views/consultation/components/TabTips/index.vue
@@ -0,0 +1,103 @@
+<script setup lang="ts">
+import AddImg from "@/assets/newInquiry/add_tab.png";
+import PrimaryDiagnosis from "../PrimaryDiagnosis/index.vue";
+import CaseWritingDialog from "../CaseWritingDialog/index.vue";
+import { ref } from "vue";
+defineOptions({
+  name: "TabTips"
+});
+const PrimaryDiagnosisRef = ref();
+const CaseWritingDialogRef = ref();
+const addFlag = ref(true);
+const add = () => {
+  addFlag.value = false;
+};
+const leave = () => {
+  addFlag.value = true;
+};
+const openDiagnosis = () => {
+  PrimaryDiagnosisRef.value.open();
+};
+const openCase = () => {
+  CaseWritingDialogRef.value.open();
+};
+</script>
+
+<template>
+  <div class="TabTips">
+    <div @mouseleave="leave" v-show="!addFlag" class="tab_tip">
+      <div @click="openCase" class="tab_tip_item">
+        <div class="case_img" />
+        <span>病历书写</span>
+      </div>
+      <div @click="openDiagnosis" class="tab_tip_item">
+        <div class="first_img" />
+        <span>初步诊断</span>
+      </div>
+      <!-- <div class="tab_tip_item">
+          <div class="fast_img" />
+          <span>快速问诊</span>
+        </div> -->
+    </div>
+    <img
+      class="add_img"
+      v-show="addFlag"
+      @mouseenter="add"
+      :src="AddImg"
+      alt=""
+    />
+    <PrimaryDiagnosis ref="PrimaryDiagnosisRef" />
+    <CaseWritingDialog ref="CaseWritingDialogRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.TabTips {
+  .add_img {
+    width: 52px;
+    height: 52px;
+    cursor: pointer;
+  }
+
+  .tab_tip {
+    display: flex;
+    align-items: center;
+    justify-content: space-around;
+    width: 224px;
+    height: 52px;
+    padding: 0 24px;
+    cursor: pointer;
+    background: #4287ff;
+    border-radius: 26px;
+    box-shadow: 0 4px 8px 0 rgb(66 135 255 / 30%);
+
+    .tab_tip_item {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      font-size: 12px;
+      font-weight: 400;
+      color: #fff;
+      cursor: pointer;
+
+      div {
+        width: 22px;
+        height: 22px;
+        background-size: 100% 100%;
+      }
+
+      .case_img {
+        background-image: url("@/assets/newInquiry/tab/case.png");
+      }
+
+      .first_img {
+        background-image: url("@/assets/newInquiry/tab/first_inspect.png");
+      }
+
+      .fast_img {
+        background-image: url("@/assets/newInquiry/tab/fast_inspect.png");
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/FooterInspect.vue b/src/views/consultation/components/VoiceInspect/FooterInspect.vue
new file mode 100644
index 0000000..4dfc5f1
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/FooterInspect.vue
@@ -0,0 +1,239 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import voiceIcon from "@/assets/inquiry/voice_icon.png";
+import textTipImg from "@/assets/inquiry/text_tip.png";
+import keyboardImg from "@/assets/inquiry/keyboard.png";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import BodyDialog from "./components/BodyDialog.vue";
+import SuppertDialog from "./components/SuppertDialog.vue";
+// import { askTalk } from "@/api/inquiry";
+import { talkByVideo } from "@/api/consultation";
+import VoiceInquiry from "./voiceInquiry.vue";
+import { onMounted, watch } from "vue";
+import { useRoute } from "vue-router";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "FooterInspect"
+});
+const route = useRoute();
+const cardType = ref(0);
+const isStartFlag = ref(false);
+watch(
+  () => useConsultationStoreHooks().voiceFlag,
+  val => {
+    if (val === true) {
+      cardType.value = 0;
+    }
+  }
+);
+watch(
+  () => useConsultationStoreHooks().voiceStartFlag,
+  val => {
+    isStartFlag.value = val;
+  }
+);
+const dialogVisible = ref(false);
+const bodyDialogRef = ref(null);
+const suppertDialogRef = ref(null);
+const question = ref("");
+
+const changeType = (val: number) => {
+  if (isStartFlag.value) return;
+  if (val === 2) {
+    cardType.value = val;
+  } else {
+    if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
+      cardType.value = val;
+    } else {
+      message("麦克风不可用", { type: "error" });
+    }
+  }
+};
+const sendOption = async () => {
+  if (!question.value) {
+    dialogVisible.value = true;
+    return;
+  }
+  submit(question.value);
+  question.value = "";
+};
+// const submit = async (val: string) => {
+//   const params = {
+//     processId: route.query.processId,
+//     roomKey: "10505",
+//     roomToken: useConsultationStoreHooks().uuid,
+//     text: val
+//   };
+//   const { data } = await askTalk(params);
+//   if (data.type === 2) {
+//     openBodyDialog(data);
+//   }
+//   if (data.type === 3) {
+//     openSuppertDialog(data);
+//   }
+// };
+const emit = defineEmits(["getVideo"]);
+const submit = async (val: string) => {
+  const params = {
+    processId: route.query.processId,
+    text: val
+  };
+  useConsultationStoreHooks().changeVoiceFlag(true);
+  const { data } = await talkByVideo(params);
+  if (data.type === 2) {
+    openBodyDialog(data);
+  }
+  if (data.type === 3) {
+    openSuppertDialog(data);
+  }
+  emit("getVideo", data.voiceBase64);
+};
+// 呼出体格检查弹框
+const openBodyDialog = (item: any) => {
+  bodyDialogRef.value.open(item);
+};
+// 呼出辅助检查弹框
+const openSuppertDialog = (item: any) => {
+  suppertDialogRef.value.open(item);
+};
+onMounted(() => {
+  cardType.value = 0;
+});
+</script>
+
+<template>
+  <div v-if="cardType === 2" class="text_footer">
+    <el-input
+      placeholder="请输入问诊问题"
+      v-model="question"
+      @keyup.enter="sendOption"
+      :maxLength="50"
+    />
+    <div class="btn_list">
+      <img @click="changeType(0)" :src="voiceIcon" alt="" />
+    </div>
+  </div>
+  <div v-if="cardType === 0" class="main_footer">
+    <div @click="changeType(1)" class="main_footer_card">
+      <img style="margin-right: 16px" :src="voiceIcon" alt="" />
+      <span>点击开始问诊</span>
+    </div>
+    <div @click="changeType(2)" class="main_footer_right">
+      <img :src="keyboardImg" alt="" />
+    </div>
+  </div>
+  <VoiceInquiry @save="submit" @changeType="changeType" v-if="cardType === 1" />
+  <BodyDialog ref="bodyDialogRef" />
+  <SuppertDialog ref="suppertDialogRef" />
+  <el-dialog
+    width="560"
+    append-to-body
+    v-model="dialogVisible"
+    :center="true"
+    :show-close="false"
+    custom-class="tipContent"
+  >
+    <div class="tipContent">
+      <div class="tip_content">
+        <img :src="textTipImg" />
+        <div class="title">请输入您要问诊的内容!</div>
+      </div>
+      <div style="text-align: center">
+        <el-button
+          class="btn"
+          size="large"
+          @click="dialogVisible = false"
+          type="primary"
+          >知道了</el-button
+        >
+      </div>
+    </div>
+  </el-dialog>
+</template>
+<style lang="scss" scoped>
+.text_footer {
+  position: absolute;
+  bottom: 24px;
+  display: flex;
+  width: 500px;
+  height: 66px;
+  background: #fff;
+  border-radius: 6px;
+
+  .btn_list {
+    position: absolute;
+    top: 0;
+    right: 16px;
+    display: flex;
+    align-items: center;
+    height: 66px;
+
+    img {
+      width: 24px;
+      height: 24px;
+      margin-right: 16px;
+      cursor: pointer;
+    }
+  }
+}
+
+.main_footer {
+  position: absolute;
+  right: 0;
+  bottom: 24px;
+  display: flex;
+  width: 500px;
+  height: 66px;
+  border-radius: 6px;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  img {
+    width: 24px;
+    height: 24px;
+  }
+
+  .main_footer_card {
+    display: flex;
+    flex: 1;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    background: #fff;
+  }
+
+  .main_footer_right {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 72px;
+    cursor: pointer;
+    background: rgb(66 135 255 / 5%);
+  }
+}
+
+.tipContent {
+  .tip_content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+
+    img {
+      width: 209px;
+      height: 102px;
+    }
+
+    .title {
+      margin-top: 32px;
+      font-size: 22px;
+      font-weight: bold;
+      color: #4287ff;
+    }
+  }
+
+  .btn {
+    width: 168px;
+    margin-top: 64px;
+  }
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/PeopleVideo.vue b/src/views/consultation/components/VoiceInspect/PeopleVideo.vue
new file mode 100644
index 0000000..cbda648
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/PeopleVideo.vue
@@ -0,0 +1,157 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import { downLoadUrl } from "@/utils/auth";
+import { onMounted } from "vue";
+import { loadFileBase64 } from "@/api/utils";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+
+defineOptions({
+  name: "PeopleVideo"
+});
+
+const videoFlag = ref(false);
+const patientSilentVideo = ref("");
+const status = ref(false);
+const videoPlayer = ref();
+const audioUrl = ref("");
+const patientDummyVideo = ref("");
+const changeVideo = async url => {
+  // if (status.value === false) {
+  //   const myAuto = document.getElementById("myAudio");
+  //   audioUrl.value = `data:audio/mp3;base64, ${url}`;
+  //   await myAuto.load();
+  //   myAuto.play();
+  //   const video = document.createElement("video");
+  //   video.src = downLoadUrl(sessionStorage.getItem("patientDummyVideo"));
+  //   video.controls = false;
+  //   video.autoplay = true;
+  //   video.style.width = "100%";
+  //   video.style.height = "100%";
+  //   video.style.objectFit = "cover";
+  //   video.addEventListener("canplaythrough", () => {
+  //     // 添加到页面的某个元素上
+  //     document.getElementById("video_content").appendChild(video);
+  //     status.value = true;
+  //     videoFlag.value = true;
+  //   });
+  //   video.addEventListener("ended", () => {
+  //     // 视频播放完毕后的操作
+  //     videoFlag.value = false;
+  //     status.value = false;
+  //     video.remove();
+  //   });
+  // } else {
+  //   setTimeout(() => {
+  //     changeVideo(url);
+  //   }, 1000);
+  // }
+  if (status.value === false) {
+    // const no_voice = downLoadUrl(sessionStorage.getItem("patientDummyVideo"));
+    const video = document.createElement("video");
+    video.src = `data:video/mp4;base64, ${patientDummyVideo.value}`;
+    video.controls = false;
+    video.autoplay = true;
+    video.style.width = "100%";
+    video.style.height = "100%";
+    video.style.objectFit = "cover";
+    const myAuto = document.getElementById("myAudio");
+    audioUrl.value = `data:audio/mp3;base64, ${url}`;
+    await myAuto.load();
+    video.addEventListener("canplaythrough", () => {
+      // 添加到页面的某个元素上
+      document.getElementById("video_content").appendChild(video);
+      videoFlag.value = true;
+      myAuto.play();
+      status.value = true;
+    });
+
+    myAuto.addEventListener("ended", function () {
+      useConsultationStoreHooks().changeVoiceFlag(false);
+      videoFlag.value = false;
+      status.value = false;
+      video.remove();
+
+      // 在这里可以执行音频播放完毕后的操作
+    });
+  } else {
+    setTimeout(() => {
+      changeVideo(url);
+    }, 1000);
+  }
+};
+defineExpose({
+  openVideo(url) {
+    if (url) {
+      changeVideo(url);
+    } else {
+      videoFlag.value = false;
+    }
+  }
+});
+
+onMounted(async () => {
+  const id = sessionStorage.getItem("patientSilentVideo");
+  patientSilentVideo.value = downLoadUrl(id);
+  patientDummyVideo.value = downLoadUrl(
+    sessionStorage.getItem("patientDummyVideo")
+  );
+  const res: any = await loadFileBase64({
+    fileId: sessionStorage.getItem("patientDummyVideo")
+  });
+  patientDummyVideo.value = res.data;
+});
+// const handleVideoEnded = () => {
+//   // videoFlag.value = false;
+// };
+</script>
+
+<template>
+  <div class="PeopleVideo">
+    <!-- <img v-show="!videoFlag" :src="peopleImg" alt="" /> -->
+    <audio :src="audioUrl" id="myAudio" hidden="true" />
+    <div class="video_content" id="video_content">
+      <video
+        v-show="!videoFlag"
+        ref="videoPlayer"
+        muted
+        loop
+        :src="patientSilentVideo"
+        autoplay
+        :controls="false"
+      />
+
+      <!-- <transition name="fade">
+        <video
+          v-if="videoFlag"
+          muted
+          loop
+          :src="patientDummyVideo"
+          autoplay
+          :controls="false"
+        />
+      </transition> -->
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.PeopleVideo {
+  height: calc(100vh - 350px);
+
+  img {
+    width: 100%;
+    object-fit: cover;
+    height: 100%;
+  }
+
+  .video_content {
+    width: 500px;
+    height: 100%;
+  }
+
+  .video_content video {
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
+  }
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/VirtualHuman.vue b/src/views/consultation/components/VoiceInspect/VirtualHuman.vue
new file mode 100644
index 0000000..56aa075
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/VirtualHuman.vue
@@ -0,0 +1,37 @@
+<script setup lang="ts">
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { watch } from "vue";
+import { ref } from "vue";
+
+defineOptions({
+  name: "virtualHuman"
+});
+const iframeUrl = ref(
+  "https://digital-human.jd.com/#/player/10505?messageboxhide=1&token="
+);
+watch(
+  () => useConsultationStoreHooks().uuid,
+  val => {
+    if (!val) return;
+    iframeUrl.value += val;
+  }
+);
+</script>
+
+<template>
+  <div class="virtualHuman">
+    <iframe
+      width="100%"
+      height="100%"
+      sandbox="allow-scripts allow-same-origin"
+      :src="iframeUrl"
+      allow="camera;microphone"
+      frameborder="0"
+    />
+  </div>
+</template>
+<style lang="scss" scoped>
+.virtualHuman {
+  height: calc(100vh - 350px);
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/VoiceInquiry.vue b/src/views/consultation/components/VoiceInspect/VoiceInquiry.vue
new file mode 100644
index 0000000..a16232b
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/VoiceInquiry.vue
@@ -0,0 +1,167 @@
+<script setup lang="ts">
+import { ref, reactive, onBeforeUnmount } from "vue";
+import AudioRecorder from "js-audio-recorder";
+import { receiveVoiceFile } from "@/api/inquiry";
+import tokeGifImg from "@/assets/inquiry/toke.gif";
+import tokeImg from "@/assets/inquiry/toke.png";
+import { onClickOutside } from "@vueuse/core";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+
+defineOptions({
+  name: "VoiceInquiry"
+});
+const defultText = "正在问诊......";
+const text = ref(defultText);
+const container = ref(null);
+let audioRecorder: any = reactive({ undefined });
+let intervalId: any = reactive({ undefined });
+const recordType = ref("0"); // 0未开始 1 开始录制 2 暂停 3完成
+onMounted(() => {
+  recordType.value = "0";
+  // 使用js-audio-recorder录制音频
+  audioRecorder = new AudioRecorder({
+    sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
+    sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
+    numChannels: 1 // 声道,支持 1 或 2, 默认是1
+  });
+  startRecording();
+  checkSpeaking();
+});
+function checkSpeaking() {
+  intervalId = setInterval(() => {
+    const dataArray = audioRecorder.getRecordAnalyseData();
+    const isSpeaking = Array.from(dataArray).some(value => value > 128);
+    if (isSpeaking) {
+      if (recordType.value === "0") {
+        recordType.value = "1";
+        // startRecording();
+      } else if (recordType.value === "2") {
+        audioRecorder.resume();
+      }
+    } else {
+      if (recordType.value === "1") {
+        audioRecorder.pause();
+        recordType.value = "2";
+      } else if (recordType.value === "2") {
+        stopRecording();
+      }
+    }
+    console.log("Is speaking:", isSpeaking);
+  }, 500); // 每 500 毫秒获取一次音量
+}
+const startRecording = () => {
+  audioRecorder.start();
+};
+async function stopRecording() {
+  recordType.value = "0";
+  clearInterval(intervalId);
+  audioRecorder.stop();
+  const blob = audioRecorder.getWAVBlob();
+  const params = new FormData();
+  params.append("file", blob);
+  const { data } = await receiveVoiceFile(params);
+  text.value = data;
+  recordType.value = "3";
+  sendVoiceOption();
+}
+const emit = defineEmits(["changeType", "save"]);
+
+// const reset = () => {
+//   text.value = defultText;
+//   recordType.value = "0";
+//   startRecording();
+//   checkSpeaking();
+// };
+onClickOutside(container, () => emit("changeType", 0));
+
+const sendVoiceOption = () => {
+  if (!text.value || text.value === defultText) {
+    message("问诊内容不能为空!", { type: "error" });
+  }
+  emit("changeType", 0);
+  emit("save", text.value);
+};
+onBeforeUnmount(() => {
+  audioRecorder.destroy();
+});
+</script>
+
+<template>
+  <div ref="container" class="voiceInquiry">
+    <div class="voice_footer_cotent">
+      <img v-show="recordType === '3'" :src="tokeImg" alt="" />
+      <img v-show="recordType !== '3'" :src="tokeGifImg" alt="" />
+      <span>{{ text }}</span>
+    </div>
+    <!-- <div v-show="recordType === '3'" class="btn_list">
+      <span @click="reset">重置</span>
+      <el-button
+        class="btn"
+        size="large"
+        @click="sendVoiceOption"
+        type="primary"
+        >发送</el-button
+      >
+    </div> -->
+  </div>
+</template>
+<style lang="scss" scoped>
+.voiceInquiry {
+  position: absolute;
+  right: 0;
+  bottom: 24px;
+  z-index: 99999;
+  display: flex;
+  justify-content: center;
+  width: 500px;
+  height: 104px;
+  background-image: url("@/assets/inquiry/voice_bg.png");
+  background-size: 100% 100%;
+  box-shadow: 0 0 8px 0 rgb(0 0 0 / 15%);
+
+  .voice_footer_cotent {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+
+    img {
+      width: 300px;
+      height: 40px;
+      margin-top: 16px;
+      cursor: pointer;
+    }
+
+    span {
+      margin-top: 6px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #364c63;
+    }
+  }
+
+  .btn_list {
+    position: absolute;
+    top: 15px;
+    right: 16px;
+    display: flex;
+    align-items: center;
+    height: 104px;
+
+    span {
+      margin-right: 16px;
+      font-size: 16px;
+      font-weight: 400;
+      color: #4287ff;
+      cursor: pointer;
+    }
+
+    img {
+      width: 24px;
+      height: 24px;
+      margin-right: 16px;
+      cursor: pointer;
+    }
+  }
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/components/BodyDialog.vue b/src/views/consultation/components/VoiceInspect/components/BodyDialog.vue
new file mode 100644
index 0000000..2d7b980
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/components/BodyDialog.vue
@@ -0,0 +1,88 @@
+<script setup lang="ts">
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { reactive } from "vue";
+import { ref } from "vue";
+defineOptions({
+  name: "BodyDialog"
+});
+const selectInfo = reactive({
+  imgUrl: "",
+  name: "",
+  requireLocation: 0,
+  actionId: ""
+});
+defineExpose({
+  open(item) {
+    dialogVisible.value = true;
+    selectInfo.imgUrl = item.itemImage;
+    selectInfo.name = item.itemName;
+    selectInfo.requireLocation = item.requireLocation;
+    selectInfo.actionId = item.actionId;
+  }
+});
+const dialogVisible = ref(false);
+const inspectTipRef = ref(null);
+const submit = () => {
+  dialogVisible.value = false;
+  useConsultationStoreHooks().changeSelectToolInfo({
+    toolName: selectInfo.name,
+    img: selectInfo.imgUrl,
+    id: selectInfo.actionId,
+    requireLocation: selectInfo.requireLocation
+  });
+  useConsultationStoreHooks().changeActivedTabKey(1);
+  useConsultationStoreHooks().changeExhalationFlag(true);
+};
+</script>
+
+<template>
+  <el-dialog
+    width="500"
+    append-to-body
+    :show-close="false"
+    v-model="dialogVisible"
+    custom-class="bodyDialog"
+  >
+    <div class="bodyDialog">
+      <img :src="selectInfo.imgUrl" alt="" />
+      <div class="name">{{ selectInfo.name }}</div>
+      <div class="desc">请确认选择体格检查</div>
+    </div>
+    <template #footer>
+      <el-button size="large" @click="submit" class="footer-btn" type="primary"
+        >确定</el-button
+      >
+      <el-button size="large" class="footer-btn" @click="dialogVisible = false"
+        >取消</el-button
+      >
+    </template>
+    <InspectTip ref="inspectTipRef" />
+  </el-dialog>
+</template>
+<style lang="scss" scoped>
+.bodyDialog {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+
+  img {
+    width: 120px;
+    height: 120px;
+    margin-bottom: 32px;
+  }
+
+  .name {
+    margin-bottom: 16px;
+    font-size: 22px;
+    font-weight: bold;
+    color: #4287ff;
+  }
+
+  .desc {
+    font-size: 14px;
+    font-weight: 400;
+    color: #666;
+  }
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/components/SuppertDialog.vue b/src/views/consultation/components/VoiceInspect/components/SuppertDialog.vue
new file mode 100644
index 0000000..aec115c
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/components/SuppertDialog.vue
@@ -0,0 +1,157 @@
+<script setup lang="ts">
+import { reactive } from "vue";
+import { ref } from "vue";
+import InspectTitleImg from "@/assets/inquiry/inspect_title.png";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import CloseIcon from "@/assets/svg/consultation/close.svg?component";
+defineOptions({
+  name: "SuppertDialog"
+});
+const selectInfo = reactive({
+  name: "",
+  actionType: "",
+  actionId: ""
+});
+defineExpose({
+  open(item) {
+    dialogVisible.value = true;
+    selectInfo.name = item.itemName;
+    selectInfo.actionId = item.actionId;
+    selectInfo.actionType = item.actionType;
+  }
+});
+const dialogVisible = ref(false);
+const submit = () => {
+  dialogVisible.value = false;
+  useConsultationStoreHooks().changeActivedKey(1);
+  const arry = [];
+  arry.push(selectInfo.actionType);
+  arry.push(selectInfo.actionId);
+  useConsultationStoreHooks().supportActionId = arry;
+};
+</script>
+
+<template>
+  <el-dialog
+    width="500"
+    append-to-body
+    :show-close="false"
+    v-model="dialogVisible"
+    custom-class="suppertDialog"
+  >
+    <div class="header-title">
+      <div class="tip" />
+      <span>门诊检查 </span>
+      <CloseIcon @click="dialogVisible = false" class="close" />
+    </div>
+    <div class="line" />
+    <div class="suppertDialog">
+      <img :src="InspectTitleImg" alt="" />
+      <div class="name">请选择您当前可能要做的检查项</div>
+      <el-radio-group v-model="selectInfo.actionId">
+        <el-radio size="large" checked :label="selectInfo.actionId">{{
+          selectInfo.name
+        }}</el-radio>
+      </el-radio-group>
+    </div>
+    <template #footer>
+      <el-button size="large" @click="submit" class="footer-btn" type="primary"
+        >确定</el-button
+      >
+      <el-button size="large" class="footer-btn" @click="dialogVisible = false"
+        >取消</el-button
+      >
+    </template>
+  </el-dialog>
+</template>
+<style lang="scss" scoped>
+.suppertDialog {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+
+  img {
+    width: 210px;
+    height: 102px;
+    margin-bottom: 32px;
+  }
+
+  .line {
+    position: relative;
+    left: 0;
+    width: 450px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .name {
+    margin-bottom: 16px;
+    font-size: 22px;
+    font-weight: bold;
+    color: #4287ff;
+  }
+
+  .header-title {
+    position: relative;
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+
+    .close {
+      position: absolute;
+      top: 6px;
+      right: 0;
+      cursor: pointer;
+    }
+  }
+}
+</style>
+<style lang="scss">
+.suppertDialog {
+  .el-radio__label {
+    font-size: 14px;
+    font-weight: 400;
+    color: #333;
+  }
+
+  /* 自定义单选框的样式 */
+  .el-radio .el-radio__inner {
+    width: 20px;
+    height: 20px;
+    border-radius: 50%; /* 使其成为圆形 */
+  }
+
+  /* 自定义单选框被选中时的样式 */
+  .el-radio.is-checked .el-radio__inner {
+    width: 20px;
+    height: 20px;
+    background-image: url("@/assets/inquiry/check.png");
+    background-size: 100% 100%;
+  }
+
+  .el-radio.is-checked .el-radio__inner::after {
+    display: none;
+  }
+}
+</style>
+<style lang="scss">
+.suppertDialog {
+  .el-dialog__body {
+    padding-top: 0;
+  }
+}
+</style>
diff --git a/src/views/consultation/components/VoiceInspect/index.vue b/src/views/consultation/components/VoiceInspect/index.vue
new file mode 100644
index 0000000..070ecf5
--- /dev/null
+++ b/src/views/consultation/components/VoiceInspect/index.vue
@@ -0,0 +1,42 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+// import VirtualHuman from "./VirtualHuman.vue";
+import FooterInspect from "./FooterInspect.vue";
+import PeopleVideo from "./PeopleVideo.vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+defineOptions({
+  name: "mindInquiry"
+});
+const PeopleVideoRef = ref();
+function generateUUID() {
+  const array = new Uint8Array(16);
+  window.crypto.getRandomValues(array);
+
+  // 设置版本和变体位
+  array[6] = (array[6] & 0x0f) | 0x40; // version 4
+  array[8] = (array[8] & 0x3f) | 0x80; // variant 10
+
+  // 将数组转换为UUID字符串
+  const uuid = Array.from(array)
+    .map(byte => byte.toString(16).padStart(2, "0"))
+    .join("");
+
+  return uuid;
+}
+const getVideo = url => {
+  PeopleVideoRef.value.openVideo(url);
+};
+onMounted(() => {
+  if (!useConsultationStoreHooks().uuid) {
+    useConsultationStoreHooks().changeUUID(generateUUID());
+  }
+});
+</script>
+
+<template>
+  <div class="VoiceInspect">
+    <!-- <VirtualHuman /> -->
+    <PeopleVideo ref="PeopleVideoRef" />
+    <FooterInspect @getVideo="getVideo" />
+  </div>
+</template>
diff --git a/src/views/consultation/index.vue b/src/views/consultation/index.vue
new file mode 100644
index 0000000..e2922e6
--- /dev/null
+++ b/src/views/consultation/index.vue
@@ -0,0 +1,288 @@
+<script setup lang="ts">
+import { onMounted } from "vue";
+import NavBar from "@/components/NavBar/index.vue";
+import FirstConsultation from "./FirstConsultation/index.vue";
+import AssistInspect from "./AssistInspect/index.vue";
+import ConfirmDiagnosis from "./ConfirmDiagnosis/index.vue";
+import ConsultationReview from "./ConsultationReview/index.vue";
+import ConsultationEvaluation from "./ConsultationEvaluation/index.vue";
+import ConsultationRecords from "./ConsultationRecords/index.vue";
+import TipIcon from "@/assets/tip.png";
+// import Evaluate from "./Evaluate/index.vue";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import KnowledgeGraph from "./KnowledgeGraph/index.vue";
+import { computed } from "vue";
+
+defineOptions({
+  name: "Consultation"
+});
+
+const inspectSatus = computed(() => {
+  return useConsultationStoreHooks().inspectSatus;
+});
+const activedIndex = computed(() => {
+  return useConsultationStoreHooks().activedKey;
+});
+const changeIndex = val => {
+  useConsultationStoreHooks().changeActivedKey(val);
+};
+// function generateUUID() {
+//   const array = new Uint8Array(16);
+//   window.crypto.getRandomValues(array);
+
+//   // 设置版本和变体位
+//   array[6] = (array[6] & 0x0f) | 0x40; // version 4
+//   array[8] = (array[8] & 0x3f) | 0x80; // variant 10
+
+//   // 将数组转换为UUID字符串
+//   const uuid = Array.from(array)
+//     .map(byte => byte.toString(16).padStart(2, "0"))
+//     .join("");
+
+//   return uuid;
+// }
+onMounted(async () => {
+  useConsultationStoreHooks().changeInspectSatus(
+    sessionStorage.getItem("inspectSatus")
+  );
+
+  // webSock连接
+  // const userInfo: any = getUserInfo();
+
+  if (sessionStorage.getItem("inspectSatus") === "1") {
+    useConsultationStoreHooks().changeActivedKey(3);
+  } else if (sessionStorage.getItem("inspectSatus") === "2") {
+    useConsultationStoreHooks().changeActivedKey(4);
+  } else {
+    // const res: any = await queryWebSocketUrl();
+    // const id = JSON.parse(userInfo).id;
+    // creatWebSocket(`${res.data}webSocket/${generateUUID()}/${id}`);
+    useConsultationStoreHooks().changeActivedKey(0);
+  }
+});
+</script>
+
+<template>
+  <div class="consultation">
+    <NavBar />
+    <div class="main">
+      <div class="left">
+        <div
+          v-if="inspectSatus === '0'"
+          class="card_item"
+          @click="changeIndex(0)"
+          :class="[activedIndex === 0 ? 'actived' : '']"
+        >
+          <div class="first_item card_item_img" />
+          <span>首次问诊</span>
+        </div>
+        <div
+          v-if="inspectSatus === '1'"
+          class="card_item"
+          @click="changeIndex(3)"
+          :class="[activedIndex === 3 ? 'actived' : '']"
+        >
+          <div class="first_item card_item_img" />
+          <span>问诊回顾 </span>
+        </div>
+
+        <div
+          v-if="inspectSatus === '0'"
+          class="card_item"
+          @click="changeIndex(1)"
+          :class="[activedIndex === 1 ? 'actived' : '']"
+        >
+          <div class="support_item card_item_img" />
+          <span>辅助检查</span>
+        </div>
+        <div
+          v-if="inspectSatus !== '2'"
+          class="card_item"
+          @click="changeIndex(2)"
+          :class="[activedIndex === 2 ? 'actived' : '']"
+        >
+          <div class="confirm_item card_item_img" />
+          <span>确认诊断</span>
+        </div>
+        <div
+          @click="changeIndex(4)"
+          v-if="inspectSatus === '2'"
+          :class="[activedIndex === 4 ? 'actived' : '']"
+          class="card_item"
+        >
+          <div class="evaluate_item card_item_img" />
+          <span>问诊评估</span>
+        </div>
+
+        <div
+          @click="changeIndex(5)"
+          v-if="inspectSatus === '2'"
+          :class="[activedIndex === 5 ? 'actived' : '']"
+          class="card_item"
+        >
+          <div class="knowledge_graph card_item_img" />
+          <span>知识图谱</span>
+        </div>
+        <div
+          @click="changeIndex(6)"
+          v-if="inspectSatus === '2'"
+          :class="[activedIndex === 6 ? 'actived' : '']"
+          class="card_item record"
+        >
+          <div class="record_item card_item_img" />
+          <span>问诊反馈</span>
+          <img :src="TipIcon" alt="" />
+        </div>
+      </div>
+      <div :class="[activedIndex === 0 ? 'first_content' : 'main_content']">
+        <FirstConsultation
+          v-if="inspectSatus === '0'"
+          v-show="activedIndex === 0"
+        />
+        <AssistInspect
+          v-if="inspectSatus === '0'"
+          v-show="activedIndex === 1"
+        />
+        <ConfirmDiagnosis v-if="activedIndex === 2" />
+        <ConsultationReview v-if="activedIndex === 3" />
+        <!-- <Evaluate v-if="activedIndex === 4" /> -->
+        <ConsultationEvaluation v-if="activedIndex === 4" />
+        <KnowledgeGraph v-if="activedIndex === 5" />
+        <ConsultationRecords v-if="activedIndex === 6" />
+      </div>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.consultation {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+  overflow-y: hidden;
+  background-image: url("../../assets/newInquiry/select_bg.png");
+  background-size: 100% 100%;
+
+  .top {
+    width: 100%;
+    height: 80px;
+  }
+
+  .main {
+    display: flex;
+    flex: 1;
+
+    .left {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      width: 152px;
+      padding: 16px;
+
+      .card_item {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        width: 120px;
+        height: 104px;
+        margin-top: 16px;
+        font-size: 18px;
+        font-weight: 400;
+        color: #4287ff;
+        cursor: pointer;
+        background: #fff;
+        border-radius: 6px;
+
+        .card_item_img {
+          width: 40px;
+          height: 40px;
+          margin-bottom: 8px;
+          background-size: 100% 100%;
+        }
+
+        .first_item {
+          background-image: url("../../assets/newInquiry/tab/first_icon.png");
+        }
+
+        .support_item {
+          background-image: url("../../assets/newInquiry/tab/support_icon.png");
+        }
+
+        .confirm_item {
+          background-image: url("../../assets/newInquiry/tab/confirm_icon.png");
+        }
+
+        .evaluate_item {
+          background-image: url("../../assets/newInquiry/tab/evaluate.png");
+        }
+
+        .record_item {
+          background-image: url("../../assets/newInquiry/tab/record.png");
+        }
+
+        .knowledge_graph {
+          background-image: url("../../assets/newInquiry/tab/graph.png");
+        }
+      }
+
+      .actived {
+        color: #fff;
+        background: #4287ff;
+
+        .first_item {
+          background-image: url("../../assets/newInquiry/tab/act_first_icon.png");
+        }
+
+        .support_item {
+          background-image: url("../../assets/newInquiry/tab/act_support_icon.png");
+        }
+
+        .evaluate_item {
+          background-image: url("../../assets/newInquiry/tab/act_evaluate.png");
+        }
+
+        .record_item {
+          background-image: url("../../assets/newInquiry/tab/act_record.png");
+        }
+
+        .confirm_item {
+          background-image: url("../../assets/newInquiry/tab/act_confirm_icon.png");
+        }
+
+        .knowledge_graph {
+          background-image: url("../../assets/newInquiry/tab/act_graph.png");
+        }
+      }
+    }
+
+    .main_content {
+      flex: 1;
+      min-width: 1760px;
+      margin-bottom: 24px;
+      background-image: url("../../assets/newInquiry/main_bg.png");
+      background-size: 100% 100%;
+    }
+
+    .first_content {
+      flex: 1;
+      // min-width: 1760px;
+      margin-bottom: 24px;
+      background-image: url("../../assets/newInquiry/main_bg.png");
+      background-size: 100% 100%;
+    }
+  }
+
+  .record {
+    position: relative;
+
+    img {
+      position: absolute;
+      top: -14px;
+      right: -13px;
+      width: 50px;
+      height: 50px;
+    }
+  }
+}
+</style>
diff --git a/src/views/digitalHuman/addEdit.vue b/src/views/digitalHuman/addEdit.vue
new file mode 100644
index 0000000..1df5364
--- /dev/null
+++ b/src/views/digitalHuman/addEdit.vue
@@ -0,0 +1,290 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { ElMessage, FormInstance, UploadProps } from "element-plus";
+import { Plus, Delete } from "@element-plus/icons-vue";
+import { message } from "@/utils/message";
+// import { useRoute } from "vue-router";
+import { getToken } from "@/utils/auth";
+defineOptions({
+  name: "AddEdit"
+});
+const fileList = ref([]);
+
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+
+const formData = reactive({
+  iconBase64: "",
+  directoryDesc: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  iconBase64: [{ required: true, message: "请选择", trigger: "change" }],
+  directoryDesc: [{ required: true, message: "请输入", trigger: "change" }]
+};
+const handleSuccess: UploadProps["onSuccess"] = response => {
+  formData.iconBase64 = `/virtual-patient-manage/fileManage/downloadFile?fileId=${response.data.id}`;
+};
+const handleRemove = () => {
+  formData.iconBase64 = "";
+  fileList.value = [];
+};
+const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
+  //上传图片格式和大小要求  png|jpg  10M
+  if (
+    rawFile.type !== "image/png" ||
+    rawFile.type == "image/jpg" ||
+    rawFile.type == "image/jpeg"
+  ) {
+    ElMessage.error("上传文件格式务必PNG|JPG|JPEG");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 10) {
+    ElMessage.error("图片大小不能大于10M");
+    return false;
+  }
+
+  return true;
+};
+defineExpose({
+  async open(item) {
+    dialogVisible.value = true;
+    await nextTick();
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  isEditFlag.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const reset = () => {
+  if (isEditFlag.value) {
+    ruleFormRef.value.resetFields([
+      "diagnosticCriteria",
+      "diagnosisAssessmentFlag",
+      "requireCheckFlag",
+      "expectedDiagnosisResult",
+      "normalResult"
+    ]);
+  } else {
+    ruleFormRef.value.resetFields();
+  }
+
+  // refWangEditor.value.valueHtml = "";
+};
+
+const save = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      // formData.result = refWangEditor.value.valueHtml;
+      // const params = {
+      //   ...formData,
+      //   result: refWangEditor.value.valueHtml,
+      //   diseaseId: route.query.id
+      // };
+      if (isEditFlag.value) {
+        // const res: any = await updateSupportInspect({
+        //   ...params,
+        //   id: id.value
+        // });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+          id.value = "";
+        }
+      } else {
+        // const res: any = await addSupportInspect(params);
+        // if (res.code === 200) {
+        //   message("新增成功", { type: "success" });
+        // }
+      }
+      dialogVisible.value = false;
+      emit("update");
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>生成数字人</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="120px"
+        >
+          <el-form-item label="选择数字人形象" prop="code">
+            <div class="upload_img">
+              <el-upload
+                :limit="1"
+                :headers="{
+                  token: getToken()
+                }"
+                action="/virtual-patient-manage/fileManage/uploadFile"
+                list-type="picture-card"
+                :file-list="fileList"
+                :on-success="handleSuccess"
+                :before-upload="beforeUpload"
+                :class="{ hide: formData.iconBase64 !== '' }"
+              >
+                <el-icon><Plus /></el-icon>
+
+                <template #file="{ file }">
+                  <div>
+                    <img
+                      class="el-upload-list__item-thumbnail"
+                      :src="formData.iconBase64"
+                      alt=""
+                    />
+                    <span class="el-upload-list__item-actions">
+                      <span
+                        class="el-upload-list__item-delete"
+                        @click="handleRemove(file)"
+                      >
+                        <el-icon><Delete /></el-icon>
+                      </span>
+                    </span>
+                  </div>
+                </template>
+              </el-upload>
+              <div class="tip">仅支持JPG、PNG格式图片,尺寸420*746</div>
+            </div>
+          </el-form-item>
+          <el-form-item label="说明 " prop="directoryDesc">
+            <el-input
+              :rows="4"
+              :maxLength="500"
+              type="textarea"
+              placeholder="请输入"
+              v-model="formData.directoryDesc"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="reset()">重置</div>
+          <div class="main" @click="save(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  :deep(.el-form-item__label) {
+    font-weight: 400;
+    color: #333;
+  }
+
+  :deep(.hide .el-upload--picture-card) {
+    display: none;
+  }
+
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .upload_img {
+    position: relative;
+    width: 100%;
+
+    .tip {
+      position: absolute;
+      top: 50px;
+      left: 200px;
+      font-size: 12px;
+      font-weight: 400;
+      color: #b4b4b4;
+    }
+  }
+}
+</style>
diff --git a/src/views/digitalHuman/index.vue b/src/views/digitalHuman/index.vue
new file mode 100644
index 0000000..b3b5daa
--- /dev/null
+++ b/src/views/digitalHuman/index.vue
@@ -0,0 +1,133 @@
+<script setup lang="ts">
+import { onMounted, ref } from "vue";
+import AddEdit from "./addEdit.vue";
+import { Edit, Delete } from "@element-plus/icons-vue";
+import { downLoadUrl } from "@/utils/auth";
+const dataList = ref([]);
+const activedId = ref("");
+const AddEditRef = ref();
+const add = () => {
+  AddEditRef.value.open();
+};
+
+const onMouseenter = id => {
+  activedId.value = id;
+};
+const onMouseleave = () => {
+  activedId.value = "";
+};
+const handleCommand = async (e: any) => {
+  if (e === "edit") {
+    // EditMaterialsRef.value.open(0, item);
+  } else {
+    // const res: any = await deleteMaterial({
+    //   id: item.id
+    // });
+    // if (res.code === 200) {
+    //   message("删除成功", { type: "success" });
+    //   getData();
+    // }
+  }
+};
+const getData = () => {};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="digitalHuman main-table">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span> 数字人生成器 </span>
+      </div>
+    </div>
+    <el-row class="mb-6">
+      <el-button size="large" class="btn" @click="add" type="primary"
+        >生成数字人</el-button
+      >
+    </el-row>
+    <div v-show="dataList.length > 0" class="img_card_list">
+      <div
+        class="img_card_item"
+        v-for="(item, index) in dataList"
+        :key="index"
+        @mouseenter.prevent="onMouseenter(item.id)"
+        @mouseleave.prevent="onMouseleave()"
+      >
+        <div class="folder_img">
+          <img :src="downLoadUrl(item.fileResourceId)" alt="" />
+        </div>
+        <div :title="item.materialName" class="name">
+          {{ item.materialName }}
+        </div>
+        <el-dropdown
+          @command="e => handleCommand(e, item)"
+          trigger="click"
+          class="icon"
+        >
+          <moreIcon v-show="activedId === item.id" />
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="edit" :icon="Edit">
+                编辑
+              </el-dropdown-item>
+              <el-dropdown-item command="del" :icon="Delete">
+                删除
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
+    <AddEdit ref="AddEditRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.digitalHuman {
+  .img_card_list {
+    display: flex;
+    flex-wrap: wrap;
+
+    .img_card_item {
+      position: relative;
+      width: 190px;
+      height: 230px;
+      margin-right: 16px;
+      margin-bottom: 16px;
+      cursor: pointer;
+      background: #fff;
+      border-radius: 0 0 12px 12px;
+      box-shadow: 0 2px 4px 0 rgb(0 0 0 / 8%);
+
+      .icon {
+        position: absolute;
+        top: 12px;
+        right: 12px;
+      }
+
+      .folder_img {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 190px;
+        background: #f5f5f5;
+
+        img {
+          width: 130px;
+          height: 130px;
+        }
+      }
+
+      .name {
+        width: 200px;
+        padding: 8px 16px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/components/addFolder.vue b/src/views/generalRules/materialCenter/components/addFolder.vue
new file mode 100644
index 0000000..b875ed1
--- /dev/null
+++ b/src/views/generalRules/materialCenter/components/addFolder.vue
@@ -0,0 +1,248 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { addDirectory, updateDirectory } from "@/api/generalRules";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+
+defineOptions({
+  name: "AddFolder"
+});
+
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  id: "",
+  directoryName: "",
+  directoryDesc: ""
+});
+
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  directoryName: [{ required: true, message: "请选择", trigger: "change" }]
+};
+const disposalMethodFlag = ref(false);
+defineExpose({
+  async open(item) {
+    disposalMethodFlag.value = true;
+    dialogVisible.value = true;
+    await nextTick;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (isEditFlag.value) {
+        const res: any = await updateDirectory({
+          ...formData,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      } else {
+        const res: any = await addDirectory({
+          ...formData,
+          id: undefined
+        });
+        if (res.code === 200) {
+          message("新增成功", { type: "success" });
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>新建文件夹</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :maxLength="10"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item label="文件名称 " prop="directoryName">
+            <el-input
+              size="large"
+              v-model="formData.directoryName"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <el-form-item label="说明 " prop="directoryDesc">
+            <el-input
+              :rows="4"
+              :maxLength="500"
+              type="textarea"
+              placeholder="请输入"
+              v-model="formData.directoryDesc"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .normal_list {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+
+    .normal_list_item {
+      margin-bottom: 12px;
+      border: 1px solid #d9d9d9;
+
+      .top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 36px;
+        padding: 0 12px;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #333;
+        background: #f5f7f9;
+
+        .icon {
+          font-size: 16px;
+          cursor: pointer;
+        }
+      }
+    }
+
+    :deep(.el-textarea__inner) {
+      box-shadow: none;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/components/editMaterials.vue b/src/views/generalRules/materialCenter/components/editMaterials.vue
new file mode 100644
index 0000000..4aee189
--- /dev/null
+++ b/src/views/generalRules/materialCenter/components/editMaterials.vue
@@ -0,0 +1,311 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { updateMaterial } from "@/api/generalRules";
+import { ElMessage, FormInstance, UploadProps } from "element-plus";
+import AudioImg from "@/assets/newInquiry/audio_img.png";
+import { message } from "@/utils/message";
+import { getToken } from "@/utils/auth";
+import PlayVideo from "@/components/PlayVideo/index.vue";
+defineOptions({
+  name: "EditMaterials"
+});
+
+const dialogVisible = ref(false);
+const formData = reactive({
+  id: "",
+  fileResourceId: "",
+  materialName: ""
+});
+const materialType = ref(1);
+const materialTypeList = ["图片", "视频", "音频"];
+const tipList = [
+  "单个素材不超过10mb支持jpeg、jpg、png、gif等格式",
+  "单个素材不超过10mb支持.mp4/.mov,清晰度=480p",
+  "单个素材不超过10mb,支持的格式是: mp3、wma、wav"
+];
+const PlayVideoRef = ref();
+const fileType = [
+  ["jpeg", "jpg", "png", "gif"],
+  ["mp4", "mov"],
+  ["mp3", "wma", "wav"]
+];
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  materialName: [{ required: true, message: "请输入", trigger: "change" }],
+  fileResourceId: [{ required: true, message: "请上传", trigger: "change" }]
+};
+const fileUrl = ref("");
+const disposalMethodFlag = ref(false);
+defineExpose({
+  async open(type, item) {
+    disposalMethodFlag.value = true;
+    dialogVisible.value = true;
+    materialType.value = type;
+    await nextTick;
+
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      formData.materialName = formData.materialName.split(".")[0];
+    }
+    fileUrl.value = `/virtual-patient-manage/fileManage/downloadFile?fileId=${formData.fileResourceId}`;
+  }
+});
+
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const handleSuccess: UploadProps["onSuccess"] = response => {
+  if (response.code === 200) {
+    formData.fileResourceId = response.data.id;
+    fileUrl.value = `/virtual-patient-manage/fileManage/downloadFile?fileId=${formData.fileResourceId}`;
+    message("上传成功", { type: "success" });
+  }
+};
+
+const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
+  //上传图片格式和大小要求  png|jpg  10M
+  const type = rawFile.name.split(".")[rawFile.name.split(".").length - 1];
+  if (!fileType[materialType.value].includes(type)) {
+    ElMessage.error("上传文件格式不正确");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 10) {
+    ElMessage.error("大小不能大于10M");
+    return false;
+  }
+
+  return true;
+};
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const res: any = await updateMaterial({
+        ...formData
+      });
+      if (res.code === 200) {
+        message("修改成功", { type: "success" });
+
+        emit("update");
+        dialogVisible.value = false;
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const openFile = val => {
+  PlayVideoRef.value.open(formData.fileResourceId, val);
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>编辑素材</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :maxLength="10"
+          :rules="rules"
+          label-width="80px"
+        >
+          <el-form-item label="素材类型 ">
+            <el-input
+              size="large"
+              readonly
+              v-model="materialTypeList[materialType]"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <el-form-item label="素材名称 " prop="materialName">
+            <el-input
+              size="large"
+              v-model="formData.materialName"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <el-form-item style="font-weight: 700" label="上传素材 ">
+            <video
+              @click="openFile(1)"
+              style="cursor: pointer"
+              v-if="materialType === 1"
+              ref="videoPlayer"
+              :src="fileUrl"
+              :controls="false"
+            />
+            <img
+              style="width: 120px; height: 120px"
+              v-if="materialType === 0"
+              :src="fileUrl"
+              alt=""
+            />
+            <div
+              v-if="materialType === 2"
+              @click="openFile(2)"
+              class="audio_item"
+            >
+              <img :src="AudioImg" alt="" />
+            </div>
+            <el-upload
+              :show-file-list="false"
+              :headers="{
+                token: getToken()
+              }"
+              action="/virtual-patient-manage/fileManage/uploadFile"
+              :on-success="handleSuccess"
+              :before-upload="beforeUpload"
+            >
+              <div class="upload_main">
+                <div class="upload_btn">重新上传</div>
+                <div class="tip">
+                  {{ tipList[materialType] }}
+                </div>
+              </div>
+            </el-upload>
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+    <PlayVideo ref="PlayVideoRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  video {
+    width: 80px;
+    height: 120px;
+  }
+
+  .audio_item {
+    width: 120px;
+    height: 120px;
+    padding: 15px;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+
+    img {
+      width: 90px;
+      height: 90px;
+    }
+  }
+
+  .upload_main {
+    display: flex;
+    flex-direction: column;
+    margin-top: 50px;
+    margin-left: 16px;
+
+    .tip {
+      margin-top: 12px;
+      font-size: 12px;
+      font-weight: 400;
+      color: #b4b4b4;
+    }
+
+    .upload_btn {
+      width: 112px;
+      height: 32px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 32px;
+      color: #333;
+      text-align: center;
+      background: #fff;
+      border: 1px solid #d1d3d6;
+      border-radius: 6px;
+    }
+  }
+
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/components/tableAudio.vue b/src/views/generalRules/materialCenter/components/tableAudio.vue
new file mode 100644
index 0000000..5d6a2f7
--- /dev/null
+++ b/src/views/generalRules/materialCenter/components/tableAudio.vue
@@ -0,0 +1,277 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { deleteMaterial, queryMedicalRecPage } from "@/api/generalRules";
+import { onMounted } from "vue";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import audioImg from "@/assets/newInquiry/audio.png";
+import moreIcon from "@/assets/svg/consultation/more.svg?component";
+import UploadMaterials from "./uploadMaterials.vue";
+import { Edit, Delete } from "@element-plus/icons-vue";
+import EditMaterials from "./editMaterials.vue";
+import PlayVideo from "@/components/PlayVideo/index.vue";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "TableAudio"
+});
+const UploadMaterialsRef = ref();
+const EditMaterialsRef = ref();
+const selectId = ref("");
+const tableList = ref([]);
+const selectName = ref("");
+const activedId = ref("");
+const PlayVideoRef = ref();
+const page = reactive<any>({
+  total: 0,
+  pageSize: 15,
+  pageNum: 1
+});
+
+const getData = async () => {
+  const res: any = await queryMedicalRecPage({
+    materialName: seachForm.materialName,
+    materialType: 2,
+    directoryId: selectId.value,
+    pageNum: page.pageNum,
+    pageSize: page.pageSize
+  });
+  tableList.value = res.data.records;
+  page.total = res.data.total;
+};
+const seachForm = reactive({
+  materialName: ""
+});
+const search = () => {
+  getData();
+};
+const upload = () => {
+  UploadMaterialsRef.value.open(2);
+};
+const handleChange = val => {
+  page.pageNum = val;
+  getData();
+};
+const handleCommand = async (e, item) => {
+  if (e === "edit") {
+    EditMaterialsRef.value.open(2, item);
+  } else {
+    const res: any = await deleteMaterial({
+      id: item.id
+    });
+    if (res.code === 200) {
+      message("删除成功", { type: "success" });
+      getData();
+    }
+  }
+};
+const onMouseenter = id => {
+  activedId.value = id;
+};
+const onMouseleave = () => {
+  activedId.value = "";
+};
+const openFile = val => {
+  PlayVideoRef.value.open(val, 2);
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="audio_card">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>{{ `全部音频(${page.total})` }}</span>
+        <div>
+          <span class="name">{{ selectName }}</span>
+        </div>
+
+        <el-form class="ml-8" :model="seachForm">
+          <el-row>
+            <el-form-item>
+              <el-input
+                style="width: 350px"
+                placeholder="请输入"
+                v-model="seachForm.materialName"
+              />
+            </el-form-item>
+
+            <div class="ml-8 seach_btn" @click="search">搜索</div>
+          </el-row>
+        </el-form>
+        <div class="add_btn" @click="upload">上传素材</div>
+      </div>
+    </div>
+    <div v-show="tableList.length > 0" class="video_list">
+      <div
+        @mouseenter.prevent="onMouseenter(item.id)"
+        @mouseleave.prevent="onMouseleave()"
+        class="video_list_item"
+        v-for="(item, index) in tableList"
+        :key="index"
+      >
+        <img :src="audioImg" alt="" />
+        <span @click="openFile(item.fileResourceId)">{{
+          item.materialName
+        }}</span>
+        <el-dropdown
+          @command="e => handleCommand(e, item)"
+          trigger="click"
+          class="icon"
+        >
+          <moreIcon v-show="activedId === item.id" />
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="edit" :icon="Edit">
+                编辑
+              </el-dropdown-item>
+              <el-dropdown-item command="del" :icon="Delete">
+                删除
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
+    <div v-show="tableList.length === 0" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无可用素材,请先上传</span>
+    </div>
+    <div class="footer">
+      <el-pagination
+        v-if="page.total > 15"
+        @current-change="handleChange"
+        :hide-on-single-page="true"
+        background
+        :default-page-size="15"
+        layout="prev, pager, next"
+        :total="page.total"
+        class="mt-4"
+      />
+    </div>
+    <UploadMaterials @update="getData" ref="UploadMaterialsRef" />
+    <EditMaterials @update="getData" ref="EditMaterialsRef" />
+    <PlayVideo ref="PlayVideoRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.audio_card {
+  position: relative;
+  height: calc(100vh - 200px);
+
+  .video_list {
+    display: flex;
+    flex-wrap: wrap;
+
+    .video_list_item {
+      position: relative;
+      display: flex;
+      align-items: center;
+      width: 33.33%;
+      height: 56px;
+      padding: 17px 18px;
+      line-height: 56px;
+      cursor: pointer;
+
+      img {
+        width: 24px;
+        height: 24px;
+        margin-right: 15px;
+      }
+
+      .icon {
+        position: absolute;
+        right: 20px;
+      }
+    }
+
+    .video_list_item:hover {
+      box-shadow: 0 0 12px 0 rgb(0 0 0 / 15%);
+    }
+  }
+
+  .title {
+    position: relative;
+
+    .name {
+      margin-left: 24px;
+      font-size: 20px;
+      font-weight: 400;
+      color: #333;
+    }
+
+    .add_btn {
+      position: absolute;
+      right: 20px;
+      width: 112px;
+      height: 40px;
+      line-height: 40px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+      box-shadow: 0 2px 0 0 rgb(0 0 0 / 4%);
+    }
+
+    .seach_btn {
+      width: 76px;
+      height: 32px;
+      font-size: 14px;
+      line-height: 32px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 50%;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .folder_btn {
+    position: absolute;
+    right: 160px;
+    display: flex;
+    align-items: center;
+    width: 168px;
+    height: 40px;
+    padding-left: 24px;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+    opacity: 1;
+
+    span {
+      margin-left: 16px;
+      font-size: 16px;
+      color: #333;
+    }
+  }
+
+  .footer {
+    position: absolute;
+    bottom: 20px;
+    display: flex;
+    justify-content: center;
+    width: 100%;
+    margin-top: 32px;
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/components/tableFolder.vue b/src/views/generalRules/materialCenter/components/tableFolder.vue
new file mode 100644
index 0000000..656294d
--- /dev/null
+++ b/src/views/generalRules/materialCenter/components/tableFolder.vue
@@ -0,0 +1,386 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import {
+  getFileDirectory,
+  queryMedicalRecPage,
+  deleteMaterial
+} from "@/api/generalRules";
+import folderImg from "@/assets/newInquiry/folder.png";
+import { onMounted } from "vue";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import viedoImg from "@/assets/newInquiry/viedo.png";
+import AddFolder from "./addFolder.vue";
+import folderIcon from "@/assets/svg/folder.svg?component";
+import moreIcon from "@/assets/svg/consultation/more.svg?component";
+import UploadMaterials from "./uploadMaterials.vue";
+import { ArrowLeft, Edit, Delete } from "@element-plus/icons-vue";
+import EditMaterials from "./editMaterials.vue";
+import PlayVideo from "@/components/PlayVideo/index.vue";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "TableFolder"
+});
+const AddFolderRef = ref();
+const UploadMaterialsRef = ref();
+const EditMaterialsRef = ref();
+const selectId = ref("");
+const detailFlag = ref(false);
+const tableList = ref([]);
+const fileList = ref([]);
+const selectName = ref("");
+const activedId = ref("");
+const PlayVideoRef = ref();
+const page = reactive<any>({
+  total: 0,
+  pageSize: 15,
+  pageNum: 1
+});
+
+const getData = async () => {
+  const res: any = await getFileDirectory({
+    fileName: seachForm.materialName
+  });
+  tableList.value = res.data;
+};
+const openFile = val => {
+  PlayVideoRef.value.open(val, 1);
+};
+const seachForm = reactive({
+  materialName: ""
+});
+const addFolder = () => {
+  AddFolderRef.value.open();
+};
+const search = () => {
+  if (!detailFlag.value) {
+    getData();
+  } else {
+    getFileList();
+  }
+};
+const upload = () => {
+  UploadMaterialsRef.value.open(1, selectId.value);
+};
+const openDetail = item => {
+  selectName.value = item.directoryName;
+  detailFlag.value = true;
+  selectId.value = item.id;
+  getFileList();
+};
+const goBack = () => {
+  selectName.value = "";
+  detailFlag.value = false;
+};
+const getFileList = async () => {
+  const res: any = await queryMedicalRecPage({
+    materialName: seachForm.materialName,
+    materialType: 1,
+    directoryId: selectId.value,
+    pageNum: page.pageNum,
+    pageSize: page.pageSize
+  });
+  fileList.value = res.data.records;
+  page.total = res.data.total;
+};
+const onMouseenter = id => {
+  activedId.value = id;
+};
+const onMouseleave = () => {
+  activedId.value = "";
+};
+const handleChange = val => {
+  page.pageNum = val;
+  getFileList();
+};
+const handleCommand = async (e, item) => {
+  if (e === "edit") {
+    EditMaterialsRef.value.open(1, item);
+  } else {
+    const res: any = await deleteMaterial({
+      id: item.id
+    });
+    if (res.code === 200) {
+      message("删除成功", { type: "success" });
+      getFileList();
+    }
+  }
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="folder_card">
+    <div class="main-table-title">
+      <div class="title">
+        <div v-show="!detailFlag" class="line" />
+        <span v-show="!detailFlag">{{ `全部文件(${tableList.length})` }}</span>
+        <div style="display: flex" v-show="detailFlag">
+          <div @click="goBack" class="back_icon">
+            <el-icon><ArrowLeft /></el-icon>
+            <span>返回</span>
+          </div>
+
+          <span class="name">{{ selectName }}</span>
+        </div>
+
+        <el-form class="ml-8" :model="seachForm">
+          <el-row>
+            <el-form-item>
+              <el-input
+                clearable
+                style="width: 350px"
+                placeholder="请输入"
+                v-model="seachForm.materialName"
+              />
+            </el-form-item>
+
+            <div class="ml-8 seach_btn" @click="search">搜索</div>
+          </el-row>
+        </el-form>
+        <div @click="addFolder" class="folder_btn">
+          <folderIcon />
+          <span>新建文件夹</span>
+        </div>
+        <div class="add_btn" @click="upload">上传素材</div>
+      </div>
+    </div>
+    <div v-show="tableList.length > 0 && !detailFlag" class="folder_card_list">
+      <div
+        class="folder_card_item"
+        v-for="(item, index) in tableList"
+        :key="index"
+        @click="openDetail(item)"
+      >
+        <div class="folder_img">
+          <img :src="folderImg" alt="" />
+        </div>
+        <div class="name">{{ item.directoryName }}</div>
+      </div>
+    </div>
+    <div class="video_list" v-show="detailFlag">
+      <div
+        @mouseenter.prevent="onMouseenter(item.id)"
+        @mouseleave.prevent="onMouseleave()"
+        class="video_list_item"
+        v-for="(item, index) in fileList"
+        :key="index"
+      >
+        <img :src="viedoImg" alt="" />
+        <span @click="openFile(item.fileResourceId)">{{
+          item.materialName.split(".")[0]
+        }}</span>
+        <el-dropdown
+          @command="e => handleCommand(e, item)"
+          trigger="click"
+          class="icon"
+        >
+          <moreIcon v-show="activedId === item.id" />
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="edit" :icon="Edit">
+                编辑
+              </el-dropdown-item>
+              <el-dropdown-item command="del" :icon="Delete">
+                删除
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
+    <div v-show="tableList.length === 0 && !detailFlag" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无可用素材,请先上传</span>
+    </div>
+    <div v-show="fileList.length === 0 && detailFlag" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无可用素材,请先上传</span>
+    </div>
+    <div v-show="detailFlag" class="footer">
+      <el-pagination
+        v-if="page.total > 15 && detailFlag"
+        @current-change="handleChange"
+        :hide-on-single-page="true"
+        background
+        :default-page-size="15"
+        layout="prev, pager, next"
+        :total="page.total"
+        class="mt-4"
+      />
+    </div>
+    <AddFolder @update="getData" ref="AddFolderRef" />
+    <UploadMaterials
+      @update="getFileList"
+      :floderList="tableList"
+      ref="UploadMaterialsRef"
+    />
+    <EditMaterials @update="getFileList" ref="EditMaterialsRef" />
+    <PlayVideo ref="PlayVideoRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.folder_card {
+  position: relative;
+  height: calc(100vh - 200px);
+
+  .back_icon {
+    color: #999;
+    cursor: pointer;
+  }
+
+  .video_list {
+    display: flex;
+    flex-wrap: wrap;
+
+    .video_list_item {
+      position: relative;
+      display: flex;
+      align-items: center;
+      width: 33.33%;
+      height: 56px;
+      padding: 17px 18px;
+      line-height: 56px;
+      cursor: pointer;
+
+      img {
+        width: 24px;
+        height: 24px;
+        margin-right: 15px;
+      }
+
+      .icon {
+        position: absolute;
+        right: 20px;
+      }
+    }
+
+    .video_list_item:hover {
+      box-shadow: 0 0 12px 0 rgb(0 0 0 / 15%);
+    }
+  }
+
+  .folder_card_list {
+    display: flex;
+    flex-wrap: wrap;
+    height: calc(100vh - 250px);
+    overflow: auto;
+
+    .folder_card_item {
+      width: 190px;
+      height: 230px;
+      margin-right: 16px;
+      margin-bottom: 16px;
+      cursor: pointer;
+      background: #fff;
+      border-radius: 0 0 12px 12px;
+      box-shadow: 0 2px 4px 0 rgb(0 0 0 / 8%);
+
+      .folder_img {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 190px;
+        background: #f5f5f5;
+
+        img {
+          width: 130px;
+          height: 130px;
+        }
+      }
+
+      .name {
+        width: 200px;
+        padding: 8px 16px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+
+  .title {
+    position: relative;
+
+    .name {
+      margin-left: 24px;
+      font-size: 20px;
+      font-weight: 400;
+      color: #333;
+    }
+
+    .add_btn {
+      position: absolute;
+      right: 20px;
+      width: 112px;
+      height: 40px;
+      line-height: 40px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+      box-shadow: 0 2px 0 0 rgb(0 0 0 / 4%);
+    }
+
+    .seach_btn {
+      width: 76px;
+      height: 32px;
+      font-size: 14px;
+      line-height: 32px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 50%;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .folder_btn {
+    position: absolute;
+    right: 160px;
+    display: flex;
+    align-items: center;
+    width: 168px;
+    height: 40px;
+    padding-left: 24px;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+    opacity: 1;
+
+    span {
+      margin-left: 16px;
+      font-size: 16px;
+      color: #333;
+    }
+  }
+
+  .footer {
+    position: absolute;
+    bottom: 20px;
+    display: flex;
+    justify-content: center;
+    width: 100%;
+    margin-top: 32px;
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/components/tableImg.vue b/src/views/generalRules/materialCenter/components/tableImg.vue
new file mode 100644
index 0000000..c8f75ad
--- /dev/null
+++ b/src/views/generalRules/materialCenter/components/tableImg.vue
@@ -0,0 +1,287 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { deleteMaterial, queryMedicalRecPage } from "@/api/generalRules";
+import { onMounted } from "vue";
+import emptyImg from "@/assets/newInquiry/empty.png";
+import moreIcon from "@/assets/svg/consultation/more.svg?component";
+import UploadMaterials from "./uploadMaterials.vue";
+import { Edit, Delete } from "@element-plus/icons-vue";
+import EditMaterials from "./editMaterials.vue";
+import { downLoadUrl } from "@/utils/auth";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "TableImg"
+});
+const UploadMaterialsRef = ref();
+const EditMaterialsRef = ref();
+const selectId = ref("");
+const tableList = ref([]);
+const selectName = ref("");
+const activedId = ref("");
+const page = reactive<any>({
+  total: 0,
+  pageSize: 20,
+  pageNum: 1
+});
+
+const getData = async () => {
+  const res: any = await queryMedicalRecPage({
+    materialName: seachForm.materialName,
+    materialType: 0,
+    directoryId: selectId.value,
+    pageNum: page.pageNum,
+    pageSize: page.pageSize
+  });
+  tableList.value = res.data.records;
+  page.total = res.data.total;
+};
+const seachForm = reactive({
+  materialName: ""
+});
+const search = () => {
+  getData();
+};
+const upload = () => {
+  UploadMaterialsRef.value.open(0);
+};
+const handleChange = val => {
+  page.pageNum = val;
+  getData();
+};
+const handleCommand = async (e, item) => {
+  if (e === "edit") {
+    EditMaterialsRef.value.open(0, item);
+  } else {
+    const res: any = await deleteMaterial({
+      id: item.id
+    });
+    if (res.code === 200) {
+      message("删除成功", { type: "success" });
+      getData();
+    }
+  }
+};
+const onMouseenter = id => {
+  activedId.value = id;
+};
+const onMouseleave = () => {
+  activedId.value = "";
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="img_card">
+    <div class="main-table-title">
+      <div class="title">
+        <div class="line" />
+        <span>{{ `全部图片(${page.total})` }}</span>
+        <div>
+          <span class="name">{{ selectName }}</span>
+        </div>
+
+        <el-form class="ml-8" :model="seachForm">
+          <el-row>
+            <el-form-item>
+              <el-input
+                style="width: 350px"
+                placeholder="请输入"
+                v-model="seachForm.materialName"
+              />
+            </el-form-item>
+
+            <div class="ml-8 seach_btn" @click="search">搜索</div>
+          </el-row>
+        </el-form>
+        <div class="add_btn" @click="upload">上传素材</div>
+      </div>
+    </div>
+    <div v-show="tableList.length > 0" class="img_card_list">
+      <div
+        class="img_card_item"
+        v-for="(item, index) in tableList"
+        :key="index"
+        @mouseenter.prevent="onMouseenter(item.id)"
+        @mouseleave.prevent="onMouseleave()"
+      >
+        <div class="folder_img">
+          <img :src="downLoadUrl(item.fileResourceId)" alt="" />
+        </div>
+        <div :title="item.materialName" class="name">
+          {{ item.materialName }}
+        </div>
+        <el-dropdown
+          @command="e => handleCommand(e, item)"
+          trigger="click"
+          class="icon"
+        >
+          <moreIcon v-show="activedId === item.id" />
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item command="edit" :icon="Edit">
+                编辑
+              </el-dropdown-item>
+              <el-dropdown-item command="del" :icon="Delete">
+                删除
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </div>
+    </div>
+    <div v-show="tableList.length === 0" class="empty_list">
+      <img :src="emptyImg" alt="" />
+      <span>暂无可用素材,请先上传</span>
+    </div>
+    <div class="footer">
+      <el-pagination
+        v-if="page.total > 20"
+        @current-change="handleChange"
+        :hide-on-single-page="true"
+        background
+        :default-page-size="20"
+        layout="prev, pager, next"
+        :total="page.total"
+        class="mt-4"
+      />
+    </div>
+    <UploadMaterials @update="getData" ref="UploadMaterialsRef" />
+    <EditMaterials @update="getData" ref="EditMaterialsRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.img_card {
+  position: relative;
+  height: calc(100vh - 200px);
+  overflow: auto;
+
+  .img_card_list {
+    display: flex;
+    flex-wrap: wrap;
+
+    .img_card_item {
+      position: relative;
+      width: 190px;
+      height: 230px;
+      margin-right: 16px;
+      margin-bottom: 16px;
+      cursor: pointer;
+      background: #fff;
+      border-radius: 0 0 12px 12px;
+      box-shadow: 0 2px 4px 0 rgb(0 0 0 / 8%);
+
+      .icon {
+        position: absolute;
+        top: 12px;
+        right: 12px;
+      }
+
+      .folder_img {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        height: 190px;
+        background: #f5f5f5;
+
+        img {
+          width: 130px;
+          height: 130px;
+        }
+      }
+
+      .name {
+        width: 200px;
+        padding: 8px 16px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+  }
+
+  .title {
+    position: relative;
+
+    .name {
+      margin-left: 24px;
+      font-size: 20px;
+      font-weight: 400;
+      color: #333;
+    }
+
+    .add_btn {
+      position: absolute;
+      right: 20px;
+      width: 112px;
+      height: 40px;
+      line-height: 40px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+      box-shadow: 0 2px 0 0 rgb(0 0 0 / 4%);
+    }
+
+    .seach_btn {
+      width: 76px;
+      height: 32px;
+      font-size: 14px;
+      line-height: 32px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 50%;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .folder_btn {
+    position: absolute;
+    right: 160px;
+    display: flex;
+    align-items: center;
+    width: 168px;
+    height: 40px;
+    padding-left: 24px;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+    opacity: 1;
+
+    span {
+      margin-left: 16px;
+      font-size: 16px;
+      color: #333;
+    }
+  }
+
+  .footer {
+    position: absolute;
+    bottom: 20px;
+    display: flex;
+    justify-content: center;
+    width: 100%;
+    margin-top: 32px;
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/components/uploadMaterials.vue b/src/views/generalRules/materialCenter/components/uploadMaterials.vue
new file mode 100644
index 0000000..6ed6ab4
--- /dev/null
+++ b/src/views/generalRules/materialCenter/components/uploadMaterials.vue
@@ -0,0 +1,392 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { uploadMaterial } from "@/api/generalRules";
+import { ElMessage, FormInstance, UploadProps } from "element-plus";
+import { message } from "@/utils/message";
+import UploadImg from "@/assets/newInquiry/upload.png";
+import { getToken } from "@/utils/auth";
+defineOptions({
+  name: "uploadMaterials"
+});
+defineProps({
+  floderList: {
+    type: Array,
+    default: () => []
+  }
+});
+
+const dialogVisible = ref(false);
+const tipList = [
+  "单个素材不超过10mb支持jpeg、jpg、png、gif等格式",
+  "单个素材不超过10mb支持.mp4/.mov,清晰度=480p",
+  "单个素材不超过10mb,支持的格式是: mp3、wma、wav"
+];
+const fileType = [
+  ["jpeg", "jpg", "png", "gif"],
+  ["mp4", "mov"],
+  ["mp3", "wma", "wav"]
+];
+const formData = reactive({
+  id: "",
+  directoryId: "",
+  directoryDesc: ""
+});
+const uploadType = ref(0);
+const ruleFormRef = ref<FormInstance>();
+const fileList = ref([]);
+const rules = {
+  directoryId: [{ required: true, message: "请选择", trigger: "change" }]
+};
+const columns: TableColumnList = [
+  {
+    label: "文件名",
+    prop: "fileName",
+    formatter: ({ fileName }) => {
+      return `${fileName.split(".")[0]}`;
+    }
+  },
+  {
+    label: "大小",
+    prop: "fileSize",
+    formatter: ({ fileSize }) => {
+      return `${fileSize}KB`;
+    }
+  },
+  {
+    label: "状态",
+    prop: "defaultAnswer",
+    slot: "status"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    slot: "operation"
+  }
+];
+defineExpose({
+  async open(type, id) {
+    dialogVisible.value = true;
+    await nextTick;
+    if (id) {
+      formData.directoryId = id;
+    }
+    uploadType.value = type;
+  }
+});
+
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+  fileList.value = [];
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+const handleSuccess: UploadProps["onSuccess"] = response => {
+  if (response.code === 200) {
+    const list = [...fileList.value];
+    list.push(response.data);
+    fileList.value = list;
+  }
+};
+
+const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
+  //上传图片格式和大小要求  png|jpg  10M
+  const type = rawFile.name.split(".")[rawFile.name.split(".").length - 1];
+  if (!fileType[uploadType.value].includes(type)) {
+    ElMessage.error("上传文件格式不正确");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 10) {
+    ElMessage.error("大小不能大于10M");
+    return false;
+  }
+
+  return true;
+};
+const del = index => {
+  fileList.value.splice(index, 1);
+};
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const list = [];
+      for (const item of fileList.value) {
+        list.push({
+          materialType: uploadType.value,
+          fileResourceId: item.id,
+          directoryId: formData.directoryId
+        });
+      }
+      const res: any = await uploadMaterial(list);
+      if (res.code === 200) {
+        message("上传成功", { type: "success" });
+        emit("update");
+        fileList.value = [];
+        dialogVisible.value = false;
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="820"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>上传素材</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :maxLength="10"
+          :rules="rules"
+          label-width=""
+        >
+          <el-form-item
+            v-if="uploadType === 1"
+            label="文件夹 "
+            prop="directoryId"
+          >
+            <el-select
+              style="width: 100%"
+              size="large"
+              filterable
+              v-model="formData.directoryId"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in floderList"
+                :key="item.id"
+                :label="item.directoryName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <div class="upload_card">
+            <img :src="UploadImg" alt="" />
+            <el-upload
+              multiple
+              :show-file-list="false"
+              :headers="{
+                token: getToken()
+              }"
+              action="/virtual-patient-manage/fileManage/uploadFile"
+              :on-success="handleSuccess"
+              :before-upload="beforeUpload"
+            >
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  align-items: center;
+                  justify-content: center;
+                "
+              >
+                <div class="upload_btn">选择文件</div>
+                <p>
+                  {{ tipList[uploadType] }}
+                </p>
+              </div>
+            </el-upload>
+          </div>
+        </el-form>
+        <div>
+          <pure-table
+            v-if="fileList.length > 0"
+            showOverflowTooltip
+            align-whole="center"
+            table-layout="auto"
+            :data="fileList"
+            adaptive
+            :columns="columns"
+            :header-cell-style="{
+              background: 'var(--el-table-row-hover-bg-color)',
+              color: 'var(--el-text-color-primary)'
+            }"
+            ><template #operation="{ index }">
+              <el-button link type="danger" @click="del(index)">删除</el-button>
+            </template>
+            <template #status>
+              <span style="color: #00975e">上传成功</span>
+            </template>
+          </pure-table>
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 800px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .normal_list {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+
+    .normal_list_item {
+      margin-bottom: 12px;
+      border: 1px solid #d9d9d9;
+
+      .top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 36px;
+        padding: 0 12px;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #333;
+        background: #f5f7f9;
+
+        .icon {
+          font-size: 16px;
+          cursor: pointer;
+        }
+      }
+    }
+
+    :deep(.el-textarea__inner) {
+      box-shadow: none;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+
+  .upload_card {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    height: 248px;
+    margin-bottom: 24px;
+    background: #f8f9fa;
+    border: 1px solid #ebedee;
+    border-radius: 6px;
+    opacity: 1;
+
+    img {
+      width: 76px;
+      height: 76px;
+    }
+
+    .upload_btn {
+      width: 112px;
+      height: 40px;
+      margin-top: 16px;
+      font-size: 16px;
+      line-height: 40px;
+      color: #333;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #d1d3d6;
+      border-radius: 6px;
+      opacity: 1;
+    }
+
+    p {
+      margin-top: 16px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #b4b4b4;
+    }
+  }
+}
+</style>
diff --git a/src/views/generalRules/materialCenter/index.vue b/src/views/generalRules/materialCenter/index.vue
new file mode 100644
index 0000000..8021e92
--- /dev/null
+++ b/src/views/generalRules/materialCenter/index.vue
@@ -0,0 +1,144 @@
+<script setup lang="ts">
+import { ref } from "vue";
+
+import TableFolder from "./components/tableFolder.vue";
+import TableImg from "./components/tableImg.vue";
+import TableAudio from "./components/tableAudio.vue";
+defineOptions({
+  name: "ResponseStrategy"
+});
+
+const tabList = ref([
+  {
+    name: "图片",
+    id: "1"
+  },
+  {
+    name: "视频",
+    id: "2"
+  },
+  {
+    name: "音频",
+    id: "3"
+  }
+]);
+const activedIndex = ref(0);
+const changeTab = val => {
+  activedIndex.value = val;
+};
+</script>
+
+<template>
+  <div class="app-main-content materialCenter">
+    <div class="main-table">
+      <div class="top">
+        <div
+          class="top_item"
+          :class="[index === activedIndex ? 'actived' : '']"
+          v-for="(item, index) in tabList"
+          :key="index"
+          @click="changeTab(index)"
+        >
+          {{ item.name }}
+        </div>
+      </div>
+      <TableImg v-show="activedIndex === 0" />
+      <TableFolder v-show="activedIndex === 1" />
+      <TableAudio v-show="activedIndex === 2" />
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.materialCenter {
+  .top {
+    display: flex;
+    margin-bottom: 25px;
+
+    .top_item {
+      width: 84px;
+      height: 40px;
+      margin-right: 16px;
+      font-size: 18px;
+      font-weight: 400;
+      line-height: 40px;
+      color: #333;
+      text-align: center;
+      cursor: pointer;
+      background: #f1f5f9;
+      border-radius: 20px;
+    }
+
+    .actived {
+      color: #fff;
+      background: #4287ff;
+    }
+  }
+
+  .title {
+    position: relative;
+
+    .add_btn {
+      position: absolute;
+      right: 20px;
+      width: 112px;
+      height: 40px;
+      line-height: 40px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+      box-shadow: 0 2px 0 0 rgb(0 0 0 / 4%);
+    }
+
+    .seach_btn {
+      width: 76px;
+      height: 32px;
+      font-size: 14px;
+      line-height: 32px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .empty_list {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    height: 50%;
+    padding: 16px;
+    margin-top: 8px;
+    margin-bottom: 16px;
+
+    img {
+      width: 200px;
+      height: 120px;
+    }
+  }
+
+  .folder_btn {
+    position: absolute;
+    right: 160px;
+    display: flex;
+    align-items: center;
+    width: 168px;
+    height: 40px;
+    padding-left: 24px;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+    opacity: 1;
+
+    span {
+      margin-left: 16px;
+      font-size: 16px;
+      color: #333;
+    }
+  }
+}
+</style>
diff --git a/src/views/generalRules/responseStrategy/addEdit.vue b/src/views/generalRules/responseStrategy/addEdit.vue
new file mode 100644
index 0000000..33ae155
--- /dev/null
+++ b/src/views/generalRules/responseStrategy/addEdit.vue
@@ -0,0 +1,308 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import { saveQuestionLibrary, updateQuestionLibrary } from "@/api/generalRules";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { queryCommonDictTree } from "@/api/utils";
+import { queryPageList } from "@/api/generalRules";
+defineOptions({
+  name: "AddEdit"
+});
+
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  id: "",
+  dictId: "",
+  dicIdPath: [],
+  description: "",
+  defaultAnswer: ""
+});
+const dictList = ref([]);
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  dictId: [{ required: true, message: "请选择", trigger: "change" }],
+  description: [{ required: true, message: "请输入", trigger: "change" }],
+  defaultAnswer: [{ required: true, message: "请输入", trigger: "change" }]
+};
+const props = {
+  value: "id",
+  label: "nameZh",
+  children: "childDictTreeList",
+  expandTrigger: "hover" as const
+};
+const disposalMethodFlag = ref(false);
+defineExpose({
+  async open(item) {
+    getCommonDictTree();
+    disposalMethodFlag.value = true;
+    dialogVisible.value = true;
+
+    await nextTick;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      handleChange(formData.dicIdPath);
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+  isEditFlag.value = false;
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  formData.dictId = "";
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+
+const getCommonDictTree = async () => {
+  const res: any = await queryCommonDictTree({
+    groupCode: "AQT"
+  });
+  dictList.value = res.data;
+};
+const handleChange = item => {
+  formData.dictId = item[item.length - 1];
+};
+/**请求后端接口检索 */
+const querySearchAsync = async (querySearch, cb) => {
+  let results = [];
+  if (querySearch === "") {
+    cb(results);
+  } else {
+    try {
+      // 请求接口
+      const params = {
+        pageNum: 1,
+        pageSize: 999999,
+        description: querySearch
+      };
+      const res: any = await queryPageList(params);
+      results = res.data.records;
+      cb(results);
+    } catch (error) {
+      message("系统异常", { type: "error" });
+    }
+  }
+};
+
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (isEditFlag.value) {
+        const res: any = await updateQuestionLibrary({
+          ...formData,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      } else {
+        const res: any = await saveQuestionLibrary(formData);
+        if (res.code === 200) {
+          message("新增成功", { type: "success" });
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>应答策略</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item label="问诊类目 " prop="dicIdPath">
+            <el-cascader
+              :disabled="isEditFlag"
+              style="width: 100%"
+              size="large"
+              v-model="formData.dicIdPath"
+              :options="dictList"
+              :props="props"
+              @change="handleChange"
+            />
+          </el-form-item>
+          <el-form-item label="问题 " prop="description">
+            <!-- <el-input
+              size="large"
+              v-model="formData.description"
+              placeholder="请输入"
+            /> -->
+            <el-autocomplete
+              placeholder="请输入"
+              style="width: 100%"
+              size="large"
+              value-key="description"
+              v-model="formData.description"
+              :fetch-suggestions="querySearchAsync"
+            />
+          </el-form-item>
+          <el-form-item label="回答 " prop="defaultAnswer">
+            <el-input
+              size="large"
+              v-model="formData.defaultAnswer"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .normal_list {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+
+    .normal_list_item {
+      margin-bottom: 12px;
+      border: 1px solid #d9d9d9;
+
+      .top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 36px;
+        padding: 0 12px;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #333;
+        background: #f5f7f9;
+
+        .icon {
+          font-size: 16px;
+          cursor: pointer;
+        }
+      }
+    }
+
+    :deep(.el-textarea__inner) {
+      box-shadow: none;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+}
+</style>
diff --git a/src/views/generalRules/responseStrategy/index.vue b/src/views/generalRules/responseStrategy/index.vue
new file mode 100644
index 0000000..52b65fb
--- /dev/null
+++ b/src/views/generalRules/responseStrategy/index.vue
@@ -0,0 +1,153 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+
+import { reactive, ref } from "vue";
+import { queryPageList, talkRasa } from "@/api/generalRules";
+import { onMounted } from "vue";
+
+import AddEdit from "./addEdit.vue";
+import UploadFile from "./uploadFile.vue";
+import { message } from "@/utils/message";
+defineOptions({
+  name: "ResponseStrategy"
+});
+
+const dataList = ref([{}]);
+const loading = ref(false);
+const AddEditRef = ref(null);
+const seachForm = reactive({
+  description: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const UploadFileref = ref();
+const columns: TableColumnList = [
+  {
+    label: "问诊类目",
+    prop: "nameZhPath",
+    minWidth: 150
+  },
+  {
+    label: "问题",
+    prop: "description",
+    minWidth: 240
+  },
+  {
+    label: "回复",
+    prop: "defaultAnswer"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    slot: "operation"
+  }
+];
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    description: seachForm.description
+  };
+  const res: any = await queryPageList(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.description = "";
+  search();
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = item => {
+  AddEditRef.value.open(JSON.parse(JSON.stringify(item)));
+};
+const batchImport = () => {
+  UploadFileref.value.open();
+};
+const dialogueDeployment = async () => {
+  const res: any = await talkRasa();
+  if (res.code === 200) {
+    message("部署成功", { type: "success" });
+  }
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="问题:">
+            <el-input size="large" v-model="seachForm.description" />
+          </el-form-item>
+
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>应答列表</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新建</el-button>
+          <el-button size="large" @click="batchImport" type="primary"
+            >批量导入</el-button
+          >
+          <el-button size="large" @click="dialogueDeployment" type="primary"
+            >对话部署</el-button
+          >
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+        </template>
+      </pure-table>
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+    <UploadFile @update="getData" ref="UploadFileref" />
+  </div>
+</template>
diff --git a/src/views/generalRules/responseStrategy/uploadFile.vue b/src/views/generalRules/responseStrategy/uploadFile.vue
new file mode 100644
index 0000000..75cd2fc
--- /dev/null
+++ b/src/views/generalRules/responseStrategy/uploadFile.vue
@@ -0,0 +1,347 @@
+<script setup lang="ts">
+import { nextTick, ref } from "vue";
+import { ElMessage, UploadProps } from "element-plus";
+import UploadImg from "@/assets/newInquiry/upload.png";
+import fileImg from "@/assets/newInquiry/file.png";
+import { getToken, downLoadUrl } from "@/utils/auth";
+import downloadIcon from "@/assets/svg/consultation/download.svg?component";
+import warnIcon from "@/assets/svg/consultation/warn.svg?component";
+import { message } from "@/utils/message";
+import { reactive } from "vue";
+defineOptions({
+  name: "UploadFile"
+});
+
+const dialogVisible = ref(false);
+
+const fileInfo = reactive({
+  failCount: 0,
+  fileId: "",
+  totalCount: 0,
+  fileName: ""
+});
+defineExpose({
+  async open() {
+    dialogVisible.value = true;
+    await nextTick;
+  }
+});
+
+const resetForm = () => {
+  fileInfo.fileId = "";
+  fileInfo.fileName = "";
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+  emit("update");
+};
+const emit = defineEmits(["update"]);
+const handleSuccess: UploadProps["onSuccess"] = response => {
+  if (response.code === 200) {
+    fileInfo.failCount = response.data.failCount;
+    fileInfo.fileId = response.data.fileId;
+    fileInfo.totalCount = response.data.totalCount;
+  } else {
+    message(response.data, { type: "error" });
+  }
+};
+const downloadFile = (url, fileName) => {
+  const link = document.createElement("a");
+  link.href = url;
+  link.download = fileName;
+  link.click();
+};
+const download = () => {
+  downloadFile(
+    "/virtual-patient-manage/aqLibrary/downloadQuestionLibraryTemplate",
+    "导入模版"
+  );
+};
+const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
+  //上传图片格式和大小要求  png|jpg  10M
+
+  const type = rawFile.name.split(".")[rawFile.name.split(".").length - 1];
+  if (!["xls", "xlsx"].includes(type)) {
+    ElMessage.error("上传文件格式不正确");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 10) {
+    ElMessage.error("大小不能大于10M");
+    return false;
+  }
+  fileInfo.fileName = rawFile.name;
+  return true;
+};
+const downErrorFile = () => {
+  downloadFile(downLoadUrl(fileInfo.fileId), "错误报告");
+};
+const submit = () => {
+  dialogVisible.value = false;
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="820"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>上传数据</span>
+        </div>
+        <div class="line" />
+        <div class="download_card">
+          <p>1.下载导入模板,根据模板提示完善内容</p>
+          <div @click="download" class="download_btn">
+            <downloadIcon />
+            <span>下载模板</span>
+          </div>
+        </div>
+        <div class="upload_card">
+          <span class="title">2.上传完善好的表格</span>
+          <div class="main">
+            <img v-if="!fileInfo.fileName" :src="UploadImg" alt="" />
+            <img v-if="fileInfo.fileName" :src="fileImg" alt="" />
+            <span v-if="fileInfo.fileName">{{ fileInfo.fileName }}</span>
+            <el-upload
+              :limit="5"
+              multiple
+              :show-file-list="false"
+              :headers="{
+                token: getToken()
+              }"
+              action="/virtual-patient-manage/aqLibrary/uploadQuestionLibrary"
+              :on-success="handleSuccess"
+              :before-upload="beforeUpload"
+            >
+              <div
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  align-items: center;
+                  justify-content: center;
+                "
+              >
+                <div class="upload_btn">
+                  {{ fileInfo.fileName ? "重新选择" : "选择文件" }}
+                </div>
+                <p>
+                  按下载模板完善信息后,可直接点击选择文件,选取本地文件进行上传,支持格式:
+                  xls,xlsx
+                </p>
+              </div>
+            </el-upload>
+          </div>
+          <div v-if="fileInfo.fileId" class="tip">
+            <warnIcon class="mr-2" />
+            <span>{{
+              `共导入数据${fileInfo.totalCount}条,失败${fileInfo.failCount}条。可`
+            }}</span>
+            <span @click="downErrorFile" style="color: #6196cc; cursor: pointer"
+              >下载错误报告</span
+            >
+            <span>,修改后重新导入</span>
+          </div>
+        </div>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <!-- <div class="reset" @click="resetForm()">重置</div> -->
+          <div class="main" @click="submit()">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 800px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+
+  .download_card {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    width: 100%;
+    padding: 24px;
+    margin-bottom: 24px;
+    font-size: 16px;
+    font-weight: 400;
+    color: #333;
+    background: #f8f9fa;
+    border: 1px solid #ebedee;
+    border-radius: 6px;
+
+    .download_btn {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 140px;
+      height: 40px;
+      margin-top: 24px;
+      line-height: 40px;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #d1d3d6;
+      border-radius: 6px;
+      opacity: 1;
+
+      span {
+        margin-left: 8px;
+      }
+    }
+  }
+
+  .upload_card {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    width: 100%;
+    padding: 24px;
+    margin-bottom: 24px;
+    background: #f8f9fa;
+    border: 1px solid #ebedee;
+    border-radius: 6px;
+    opacity: 1;
+
+    .tip {
+      display: flex;
+      align-items: center;
+      width: 100%;
+      margin-top: 24px;
+      font-size: 14px;
+      color: #333;
+    }
+
+    .main {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      padding: 32px;
+      background: #fff;
+      border: 1px dashed #bcbfc3;
+    }
+
+    .title {
+      width: 100%;
+      margin-bottom: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      color: #333 !important;
+    }
+
+    img {
+      width: 76px;
+      height: 76px;
+    }
+
+    .upload_btn {
+      width: 112px;
+      height: 40px;
+      margin-top: 16px;
+      font-size: 16px;
+      line-height: 40px;
+      color: #333;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #d1d3d6;
+      border-radius: 6px;
+      opacity: 1;
+    }
+
+    p {
+      margin-top: 16px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #b4b4b4;
+    }
+  }
+}
+</style>
diff --git a/src/views/inquiry/evaluate/index.vue b/src/views/inquiry/evaluate/index.vue
index c6db3d4..575caba 100644
--- a/src/views/inquiry/evaluate/index.vue
+++ b/src/views/inquiry/evaluate/index.vue
@@ -44,7 +44,7 @@ onMounted(() => {
           <div class="evaluate_desc_title">
             <img :src="tipIcon" alt="" />
             <span
-              >该初步评估提供了有关您对病例进行诊治的信息评估类别旁将标记本次诊断成功完成的任务
+              >该初步评估提供了有关您对病历进行诊治的信息评估类别旁将标记本次诊断成功完成的任务
             </span>
           </div>
           <div class="evaluate_text">评估类别:预期诊断结果/初步诊断</div>
@@ -132,9 +132,16 @@ onMounted(() => {
                 .nodeList"
               :key="index"
             >
-              <div class="value">
+              <div v-if="item.correct === 1" class="correct">
+                <span>【正确】</span>
+                <span style="margin-left: 4px">{{ item.recordName }}</span>
+              </div>
+              <div v-if="item.correct === 0" class="error">
                 <span>{{ item.recordName }}</span>
               </div>
+              <div v-if="item.correct === 2" class="value">
+                <span style="padding-left: 60px">{{ item.recordName }}</span>
+              </div>
             </div>
           </div>
         </div>
@@ -195,95 +202,106 @@ onMounted(() => {
 </template>
 <style lang="scss" scoped>
 .evaluate {
-  background-image: url("@/assets/inquiry/main_bg.png");
-  background-size: 100% 100%;
   flex: 1;
   padding: 24px;
-  margin: 0 12px 26px 0;
   padding: 52px 50px 32px 32px;
+  margin: 0 12px 26px 0;
+  background-image: url("@/assets/inquiry/main_bg.png");
+  background-size: 100% 100%;
+
   :deep(.el-collapse-item__header) {
     width: 100%;
     height: 40px;
     background-image: url("@/assets/inquiry/long_title.png");
     background-size: 100% 100%;
   }
+
   .evaluate_main {
-    overflow: auto;
     height: calc(100vh - 295px);
+    overflow: auto;
   }
+
   .title {
-    margin-left: 34px;
     display: flex;
     align-items: center;
+    margin-left: 34px;
+
     span {
+      margin-left: 10px;
       font-size: 16px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #283c51;
-      margin-left: 10px;
     }
   }
+
   :deep(.el-collapse-item__content) {
     padding: 0;
   }
+
   .evaluate_content {
-    background: rgba(91, 139, 255, 0.05);
     padding: 16px;
     margin-top: 8px;
+    background: rgb(91 139 255 / 5%);
   }
+
   :deep(.el-collapse-item) {
     margin-bottom: 24px;
   }
+
   :deep(.el-collapse-item__wrap) {
     background-color: unset !important;
   }
+
   :deep(.el-collapse) {
     border: 0;
   }
+
   .evaluate_text {
     font-size: 14px;
-    font-family: Microsoft YaHei-Regular, Microsoft YaHei;
     font-weight: 400;
     color: #364c63;
   }
+
   .evaluate_desc {
     .evaluate_desc_title {
       display: flex;
       height: 32px;
+
       img {
         width: 20px;
         height: 20px;
       }
+
       span {
+        margin-left: 8px;
         font-size: 12px;
-        font-family: Microsoft YaHei-Regular, Microsoft YaHei;
         font-weight: 400;
         color: #4287ff;
-        margin-left: 8px;
       }
     }
   }
+
   .userDiagnosisResult {
-    border-radius: 6px 6px 6px 6px;
-    border: 1px solid #ffffff;
     padding: 16px;
     margin-top: 8px;
+    border: 1px solid #fff;
+    border-radius: 6px;
+
     .correct {
       font-size: 14px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #0db274;
     }
+
     .error {
+      padding-left: 60px;
       font-size: 14px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #ff3b39;
-      padding-left: 60px;
     }
+
     .value {
       font-size: 14px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
     }
   }
@@ -291,9 +309,9 @@ onMounted(() => {
 </style>
 <style lang="scss">
 .evaluate .el-collapse-item__header:hover {
+  box-sizing: border-box;
+  height: 40px;
   background-image: url("@/assets/inquiry/act_long_title.png");
   background-size: 100% 100%;
-  height: 40px;
-  box-sizing: border-box;
 }
 </style>
diff --git a/src/views/inquiry/inspect/index.vue b/src/views/inquiry/inspect/index.vue
index 423eb8e..c3b3397 100644
--- a/src/views/inquiry/inspect/index.vue
+++ b/src/views/inquiry/inspect/index.vue
@@ -49,7 +49,7 @@ const reset = () => {
     </div>
     <div v-if="isEnd" class="footer">
       <el-button class="footer_item">打印</el-button>
-      <el-button class="footer_item" @click="reset">更换病例</el-button>
+      <el-button class="footer_item" @click="reset">更换病历</el-button>
     </div>
     <FirstInspect v-model:visible="firstInspectVisible" />
     <FinishInspect
@@ -62,47 +62,53 @@ const reset = () => {
 
 <style lang="scss" scoped>
 .inspect {
-  width: 512px;
-  background-image: url(../../../assets/inquiry/inspect_bg.png);
-  margin: 0 12px 26px 24px;
-  background-size: 100% 100%;
   display: flex;
   flex-direction: column;
+  width: 512px;
   height: calc(100vh - 120px);
+  margin: 0 12px 26px 24px;
+  background-image: url("../../../assets/inquiry/inspect_bg.png");
+  background-size: 100% 100%;
+
   .inspect_content {
     flex: 1;
     margin: 0 47px 0 32px;
     overflow-y: auto;
   }
+
   /* 隐藏滚动条(适用于WebKit浏览器,如Chrome和Safari) */
   .inspect_content::-webkit-scrollbar {
-    width: 0em; /* 设置滚动条宽度 */
+    width: 0; /* 设置滚动条宽度 */
   }
 
   .inspect_content::-webkit-scrollbar-thumb {
     background-color: transparent; /* 滚动条颜色,这里设置为透明 */
   }
+
   .footer {
-    height: 130px;
     display: flex;
     align-items: center;
     justify-content: space-around;
+    height: 130px;
+
     .footer_item {
       width: 160px;
       height: 50px;
-      background: #4287ff;
-      box-shadow: inset 0px 4px 8px 0px rgba(255, 255, 255, 0.25),
-        2px 2px 0px 0px rgba(90, 145, 255, 0.4);
-      border-radius: 8px 8px 8px 8px;
-      opacity: 1;
-      color: #fff;
       line-height: 50px;
+      color: #fff;
       text-align: center;
       cursor: pointer;
+      background: #4287ff;
+      border-radius: 8px;
+      box-shadow: inset 0 4px 8px 0 rgb(255 255 255 / 25%),
+        2px 2px 0 0 rgb(90 145 255 / 40%);
+      opacity: 1;
     }
+
     .footer_item:hover {
       background-color: #2473ff;
     }
+
     :deep(button.el-button:active) {
       background-color: #2473ff !important; /* 修改为您希望的激活颜色 */
     }
diff --git a/src/views/inquiry/mainContent/bodyInspect/Details/headerDetails.vue b/src/views/inquiry/mainContent/bodyInspect/Details/headerDetails.vue
index d83cab7..66088fb 100644
--- a/src/views/inquiry/mainContent/bodyInspect/Details/headerDetails.vue
+++ b/src/views/inquiry/mainContent/bodyInspect/Details/headerDetails.vue
@@ -22,9 +22,15 @@ const headerList = ref([
   {
     key: "right_ear",
     name: "耳部",
-    top: 204,
+    top: 145,
     left: 77
   },
+  {
+    key: "right_eye",
+    name: "眼睛",
+    top: 366,
+    left: 60
+  },
   {
     key: "mouth",
     name: "口",
@@ -65,14 +71,16 @@ const inpectClick = item => {
 <style lang="scss" scoped>
 .header_detail {
   position: relative;
+
   .header_detail_img {
     width: 718px;
     height: 715px;
   }
+
   .header_detail_item {
+    position: absolute;
     width: 45px;
     height: 45px;
-    position: absolute;
     cursor: pointer;
   }
 }
diff --git a/src/views/inquiry/mainContent/bodyInspect/peopleBody.vue b/src/views/inquiry/mainContent/bodyInspect/peopleBody.vue
index 482d938..59149c5 100644
--- a/src/views/inquiry/mainContent/bodyInspect/peopleBody.vue
+++ b/src/views/inquiry/mainContent/bodyInspect/peopleBody.vue
@@ -337,230 +337,255 @@ const selectPostion = val => {
 </template>
 <style lang="scss" scoped>
 .peopleBody {
-  flex: 1;
+  position: relative;
   display: flex;
+  flex: 1;
   // align-items: center;
   justify-content: center;
-  position: relative;
-  margin-left: 24px;
   height: calc(100vh - 290px);
+  margin-left: 24px;
   overflow-y: auto;
+
   .body {
+    position: relative;
     width: 720px;
     height: 790px;
     margin-left: 20px;
-    position: relative;
+
     .body_img {
       width: 720px;
       height: 790px;
     }
+
     .body_item {
+      position: absolute;
       width: 36px;
       height: 36px;
-      position: absolute;
       // background-color: #ffffff;
       cursor: pointer;
     }
+
     .body_header {
-      width: 65px;
-      height: 87px;
       position: absolute;
-      cursor: pointer;
       top: 39px;
       left: 340px;
+      width: 65px;
+      height: 87px;
+      cursor: pointer;
     }
+
     .body_chest {
-      width: 115px;
-      height: 123px;
       position: absolute;
-      cursor: pointer;
       top: 165px;
       left: 312px;
+      width: 115px;
+      height: 123px;
+      cursor: pointer;
     }
+
     .body_abdomen {
-      width: 115px;
-      height: 121px;
       position: absolute;
-      cursor: pointer;
       top: 293px;
       left: 312px;
+      width: 115px;
+      height: 121px;
+      cursor: pointer;
     }
+
     .body_left_hand {
-      width: 50px;
-      height: 272px;
       position: absolute;
-      cursor: pointer;
       top: 165px;
       left: 428px;
+      width: 50px;
+      height: 272px;
+      cursor: pointer;
     }
+
     .body_right_hand {
-      width: 50px;
-      height: 284px;
       position: absolute;
-      cursor: pointer;
       top: 165px;
       left: 258px;
+      width: 50px;
+      height: 284px;
+      cursor: pointer;
     }
+
     .body_left_leg {
-      width: 64px;
-      height: 340px;
       position: absolute;
-      cursor: pointer;
       top: 430px;
       left: 376px;
+      width: 64px;
+      height: 340px;
+      cursor: pointer;
     }
+
     .body_right_leg {
-      width: 98px;
-      height: 284px;
       position: absolute;
-      cursor: pointer;
       top: 455px;
       left: 263px;
+      width: 98px;
+      height: 284px;
+      cursor: pointer;
     }
+
     .view_img {
-      width: 311px;
-      height: 311px;
       position: absolute;
       top: 50%; /* 使子元素顶部位于父元素中垂直居中 */
       left: 50%; /* 使子元素左侧位于父元素中水平居中 */
-      transform: translate(-50%, -50%); /* 使用transform属性来水平和垂直居中 */
+      width: 311px;
+      height: 311px;
+      pointer-events: none; /* 使用transform属性来水平和垂直居中 */
       transform: translate(-50%, -50%);
-      pointer-events: none;
     }
   }
+
   .select_tool {
     position: absolute;
     top: 0;
-    right: 0px;
+    right: 0;
     text-align: center;
+
     .select_tool_content {
-      width: 120px;
-      height: 145px;
-      background: rgba(66, 135, 255, 0.05);
-      border-radius: 4px 4px 4px 4px;
-      opacity: 1;
-      border: 1px solid rgba(66, 135, 255, 0.5);
       display: flex;
       flex-direction: column;
       align-items: center;
       justify-content: center;
+      width: 120px;
+      height: 145px;
+      background: rgb(66 135 255 / 5%);
+      border: 1px solid rgb(66 135 255 / 50%);
+      border-radius: 4px;
+      opacity: 1;
+
       img {
         width: 80px;
         height: 80px;
-        background: #ffffff;
-        border-radius: 6px 6px 6px 6px;
+        background: #fff;
+        border-radius: 6px;
       }
+
       span {
+        margin-top: 8px;
         font-size: 16px;
-        font-family: Microsoft YaHei-Regular, Microsoft YaHei;
         font-weight: 400;
         color: #4287ff;
-        margin-top: 8px;
       }
     }
+
     .title {
+      margin-top: 8px;
       font-size: 16px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #364c63;
-      margin-top: 8px;
     }
   }
+
   .whole_body {
     position: absolute;
     top: 0;
     left: 24px;
     text-align: center;
+
     .whole_body_content {
-      width: 120px;
-      height: 145px;
-      background: rgba(66, 135, 255, 0.05);
-      border-radius: 4px 4px 4px 4px;
-      border: 1px solid rgba(66, 135, 255, 0.5);
       display: flex;
       flex-direction: column;
-      justify-content: center;
       align-items: center;
+      justify-content: center;
+      width: 120px;
+      height: 145px;
       cursor: pointer;
+      background: rgb(66 135 255 / 5%);
+      border: 1px solid rgb(66 135 255 / 50%);
+      border-radius: 4px;
+
       img {
         width: 98px;
         height: 130px;
       }
     }
+
     .title {
+      margin-top: 8px;
       font-size: 16px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #364c63;
-      margin-top: 8px;
     }
   }
+
   .body_back {
     position: absolute;
     top: 0;
     left: 24px;
     text-align: center;
+
     .body_back_content {
       display: flex;
       flex-direction: column;
-      justify-content: center;
       align-items: center;
+      justify-content: center;
       cursor: pointer;
+
       img {
         width: 98px;
         height: 130px;
       }
     }
+
     .title {
+      margin-top: 8px;
       font-size: 16px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #364c63;
-      margin-top: 8px;
     }
   }
+
   .result_card {
-    min-height: 105px;
     position: fixed;
-    bottom: 67px;
-    background: rgba(255, 255, 255, 0.8);
-    border-radius: 6px 6px 6px 6px;
-    opacity: 1;
-    border: 1px solid #ffffff;
-    padding: 24px;
-    display: flex;
-    left: 1083px;
+
     /* margin-right: 52px; */
     right: 58px;
+    bottom: 67px;
+    left: 1083px;
     z-index: 1;
+    display: flex;
+    min-height: 105px;
+    padding: 24px;
     font-size: 16px;
-    font-family: Microsoft YaHei-Regular, Microsoft YaHei;
     font-weight: 400;
     color: #283c51;
     pointer-events: none;
+    background: rgb(255 255 255 / 80%);
+    border: 1px solid #fff;
+    border-radius: 6px;
+    opacity: 1;
+
     .result_card_left {
       display: flex;
       flex-direction: column;
       justify-content: center;
-      width: 50px;
+      width: 64px;
     }
+
     .result_card_right {
-      height: 58px;
-      border-left: 1px solid rgba(91, 139, 255, 0.2);
-      padding-left: 16px;
-      margin-left: 16px;
       display: flex;
+      flex: 1;
       flex-wrap: wrap;
       align-items: center;
+      height: 58px;
+      padding-left: 16px;
+      margin-left: 16px;
+      border-left: 1px solid rgb(91 139 255 / 20%);
     }
+
     .result_card_item {
       margin-right: 50px;
     }
   }
 }
+
 /* 隐藏滚动条(适用于WebKit浏览器,如Chrome和Safari) */
 .peopleBody::-webkit-scrollbar {
-  width: 0em; /* 设置滚动条宽度 */
+  width: 0; /* 设置滚动条宽度 */
 }
 
 .peopleBody::-webkit-scrollbar-thumb {
diff --git a/src/views/inquiry/mainContent/mindInquiry/components/voiceInquiry.vue b/src/views/inquiry/mainContent/mindInquiry/components/voiceInquiry.vue
index aea144c..f834fe6 100644
--- a/src/views/inquiry/mainContent/mindInquiry/components/voiceInquiry.vue
+++ b/src/views/inquiry/mainContent/mindInquiry/components/voiceInquiry.vue
@@ -57,22 +57,22 @@ async function stopRecording() {
   recordType.value = "0";
   clearInterval(intervalId);
   audioRecorder.stop();
-  text.value = "识别中...";
   const blob = audioRecorder.getWAVBlob();
   const params = new FormData();
   params.append("file", blob);
   const { data } = await receiveVoiceFile(params);
   text.value = data;
   recordType.value = "3";
+  sendVoiceOption();
 }
 const emit = defineEmits(["changeType", "save"]);
 
-const reset = () => {
-  text.value = defultText;
-  recordType.value = "0";
-  startRecording();
-  checkSpeaking();
-};
+// const reset = () => {
+//   text.value = defultText;
+//   recordType.value = "0";
+//   startRecording();
+//   checkSpeaking();
+// };
 onClickOutside(container, () => emit("changeType", 0));
 
 const sendVoiceOption = () => {
@@ -94,7 +94,7 @@ onBeforeUnmount(() => {
       <img v-show="recordType !== '3'" :src="tokeGifImg" alt="" />
       <span>{{ text }}</span>
     </div>
-    <div v-show="recordType === '3'" class="btn_list">
+    <!-- <div v-show="recordType === '3'" class="btn_list">
       <span @click="reset">重置</span>
       <el-button
         class="btn"
@@ -103,53 +103,56 @@ onBeforeUnmount(() => {
         type="primary"
         >发送</el-button
       >
-    </div>
+    </div> -->
   </div>
 </template>
 <style lang="scss" scoped>
 .voiceInquiry {
-  height: 104px;
-  background-image: url(@/assets/inquiry/voice_bg.png);
-  background-size: 100% 100%;
   position: fixed;
-  width: calc(100vw - 642px);
   bottom: 48px;
   display: flex;
   justify-content: center;
+  width: calc(100vw - 642px);
+  height: 104px;
+  background-image: url("@/assets/inquiry/voice_bg.png");
+  background-size: 100% 100%;
+
   .voice_footer_cotent {
     display: flex;
     flex-direction: column;
     align-items: center;
+
     img {
       width: 300px;
       height: 40px;
       margin-top: 16px;
       cursor: pointer;
     }
+
     span {
+      margin-top: 6px;
       font-size: 14px;
-      font-family: Microsoft YaHei-Regular, Microsoft YaHei;
       font-weight: 400;
       color: #364c63;
-      margin-top: 6px;
     }
   }
 
   .btn_list {
     position: absolute;
+    top: 15px;
     right: 16px;
     display: flex;
-    top: 15px;
     align-items: center;
     height: 104px;
+
     span {
+      margin-right: 16px;
       font-size: 16px;
-      font-family: Inter-Regular, Inter;
       font-weight: 400;
       color: #4287ff;
       cursor: pointer;
-      margin-right: 16px;
     }
+
     img {
       width: 24px;
       height: 24px;
diff --git a/src/views/inquiry/mainContent/mindInquiry/components/voiceInspect.vue b/src/views/inquiry/mainContent/mindInquiry/components/voiceInspect.vue
deleted file mode 100644
index 80d3129..0000000
--- a/src/views/inquiry/mainContent/mindInquiry/components/voiceInspect.vue
+++ /dev/null
@@ -1,196 +0,0 @@
-<script setup lang="ts">
-import { ref, reactive } from "vue";
-import voiceGifImg from "@/assets/inquiry/voice.gif";
-import voiceImg from "@/assets/inquiry/voice.png";
-import AudioRecorder from "js-audio-recorder";
-import { receiveVoiceFile } from "@/api/inquiry";
-defineOptions({
-  name: "VoiceInspect"
-});
-const dialogVisible = ref(false);
-const defultText = "点击【结束】可获取语音转文字信息,再次确认问诊信息是否准确";
-const rc: any = reactive({ undefined });
-const type = ref(0); //0录制中 1 识别中 2 录制完成
-const text = ref(defultText);
-let audioRecorder: any = reactive({ undefined });
-let intervalId: any = reactive({ undefined });
-
-const recordType = ref("0"); // 0未开始 1 开始录制 2 暂停
-defineExpose({
-  async open() {
-    type.value = 0;
-    dialogVisible.value = true;
-    // 使用js-audio-recorder录制音频
-    audioRecorder = new AudioRecorder({
-      sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
-      sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
-      numChannels: 1 // 声道,支持 1 或 2, 默认是1
-    });
-    startRecording();
-    checkSpeaking();
-  },
-  closed() {
-    cancel();
-  }
-});
-function checkSpeaking() {
-  intervalId = setInterval(() => {
-    const dataArray = audioRecorder.getRecordAnalyseData();
-    const isSpeaking = Array.from(dataArray).some(value => value > 128);
-    if (isSpeaking) {
-      if (recordType.value === "0") {
-        recordType.value = "1";
-        // startRecording();
-      } else if (recordType.value === "2") {
-        audioRecorder.resume();
-      }
-    } else {
-      if (recordType.value === "1") {
-        audioRecorder.pause();
-        recordType.value = "2";
-      } else if (recordType.value === "2") {
-        stopRecording();
-      }
-    }
-    console.log("Is speaking:", isSpeaking);
-  }, 500); // 每 500 毫秒获取一次音量
-}
-const startRecording = () => {
-  audioRecorder.start();
-};
-async function stopRecording() {
-  recordType.value = "0";
-  clearInterval(intervalId);
-  audioRecorder.stop();
-  text.value = "识别中...";
-  type.value = 1;
-  const blob = audioRecorder.getWAVBlob();
-  const params = new FormData();
-  params.append("file", blob);
-  const { data } = await receiveVoiceFile(params);
-  type.value = 2;
-  text.value = data;
-}
-
-const start = () => {
-  rc.start();
-};
-const cancel = () => {
-  dialogVisible.value = false;
-  type.value === 0;
-  text.value = defultText;
-};
-const end = async () => {
-  // text.value = "识别中...";
-  // type.value = 1;
-  // rc.pause();
-  // const pcm = rc.getRecord({
-  //   encodeTo: ENCODE_TYPE.WAV
-  // });
-  // const params = new FormData();
-  // params.append("file", pcm);
-  // const { data } = await receiveVoiceFile(params);
-  // rc.clear();
-  // type.value = 2;
-  // text.value = data;
-  stopRecording();
-};
-const emit = defineEmits(["submit"]);
-const submit = () => {
-  emit("submit", text.value);
-};
-const reset = () => {
-  setTimeout(() => {
-    if (type.value === 0) {
-      end();
-    }
-  }, 600000);
-  start();
-  type.value = 0;
-  text.value = defultText;
-};
-</script>
-
-<template>
-  <div>
-    <el-dialog
-      width="500"
-      append-to-body
-      v-model="dialogVisible"
-      :before-close="cancel"
-      custom-class="voiceInspect"
-    >
-      <div class="voiceInspect">
-        <div class="title">正在记录您的问诊信息,建议语音时长不超过1分钟</div>
-        <img v-show="type === 0" :src="voiceGifImg" alt="" />
-        <img v-show="type !== 0" :src="voiceImg" alt="" />
-
-        <div class="content">
-          {{ text }}
-        </div>
-      </div>
-      <template #footer>
-        <el-button
-          v-if="type !== 2"
-          size="large"
-          :disabled="type !== 0"
-          @click="end"
-          class="footer-btn"
-          type="primary"
-          >结束</el-button
-        >
-        <el-button
-          v-if="type === 2"
-          size="large"
-          @click="submit"
-          class="footer-btn"
-          type="primary"
-          >同意并发送</el-button
-        >
-        <el-button
-          v-if="type !== 2"
-          size="large"
-          class="footer-btn"
-          @click="cancel"
-          >取消</el-button
-        >
-        <el-button
-          v-if="type === 2"
-          size="large"
-          class="footer-btn"
-          @click="reset"
-          >重新录制</el-button
-        >
-      </template>
-    </el-dialog>
-  </div>
-</template>
-<style lang="scss" scoped>
-.voiceInspect {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  .title {
-    font-size: 14px;
-    font-family: Microsoft YaHei-Regular, Microsoft YaHei;
-    font-weight: 400;
-    color: #333333;
-  }
-  img {
-    width: 360px;
-    height: 72px;
-    margin: 40px 0;
-  }
-  .content {
-    width: 400px;
-    height: 40px;
-    background: rgba(91, 139, 255, 0.05);
-    border-radius: 0px 0px 0px 0px;
-    font-size: 12px;
-    font-family: Microsoft YaHei-Regular, Microsoft YaHei;
-    font-weight: 400;
-    color: #4287ff;
-    padding: 12px;
-  }
-}
-</style>
diff --git a/src/views/inquiry/mainContent/mindInquiry/virtualHuman.vue b/src/views/inquiry/mainContent/mindInquiry/virtualHuman.vue
index cf8ecba..1ddaaff 100644
--- a/src/views/inquiry/mainContent/mindInquiry/virtualHuman.vue
+++ b/src/views/inquiry/mainContent/mindInquiry/virtualHuman.vue
@@ -6,7 +6,9 @@ import { ref } from "vue";
 defineOptions({
   name: "virtualHuman"
 });
-const iframeUrl = ref("https://digital-human.jd.com/#/player/10505?token=");
+const iframeUrl = ref(
+  "https://digital-human.jd.com/#/player/10505?messageboxhide=1&token="
+);
 watch(
   () => useInquiryStoreHooks().uuid,
   val => {
diff --git a/src/views/inquiryCase/estimate/components/PatientCase.vue b/src/views/inquiryCase/estimate/components/PatientCase.vue
new file mode 100644
index 0000000..13f1779
--- /dev/null
+++ b/src/views/inquiryCase/estimate/components/PatientCase.vue
@@ -0,0 +1,264 @@
+<script setup lang="ts">
+import { findByProcessId } from "@/api/consultation";
+import { queryViewDetails } from "@/api/inquiryCase";
+import { onMounted, reactive, ref } from "vue";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "BasicInfo"
+});
+
+const route = useRoute();
+const dataInfo = ref({
+  processNo: "",
+  medicalRecNo: "",
+  createTime: "",
+  patientSelfDesc: "",
+  patientName: "",
+  patientGender: "",
+  patientAge: "",
+  patientMarriage: "",
+  patientProfession: "",
+  patientPhone: "",
+  nativePlace: "",
+  patientHabitation: "",
+  patientPostcode: "",
+  patientNation: "",
+  patientBirthplace: ""
+});
+const formData = reactive({
+  familyHistoryFlag: undefined,
+  familyHistory: "",
+  previousHistoryFlag: undefined,
+  previousHistory: "",
+  allergyHistoryFlag: undefined,
+  allergyHistory: "",
+  patientSelfDesc: "",
+  personalHistory: "",
+  operationHistoryFlag: undefined,
+  illnessHistory: "",
+  operationHistory: ""
+});
+const resultInfo = reactive({
+  physicalDiagnosisNameList: [],
+  primaryDiseaseNameList: [],
+  ancillaryDiagnosisNameList: [],
+  userName: "",
+  recentTime: ""
+});
+const getDetails = async () => {
+  const res: any = await findByProcessId({
+    processId: route.query.processId
+  });
+  dataInfo.value = res.data.base;
+  for (const key in res.data.processMedical) {
+    // eslint-disable-next-line no-prototype-builtins
+    if (formData.hasOwnProperty(key)) {
+      formData[key] = res.data.processMedical[key];
+    }
+  }
+};
+const getResult = async () => {
+  const res: any = await queryViewDetails({
+    processId: route.query.processId
+  });
+  for (const key in res.data) {
+    // eslint-disable-next-line no-prototype-builtins
+    if (resultInfo.hasOwnProperty(key)) {
+      resultInfo[key] = res.data[key];
+    }
+  }
+};
+const getText = val => {
+  if (val === 1) {
+    return "";
+  } else {
+    return "无";
+  }
+};
+onMounted(() => {
+  getDetails();
+  getResult();
+});
+</script>
+
+<template>
+  <div class="basicInfo-detail">
+    <el-form :model="dataInfo" label-width="100px">
+      <el-row>
+        <el-col :span="3">
+          <el-form-item label="虚拟人:" prop="patientName">
+            <span>201242</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="年龄:" prop="patientAge">
+            <span>{{ dataInfo.patientAge }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="婚姻状态:" prop="patientMarriage">
+            <span>{{ dataInfo.patientMarriage }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="邮编:">
+            <span>{{ dataInfo.patientPostcode }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="3">
+          <el-form-item label="姓名:" prop="patientName">
+            <span>{{ dataInfo.patientName }}</span>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="3">
+          <el-form-item label="职业:" prop="patientProfession">
+            <span>{{ dataInfo.patientProfession }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="民族:">
+            <span>{{ dataInfo.patientNation }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="出生地:" prop="patientBirthplace">
+            <span>{{ dataInfo.patientBirthplace }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="3">
+          <el-form-item label="性别:" prop="patientGender">
+            <span>{{ dataInfo.patientGender }}</span>
+          </el-form-item>
+        </el-col>
+
+        <el-col :span="3">
+          <el-form-item label="电话:" prop="patientPhone">
+            <span>{{ dataInfo.patientPhone }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="3">
+          <el-form-item label="籍贯:">
+            <span>{{ dataInfo.nativePlace }}</span>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="现住址:" prop="patientHabitation">
+            <span>{{ dataInfo.patientHabitation }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+    <div class="content">
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="主诉: " prop="patientSelfDesc">
+            <span>{{ formData.patientSelfDesc }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="现病史: " prop="illnessHistory">
+            <span>{{ formData.illnessHistory }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="过敏史: " prop="allergyHistoryFlag">
+            <span>{{ getText(formData.allergyHistoryFlag) }}</span>
+            <span class="ml-1" v-if="formData.allergyHistoryFlag === 1">{{
+              formData.allergyHistory
+            }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="个人史: " prop="personalHistory">
+            <span>{{ formData.personalHistory }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="家族史: " prop="familyHistoryFlag">
+            <span>{{ getText(formData.familyHistoryFlag) }}</span>
+
+            <span class="ml-1" v-if="formData.familyHistoryFlag === 1">{{
+              formData.familyHistory
+            }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="既往史: " prop="previousHistoryFlag">
+            <span>{{ getText(formData.previousHistoryFlag) }}</span>
+
+            <span class="ml-1" v-if="formData.previousHistoryFlag === 1">{{
+              formData.previousHistory
+            }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row class="item">
+        <el-col :span="24">
+          <el-form-item label="手术史: " prop="operationHistoryFlag">
+            <span>{{ getText(formData.operationHistoryFlag) }}</span>
+            <span class="ml-1" v-if="formData.operationHistoryFlag === 1">{{
+              formData.operationHistory
+            }}</span>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </div>
+    <div class="text">
+      {{ `初步诊断:${resultInfo.primaryDiseaseNameList.join(",")}` }}
+    </div>
+    <div class="text">
+      {{
+        `检查:${resultInfo.physicalDiagnosisNameList.join(
+          ","
+        )} ${resultInfo.ancillaryDiagnosisNameList.join(",")}`
+      }}
+    </div>
+    <div class="text" style="margin: 140px 48px">
+      <span>{{ `医生:${resultInfo.userName}` }}</span>
+      <span style="margin-left: 80px">{{
+        `日期:${resultInfo.recentTime}`
+      }}</span>
+    </div>
+  </div>
+</template>
+<style lang="scss" scoped>
+.basicInfo-detail {
+  :deep(.el-form-item__label) {
+    font-size: 14px;
+    font-weight: 400;
+    color: #333;
+  }
+
+  .content {
+    padding: 24px 48px;
+    padding-top: 16px;
+    padding-left: 48px;
+    font-size: 14px;
+    border-top: 1px solid rgb(91 139 255 / 30%);
+    border-bottom: 1px solid rgb(91 139 255 / 30%);
+  }
+
+  .text {
+    margin-top: 24px;
+    margin-left: 48px;
+    font-size: 14px;
+    font-weight: 400 !important;
+    color: #333 !important;
+  }
+}
+</style>
diff --git a/src/views/inquiryCase/estimate/index.vue b/src/views/inquiryCase/estimate/index.vue
new file mode 100644
index 0000000..3d530c1
--- /dev/null
+++ b/src/views/inquiryCase/estimate/index.vue
@@ -0,0 +1,438 @@
+<script setup lang="ts">
+import { onMounted, reactive, ref } from "vue";
+import PatientCase from "./components/PatientCase.vue";
+import { queryDiagnosisResult } from "@/api/inquiry";
+import {
+  saveProcessEvaluation,
+  queryProcessEvaluation
+} from "@/api/inquiryCase";
+import tipIcon from "@/assets/inquiry/tip.png";
+import router from "@/router";
+import CheckIcon from "@/assets/svg/consultation/check.svg?component";
+import { useRoute } from "vue-router";
+defineOptions({
+  name: "estimate"
+});
+const route = useRoute();
+const state = reactive({
+  dataInfo: undefined
+});
+const columns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlanName"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+  {
+    label: "说明",
+    prop: "guide"
+  }
+];
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const drugRouteList = [
+  {
+    id: 0,
+    name: "口服"
+  },
+  {
+    id: 1,
+    name: "静脉注射"
+  },
+  {
+    id: 2,
+    name: "静脉输液"
+  },
+  {
+    id: 3,
+    name: "皮下注射"
+  },
+  {
+    id: 4,
+    name: "局部用药"
+  },
+  {
+    id: 5,
+    name: "气雾剂/粉雾剂吸入"
+  },
+  {
+    id: 6,
+    name: "雾化吸入"
+  },
+  {
+    id: 7,
+    name: "鞘内注射"
+  }
+];
+const rules = {
+  overview: [{ required: true, message: "请输入", trigger: "change" }]
+};
+const addFlag = ref(true);
+const drugColumns: TableColumnList = [
+  {
+    label: "处置计划",
+    prop: "disposalPlanName"
+  },
+  {
+    label: "药物名称",
+    prop: "drugName"
+  },
+  {
+    label: "用药途径",
+    formatter: ({ drugRoute }) => `${drugRouteList[drugRoute]?.name || ""}`
+  },
+  {
+    label: "用药间隔",
+    prop: "select",
+    formatter: ({ intervalDay, intervalHour }) => {
+      return intervalDay !== null
+        ? intervalDayList[intervalDay]?.name
+        : `${intervalHour}小时`;
+    }
+  },
+  {
+    label: "说明",
+    prop: "guide"
+  }
+];
+const addForm = reactive({
+  overview: ""
+});
+const getDetails = async () => {
+  const { data } = await queryDiagnosisResult({
+    processId: route.query.processId
+  });
+  state.dataInfo = data;
+};
+const save = async () => {
+  const res: any = await saveProcessEvaluation({
+    processId: route.query.processId,
+    overview: addForm.overview
+  });
+  if (res.code === 200) {
+    router.push("/inquiryCase/list");
+    addForm.overview = "";
+  }
+};
+const getProcessEvaluation = async () => {
+  const res: any = await queryProcessEvaluation({
+    processId: route.query.processId
+  });
+  if (res.data) {
+    addForm.overview = res.data.overview;
+    addFlag.value = false;
+    activeName.value = "1";
+  } else {
+    activeName.value = "2";
+    addFlag.value = true;
+  }
+};
+onMounted(() => {
+  getProcessEvaluation();
+  getDetails();
+});
+const activeName = ref("");
+</script>
+<template>
+  <div class="main-table estimate">
+    <el-tabs v-model="activeName">
+      <el-tab-pane label="患者病历" name="1">
+        <PatientCase />
+      </el-tab-pane>
+      <el-tab-pane label="评分概述" name="2">
+        <div class="score">
+          <div class="evaluate_desc evaluate_content">
+            <div class="evaluate_desc_title">
+              <img :src="tipIcon" alt="" />
+              <span
+                >该初步评估提供了有关您对病历进行诊治的信息,评估类别旁将标记√为本次诊断成功完成的任务。
+              </span>
+            </div>
+          </div>
+          <div style="margin: 24px 0">
+            评估类别:包含首次问诊(问诊、体格检查)、辅助检查、确认诊断(确诊、处置计划)三个阶段的诊断评估结果。
+          </div>
+          <el-form :model="addForm" :rules="rules">
+            <el-form-item label="医生评估概述" prop="overview">
+              <el-input
+                :readonly="!addFlag"
+                size="large"
+                style="width: 500px"
+                :rows="4"
+                type="textarea"
+                v-model="addForm.overview"
+              />
+            </el-form-item>
+          </el-form>
+          <div v-if="addFlag" class="btn" @click="save">保存</div>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="预期诊断结果" name="3">
+        <div v-if="state.dataInfo?.expertDiagnosisResult" class="score">
+          <el-row class="evaluate_text">
+            {{
+              `正确诊断:${state.dataInfo?.expertDiagnosisResult.diagnosis} `
+            }}
+          </el-row>
+          <el-row style="margin-top: 16px">您的诊断结果:</el-row>
+          <div class="userDiagnosisResult">
+            <div
+              class="mb-4 userDiagnosisResult_item"
+              v-for="(item, index) in state.dataInfo.expertDiagnosisResult
+                .userDiagnosisResult"
+              :key="index"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.diseaseName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.diseaseName }}</span>
+              </div>
+            </div>
+          </div>
+          <el-row style="margin-top: 16px">预期初诊诊断列表:</el-row>
+          <div
+            class="userDiagnosisResult"
+            v-for="(item, index) in state.dataInfo.expertDiagnosisResult
+              .expertDiagnosisResult"
+            :key="index"
+          >
+            {{ item.diseaseName }}
+          </div>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="初步诊断依据" name="4">
+        <div v-if="state.dataInfo" class="score">
+          <div class="userDiagnosisResult">
+            <div
+              v-for="(item, index) in state.dataInfo.basisPrimaryResultResVO
+                .nodeList"
+              :key="index"
+              class="mb-4 userDiagnosisResult_item"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.recordName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.recordName }}</span>
+              </div>
+            </div>
+          </div>
+          <div
+            class="desc mt-4"
+            v-html="state.dataInfo.basisPrimaryResultResVO.preliminaryDiagnosis"
+          />
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="证实诊断依据" name="5">
+        <div v-if="state.dataInfo" class="score">
+          <div>证实或排除初步诊断的必须项目:</div>
+          <div class="userDiagnosisResult">
+            <div
+              v-for="(item, index) in state.dataInfo.basisConfirmResultResVO
+                .nodeList"
+              :key="index"
+              class="mb-4 userDiagnosisResult_item"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.recordName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.recordName }}</span>
+              </div>
+            </div>
+          </div>
+          <div
+            class="desc mt-4"
+            v-html="state.dataInfo.basisConfirmResultResVO.confirmingDiagnosis"
+          />
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="鉴别依据" name="6">
+        <div v-if="state.dataInfo" class="score">
+          <div>鉴别依据所必须的项目:</div>
+          <div class="userDiagnosisResult">
+            <div
+              v-for="(item, index) in state.dataInfo.basisIdentificationResult
+                .nodeList"
+              :key="index"
+              class="mb-4 userDiagnosisResult_item"
+            >
+              <div v-if="item.correct === 1" class="correct">
+                <CheckIcon />
+                <span style="margin-left: 8px; color: #0db274">{{
+                  item.recordName
+                }}</span>
+              </div>
+              <div v-else class="error">
+                <span>{{ item.recordName }}</span>
+              </div>
+            </div>
+          </div>
+          <div
+            class="desc mt-4"
+            v-html="
+              state.dataInfo.basisIdentificationResult.identificationDiagnosis
+            "
+          />
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="处置方案" name="7">
+        <div v-if="state.dataInfo" class="score">
+          <div class="evaluate_content" style="background-color: #fff">
+            <div class="plan_list">
+              <pure-table
+                border
+                align-whole="center"
+                style="width: 100%"
+                showOverflowTooltip
+                class="mt-4"
+                :data="state.dataInfo.dealPlan.otherTreatmentPlan"
+                :columns="columns"
+                :header-cell-style="{
+                  background: 'var(--el-table-row-hover-bg-color)',
+                  color: 'var(--el-text-color-primary)'
+                }"
+              />
+              <pure-table
+                border
+                align-whole="center"
+                showOverflowTooltip
+                class="mt-4"
+                style="width: 100%"
+                :data="state.dataInfo.dealPlan.drugTreatmentPlan"
+                :columns="drugColumns"
+                :header-cell-style="{
+                  background: 'var(--el-table-row-hover-bg-color)',
+                  color: 'var(--el-text-color-primary)'
+                }"
+              />
+            </div>
+          </div>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+<style lang="scss" scoped>
+.estimate {
+  font-size: 14px;
+
+  .score {
+    padding: 12px 24px;
+
+    :deep(.el-form-item__label) {
+      font-size: 14px;
+      font-weight: 400;
+      color: #333;
+    }
+
+    .btn {
+      width: 80px;
+      height: 36px;
+      margin-left: 100px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 36px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  :deep(.el-tabs) {
+    overflow: auto;
+  }
+
+  .userDiagnosisResult {
+    display: flex;
+    flex-wrap: wrap;
+    width: 100%;
+    padding: 16px;
+    margin-top: 8px;
+    background: #f5f5f5;
+    border: 1px solid rgb(66 135 255 / 30%);
+    border-radius: 6px;
+
+    .userDiagnosisResult_item {
+      width: 50%;
+    }
+
+    .correct {
+      display: flex;
+      font-size: 14px;
+      font-weight: 400;
+      color: #0db274;
+    }
+
+    .error {
+      padding-left: 25px;
+      font-size: 14px;
+      font-weight: 400;
+      color: #2b3f54;
+    }
+
+    .value {
+      font-size: 14px;
+      font-weight: 400;
+    }
+  }
+
+  .evaluate_desc {
+    .evaluate_desc_title {
+      display: flex;
+      align-items: center;
+      height: 32px;
+
+      img {
+        width: 20px;
+        height: 20px;
+      }
+
+      span {
+        margin-left: 8px;
+        font-size: 12px;
+        font-weight: 400;
+        color: #4287ff;
+      }
+    }
+  }
+
+  .evaluate_content {
+    padding: 16px;
+    margin-top: 8px;
+    line-height: 32px;
+    background: rgb(91 139 255 / 5%);
+  }
+}
+</style>
diff --git a/src/views/inquiryCase/list/index.vue b/src/views/inquiryCase/list/index.vue
new file mode 100644
index 0000000..ad10568
--- /dev/null
+++ b/src/views/inquiryCase/list/index.vue
@@ -0,0 +1,197 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+
+import { reactive, ref } from "vue";
+import {
+  queryProcessRecordPage,
+  querySingleDiseaseListByDropList
+} from "@/api/inquiryCase";
+import { onMounted } from "vue";
+
+import router from "@/router";
+defineOptions({
+  name: "InquiryCase"
+});
+
+const dataList = ref([{}]);
+const loading = ref(false);
+const diseaseList = ref([]);
+const seachForm = reactive({
+  studentName: "",
+  diseaseType: "",
+  medicalRecNo: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns = [
+  {
+    label: "问诊编号",
+    prop: "processNo"
+  },
+  {
+    label: "病例编号",
+    prop: "medicalRecNo"
+  },
+  {
+    label: "学生姓名",
+    prop: "studentName"
+  },
+  {
+    label: "疾病分类",
+    prop: "diseaseType"
+  },
+  {
+    label: "状态",
+    prop: "status",
+    slot: "status"
+  },
+  {
+    label: "更新时间",
+    prop: "updateTime"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    width: 200,
+    slot: "operation"
+  }
+];
+const getDiseaseList = async () => {
+  const res: any = await querySingleDiseaseListByDropList({});
+  diseaseList.value = res.data;
+};
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    studentName: seachForm.studentName,
+    diseaseType: seachForm.diseaseType,
+    medicalRecNo: seachForm.medicalRecNo
+  };
+  const res: any = await queryProcessRecordPage(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.studentName = "";
+  seachForm.diseaseType = "";
+  seachForm.medicalRecNo = "";
+  search();
+};
+const openDetail = row => {
+  router.push({
+    path: "/inquiryCase/estimate",
+    query: {
+      processId: row.processId
+    }
+  });
+};
+const estimate = row => {
+  router.push({
+    path: "/inquiryCase/estimate",
+    query: {
+      processId: row.processId
+    }
+  });
+};
+onMounted(() => {
+  getData();
+  getDiseaseList();
+});
+</script>
+
+<template>
+  <div class="app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="学生姓名">
+            <el-input size="large" v-model="seachForm.studentName" />
+          </el-form-item>
+          <el-form-item class="ml-4" label="病例编号">
+            <el-input size="large" v-model="seachForm.medicalRecNo" />
+          </el-form-item>
+          <el-form-item class="ml-4" label="疾病分类" prop="diseaseType">
+            <el-select
+              size="large"
+              filterable
+              v-model="seachForm.diseaseType"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in diseaseList"
+                :key="item.id"
+                :label="item.diseaseNameAlias"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>问诊病历列表</span>
+        </div>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button
+            v-if="row.status !== 3"
+            link
+            type="primary"
+            @click="estimate(row)"
+            >评估</el-button
+          >
+          <el-button link type="primary" @click="openDetail(row)"
+            >详情
+          </el-button>
+        </template>
+        <template #status="{ row }">
+          <span style="color: #00975e" v-if="row.status === 3">已评估</span>
+          <span style="color: #ff3429" v-else>未评估</span>
+        </template>
+      </pure-table>
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+  </div>
+</template>
diff --git a/src/views/inquiryManagement/bodyInspect/list/addEdit.vue b/src/views/inquiryManagement/bodyInspect/list/addEdit.vue
new file mode 100644
index 0000000..80964c6
--- /dev/null
+++ b/src/views/inquiryManagement/bodyInspect/list/addEdit.vue
@@ -0,0 +1,607 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { Plus, Delete, Close, CircleClose } from "@element-plus/icons-vue";
+import {
+  saveConfigPhysicalTool,
+  modifyConfigPhysicalTool,
+  queryPhysicalLocation,
+  queryConfigPhysicalToolDetail
+} from "@/api/inquiryManagement";
+import { ElMessage, FormInstance, UploadProps } from "element-plus";
+import { message } from "@/utils/message";
+import { getToken } from "@/utils/auth";
+import { nextTick } from "vue";
+defineOptions({
+  name: "AddEdit"
+});
+
+const typeList = ref(["采集生命体征", "动作", "观察", "精神状态"]);
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  id: "",
+  toolName: "",
+  iconBase64: "",
+  type: "",
+  requireLocation: undefined,
+  locationList: [],
+  keyword: "",
+  defaultPhysicalIndicatorList: [],
+  keywordList: [],
+  noLocationDefault: "",
+  noLocationDefaultId: ""
+});
+const fileList = ref([]);
+const locationList = ref([]);
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  toolName: [{ required: true, message: "请输入名称", trigger: "change" }],
+  type: [{ required: true, message: "请选择", trigger: "change" }],
+  requireLocation: [{ required: true, message: "请选择", trigger: "change" }],
+  locationList: [{ required: true, message: "请选择", trigger: "change" }]
+};
+
+defineExpose({
+  async open(item) {
+    getPhysicalLocation();
+    dialogVisible.value = true;
+    if (item) {
+      await nextTick;
+      getDetails(item.id);
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+const getDetails = async id => {
+  const res: any = await queryConfigPhysicalToolDetail({ id });
+  for (const key in res.data) {
+    // eslint-disable-next-line no-prototype-builtins
+    if (formData.hasOwnProperty(key)) {
+      formData[key] = res.data[key];
+    }
+  }
+  if (formData.keyword) {
+    formData.keywordList = formData.keyword.split(",");
+  }
+
+  formData.keyword = "";
+  fileList.value = [];
+  if (formData.iconBase64) {
+    fileList.value.push({
+      url: formData.iconBase64
+    });
+  }
+  formData.locationList = [];
+  if (formData.defaultPhysicalIndicatorList) {
+    formData.defaultPhysicalIndicatorList.forEach(e => {
+      formData.locationList.push(e.locationId);
+    });
+  } else {
+    formData.defaultPhysicalIndicatorList = [];
+  }
+
+  formData.noLocationDefault =
+    res.data.noLocationDefaultPhysicalIndicator?.indicatorValue || "";
+  formData.noLocationDefaultId =
+    res.data.noLocationDefaultPhysicalIndicator?.id || "";
+};
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+  fileList.value = [];
+  formData.keywordList = [];
+  isEditFlag.value = false;
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const {
+        iconBase64,
+        type,
+        toolName,
+        requireLocation,
+        defaultPhysicalIndicatorList
+      } = formData;
+      const params = {
+        iconBase64,
+        type,
+        toolName,
+        requireLocation,
+        keyword: formData.keywordList.join(","),
+        defaultPhysicalIndicatorList,
+        noLocationDefaultPhysicalIndicator: {
+          indicatorValue: formData.noLocationDefault,
+          id: formData.noLocationDefaultId
+        }
+      };
+      if (isEditFlag.value) {
+        const res: any = await modifyConfigPhysicalTool({
+          ...params,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      } else {
+        const res: any = await saveConfigPhysicalTool({
+          ...params
+        });
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const handleRemove = () => {
+  formData.iconBase64 = "";
+  fileList.value = [];
+};
+const handleSuccess: UploadProps["onSuccess"] = response => {
+  formData.iconBase64 = `/virtual-patient-manage/fileManage/downloadFile?fileId=${response.data.id}`;
+};
+
+const beforeUpload: UploadProps["beforeUpload"] = async rawFile => {
+  //上传图片格式和大小要求  png|jpg  10M
+  if (
+    rawFile.type !== "image/png" ||
+    rawFile.type == "image/jpg" ||
+    rawFile.type == "image/jpeg"
+  ) {
+    ElMessage.error("上传文件格式务必PNG|JPG|JPEG");
+    return false;
+  } else if (rawFile.size / 1024 / 1024 > 10) {
+    ElMessage.error("图片大小不能大于10M");
+    return false;
+  }
+
+  return true;
+};
+const getPhysicalLocation = async () => {
+  const res: any = await queryPhysicalLocation();
+  locationList.value = res.data;
+};
+const getValue = (type, id) => {
+  let value = "";
+
+  for (const item of formData.defaultPhysicalIndicatorList) {
+    if (item.locationId === id) {
+      value = item[type];
+    }
+  }
+  return value;
+};
+const getItemName = id => {
+  let value = undefined;
+  locationList.value.forEach(e => {
+    if (e.id === id) {
+      value = e.locationName;
+    }
+  });
+  return value;
+};
+const selectLocation = val => {
+  const list = [];
+  for (const item of val) {
+    list.push({
+      locationId: item,
+      indicatorValue: getValue("indicatorValue", item)
+    });
+  }
+  formData.defaultPhysicalIndicatorList = list;
+};
+const delItem = index => {
+  formData.defaultPhysicalIndicatorList.splice(index, 1);
+  const list = [...formData.locationList];
+  list.splice(index, 1);
+  formData.locationList = list;
+};
+const setText = (val, index) => {
+  formData.defaultPhysicalIndicatorList[index].indicatorValue = val;
+};
+const addKeyword = () => {
+  if (formData.keywordList.length === 5) {
+    message("最多添加5个", { type: "error" });
+    return;
+  }
+  if (formData.keyword) {
+    formData.keywordList.push(formData.keyword);
+  }
+  formData.keyword = "";
+};
+const changeFlag = val => {
+  if (val === 1) {
+    formData.noLocationDefault = "";
+  } else {
+    formData.locationList = [];
+  }
+};
+const delKeyWord = index => {
+  formData.keywordList.splice(index, 1);
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>体格检查</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item label="名称" prop="toolName">
+            <el-input size="large" v-model="formData.toolName" />
+          </el-form-item>
+          <el-form-item
+            style="font-weight: 700"
+            label="图片:"
+            prop="iconBase64"
+          >
+            <div class="upload_img">
+              <el-upload
+                :limit="1"
+                :headers="{
+                  token: getToken()
+                }"
+                action="/virtual-patient-manage/fileManage/uploadFile"
+                list-type="picture-card"
+                :file-list="fileList"
+                :on-success="handleSuccess"
+                :before-upload="beforeUpload"
+                :class="{ hide: formData.iconBase64 !== '' }"
+              >
+                <el-icon><Plus /></el-icon>
+
+                <template #file="{ file }">
+                  <div>
+                    <img
+                      class="el-upload-list__item-thumbnail"
+                      :src="formData.iconBase64"
+                      alt=""
+                    />
+                    <span class="el-upload-list__item-actions">
+                      <span
+                        class="el-upload-list__item-delete"
+                        @click="handleRemove(file)"
+                      >
+                        <el-icon><Delete /></el-icon>
+                      </span>
+                    </span>
+                  </div>
+                </template>
+              </el-upload>
+              <div class="tip">
+                建议1:1尺寸,小于10M的JPG、jpeg、PNG格式图片
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="类目" prop="type">
+            <el-select
+              size="large"
+              filterable
+              style="width: 100%"
+              v-model="formData.type"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in typeList"
+                :key="item"
+                :label="item"
+                :value="item"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="固定检查位:" prop="requireLocation">
+            <el-radio-group
+              @change="changeFlag"
+              v-model="formData.requireLocation"
+            >
+              <el-radio :label="0" size="large">不需要</el-radio>
+              <el-radio :label="1" size="large">需要</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item
+            v-if="formData.requireLocation === 1"
+            label="检查位:"
+            prop="locationList"
+          >
+            <el-select
+              size="large"
+              filterable
+              multiple
+              style="width: 100%"
+              v-model="formData.locationList"
+              placeholder="请选择"
+              @change="selectLocation"
+            >
+              <el-option
+                v-for="item in locationList"
+                :key="item.id"
+                :label="item.locationName"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            style="font-weight: 700"
+            label="正常结果:"
+            v-if="formData.requireLocation === 0"
+            prop="noLocationDefault"
+          >
+            <el-input
+              v-model="formData.noLocationDefault"
+              placeholder="请输入"
+              size="large"
+            />
+          </el-form-item>
+          <el-form-item
+            v-show="formData.locationList.length > 0"
+            label="正常结果:"
+            prop="defaultPhysicalIndicatorList"
+          >
+            <div class="normal_list">
+              <div
+                class="normal_list_item"
+                v-for="(item, index) in formData.defaultPhysicalIndicatorList"
+                :key="index"
+              >
+                <div class="top">
+                  <span>{{ getItemName(item.locationId) }}</span>
+                  <el-icon class="icon" @click="delItem(index)"
+                    ><Close
+                  /></el-icon>
+                </div>
+                <el-input
+                  class="time_input"
+                  :rows="2"
+                  :style="{ border: 'none' }"
+                  @change="val => setText(val, index)"
+                  type="textarea"
+                  :maxLength="500"
+                  placeholder="请输入"
+                  v-model="
+                    formData.defaultPhysicalIndicatorList[index].indicatorValue
+                  "
+                />
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item style="margin-bottom: 0" label="关键词:" prop="keyword">
+            <el-input
+              v-model="formData.keyword"
+              style="width: 546px"
+              maxLength="8"
+              @keyup.enter="addKeyword"
+              placeholder="请输入关键词"
+              size="large"
+            />
+            <div @click="addKeyword" class="add_btn">添加</div>
+          </el-form-item>
+          <el-form-item label="">
+            <div class="keyword">
+              <p>可设置呼出关键词,回车Enter键保存,最多可设置5个</p>
+              <div class="keyword_list">
+                <div
+                  class="keyword_list_item"
+                  v-for="(item, index) in formData.keywordList"
+                  :key="index"
+                >
+                  <span>{{ item }}</span>
+                  <el-icon @click="delKeyWord(index)" class="del"
+                    ><CircleClose
+                  /></el-icon>
+                </div>
+                <span
+                  v-if="formData.keywordList.length > 0"
+                  style="margin-left: 10px; color: #a0a0a0"
+                  >{{ `${formData.keywordList.length}/5` }}</span
+                >
+              </div>
+            </div>
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  :deep(.hide .el-upload--picture-card) {
+    display: none;
+  }
+
+  .normal_list {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+
+    .normal_list_item {
+      margin-bottom: 12px;
+      border: 1px solid #d9d9d9;
+
+      .top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 36px;
+        padding: 0 12px;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #333;
+        background: #f5f7f9;
+
+        .icon {
+          font-size: 16px;
+          cursor: pointer;
+        }
+      }
+    }
+
+    :deep(.el-textarea__inner) {
+      box-shadow: none;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+
+  .keyword {
+    p {
+      font-size: 12px;
+      font-weight: 400;
+      line-height: 22px;
+      color: #a0a0a0;
+    }
+
+    .keyword_list {
+      display: flex;
+      flex-wrap: wrap;
+
+      .keyword_list_item {
+        display: flex;
+        align-items: center;
+        justify-content: space-around;
+        height: 32px;
+        padding: 0 12px;
+        margin-right: 12px;
+        margin-bottom: 12px;
+        color: #333;
+        background: #f0f0f0;
+        border-radius: 6px;
+
+        .del {
+          margin-left: 16px;
+          font-size: 12px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+
+  .upload_img {
+    position: relative;
+    width: 100%;
+
+    .tip {
+      position: absolute;
+      top: 50px;
+      left: 200px;
+      font-size: 12px;
+      font-weight: 400;
+      color: #b4b4b4;
+    }
+  }
+}
+</style>
diff --git a/src/views/inquiryManagement/bodyInspect/list/index.vue b/src/views/inquiryManagement/bodyInspect/list/index.vue
new file mode 100644
index 0000000..125d423
--- /dev/null
+++ b/src/views/inquiryManagement/bodyInspect/list/index.vue
@@ -0,0 +1,216 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+import { reactive, ref } from "vue";
+import {
+  queryPhysicalPage,
+  deleteConfigPhysicalTool
+} from "@/api/inquiryManagement";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import { ElMessageBox } from "element-plus";
+import AddEdit from "./addEdit.vue";
+const dataList = ref([{}]);
+const loading = ref(false);
+const seachForm = reactive({
+  toolName: "",
+  type: "",
+  requireLocation: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns: TableColumnList = [
+  {
+    label: "名称",
+    prop: "toolName"
+  },
+  {
+    label: "图片",
+    prop: "iconBase64",
+
+    slot: "img"
+  },
+  {
+    label: "类目",
+    prop: "type"
+  },
+  {
+    label: "固定检查位",
+    prop: "dose",
+
+    formatter: ({ requireLocation }) => {
+      return requireLocation === 0 ? "不需要" : "需要";
+    }
+  },
+  {
+    label: "关键词",
+    prop: "keyword"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    width: 400,
+    slot: "operation"
+  }
+];
+
+const typeList = ref(["采集生命体征", "动作", "观察", "精神状态"]);
+const AddEditRef = ref();
+
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    toolName: seachForm.toolName,
+    type: seachForm.type,
+    requireLocation: seachForm.requireLocation
+  };
+  const res: any = await queryPhysicalPage(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.toolName = "";
+  seachForm.requireLocation = "";
+  seachForm.type = "";
+  search();
+};
+
+const del = item => {
+  ElMessageBox.confirm(
+    item ? `确认删除后所有信息将被清空, 且无法恢复` : "",
+    "提示",
+    {
+      type: "warning"
+    }
+  )
+    .then(async () => {
+      const res = await deleteConfigPhysicalTool({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = row => {
+  AddEditRef.value.open(row);
+};
+
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="app-main-content body_inspect">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="名称">
+            <el-input size="large" v-model="seachForm.toolName" />
+          </el-form-item>
+          <el-form-item class="ml-4" label="类目">
+            <el-select
+              size="large"
+              filterable
+              v-model="seachForm.type"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in typeList"
+                :key="item"
+                :label="item"
+                :value="item"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item class="ml-4" label="固定检查位">
+            <el-select
+              size="large"
+              clearable
+              v-model="seachForm.requireLocation"
+              placeholder="请选择性别"
+            >
+              <el-option label="全部" value="" />
+              <el-option label="不需要" :value="0" />
+              <el-option label="需要" :value="1" />
+            </el-select>
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>体格检查</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新建</el-button>
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+          <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+        </template>
+        <template #img="{ row }">
+          <div style="display: flex; justify-content: center">
+            <img
+              v-if="row.iconBase64"
+              style="width: 50px; height: 58px"
+              :src="row.iconBase64"
+            />
+          </div> </template
+      ></pure-table>
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+  </div>
+</template>
+<style lang="scss" scoped>
+.body_inspect {
+  :deep(.el-table__row) {
+    height: 75px;
+  }
+}
+</style>
diff --git a/src/views/inquiryManagement/disposalPlan/list/addEdit.vue b/src/views/inquiryManagement/disposalPlan/list/addEdit.vue
new file mode 100644
index 0000000..5b2aab7
--- /dev/null
+++ b/src/views/inquiryManagement/disposalPlan/list/addEdit.vue
@@ -0,0 +1,236 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { queryTree } from "@/api/consultation";
+import {
+  saveTreatmentPlan,
+  updateTreatmentPlan
+} from "@/api/inquiryManagement";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { useRoute } from "vue-router";
+import { nextTick } from "vue";
+
+defineOptions({
+  name: "AddEdit"
+});
+
+const route = useRoute();
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  id: "",
+  disposalPlanId: "",
+  disposalMethod: "",
+  description: "",
+  firstMeasures: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  disposalMethod: [{ required: true, message: "请选择", trigger: "change" }],
+  disposalPlanId: [{ required: true, message: "请选择", trigger: "change" }]
+};
+const disposalMethodFlag = ref(false);
+defineExpose({
+  async open(item) {
+    disposalMethodFlag.value = true;
+    dialogVisible.value = true;
+    isEditFlag.value = false;
+    await nextTick;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+    getTree(formData.disposalMethod);
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+
+const disposalPlanList = ref([]);
+
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (isEditFlag.value) {
+        const res: any = await updateTreatmentPlan(formData);
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+          emit("update");
+          dialogVisible.value = false;
+        }
+        updateTreatmentPlan;
+      } else {
+        const res: any = await saveTreatmentPlan(formData);
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+const selectType = val => {
+  getTree(val);
+};
+const getTree = async val => {
+  const res: any = await queryTree({
+    diseaseId: route.query.id,
+    disposalMethod: val
+  });
+  disposalPlanList.value = res.data;
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>处置计划</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item label="处置方式:" prop="disposalMethod">
+            <el-radio-group
+              v-model="formData.disposalMethod"
+              @change="selectType"
+            >
+              <el-radio :label="0" size="large">门诊收治</el-radio>
+              <el-radio :label="1" size="large">入院治疗</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="处置计划:" prop="disposalPlanId">
+            <el-select
+              filterable
+              size="large"
+              v-model="formData.disposalPlanId"
+              style="width: 100%"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in disposalPlanList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="一级措施" prop="firstMeasures">
+            <el-input size="large" v-model="formData.firstMeasures" />
+          </el-form-item>
+          <el-form-item label="说明" prop="description">
+            <el-input
+              :rows="2"
+              type="textarea"
+              :maxLength="500"
+              placeholder="请输入"
+              v-model="formData.description"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+}
+</style>
diff --git a/src/views/inquiryManagement/disposalPlan/list/index.vue b/src/views/inquiryManagement/disposalPlan/list/index.vue
new file mode 100644
index 0000000..20047a7
--- /dev/null
+++ b/src/views/inquiryManagement/disposalPlan/list/index.vue
@@ -0,0 +1,168 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+import { reactive, ref } from "vue";
+import {
+  queryTreatmentPlanList,
+  delTreatmentPlan
+} from "@/api/inquiryManagement";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import { ElMessageBox } from "element-plus";
+import AddEdit from "./addEdit.vue";
+const dataList = ref([{}]);
+const loading = ref(false);
+const seachForm = reactive({
+  disposalMethod: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+
+const columns: TableColumnList = [
+  {
+    label: "处置方式",
+    prop: "disposalMethod",
+    formatter: ({ disposalMethod }) => {
+      return disposalMethod === 0 ? "门诊收治" : "入院治疗";
+    }
+  },
+  {
+    label: "处置计划",
+    prop: "disposalPlan"
+  },
+  {
+    label: "一级措施",
+    prop: "firstMeasures"
+  },
+  {
+    label: "说明",
+    prop: "description"
+  },
+  {
+    label: "操作",
+    width: 150,
+    slot: "operation"
+  }
+];
+const AddEditRef = ref();
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    disposalMethod: seachForm.disposalMethod
+  };
+  const res: any = await queryTreatmentPlanList(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.disposalMethod = "";
+  search();
+};
+
+const del = item => {
+  ElMessageBox.confirm(
+    item ? `确认删除后所有信息将被清空, 且无法恢复` : "",
+    "提示",
+    {
+      type: "warning"
+    }
+  )
+    .then(async () => {
+      const res = await delTreatmentPlan({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = row => {
+  AddEditRef.value.open(row);
+};
+
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="处置方式">
+            <!-- <el-input size="large" v-model="seachForm.disposalMethod" /> -->
+            <el-select
+              size="large"
+              clearable
+              v-model="seachForm.disposalMethod"
+              placeholder="请选择"
+            >
+              <el-option label="全部" value="" />
+              <el-option label="门诊收治" :value="0" />
+              <el-option label="入院治疗" :value="1" />
+            </el-select>
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>处置计划</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新建</el-button>
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+          <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+        </template></pure-table
+      >
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+  </div>
+</template>
diff --git a/src/views/inquiryManagement/medicationManagement/list/addEdit.vue b/src/views/inquiryManagement/medicationManagement/list/addEdit.vue
new file mode 100644
index 0000000..57c4d62
--- /dev/null
+++ b/src/views/inquiryManagement/medicationManagement/list/addEdit.vue
@@ -0,0 +1,380 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { addDrugManage, edtDrugManage } from "@/api/inquiryManagement";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { queryCommonDictTree } from "@/api/utils";
+import { nextTick } from "vue";
+defineOptions({
+  name: "AddEdit"
+});
+
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  drugName: "",
+  drugNameEn: "",
+  specification: "",
+  dose: "",
+  unit: "",
+  intervalDay: null,
+  intervalHour: "",
+  dosageForm: "",
+  skinTestFlag: "",
+  costType: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const unitList = ["毫克mg", "克g", "毫升ml"];
+const dosageFormList = ref([]);
+const rules = {
+  drugName: [{ required: true, message: "请输入", trigger: "change" }],
+  drugNameEn: [{ required: true, message: "请输入", trigger: "change" }],
+  specification: [{ required: true, message: "请输入", trigger: "change" }],
+  dose: [
+    {
+      pattern: /^\d+(\.\d+)?$/,
+      message: "请输入正确格式",
+      trigger: "change"
+    }
+  ],
+  // unit: [{ required: true, message: "请选择", trigger: "change" }],
+  // intervalDay: [{ required: true, message: "请选择", trigger: "change" }],
+  // dosageForm: [{ required: true, message: "请选择", trigger: "change" }],
+  skinTestFlag: [{ required: true, message: "请选择", trigger: "change" }],
+  costType: [{ required: true, message: "请选择", trigger: "change" }]
+};
+
+defineExpose({
+  async open(item) {
+    getDosageFormList();
+    dialogVisible.value = true;
+    isEditFlag.value = false;
+    await nextTick;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const getDosageFormList = async () => {
+  const res: any = await queryCommonDictTree({ groupCode: "DOSE" });
+  dosageFormList.value = res.data;
+};
+const emit = defineEmits(["update"]);
+const changeTime = val => {
+  if (val === "") {
+    formData.intervalDay = null;
+  }
+  formData.intervalHour = "";
+};
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (isEditFlag.value) {
+        const res: any = await edtDrugManage({
+          ...formData,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+          emit("update");
+          dialogVisible.value = false;
+        }
+      } else {
+        const res: any = await addDrugManage(formData);
+        if (res.code === 200) {
+          message("提交成功", { type: "success" });
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>药品管理</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="药品通用名:" prop="drugName">
+                <el-input
+                  size="large"
+                  v-model="formData.drugName"
+                  placeholder="请输入药品通用名"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="24">
+              <el-form-item label="通用英文名:" prop="drugNameEn">
+                <el-input
+                  size="large"
+                  v-model="formData.drugNameEn"
+                  placeholder="请输入通用英文名"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <el-form-item label="规格:" prop="specification">
+            <el-input
+              size="large"
+              v-model="formData.specification"
+              placeholder="请输入规格"
+            />
+          </el-form-item>
+
+          <el-form-item label="剂量:" prop="dose">
+            <el-input
+              size="large"
+              v-model="formData.dose"
+              placeholder="请输入剂量"
+            />
+          </el-form-item>
+
+          <el-form-item label="单位:" prop="unit">
+            <el-select
+              size="large"
+              filterable
+              v-model="formData.unit"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in unitList"
+                :key="item"
+                :label="item"
+                :value="item"
+              />
+            </el-select>
+          </el-form-item>
+
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="用药间隔:" prop="intervalDay">
+                <el-select
+                  clearable
+                  size="large"
+                  filterable
+                  @change="changeTime"
+                  v-model="formData.intervalDay"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in intervalDayList"
+                    :key="item.id"
+                    :label="item.name"
+                    :value="item.id"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="" label-width="12" prop="intervalHour">
+                <div v-show="formData.intervalDay === null" class="time ml-1">
+                  <span>间隔</span>
+                  <el-input
+                    class="time_input"
+                    :style="{ border: 'none' }"
+                    :maxLength="2"
+                    placeholder="请输入"
+                    v-model="formData.intervalHour"
+                  />
+                  <span>小时</span>
+                </div>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="剂型:" prop="dosageForm">
+                <el-select
+                  size="large"
+                  filterable
+                  v-model="formData.dosageForm"
+                  placeholder="请选择"
+                >
+                  <el-option
+                    v-for="item in dosageFormList"
+                    :key="item.code"
+                    :label="item.nameZh"
+                    :value="item.code"
+                  />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="皮试:" prop="skinTestFlag">
+                <el-radio-group v-model="formData.skinTestFlag">
+                  <el-radio label="0" size="large">不需要</el-radio>
+                  <el-radio label="1" size="large">需要</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="费用类型:" prop="costType">
+                <el-radio-group v-model="formData.costType">
+                  <el-radio :label="0" size="large">自费</el-radio>
+                  <el-radio :label="1" size="large">医保</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  :deep(.el-select) {
+    width: 100%;
+  }
+
+  .time {
+    display: flex;
+    width: 169px;
+    height: 40px;
+    padding: 0 12px;
+    line-height: 40px;
+    border: 1px solid #d9d9d9;
+    border-radius: 6px;
+
+    .time_input {
+      width: 65px;
+    }
+
+    :deep(.el-input__wrapper) {
+      cursor: default;
+      border: none !important;
+      box-shadow: 0 0 0 0 var(--el-input-border-color, var(--el-border-color))
+        inset;
+    }
+  }
+}
+</style>
diff --git a/src/views/inquiryManagement/medicationManagement/list/index.vue b/src/views/inquiryManagement/medicationManagement/list/index.vue
new file mode 100644
index 0000000..98561f7
--- /dev/null
+++ b/src/views/inquiryManagement/medicationManagement/list/index.vue
@@ -0,0 +1,206 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+import { reactive, ref } from "vue";
+import {
+  queryDrugManagePageList,
+  delDrugManage
+} from "@/api/inquiryManagement";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import { ElMessageBox } from "element-plus";
+import AddEdit from "./addEdit.vue";
+const dataList = ref([{}]);
+const loading = ref(false);
+const seachForm = reactive({
+  drugName: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const intervalDayList = [
+  {
+    id: 0,
+    name: "每日一次"
+  },
+  {
+    id: 1,
+    name: "每日两次"
+  },
+  {
+    id: 2,
+    name: "每日三次"
+  },
+  {
+    id: 3,
+    name: "每日四次"
+  }
+];
+const columns: TableColumnList = [
+  {
+    label: "药品通用名",
+    prop: "drugName"
+  },
+  {
+    label: "通用英文名",
+    prop: "drugNameEn"
+  },
+  {
+    label: "规格",
+    prop: "specification"
+  },
+  {
+    label: "剂量",
+    prop: "dose"
+  },
+  {
+    label: "单位",
+    prop: "unit"
+  },
+  {
+    label: "用药间隔",
+    prop: "select",
+    formatter: ({ intervalDay, intervalHour }) => {
+      return intervalDay !== null
+        ? intervalDayList[intervalDay]?.name
+        : intervalHour
+        ? `${intervalHour}小时`
+        : "";
+    }
+  },
+  {
+    label: "剂型",
+    prop: "dosageFormDesc"
+  },
+  {
+    label: "皮试",
+    prop: "skinTestFlag",
+    formatter: ({ skinTestFlag }) => {
+      return skinTestFlag == 0 ? "不需要" : "需要";
+    }
+  },
+  {
+    label: "费用类型",
+    prop: "costType",
+    formatter: ({ costType }) => {
+      return costType === 0 ? "自费" : "医保";
+    }
+  },
+  {
+    label: "操作",
+    fixed: "right",
+
+    slot: "operation"
+  }
+];
+const AddEditRef = ref();
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    drugName: seachForm.drugName
+  };
+  const res: any = await queryDrugManagePageList(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.drugName = "";
+  search();
+};
+
+const del = item => {
+  ElMessageBox.confirm(
+    item ? `确认删除后${item.drugName}的所有信息将被清空, 且无法恢复` : "",
+    "提示",
+    {
+      type: "warning"
+    }
+  )
+    .then(async () => {
+      const res = await delDrugManage({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = row => {
+  AddEditRef.value.open(row);
+};
+
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="药品名称">
+            <el-input size="large" v-model="seachForm.drugName" />
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>药品列表</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新增</el-button>
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+          <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+        </template></pure-table
+      >
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+  </div>
+</template>
diff --git a/src/views/inquiryManagement/supportInspect/list/addEdit.vue b/src/views/inquiryManagement/supportInspect/list/addEdit.vue
new file mode 100644
index 0000000..927d801
--- /dev/null
+++ b/src/views/inquiryManagement/supportInspect/list/addEdit.vue
@@ -0,0 +1,371 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from "vue";
+import {
+  saveAncillaryItem,
+  modifyAncillaryItem
+} from "@/api/inquiryManagement";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import WangEditor from "@/components/WangEditor/index.vue";
+defineOptions({
+  name: "AddEdit"
+});
+
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  itemName: "",
+  itemNameEn: "",
+  type: "",
+  price: "",
+  info: "",
+  keyword: "",
+  keywordList: [],
+  description: ""
+});
+const ruleFormRef = ref<FormInstance>();
+
+const refWangEditor = ref();
+const rules = {
+  itemName: [{ required: true, message: "请输入", trigger: "change" }],
+  itemNameEn: [{ required: true, message: "请输入", trigger: "change" }],
+  type: [{ required: true, message: "请选择", trigger: "change" }],
+  price: {
+    pattern: /^\d+$|^\d*\.\d+$/,
+    message: "请输入正确格式",
+    trigger: "blur"
+  },
+
+  info: [{ required: true, message: "请输入", trigger: "change" }],
+  costType: [{ required: true, message: "请选择", trigger: "change" }]
+};
+defineProps({
+  typeList: {
+    type: Array,
+    default: () => []
+  }
+});
+defineExpose({
+  async open(item) {
+    dialogVisible.value = true;
+    isEditFlag.value = false;
+    await nextTick();
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+
+      isEditFlag.value = true;
+      id.value = item.id;
+      if (formData.keyword) {
+        formData.keywordList = formData.keyword.split(",");
+      }
+
+      formData.keyword = "";
+      nextTick(() => {
+        setTimeout(() => {
+          refWangEditor.value.initText(item.description);
+        }, 200);
+      });
+    }
+  }
+});
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+  formData.keywordList = [];
+};
+const closeDialog = () => {
+  resetForm();
+  dialogVisible.value = false;
+};
+const emit = defineEmits(["update"]);
+const addKeyword = () => {
+  if (formData.keywordList.length === 5) {
+    message("最多添加5个", { type: "error" });
+    return;
+  }
+  if (formData.keyword) {
+    formData.keywordList.push(formData.keyword);
+  }
+  formData.keyword = "";
+};
+const delKeyWord = index => {
+  formData.keywordList.splice(index, 1);
+};
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      // formData.result = refWangEditor.value.valueHtml;
+      const params = {
+        ...formData,
+        keyword: formData.keywordList.join(","),
+        description: refWangEditor.value.valueHtml
+      };
+      if (isEditFlag.value) {
+        const res: any = await modifyAncillaryItem({
+          ...params,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+          dialogVisible.value = false;
+          id.value = "";
+          emit("update");
+        }
+      } else {
+        const res: any = await saveAncillaryItem(params);
+        if (res.code === 200) {
+          message("新增成功", { type: "success" });
+          dialogVisible.value = false;
+          emit("update");
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :size="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>辅助检查</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-row>
+            <el-col :span="24">
+              <el-form-item label="名称" prop="itemName">
+                <el-input
+                  size="large"
+                  v-model="formData.itemName"
+                  placeholder="请输入名称"
+                />
+              </el-form-item>
+            </el-col>
+            <el-col :span="24">
+              <el-form-item label="英文名称" prop="itemNameEn">
+                <el-input
+                  size="large"
+                  v-model="formData.itemNameEn"
+                  placeholder="请输入通用英文名"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-form-item label="类目" prop="type">
+            <el-select
+              size="large"
+              filterable
+              v-model="formData.type"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in typeList"
+                :key="item.nameZh"
+                :label="item.nameZh"
+                :value="item.nameZh"
+              />
+            </el-select>
+          </el-form-item>
+
+          <el-form-item label="检查价格" prop="price">
+            <el-input
+              v-model="formData.price"
+              size="large"
+              placeholder="请输入检查价格"
+            />
+          </el-form-item>
+          <el-form-item label="正常结果" prop="info">
+            <el-input
+              size="large"
+              v-model="formData.info"
+              placeholder="请输入,不填写默认辅助工具正常值"
+            />
+          </el-form-item>
+          <el-form-item style="margin-bottom: 0" label="关键词" prop="keyword">
+            <el-input
+              v-model="formData.keyword"
+              style="width: 550px"
+              maxLength="8"
+              @keyup.enter="addKeyword"
+              placeholder="请输入关键词"
+              size="large"
+            />
+            <div @click="addKeyword" class="add_btn">添加</div>
+          </el-form-item>
+          <el-form-item label="">
+            <div class="keyword">
+              <p>
+                为了系统更准确的识别对应检查项目,可配置关键词,例如辅助检查项“超声心电图”可设置关键词“心电图”,“心动图”,Enter键保存,最多设置5个关键词
+              </p>
+              <div class="keyword_list">
+                <div
+                  class="keyword_list_item"
+                  v-for="(item, index) in formData.keywordList"
+                  :key="index"
+                >
+                  <span>{{ item }}</span>
+                  <el-icon @click="delKeyWord(index)" class="del"
+                    ><CircleClose
+                  /></el-icon>
+                </div>
+                <span
+                  v-if="formData.keywordList.length > 0"
+                  style="margin-left: 10px; color: #a0a0a0"
+                  >{{ `${formData.keywordList.length}/5` }}</span
+                >
+              </div>
+            </div>
+          </el-form-item>
+          <el-form-item label="说明" prop="description">
+            <WangEditor v-if="dialogVisible" ref="refWangEditor" />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  :deep(.el-select) {
+    width: 100%;
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+
+  .keyword {
+    p {
+      font-size: 12px;
+      font-weight: 400;
+      line-height: 22px;
+      color: #a0a0a0;
+    }
+
+    .keyword_list {
+      display: flex;
+
+      .keyword_list_item {
+        display: flex;
+        align-items: center;
+        justify-content: space-around;
+        height: 32px;
+        padding: 0 12px;
+        margin-right: 12px;
+        color: #333;
+        background: #f0f0f0;
+        border-radius: 6px;
+
+        .del {
+          margin-left: 16px;
+          font-size: 12px;
+          cursor: pointer;
+        }
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/inquiryManagement/supportInspect/list/index.vue b/src/views/inquiryManagement/supportInspect/list/index.vue
new file mode 100644
index 0000000..08b1135
--- /dev/null
+++ b/src/views/inquiryManagement/supportInspect/list/index.vue
@@ -0,0 +1,191 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+import { reactive, ref } from "vue";
+import {
+  queryAncillaryPage,
+  deleteAncillaryItem
+} from "@/api/inquiryManagement";
+import { queryCommonDictTree } from "@/api/utils";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import { ElMessageBox } from "element-plus";
+import AddEdit from "./addEdit.vue";
+const dataList = ref([{}]);
+const loading = ref(false);
+const seachForm = reactive({
+  name: "",
+  type: ""
+});
+defineOptions({
+  name: "InquiryManagementSupportInspect"
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns: TableColumnList = [
+  {
+    label: "名称",
+    prop: "itemName"
+  },
+  {
+    label: "类目",
+    prop: "type"
+  },
+  {
+    label: "关键词",
+    prop: "keyword"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    width: 400,
+    slot: "operation"
+  }
+];
+
+const typeList = ref([]);
+const AddEditRef = ref();
+
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    name: seachForm.name,
+    type: seachForm.type
+  };
+  const res: any = await queryAncillaryPage(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.name = "";
+  seachForm.type = "";
+  search();
+};
+
+const del = item => {
+  ElMessageBox.confirm(
+    item ? `确认删除后所有信息将被清空, 且无法恢复` : "",
+    "提示",
+    {
+      type: "warning"
+    }
+  )
+    .then(async () => {
+      const res = await deleteAncillaryItem({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = row => {
+  AddEditRef.value.open(row);
+};
+const getTypeList = async () => {
+  const res: any = await queryCommonDictTree({
+    groupCode: "ANCILLARY_ITEM_PRIORITY"
+  });
+  typeList.value = res.data;
+};
+onMounted(() => {
+  getData();
+  getTypeList();
+});
+</script>
+
+<template>
+  <div class="app-main-content support_inspect">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="名称">
+            <el-input size="large" v-model="seachForm.name" />
+          </el-form-item>
+          <el-form-item class="ml-4" label="类目">
+            <el-select
+              size="large"
+              filterable
+              v-model="seachForm.type"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in typeList"
+                :key="item.nameZh"
+                :label="item.nameZh"
+                :value="item.nameZh"
+              />
+            </el-select>
+          </el-form-item>
+
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>辅助检查</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新建</el-button>
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+          <el-button link type="danger" @click="del(row)"> 删除 </el-button>
+        </template>
+        <template #img="{ row }">
+          <div style="display: flex; justify-content: center">
+            <img
+              v-if="row.iconBase64"
+              style="width: 50px; height: 58px"
+              :src="row.iconBase64"
+            />
+          </div> </template
+      ></pure-table>
+    </div>
+    <AddEdit :typeList="typeList" @update="getData" ref="AddEditRef" />
+  </div>
+</template>
diff --git a/src/views/login/index.vue b/src/views/login/index.vue
index e82128e..1977b07 100644
--- a/src/views/login/index.vue
+++ b/src/views/login/index.vue
@@ -2,28 +2,25 @@
 import Motion from "./utils/motion";
 import { useRouter } from "vue-router";
 import { message } from "@/utils/message";
-import { loginRules } from "./utils/rule";
+// import { loginRules } from "./utils/rule";
 // import { useNav } from "@/layout/hooks/useNav";
 import type { FormInstance } from "element-plus";
 import { useLayout } from "@/layout/hooks/useLayout";
 import { useUserStoreHook } from "@/store/modules/user";
-import { initRouter, getTopMenu } from "@/router/utils";
-import { leftLogo, sst } from "./utils/static";
+import { initRouter } from "@/router/utils";
+// import { leftLogo, sst } from "./utils/static";
 import bg from "../../assets/login/login_bg.png";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 // import update from "./components/update.vue";
-import {
-  ref,
-  reactive,
-  onMounted,
-  onBeforeUnmount,
-  toRaw,
-  nextTick
-} from "vue";
+import { ref, reactive, onMounted, onBeforeUnmount, nextTick } from "vue";
+import registerIcon from "@/assets/login/register.png";
+import { getRegister, changePassWord } from "@/api/user";
 import Lock from "@iconify-icons/icon-park-outline/lock";
 import User from "@iconify-icons/icon-park-outline/user";
 import PreviewClose from "@iconify-icons/icon-park-outline/preview-close";
 import PreviewOpen from "@iconify-icons/icon-park-outline/preview-open";
+import IdCard from "@iconify-icons/icon-park-outline/id-card";
+// import InviteCode from "@iconify-icons/icon-park-outline/user-to-user-transmission";
 
 defineOptions({
   name: "Login"
@@ -31,11 +28,11 @@ defineOptions({
 const router = useRouter();
 const loading = ref(false);
 const ruleFormRef = ref<FormInstance>();
+const registerFormRef = ref<FormInstance>();
+const modifyFormRef = ref<FormInstance>();
 const checked = ref(false);
-// const currentPage = computed(() => {
-//   return useUserStoreHook().currentPage;
-// });
 
+const cardType = ref(1);
 const { initStorage } = useLayout();
 initStorage();
 
@@ -44,10 +41,21 @@ initStorage();
 // const { title } = useNav();
 
 const ruleForm = reactive({
-  username: "test",
-  password: "123456"
+  username: "",
+  password: ""
+});
+const registerForm = reactive({
+  account: "",
+  name: "",
+  password: "",
+  newPassword: ""
+});
+const modifyForm = reactive({
+  account: "",
+  name: "",
+  password: "",
+  newPassword: ""
 });
-
 const onLogin = async (formEl: FormInstance | undefined) => {
   loading.value = true;
   if (!formEl) return;
@@ -59,11 +67,20 @@ const onLogin = async (formEl: FormInstance | undefined) => {
           password: ruleForm.password
         })
         .then((res: any) => {
+          loading.value = false;
           if (res.code === 200) {
-            router.push("/inquiry");
+            if (res.data.roleCode === "1") {
+              initRouter().then(() => {
+                router.push("/selectCase");
+              });
+            } else {
+              initRouter().then(() => {
+                router.push("/inquiryCase");
+              });
+            }
+
             message("登录成功", { type: "success" });
-          } else {
-            message("登录失败", { type: "error" });
+            // sessionStorage.setItem("userInfo", JSON.stringify({ role: "1" }));
           }
         })
         .catch(() => {
@@ -76,6 +93,46 @@ const onLogin = async (formEl: FormInstance | undefined) => {
     }
   });
 };
+const register = async (formEl: FormInstance | undefined) => {
+  loading.value = true;
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const res: any = await getRegister({
+        account: registerForm.account,
+        name: registerForm.name,
+        password: registerForm.password
+      });
+      loading.value = false;
+      if (res.code === 200) {
+        changeCardType(4);
+      }
+    } else {
+      loading.value = false;
+      return fields;
+    }
+  });
+};
+const onModify = async (formEl: FormInstance | undefined) => {
+  loading.value = true;
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      const res: any = await changePassWord({
+        account: modifyForm.account,
+        name: modifyForm.name,
+        password: modifyForm.password
+      });
+      loading.value = false;
+      if (res.code === 200) {
+        changeCardType(5);
+      }
+    } else {
+      loading.value = false;
+      return fields;
+    }
+  });
+};
 const passwordType = ref("password");
 const refInput = ref();
 /** 使用公共函数,避免`removeEventListener`失效 */
@@ -96,6 +153,23 @@ function showPass() {
   });
 }
 
+const changeCardType = val => {
+  cardType.value = val;
+};
+const validateConfirmPassword = (rule, value, callback) => {
+  if (value !== registerForm.password) {
+    callback(new Error("请再次输入密码以确保一致,不能留空"));
+  } else {
+    callback();
+  }
+};
+const validatePassword = (rule, value, callback) => {
+  if (value !== modifyForm.password) {
+    callback(new Error("请再次输入密码以确保一致,不能留空"));
+  } else {
+    callback();
+  }
+};
 onMounted(() => {
   window.document.addEventListener("keypress", onkeypress);
 });
@@ -114,12 +188,12 @@ onBeforeUnmount(() => {
         <span class="systeam-name">虚拟病人系统</span>
         <span class="desc">Welcome to the Virtual Patient System</span>
       </div>
-      <div class="login-box">
+      <div v-if="cardType === 1" class="login-box">
         <div class="login-form">
-          <!-- <avatar class="avatar" /> -->
-          <Motion>
-            <h2 class="outline-none">{{ "欢迎登录" }}</h2>
-          </Motion>
+          <div class="top">
+            <p class="title">欢迎登录虚拟病人系统</p>
+            <p class="top_desc">Welcome to login</p>
+          </div>
 
           <el-form ref="ruleFormRef" :model="ruleForm" size="large">
             <Motion :delay="100">
@@ -134,6 +208,7 @@ onBeforeUnmount(() => {
                 prop="username"
               >
                 <el-input
+                  style="height: 60px; font-size: 16px"
                   v-model="ruleForm.username"
                   placeholder="账号"
                   :prefix-icon="useRenderIcon(User)"
@@ -142,8 +217,18 @@ onBeforeUnmount(() => {
             </Motion>
 
             <Motion :delay="150">
-              <el-form-item prop="password">
+              <el-form-item
+                prop="password"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请输入密码',
+                    trigger: 'blur'
+                  }
+                ]"
+              >
                 <el-input
+                  style="height: 60px; font-size: 16px"
                   ref="refInput"
                   :type="passwordType"
                   v-model="ruleForm.password"
@@ -172,20 +257,21 @@ onBeforeUnmount(() => {
                 <el-checkbox v-model="checked">
                   {{ "记住密码" }}
                 </el-checkbox>
-                <el-button
+                <!-- <el-button
                   link
                   class="btn-color"
                   type="primary"
                   @click="useUserStoreHook().SET_CURRENTPAGE(4)"
                 >
                   {{ "忘记密码?" }}
-                </el-button>
+                </el-button> -->
+                <div class="btn-color" @click="changeCardType(3)">忘记密码</div>
               </div>
               <el-button
-                class="w-full mt-7 login-btn"
-                size="default"
+                class="w-full mt-9 login-btn"
+                size="large"
                 type="primary"
-                color="#1C0D82"
+                color="rgba(66, 135, 255, 1)"
                 :loading="loading"
                 @click="onLogin(ruleFormRef)"
               >
@@ -193,8 +279,273 @@ onBeforeUnmount(() => {
               </el-button>
             </Motion>
           </el-form>
-          <!-- 忘记密码 -->
-          <!-- <update v-if="currentPage === 4" /> -->
+          <div @click="changeCardType(2)" class="desc">还没账号?去注册</div>
+        </div>
+      </div>
+      <div v-if="cardType === 2" class="register-box">
+        <div class="login-form">
+          <div class="top">
+            <p class="title">注册账号</p>
+            <p class="top_desc">Sign up for an to account</p>
+          </div>
+
+          <el-form ref="registerFormRef" :model="registerForm" size="large">
+            <Motion :delay="100">
+              <el-form-item
+                :rules="[
+                  {
+                    required: true,
+                    message: '请使用中文填写您的姓名,6字以内',
+                    trigger: 'blur'
+                  },
+                  {
+                    pattern: /^[\u4e00-\u9fa5]+$/,
+                    message: '请使用中文填写您的姓名,6字以内',
+                    trigger: 'change'
+                  }
+                ]"
+                prop="name"
+              >
+                <el-input
+                  maxlength="6"
+                  style="height: 60px; font-size: 16px"
+                  v-model="registerForm.name"
+                  placeholder="请输入姓名"
+                  :prefix-icon="useRenderIcon(IdCard)"
+                />
+              </el-form-item>
+            </Motion>
+            <Motion :delay="100">
+              <el-form-item
+                :rules="[
+                  {
+                    required: true,
+                    message: '请输入账号',
+                    trigger: 'blur'
+                  },
+                  {
+                    pattern: /^[a-zA-Z0-9]{6,18}$/,
+                    message: '使用6至18个英文字母或数字',
+                    trigger: 'change'
+                  }
+                ]"
+                prop="account"
+              >
+                <el-input
+                  autocomplete="off"
+                  style="height: 60px; font-size: 16px"
+                  v-model="registerForm.account"
+                  placeholder="请输入账号"
+                  :prefix-icon="useRenderIcon(User)"
+                />
+              </el-form-item>
+            </Motion>
+            <Motion :delay="150">
+              <el-form-item
+                prop="password"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请输入密码',
+                    trigger: 'blur'
+                  },
+                  {
+                    pattern: /^(?![\u4e00-\u9fa5\s])[\x21-\x7e]{6,18}$/,
+                    message: '密码6-18位 不包含中文特殊字符和空格',
+                    trigger: 'change'
+                  }
+                ]"
+              >
+                <el-input
+                  type="password"
+                  autocomplete="new-password"
+                  style="height: 60px; font-size: 16px"
+                  v-model="registerForm.password"
+                  placeholder="请输入密码"
+                  :prefix-icon="useRenderIcon(Lock)"
+                />
+              </el-form-item>
+            </Motion>
+            <Motion :delay="150">
+              <el-form-item
+                prop="newPassword"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请再次输入密码',
+                    trigger: 'blur'
+                  },
+                  {
+                    pattern: /^(?![\u4e00-\u9fa5\s])[\x21-\x7e]{6,18}$/,
+                    message: '密码6-18位 不包含中文特殊字符和空格',
+                    trigger: 'change'
+                  },
+                  { validator: validateConfirmPassword, trigger: 'blur' }
+                ]"
+              >
+                <el-input
+                  style="height: 60px; font-size: 16px"
+                  type="password"
+                  autocomplete="new-password"
+                  v-model="registerForm.newPassword"
+                  placeholder="请再次输入密码"
+                  :prefix-icon="useRenderIcon(Lock)"
+                />
+              </el-form-item>
+            </Motion>
+            <Motion :delay="250">
+              <el-button
+                class="w-full mt-9 login-btn"
+                size="large"
+                type="primary"
+                color="rgba(66, 135, 255, 1)"
+                :loading="loading"
+                @click="register(registerFormRef)"
+              >
+                确定
+              </el-button>
+            </Motion>
+          </el-form>
+          <div @click="changeCardType(1)" class="desc">已有账号?去登录</div>
+        </div>
+      </div>
+      <div v-if="cardType === 3" class="login-box" style="height: 560px">
+        <div class="login-form">
+          <div class="top">
+            <p class="title" style="margin-bottom: 52px">忘记密码</p>
+            <!-- <p class="top_desc" style="font-size: 14px">
+              为了您的账户安全,请重新设置位数密码
+            </p> -->
+          </div>
+
+          <el-form ref="modifyFormRef" :model="modifyForm" size="large">
+            <Motion :delay="100">
+              <el-form-item
+                :rules="[
+                  {
+                    required: true,
+                    message: '请输入账号',
+                    trigger: 'blur'
+                  }
+                ]"
+                prop="account"
+              >
+                <el-input
+                  style="height: 60px; font-size: 16px"
+                  v-model="modifyForm.account"
+                  placeholder="请输入账号"
+                  :prefix-icon="useRenderIcon(User)"
+                />
+              </el-form-item>
+            </Motion>
+
+            <Motion :delay="150">
+              <el-form-item
+                prop="password"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请输入新密码',
+                    trigger: 'blur'
+                  },
+                  {
+                    pattern: /^(?![\u4e00-\u9fa5\s])[\x21-\x7e]{6,18}$/,
+                    message: '密码6-18位 不包含中文特殊字符和空格',
+                    trigger: 'change'
+                  }
+                ]"
+              >
+                <el-input
+                  type="password"
+                  autocomplete="new-password"
+                  style="height: 60px; font-size: 16px"
+                  v-model="modifyForm.password"
+                  placeholder="请输入密码"
+                  :prefix-icon="useRenderIcon(Lock)"
+                />
+              </el-form-item>
+            </Motion>
+            <Motion :delay="150">
+              <el-form-item
+                prop="newPassword"
+                :rules="[
+                  {
+                    required: true,
+                    message: '请再次输入新密码',
+                    trigger: 'blur'
+                  },
+                  {
+                    pattern: /^(?![\u4e00-\u9fa5\s])[\x21-\x7e]{6,18}$/,
+                    message: '密码6-18位 不包含中文特殊字符和空格',
+                    trigger: 'change'
+                  },
+                  { validator: validatePassword, trigger: 'blur' }
+                ]"
+              >
+                <el-input
+                  type="password"
+                  autocomplete="new-password"
+                  style="height: 60px; font-size: 16px"
+                  v-model="modifyForm.newPassword"
+                  placeholder="请再次输入新密码"
+                  :prefix-icon="useRenderIcon(Lock)"
+                />
+              </el-form-item>
+            </Motion>
+            <Motion :delay="250">
+              <el-button
+                class="w-full mt-9 login-btn"
+                size="large"
+                type="primary"
+                color="rgba(66, 135, 255, 1)"
+                :loading="loading"
+                @click="onModify(modifyFormRef)"
+              >
+                确定
+              </el-button>
+            </Motion>
+          </el-form>
+          <div @click="changeCardType(1)" class="desc">已有账号?去登录</div>
+        </div>
+      </div>
+      <div v-if="cardType === 4" class="login-box" style="height: 546px">
+        <div class="content">
+          <img :src="registerIcon" alt="" />
+          <div class="content_top">
+            <p class="content_top_title">注册成功</p>
+            <p class="content_top_desc">
+              已注册成功,您可以使用账号密码登录系统
+            </p>
+          </div>
+          <el-button
+            style="margin-top: 130px"
+            class="w-full login-btn"
+            size="large"
+            type="primary"
+            color="rgba(66, 135, 255, 1)"
+            @click="changeCardType(1)"
+          >
+            去登录
+          </el-button>
+        </div>
+      </div>
+      <div v-if="cardType === 5" class="login-box" style="height: 546px">
+        <div class="content">
+          <img :src="registerIcon" alt="" />
+          <div class="content_top">
+            <p class="content_top_title">重置成功</p>
+            <p class="content_top_desc">您可以重新登录系统验证您的新密码</p>
+          </div>
+          <el-button
+            style="margin-top: 130px"
+            class="w-full login-btn"
+            size="large"
+            type="primary"
+            color="rgba(66, 135, 255, 1)"
+            @click="changeCardType(1)"
+          >
+            重新登录
+          </el-button>
         </div>
       </div>
     </div>
@@ -211,19 +562,25 @@ onBeforeUnmount(() => {
 }
 
 .login-btn {
-  height: 40px;
-  font-weight: 600;
-  // font-family: "PingFang SC";
+  height: 60px;
+  font-size: 16px;
   color: #fff;
+  background: #4287ff;
+  border-radius: 6px;
+  box-shadow: 0 10px 20px 2px rgb(24 144 255 / 20%);
 }
 
 .btn-color {
-  color: #1c0d82;
+  font-size: 16px;
+  color: #4287ff;
+  cursor: pointer;
 }
 
-.btn-color:hover {
-  color: #1c0d82;
-  opacity: 0.5;
+.desc {
+  margin-top: 16px;
+  font-size: 14px;
+  color: #787878;
+  cursor: pointer;
 }
 
 .el-input__icon {
@@ -236,14 +593,74 @@ onBeforeUnmount(() => {
 .login-left {
   display: flex;
   flex-direction: column;
+
   span {
     font-size: 50px;
-    font-family: Microsoft YaHei-Bold, Microsoft YaHei;
     font-weight: bold;
-    color: #ffffff;
+    color: #fff;
   }
+
   .systeam-name {
     font-size: 80px;
   }
 }
+
+.login-box,
+.register-box {
+  .top {
+    .title {
+      font-size: 24px;
+      font-weight: 400;
+      color: #333;
+    }
+
+    .top_desc {
+      margin-bottom: 52px;
+      font-size: 23px;
+      font-weight: 400;
+      color: #666;
+    }
+  }
+
+  .content {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 100%;
+    padding: 35px 40px 0;
+
+    img {
+      width: 137px;
+      height: 94px;
+      margin-bottom: 40px;
+    }
+
+    .content_top {
+      .content_top_title {
+        font-size: 24px;
+        color: #333;
+      }
+
+      .content_top_desc {
+        margin-top: 8px;
+        font-size: 14px;
+        color: #666;
+      }
+    }
+  }
+}
+
+.register-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  width: 500px;
+  height: 665px;
+  padding-top: 65px;
+  margin-left: 160px;
+  text-align: center;
+  background: #fff;
+  border-radius: 10px;
+}
 </style>
diff --git a/src/views/selectCase/index.vue b/src/views/selectCase/index.vue
new file mode 100644
index 0000000..271748a
--- /dev/null
+++ b/src/views/selectCase/index.vue
@@ -0,0 +1,515 @@
+<script setup lang="ts">
+import NavBar from "@/components/NavBar/index.vue";
+
+import { ref, onMounted, reactive } from "vue";
+import addImg from "@/assets/newInquiry/add.png";
+import goBackImg from "@/assets/newInquiry/go_back.png";
+import userAvatar from "@/assets/user.jpg";
+import router from "@/router";
+import {
+  queryDiagnoseProcessPageList,
+  queryMedicalRecPageList,
+  deleteProcess
+} from "@/api/consultation";
+import { getUserInfo } from "@/utils/auth";
+import { useConsultationStoreHooks } from "@/store/modules/consultation";
+import { creatDiagnosisProcesse } from "@/api/inquiry";
+
+// import { message } from "@/utils/message";
+import { downLoadUrl } from "@/utils/auth";
+import { ElMessageBox } from "element-plus";
+import { message } from "@/utils/message";
+
+const addFlag = ref(false);
+const caseList = ref([]);
+const diagnoseProcessList = ref([]); //问诊流程列表
+const medicalRecList = ref([]); //病例信息列表
+const addCase = () => {
+  addFlag.value = true;
+  caseList.value = medicalRecList.value;
+};
+const goBack = () => {
+  console.log("111", userPagination);
+  addFlag.value = false;
+  caseList.value = diagnoseProcessList.value;
+};
+const openCase = async item => {
+  // const res: any = await resourceIsFree();
+  // if (res.data === true) {
+  if (item.status) {
+    sessionStorage.setItem(
+      "inspectSatus",
+      item.status === "3" ? "2" : item.status // 已评估状态和未评估进入页面一样
+    );
+    if (item.processId) {
+      router.push({
+        path: "/consultation",
+        query: {
+          processId: item.processId
+        }
+      });
+    }
+  } else {
+    createProcess(item);
+  }
+  sessionStorage.setItem("patientSilentVideo", item.patientSilentVideo);
+  sessionStorage.setItem("patientDummyVideo", item.patientDummyVideo);
+  // } else {
+  //   message("实例资源占用,请稍后再试", { type: "warning" });
+  // }
+};
+const createProcess = async item => {
+  const res: any = await creatDiagnosisProcesse({
+    medicalId: item.medicalId,
+    patientId: item.patientId
+  });
+  if (res.code === 200) {
+    sessionStorage.setItem("inspectSatus", "0");
+    router.push({
+      path: "/consultation",
+      query: {
+        processId: res.data.id
+      }
+    });
+  }
+};
+const userPagination = reactive<any>({
+  total: 0,
+  pageSize: 11,
+  currentPage: 1
+});
+const casePagination = reactive<any>({
+  total: 0,
+  pageSize: 11,
+  currentPage: 1
+});
+const getDiagnoseProcessPageList = async () => {
+  const userInfo: any = getUserInfo();
+  const params = {
+    pageNum: userPagination.currentPage,
+    pageSize: userPagination.pageSize,
+    userId: JSON.parse(userInfo).id
+  };
+  const res: any = await queryDiagnoseProcessPageList(params);
+  if (res?.code === 200) {
+    userPagination.total = res.data?.total;
+    caseList.value = res.data?.records;
+
+    diagnoseProcessList.value = res.data?.records;
+    userPagination.total = res.data?.total;
+  }
+};
+const getMedicalRecPageList = async () => {
+  const params = {
+    pageNum: casePagination.currentPage,
+    pageSize: casePagination.pageSize
+  };
+  const res: any = await queryMedicalRecPageList(params);
+  if (res?.code === 200) {
+    medicalRecList.value = res.data.records;
+    casePagination.total = res.data.total;
+    if (addFlag.value === true) {
+      caseList.value = medicalRecList.value;
+    }
+  }
+};
+const handleUserChange = val => {
+  userPagination.currentPage = val;
+  console.log("111", userPagination);
+  getDiagnoseProcessPageList();
+};
+const handleCaseChange = val => {
+  casePagination.currentPage = val;
+  getMedicalRecPageList();
+};
+const delItem = async item => {
+  ElMessageBox.confirm(item ? `确定删除这条问诊实例”` : "", "提示", {
+    type: "warning"
+  })
+    .then(async () => {
+      const res: any = await deleteProcess({ processId: item.processId });
+      if (res.code === 200) {
+        getDiagnoseProcessPageList();
+        getMedicalRecPageList();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+onMounted(() => {
+  getDiagnoseProcessPageList();
+  getMedicalRecPageList();
+  sessionStorage.setItem("inspectSatus", "");
+  useConsultationStoreHooks().changeInspectSatus("");
+});
+</script>
+<template>
+  <div class="selectCase">
+    <NavBar />
+    <div v-if="caseList.length === 0" class="no_data">
+      <div class="add_card" @click="addCase">
+        <p>选择问诊实例</p>
+        <span class="desc">暂无可选择问诊实例,请先新建问诊实例</span>
+        <div class="content">
+          <img class="add_img" :src="addImg" alt="" />
+          <span>新建问诊实例</span>
+        </div>
+      </div>
+    </div>
+    <div v-if="caseList.length > 0" class="main">
+      <div class="content">
+        <div class="title">选择问诊实例</div>
+        <div class="case_list">
+          <div v-if="!addFlag" @click="addCase" class="case_list_item add_item">
+            <img class="add_img" :src="addImg" alt="" />
+            <span>新建问诊实例</span>
+          </div>
+          <div v-if="addFlag" @click="goBack" class="case_list_item add_item">
+            <img class="add_img" :src="goBackImg" alt="" />
+            <span>返回问诊历史</span>
+          </div>
+          <div
+            v-for="(item, index) in caseList"
+            :key="index"
+            class="case_list_item"
+            @click="openCase(item)"
+          >
+            <div class="item_info">
+              <img v-if="!item.patientHeadPic" :src="userAvatar" alt="" />
+              <img
+                v-if="item.patientHeadPic"
+                :src="downLoadUrl(item.patientHeadPic)"
+                alt=""
+              />
+              <div class="item_info_content">
+                <span class="name">{{ item.name }}</span>
+                <span>{{ `年龄:${item.age}岁  性别:${item.gender}` }}</span>
+              </div>
+            </div>
+            <div class="desc" :title="item.patientSelfDesc">
+              {{ `主诉:${item.patientSelfDesc}` }}
+            </div>
+            <div class="time" v-show="item.status">
+              {{ `最近问诊时间:${item.time}` }}
+            </div>
+            <div :class="[addFlag ? 'add_btn_list' : 'btn_list']">
+              <div class="del_btn" v-if="!addFlag" @click.stop="delItem(item)">
+                删除
+              </div>
+              <div class="btn" v-if="item.status === '0'">继续问诊</div>
+              <div class="btn" v-else-if="item.status === '1'">去处置</div>
+              <div class="btn" v-else-if="item.status === '2'">
+                查看评估结果
+              </div>
+              <div class="btn" v-else-if="item.status === '3'">
+                查看评估结果
+              </div>
+              <div class="btn" v-else>开始问诊</div>
+            </div>
+
+            <div
+              v-if="item.status === '0'"
+              style="background-color: #0db274"
+              class="type"
+            >
+              待问诊
+            </div>
+            <div v-if="item.status === '1'" class="type wait">待处置</div>
+            <div v-if="item.status === '2'" class="type determine">已确诊</div>
+            <div v-if="item.status === '3'" class="type determine">已评估</div>
+          </div>
+        </div>
+        <div class="footer">
+          <el-pagination
+            :current-page="userPagination.currentPage"
+            v-if="userPagination.total > 11 && !addFlag"
+            @current-change="handleUserChange"
+            :hide-on-single-page="true"
+            background
+            :default-page-size="11"
+            layout="prev, pager, next"
+            :total="userPagination.total"
+            class="mt-4"
+          />
+          <el-pagination
+            :current-page="casePagination.currentPage"
+            v-if="casePagination.total > 11 && addFlag"
+            @current-change="handleCaseChange"
+            :hide-on-single-page="true"
+            background
+            :default-page-size="11"
+            layout="prev, pager, next"
+            :total="casePagination.total"
+            class="mt-4"
+          />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.selectCase {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+  background-image: url("../../assets/newInquiry/select_bg.png");
+  background-size: 100% 100%;
+
+  .no_data {
+    display: flex;
+    flex: 1;
+    align-items: center;
+    justify-content: center;
+
+    .add_card {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 439px;
+      height: 445px;
+      background: linear-gradient(225deg, #f4f8ff 0%, #fff 46%);
+      border-radius: 6px;
+      box-shadow: 0 40px 100px 0 rgb(65 149 249 / 30%);
+
+      p {
+        margin-bottom: 8px;
+        font-size: 20px;
+        font-weight: bold;
+        color: #2b3f54;
+      }
+
+      .desc {
+        font-size: 14px;
+        font-weight: 400;
+        color: rgb(43 63 84 / 60%);
+      }
+
+      .content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        width: 367px;
+        height: 193px;
+        margin-top: 40px;
+        cursor: pointer;
+        background: rgb(66 135 255 / 5%);
+        border: 1px dashed #4287ff;
+        border-radius: 6px;
+
+        img {
+          width: 60px;
+          height: 60px;
+        }
+
+        span {
+          margin-top: 8px;
+          font-size: 16px;
+          color: #4287ff;
+        }
+      }
+    }
+  }
+
+  .main {
+    display: flex;
+    justify-content: center;
+    margin-top: 80px;
+    margin-bottom: 32px;
+    overflow: auto;
+
+    .content {
+      width: 1200px;
+
+      .title {
+        margin-bottom: 24px;
+        font-size: 24px;
+        font-weight: bold;
+        color: #2b3f54;
+      }
+
+      .case_list {
+        display: flex;
+        flex-wrap: wrap;
+
+        .case_list_item {
+          position: relative;
+          width: 266px;
+          height: 210px;
+          padding: 16px;
+          margin-right: 24px;
+          margin-bottom: 24px;
+          cursor: pointer;
+          background: #fff;
+          border-radius: 6px;
+
+          .item_info {
+            display: flex;
+
+            img {
+              width: 64px;
+              height: 64px;
+              margin-right: 16px;
+              border-radius: 50%;
+            }
+          }
+
+          .item_info_content {
+            display: flex;
+            flex-direction: column;
+            font-size: 12px;
+            color: #666;
+
+            .name {
+              margin-bottom: 8px;
+              font-size: 16px;
+              font-weight: 400;
+              color: #2b3f54;
+            }
+          }
+
+          .desc {
+            display: -webkit-box;
+            height: 40px;
+            padding-bottom: 16px;
+            margin-top: 16px;
+            margin-bottom: 4px;
+            overflow: hidden;
+            font-size: 14px;
+            font-weight: 400;
+            color: #2b3f54;
+            text-overflow: ellipsis;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 2;
+          }
+
+          .time {
+            font-size: 12px;
+            font-weight: 400;
+            color: #999;
+          }
+
+          .btn_list {
+            position: absolute;
+            bottom: 16px;
+            display: flex;
+            margin-top: 16px;
+            opacity: 1;
+
+            .del_btn {
+              width: 109px;
+              height: 29px;
+              margin-right: 16px;
+              font-size: 14px;
+              line-height: 29px;
+              color: #999;
+              text-align: center;
+              border: 1px solid #999;
+              border-radius: 6px;
+            }
+
+            .btn {
+              width: 109px;
+              height: 29px;
+              line-height: 29px;
+              color: #4287ff;
+              text-align: center;
+              border: 1px solid #4287ff;
+              border-radius: 6px;
+            }
+          }
+
+          .add_btn_list {
+            .btn {
+              position: absolute;
+              bottom: 16px;
+              width: 234px;
+              height: 29px;
+              margin-top: 16px;
+              line-height: 29px;
+              color: #4287ff;
+              text-align: center;
+              border: 1px solid #4287ff;
+              border-radius: 6px;
+              opacity: 1;
+            }
+          }
+
+          .type {
+            position: absolute;
+            top: 0;
+            right: 0;
+            width: 72px;
+            height: 24px;
+            font-size: 12px;
+            font-weight: 400;
+            line-height: 24px;
+            color: #fff;
+            text-align: center;
+            border-top-right-radius: 6px;
+          }
+
+          .wait {
+            background: #ffa700;
+          }
+
+          .determine {
+            background: #4287ff;
+          }
+        }
+
+        .case_list_item:hover {
+          box-shadow: 0 40px 100px 0 rgb(65 149 249 / 30%);
+
+          .btn {
+            color: #fff;
+            background: #4287ff;
+          }
+        }
+
+        .add_item {
+          display: flex;
+          flex-direction: column;
+          align-items: center;
+          justify-content: center;
+          color: #4287ff;
+          cursor: pointer;
+        }
+
+        .add_img {
+          width: 80px;
+          height: 80px;
+        }
+      }
+
+      .footer {
+        display: flex;
+        justify-content: center;
+        margin-top: 32px;
+      }
+    }
+
+    .view {
+      margin-top: 32px;
+      text-align: center;
+      cursor: pointer;
+    }
+  }
+}
+</style>
+<!-- <style lang="scss">
+.el-pagination.is-background .btn-next,
+.el-pagination.is-background .btn-prev,
+.el-pagination.is-background .el-pager li {
+  background-color: #fff !important;
+}
+.el-pagination.is-background .btn-next.is-active,
+.el-pagination.is-background .btn-prev.is-active,
+.el-pagination.is-background .el-pager li.is-active {
+  color: rgba(0, 0, 0, 0.85);
+}
+</style> -->
diff --git a/src/views/systemManagement/accountManagement/addEdit.vue b/src/views/systemManagement/accountManagement/addEdit.vue
new file mode 100644
index 0000000..a209f5c
--- /dev/null
+++ b/src/views/systemManagement/accountManagement/addEdit.vue
@@ -0,0 +1,292 @@
+<script setup lang="ts">
+import { reactive, ref } from "vue";
+import { saveUser, updateUser } from "@/api/systemManagement";
+import { FormInstance } from "element-plus";
+import { message } from "@/utils/message";
+import { nextTick } from "vue";
+
+defineOptions({
+  name: "AddEdit"
+});
+
+const isEditFlag = ref(false);
+const id = ref("");
+const dialogVisible = ref(false);
+const formData = reactive({
+  roleCode: "",
+  name: "",
+  phone: "",
+  account: "",
+  password: ""
+});
+const ruleFormRef = ref<FormInstance>();
+const rules = {
+  name: [{ required: true, message: "请输入名称", trigger: "change" }],
+  roleCode: [{ required: true, message: "请选择", trigger: "change" }],
+  account: [
+    { required: true, message: "账号不能为空", trigger: "change" },
+    {
+      pattern: /^[a-zA-Z0-9_]*$/,
+      message: "账号不能包含特殊符号,请重新输入",
+      trigger: "blur"
+    }
+  ],
+  password: [
+    { required: true, message: "密码不能为空", trigger: "change" }
+    // {
+    //   pattern: /^[a-zA-Z0-9_]*$/,
+    //   message: "密码不能包含特殊符号,请重新输入",
+    //   trigger: "blur"
+    // }
+  ]
+};
+
+const disposalMethodFlag = ref(false);
+defineExpose({
+  async open(item) {
+    disposalMethodFlag.value = true;
+    dialogVisible.value = true;
+    await nextTick();
+    isEditFlag.value = false;
+    if (item) {
+      for (const key in item) {
+        // eslint-disable-next-line no-prototype-builtins
+        if (formData.hasOwnProperty(key)) {
+          formData[key] = item[key];
+        }
+      }
+      isEditFlag.value = true;
+      id.value = item.id;
+    }
+  }
+});
+
+const resetForm = () => {
+  ruleFormRef.value.resetFields();
+};
+const closeDialog = () => {
+  dialogVisible.value = false;
+  resetForm();
+};
+const emit = defineEmits(["update"]);
+
+const submit = (formEl: FormInstance | undefined) => {
+  formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (isEditFlag.value) {
+        const res: any = await updateUser({
+          ...formData,
+          id: id.value
+        });
+        if (res.code === 200) {
+          message("修改成功", { type: "success" });
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      } else {
+        const res: any = await saveUser(formData);
+        if (res.code === 200) {
+          message("新增成功", { type: "success" });
+
+          emit("update");
+          dialogVisible.value = false;
+        }
+      }
+    } else {
+      return fields;
+    }
+  });
+};
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      width="800"
+      append-to-body
+      v-model="dialogVisible"
+      :show-close="false"
+      :with-header="false"
+      :before-close="closeDialog"
+      custom-class="AddEdit"
+    >
+      <div class="AddEdit">
+        <div class="header-title">
+          <div class="tip" />
+          <span>新建账号</span>
+        </div>
+        <div class="line" />
+        <el-form
+          ref="ruleFormRef"
+          :model="formData"
+          :rules="rules"
+          label-width="100px"
+        >
+          <el-form-item label="角色 " prop="roleCode">
+            <el-select
+              style="width: 100%"
+              size="large"
+              filterable
+              clearable
+              v-model="formData.roleCode"
+              placeholder="请选择角色"
+            >
+              <el-option label="普通用户" value="1" />
+              <el-option label="管理员" value="0" />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="姓名 " prop="name">
+            <el-input
+              size="large"
+              v-model="formData.name"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <!-- <el-form-item label="联系电话 " prop="phone">
+            <el-input
+              size="large"
+              v-model="formData.phone"
+              placeholder="请输入"
+            />
+          </el-form-item> -->
+          <el-form-item label="账号 " prop="account">
+            <el-input
+              :disabled="isEditFlag"
+              size="large"
+              v-model="formData.account"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <el-form-item label="密码 " prop="password">
+            <el-input
+              size="large"
+              v-model="formData.password"
+              placeholder="请输入"
+            />
+          </el-form-item>
+        </el-form>
+      </div>
+      <template #footer>
+        <div class="footer_btn">
+          <div class="reset" @click="resetForm()">重置</div>
+          <div class="main" @click="submit(ruleFormRef)">确定</div>
+        </div>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+<style lang="scss" scoped>
+.AddEdit {
+  .header-title {
+    display: flex;
+    align-items: center;
+    // border-left: 6px solid #4287ff;
+
+    font-size: 20px;
+    font-weight: bold;
+    color: #2b3f54;
+
+    .tip {
+      width: 6px;
+      height: 20px;
+      margin-right: 10px;
+      line-height: 20px;
+      background: #4287ff;
+    }
+  }
+
+  .line {
+    position: relative;
+    left: -20px;
+    width: 755px;
+    height: 1px;
+    margin: 24px 0;
+    background: rgb(91 139 255 / 30%);
+  }
+
+  .footer_btn {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    margin-top: 16px;
+
+    .reset {
+      width: 188px;
+      height: 48px;
+      margin-right: 24px;
+      font-size: 16px;
+      font-weight: 400;
+      line-height: 48px;
+      color: #4287ff;
+      text-align: center;
+      cursor: pointer;
+      background: #fff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+
+    .main {
+      width: 188px;
+      height: 48px;
+      font-size: 16px;
+      line-height: 48px;
+      color: #fff;
+      text-align: center;
+      cursor: pointer;
+      background: #4287ff;
+      border: 1px solid #4287ff;
+      border-radius: 6px;
+    }
+  }
+
+  .normal_list {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+
+    .normal_list_item {
+      margin-bottom: 12px;
+      border: 1px solid #d9d9d9;
+
+      .top {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 36px;
+        padding: 0 12px;
+        font-size: 14px;
+        font-weight: 400;
+        line-height: 36px;
+        color: #333;
+        background: #f5f7f9;
+
+        .icon {
+          font-size: 16px;
+          cursor: pointer;
+        }
+      }
+    }
+
+    :deep(.el-textarea__inner) {
+      box-shadow: none;
+    }
+  }
+
+  .add_btn {
+    width: 76px;
+    height: 32px;
+    margin-left: 16px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 32px;
+    color: #4287ff;
+    text-align: center;
+    cursor: pointer;
+    background: #fff;
+    border: 1px solid #4287ff;
+    border-radius: 6px;
+    opacity: 1;
+  }
+}
+</style>
diff --git a/src/views/systemManagement/accountManagement/index.vue b/src/views/systemManagement/accountManagement/index.vue
new file mode 100644
index 0000000..840d045
--- /dev/null
+++ b/src/views/systemManagement/accountManagement/index.vue
@@ -0,0 +1,173 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+
+import { reactive, ref } from "vue";
+import { queryUserPage, deactivateUser } from "@/api/systemManagement";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import AddEdit from "./addEdit.vue";
+defineOptions({
+  name: "AccountManagement"
+});
+
+const dataList = ref([{}]);
+const loading = ref(false);
+const AddEditRef = ref(null);
+const seachForm = reactive({
+  userName: "",
+  roleCode: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns: TableColumnList = [
+  {
+    label: "用户账号",
+    prop: "account",
+    minWidth: 150
+  },
+  {
+    label: "用户姓名",
+    prop: "name",
+    minWidth: 240
+  },
+  {
+    label: "角色",
+    prop: "roleCode",
+    formatter: ({ roleCode }) => {
+      return roleCode === "0" ? "管理员 " : "普通用户";
+    }
+  },
+  {
+    label: "启用/禁用",
+    fixed: "right",
+    slot: "enable"
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    slot: "operation"
+  }
+];
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    userName: seachForm.userName,
+    roleCode: seachForm.roleCode
+  };
+  const res: any = await queryUserPage(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+const search = () => {
+  pagination.currentPage = 1;
+  pagination.pageSize = 10;
+  getData();
+};
+
+const reset = () => {
+  seachForm.userName = "";
+  seachForm.roleCode = "";
+  search();
+};
+const add = () => {
+  AddEditRef.value.open();
+};
+const edit = item => {
+  AddEditRef.value.open(JSON.parse(JSON.stringify(item)));
+};
+const changeStatus = async id => {
+  if (!id) return;
+  const res: any = await deactivateUser({ id });
+  if (res.code === 200) {
+    message("操作成功", { type: "success" });
+    getData();
+  }
+};
+onMounted(() => {
+  getData();
+});
+</script>
+
+<template>
+  <div class="app-main-content">
+    <div class="seach">
+      <el-form :model="seachForm">
+        <el-row>
+          <el-form-item label="姓名:">
+            <el-input size="large" v-model="seachForm.userName" />
+          </el-form-item>
+          <el-form-item class="ml-4" label="角色:" prop="role">
+            <el-select
+              size="large"
+              filterable
+              clearable
+              v-model="seachForm.roleCode"
+              placeholder="请选择角色"
+            >
+              <el-option label="普通用户" value="1" />
+              <el-option label="管理员" value="0" />
+            </el-select>
+          </el-form-item>
+          <el-button class="ml-8" size="large" @click="search" type="primary"
+            >搜索</el-button
+          >
+          <el-button size="large" @click="reset">重置</el-button>
+        </el-row>
+      </el-form>
+    </div>
+    <div class="main-table">
+      <div class="main-table-title">
+        <div class="title">
+          <div class="line" />
+          <span>用户列表</span>
+        </div>
+        <el-row class="mb-6">
+          <el-button size="large" @click="add" type="primary">新建</el-button>
+        </el-row>
+      </div>
+      <pure-table
+        align-whole="center"
+        showOverflowTooltip
+        table-layout="auto"
+        :loading="loading"
+        adaptive
+        :data="dataList"
+        :columns="columns"
+        :pagination="pagination"
+        :header-cell-style="{
+          background: 'var(--el-table-row-hover-bg-color)',
+          color: 'var(--el-text-color-primary)'
+        }"
+        @page-size-change="handleSizeChange"
+        @page-current-change="handleCurrentChange"
+        ><template #operation="{ row }">
+          <el-button link type="primary" @click="edit(row)">编辑</el-button>
+        </template>
+        <template #enable="{ row }">
+          <el-switch
+            size="large"
+            v-model="row.status"
+            @change="changeStatus(row.id)"
+            :active-value="0"
+            :inactive-value="1"
+          />
+        </template>
+      </pure-table>
+    </div>
+    <AddEdit @update="getData" ref="AddEditRef" />
+  </div>
+</template>
diff --git a/src/views/systemManagement/loginStatus/index.vue b/src/views/systemManagement/loginStatus/index.vue
new file mode 100644
index 0000000..643142f
--- /dev/null
+++ b/src/views/systemManagement/loginStatus/index.vue
@@ -0,0 +1,125 @@
+<script setup lang="ts">
+import { PaginationProps } from "@pureadmin/table";
+
+import { reactive, ref } from "vue";
+import { queryPageList, deleteItem } from "@/api/disease";
+import { onMounted } from "vue";
+import { message } from "@/utils/message";
+import { ElMessageBox } from "element-plus";
+defineOptions({
+  name: "AccountManagement"
+});
+
+const dataList = ref([{}]);
+const loading = ref(false);
+const addEditRef = ref(null);
+const seachForm = reactive({
+  name: ""
+});
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 10,
+  currentPage: 1,
+  background: true
+});
+const columns: TableColumnList = [
+  {
+    label: "用户账号",
+    prop: "code"
+  },
+  {
+    label: "用户姓名",
+    prop: "diseaseName"
+  },
+  {
+    label: "角色",
+    prop: "diseaseName"
+  },
+  {
+    label: "登录时间",
+    prop: "diseaseName",
+    width: 200
+  },
+  {
+    label: "状态",
+    prop: "diseaseName",
+    width: 100
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    slot: "operation"
+  }
+];
+const getData = async () => {
+  const params = {
+    pageNum: pagination.currentPage,
+    pageSize: pagination.pageSize,
+    name: seachForm.name
+  };
+  const res: any = await queryPageList(params);
+  dataList.value = res.data.records;
+  pagination.total = res.data.total;
+};
+function handleSizeChange(val: number) {
+  pagination.pageSize = val;
+  getData();
+}
+
+function handleCurrentChange(val: number) {
+  pagination.currentPage = val;
+  getData();
+}
+
+const edit = item => {
+  addEditRef.value.open("edit", JSON.parse(JSON.stringify(item)));
+};
+const handleDelete = item => {
+  ElMessageBox.confirm(
+    item ? `确认删除后${item.diseaseName}的所有信息将被清空, 且无法恢复` : "",
+    "提示",
+    {
+      type: "warning"
+    }
+  )
+    .then(async () => {
+      const res = await deleteItem({ id: item.id });
+      if (res.code === 200) {
+        getData();
+        message("删除成功", { type: "success" });
+      }
+    })
+    .catch(() => {});
+};
+onMounted(() => {
+  // getData();
+});
+</script>
+
+<template>
+  <div class="accountManagement">
+    <pure-table
+      border
+      align-whole="center"
+      showOverflowTooltip
+      table-layout="auto"
+      :loading="loading"
+      adaptive
+      :data="dataList"
+      :columns="columns"
+      :pagination="pagination"
+      :header-cell-style="{
+        background: 'var(--el-table-row-hover-bg-color)',
+        color: 'var(--el-text-color-primary)'
+      }"
+      @page-size-change="handleSizeChange"
+      @page-current-change="handleCurrentChange"
+      ><template #operation="{ row }">
+        <el-button link type="primary" @click="edit(row)"> 编辑 </el-button>
+        <el-button link type="primary" @click="handleDelete(row)">
+          删除
+        </el-button>
+      </template>
+    </pure-table>
+  </div>
+</template>
diff --git a/src/views/welcome/index.vue b/src/views/welcome/index.vue
new file mode 100644
index 0000000..66538c9
--- /dev/null
+++ b/src/views/welcome/index.vue
@@ -0,0 +1,11 @@
+<script setup lang="ts">
+defineOptions({
+  name: "Welcome"
+});
+</script>
+
+<template>
+  <div class="container">
+    <h1>算法管理</h1>
+  </div>
+</template>
diff --git a/vite.config.ts b/vite.config.ts
index ffe1161..0af3be0 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -45,8 +45,29 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
       // 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
       proxy: {
         // 类型: Record<string, string | ProxyOp 为开发服务器配置自定义代理规则
-        "/virtual-patient": {
-          target: "http://192.168.10.87:8899/",
+        "/virtual-patient-manage/": {
+          target: "http://192.168.10.137:8891/",
+          changeOrigin: true,
+          secure: false
+          // eslint-disable-next-line no-shadow
+          // rewrite: path => path.replace("/ask", "")
+        },
+        "/virtual-patient/": {
+          target: "http://192.168.10.137:8899/",
+          changeOrigin: true,
+          secure: false
+          // eslint-disable-next-line no-shadow
+          // rewrite: path => path.replace("/ask", "")
+        },
+        "/virtual-patient-rasa/": {
+          target: "http://192.168.10.137:8890/",
+          changeOrigin: true,
+          secure: false
+          // eslint-disable-next-line no-shadow
+          // rewrite: path => path.replace("/ask", "")
+        },
+        "/virtual-patient-graph/": {
+          target: "http://192.168.10.137:8892/",
           changeOrigin: true,
           secure: false
           // eslint-disable-next-line no-shadow