28 Revize 6fd8c33a6c ... fe7441a603

Autor SHA1 Zpráva Datum
  classic_blue fe7441a603 fix 封禁群组二开 před 1 měsícem
  limeng 9bca96435d Merge remote-tracking branch 'origin/v1.7' into dev před 1 měsícem
  classic_blue 73391ccf34 fix 1.类型启用必填校验 před 1 měsícem
  chenchen fbccfc404c [fix] před 1 měsícem
  classic_blue b1ba5b6558 fix 增加群组类型提示 před 1 měsícem
  chenchen 9673457439 [fix] před 2 měsíci
  chenchen 200e20fe37 [fix] před 2 měsíci
  limeng edffa4a3ac Merge remote-tracking branch 'origin/v1.6' into dev před 2 měsíci
  chenchen 05cebba635 [fix] před 2 měsíci
  chenchen 6daf009345 [fix] před 2 měsíci
  chenchen a0d65a5585 [fix] před 2 měsíci
  chenchen 382284fe25 [fix] před 2 měsíci
  chenchen 3a12c65ea9 [fix] před 2 měsíci
  chenchen 3dfb395ca0 [fix] před 2 měsíci
  chenchen daa62add17 [fix] před 2 měsíci
  chenchen 5c57d1fe2a [fix] před 2 měsíci
  classic_blue 8b6384561b fix 修改聊天板块后台界面bug před 2 měsíci
  chenchen 031e7f6238 [fix] před 2 měsíci
  classic_blue 2417fd7572 fix 去掉浏览记录管理页面 před 2 měsíci
  classic_blue ce0e9e57b6 fix 修改群聊类型为级联选择 před 2 měsíci
  classic_blue c419d273ec feat 新增群 群成员 群消息 群邀请 管理页面 před 2 měsíci
  classic_blue e3ccbff987 feat 新增群聊类型管理页面 před 2 měsíci
  chenchen 5b85578245 Merge branch 'v1.6' of http://1.94.207.143:3000/xyy/tourism_platform_web_v3 into v1.6 před 2 měsíci
  chenchen bbd224d3d5 [fix] před 2 měsíci
  classic_blue 036a4024cf feat 新增举报、举报类型、敏感词黑白名单管理页面 před 2 měsíci
  classic_blue a5d961021d feat 新增浏览记录管理页面 před 2 měsíci
  畅 8618624215 feat新增粉丝管理模块 před 2 měsíci
   2c99035aee feat新增粉丝管理模块 před 2 měsíci
78 změnil soubory, kde provedl 32232 přidání a 20 odebrání
  1. 1 1
      .env.development
  2. 17589 0
      package-lock.json
  3. 34 2
      src/api/generated/index.ts
  4. 43 0
      src/api/generated/tourBrowseRecordsController.ts
  5. 43 0
      src/api/generated/tourFansController.ts
  6. 43 0
      src/api/generated/tourImComplaintTypeController.ts
  7. 43 0
      src/api/generated/tourImComplaitController.ts
  8. 53 0
      src/api/generated/tourImGroupController.ts
  9. 43 0
      src/api/generated/tourImGroupInvitationController.ts
  10. 43 0
      src/api/generated/tourImGroupTypeController.ts
  11. 43 0
      src/api/generated/tourImMemberController.ts
  12. 43 0
      src/api/generated/tourImMessageController.ts
  13. 43 0
      src/api/generated/tourImSensitiveWordAllowController.ts
  14. 43 0
      src/api/generated/tourImSensitiveWordDenyController.ts
  15. 6 3
      src/api/generated/tourOrderController.ts
  16. 47 0
      src/api/generated/tourProjectGroupPurchaseApplyController.ts
  17. 43 0
      src/api/generated/tourProjectGroupPurchaseBannerController.ts
  18. 47 0
      src/api/generated/tourProjectGroupPurchaseController.ts
  19. 45 0
      src/api/generated/tourProjectGroupPurchaseDetailController.ts
  20. 49 0
      src/api/generated/tourProjectGroupPurchaseRebateController.ts
  21. 55 0
      src/api/system/DictionaryController.ts
  22. 47 0
      src/common/staticDict/index.ts
  23. 1 1
      src/components/Dialog/types.d.ts
  24. 301 0
      src/pages/ImComplaint/formEditTourImComplaintType.vue
  25. 493 0
      src/pages/ImComplaint/formEditTourImComplait.vue
  26. 409 0
      src/pages/ImComplaint/formTourImComplaintType.vue
  27. 546 0
      src/pages/ImComplaint/formTourImComplait.vue
  28. 607 0
      src/pages/ImGroup/formEditTourImGroup.vue
  29. 278 0
      src/pages/ImGroup/formEditTourImGroupInvitation.vue
  30. 382 0
      src/pages/ImGroup/formEditTourImGroupType.vue
  31. 260 0
      src/pages/ImGroup/formEditTourImMember.vue
  32. 524 0
      src/pages/ImGroup/formEditTourImMessage.vue
  33. 789 0
      src/pages/ImGroup/formTourImGroup.vue
  34. 528 0
      src/pages/ImGroup/formTourImGroupInvitation.vue
  35. 558 0
      src/pages/ImGroup/formTourImGroupType.vue
  36. 595 0
      src/pages/ImGroup/formTourImMember.vue
  37. 559 0
      src/pages/ImGroup/formTourImMessage.vue
  38. 225 0
      src/pages/SensitiveWord/formEditTourImSensitiveWordAllow.vue
  39. 225 0
      src/pages/SensitiveWord/formEditTourImSensitiveWordDeny.vue
  40. 365 0
      src/pages/SensitiveWord/formTourImSensitiveWordAllow.vue
  41. 365 0
      src/pages/SensitiveWord/formTourImSensitiveWordDeny.vue
  42. 363 0
      src/pages/TourBrowseRecords/formTourBrowseRecords.vue
  43. 319 0
      src/pages/tourFans/formEditTourFans.vue
  44. 437 0
      src/pages/tourFans/formTourFans.vue
  45. 2 2
      src/pages/tourHouseRentInfo/formTourHouseRentInfo.vue
  46. 6 0
      src/pages/tourOrder/formEditTourOrder.vue
  47. 276 0
      src/pages/tourOrder/formEditTourOrderRebate.vue
  48. 50 8
      src/pages/tourOrder/formTourOrder.vue
  49. 311 0
      src/pages/tourProjectGroupPurchase/editFormProjectGroupPurchaseDetail.vue
  50. 636 0
      src/pages/tourProjectGroupPurchase/editTourProjectGroupPurchase.vue
  51. 279 0
      src/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseDetail.vue
  52. 500 0
      src/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseInfo.vue
  53. 456 0
      src/pages/tourProjectGroupPurchaseApply/editTourProjectGroupPurchaseState.vue
  54. 313 0
      src/pages/tourProjectGroupPurchaseApply/formTourProjectGroupPurchaseApply.vue
  55. 511 0
      src/pages/tourProjectGroupPurchaseBanner/editTourProjectGroupPurchaseBanner.vue
  56. 433 0
      src/pages/tourProjectGroupPurchaseBanner/formTourProjectGroupPurchaseBannerInfo.vue
  57. 270 0
      src/pages/tourProjectGroupPurchaseRebate/formTourProjectGroupPurchaseRebate.vue
  58. 7 0
      src/pages/tourTourismBookInfo/selectBookTourismProject/selectBookTourismProject.vue
  59. 1 1
      src/pages/tourismProject/formTourismProject.vue
  60. 2 2
      src/pages/tourismProject/verifyTourismProjectDatePrice.vue
  61. 112 0
      src/router/systemRouters.ts
  62. 8 0
      src/types/table/TourOrder.d.ts
  63. 27 0
      src/types/table/tourBrowseRecords.d.ts
  64. 23 0
      src/types/table/tourFans.d.ts
  65. 25 0
      src/types/table/tourImComplaintType.d.ts
  66. 30 0
      src/types/table/tourImComplait.d.ts
  67. 44 0
      src/types/table/tourImGroup.d.ts
  68. 30 0
      src/types/table/tourImGroupInvitation.d.ts
  69. 28 0
      src/types/table/tourImGroupType.d.ts
  70. 42 0
      src/types/table/tourImMember.d.ts
  71. 40 0
      src/types/table/tourImMessage.d.ts
  72. 10 0
      src/types/table/tourImSensitiveWordAllow.d.ts
  73. 10 0
      src/types/table/tourImSensitiveWordDeny.d.ts
  74. 53 0
      src/types/table/tourProjectGroupPurchase.d.ts
  75. 29 0
      src/types/table/tourProjectGroupPurchaseApply.d.ts
  76. 32 0
      src/types/table/tourProjectGroupPurchaseBanner.d.ts
  77. 28 0
      src/types/table/tourProjectGroupPurchaseDetail.d.ts
  78. 33 0
      src/types/table/tourProjectGroupPurchaseRebate.d.ts

+ 1 - 1
.env.development

@@ -1,3 +1,3 @@
 # VUE_APP_SERVER_HOST='http://localhost:8082/'
-VUE_APP_SERVER_HOST='http://192.168.1.43:8082/'
+VUE_APP_SERVER_HOST='http://192.168.1.44:8082/'
 VUE_APP_PROJECT_NAME='橙单演示工程'

+ 17589 - 0
package-lock.json

@@ -0,0 +1,17589 @@
+{
+  "name": "orange",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "orange",
+      "version": "0.0.0",
+      "license": "ISC",
+      "dependencies": {
+        "@element-plus/icons-vue": "^2.3.1",
+        "@highlightjs/vue-plugin": "^2.1.0",
+        "@layui/layui-vue": "^2.11.5",
+        "@vue-office/docx": "^1.6.2",
+        "@vue-office/excel": "^1.7.11",
+        "@vue-office/pdf": "^2.0.8",
+        "@wangeditor/editor": "^5.1.23",
+        "@wangeditor/editor-for-vue": "^5.1.12",
+        "ace-builds": "^1.32.2",
+        "axios": "^1.5.1",
+        "bpmn-js-token-simulation": "^0.10.0",
+        "clipboard": "^2.0.11",
+        "core-js": "^3.8.3",
+        "crypto-js": "^4.2.0",
+        "dayjs": "^1.11.10",
+        "diagram-js": "^6.8.2",
+        "echarts": "^5.5.0",
+        "ejs": "^3.1.9",
+        "element-plus": "^2.7.3",
+        "highlight.js": "^11.9.0",
+        "jsencrypt": "^3.3.2",
+        "json-bigint": "^1.0.0",
+        "lodash": "^4.17.21",
+        "min-dash": "^4.2.2",
+        "pinia": "^2.1.6",
+        "pinia-plugin-persist": "^1.0.0",
+        "print-js": "^1.6.0",
+        "vant": "^4.7.3",
+        "vue": "^3.3.8",
+        "vue-demi": "^0.14.6",
+        "vue-draggable-plus": "0.3.1",
+        "vue-json-viewer": "^3.0.4",
+        "vue-router": "^4.2.5",
+        "vxe-table": "^4.5.13",
+        "xe-utils": "^3.5.14",
+        "xml-js": "^1.6.11"
+      },
+      "devDependencies": {
+        "@types/ejs": "^3.1.5",
+        "@types/json-bigint": "^1.0.4",
+        "@types/node": "^18.11.17",
+        "@typescript-eslint/eslint-plugin": "^5.46.1",
+        "@typescript-eslint/parser": "^5.46.1",
+        "@vant/auto-import-resolver": "^1.0.2",
+        "@vue/cli-plugin-babel": "~5.0.0",
+        "@vue/cli-plugin-eslint": "~5.0.0",
+        "@vue/cli-plugin-router": "~5.0.0",
+        "@vue/cli-plugin-typescript": "~5.0.0",
+        "@vue/cli-plugin-vuex": "~5.0.0",
+        "@vue/cli-service": "~5.0.0",
+        "autoprefixer": "^10.4.16",
+        "bpmn-js": "7.5.0",
+        "bpmn-js-properties-panel": "0.37.6",
+        "eslint": "^8.30.0",
+        "eslint-config-prettier": "^8.5.0",
+        "eslint-import-resolver-typescript": "^3.6.1",
+        "eslint-plugin-import": "^2.29.0",
+        "eslint-plugin-prettier": "^4.2.1",
+        "eslint-plugin-vue": "^9.8.0",
+        "node-polyfill-webpack-plugin": "^4.0.0",
+        "postcss": "^8.4.20",
+        "postcss-html": "^1.5.0",
+        "postcss-preset-env": "^7.8.3",
+        "postcss-scss": "^4.0.6",
+        "prettier": "2.8.1",
+        "sass": "^1.32.7",
+        "sass-loader": "^12.0.0",
+        "typescript": "^4.9.3",
+        "unplugin-auto-import": "^0.16.7",
+        "unplugin-vue-components": "^0.25.2",
+        "vue-eslint-parser": "^9.1.0"
+      }
+    },
+    "node_modules/@achrinza/node-ipc": {
+      "version": "9.2.9",
+      "resolved": "https://registry.npmmirror.com/@achrinza/node-ipc/-/node-ipc-9.2.9.tgz",
+      "integrity": "sha512-7s0VcTwiK/0tNOVdSX9FWMeFdOEcsAOz9HesBldXxFMaGvIak7KC2z9tV9EgsQXn6KUsWsfIkViMNuIo0GoZDQ==",
+      "dev": true,
+      "dependencies": {
+        "@node-ipc/js-queue": "2.0.3",
+        "event-pubsub": "4.3.0",
+        "js-message": "1.0.7"
+      },
+      "engines": {
+        "node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22"
+      }
+    },
+    "node_modules/@ampproject/remapping": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz",
+      "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@antfu/utils": {
+      "version": "0.7.10",
+      "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.10.tgz",
+      "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.26.2",
+      "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.2.tgz",
+      "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/compat-data": {
+      "version": "7.26.2",
+      "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.26.2.tgz",
+      "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.0.tgz",
+      "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
+      "dev": true,
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.0",
+        "@babel/code-frame": "^7.26.0",
+        "@babel/generator": "^7.26.0",
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-module-transforms": "^7.26.0",
+        "@babel/helpers": "^7.26.0",
+        "@babel/parser": "^7.26.0",
+        "@babel/template": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.26.0",
+        "convert-source-map": "^2.0.0",
+        "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.2",
+        "json5": "^2.2.3",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/babel"
+      }
+    },
+    "node_modules/@babel/core/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/core/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.26.2",
+      "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.26.2.tgz",
+      "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.26.2",
+        "@babel/types": "^7.26.0",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/generator/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz",
+      "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-builder-binary-assignment-operator-visitor/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
+      "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/compat-data": "^7.25.9",
+        "@babel/helper-validator-option": "^7.25.9",
+        "browserslist": "^4.24.0",
+        "lru-cache": "^5.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
+      "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-member-expression-to-functions": "^7.25.9",
+        "@babel/helper-optimise-call-expression": "^7.25.9",
+        "@babel/helper-replace-supers": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-create-regexp-features-plugin": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz",
+      "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "regexpu-core": "^6.1.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/helper-define-polyfill-provider": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz",
+      "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.22.6",
+        "@babel/helper-plugin-utils": "^7.22.5",
+        "debug": "^4.1.1",
+        "lodash.debounce": "^4.0.8",
+        "resolve": "^1.14.2"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/@babel/helper-member-expression-to-functions": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+      "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-member-expression-to-functions/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+      "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-transforms": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+      "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-optimise-call-expression": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+      "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-optimise-call-expression/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-plugin-utils": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
+      "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-remap-async-to-generator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+      "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-wrap-function": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-replace-supers": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz",
+      "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-member-expression-to-functions": "^7.25.9",
+        "@babel/helper-optimise-call-expression": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/helper-simple-access": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz",
+      "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-simple-access/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+      "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-skip-transparent-expression-wrappers/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-option": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+      "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-wrap-function": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+      "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-wrap-function/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.26.0.tgz",
+      "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.26.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helpers/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.26.2",
+      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.2.tgz",
+      "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
+      "dependencies": {
+        "@babel/types": "^7.26.0"
+      },
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/parser/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+      "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+      "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
+      "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+      "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+        "@babel/plugin-transform-optional-chaining": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.13.0"
+      }
+    },
+    "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+      "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-proposal-class-properties": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
+      "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+      "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.18.6",
+        "@babel/helper-plugin-utils": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-proposal-decorators": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz",
+      "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/plugin-syntax-decorators": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-proposal-private-property-in-object": {
+      "version": "7.21.0-placeholder-for-preset-env.2",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+      "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-decorators": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz",
+      "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+      "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-assertions": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+      "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-import-attributes": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+      "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-jsx": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
+      "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-syntax-unicode-sets-regex": {
+      "version": "7.18.6",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+      "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+        "@babel/helper-plugin-utils": "^7.18.6"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-arrow-functions": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+      "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-async-generator-functions": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz",
+      "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-remap-async-to-generator": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-async-to-generator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz",
+      "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-remap-async-to-generator": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-block-scoped-functions": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz",
+      "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-block-scoping": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
+      "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-class-properties": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+      "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-class-static-block": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+      "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.12.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-classes": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+      "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-replace-supers": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-computed-properties": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+      "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/template": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-destructuring": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+      "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-dotall-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+      "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-duplicate-keys": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+      "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+      "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-dynamic-import": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+      "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-exponentiation-operator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz",
+      "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-export-namespace-from": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+      "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-for-of": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
+      "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-function-name": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+      "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-json-strings": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+      "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-literals": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+      "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-logical-assignment-operators": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+      "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-member-expression-literals": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+      "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-amd": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+      "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-commonjs": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz",
+      "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-simple-access": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-systemjs": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+      "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-modules-umd": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+      "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+      "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-new-target": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+      "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz",
+      "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-numeric-separator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+      "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-object-rest-spread": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+      "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/plugin-transform-parameters": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-object-super": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+      "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-replace-supers": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-optional-catch-binding": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+      "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-optional-chaining": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+      "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-parameters": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+      "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-methods": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+      "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-private-property-in-object": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+      "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-property-literals": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+      "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-regenerator": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
+      "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "regenerator-transform": "^0.15.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-regexp-modifiers": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz",
+      "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-reserved-words": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+      "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-runtime": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz",
+      "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "babel-plugin-polyfill-corejs2": "^0.4.10",
+        "babel-plugin-polyfill-corejs3": "^0.10.6",
+        "babel-plugin-polyfill-regenerator": "^0.6.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-runtime/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/plugin-transform-shorthand-properties": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+      "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-spread": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+      "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-sticky-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+      "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-template-literals": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
+      "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-typeof-symbol": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
+      "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-escapes": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+      "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-property-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+      "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+      "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/plugin-transform-unicode-sets-regex": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+      "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0"
+      }
+    },
+    "node_modules/@babel/preset-env": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.26.0.tgz",
+      "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/compat-data": "^7.26.0",
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-validator-option": "^7.25.9",
+        "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9",
+        "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9",
+        "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9",
+        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9",
+        "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9",
+        "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+        "@babel/plugin-syntax-import-assertions": "^7.26.0",
+        "@babel/plugin-syntax-import-attributes": "^7.26.0",
+        "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+        "@babel/plugin-transform-arrow-functions": "^7.25.9",
+        "@babel/plugin-transform-async-generator-functions": "^7.25.9",
+        "@babel/plugin-transform-async-to-generator": "^7.25.9",
+        "@babel/plugin-transform-block-scoped-functions": "^7.25.9",
+        "@babel/plugin-transform-block-scoping": "^7.25.9",
+        "@babel/plugin-transform-class-properties": "^7.25.9",
+        "@babel/plugin-transform-class-static-block": "^7.26.0",
+        "@babel/plugin-transform-classes": "^7.25.9",
+        "@babel/plugin-transform-computed-properties": "^7.25.9",
+        "@babel/plugin-transform-destructuring": "^7.25.9",
+        "@babel/plugin-transform-dotall-regex": "^7.25.9",
+        "@babel/plugin-transform-duplicate-keys": "^7.25.9",
+        "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9",
+        "@babel/plugin-transform-dynamic-import": "^7.25.9",
+        "@babel/plugin-transform-exponentiation-operator": "^7.25.9",
+        "@babel/plugin-transform-export-namespace-from": "^7.25.9",
+        "@babel/plugin-transform-for-of": "^7.25.9",
+        "@babel/plugin-transform-function-name": "^7.25.9",
+        "@babel/plugin-transform-json-strings": "^7.25.9",
+        "@babel/plugin-transform-literals": "^7.25.9",
+        "@babel/plugin-transform-logical-assignment-operators": "^7.25.9",
+        "@babel/plugin-transform-member-expression-literals": "^7.25.9",
+        "@babel/plugin-transform-modules-amd": "^7.25.9",
+        "@babel/plugin-transform-modules-commonjs": "^7.25.9",
+        "@babel/plugin-transform-modules-systemjs": "^7.25.9",
+        "@babel/plugin-transform-modules-umd": "^7.25.9",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9",
+        "@babel/plugin-transform-new-target": "^7.25.9",
+        "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9",
+        "@babel/plugin-transform-numeric-separator": "^7.25.9",
+        "@babel/plugin-transform-object-rest-spread": "^7.25.9",
+        "@babel/plugin-transform-object-super": "^7.25.9",
+        "@babel/plugin-transform-optional-catch-binding": "^7.25.9",
+        "@babel/plugin-transform-optional-chaining": "^7.25.9",
+        "@babel/plugin-transform-parameters": "^7.25.9",
+        "@babel/plugin-transform-private-methods": "^7.25.9",
+        "@babel/plugin-transform-private-property-in-object": "^7.25.9",
+        "@babel/plugin-transform-property-literals": "^7.25.9",
+        "@babel/plugin-transform-regenerator": "^7.25.9",
+        "@babel/plugin-transform-regexp-modifiers": "^7.26.0",
+        "@babel/plugin-transform-reserved-words": "^7.25.9",
+        "@babel/plugin-transform-shorthand-properties": "^7.25.9",
+        "@babel/plugin-transform-spread": "^7.25.9",
+        "@babel/plugin-transform-sticky-regex": "^7.25.9",
+        "@babel/plugin-transform-template-literals": "^7.25.9",
+        "@babel/plugin-transform-typeof-symbol": "^7.25.9",
+        "@babel/plugin-transform-unicode-escapes": "^7.25.9",
+        "@babel/plugin-transform-unicode-property-regex": "^7.25.9",
+        "@babel/plugin-transform-unicode-regex": "^7.25.9",
+        "@babel/plugin-transform-unicode-sets-regex": "^7.25.9",
+        "@babel/preset-modules": "0.1.6-no-external-plugins",
+        "babel-plugin-polyfill-corejs2": "^0.4.10",
+        "babel-plugin-polyfill-corejs3": "^0.10.6",
+        "babel-plugin-polyfill-regenerator": "^0.6.1",
+        "core-js-compat": "^3.38.1",
+        "semver": "^6.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@babel/preset-env/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/@babel/preset-modules": {
+      "version": "0.1.6-no-external-plugins",
+      "resolved": "https://registry.npmmirror.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz",
+      "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/types": "^7.4.4",
+        "esutils": "^2.0.2"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.0.tgz",
+      "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
+      "dependencies": {
+        "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.25.9.tgz",
+      "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.25.9",
+        "@babel/parser": "^7.25.9",
+        "@babel/types": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.25.9",
+      "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.25.9.tgz",
+      "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.25.9",
+        "@babel/generator": "^7.25.9",
+        "@babel/parser": "^7.25.9",
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.25.9",
+        "debug": "^4.3.1",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.21.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.21.0.tgz",
+      "integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.19.4",
+        "@babel/helper-validator-identifier": "^7.19.1",
+        "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@bpmn-io/extract-process-variables": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/@bpmn-io/extract-process-variables/-/extract-process-variables-0.3.0.tgz",
+      "integrity": "sha512-cZMPBvVUXBn7++ZaOVQQGvhrMnFVcOP218yfYBKUv0EMYjo775ust/ZmfIgWd8llT4myXA6dPz12wcYXUBR1Bg==",
+      "dev": true,
+      "dependencies": {
+        "min-dash": "^3.5.2"
+      },
+      "peerDependencies": {
+        "camunda-bpmn-moddle": "^4.x"
+      }
+    },
+    "node_modules/@bpmn-io/extract-process-variables/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/@csstools/postcss-cascade-layers": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz",
+      "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/selector-specificity": "^2.0.2",
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-color-function": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz",
+      "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-font-format-keywords": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz",
+      "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-hwb-function": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz",
+      "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-ic-unit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz",
+      "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-is-pseudo-class": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz",
+      "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/selector-specificity": "^2.0.0",
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-nested-calc": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz",
+      "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-normalize-display-values": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz",
+      "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-oklab-function": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz",
+      "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-progressive-custom-properties": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz",
+      "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/@csstools/postcss-stepped-value-functions": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz",
+      "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-text-decoration-shorthand": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz",
+      "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-trigonometric-functions": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz",
+      "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/postcss-unset-value": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz",
+      "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==",
+      "dev": true,
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/@csstools/selector-specificity": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz",
+      "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==",
+      "dev": true,
+      "engines": {
+        "node": "^14 || ^16 || >=18"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss-selector-parser": "^6.0.10"
+      }
+    },
+    "node_modules/@ctrl/tinycolor": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+      "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@discoveryjs/json-ext": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
+      "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/@element-plus/icons-vue": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
+      "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/@eslint-community/eslint-utils": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmmirror.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+      "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
+      "dev": true,
+      "dependencies": {
+        "eslint-visitor-keys": "^3.4.3"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+      }
+    },
+    "node_modules/@eslint-community/regexpp": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+      "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@eslint/eslintrc": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+      "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^6.12.4",
+        "debug": "^4.3.2",
+        "espree": "^9.6.0",
+        "globals": "^13.19.0",
+        "ignore": "^5.2.0",
+        "import-fresh": "^3.2.1",
+        "js-yaml": "^4.1.0",
+        "minimatch": "^3.1.2",
+        "strip-json-comments": "^3.1.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/js": {
+      "version": "8.57.1",
+      "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.57.1.tgz",
+      "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/@floating-ui/core": {
+      "version": "1.6.8",
+      "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.8.tgz",
+      "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
+      "dependencies": {
+        "@floating-ui/utils": "^0.2.8"
+      }
+    },
+    "node_modules/@floating-ui/dom": {
+      "version": "1.6.5",
+      "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.5.tgz",
+      "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==",
+      "dependencies": {
+        "@floating-ui/core": "^1.0.0",
+        "@floating-ui/utils": "^0.2.0"
+      }
+    },
+    "node_modules/@floating-ui/utils": {
+      "version": "0.2.8",
+      "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.8.tgz",
+      "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig=="
+    },
+    "node_modules/@hapi/hoek": {
+      "version": "9.3.0",
+      "resolved": "https://registry.npmmirror.com/@hapi/hoek/-/hoek-9.3.0.tgz",
+      "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
+      "dev": true
+    },
+    "node_modules/@hapi/topo": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/@hapi/topo/-/topo-5.1.0.tgz",
+      "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
+      "dev": true,
+      "dependencies": {
+        "@hapi/hoek": "^9.0.0"
+      }
+    },
+    "node_modules/@highlightjs/vue-plugin": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/@highlightjs/vue-plugin/-/vue-plugin-2.1.0.tgz",
+      "integrity": "sha512-E+bmk4ncca+hBEYRV2a+1aIzIV0VSY/e5ArjpuSN9IO7wBJrzUE2u4ESCwrbQD7sAy+jWQjkV5qCCWgc+pu7CQ==",
+      "peerDependencies": {
+        "highlight.js": "^11.0.1",
+        "vue": "^3"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array": {
+      "version": "0.13.0",
+      "resolved": "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+      "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+      "deprecated": "Use @eslint/config-array instead",
+      "dev": true,
+      "dependencies": {
+        "@humanwhocodes/object-schema": "^2.0.3",
+        "debug": "^4.3.1",
+        "minimatch": "^3.0.5"
+      },
+      "engines": {
+        "node": ">=10.10.0"
+      }
+    },
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
+    "node_modules/@humanwhocodes/object-schema": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+      "deprecated": "Use @eslint/object-schema instead",
+      "dev": true
+    },
+    "node_modules/@intlify/core-base": {
+      "version": "9.6.3",
+      "resolved": "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.6.3.tgz",
+      "integrity": "sha512-18QrM11RVacRX5fnxCU6twfFZ+utEciIZ+fC8I2GlVPn6Mig/8TTNcPgCIF7TE2UAVdO3ndEQJNZN09QzWxC4g==",
+      "dependencies": {
+        "@intlify/message-compiler": "9.6.3",
+        "@intlify/shared": "9.6.3"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      }
+    },
+    "node_modules/@intlify/message-compiler": {
+      "version": "9.6.3",
+      "resolved": "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.6.3.tgz",
+      "integrity": "sha512-F5u5IgBisGGjErY7yCjxTUEGgEFbjvmwbRp/gwVAgOxlz6SVZrvHGRchv8BAiyvbKP3wEc5elw7KkpBZm0ZOdA==",
+      "dependencies": {
+        "@intlify/shared": "9.6.3",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      }
+    },
+    "node_modules/@intlify/shared": {
+      "version": "9.6.3",
+      "resolved": "https://registry.npmmirror.com/@intlify/shared/-/shared-9.6.3.tgz",
+      "integrity": "sha512-dDK+th57VhfMqUYQy5WXH5Qjoi0HHj4vtga9uLkqe7DXbhdPz95LSsnilsk3wg8gTdUOyhHnWCYMFRkASxM6lw==",
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+      "dependencies": {
+        "@jridgewell/set-array": "^1.2.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/resolve-uri": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+      "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/source-map": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.6.tgz",
+      "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25"
+      }
+    },
+    "node_modules/@jridgewell/sourcemap-codec": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+      "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
+    },
+    "node_modules/@jridgewell/trace-mapping": {
+      "version": "0.3.25",
+      "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+      "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+      "dependencies": {
+        "@jridgewell/resolve-uri": "^3.1.0",
+        "@jridgewell/sourcemap-codec": "^1.4.14"
+      }
+    },
+    "node_modules/@layui/icons-vue": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/@layui/icons-vue/-/icons-vue-1.1.3.tgz",
+      "integrity": "sha512-SQeYYdSjxuZtWRt+g7mStPh16Bh55rbi5+5yJYEMt/7/f9CPBzN8A/CfRoh90MC/1qCiYZYravWvooHF2NqxNw=="
+    },
+    "node_modules/@layui/layer-vue": {
+      "version": "2.4.7",
+      "resolved": "https://registry.npmmirror.com/@layui/layer-vue/-/layer-vue-2.4.7.tgz",
+      "integrity": "sha512-5lrsQ0v4ov7bHMGZ3StqAmIh9twvGDhAyWkQCoZN8ZaviXuLdvsztd6lvETpvLDtRC6TNwt0WgwWtBpLtW+vjw==",
+      "dependencies": {
+        "@layui/icons-vue": "1.1.3"
+      }
+    },
+    "node_modules/@layui/layui-vue": {
+      "version": "2.21.0",
+      "resolved": "https://registry.npmmirror.com/@layui/layui-vue/-/layui-vue-2.21.0.tgz",
+      "integrity": "sha512-wS+j3cdbVja3MuBM6KCCxIQzsesxjjAaSGp+WcPZScYUgVR7MbbNf1Q4l3oqWS1PQtWFpDoYqm+WmcFU/+JLYQ==",
+      "dependencies": {
+        "@babel/types": "7.21.0",
+        "@ctrl/tinycolor": "^3.4.1",
+        "@floating-ui/dom": "1.6.5",
+        "@layui/icons-vue": "1.1.3",
+        "@layui/layer-vue": "2.4.7",
+        "@rollup/plugin-terser": "0.4.4",
+        "@types/qrcode": "1.5.0",
+        "@umijs/ssr-darkreader": "^4.9.45",
+        "@vueuse/core": "8.7.3",
+        "async-validator": "^4.1.1",
+        "cropperjs": "^1.5.12",
+        "dayjs": "^1.11.10",
+        "evtd": "^0.2.3",
+        "jsbarcode": "3.11.5",
+        "qrcode": "1.5.0",
+        "vue-i18n": "9.6.3"
+      }
+    },
+    "node_modules/@leichtgewicht/ip-codec": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
+      "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
+      "dev": true
+    },
+    "node_modules/@node-ipc/js-queue": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/@node-ipc/js-queue/-/js-queue-2.0.3.tgz",
+      "integrity": "sha512-fL1wpr8hhD5gT2dA1qifeVaoDFlQR5es8tFuKqjHX+kdOtdNHnxkVZbtIrR2rxnMFvehkjaZRNV2H/gPXlb0hw==",
+      "dev": true,
+      "dependencies": {
+        "easy-stack": "1.0.1"
+      },
+      "engines": {
+        "node": ">=1.0.0"
+      }
+    },
+    "node_modules/@nodelib/fs.scandir": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.stat": "2.0.5",
+        "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.stat": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nodelib/fs.walk": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.scandir": "2.1.5",
+        "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/@nolyfill/is-core-module": {
+      "version": "1.0.39",
+      "resolved": "https://registry.npmmirror.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz",
+      "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.4.0"
+      }
+    },
+    "node_modules/@parcel/watcher": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.0.tgz",
+      "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "dependencies": {
+        "detect-libc": "^1.0.3",
+        "is-glob": "^4.0.3",
+        "micromatch": "^4.0.5",
+        "node-addon-api": "^7.0.0"
+      },
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      },
+      "optionalDependencies": {
+        "@parcel/watcher-android-arm64": "2.5.0",
+        "@parcel/watcher-darwin-arm64": "2.5.0",
+        "@parcel/watcher-darwin-x64": "2.5.0",
+        "@parcel/watcher-freebsd-x64": "2.5.0",
+        "@parcel/watcher-linux-arm-glibc": "2.5.0",
+        "@parcel/watcher-linux-arm-musl": "2.5.0",
+        "@parcel/watcher-linux-arm64-glibc": "2.5.0",
+        "@parcel/watcher-linux-arm64-musl": "2.5.0",
+        "@parcel/watcher-linux-x64-glibc": "2.5.0",
+        "@parcel/watcher-linux-x64-musl": "2.5.0",
+        "@parcel/watcher-win32-arm64": "2.5.0",
+        "@parcel/watcher-win32-ia32": "2.5.0",
+        "@parcel/watcher-win32-x64": "2.5.0"
+      }
+    },
+    "node_modules/@parcel/watcher-android-arm64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz",
+      "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-darwin-arm64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz",
+      "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-darwin-x64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz",
+      "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-freebsd-x64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz",
+      "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm-glibc": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz",
+      "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm-musl": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz",
+      "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm64-glibc": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz",
+      "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm64-musl": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz",
+      "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-x64-glibc": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz",
+      "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-x64-musl": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz",
+      "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-arm64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz",
+      "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-ia32": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz",
+      "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-x64": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz",
+      "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@polka/url": {
+      "version": "1.0.0-next.28",
+      "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.28.tgz",
+      "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
+      "dev": true
+    },
+    "node_modules/@popperjs/core": {
+      "name": "@sxzz/popperjs-es",
+      "version": "2.11.7",
+      "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
+      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
+    "node_modules/@rollup/plugin-terser": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmmirror.com/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
+      "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
+      "dependencies": {
+        "serialize-javascript": "^6.0.1",
+        "smob": "^1.0.0",
+        "terser": "^5.17.4"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^2.0.0||^3.0.0||^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@rollup/pluginutils": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.3.tgz",
+      "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "^1.0.0",
+        "estree-walker": "^2.0.2",
+        "picomatch": "^4.0.2"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
+      },
+      "peerDependenciesMeta": {
+        "rollup": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@rollup/pluginutils/node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/@rtsao/scc": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/@rtsao/scc/-/scc-1.1.0.tgz",
+      "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+      "dev": true
+    },
+    "node_modules/@sideway/address": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz",
+      "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
+      "dev": true,
+      "dependencies": {
+        "@hapi/hoek": "^9.0.0"
+      }
+    },
+    "node_modules/@sideway/formula": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/@sideway/formula/-/formula-3.0.1.tgz",
+      "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
+      "dev": true
+    },
+    "node_modules/@sideway/pinpoint": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
+      "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
+      "dev": true
+    },
+    "node_modules/@soda/friendly-errors-webpack-plugin": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmmirror.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz",
+      "integrity": "sha512-h2ooWqP8XuFqTXT+NyAFbrArzfQA7R6HTezADrvD9Re8fxMLTPPniLdqVTdDaO0eIoLaAwKT+d6w+5GeTk7Vbg==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^3.0.0",
+        "error-stack-parser": "^2.0.6",
+        "string-width": "^4.2.3",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      },
+      "peerDependencies": {
+        "webpack": "^4.0.0 || ^5.0.0"
+      }
+    },
+    "node_modules/@soda/get-current-script": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@soda/get-current-script/-/get-current-script-1.0.2.tgz",
+      "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==",
+      "dev": true
+    },
+    "node_modules/@transloadit/prettier-bytes": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmmirror.com/@transloadit/prettier-bytes/-/prettier-bytes-0.0.7.tgz",
+      "integrity": "sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA=="
+    },
+    "node_modules/@trysound/sax": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz",
+      "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/@types/body-parser": {
+      "version": "1.19.5",
+      "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.5.tgz",
+      "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
+      "dev": true,
+      "dependencies": {
+        "@types/connect": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/bonjour": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@types/bonjour/-/bonjour-3.5.13.tgz",
+      "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/connect": {
+      "version": "3.4.38",
+      "resolved": "https://registry.npmmirror.com/@types/connect/-/connect-3.4.38.tgz",
+      "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/connect-history-api-fallback": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmmirror.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz",
+      "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==",
+      "dev": true,
+      "dependencies": {
+        "@types/express-serve-static-core": "*",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/ejs": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmmirror.com/@types/ejs/-/ejs-3.1.5.tgz",
+      "integrity": "sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg==",
+      "dev": true
+    },
+    "node_modules/@types/eslint": {
+      "version": "8.56.12",
+      "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.56.12.tgz",
+      "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "*",
+        "@types/json-schema": "*"
+      }
+    },
+    "node_modules/@types/eslint-scope": {
+      "version": "3.7.7",
+      "resolved": "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
+      "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
+      "dev": true,
+      "dependencies": {
+        "@types/eslint": "*",
+        "@types/estree": "*"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz",
+      "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+      "dev": true
+    },
+    "node_modules/@types/event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmmirror.com/@types/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ=="
+    },
+    "node_modules/@types/express": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/@types/express/-/express-4.17.21.tgz",
+      "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/body-parser": "*",
+        "@types/express-serve-static-core": "^4.17.33",
+        "@types/qs": "*",
+        "@types/serve-static": "*"
+      }
+    },
+    "node_modules/@types/express-serve-static-core": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-5.0.2.tgz",
+      "integrity": "sha512-vluaspfvWEtE4vcSDlKRNer52DvOGrB2xv6diXy6UKyKW0lqZiWHGNApSyxOv+8DE5Z27IzVvE7hNkxg7EXIcg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*",
+        "@types/send": "*"
+      }
+    },
+    "node_modules/@types/express/node_modules/@types/express-serve-static-core": {
+      "version": "4.19.6",
+      "resolved": "https://registry.npmmirror.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz",
+      "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "@types/qs": "*",
+        "@types/range-parser": "*",
+        "@types/send": "*"
+      }
+    },
+    "node_modules/@types/html-minifier-terser": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+      "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==",
+      "dev": true
+    },
+    "node_modules/@types/http-errors": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/@types/http-errors/-/http-errors-2.0.4.tgz",
+      "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
+      "dev": true
+    },
+    "node_modules/@types/http-proxy": {
+      "version": "1.17.15",
+      "resolved": "https://registry.npmmirror.com/@types/http-proxy/-/http-proxy-1.17.15.tgz",
+      "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/json-bigint": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/@types/json-bigint/-/json-bigint-1.0.4.tgz",
+      "integrity": "sha512-ydHooXLbOmxBbubnA7Eh+RpBzuaIiQjh8WGJYQB50JFGFrdxW7JzVlyEV7fAXw0T2sqJ1ysTneJbiyNLqZRAag==",
+      "dev": true
+    },
+    "node_modules/@types/json-schema": {
+      "version": "7.0.15",
+      "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
+      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+      "dev": true
+    },
+    "node_modules/@types/json5": {
+      "version": "0.0.29",
+      "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz",
+      "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+      "dev": true
+    },
+    "node_modules/@types/lodash": {
+      "version": "4.17.13",
+      "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.13.tgz",
+      "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg=="
+    },
+    "node_modules/@types/lodash-es": {
+      "version": "4.17.12",
+      "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz",
+      "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
+      "dependencies": {
+        "@types/lodash": "*"
+      }
+    },
+    "node_modules/@types/mime": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-1.3.5.tgz",
+      "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
+      "dev": true
+    },
+    "node_modules/@types/minimist": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmmirror.com/@types/minimist/-/minimist-1.2.5.tgz",
+      "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
+      "dev": true
+    },
+    "node_modules/@types/node": {
+      "version": "18.19.67",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.19.67.tgz",
+      "integrity": "sha512-wI8uHusga+0ZugNp0Ol/3BqQfEcCCNfojtO6Oou9iVNGPTL6QNSdnUdqq85fRgIorLhLMuPIKpsN98QE9Nh+KQ==",
+      "dependencies": {
+        "undici-types": "~5.26.4"
+      }
+    },
+    "node_modules/@types/node-forge": {
+      "version": "1.3.11",
+      "resolved": "https://registry.npmmirror.com/@types/node-forge/-/node-forge-1.3.11.tgz",
+      "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/normalize-package-data": {
+      "version": "2.4.4",
+      "resolved": "https://registry.npmmirror.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+      "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+      "dev": true
+    },
+    "node_modules/@types/parse-json": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.2.tgz",
+      "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
+      "dev": true
+    },
+    "node_modules/@types/qrcode": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/@types/qrcode/-/qrcode-1.5.0.tgz",
+      "integrity": "sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==",
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/qs": {
+      "version": "6.9.17",
+      "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.17.tgz",
+      "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==",
+      "dev": true
+    },
+    "node_modules/@types/range-parser": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/@types/range-parser/-/range-parser-1.2.7.tgz",
+      "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
+      "dev": true
+    },
+    "node_modules/@types/retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/@types/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+      "dev": true
+    },
+    "node_modules/@types/semver": {
+      "version": "7.5.8",
+      "resolved": "https://registry.npmmirror.com/@types/semver/-/semver-7.5.8.tgz",
+      "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
+      "dev": true
+    },
+    "node_modules/@types/send": {
+      "version": "0.17.4",
+      "resolved": "https://registry.npmmirror.com/@types/send/-/send-0.17.4.tgz",
+      "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
+      "dev": true,
+      "dependencies": {
+        "@types/mime": "^1",
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/serve-index": {
+      "version": "1.9.4",
+      "resolved": "https://registry.npmmirror.com/@types/serve-index/-/serve-index-1.9.4.tgz",
+      "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==",
+      "dev": true,
+      "dependencies": {
+        "@types/express": "*"
+      }
+    },
+    "node_modules/@types/serve-static": {
+      "version": "1.15.7",
+      "resolved": "https://registry.npmmirror.com/@types/serve-static/-/serve-static-1.15.7.tgz",
+      "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==",
+      "dev": true,
+      "dependencies": {
+        "@types/http-errors": "*",
+        "@types/node": "*",
+        "@types/send": "*"
+      }
+    },
+    "node_modules/@types/sockjs": {
+      "version": "0.3.36",
+      "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.36.tgz",
+      "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@types/web-bluetooth": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
+      "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
+    },
+    "node_modules/@types/webpack-env": {
+      "version": "1.18.5",
+      "resolved": "https://registry.npmmirror.com/@types/webpack-env/-/webpack-env-1.18.5.tgz",
+      "integrity": "sha512-wz7kjjRRj8/Lty4B+Kr0LN6Ypc/3SymeCCGSbaXp2leH0ZVg/PriNiOwNj4bD4uphI7A8NXS4b6Gl373sfO5mA==",
+      "dev": true
+    },
+    "node_modules/@types/ws": {
+      "version": "8.5.13",
+      "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.13.tgz",
+      "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
+    "node_modules/@typescript-eslint/eslint-plugin": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
+      "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.4.0",
+        "@typescript-eslint/scope-manager": "5.62.0",
+        "@typescript-eslint/type-utils": "5.62.0",
+        "@typescript-eslint/utils": "5.62.0",
+        "debug": "^4.3.4",
+        "graphemer": "^1.4.0",
+        "ignore": "^5.2.0",
+        "natural-compare-lite": "^1.4.0",
+        "semver": "^7.3.7",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/parser": "^5.0.0",
+        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/parser": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-5.62.0.tgz",
+      "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "5.62.0",
+        "@typescript-eslint/types": "5.62.0",
+        "@typescript-eslint/typescript-estree": "5.62.0",
+        "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
+      "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.62.0",
+        "@typescript-eslint/visitor-keys": "5.62.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/type-utils": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
+      "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/typescript-estree": "5.62.0",
+        "@typescript-eslint/utils": "5.62.0",
+        "debug": "^4.3.4",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "*"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/types": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/types/-/types-5.62.0.tgz",
+      "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@typescript-eslint/typescript-estree": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
+      "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+      "dev": true,
+      "dependencies": {
+        "@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",
+        "semver": "^7.3.7",
+        "tsutils": "^3.21.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@typescript-eslint/utils": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-5.62.0.tgz",
+      "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@types/json-schema": "^7.0.9",
+        "@types/semver": "^7.3.12",
+        "@typescript-eslint/scope-manager": "5.62.0",
+        "@typescript-eslint/types": "5.62.0",
+        "@typescript-eslint/typescript-estree": "5.62.0",
+        "eslint-scope": "^5.1.1",
+        "semver": "^7.3.7"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
+    },
+    "node_modules/@typescript-eslint/visitor-keys": {
+      "version": "5.62.0",
+      "resolved": "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+      "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+      "dev": true,
+      "dependencies": {
+        "@typescript-eslint/types": "5.62.0",
+        "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
+    },
+    "node_modules/@umijs/ssr-darkreader": {
+      "version": "4.9.45",
+      "resolved": "https://registry.npmmirror.com/@umijs/ssr-darkreader/-/ssr-darkreader-4.9.45.tgz",
+      "integrity": "sha512-XlcwzSYQ/SRZpHdwIyMDS4FOGX5kP4U/2g2mykyn/iPQTK4xTiQAyBu6UnnDnn7d5P8s7Atzh1C7H0ETNOypJg==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/darkreader"
+      }
+    },
+    "node_modules/@ungap/structured-clone": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+      "dev": true
+    },
+    "node_modules/@uppy/companion-client": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmmirror.com/@uppy/companion-client/-/companion-client-2.2.2.tgz",
+      "integrity": "sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==",
+      "dependencies": {
+        "@uppy/utils": "^4.1.2",
+        "namespace-emitter": "^2.0.1"
+      }
+    },
+    "node_modules/@uppy/core": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmmirror.com/@uppy/core/-/core-2.3.4.tgz",
+      "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.1.25",
+        "preact": "^10.5.13"
+      }
+    },
+    "node_modules/@uppy/store-default": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/@uppy/store-default/-/store-default-2.1.1.tgz",
+      "integrity": "sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ=="
+    },
+    "node_modules/@uppy/utils": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmmirror.com/@uppy/utils/-/utils-4.1.3.tgz",
+      "integrity": "sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==",
+      "dependencies": {
+        "lodash.throttle": "^4.1.1"
+      }
+    },
+    "node_modules/@uppy/xhr-upload": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/@uppy/xhr-upload/-/xhr-upload-2.1.3.tgz",
+      "integrity": "sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==",
+      "dependencies": {
+        "@uppy/companion-client": "^2.2.2",
+        "@uppy/utils": "^4.1.2",
+        "nanoid": "^3.1.25"
+      },
+      "peerDependencies": {
+        "@uppy/core": "^2.3.3"
+      }
+    },
+    "node_modules/@vant/auto-import-resolver": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/@vant/auto-import-resolver/-/auto-import-resolver-1.2.1.tgz",
+      "integrity": "sha512-czGWW4UolNITkF3qQSQlpHDHAsI3/GHVKbRMmEEpry7NWdnU4p5a5jBi0VApbaLa5g80Hy10XVs3IB+UozoSUw==",
+      "dev": true
+    },
+    "node_modules/@vant/popperjs": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
+      "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
+    },
+    "node_modules/@vant/use": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
+      "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/@vue-office/docx": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmmirror.com/@vue-office/docx/-/docx-1.6.2.tgz",
+      "integrity": "sha512-OHAoUHeY8nHjhWvwDhlPx+/rmRkxmqLpvPgtfCEOZ4H1c1LCdJ6eDbdV3152ww8dcdZ7fgGQu3fmSSaI7JwdpQ==",
+      "hasInstallScript": true,
+      "peerDependencies": {
+        "@vue/composition-api": "^1.7.1",
+        "vue": "^2.0.0 || >=3.0.0",
+        "vue-demi": "^0.14.6"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue-office/excel": {
+      "version": "1.7.11",
+      "resolved": "https://registry.npmmirror.com/@vue-office/excel/-/excel-1.7.11.tgz",
+      "integrity": "sha512-LF3R9IV573Sf4qTu6Ik5Ee8UMfkrsZQ6HEQE25/2m1c0CMcHX6KanIy6Cz0b0Q+FrLH3TjIsLTm6oPcqAbDGSA==",
+      "hasInstallScript": true,
+      "peerDependencies": {
+        "@vue/composition-api": "^1.7.1",
+        "vue": "^2.0.0 || >=3.0.0",
+        "vue-demi": "^0.14.6"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue-office/pdf": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmmirror.com/@vue-office/pdf/-/pdf-2.0.9.tgz",
+      "integrity": "sha512-sRjIiMV1CDDFv1Ls4U7zglkjkMr1Ntm16q8Krh0m1Lh7vAdVox1EcgEw4MXU6Mqsz7NB6nppxCPlSms6ue9eIQ==",
+      "hasInstallScript": true,
+      "peerDependencies": {
+        "@vue/composition-api": "^1.7.1",
+        "vue": "^2.0.0 || >=3.0.0",
+        "vue-demi": "^0.14.6"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/babel-helper-vue-jsx-merge-props": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz",
+      "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==",
+      "dev": true
+    },
+    "node_modules/@vue/babel-helper-vue-transform-on": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.5.tgz",
+      "integrity": "sha512-lOz4t39ZdmU4DJAa2hwPYmKc8EsuGa2U0L9KaZaOJUt0UwQNjNA3AZTq6uEivhOKhhG1Wvy96SvYBoFmCg3uuw==",
+      "dev": true
+    },
+    "node_modules/@vue/babel-plugin-jsx": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.5.tgz",
+      "integrity": "sha512-zTrNmOd4939H9KsRIGmmzn3q2zvv1mjxkYZHgqHZgDrXz5B1Q3WyGEjO2f+JrmKghvl1JIRcvo63LgM1kH5zFg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.24.7",
+        "@babel/helper-plugin-utils": "^7.24.8",
+        "@babel/plugin-syntax-jsx": "^7.24.7",
+        "@babel/template": "^7.25.0",
+        "@babel/traverse": "^7.25.6",
+        "@babel/types": "^7.25.6",
+        "@vue/babel-helper-vue-transform-on": "1.2.5",
+        "@vue/babel-plugin-resolve-type": "1.2.5",
+        "html-tags": "^3.3.1",
+        "svg-tags": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      },
+      "peerDependenciesMeta": {
+        "@babel/core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/babel-plugin-jsx/node_modules/@babel/types": {
+      "version": "7.26.0",
+      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-resolve-type": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.5.tgz",
+      "integrity": "sha512-U/ibkQrf5sx0XXRnUZD1mo5F7PkpKyTbfXM3a3rC4YnUz6crHEz9Jg09jzzL6QYlXNto/9CePdOg/c87O4Nlfg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.24.7",
+        "@babel/helper-module-imports": "^7.24.7",
+        "@babel/helper-plugin-utils": "^7.24.8",
+        "@babel/parser": "^7.25.6",
+        "@vue/compiler-sfc": "^3.5.3"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-transform-vue-jsx": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.4.0.tgz",
+      "integrity": "sha512-Fmastxw4MMx0vlgLS4XBX0XiBbUFzoMGeVXuMV08wyOfXdikAFqBTuYPR0tlk+XskL19EzHc39SgjrPGY23JnA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.0.0",
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
+        "html-tags": "^2.0.0",
+        "lodash.kebabcase": "^4.1.1",
+        "svg-tags": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-plugin-transform-vue-jsx/node_modules/html-tags": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-2.0.0.tgz",
+      "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@vue/babel-preset-app": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-preset-app/-/babel-preset-app-5.0.8.tgz",
+      "integrity": "sha512-yl+5qhpjd8e1G4cMXfORkkBlvtPCIgmRf3IYCWYDKIQ7m+PPa5iTm4feiNmCMD6yGqQWMhhK/7M3oWGL9boKwg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.12.16",
+        "@babel/helper-compilation-targets": "^7.12.16",
+        "@babel/helper-module-imports": "^7.12.13",
+        "@babel/plugin-proposal-class-properties": "^7.12.13",
+        "@babel/plugin-proposal-decorators": "^7.12.13",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+        "@babel/plugin-syntax-jsx": "^7.12.13",
+        "@babel/plugin-transform-runtime": "^7.12.15",
+        "@babel/preset-env": "^7.12.16",
+        "@babel/runtime": "^7.12.13",
+        "@vue/babel-plugin-jsx": "^1.0.3",
+        "@vue/babel-preset-jsx": "^1.1.2",
+        "babel-plugin-dynamic-import-node": "^2.3.3",
+        "core-js": "^3.8.3",
+        "core-js-compat": "^3.8.3",
+        "semver": "^7.3.4"
+      },
+      "peerDependencies": {
+        "@babel/core": "*",
+        "core-js": "^3",
+        "vue": "^2 || ^3.2.13"
+      },
+      "peerDependenciesMeta": {
+        "core-js": {
+          "optional": true
+        },
+        "vue": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/babel-preset-jsx": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-preset-jsx/-/babel-preset-jsx-1.4.0.tgz",
+      "integrity": "sha512-QmfRpssBOPZWL5xw7fOuHNifCQcNQC1PrOo/4fu6xlhlKJJKSA3HqX92Nvgyx8fqHZTUGMPHmFA+IDqwXlqkSA==",
+      "dev": true,
+      "dependencies": {
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
+        "@vue/babel-sugar-composition-api-inject-h": "^1.4.0",
+        "@vue/babel-sugar-composition-api-render-instance": "^1.4.0",
+        "@vue/babel-sugar-functional-vue": "^1.4.0",
+        "@vue/babel-sugar-inject-h": "^1.4.0",
+        "@vue/babel-sugar-v-model": "^1.4.0",
+        "@vue/babel-sugar-v-on": "^1.4.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0",
+        "vue": "*"
+      },
+      "peerDependenciesMeta": {
+        "vue": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/babel-sugar-composition-api-inject-h": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.4.0.tgz",
+      "integrity": "sha512-VQq6zEddJHctnG4w3TfmlVp5FzDavUSut/DwR0xVoe/mJKXyMcsIibL42wPntozITEoY90aBV0/1d2KjxHU52g==",
+      "dev": true,
+      "dependencies": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-sugar-composition-api-render-instance": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.4.0.tgz",
+      "integrity": "sha512-6ZDAzcxvy7VcnCjNdHJ59mwK02ZFuP5CnucloidqlZwVQv5CQLijc3lGpR7MD3TWFi78J7+a8J56YxbCtHgT9Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-sugar-functional-vue": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.4.0.tgz",
+      "integrity": "sha512-lTEB4WUFNzYt2In6JsoF9sAYVTo84wC4e+PoZWSgM6FUtqRJz7wMylaEhSRgG71YF+wfLD6cc9nqVeXN2rwBvw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-sugar-inject-h": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.4.0.tgz",
+      "integrity": "sha512-muwWrPKli77uO2fFM7eA3G1lAGnERuSz2NgAxuOLzrsTlQl8W4G+wwbM4nB6iewlKbwKRae3nL03UaF5ffAPMA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/plugin-syntax-jsx": "^7.2.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-sugar-v-model": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.4.0.tgz",
+      "integrity": "sha512-0t4HGgXb7WHYLBciZzN5s0Hzqan4Ue+p/3FdQdcaHAb7s5D9WZFGoSxEZHrR1TFVZlAPu1bejTKGeAzaaG3NCQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.4.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
+        "camelcase": "^5.0.0",
+        "html-tags": "^2.0.0",
+        "svg-tags": "^1.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/babel-sugar-v-model/node_modules/html-tags": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-2.0.0.tgz",
+      "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/@vue/babel-sugar-v-on": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.4.0.tgz",
+      "integrity": "sha512-m+zud4wKLzSKgQrWwhqRObWzmTuyzl6vOP7024lrpeJM4x2UhQtRDLgYjXAw9xBXjCwS0pP9kXjg91F9ZNo9JA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/plugin-syntax-jsx": "^7.2.0",
+        "@vue/babel-plugin-transform-vue-jsx": "^1.4.0",
+        "camelcase": "^5.0.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0-0"
+      }
+    },
+    "node_modules/@vue/cli-overlay": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-overlay/-/cli-overlay-5.0.8.tgz",
+      "integrity": "sha512-KmtievE/B4kcXp6SuM2gzsnSd8WebkQpg3XaB6GmFh1BJGRqa1UiW9up7L/Q67uOdTigHxr5Ar2lZms4RcDjwQ==",
+      "dev": true
+    },
+    "node_modules/@vue/cli-plugin-babel": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-babel/-/cli-plugin-babel-5.0.8.tgz",
+      "integrity": "sha512-a4qqkml3FAJ3auqB2kN2EMPocb/iu0ykeELwed+9B1c1nQ1HKgslKMHMPavYx3Cd/QAx2mBD4hwKBqZXEI/CsQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.12.16",
+        "@vue/babel-preset-app": "^5.0.8",
+        "@vue/cli-shared-utils": "^5.0.8",
+        "babel-loader": "^8.2.2",
+        "thread-loader": "^3.0.0",
+        "webpack": "^5.54.0"
+      },
+      "peerDependencies": {
+        "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
+      }
+    },
+    "node_modules/@vue/cli-plugin-eslint": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-eslint/-/cli-plugin-eslint-5.0.8.tgz",
+      "integrity": "sha512-d11+I5ONYaAPW1KyZj9GlrV/E6HZePq5L5eAF5GgoVdu6sxr6bDgEoxzhcS1Pk2eh8rn1MxG/FyyR+eCBj/CNg==",
+      "dev": true,
+      "dependencies": {
+        "@vue/cli-shared-utils": "^5.0.8",
+        "eslint-webpack-plugin": "^3.1.0",
+        "globby": "^11.0.2",
+        "webpack": "^5.54.0",
+        "yorkie": "^2.0.0"
+      },
+      "peerDependencies": {
+        "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0",
+        "eslint": ">=7.5.0"
+      }
+    },
+    "node_modules/@vue/cli-plugin-router": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-router/-/cli-plugin-router-5.0.8.tgz",
+      "integrity": "sha512-Gmv4dsGdAsWPqVijz3Ux2OS2HkMrWi1ENj2cYL75nUeL+Xj5HEstSqdtfZ0b1q9NCce+BFB6QnHfTBXc/fCvMg==",
+      "dev": true,
+      "dependencies": {
+        "@vue/cli-shared-utils": "^5.0.8"
+      },
+      "peerDependencies": {
+        "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
+      }
+    },
+    "node_modules/@vue/cli-plugin-typescript": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-typescript/-/cli-plugin-typescript-5.0.8.tgz",
+      "integrity": "sha512-JKJOwzJshBqsmp4yLBexwVMebOZ4VGJgbnYvmHVxasJOStF2RxwyW28ZF+zIvASGdat4sAUuo/3mAQyVhm7JHg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/core": "^7.12.16",
+        "@types/webpack-env": "^1.15.2",
+        "@vue/cli-shared-utils": "^5.0.8",
+        "babel-loader": "^8.2.2",
+        "fork-ts-checker-webpack-plugin": "^6.4.0",
+        "globby": "^11.0.2",
+        "thread-loader": "^3.0.0",
+        "ts-loader": "^9.2.5",
+        "webpack": "^5.54.0"
+      },
+      "peerDependencies": {
+        "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0",
+        "cache-loader": "^4.1.0",
+        "typescript": ">=2",
+        "vue": "^2 || ^3.2.13",
+        "vue-template-compiler": "^2.0.0"
+      },
+      "peerDependenciesMeta": {
+        "cache-loader": {
+          "optional": true
+        },
+        "vue-template-compiler": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/cli-plugin-vuex": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-plugin-vuex/-/cli-plugin-vuex-5.0.8.tgz",
+      "integrity": "sha512-HSYWPqrunRE5ZZs8kVwiY6oWcn95qf/OQabwLfprhdpFWAGtLStShjsGED2aDpSSeGAskQETrtR/5h7VqgIlBA==",
+      "dev": true,
+      "peerDependencies": {
+        "@vue/cli-service": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
+      }
+    },
+    "node_modules/@vue/cli-service": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-service/-/cli-service-5.0.8.tgz",
+      "integrity": "sha512-nV7tYQLe7YsTtzFrfOMIHc5N2hp5lHG2rpYr0aNja9rNljdgcPZLyQRb2YRivTHqTv7lI962UXFURcpStHgyFw==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-compilation-targets": "^7.12.16",
+        "@soda/friendly-errors-webpack-plugin": "^1.8.0",
+        "@soda/get-current-script": "^1.0.2",
+        "@types/minimist": "^1.2.0",
+        "@vue/cli-overlay": "^5.0.8",
+        "@vue/cli-plugin-router": "^5.0.8",
+        "@vue/cli-plugin-vuex": "^5.0.8",
+        "@vue/cli-shared-utils": "^5.0.8",
+        "@vue/component-compiler-utils": "^3.3.0",
+        "@vue/vue-loader-v15": "npm:vue-loader@^15.9.7",
+        "@vue/web-component-wrapper": "^1.3.0",
+        "acorn": "^8.0.5",
+        "acorn-walk": "^8.0.2",
+        "address": "^1.1.2",
+        "autoprefixer": "^10.2.4",
+        "browserslist": "^4.16.3",
+        "case-sensitive-paths-webpack-plugin": "^2.3.0",
+        "cli-highlight": "^2.1.10",
+        "clipboardy": "^2.3.0",
+        "cliui": "^7.0.4",
+        "copy-webpack-plugin": "^9.0.1",
+        "css-loader": "^6.5.0",
+        "css-minimizer-webpack-plugin": "^3.0.2",
+        "cssnano": "^5.0.0",
+        "debug": "^4.1.1",
+        "default-gateway": "^6.0.3",
+        "dotenv": "^10.0.0",
+        "dotenv-expand": "^5.1.0",
+        "fs-extra": "^9.1.0",
+        "globby": "^11.0.2",
+        "hash-sum": "^2.0.0",
+        "html-webpack-plugin": "^5.1.0",
+        "is-file-esm": "^1.0.0",
+        "launch-editor-middleware": "^2.2.1",
+        "lodash.defaultsdeep": "^4.6.1",
+        "lodash.mapvalues": "^4.6.0",
+        "mini-css-extract-plugin": "^2.5.3",
+        "minimist": "^1.2.5",
+        "module-alias": "^2.2.2",
+        "portfinder": "^1.0.26",
+        "postcss": "^8.2.6",
+        "postcss-loader": "^6.1.1",
+        "progress-webpack-plugin": "^1.0.12",
+        "ssri": "^8.0.1",
+        "terser-webpack-plugin": "^5.1.1",
+        "thread-loader": "^3.0.0",
+        "vue-loader": "^17.0.0",
+        "vue-style-loader": "^4.1.3",
+        "webpack": "^5.54.0",
+        "webpack-bundle-analyzer": "^4.4.0",
+        "webpack-chain": "^6.5.1",
+        "webpack-dev-server": "^4.7.3",
+        "webpack-merge": "^5.7.3",
+        "webpack-virtual-modules": "^0.4.2",
+        "whatwg-fetch": "^3.6.2"
+      },
+      "bin": {
+        "vue-cli-service": "bin/vue-cli-service.js"
+      },
+      "engines": {
+        "node": "^12.0.0 || >= 14.0.0"
+      },
+      "peerDependencies": {
+        "vue-template-compiler": "^2.0.0",
+        "webpack-sources": "*"
+      },
+      "peerDependenciesMeta": {
+        "cache-loader": {
+          "optional": true
+        },
+        "less-loader": {
+          "optional": true
+        },
+        "pug-plain-loader": {
+          "optional": true
+        },
+        "raw-loader": {
+          "optional": true
+        },
+        "sass-loader": {
+          "optional": true
+        },
+        "stylus-loader": {
+          "optional": true
+        },
+        "vue-template-compiler": {
+          "optional": true
+        },
+        "webpack-sources": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/cli-shared-utils": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/@vue/cli-shared-utils/-/cli-shared-utils-5.0.8.tgz",
+      "integrity": "sha512-uK2YB7bBVuQhjOJF+O52P9yFMXeJVj7ozqJkwYE9PlMHL1LMHjtCYm4cSdOebuPzyP+/9p0BimM/OqxsevIopQ==",
+      "dev": true,
+      "dependencies": {
+        "@achrinza/node-ipc": "^9.2.5",
+        "chalk": "^4.1.2",
+        "execa": "^1.0.0",
+        "joi": "^17.4.0",
+        "launch-editor": "^2.2.1",
+        "lru-cache": "^6.0.0",
+        "node-fetch": "^2.6.7",
+        "open": "^8.0.2",
+        "ora": "^5.3.0",
+        "read-pkg": "^5.1.1",
+        "semver": "^7.3.4",
+        "strip-ansi": "^6.0.0"
+      }
+    },
+    "node_modules/@vue/cli-shared-utils/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/@vue/cli-shared-utils/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/@vue/cli-shared-utils/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
+    "node_modules/@vue/compiler-core": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz",
+      "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==",
+      "dependencies": {
+        "@babel/parser": "^7.25.3",
+        "@vue/shared": "3.5.13",
+        "entities": "^4.5.0",
+        "estree-walker": "^2.0.2",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/@vue/compiler-dom": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz",
+      "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==",
+      "dependencies": {
+        "@vue/compiler-core": "3.5.13",
+        "@vue/shared": "3.5.13"
+      }
+    },
+    "node_modules/@vue/compiler-sfc": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz",
+      "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==",
+      "dependencies": {
+        "@babel/parser": "^7.25.3",
+        "@vue/compiler-core": "3.5.13",
+        "@vue/compiler-dom": "3.5.13",
+        "@vue/compiler-ssr": "3.5.13",
+        "@vue/shared": "3.5.13",
+        "estree-walker": "^2.0.2",
+        "magic-string": "^0.30.11",
+        "postcss": "^8.4.48",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/@vue/compiler-ssr": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz",
+      "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.5.13",
+        "@vue/shared": "3.5.13"
+      }
+    },
+    "node_modules/@vue/component-compiler-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz",
+      "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==",
+      "dev": true,
+      "dependencies": {
+        "consolidate": "^0.15.1",
+        "hash-sum": "^1.0.2",
+        "lru-cache": "^4.1.2",
+        "merge-source-map": "^1.1.0",
+        "postcss": "^7.0.36",
+        "postcss-selector-parser": "^6.0.2",
+        "source-map": "~0.6.1",
+        "vue-template-es2015-compiler": "^1.9.0"
+      },
+      "optionalDependencies": {
+        "prettier": "^1.18.2 || ^2.0.0"
+      }
+    },
+    "node_modules/@vue/component-compiler-utils/node_modules/hash-sum": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
+      "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+      "dev": true
+    },
+    "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-4.1.5.tgz",
+      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+      "dev": true,
+      "dependencies": {
+        "pseudomap": "^1.0.2",
+        "yallist": "^2.1.2"
+      }
+    },
+    "node_modules/@vue/component-compiler-utils/node_modules/picocolors": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-0.2.1.tgz",
+      "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==",
+      "dev": true
+    },
+    "node_modules/@vue/component-compiler-utils/node_modules/postcss": {
+      "version": "7.0.39",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-7.0.39.tgz",
+      "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
+      "dev": true,
+      "dependencies": {
+        "picocolors": "^0.2.1",
+        "source-map": "^0.6.1"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/postcss/"
+      }
+    },
+    "node_modules/@vue/component-compiler-utils/node_modules/yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+      "dev": true
+    },
+    "node_modules/@vue/devtools-api": {
+      "version": "6.6.4",
+      "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
+      "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="
+    },
+    "node_modules/@vue/reactivity": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz",
+      "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==",
+      "dependencies": {
+        "@vue/shared": "3.5.13"
+      }
+    },
+    "node_modules/@vue/runtime-core": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz",
+      "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==",
+      "dependencies": {
+        "@vue/reactivity": "3.5.13",
+        "@vue/shared": "3.5.13"
+      }
+    },
+    "node_modules/@vue/runtime-dom": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz",
+      "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==",
+      "dependencies": {
+        "@vue/reactivity": "3.5.13",
+        "@vue/runtime-core": "3.5.13",
+        "@vue/shared": "3.5.13",
+        "csstype": "^3.1.3"
+      }
+    },
+    "node_modules/@vue/server-renderer": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz",
+      "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==",
+      "dependencies": {
+        "@vue/compiler-ssr": "3.5.13",
+        "@vue/shared": "3.5.13"
+      },
+      "peerDependencies": {
+        "vue": "3.5.13"
+      }
+    },
+    "node_modules/@vue/shared": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz",
+      "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="
+    },
+    "node_modules/@vue/vue-loader-v15": {
+      "name": "vue-loader",
+      "version": "15.11.1",
+      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-15.11.1.tgz",
+      "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
+      "dev": true,
+      "dependencies": {
+        "@vue/component-compiler-utils": "^3.1.0",
+        "hash-sum": "^1.0.2",
+        "loader-utils": "^1.1.0",
+        "vue-hot-reload-api": "^2.3.0",
+        "vue-style-loader": "^4.1.0"
+      },
+      "peerDependencies": {
+        "css-loader": "*",
+        "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0"
+      },
+      "peerDependenciesMeta": {
+        "cache-loader": {
+          "optional": true
+        },
+        "prettier": {
+          "optional": true
+        },
+        "vue-template-compiler": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vue/vue-loader-v15/node_modules/hash-sum": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
+      "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+      "dev": true
+    },
+    "node_modules/@vue/web-component-wrapper": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz",
+      "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==",
+      "dev": true
+    },
+    "node_modules/@vueuse/core": {
+      "version": "8.7.3",
+      "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-8.7.3.tgz",
+      "integrity": "sha512-jpBnyG9b4wXgk0Dz3I71lfhD0o53t1tZR+NoAQ+17zJy7MP/VDfGIkq8GcqpDwmptLCmGiGVipkPbWmDGMic8Q==",
+      "dependencies": {
+        "@vueuse/metadata": "8.7.3",
+        "@vueuse/shared": "8.7.3",
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.1.0",
+        "vue": "^2.6.0 || ^3.2.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        },
+        "vue": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@vueuse/metadata": {
+      "version": "8.7.3",
+      "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-8.7.3.tgz",
+      "integrity": "sha512-spf9kgCsBEFbQb90I6SIqAWh1yP5T1JoJGj+/04+VTMIHXKzn3iecmHUalg8QEOCPNtnFQGNEw5OLg0L39eizg==",
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/@vueuse/shared": {
+      "version": "8.7.3",
+      "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-8.7.3.tgz",
+      "integrity": "sha512-PMc/h6cEakJ4+5VuNUGi7RnbA6CkLvtG2230x8w3zYJpW1P6Qphh9+dFFvHn7TX+RlaicF5ND0RX1NxWmAoW7w==",
+      "dependencies": {
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.1.0",
+        "vue": "^2.6.0 || ^3.2.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        },
+        "vue": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@wangeditor/basic-modules": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/basic-modules/-/basic-modules-1.1.7.tgz",
+      "integrity": "sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==",
+      "dependencies": {
+        "is-url": "^1.2.4"
+      },
+      "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"
+      }
+    },
+    "node_modules/@wangeditor/code-highlight": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/code-highlight/-/code-highlight-1.0.3.tgz",
+      "integrity": "sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==",
+      "dependencies": {
+        "prismjs": "^1.23.0"
+      },
+      "peerDependencies": {
+        "@wangeditor/core": "1.x",
+        "dom7": "^3.0.0",
+        "slate": "^0.72.0",
+        "snabbdom": "^3.1.0"
+      }
+    },
+    "node_modules/@wangeditor/core": {
+      "version": "1.1.19",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/core/-/core-1.1.19.tgz",
+      "integrity": "sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==",
+      "dependencies": {
+        "@types/event-emitter": "^0.3.3",
+        "event-emitter": "^0.3.5",
+        "html-void-elements": "^2.0.0",
+        "i18next": "^20.4.0",
+        "scroll-into-view-if-needed": "^2.2.28",
+        "slate-history": "^0.66.0"
+      },
+      "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"
+      }
+    },
+    "node_modules/@wangeditor/editor": {
+      "version": "5.1.23",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/editor/-/editor-5.1.23.tgz",
+      "integrity": "sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==",
+      "dependencies": {
+        "@uppy/core": "^2.1.1",
+        "@uppy/xhr-upload": "^2.0.3",
+        "@wangeditor/basic-modules": "^1.1.7",
+        "@wangeditor/code-highlight": "^1.0.3",
+        "@wangeditor/core": "^1.1.19",
+        "@wangeditor/list-module": "^1.0.5",
+        "@wangeditor/table-module": "^1.1.4",
+        "@wangeditor/upload-image-module": "^1.0.2",
+        "@wangeditor/video-module": "^1.1.4",
+        "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"
+      }
+    },
+    "node_modules/@wangeditor/editor-for-vue": {
+      "version": "5.1.12",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/editor-for-vue/-/editor-for-vue-5.1.12.tgz",
+      "integrity": "sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==",
+      "peerDependencies": {
+        "@wangeditor/editor": ">=5.1.0",
+        "vue": "^3.0.5"
+      }
+    },
+    "node_modules/@wangeditor/list-module": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/list-module/-/list-module-1.0.5.tgz",
+      "integrity": "sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==",
+      "peerDependencies": {
+        "@wangeditor/core": "1.x",
+        "dom7": "^3.0.0",
+        "slate": "^0.72.0",
+        "snabbdom": "^3.1.0"
+      }
+    },
+    "node_modules/@wangeditor/table-module": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/table-module/-/table-module-1.1.4.tgz",
+      "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"
+      }
+    },
+    "node_modules/@wangeditor/upload-image-module": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/upload-image-module/-/upload-image-module-1.0.2.tgz",
+      "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"
+      }
+    },
+    "node_modules/@wangeditor/video-module": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/@wangeditor/video-module/-/video-module-1.1.4.tgz",
+      "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"
+      }
+    },
+    "node_modules/@webassemblyjs/ast": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+      "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/helper-numbers": "1.13.2",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
+      }
+    },
+    "node_modules/@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+      "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
+      "dev": true
+    },
+    "node_modules/@webassemblyjs/helper-api-error": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+      "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
+      "dev": true
+    },
+    "node_modules/@webassemblyjs/helper-buffer": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+      "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
+      "dev": true
+    },
+    "node_modules/@webassemblyjs/helper-numbers": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+      "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+        "@webassemblyjs/helper-api-error": "1.13.2",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+      "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
+      "dev": true
+    },
+    "node_modules/@webassemblyjs/helper-wasm-section": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+      "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/wasm-gen": "1.14.1"
+      }
+    },
+    "node_modules/@webassemblyjs/ieee754": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+      "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
+      "dev": true,
+      "dependencies": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "node_modules/@webassemblyjs/leb128": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+      "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
+      "dev": true,
+      "dependencies": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@webassemblyjs/utf8": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+      "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
+      "dev": true
+    },
+    "node_modules/@webassemblyjs/wasm-edit": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+      "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/helper-wasm-section": "1.14.1",
+        "@webassemblyjs/wasm-gen": "1.14.1",
+        "@webassemblyjs/wasm-opt": "1.14.1",
+        "@webassemblyjs/wasm-parser": "1.14.1",
+        "@webassemblyjs/wast-printer": "1.14.1"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-gen": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+      "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/ieee754": "1.13.2",
+        "@webassemblyjs/leb128": "1.13.2",
+        "@webassemblyjs/utf8": "1.13.2"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-opt": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+      "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-buffer": "1.14.1",
+        "@webassemblyjs/wasm-gen": "1.14.1",
+        "@webassemblyjs/wasm-parser": "1.14.1"
+      }
+    },
+    "node_modules/@webassemblyjs/wasm-parser": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+      "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@webassemblyjs/helper-api-error": "1.13.2",
+        "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+        "@webassemblyjs/ieee754": "1.13.2",
+        "@webassemblyjs/leb128": "1.13.2",
+        "@webassemblyjs/utf8": "1.13.2"
+      }
+    },
+    "node_modules/@webassemblyjs/wast-printer": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+      "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
+      "dev": true,
+      "dependencies": {
+        "@webassemblyjs/ast": "1.14.1",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "node_modules/@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "node_modules/@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmmirror.com/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
+    },
+    "node_modules/abort-controller": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/abort-controller/-/abort-controller-3.0.0.tgz",
+      "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+      "dev": true,
+      "dependencies": {
+        "event-target-shim": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=6.5"
+      }
+    },
+    "node_modules/accepts": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz",
+      "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+      "dev": true,
+      "dependencies": {
+        "mime-types": "~2.1.34",
+        "negotiator": "0.6.3"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/accepts/node_modules/negotiator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz",
+      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/ace-builds": {
+      "version": "1.36.5",
+      "resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.36.5.tgz",
+      "integrity": "sha512-mZ5KVanRT6nLRDLqtG/1YQQLX/gZVC/v526cm1Ru/MTSlrbweSmqv2ZT0d2GaHpJq035MwCMIrj+LgDAUnDXrg=="
+    },
+    "node_modules/acorn": {
+      "version": "8.14.0",
+      "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.0.tgz",
+      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/acorn-jsx": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmmirror.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+      "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+      "dev": true,
+      "peerDependencies": {
+        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
+    },
+    "node_modules/acorn-walk": {
+      "version": "8.3.4",
+      "resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.4.tgz",
+      "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.11.0"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/address": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/address/-/address-1.2.2.tgz",
+      "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/ajv": {
+      "version": "6.12.6",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
+      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/ajv-formats": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
+      "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
+      "dev": true,
+      "dependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependencies": {
+        "ajv": "^8.0.0"
+      },
+      "peerDependenciesMeta": {
+        "ajv": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/ajv-formats/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/ajv-formats/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/ajv-keywords": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+      "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+      "dev": true,
+      "peerDependencies": {
+        "ajv": "^6.9.1"
+      }
+    },
+    "node_modules/ansi-escapes": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/ansi-html-community": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmmirror.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
+      "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==",
+      "dev": true,
+      "engines": [
+        "node >= 0.8.0"
+      ],
+      "bin": {
+        "ansi-html": "bin/ansi-html"
+      }
+    },
+    "node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
+      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz",
+      "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+      "dev": true
+    },
+    "node_modules/anymatch": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
+      "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+      "dev": true,
+      "dependencies": {
+        "normalize-path": "^3.0.0",
+        "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/arch": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/arch/-/arch-2.2.0.tgz",
+      "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
+    },
+    "node_modules/array-buffer-byte-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+      "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.5",
+        "is-array-buffer": "^3.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
+      "dev": true
+    },
+    "node_modules/array-includes": {
+      "version": "3.1.8",
+      "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.8.tgz",
+      "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.2",
+        "es-object-atoms": "^1.0.0",
+        "get-intrinsic": "^1.2.4",
+        "is-string": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/array.prototype.findlastindex": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmmirror.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
+      "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.2",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0",
+        "es-shim-unscopables": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array.prototype.flat": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+      "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/array.prototype.flatmap": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+      "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "es-shim-unscopables": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/arraybuffer.prototype.slice": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+      "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+      "dev": true,
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.1",
+        "call-bind": "^1.0.5",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.22.3",
+        "es-errors": "^1.2.1",
+        "get-intrinsic": "^1.2.3",
+        "is-array-buffer": "^3.0.4",
+        "is-shared-array-buffer": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmmirror.com/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/asn1.js/node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "dev": true
+    },
+    "node_modules/assert": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/assert/-/assert-2.1.0.tgz",
+      "integrity": "sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "is-nan": "^1.3.2",
+        "object-is": "^1.1.5",
+        "object.assign": "^4.1.4",
+        "util": "^0.12.5"
+      }
+    },
+    "node_modules/async": {
+      "version": "3.2.6",
+      "resolved": "https://registry.npmmirror.com/async/-/async-3.2.6.tgz",
+      "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="
+    },
+    "node_modules/async-validator": {
+      "version": "4.2.5",
+      "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
+      "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+    },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/at-least-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
+      "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/autoprefixer": {
+      "version": "10.4.20",
+      "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.20.tgz",
+      "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "browserslist": "^4.23.3",
+        "caniuse-lite": "^1.0.30001646",
+        "fraction.js": "^4.3.7",
+        "normalize-range": "^0.1.2",
+        "picocolors": "^1.0.1",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "bin": {
+        "autoprefixer": "bin/autoprefixer"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/available-typed-arrays": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+      "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+      "dev": true,
+      "dependencies": {
+        "possible-typed-array-names": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/axios": {
+      "version": "1.7.8",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.8.tgz",
+      "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/babel-loader": {
+      "version": "8.4.1",
+      "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.4.1.tgz",
+      "integrity": "sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==",
+      "dev": true,
+      "dependencies": {
+        "find-cache-dir": "^3.3.1",
+        "loader-utils": "^2.0.4",
+        "make-dir": "^3.1.0",
+        "schema-utils": "^2.6.5"
+      },
+      "engines": {
+        "node": ">= 8.9"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.0.0",
+        "webpack": ">=2"
+      }
+    },
+    "node_modules/babel-loader/node_modules/loader-utils": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+      "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+      "dev": true,
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      }
+    },
+    "node_modules/babel-plugin-dynamic-import-node": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+      "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+      "dev": true,
+      "dependencies": {
+        "object.assign": "^4.1.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs2": {
+      "version": "0.4.12",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz",
+      "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==",
+      "dev": true,
+      "dependencies": {
+        "@babel/compat-data": "^7.22.6",
+        "@babel/helper-define-polyfill-provider": "^0.6.3",
+        "semver": "^6.3.1"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-corejs3": {
+      "version": "0.10.6",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz",
+      "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-define-polyfill-provider": "^0.6.2",
+        "core-js-compat": "^3.38.0"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/babel-plugin-polyfill-regenerator": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz",
+      "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/helper-define-polyfill-provider": "^0.6.3"
+      },
+      "peerDependencies": {
+        "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
+      }
+    },
+    "node_modules/balanced-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+    },
+    "node_modules/base64-js": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+      "dev": true
+    },
+    "node_modules/big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/bignumber.js": {
+      "version": "9.1.2",
+      "resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.1.2.tgz",
+      "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/binary-extensions": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz",
+      "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/bl": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
+      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+      "dev": true,
+      "dependencies": {
+        "buffer": "^5.5.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.4.0"
+      }
+    },
+    "node_modules/bl/node_modules/buffer": {
+      "version": "5.7.1",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
+      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.1.13"
+      }
+    },
+    "node_modules/bl/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/bluebird": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmmirror.com/bluebird/-/bluebird-3.7.2.tgz",
+      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+      "dev": true
+    },
+    "node_modules/bn.js": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-5.2.1.tgz",
+      "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==",
+      "dev": true
+    },
+    "node_modules/body-parser": {
+      "version": "1.20.3",
+      "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.3.tgz",
+      "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.2",
+        "content-type": "~1.0.5",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "on-finished": "2.4.1",
+        "qs": "6.13.0",
+        "raw-body": "2.5.2",
+        "type-is": "~1.6.18",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/body-parser/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/body-parser/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/body-parser/node_modules/qs": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz",
+      "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+      "dev": true,
+      "dependencies": {
+        "side-channel": "^1.0.6"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/bonjour-service": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/bonjour-service/-/bonjour-service-1.3.0.tgz",
+      "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "multicast-dns": "^7.2.5"
+      }
+    },
+    "node_modules/boolbase": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/boolbase/-/boolbase-1.0.0.tgz",
+      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+      "dev": true
+    },
+    "node_modules/bpmn-js": {
+      "version": "7.5.0",
+      "resolved": "https://registry.npmmirror.com/bpmn-js/-/bpmn-js-7.5.0.tgz",
+      "integrity": "sha512-0ANaE6Bikg1GmkcvO7RK0MQPX+EKYKBc+q7OWk39/16NcCdNZ/4UiRcCr9n0u1VUCIDsSU/jJ79TIZFnV5CNjw==",
+      "dev": true,
+      "dependencies": {
+        "bpmn-moddle": "^7.0.4",
+        "css.escape": "^1.5.1",
+        "diagram-js": "^6.8.2",
+        "diagram-js-direct-editing": "^1.6.1",
+        "ids": "^1.0.0",
+        "inherits": "^2.0.4",
+        "min-dash": "^3.5.2",
+        "min-dom": "^3.1.3",
+        "object-refs": "^0.3.0",
+        "tiny-svg": "^2.2.2"
+      }
+    },
+    "node_modules/bpmn-js-properties-panel": {
+      "version": "0.37.6",
+      "resolved": "https://registry.npmmirror.com/bpmn-js-properties-panel/-/bpmn-js-properties-panel-0.37.6.tgz",
+      "integrity": "sha512-1rP9r6ItL1gKqXezXnpr9eVsQtdufH6TNqxUs11Q68CtxeBAs0l1wEHw2f01i9ceHHxItmrZUTndqnASi89EYA==",
+      "dev": true,
+      "dependencies": {
+        "@bpmn-io/extract-process-variables": "^0.3.0",
+        "ids": "^1.0.0",
+        "inherits": "^2.0.1",
+        "lodash": "^4.17.20",
+        "min-dom": "^3.1.3",
+        "scroll-tabs": "^1.0.1",
+        "selection-update": "^0.1.2"
+      },
+      "peerDependencies": {
+        "bpmn-js": "^3.x || ^4.x || ^5.x || ^6.x || ^7.x"
+      }
+    },
+    "node_modules/bpmn-js-token-simulation": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmmirror.com/bpmn-js-token-simulation/-/bpmn-js-token-simulation-0.10.0.tgz",
+      "integrity": "sha512-QuZQ/KVXKt9Vl+XENyOBoTW2Aw+uKjuBlKdCJL6El7AyM7DkJ5bZkSYURshId1SkBDdYg2mJ1flSmsrhGuSfwg==",
+      "dependencies": {
+        "min-dash": "^3.3.0",
+        "min-dom": "^0.2.0",
+        "svg.js": "^2.6.3"
+      }
+    },
+    "node_modules/bpmn-js-token-simulation/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg=="
+    },
+    "node_modules/bpmn-js-token-simulation/node_modules/min-dom": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/min-dom/-/min-dom-0.2.0.tgz",
+      "integrity": "sha512-VmxugbnAcVZGqvepjhOA4d4apmrpX8mMaRS+/jo0dI5Yorzrr4Ru9zc9KVALlY/+XakVCb8iQ+PYXljihQcsNw==",
+      "dependencies": {
+        "component-classes": "^1.2.3",
+        "component-closest": "^0.1.4",
+        "component-delegate": "^0.2.3",
+        "component-event": "^0.1.4",
+        "component-matches-selector": "^0.1.5",
+        "component-query": "^0.0.3",
+        "domify": "^1.3.1"
+      }
+    },
+    "node_modules/bpmn-js/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/bpmn-moddle": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmmirror.com/bpmn-moddle/-/bpmn-moddle-7.1.3.tgz",
+      "integrity": "sha512-ZcBfw0NSOdYTSXFKEn7MOXHItz7VfLZTrFYKO8cK6V8ZzGjCcdiLIOiw7Lctw1PJsihhLiZQS8Htj2xKf+NwCg==",
+      "dev": true,
+      "dependencies": {
+        "min-dash": "^3.5.2",
+        "moddle": "^5.0.2",
+        "moddle-xml": "^9.0.6"
+      }
+    },
+    "node_modules/bpmn-moddle/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/braces": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+      "dev": true,
+      "dependencies": {
+        "fill-range": "^7.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==",
+      "dev": true
+    },
+    "node_modules/browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "dependencies": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "node_modules/browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "dependencies": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "node_modules/browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/browserify-rsa": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz",
+      "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^5.2.1",
+        "randombytes": "^2.1.0",
+        "safe-buffer": "^5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/browserify-sign": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/browserify-sign/-/browserify-sign-4.2.3.tgz",
+      "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^5.2.1",
+        "browserify-rsa": "^4.1.0",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.5",
+        "hash-base": "~3.0",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.7",
+        "readable-stream": "^2.3.8",
+        "safe-buffer": "^5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.12"
+      }
+    },
+    "node_modules/browserify-sign/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+      "dev": true
+    },
+    "node_modules/browserify-sign/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true
+    },
+    "node_modules/browserify-sign/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true
+    },
+    "node_modules/browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "dependencies": {
+        "pako": "~1.0.5"
+      }
+    },
+    "node_modules/browserslist": {
+      "version": "4.24.2",
+      "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.2.tgz",
+      "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "caniuse-lite": "^1.0.30001669",
+        "electron-to-chromium": "^1.5.41",
+        "node-releases": "^2.0.18",
+        "update-browserslist-db": "^1.1.1"
+      },
+      "bin": {
+        "browserslist": "cli.js"
+      },
+      "engines": {
+        "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+      }
+    },
+    "node_modules/buffer": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/buffer/-/buffer-6.0.3.tgz",
+      "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "base64-js": "^1.3.1",
+        "ieee754": "^1.2.1"
+      }
+    },
+    "node_modules/buffer-from": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+    },
+    "node_modules/buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
+      "dev": true
+    },
+    "node_modules/builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==",
+      "dev": true
+    },
+    "node_modules/bytes": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz",
+      "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/call-bind": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.7.tgz",
+      "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+      "dev": true,
+      "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.4",
+        "set-function-length": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/callsites": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/camel-case": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/camel-case/-/camel-case-4.1.2.tgz",
+      "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
+      "dev": true,
+      "dependencies": {
+        "pascal-case": "^3.1.2",
+        "tslib": "^2.0.3"
+      }
+    },
+    "node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/caniuse-api": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/caniuse-api/-/caniuse-api-3.0.0.tgz",
+      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.0.0",
+        "caniuse-lite": "^1.0.0",
+        "lodash.memoize": "^4.1.2",
+        "lodash.uniq": "^4.5.0"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001686",
+      "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz",
+      "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ]
+    },
+    "node_modules/case-sensitive-paths-webpack-plugin": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmmirror.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
+      "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chalk": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-3.0.0.tgz",
+      "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/chokidar": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+      "dev": true,
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chokidar/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/chrome-trace-event": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
+      "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0"
+      }
+    },
+    "node_modules/ci-info": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-1.6.0.tgz",
+      "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
+      "dev": true
+    },
+    "node_modules/cipher-base": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/cipher-base/-/cipher-base-1.0.6.tgz",
+      "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "safe-buffer": "^5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/clean-css": {
+      "version": "5.3.3",
+      "resolved": "https://registry.npmmirror.com/clean-css/-/clean-css-5.3.3.tgz",
+      "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==",
+      "dev": true,
+      "dependencies": {
+        "source-map": "~0.6.0"
+      },
+      "engines": {
+        "node": ">= 10.0"
+      }
+    },
+    "node_modules/cli-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz",
+      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+      "dev": true,
+      "dependencies": {
+        "restore-cursor": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cli-highlight": {
+      "version": "2.1.11",
+      "resolved": "https://registry.npmmirror.com/cli-highlight/-/cli-highlight-2.1.11.tgz",
+      "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^4.0.0",
+        "highlight.js": "^10.7.1",
+        "mz": "^2.4.0",
+        "parse5": "^5.1.1",
+        "parse5-htmlparser2-tree-adapter": "^6.0.0",
+        "yargs": "^16.0.0"
+      },
+      "bin": {
+        "highlight": "bin/highlight"
+      },
+      "engines": {
+        "node": ">=8.0.0",
+        "npm": ">=5.0.0"
+      }
+    },
+    "node_modules/cli-highlight/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/cli-highlight/node_modules/highlight.js": {
+      "version": "10.7.3",
+      "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-10.7.3.tgz",
+      "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/cli-spinners": {
+      "version": "2.9.2",
+      "resolved": "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.9.2.tgz",
+      "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/clipboard": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
+      "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==",
+      "dependencies": {
+        "good-listener": "^1.2.2",
+        "select": "^1.1.2",
+        "tiny-emitter": "^2.0.0"
+      }
+    },
+    "node_modules/clipboardy": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/clipboardy/-/clipboardy-2.3.0.tgz",
+      "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
+      "dev": true,
+      "dependencies": {
+        "arch": "^2.1.1",
+        "execa": "^1.0.0",
+        "is-wsl": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "node_modules/clone": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz",
+      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/clone-deep": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/clone-deep/-/clone-deep-4.0.1.tgz",
+      "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+      "dev": true,
+      "dependencies": {
+        "is-plain-object": "^2.0.4",
+        "kind-of": "^6.0.2",
+        "shallow-clone": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/clone-deep/node_modules/is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "dependencies": {
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+    },
+    "node_modules/colord": {
+      "version": "2.9.3",
+      "resolved": "https://registry.npmmirror.com/colord/-/colord-2.9.3.tgz",
+      "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
+      "dev": true
+    },
+    "node_modules/colorette": {
+      "version": "2.0.20",
+      "resolved": "https://registry.npmmirror.com/colorette/-/colorette-2.0.20.tgz",
+      "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+      "dev": true
+    },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/commander": {
+      "version": "8.3.0",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
+      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+      "dev": true,
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
+      "dev": true
+    },
+    "node_modules/component-classes": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmmirror.com/component-classes/-/component-classes-1.2.6.tgz",
+      "integrity": "sha512-hPFGULxdwugu1QWW3SvVOCUHLzO34+a2J6Wqy0c5ASQkfi9/8nZcBB0ZohaEbXOQlCflMAEMmEWk7u7BVs4koA==",
+      "dependencies": {
+        "component-indexof": "0.0.3"
+      }
+    },
+    "node_modules/component-closest": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/component-closest/-/component-closest-0.1.4.tgz",
+      "integrity": "sha512-NF9hMj6JKGM5sb6wP/dg7GdJOttaIH9PcTsUNdWcrvu7Kw/5R5swQAFpgaYEHlARrNMyn4Wf7O1PlRej+pt76Q==",
+      "dependencies": {
+        "component-matches-selector": "~0.1.5"
+      }
+    },
+    "node_modules/component-delegate": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmmirror.com/component-delegate/-/component-delegate-0.2.4.tgz",
+      "integrity": "sha512-OlpcB/6Fi+kXQPh/TfXnSvvmrU04ghz7vcJh/jgLF0Ni+I+E3WGlKJQbBGDa5X+kVUG8WxOgjP+8iWbz902fPg==",
+      "dependencies": {
+        "component-closest": "*",
+        "component-event": "*"
+      }
+    },
+    "node_modules/component-event": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/component-event/-/component-event-0.1.4.tgz",
+      "integrity": "sha512-GMwOG8MnUHP1l8DZx1ztFO0SJTFnIzZnBDkXAj8RM2ntV2A6ALlDxgbMY1Fvxlg6WPQ+5IM/a6vg4PEYbjg/Rw=="
+    },
+    "node_modules/component-indexof": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmmirror.com/component-indexof/-/component-indexof-0.0.3.tgz",
+      "integrity": "sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw=="
+    },
+    "node_modules/component-matches-selector": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmmirror.com/component-matches-selector/-/component-matches-selector-0.1.7.tgz",
+      "integrity": "sha512-Yb2+pVBvrqkQVpPaDBF0DYXRreBveXJNrpJs9FnFu8PF6/5IIcz5oDZqiH9nB5hbD2/TmFVN5ZCxBzqu7yFFYQ==",
+      "dependencies": {
+        "component-query": "*",
+        "global-object": "^1.0.0"
+      }
+    },
+    "node_modules/component-query": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmmirror.com/component-query/-/component-query-0.0.3.tgz",
+      "integrity": "sha512-VgebQseT1hz1Ps7vVp2uaSg+N/gsI5ts3AZUSnN6GMA2M82JH7o+qYifWhmVE/e8w/H48SJuA3nA9uX8zRe95Q=="
+    },
+    "node_modules/compressible": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmmirror.com/compressible/-/compressible-2.0.18.tgz",
+      "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+      "dev": true,
+      "dependencies": {
+        "mime-db": ">= 1.43.0 < 2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/compression": {
+      "version": "1.7.5",
+      "resolved": "https://registry.npmmirror.com/compression/-/compression-1.7.5.tgz",
+      "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.2",
+        "compressible": "~2.0.18",
+        "debug": "2.6.9",
+        "negotiator": "~0.6.4",
+        "on-headers": "~1.0.2",
+        "safe-buffer": "5.2.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/compression/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/compression/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/compute-scroll-into-view": {
+      "version": "1.0.20",
+      "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
+      "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
+    },
+    "node_modules/concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+    },
+    "node_modules/confbox": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz",
+      "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+      "dev": true
+    },
+    "node_modules/connect-history-api-fallback": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
+      "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/console-browserify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/console-browserify/-/console-browserify-1.2.0.tgz",
+      "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+      "dev": true
+    },
+    "node_modules/consolidate": {
+      "version": "0.15.1",
+      "resolved": "https://registry.npmmirror.com/consolidate/-/consolidate-0.15.1.tgz",
+      "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==",
+      "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog",
+      "dev": true,
+      "dependencies": {
+        "bluebird": "^3.1.1"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==",
+      "dev": true
+    },
+    "node_modules/content-disposition": {
+      "version": "0.5.4",
+      "resolved": "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz",
+      "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/content-type": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz",
+      "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/convert-source-map": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true
+    },
+    "node_modules/cookie": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.7.1.tgz",
+      "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
+      "dev": true
+    },
+    "node_modules/copy-webpack-plugin": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmmirror.com/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz",
+      "integrity": "sha512-rxnR7PaGigJzhqETHGmAcxKnLZSR5u1Y3/bcIv/1FnqXedcL/E2ewK7ZCNrArJKCiSv8yVXhTqetJh8inDvfsA==",
+      "dev": true,
+      "dependencies": {
+        "fast-glob": "^3.2.7",
+        "glob-parent": "^6.0.1",
+        "globby": "^11.0.3",
+        "normalize-path": "^3.0.0",
+        "schema-utils": "^3.1.1",
+        "serialize-javascript": "^6.0.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.1.0"
+      }
+    },
+    "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/core-js": {
+      "version": "3.39.0",
+      "resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.39.0.tgz",
+      "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==",
+      "hasInstallScript": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/core-js-compat": {
+      "version": "3.39.0",
+      "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.39.0.tgz",
+      "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.24.2"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/core-js"
+      }
+    },
+    "node_modules/core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+      "dev": true
+    },
+    "node_modules/cosmiconfig": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+      "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+      "dev": true,
+      "dependencies": {
+        "@types/parse-json": "^4.0.0",
+        "import-fresh": "^3.1.0",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0",
+        "yaml": "^1.7.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/create-ecdh": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmmirror.com/create-ecdh/-/create-ecdh-4.0.4.tgz",
+      "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.5.3"
+      }
+    },
+    "node_modules/create-ecdh/node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "dev": true
+    },
+    "node_modules/create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "node_modules/create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmmirror.com/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "dependencies": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "node_modules/cropperjs": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmmirror.com/cropperjs/-/cropperjs-1.6.2.tgz",
+      "integrity": "sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA=="
+    },
+    "node_modules/cross-spawn": {
+      "version": "7.0.6",
+      "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.1.0",
+        "shebang-command": "^2.0.0",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/crypto-browserify": {
+      "version": "3.12.1",
+      "resolved": "https://registry.npmmirror.com/crypto-browserify/-/crypto-browserify-3.12.1.tgz",
+      "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==",
+      "dev": true,
+      "dependencies": {
+        "browserify-cipher": "^1.0.1",
+        "browserify-sign": "^4.2.3",
+        "create-ecdh": "^4.0.4",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "diffie-hellman": "^5.0.3",
+        "hash-base": "~3.0.4",
+        "inherits": "^2.0.4",
+        "pbkdf2": "^3.1.2",
+        "public-encrypt": "^4.0.3",
+        "randombytes": "^2.1.0",
+        "randomfill": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/crypto-js": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
+      "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
+    },
+    "node_modules/css-blank-pseudo": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz",
+      "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.9"
+      },
+      "bin": {
+        "css-blank-pseudo": "dist/cli.cjs"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/css-declaration-sorter": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
+      "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.0.9"
+      }
+    },
+    "node_modules/css-has-pseudo": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz",
+      "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.9"
+      },
+      "bin": {
+        "css-has-pseudo": "dist/cli.cjs"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/css-loader": {
+      "version": "6.11.0",
+      "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-6.11.0.tgz",
+      "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==",
+      "dev": true,
+      "dependencies": {
+        "icss-utils": "^5.1.0",
+        "postcss": "^8.4.33",
+        "postcss-modules-extract-imports": "^3.1.0",
+        "postcss-modules-local-by-default": "^4.0.5",
+        "postcss-modules-scope": "^3.2.0",
+        "postcss-modules-values": "^4.0.0",
+        "postcss-value-parser": "^4.2.0",
+        "semver": "^7.5.4"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "@rspack/core": "0.x || 1.x",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@rspack/core": {
+          "optional": true
+        },
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/css-minimizer-webpack-plugin": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmmirror.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz",
+      "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==",
+      "dev": true,
+      "dependencies": {
+        "cssnano": "^5.0.6",
+        "jest-worker": "^27.0.2",
+        "postcss": "^8.3.5",
+        "schema-utils": "^4.0.0",
+        "serialize-javascript": "^6.0.0",
+        "source-map": "^0.6.1"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@parcel/css": {
+          "optional": true
+        },
+        "clean-css": {
+          "optional": true
+        },
+        "csso": {
+          "optional": true
+        },
+        "esbuild": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz",
+      "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/css-prefers-color-scheme": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz",
+      "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==",
+      "dev": true,
+      "bin": {
+        "css-prefers-color-scheme": "dist/cli.cjs"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/css-select": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/css-select/-/css-select-4.3.0.tgz",
+      "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+      "dev": true,
+      "dependencies": {
+        "boolbase": "^1.0.0",
+        "css-what": "^6.0.1",
+        "domhandler": "^4.3.1",
+        "domutils": "^2.8.0",
+        "nth-check": "^2.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/css-select/node_modules/dom-serializer": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz",
+      "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.2.0",
+        "entities": "^2.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/css-select/node_modules/domhandler": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-4.3.1.tgz",
+      "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.2.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/css-select/node_modules/domutils": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz",
+      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+      "dev": true,
+      "dependencies": {
+        "dom-serializer": "^1.0.1",
+        "domelementtype": "^2.2.0",
+        "domhandler": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/css-select/node_modules/entities": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-2.2.0.tgz",
+      "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/css-tree": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/css-tree/-/css-tree-1.1.3.tgz",
+      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+      "dev": true,
+      "dependencies": {
+        "mdn-data": "2.0.14",
+        "source-map": "^0.6.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/css-what": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/css-what/-/css-what-6.1.0.tgz",
+      "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/fb55"
+      }
+    },
+    "node_modules/css.escape": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmmirror.com/css.escape/-/css.escape-1.5.1.tgz",
+      "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="
+    },
+    "node_modules/cssdb": {
+      "version": "7.11.2",
+      "resolved": "https://registry.npmmirror.com/cssdb/-/cssdb-7.11.2.tgz",
+      "integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/csstools"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/csstools"
+        }
+      ]
+    },
+    "node_modules/cssesc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz",
+      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+      "dev": true,
+      "bin": {
+        "cssesc": "bin/cssesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/cssnano": {
+      "version": "5.1.15",
+      "resolved": "https://registry.npmmirror.com/cssnano/-/cssnano-5.1.15.tgz",
+      "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==",
+      "dev": true,
+      "dependencies": {
+        "cssnano-preset-default": "^5.2.14",
+        "lilconfig": "^2.0.3",
+        "yaml": "^1.10.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/cssnano"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/cssnano-preset-default": {
+      "version": "5.2.14",
+      "resolved": "https://registry.npmmirror.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz",
+      "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==",
+      "dev": true,
+      "dependencies": {
+        "css-declaration-sorter": "^6.3.1",
+        "cssnano-utils": "^3.1.0",
+        "postcss-calc": "^8.2.3",
+        "postcss-colormin": "^5.3.1",
+        "postcss-convert-values": "^5.1.3",
+        "postcss-discard-comments": "^5.1.2",
+        "postcss-discard-duplicates": "^5.1.0",
+        "postcss-discard-empty": "^5.1.1",
+        "postcss-discard-overridden": "^5.1.0",
+        "postcss-merge-longhand": "^5.1.7",
+        "postcss-merge-rules": "^5.1.4",
+        "postcss-minify-font-values": "^5.1.0",
+        "postcss-minify-gradients": "^5.1.1",
+        "postcss-minify-params": "^5.1.4",
+        "postcss-minify-selectors": "^5.2.1",
+        "postcss-normalize-charset": "^5.1.0",
+        "postcss-normalize-display-values": "^5.1.0",
+        "postcss-normalize-positions": "^5.1.1",
+        "postcss-normalize-repeat-style": "^5.1.1",
+        "postcss-normalize-string": "^5.1.0",
+        "postcss-normalize-timing-functions": "^5.1.0",
+        "postcss-normalize-unicode": "^5.1.1",
+        "postcss-normalize-url": "^5.1.0",
+        "postcss-normalize-whitespace": "^5.1.1",
+        "postcss-ordered-values": "^5.1.3",
+        "postcss-reduce-initial": "^5.1.2",
+        "postcss-reduce-transforms": "^5.1.0",
+        "postcss-svgo": "^5.1.0",
+        "postcss-unique-selectors": "^5.1.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/cssnano-utils": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
+      "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/csso": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/csso/-/csso-4.2.0.tgz",
+      "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+      "dev": true,
+      "dependencies": {
+        "css-tree": "^1.1.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/csstype": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
+      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+    },
+    "node_modules/d": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/d/-/d-1.0.2.tgz",
+      "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
+      "dependencies": {
+        "es5-ext": "^0.10.64",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/data-view-buffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+      "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.6",
+        "es-errors": "^1.3.0",
+        "is-data-view": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/data-view-byte-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+      "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "es-errors": "^1.3.0",
+        "is-data-view": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/data-view-byte-offset": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+      "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.6",
+        "es-errors": "^1.3.0",
+        "is-data-view": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/dayjs": {
+      "version": "1.11.13",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
+      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
+    },
+    "node_modules/debounce": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/debounce/-/debounce-1.2.1.tgz",
+      "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==",
+      "dev": true
+    },
+    "node_modules/debug": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.7.tgz",
+      "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.3"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/deep-is": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/deep-is/-/deep-is-0.1.4.tgz",
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+      "dev": true
+    },
+    "node_modules/deepmerge": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/default-gateway": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/default-gateway/-/default-gateway-6.0.3.tgz",
+      "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==",
+      "dev": true,
+      "dependencies": {
+        "execa": "^5.0.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/default-gateway/node_modules/execa": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz",
+      "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.3",
+        "get-stream": "^6.0.0",
+        "human-signals": "^2.1.0",
+        "is-stream": "^2.0.0",
+        "merge-stream": "^2.0.0",
+        "npm-run-path": "^4.0.1",
+        "onetime": "^5.1.2",
+        "signal-exit": "^3.0.3",
+        "strip-final-newline": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sindresorhus/execa?sponsor=1"
+      }
+    },
+    "node_modules/default-gateway/node_modules/get-stream": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz",
+      "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/default-gateway/node_modules/is-stream": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz",
+      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/default-gateway/node_modules/npm-run-path": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",
+      "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/defaults": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz",
+      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
+      "dev": true,
+      "dependencies": {
+        "clone": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/define-data-property": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz",
+      "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+      "dev": true,
+      "dependencies": {
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/define-lazy-prop": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
+      "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/define-properties": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz",
+      "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+      "dev": true,
+      "dependencies": {
+        "define-data-property": "^1.0.1",
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
+    "node_modules/delegate": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz",
+      "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
+    },
+    "node_modules/depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/des.js": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/des.js/-/des.js-1.1.0.tgz",
+      "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/destroy": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz",
+      "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8",
+        "npm": "1.2.8000 || >= 1.4.16"
+      }
+    },
+    "node_modules/detect-libc": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz",
+      "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+      "dev": true,
+      "optional": true,
+      "bin": {
+        "detect-libc": "bin/detect-libc.js"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/detect-node": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz",
+      "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
+      "dev": true
+    },
+    "node_modules/diagram-js": {
+      "version": "6.8.2",
+      "resolved": "https://registry.npmmirror.com/diagram-js/-/diagram-js-6.8.2.tgz",
+      "integrity": "sha512-5EKYHjW2mmGsn9/jSenSkm8cScK5sO9eETBRQNIIzgZjxBDJn6eX964L2d7/vrAW9SeuijGUsztL9+NUinSsNg==",
+      "dependencies": {
+        "css.escape": "^1.5.1",
+        "didi": "^4.0.0",
+        "hammerjs": "^2.0.1",
+        "inherits": "^2.0.1",
+        "min-dash": "^3.5.0",
+        "min-dom": "^3.1.2",
+        "object-refs": "^0.3.0",
+        "path-intersection": "^2.2.0",
+        "tiny-svg": "^2.2.1"
+      }
+    },
+    "node_modules/diagram-js-direct-editing": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmmirror.com/diagram-js-direct-editing/-/diagram-js-direct-editing-1.8.0.tgz",
+      "integrity": "sha512-B4Xj+PJfgBjbPEzT3uZQEkZI5xHFB0Izc+7BhDFuHidzrEMzQKZrFGdA3PqfWhReHf3dp+iB6Tt11G9eGNjKMw==",
+      "dev": true,
+      "dependencies": {
+        "min-dash": "^3.5.2",
+        "min-dom": "^3.1.3"
+      },
+      "peerDependencies": {
+        "diagram-js": "*"
+      }
+    },
+    "node_modules/diagram-js-direct-editing/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/diagram-js/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg=="
+    },
+    "node_modules/didi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/didi/-/didi-4.0.0.tgz",
+      "integrity": "sha512-AzMElh8mCHOPWPCWfGjoJRla31fMXUT6+287W5ef3IPmtuBcyG9+MkFS7uPP6v3t2Cl086KwWfRB9mESa0OsHQ=="
+    },
+    "node_modules/diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmmirror.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "node_modules/diffie-hellman/node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "dev": true
+    },
+    "node_modules/dijkstrajs": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+      "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
+    },
+    "node_modules/dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "dependencies": {
+        "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/dns-packet": {
+      "version": "5.6.1",
+      "resolved": "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.6.1.tgz",
+      "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
+      "dev": true,
+      "dependencies": {
+        "@leichtgewicht/ip-codec": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "dev": true,
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/dom-converter": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/dom-converter/-/dom-converter-0.2.0.tgz",
+      "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+      "dev": true,
+      "dependencies": {
+        "utila": "~0.4"
+      }
+    },
+    "node_modules/dom-serializer": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-2.0.0.tgz",
+      "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.2",
+        "entities": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/dom-zindex": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.6.tgz",
+      "integrity": "sha512-FKWIhiU96bi3xpP9ewRMgANsoVmMUBnMnmpCT6dPMZOunVYJQmJhSRruoI0XSPoHeIif3kyEuiHbFrOJwEJaEA=="
+    },
+    "node_modules/dom7": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/dom7/-/dom7-3.0.0.tgz",
+      "integrity": "sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==",
+      "dependencies": {
+        "ssr-window": "^3.0.0-alpha.1"
+      }
+    },
+    "node_modules/domain-browser": {
+      "version": "5.7.0",
+      "resolved": "https://registry.npmmirror.com/domain-browser/-/domain-browser-5.7.0.tgz",
+      "integrity": "sha512-edTFu0M/7wO1pXY6GDxVNVW086uqwWYIHP98txhcPyV995X21JIH2DtYp33sQJOupYoXKe9RwTw2Ya2vWaquTQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      },
+      "funding": {
+        "url": "https://bevry.me/fund"
+      }
+    },
+    "node_modules/domelementtype": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz",
+      "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ]
+    },
+    "node_modules/domhandler": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-5.0.3.tgz",
+      "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/domify": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/domify/-/domify-1.4.2.tgz",
+      "integrity": "sha512-m4yreHcUWHBncGVV7U+yQzc12vIlq0jMrtHZ5mW6dQMiL/7skSYNVX9wqKwOtyO9SGCgevrAFEgOCAHmamHTUA==",
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/domutils": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/domutils/-/domutils-3.1.0.tgz",
+      "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+      "dev": true,
+      "dependencies": {
+        "dom-serializer": "^2.0.0",
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/dot-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/dot-case/-/dot-case-3.0.4.tgz",
+      "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
+      "dev": true,
+      "dependencies": {
+        "no-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
+    "node_modules/dotenv": {
+      "version": "10.0.0",
+      "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-10.0.0.tgz",
+      "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/dotenv-expand": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
+      "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
+      "dev": true
+    },
+    "node_modules/duplexer": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/duplexer/-/duplexer-0.1.2.tgz",
+      "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+      "dev": true
+    },
+    "node_modules/easy-stack": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/easy-stack/-/easy-stack-1.0.1.tgz",
+      "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/echarts": {
+      "version": "5.5.1",
+      "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
+      "integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==",
+      "dependencies": {
+        "tslib": "2.3.0",
+        "zrender": "5.6.0"
+      }
+    },
+    "node_modules/ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+      "dev": true
+    },
+    "node_modules/ejs": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz",
+      "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+      "dependencies": {
+        "jake": "^10.8.5"
+      },
+      "bin": {
+        "ejs": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/electron-to-chromium": {
+      "version": "1.5.68",
+      "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz",
+      "integrity": "sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==",
+      "dev": true
+    },
+    "node_modules/element-plus": {
+      "version": "2.9.0",
+      "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.0.tgz",
+      "integrity": "sha512-ccOFXKsauo2dtokAr4OX7gZsb7TuAoVxA2zGRZo5o2yyDDBLBaZxOoFQPoxITSLcHbBfQuNDGK5Iag5hnyKkZA==",
+      "dependencies": {
+        "@ctrl/tinycolor": "^3.4.1",
+        "@element-plus/icons-vue": "^2.3.1",
+        "@floating-ui/dom": "^1.0.1",
+        "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
+        "@types/lodash": "^4.14.182",
+        "@types/lodash-es": "^4.17.6",
+        "@vueuse/core": "^9.1.0",
+        "async-validator": "^4.2.5",
+        "dayjs": "^1.11.13",
+        "escape-html": "^1.0.3",
+        "lodash": "^4.17.21",
+        "lodash-es": "^4.17.21",
+        "lodash-unified": "^1.0.2",
+        "memoize-one": "^6.0.0",
+        "normalize-wheel-es": "^1.2.0"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/element-plus/node_modules/@vueuse/core": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz",
+      "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
+      "dependencies": {
+        "@types/web-bluetooth": "^0.0.16",
+        "@vueuse/metadata": "9.13.0",
+        "@vueuse/shared": "9.13.0",
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/element-plus/node_modules/@vueuse/metadata": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz",
+      "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/element-plus/node_modules/@vueuse/shared": {
+      "version": "9.13.0",
+      "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz",
+      "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
+      "dependencies": {
+        "vue-demi": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/elliptic": {
+      "version": "6.6.1",
+      "resolved": "https://registry.npmmirror.com/elliptic/-/elliptic-6.6.1.tgz",
+      "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.11.9",
+        "brorand": "^1.1.0",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.1",
+        "inherits": "^2.0.4",
+        "minimalistic-assert": "^1.0.1",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/elliptic/node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "dev": true
+    },
+    "node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+    },
+    "node_modules/emojis-list": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
+      "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/encode-utf8": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/encode-utf8/-/encode-utf8-1.0.3.tgz",
+      "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw=="
+    },
+    "node_modules/encodeurl": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
+      "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/end-of-stream": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz",
+      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.4.0"
+      }
+    },
+    "node_modules/enhanced-resolve": {
+      "version": "5.17.1",
+      "resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
+      "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/entities": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
+      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+      "engines": {
+        "node": ">=0.12"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "dependencies": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "node_modules/error-stack-parser": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmmirror.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
+      "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
+      "dev": true,
+      "dependencies": {
+        "stackframe": "^1.3.4"
+      }
+    },
+    "node_modules/es-abstract": {
+      "version": "1.23.5",
+      "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.23.5.tgz",
+      "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==",
+      "dev": true,
+      "dependencies": {
+        "array-buffer-byte-length": "^1.0.1",
+        "arraybuffer.prototype.slice": "^1.0.3",
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.7",
+        "data-view-buffer": "^1.0.1",
+        "data-view-byte-length": "^1.0.1",
+        "data-view-byte-offset": "^1.0.0",
+        "es-define-property": "^1.0.0",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0",
+        "es-set-tostringtag": "^2.0.3",
+        "es-to-primitive": "^1.2.1",
+        "function.prototype.name": "^1.1.6",
+        "get-intrinsic": "^1.2.4",
+        "get-symbol-description": "^1.0.2",
+        "globalthis": "^1.0.4",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.2",
+        "has-proto": "^1.0.3",
+        "has-symbols": "^1.0.3",
+        "hasown": "^2.0.2",
+        "internal-slot": "^1.0.7",
+        "is-array-buffer": "^3.0.4",
+        "is-callable": "^1.2.7",
+        "is-data-view": "^1.0.1",
+        "is-negative-zero": "^2.0.3",
+        "is-regex": "^1.1.4",
+        "is-shared-array-buffer": "^1.0.3",
+        "is-string": "^1.0.7",
+        "is-typed-array": "^1.1.13",
+        "is-weakref": "^1.0.2",
+        "object-inspect": "^1.13.3",
+        "object-keys": "^1.1.1",
+        "object.assign": "^4.1.5",
+        "regexp.prototype.flags": "^1.5.3",
+        "safe-array-concat": "^1.1.2",
+        "safe-regex-test": "^1.0.3",
+        "string.prototype.trim": "^1.2.9",
+        "string.prototype.trimend": "^1.0.8",
+        "string.prototype.trimstart": "^1.0.8",
+        "typed-array-buffer": "^1.0.2",
+        "typed-array-byte-length": "^1.0.1",
+        "typed-array-byte-offset": "^1.0.2",
+        "typed-array-length": "^1.0.6",
+        "unbox-primitive": "^1.0.2",
+        "which-typed-array": "^1.1.15"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/es-define-property": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz",
+      "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-module-lexer": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
+      "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
+      "dev": true
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+      "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+      "dev": true,
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+      "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.4",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-shim-unscopables": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+      "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+      "dev": true,
+      "dependencies": {
+        "hasown": "^2.0.0"
+      }
+    },
+    "node_modules/es-to-primitive": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+      "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.2.7",
+        "is-date-object": "^1.0.5",
+        "is-symbol": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/es5-ext": {
+      "version": "0.10.64",
+      "resolved": "https://registry.npmmirror.com/es5-ext/-/es5-ext-0.10.64.tgz",
+      "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.3",
+        "esniff": "^2.0.1",
+        "next-tick": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "node_modules/es6-symbol": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmmirror.com/es6-symbol/-/es6-symbol-3.1.4.tgz",
+      "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
+      "dependencies": {
+        "d": "^1.0.2",
+        "ext": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/escalade": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
+      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+    },
+    "node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint": {
+      "version": "8.57.1",
+      "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.57.1.tgz",
+      "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+      "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.2.0",
+        "@eslint-community/regexpp": "^4.6.1",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.57.1",
+        "@humanwhocodes/config-array": "^0.13.0",
+        "@humanwhocodes/module-importer": "^1.0.1",
+        "@nodelib/fs.walk": "^1.2.8",
+        "@ungap/structured-clone": "^1.2.0",
+        "ajv": "^6.12.4",
+        "chalk": "^4.0.0",
+        "cross-spawn": "^7.0.2",
+        "debug": "^4.3.2",
+        "doctrine": "^3.0.0",
+        "escape-string-regexp": "^4.0.0",
+        "eslint-scope": "^7.2.2",
+        "eslint-visitor-keys": "^3.4.3",
+        "espree": "^9.6.1",
+        "esquery": "^1.4.2",
+        "esutils": "^2.0.2",
+        "fast-deep-equal": "^3.1.3",
+        "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.2",
+        "globals": "^13.19.0",
+        "graphemer": "^1.4.0",
+        "ignore": "^5.2.0",
+        "imurmurhash": "^0.1.4",
+        "is-glob": "^4.0.0",
+        "is-path-inside": "^3.0.3",
+        "js-yaml": "^4.1.0",
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "levn": "^0.4.1",
+        "lodash.merge": "^4.6.2",
+        "minimatch": "^3.1.2",
+        "natural-compare": "^1.4.0",
+        "optionator": "^0.9.3",
+        "strip-ansi": "^6.0.1",
+        "text-table": "^0.2.0"
+      },
+      "bin": {
+        "eslint": "bin/eslint.js"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-config-prettier": {
+      "version": "8.10.0",
+      "resolved": "https://registry.npmmirror.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
+      "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
+      "dev": true,
+      "bin": {
+        "eslint-config-prettier": "bin/cli.js"
+      },
+      "peerDependencies": {
+        "eslint": ">=7.0.0"
+      }
+    },
+    "node_modules/eslint-import-resolver-node": {
+      "version": "0.3.9",
+      "resolved": "https://registry.npmmirror.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+      "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^3.2.7",
+        "is-core-module": "^2.13.0",
+        "resolve": "^1.22.4"
+      }
+    },
+    "node_modules/eslint-import-resolver-node/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/eslint-import-resolver-typescript": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmmirror.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz",
+      "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==",
+      "dev": true,
+      "dependencies": {
+        "@nolyfill/is-core-module": "1.0.39",
+        "debug": "^4.3.7",
+        "enhanced-resolve": "^5.15.0",
+        "fast-glob": "^3.3.2",
+        "get-tsconfig": "^4.7.5",
+        "is-bun-module": "^1.0.2",
+        "is-glob": "^4.0.3",
+        "stable-hash": "^0.0.4"
+      },
+      "engines": {
+        "node": "^14.18.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts"
+      },
+      "peerDependencies": {
+        "eslint": "*",
+        "eslint-plugin-import": "*",
+        "eslint-plugin-import-x": "*"
+      },
+      "peerDependenciesMeta": {
+        "eslint-plugin-import": {
+          "optional": true
+        },
+        "eslint-plugin-import-x": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/eslint-module-utils": {
+      "version": "2.12.0",
+      "resolved": "https://registry.npmmirror.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+      "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^3.2.7"
+      },
+      "engines": {
+        "node": ">=4"
+      },
+      "peerDependenciesMeta": {
+        "eslint": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/eslint-module-utils/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/eslint-plugin-import": {
+      "version": "2.31.0",
+      "resolved": "https://registry.npmmirror.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+      "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
+      "dev": true,
+      "dependencies": {
+        "@rtsao/scc": "^1.1.0",
+        "array-includes": "^3.1.8",
+        "array.prototype.findlastindex": "^1.2.5",
+        "array.prototype.flat": "^1.3.2",
+        "array.prototype.flatmap": "^1.3.2",
+        "debug": "^3.2.7",
+        "doctrine": "^2.1.0",
+        "eslint-import-resolver-node": "^0.3.9",
+        "eslint-module-utils": "^2.12.0",
+        "hasown": "^2.0.2",
+        "is-core-module": "^2.15.1",
+        "is-glob": "^4.0.3",
+        "minimatch": "^3.1.2",
+        "object.fromentries": "^2.0.8",
+        "object.groupby": "^1.0.3",
+        "object.values": "^1.2.0",
+        "semver": "^6.3.1",
+        "string.prototype.trimend": "^1.0.8",
+        "tsconfig-paths": "^3.15.0"
+      },
+      "engines": {
+        "node": ">=4"
+      },
+      "peerDependencies": {
+        "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+      }
+    },
+    "node_modules/eslint-plugin-import/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/eslint-plugin-import/node_modules/doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "dependencies": {
+        "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/eslint-plugin-import/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/eslint-plugin-prettier": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz",
+      "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==",
+      "dev": true,
+      "dependencies": {
+        "prettier-linter-helpers": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "eslint": ">=7.28.0",
+        "prettier": ">=2.0.0"
+      },
+      "peerDependenciesMeta": {
+        "eslint-config-prettier": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/eslint-plugin-vue": {
+      "version": "9.32.0",
+      "resolved": "https://registry.npmmirror.com/eslint-plugin-vue/-/eslint-plugin-vue-9.32.0.tgz",
+      "integrity": "sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/eslint-utils": "^4.4.0",
+        "globals": "^13.24.0",
+        "natural-compare": "^1.4.0",
+        "nth-check": "^2.1.1",
+        "postcss-selector-parser": "^6.0.15",
+        "semver": "^7.6.3",
+        "vue-eslint-parser": "^9.4.3",
+        "xml-name-validator": "^4.0.0"
+      },
+      "engines": {
+        "node": "^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+      }
+    },
+    "node_modules/eslint-plugin-vue/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint-plugin-vue/node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint-scope": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz",
+      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^4.1.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/eslint-visitor-keys": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+      "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint-webpack-plugin": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz",
+      "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==",
+      "dev": true,
+      "dependencies": {
+        "@types/eslint": "^7.29.0 || ^8.4.1",
+        "jest-worker": "^28.0.2",
+        "micromatch": "^4.0.5",
+        "normalize-path": "^3.0.0",
+        "schema-utils": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "eslint": "^7.0.0 || ^8.0.0",
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/eslint-webpack-plugin/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/eslint-webpack-plugin/node_modules/jest-worker": {
+      "version": "28.1.3",
+      "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-28.1.3.tgz",
+      "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "merge-stream": "^2.0.0",
+        "supports-color": "^8.0.0"
+      },
+      "engines": {
+        "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0"
+      }
+    },
+    "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/eslint-webpack-plugin/node_modules/schema-utils": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz",
+      "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/eslint-webpack-plugin/node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/eslint-scope": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/eslint/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmmirror.com/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/type-fest": {
+      "version": "0.20.2",
+      "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.20.2.tgz",
+      "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/esniff": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/esniff/-/esniff-2.0.1.tgz",
+      "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
+      "dependencies": {
+        "d": "^1.0.1",
+        "es5-ext": "^0.10.62",
+        "event-emitter": "^0.3.5",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/espree": {
+      "version": "9.6.1",
+      "resolved": "https://registry.npmmirror.com/espree/-/espree-9.6.1.tgz",
+      "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.9.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/esquery": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.6.0.tgz",
+      "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+      "dev": true,
+      "dependencies": {
+        "estraverse": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/esquery/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esrecurse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/esrecurse/-/esrecurse-4.3.0.tgz",
+      "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+      "dev": true,
+      "dependencies": {
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/esrecurse/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estraverse": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/estree-walker": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
+      "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+    },
+    "node_modules/esutils": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/esutils/-/esutils-2.0.3.tgz",
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmmirror.com/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
+    "node_modules/event-pubsub": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/event-pubsub/-/event-pubsub-4.3.0.tgz",
+      "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/event-target-shim": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/event-target-shim/-/event-target-shim-5.0.1.tgz",
+      "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/eventemitter3": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz",
+      "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+      "dev": true
+    },
+    "node_modules/events": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz",
+      "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.x"
+      }
+    },
+    "node_modules/evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "dependencies": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node_modules/evtd": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmmirror.com/evtd/-/evtd-0.2.4.tgz",
+      "integrity": "sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw=="
+    },
+    "node_modules/execa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/execa/-/execa-1.0.0.tgz",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/execa/node_modules/cross-spawn": {
+      "version": "6.0.6",
+      "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-6.0.6.tgz",
+      "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
+      "dev": true,
+      "dependencies": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      },
+      "engines": {
+        "node": ">=4.8"
+      }
+    },
+    "node_modules/execa/node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/execa/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/execa/node_modules/shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/execa/node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/execa/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/express": {
+      "version": "4.21.1",
+      "resolved": "https://registry.npmmirror.com/express/-/express-4.21.1.tgz",
+      "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==",
+      "dev": true,
+      "dependencies": {
+        "accepts": "~1.3.8",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.20.3",
+        "content-disposition": "0.5.4",
+        "content-type": "~1.0.4",
+        "cookie": "0.7.1",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "encodeurl": "~2.0.0",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.3.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "merge-descriptors": "1.0.3",
+        "methods": "~1.1.2",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.10",
+        "proxy-addr": "~2.0.7",
+        "qs": "6.13.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.2.1",
+        "send": "0.19.0",
+        "serve-static": "1.16.2",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.10.0"
+      }
+    },
+    "node_modules/express/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/express/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/express/node_modules/qs": {
+      "version": "6.13.0",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.0.tgz",
+      "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+      "dev": true,
+      "dependencies": {
+        "side-channel": "^1.0.6"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/ext": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmmirror.com/ext/-/ext-1.7.0.tgz",
+      "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+      "dependencies": {
+        "type": "^2.7.2"
+      }
+    },
+    "node_modules/fast-deep-equal": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+      "dev": true
+    },
+    "node_modules/fast-diff": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/fast-diff/-/fast-diff-1.3.0.tgz",
+      "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+      "dev": true
+    },
+    "node_modules/fast-glob": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz",
+      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+      "dev": true,
+      "dependencies": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.2",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.4"
+      },
+      "engines": {
+        "node": ">=8.6.0"
+      }
+    },
+    "node_modules/fast-glob/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/fast-json-stable-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+      "dev": true
+    },
+    "node_modules/fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+      "dev": true
+    },
+    "node_modules/fast-uri": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/fast-uri/-/fast-uri-3.0.3.tgz",
+      "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
+      "dev": true
+    },
+    "node_modules/fastq": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz",
+      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+      "dev": true,
+      "dependencies": {
+        "reusify": "^1.0.4"
+      }
+    },
+    "node_modules/faye-websocket": {
+      "version": "0.11.4",
+      "resolved": "https://registry.npmmirror.com/faye-websocket/-/faye-websocket-0.11.4.tgz",
+      "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+      "dev": true,
+      "dependencies": {
+        "websocket-driver": ">=0.5.1"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/fdir": {
+      "version": "6.4.2",
+      "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.4.2.tgz",
+      "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==",
+      "dev": true,
+      "peerDependencies": {
+        "picomatch": "^3 || ^4"
+      },
+      "peerDependenciesMeta": {
+        "picomatch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
+      "dev": true,
+      "dependencies": {
+        "escape-string-regexp": "^1.0.5"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/figures/node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/file-entry-cache": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+      "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+      "dev": true,
+      "dependencies": {
+        "flat-cache": "^3.0.4"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
+      }
+    },
+    "node_modules/filelist": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/filelist/-/filelist-1.0.4.tgz",
+      "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+      "dependencies": {
+        "minimatch": "^5.0.1"
+      }
+    },
+    "node_modules/filelist/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/filelist/node_modules/minimatch": {
+      "version": "5.1.6",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
+      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/fill-range": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+      "dev": true,
+      "dependencies": {
+        "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/finalhandler": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.3.1.tgz",
+      "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+      "dev": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "encodeurl": "~2.0.0",
+        "escape-html": "~1.0.3",
+        "on-finished": "2.4.1",
+        "parseurl": "~1.3.3",
+        "statuses": "2.0.1",
+        "unpipe": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/finalhandler/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/finalhandler/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/find-cache-dir": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmmirror.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+      "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+      "dev": true,
+      "dependencies": {
+        "commondir": "^1.0.1",
+        "make-dir": "^3.0.2",
+        "pkg-dir": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+      }
+    },
+    "node_modules/find-up": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/flat": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmmirror.com/flat/-/flat-5.0.2.tgz",
+      "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
+      "dev": true,
+      "bin": {
+        "flat": "cli.js"
+      }
+    },
+    "node_modules/flat-cache": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.2.0.tgz",
+      "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+      "dev": true,
+      "dependencies": {
+        "flatted": "^3.2.9",
+        "keyv": "^4.5.3",
+        "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
+      }
+    },
+    "node_modules/flatted": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.3.2.tgz",
+      "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
+      "dev": true
+    },
+    "node_modules/follow-redirects": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
+      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/for-each": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz",
+      "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+      "dev": true,
+      "dependencies": {
+        "is-callable": "^1.1.3"
+      }
+    },
+    "node_modules/fork-ts-checker-webpack-plugin": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz",
+      "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.8.3",
+        "@types/json-schema": "^7.0.5",
+        "chalk": "^4.1.0",
+        "chokidar": "^3.4.2",
+        "cosmiconfig": "^6.0.0",
+        "deepmerge": "^4.2.2",
+        "fs-extra": "^9.0.0",
+        "glob": "^7.1.6",
+        "memfs": "^3.1.2",
+        "minimatch": "^3.0.4",
+        "schema-utils": "2.7.0",
+        "semver": "^7.3.2",
+        "tapable": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=10",
+        "yarn": ">=1.0.0"
+      },
+      "peerDependencies": {
+        "eslint": ">= 6",
+        "typescript": ">= 2.7",
+        "vue-template-compiler": "*",
+        "webpack": ">= 4"
+      },
+      "peerDependenciesMeta": {
+        "eslint": {
+          "optional": true
+        },
+        "vue-template-compiler": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.0.tgz",
+      "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.4",
+        "ajv": "^6.12.2",
+        "ajv-keywords": "^3.4.1"
+      },
+      "engines": {
+        "node": ">= 8.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/tapable/-/tapable-1.1.3.tgz",
+      "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz",
+      "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/forwarded": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
+      "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fraction.js": {
+      "version": "4.3.7",
+      "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz",
+      "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+      "dev": true,
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "type": "patreon",
+        "url": "https://github.com/sponsors/rawify"
+      }
+    },
+    "node_modules/fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/fs-extra": {
+      "version": "9.1.0",
+      "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
+      "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+      "dev": true,
+      "dependencies": {
+        "at-least-node": "^1.0.0",
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/fs-monkey": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/fs-monkey/-/fs-monkey-1.0.6.tgz",
+      "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==",
+      "dev": true
+    },
+    "node_modules/fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+      "dev": true
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/function.prototype.name": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmmirror.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+      "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.2.0",
+        "es-abstract": "^1.22.1",
+        "functions-have-names": "^1.2.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/gensync": {
+      "version": "1.0.0-beta.2",
+      "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
+    },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+      "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+      "dev": true,
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "has-proto": "^1.0.1",
+        "has-symbols": "^1.0.3",
+        "hasown": "^2.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "dependencies": {
+        "pump": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/get-symbol-description": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+      "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.5",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-tsconfig": {
+      "version": "4.8.1",
+      "resolved": "https://registry.npmmirror.com/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
+      "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
+      "dev": true,
+      "dependencies": {
+        "resolve-pkg-maps": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+      }
+    },
+    "node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "deprecated": "Glob versions prior to v9 are no longer supported",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/glob-parent": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/glob-to-regexp": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
+      "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
+      "dev": true
+    },
+    "node_modules/global-object": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/global-object/-/global-object-1.0.0.tgz",
+      "integrity": "sha512-mSPSkY6UsHv6hgW0V2dfWBWTS8TnPnLx3ECVNoWp6rBI2Bg66VYoqGoTFlH/l7XhAZ/l+StYlntXlt87BEeCcg=="
+    },
+    "node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/globalthis": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz",
+      "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+      "dev": true,
+      "dependencies": {
+        "define-properties": "^1.2.1",
+        "gopd": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/globby": {
+      "version": "11.1.0",
+      "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz",
+      "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+      "dev": true,
+      "dependencies": {
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.2.9",
+        "ignore": "^5.2.0",
+        "merge2": "^1.4.1",
+        "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/good-listener": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz",
+      "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
+      "dependencies": {
+        "delegate": "^3.1.2"
+      }
+    },
+    "node_modules/gopd": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.1.0.tgz",
+      "integrity": "sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.2.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "dev": true
+    },
+    "node_modules/graphemer": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/graphemer/-/graphemer-1.4.0.tgz",
+      "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+      "dev": true
+    },
+    "node_modules/gzip-size": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz",
+      "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==",
+      "dev": true,
+      "dependencies": {
+        "duplexer": "^0.1.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/hammerjs": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmmirror.com/hammerjs/-/hammerjs-2.0.8.tgz",
+      "integrity": "sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/handle-thing": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/handle-thing/-/handle-thing-2.0.1.tgz",
+      "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+      "dev": true
+    },
+    "node_modules/has-bigints": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/has-bigints/-/has-bigints-1.0.2.tgz",
+      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+      "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+      "dev": true,
+      "dependencies": {
+        "es-define-property": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-proto": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.1.0.tgz",
+      "integrity": "sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "dev": true,
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hash-base": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/hash-base/-/hash-base-3.0.5.tgz",
+      "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.4",
+        "safe-buffer": "^5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/hash-sum": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-2.0.0.tgz",
+      "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+      "dev": true
+    },
+    "node_modules/hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmmirror.com/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "dev": true,
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/he": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz",
+      "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+      "dev": true,
+      "bin": {
+        "he": "bin/he"
+      }
+    },
+    "node_modules/highlight.js": {
+      "version": "11.10.0",
+      "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.10.0.tgz",
+      "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==",
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==",
+      "dev": true,
+      "dependencies": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "node_modules/hosted-git-info": {
+      "version": "2.8.9",
+      "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+      "dev": true
+    },
+    "node_modules/hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmmirror.com/hpack.js/-/hpack.js-2.1.6.tgz",
+      "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      }
+    },
+    "node_modules/hpack.js/node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+      "dev": true
+    },
+    "node_modules/hpack.js/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dev": true,
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/hpack.js/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+      "dev": true
+    },
+    "node_modules/hpack.js/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/html-entities": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmmirror.com/html-entities/-/html-entities-2.5.2.tgz",
+      "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/mdevils"
+        },
+        {
+          "type": "patreon",
+          "url": "https://patreon.com/mdevils"
+        }
+      ]
+    },
+    "node_modules/html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true
+    },
+    "node_modules/html-minifier-terser": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
+      "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==",
+      "dev": true,
+      "dependencies": {
+        "camel-case": "^4.1.2",
+        "clean-css": "^5.2.2",
+        "commander": "^8.3.0",
+        "he": "^1.2.0",
+        "param-case": "^3.0.4",
+        "relateurl": "^0.2.7",
+        "terser": "^5.10.0"
+      },
+      "bin": {
+        "html-minifier-terser": "cli.js"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/html-tags": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-3.3.1.tgz",
+      "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/html-void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/html-void-elements/-/html-void-elements-2.0.1.tgz",
+      "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==",
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/wooorm"
+      }
+    },
+    "node_modules/html-webpack-plugin": {
+      "version": "5.6.3",
+      "resolved": "https://registry.npmmirror.com/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz",
+      "integrity": "sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg==",
+      "dev": true,
+      "dependencies": {
+        "@types/html-minifier-terser": "^6.0.0",
+        "html-minifier-terser": "^6.0.2",
+        "lodash": "^4.17.21",
+        "pretty-error": "^4.0.0",
+        "tapable": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/html-webpack-plugin"
+      },
+      "peerDependencies": {
+        "@rspack/core": "0.x || 1.x",
+        "webpack": "^5.20.0"
+      },
+      "peerDependenciesMeta": {
+        "@rspack/core": {
+          "optional": true
+        },
+        "webpack": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/htmlparser2": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-8.0.2.tgz",
+      "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+      "dev": true,
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "dependencies": {
+        "domelementtype": "^2.3.0",
+        "domhandler": "^5.0.3",
+        "domutils": "^3.0.1",
+        "entities": "^4.4.0"
+      }
+    },
+    "node_modules/http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/http-deceiver/-/http-deceiver-1.2.7.tgz",
+      "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+      "dev": true
+    },
+    "node_modules/http-errors": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz",
+      "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+      "dev": true,
+      "dependencies": {
+        "depd": "2.0.0",
+        "inherits": "2.0.4",
+        "setprototypeof": "1.2.0",
+        "statuses": "2.0.1",
+        "toidentifier": "1.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/http-parser-js": {
+      "version": "0.5.8",
+      "resolved": "https://registry.npmmirror.com/http-parser-js/-/http-parser-js-0.5.8.tgz",
+      "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
+      "dev": true
+    },
+    "node_modules/http-proxy": {
+      "version": "1.18.1",
+      "resolved": "https://registry.npmmirror.com/http-proxy/-/http-proxy-1.18.1.tgz",
+      "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+      "dev": true,
+      "dependencies": {
+        "eventemitter3": "^4.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/http-proxy-middleware": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmmirror.com/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
+      "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==",
+      "dev": true,
+      "dependencies": {
+        "@types/http-proxy": "^1.17.8",
+        "http-proxy": "^1.18.1",
+        "is-glob": "^4.0.1",
+        "is-plain-obj": "^3.0.0",
+        "micromatch": "^4.0.2"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "@types/express": "^4.17.13"
+      },
+      "peerDependenciesMeta": {
+        "@types/express": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==",
+      "dev": true
+    },
+    "node_modules/human-signals": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz",
+      "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.17.0"
+      }
+    },
+    "node_modules/i18next": {
+      "version": "20.6.1",
+      "resolved": "https://registry.npmmirror.com/i18next/-/i18next-20.6.1.tgz",
+      "integrity": "sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==",
+      "dependencies": {
+        "@babel/runtime": "^7.12.0"
+      }
+    },
+    "node_modules/iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+      "dev": true,
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/icss-utils": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/icss-utils/-/icss-utils-5.1.0.tgz",
+      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/ids": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/ids/-/ids-1.0.5.tgz",
+      "integrity": "sha512-XQ0yom/4KWTL29sLG+tyuycy7UmeaM/79GRtSJq6IG9cJGIPeBz5kwDCguie3TwxaMNIc3WtPi0cTa1XYHicpw==",
+      "dev": true
+    },
+    "node_modules/ieee754": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/ignore": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz",
+      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/immer": {
+      "version": "9.0.21",
+      "resolved": "https://registry.npmmirror.com/immer/-/immer-9.0.21.tgz",
+      "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/immer"
+      }
+    },
+    "node_modules/immutable": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.0.3.tgz",
+      "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==",
+      "dev": true
+    },
+    "node_modules/import-fresh": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz",
+      "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+      "dev": true,
+      "dependencies": {
+        "parent-module": "^1.0.0",
+        "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.19"
+      }
+    },
+    "node_modules/indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
+    },
+    "node_modules/inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+      "dev": true,
+      "dependencies": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+    },
+    "node_modules/internal-slot": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.7.tgz",
+      "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
+      "dev": true,
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "hasown": "^2.0.0",
+        "side-channel": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/ipaddr.js": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
+      "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/is-arguments": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/is-arguments/-/is-arguments-1.1.1.tgz",
+      "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-array-buffer": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+      "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "get-intrinsic": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+      "dev": true
+    },
+    "node_modules/is-async-function": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/is-async-function/-/is-async-function-2.0.0.tgz",
+      "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-bigint": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-bigint/-/is-bigint-1.1.0.tgz",
+      "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
+      "dev": true,
+      "dependencies": {
+        "has-bigints": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-binary-path": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
+      "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+      "dev": true,
+      "dependencies": {
+        "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-boolean-object": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.2.0.tgz",
+      "integrity": "sha512-kR5g0+dXf/+kXnqI+lu0URKYPKgICtHGGNCDSB10AaUFj3o/HkB3u7WfpRBJGFopxxY0oH3ux7ZsDjLtK7xqvw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-bun-module": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/is-bun-module/-/is-bun-module-1.3.0.tgz",
+      "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==",
+      "dev": true,
+      "dependencies": {
+        "semver": "^7.6.3"
+      }
+    },
+    "node_modules/is-callable": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-ci": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/is-ci/-/is-ci-1.2.1.tgz",
+      "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
+      "dev": true,
+      "dependencies": {
+        "ci-info": "^1.5.0"
+      },
+      "bin": {
+        "is-ci": "bin.js"
+      }
+    },
+    "node_modules/is-core-module": {
+      "version": "2.15.1",
+      "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.15.1.tgz",
+      "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+      "dev": true,
+      "dependencies": {
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-data-view": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/is-data-view/-/is-data-view-1.0.1.tgz",
+      "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+      "dev": true,
+      "dependencies": {
+        "is-typed-array": "^1.1.13"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-date-object": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/is-date-object/-/is-date-object-1.0.5.tgz",
+      "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-docker": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz",
+      "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+      "dev": true,
+      "bin": {
+        "is-docker": "cli.js"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-file-esm": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-file-esm/-/is-file-esm-1.0.0.tgz",
+      "integrity": "sha512-rZlaNKb4Mr8WlRu2A9XdeoKgnO5aA53XdPHgCKVyCrQ/rWi89RET1+bq37Ru46obaQXeiX4vmFIm1vks41hoSA==",
+      "dev": true,
+      "dependencies": {
+        "read-pkg-up": "^7.0.1"
+      }
+    },
+    "node_modules/is-finalizationregistry": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz",
+      "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-generator-function": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.0.10.tgz",
+      "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+      "dev": true,
+      "dependencies": {
+        "has-tostringtag": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-glob": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+      "dev": true,
+      "dependencies": {
+        "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-hotkey": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/is-hotkey/-/is-hotkey-0.2.0.tgz",
+      "integrity": "sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw=="
+    },
+    "node_modules/is-interactive": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz",
+      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-map": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/is-map/-/is-map-2.0.3.tgz",
+      "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-nan": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmmirror.com/is-nan/-/is-nan-1.3.2.tgz",
+      "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-negative-zero": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+      "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-number": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
+    },
+    "node_modules/is-number-object": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-number-object/-/is-number-object-1.1.0.tgz",
+      "integrity": "sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-path-inside": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/is-path-inside/-/is-path-inside-3.0.3.tgz",
+      "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/is-plain-obj": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz",
+      "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-plain-object": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz",
+      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-regex": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/is-regex/-/is-regex-1.2.0.tgz",
+      "integrity": "sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "gopd": "^1.1.0",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-set": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/is-set/-/is-set-2.0.3.tgz",
+      "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-shared-array-buffer": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+      "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/is-string": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-string/-/is-string-1.1.0.tgz",
+      "integrity": "sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-symbol": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/is-symbol/-/is-symbol-1.1.0.tgz",
+      "integrity": "sha512-qS8KkNNXUZ/I+nX6QT8ZS1/Yx0A444yhzdTKxCzKkNjQ9sHErBxJnJAgh+f5YhusYECEcjo4XcyH87hn6+ks0A==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "has-symbols": "^1.0.3",
+        "safe-regex-test": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-typed-array": {
+      "version": "1.1.13",
+      "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.13.tgz",
+      "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+      "dev": true,
+      "dependencies": {
+        "which-typed-array": "^1.1.14"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-unicode-supported": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/is-url": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz",
+      "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
+    },
+    "node_modules/is-weakmap": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/is-weakmap/-/is-weakmap-2.0.2.tgz",
+      "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-weakref": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/is-weakref/-/is-weakref-1.0.2.tgz",
+      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-weakset": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/is-weakset/-/is-weakset-2.0.3.tgz",
+      "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "get-intrinsic": "^1.2.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/is-wsl": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz",
+      "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+      "dev": true,
+      "dependencies": {
+        "is-docker": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/isarray": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz",
+      "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+      "dev": true
+    },
+    "node_modules/isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+      "dev": true
+    },
+    "node_modules/isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/jake": {
+      "version": "10.9.2",
+      "resolved": "https://registry.npmmirror.com/jake/-/jake-10.9.2.tgz",
+      "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+      "dependencies": {
+        "async": "^3.2.3",
+        "chalk": "^4.0.2",
+        "filelist": "^1.0.4",
+        "minimatch": "^3.1.2"
+      },
+      "bin": {
+        "jake": "bin/cli.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/jake/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/javascript-stringify": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz",
+      "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
+      "dev": true
+    },
+    "node_modules/jest-worker": {
+      "version": "27.5.1",
+      "resolved": "https://registry.npmmirror.com/jest-worker/-/jest-worker-27.5.1.tgz",
+      "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*",
+        "merge-stream": "^2.0.0",
+        "supports-color": "^8.0.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      }
+    },
+    "node_modules/jest-worker/node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/joi": {
+      "version": "17.13.3",
+      "resolved": "https://registry.npmmirror.com/joi/-/joi-17.13.3.tgz",
+      "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==",
+      "dev": true,
+      "dependencies": {
+        "@hapi/hoek": "^9.3.0",
+        "@hapi/topo": "^5.1.0",
+        "@sideway/address": "^4.1.5",
+        "@sideway/formula": "^3.0.1",
+        "@sideway/pinpoint": "^2.0.0"
+      }
+    },
+    "node_modules/js-message": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/js-message/-/js-message-1.0.7.tgz",
+      "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+      "dev": true
+    },
+    "node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
+      }
+    },
+    "node_modules/jsbarcode": {
+      "version": "3.11.5",
+      "resolved": "https://registry.npmmirror.com/jsbarcode/-/jsbarcode-3.11.5.tgz",
+      "integrity": "sha512-zv3KsH51zD00I/LrFzFSM6dst7rDn0vIMzaiZFL7qusTjPZiPtxg3zxetp0RR7obmjTw4f6NyGgbdkBCgZUIrA==",
+      "bin": {
+        "auto.js": "bin/barcodes/CODE128/auto.js",
+        "Barcode.js": "bin/barcodes/Barcode.js",
+        "barcodes": "bin/barcodes",
+        "canvas.js": "bin/renderers/canvas.js",
+        "checksums.js": "bin/barcodes/MSI/checksums.js",
+        "codabar": "bin/barcodes/codabar",
+        "CODE128": "bin/barcodes/CODE128",
+        "CODE128_AUTO.js": "bin/barcodes/CODE128/CODE128_AUTO.js",
+        "CODE128.js": "bin/barcodes/CODE128/CODE128.js",
+        "CODE128A.js": "bin/barcodes/CODE128/CODE128A.js",
+        "CODE128B.js": "bin/barcodes/CODE128/CODE128B.js",
+        "CODE128C.js": "bin/barcodes/CODE128/CODE128C.js",
+        "CODE39": "bin/barcodes/CODE39",
+        "constants.js": "bin/barcodes/ITF/constants.js",
+        "defaults.js": "bin/options/defaults.js",
+        "EAN_UPC": "bin/barcodes/EAN_UPC",
+        "EAN.js": "bin/barcodes/EAN_UPC/EAN.js",
+        "EAN13.js": "bin/barcodes/EAN_UPC/EAN13.js",
+        "EAN2.js": "bin/barcodes/EAN_UPC/EAN2.js",
+        "EAN5.js": "bin/barcodes/EAN_UPC/EAN5.js",
+        "EAN8.js": "bin/barcodes/EAN_UPC/EAN8.js",
+        "encoder.js": "bin/barcodes/EAN_UPC/encoder.js",
+        "ErrorHandler.js": "bin/exceptions/ErrorHandler.js",
+        "exceptions": "bin/exceptions",
+        "exceptions.js": "bin/exceptions/exceptions.js",
+        "fixOptions.js": "bin/help/fixOptions.js",
+        "GenericBarcode": "bin/barcodes/GenericBarcode",
+        "getOptionsFromElement.js": "bin/help/getOptionsFromElement.js",
+        "getRenderProperties.js": "bin/help/getRenderProperties.js",
+        "help": "bin/help",
+        "index.js": "bin/renderers/index.js",
+        "index.tmp.js": "bin/barcodes/index.tmp.js",
+        "ITF": "bin/barcodes/ITF",
+        "ITF.js": "bin/barcodes/ITF/ITF.js",
+        "ITF14.js": "bin/barcodes/ITF/ITF14.js",
+        "JsBarcode.js": "bin/JsBarcode.js",
+        "linearizeEncodings.js": "bin/help/linearizeEncodings.js",
+        "merge.js": "bin/help/merge.js",
+        "MSI": "bin/barcodes/MSI",
+        "MSI.js": "bin/barcodes/MSI/MSI.js",
+        "MSI10.js": "bin/barcodes/MSI/MSI10.js",
+        "MSI1010.js": "bin/barcodes/MSI/MSI1010.js",
+        "MSI11.js": "bin/barcodes/MSI/MSI11.js",
+        "MSI1110.js": "bin/barcodes/MSI/MSI1110.js",
+        "object.js": "bin/renderers/object.js",
+        "options": "bin/options",
+        "optionsFromStrings.js": "bin/help/optionsFromStrings.js",
+        "pharmacode": "bin/barcodes/pharmacode",
+        "renderers": "bin/renderers",
+        "shared.js": "bin/renderers/shared.js",
+        "svg.js": "bin/renderers/svg.js",
+        "UPC.js": "bin/barcodes/EAN_UPC/UPC.js",
+        "UPCE.js": "bin/barcodes/EAN_UPC/UPCE.js"
+      }
+    },
+    "node_modules/jsencrypt": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.2.tgz",
+      "integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A=="
+    },
+    "node_modules/jsesc": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.0.2.tgz",
+      "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+      "dev": true,
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/json-bigint": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz",
+      "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+      "dependencies": {
+        "bignumber.js": "^9.0.0"
+      }
+    },
+    "node_modules/json-buffer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
+      "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+      "dev": true
+    },
+    "node_modules/json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "node_modules/json-parse-even-better-errors": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true
+    },
+    "node_modules/json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "node_modules/json-stable-stringify-without-jsonify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+      "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+      "dev": true
+    },
+    "node_modules/json5": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
+      "bin": {
+        "json5": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/jsonfile": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
+      "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+      "dev": true,
+      "dependencies": {
+        "universalify": "^2.0.0"
+      },
+      "optionalDependencies": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "node_modules/keyv": {
+      "version": "4.5.4",
+      "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
+      "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+      "dev": true,
+      "dependencies": {
+        "json-buffer": "3.0.1"
+      }
+    },
+    "node_modules/kind-of": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
+      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/klona": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",
+      "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/launch-editor": {
+      "version": "2.9.1",
+      "resolved": "https://registry.npmmirror.com/launch-editor/-/launch-editor-2.9.1.tgz",
+      "integrity": "sha512-Gcnl4Bd+hRO9P9icCP/RVVT2o8SFlPXofuCxvA2SaZuH45whSvf5p8x5oih5ftLiVhEI4sp5xDY+R+b3zJBh5w==",
+      "dev": true,
+      "dependencies": {
+        "picocolors": "^1.0.0",
+        "shell-quote": "^1.8.1"
+      }
+    },
+    "node_modules/launch-editor-middleware": {
+      "version": "2.9.1",
+      "resolved": "https://registry.npmmirror.com/launch-editor-middleware/-/launch-editor-middleware-2.9.1.tgz",
+      "integrity": "sha512-4wF6AtPtaIENiZdH/a+3yW8Xni7uxzTEDd1z+gH00hUWBCSmQknFohznMd9BWhLk8MXObeB5ir69GbIr9qFW1w==",
+      "dev": true,
+      "dependencies": {
+        "launch-editor": "^2.9.1"
+      }
+    },
+    "node_modules/levn": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmmirror.com/levn/-/levn-0.4.1.tgz",
+      "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "^1.2.1",
+        "type-check": "~0.4.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/lilconfig": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz",
+      "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/lines-and-columns": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+      "dev": true
+    },
+    "node_modules/loader-runner": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.0.tgz",
+      "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.11.5"
+      }
+    },
+    "node_modules/loader-utils": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz",
+      "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+      "dev": true,
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
+    "node_modules/loader-utils/node_modules/json5": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
+      "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+      "dev": true,
+      "dependencies": {
+        "minimist": "^1.2.0"
+      },
+      "bin": {
+        "json5": "lib/cli.js"
+      }
+    },
+    "node_modules/local-pkg": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.5.1.tgz",
+      "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==",
+      "dev": true,
+      "dependencies": {
+        "mlly": "^1.7.3",
+        "pkg-types": "^1.2.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/locate-path": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-6.0.0.tgz",
+      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/lodash": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
+      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+    },
+    "node_modules/lodash-es": {
+      "version": "4.17.21",
+      "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
+      "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
+    },
+    "node_modules/lodash-unified": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz",
+      "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
+      "peerDependencies": {
+        "@types/lodash-es": "*",
+        "lodash": "*",
+        "lodash-es": "*"
+      }
+    },
+    "node_modules/lodash.camelcase": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+      "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="
+    },
+    "node_modules/lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ=="
+    },
+    "node_modules/lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+    },
+    "node_modules/lodash.defaultsdeep": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmmirror.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+      "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+      "dev": true
+    },
+    "node_modules/lodash.foreach": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
+      "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ=="
+    },
+    "node_modules/lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+    },
+    "node_modules/lodash.kebabcase": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+      "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+      "dev": true
+    },
+    "node_modules/lodash.mapvalues": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmmirror.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
+      "integrity": "sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==",
+      "dev": true
+    },
+    "node_modules/lodash.memoize": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+      "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+      "dev": true
+    },
+    "node_modules/lodash.merge": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz",
+      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+      "dev": true
+    },
+    "node_modules/lodash.throttle": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+      "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+    },
+    "node_modules/lodash.toarray": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmmirror.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
+      "integrity": "sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw=="
+    },
+    "node_modules/lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+      "dev": true
+    },
+    "node_modules/log-symbols": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz",
+      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^4.1.0",
+        "is-unicode-supported": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/log-symbols/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/log-update": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/log-update/-/log-update-2.3.0.tgz",
+      "integrity": "sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg==",
+      "dev": true,
+      "dependencies": {
+        "ansi-escapes": "^3.0.0",
+        "cli-cursor": "^2.0.0",
+        "wrap-ansi": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/ansi-regex": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-3.0.1.tgz",
+      "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==",
+      "dev": true,
+      "dependencies": {
+        "restore-cursor": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==",
+      "dev": true,
+      "dependencies": {
+        "mimic-fn": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==",
+      "dev": true,
+      "dependencies": {
+        "onetime": "^2.0.0",
+        "signal-exit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/string-width": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-2.1.1.tgz",
+      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+      "dev": true,
+      "dependencies": {
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/strip-ansi": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-4.0.0.tgz",
+      "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/log-update/node_modules/wrap-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
+      "integrity": "sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^2.1.1",
+        "strip-ansi": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/lower-case": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/lower-case/-/lower-case-2.0.2.tgz",
+      "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^2.0.3"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "node_modules/magic-string": {
+      "version": "0.30.14",
+      "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.14.tgz",
+      "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==",
+      "dependencies": {
+        "@jridgewell/sourcemap-codec": "^1.5.0"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-3.1.0.tgz",
+      "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+      "dev": true,
+      "dependencies": {
+        "semver": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/make-dir/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/matches-selector": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/matches-selector/-/matches-selector-1.2.0.tgz",
+      "integrity": "sha512-c4vLwYWyl+Ji+U43eU/G5FwxWd4ZH0ePUsFs5y0uwD9HUEFBXUQ1zUUan+78IpRD+y4pUfG0nAzNM292K7ItvA=="
+    },
+    "node_modules/md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmmirror.com/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/mdn-data": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.14.tgz",
+      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+      "dev": true
+    },
+    "node_modules/media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/memfs": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmmirror.com/memfs/-/memfs-3.5.3.tgz",
+      "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==",
+      "dev": true,
+      "dependencies": {
+        "fs-monkey": "^1.0.4"
+      },
+      "engines": {
+        "node": ">= 4.0.0"
+      }
+    },
+    "node_modules/memoize-one": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
+      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
+    },
+    "node_modules/merge-descriptors": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+      "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/merge-source-map": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/merge-source-map/-/merge-source-map-1.1.0.tgz",
+      "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+      "dev": true,
+      "dependencies": {
+        "source-map": "^0.6.1"
+      }
+    },
+    "node_modules/merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "node_modules/merge2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz",
+      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/micromatch": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
+      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+      "dev": true,
+      "dependencies": {
+        "braces": "^3.0.3",
+        "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
+      }
+    },
+    "node_modules/miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "bin": {
+        "miller-rabin": "bin/miller-rabin"
+      }
+    },
+    "node_modules/miller-rabin/node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "dev": true
+    },
+    "node_modules/mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true,
+      "bin": {
+        "mime": "cli.js"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-match": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/mime-match/-/mime-match-1.0.2.tgz",
+      "integrity": "sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==",
+      "dependencies": {
+        "wildcard": "^1.1.0"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mimic-fn": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz",
+      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/min-dash": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-4.2.2.tgz",
+      "integrity": "sha512-qbhSYUxk6mBaF096B3JOQSumXbKWHenmT97cSpdNzgkWwGjhjhE/KZODCoDNhI2I4C9Cb6R/Q13S4BYkUSXoXQ=="
+    },
+    "node_modules/min-dom": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/min-dom/-/min-dom-3.2.1.tgz",
+      "integrity": "sha512-v6YCmnDzxk4rRJntWTUiwggLupPw/8ZSRqUq0PDaBwVZEO/wYzCH4SKVBV+KkEvf3u0XaWHly5JEosPtqRATZA==",
+      "dependencies": {
+        "component-event": "^0.1.4",
+        "domify": "^1.3.1",
+        "indexof": "0.0.1",
+        "matches-selector": "^1.2.0",
+        "min-dash": "^3.8.1"
+      }
+    },
+    "node_modules/min-dom/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg=="
+    },
+    "node_modules/mini-css-extract-plugin": {
+      "version": "2.9.2",
+      "resolved": "https://registry.npmmirror.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz",
+      "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==",
+      "dev": true,
+      "dependencies": {
+        "schema-utils": "^4.0.0",
+        "tapable": "^2.2.1"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/mini-css-extract-plugin/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/mini-css-extract-plugin/node_modules/schema-utils": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz",
+      "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "node_modules/minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==",
+      "dev": true
+    },
+    "node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/minipass": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
+      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/minipass/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
+    "node_modules/mitt": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/mitt/-/mitt-1.2.0.tgz",
+      "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==",
+      "dev": true
+    },
+    "node_modules/mkdirp": {
+      "version": "0.5.6",
+      "resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+      "dev": true,
+      "dependencies": {
+        "minimist": "^1.2.6"
+      },
+      "bin": {
+        "mkdirp": "bin/cmd.js"
+      }
+    },
+    "node_modules/mlly": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.7.3.tgz",
+      "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.14.0",
+        "pathe": "^1.1.2",
+        "pkg-types": "^1.2.1",
+        "ufo": "^1.5.4"
+      }
+    },
+    "node_modules/moddle": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/moddle/-/moddle-5.0.4.tgz",
+      "integrity": "sha512-Kjb+hjuzO+YlojNGxEUXvdhLYTHTtAABDlDcJTtTcn5MbJF9Zkv4I1Fyvp3Ypmfgg1EfHDZ3PsCQTuML9JD6wg==",
+      "dev": true,
+      "dependencies": {
+        "min-dash": "^3.0.0"
+      }
+    },
+    "node_modules/moddle-xml": {
+      "version": "9.0.6",
+      "resolved": "https://registry.npmmirror.com/moddle-xml/-/moddle-xml-9.0.6.tgz",
+      "integrity": "sha512-tl0reHpsY/aKlLGhXeFlQWlYAQHFxTkFqC8tq8jXRYpQSnLVw13T6swMaourLd7EXqHdWsc+5ggsB+fEep6xZQ==",
+      "dev": true,
+      "dependencies": {
+        "min-dash": "^3.5.2",
+        "moddle": "^5.0.2",
+        "saxen": "^8.1.2"
+      }
+    },
+    "node_modules/moddle-xml/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/moddle/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/module-alias": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz",
+      "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
+      "dev": true
+    },
+    "node_modules/mrmime": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz",
+      "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "dev": true
+    },
+    "node_modules/multicast-dns": {
+      "version": "7.2.5",
+      "resolved": "https://registry.npmmirror.com/multicast-dns/-/multicast-dns-7.2.5.tgz",
+      "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==",
+      "dev": true,
+      "dependencies": {
+        "dns-packet": "^5.2.2",
+        "thunky": "^1.0.2"
+      },
+      "bin": {
+        "multicast-dns": "cli.js"
+      }
+    },
+    "node_modules/mz": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz",
+      "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "^1.0.0",
+        "object-assign": "^4.0.1",
+        "thenify-all": "^1.0.0"
+      }
+    },
+    "node_modules/namespace-emitter": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/namespace-emitter/-/namespace-emitter-2.0.1.tgz",
+      "integrity": "sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g=="
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz",
+      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+      "dev": true
+    },
+    "node_modules/natural-compare-lite": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+      "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+      "dev": true
+    },
+    "node_modules/negotiator": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz",
+      "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/neo-async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
+      "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+      "dev": true
+    },
+    "node_modules/next-tick": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/next-tick/-/next-tick-1.1.0.tgz",
+      "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+    },
+    "node_modules/nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+      "dev": true
+    },
+    "node_modules/no-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/no-case/-/no-case-3.0.4.tgz",
+      "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
+      "dev": true,
+      "dependencies": {
+        "lower-case": "^2.0.2",
+        "tslib": "^2.0.3"
+      }
+    },
+    "node_modules/node-addon-api": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz",
+      "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+      "dev": true,
+      "optional": true
+    },
+    "node_modules/node-fetch": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz",
+      "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+      "dev": true,
+      "dependencies": {
+        "whatwg-url": "^5.0.0"
+      },
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      },
+      "peerDependencies": {
+        "encoding": "^0.1.0"
+      },
+      "peerDependenciesMeta": {
+        "encoding": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/node-forge": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.1.tgz",
+      "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6.13.0"
+      }
+    },
+    "node_modules/node-polyfill-webpack-plugin": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-4.0.0.tgz",
+      "integrity": "sha512-WLk77vLpbcpmTekRj6s6vYxk30XoyaY5MDZ4+9g8OaKoG3Ij+TjOqhpQjVUlfDZBPBgpNATDltaQkzuXSnnkwg==",
+      "dev": true,
+      "dependencies": {
+        "assert": "^2.1.0",
+        "browserify-zlib": "^0.2.0",
+        "buffer": "^6.0.3",
+        "console-browserify": "^1.2.0",
+        "constants-browserify": "^1.0.0",
+        "crypto-browserify": "^3.12.0",
+        "domain-browser": "^5.7.0",
+        "events": "^3.3.0",
+        "https-browserify": "^1.0.0",
+        "os-browserify": "^0.3.0",
+        "path-browserify": "^1.0.1",
+        "process": "^0.11.10",
+        "punycode": "^2.3.1",
+        "querystring-es3": "^0.2.1",
+        "readable-stream": "^4.5.2",
+        "stream-browserify": "^3.0.0",
+        "stream-http": "^3.2.0",
+        "string_decoder": "^1.3.0",
+        "timers-browserify": "^2.0.12",
+        "tty-browserify": "^0.0.1",
+        "type-fest": "^4.18.2",
+        "url": "^0.11.3",
+        "util": "^0.12.5",
+        "vm-browserify": "^1.1.2"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "peerDependencies": {
+        "webpack": ">=5"
+      }
+    },
+    "node_modules/node-releases": {
+      "version": "2.0.18",
+      "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.18.tgz",
+      "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+      "dev": true
+    },
+    "node_modules/normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "dependencies": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "node_modules/normalize-package-data/node_modules/semver": {
+      "version": "5.7.2",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
+      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver"
+      }
+    },
+    "node_modules/normalize-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
+      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/normalize-url": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz",
+      "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/normalize-wheel-es": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
+      "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw=="
+    },
+    "node_modules/npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+      "dev": true,
+      "dependencies": {
+        "path-key": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/npm-run-path/node_modules/path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/nth-check": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/nth-check/-/nth-check-2.1.1.tgz",
+      "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+      "dev": true,
+      "dependencies": {
+        "boolbase": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/nth-check?sponsor=1"
+      }
+    },
+    "node_modules/object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/object-inspect": {
+      "version": "1.13.3",
+      "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.13.3.tgz",
+      "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object-is": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmmirror.com/object-is/-/object-is-1.1.6.tgz",
+      "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object-refs": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/object-refs/-/object-refs-0.3.0.tgz",
+      "integrity": "sha512-eP0ywuoWOaDoiake/6kTJlPJhs+k0qNm4nYRzXLNHj6vh+5M3i9R1epJTdxIPGlhWc4fNRQ7a6XJNCX+/L4FOQ=="
+    },
+    "node_modules/object.assign": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.5.tgz",
+      "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.5",
+        "define-properties": "^1.2.1",
+        "has-symbols": "^1.0.3",
+        "object-keys": "^1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.fromentries": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.8.tgz",
+      "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.2",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/object.groupby": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/object.groupby/-/object.groupby-1.0.3.tgz",
+      "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/object.values": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.2.0.tgz",
+      "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/obuf": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/obuf/-/obuf-1.1.2.tgz",
+      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+      "dev": true
+    },
+    "node_modules/on-finished": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
+      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+      "dev": true,
+      "dependencies": {
+        "ee-first": "1.1.1"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/on-headers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/on-headers/-/on-headers-1.0.2.tgz",
+      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+      "dev": true,
+      "dependencies": {
+        "wrappy": "1"
+      }
+    },
+    "node_modules/onetime": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz",
+      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+      "dev": true,
+      "dependencies": {
+        "mimic-fn": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/open": {
+      "version": "8.4.2",
+      "resolved": "https://registry.npmmirror.com/open/-/open-8.4.2.tgz",
+      "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
+      "dev": true,
+      "dependencies": {
+        "define-lazy-prop": "^2.0.0",
+        "is-docker": "^2.1.1",
+        "is-wsl": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/opener": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmmirror.com/opener/-/opener-1.5.2.tgz",
+      "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+      "dev": true,
+      "bin": {
+        "opener": "bin/opener-bin.js"
+      }
+    },
+    "node_modules/optionator": {
+      "version": "0.9.4",
+      "resolved": "https://registry.npmmirror.com/optionator/-/optionator-0.9.4.tgz",
+      "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+      "dev": true,
+      "dependencies": {
+        "deep-is": "^0.1.3",
+        "fast-levenshtein": "^2.0.6",
+        "levn": "^0.4.1",
+        "prelude-ls": "^1.2.1",
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.5"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/ora": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz",
+      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
+      "dev": true,
+      "dependencies": {
+        "bl": "^4.1.0",
+        "chalk": "^4.1.0",
+        "cli-cursor": "^3.1.0",
+        "cli-spinners": "^2.5.0",
+        "is-interactive": "^1.0.0",
+        "is-unicode-supported": "^0.1.0",
+        "log-symbols": "^4.1.0",
+        "strip-ansi": "^6.0.0",
+        "wcwidth": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/ora/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmmirror.com/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==",
+      "dev": true
+    },
+    "node_modules/p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/p-limit": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "dev": true,
+      "dependencies": {
+        "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-locate": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-5.0.0.tgz",
+      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/p-retry": {
+      "version": "4.6.2",
+      "resolved": "https://registry.npmmirror.com/p-retry/-/p-retry-4.6.2.tgz",
+      "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/retry": "0.12.0",
+        "retry": "^0.13.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmmirror.com/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+      "dev": true
+    },
+    "node_modules/param-case": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/param-case/-/param-case-3.0.4.tgz",
+      "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
+      "dev": true,
+      "dependencies": {
+        "dot-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
+    "node_modules/parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "dependencies": {
+        "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/parse-asn1": {
+      "version": "5.1.7",
+      "resolved": "https://registry.npmmirror.com/parse-asn1/-/parse-asn1-5.1.7.tgz",
+      "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==",
+      "dev": true,
+      "dependencies": {
+        "asn1.js": "^4.10.1",
+        "browserify-aes": "^1.2.0",
+        "evp_bytestokey": "^1.0.3",
+        "hash-base": "~3.0",
+        "pbkdf2": "^3.1.2",
+        "safe-buffer": "^5.2.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/parse-json": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz",
+      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/code-frame": "^7.0.0",
+        "error-ex": "^1.3.1",
+        "json-parse-even-better-errors": "^2.3.0",
+        "lines-and-columns": "^1.1.6"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/parse5": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/parse5/-/parse5-5.1.1.tgz",
+      "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+      "dev": true
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+      "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+      "dev": true,
+      "dependencies": {
+        "parse5": "^6.0.1"
+      }
+    },
+    "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/parse5/-/parse5-6.0.1.tgz",
+      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+      "dev": true
+    },
+    "node_modules/parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/pascal-case": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/pascal-case/-/pascal-case-3.1.2.tgz",
+      "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
+      "dev": true,
+      "dependencies": {
+        "no-case": "^3.0.4",
+        "tslib": "^2.0.3"
+      }
+    },
+    "node_modules/path-browserify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz",
+      "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+      "dev": true
+    },
+    "node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-intersection": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/path-intersection/-/path-intersection-2.2.1.tgz",
+      "integrity": "sha512-9u8xvMcSfuOiStv9bPdnRJQhGQXLKurew94n4GPQCdH1nj9QKC9ObbNoIpiRq8skiOBxKkt277PgOoFgAt3/rA=="
+    },
+    "node_modules/path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/path-key": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/path-parse": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+      "dev": true
+    },
+    "node_modules/path-to-regexp": {
+      "version": "0.1.10",
+      "resolved": "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
+      "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
+      "dev": true
+    },
+    "node_modules/path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pathe": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz",
+      "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
+      "dev": true
+    },
+    "node_modules/pbkdf2": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/pbkdf2/-/pbkdf2-3.1.2.tgz",
+      "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+      "dev": true,
+      "dependencies": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+    },
+    "node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/pinia": {
+      "version": "2.2.8",
+      "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.2.8.tgz",
+      "integrity": "sha512-NRTYy2g+kju5tBRe0oNlriZIbMNvma8ZJrpHsp3qudyiMEA8jMmPPKQ2QMHg0Oc4BkUyQYWagACabrwriCK9HQ==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.6.3",
+        "vue-demi": "^0.14.10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.4.0",
+        "typescript": ">=4.4.4",
+        "vue": "^2.6.14 || ^3.5.11"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        },
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pinia-plugin-persist": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz",
+      "integrity": "sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==",
+      "dependencies": {
+        "vue-demi": "^0.12.1"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0",
+        "pinia": "^2.0.0",
+        "vue": "^2.0.0 || >=3.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pinia-plugin-persist/node_modules/vue-demi": {
+      "version": "0.12.5",
+      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.12.5.tgz",
+      "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/pkg-dir": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
+      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/pkg-dir/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/pkg-types": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.2.1.tgz",
+      "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==",
+      "dev": true,
+      "dependencies": {
+        "confbox": "^0.1.8",
+        "mlly": "^1.7.2",
+        "pathe": "^1.1.2"
+      }
+    },
+    "node_modules/pngjs": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
+      "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/portfinder": {
+      "version": "1.0.32",
+      "resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.32.tgz",
+      "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==",
+      "dev": true,
+      "dependencies": {
+        "async": "^2.6.4",
+        "debug": "^3.2.7",
+        "mkdirp": "^0.5.6"
+      },
+      "engines": {
+        "node": ">= 0.12.0"
+      }
+    },
+    "node_modules/portfinder/node_modules/async": {
+      "version": "2.6.4",
+      "resolved": "https://registry.npmmirror.com/async/-/async-2.6.4.tgz",
+      "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.14"
+      }
+    },
+    "node_modules/portfinder/node_modules/debug": {
+      "version": "3.2.7",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz",
+      "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+      "dev": true,
+      "dependencies": {
+        "ms": "^2.1.1"
+      }
+    },
+    "node_modules/possible-typed-array-names": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+      "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.4.49",
+      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz",
+      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/postcss-attribute-case-insensitive": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmmirror.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz",
+      "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-calc": {
+      "version": "8.2.4",
+      "resolved": "https://registry.npmmirror.com/postcss-calc/-/postcss-calc-8.2.4.tgz",
+      "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.9",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.2"
+      }
+    },
+    "node_modules/postcss-clamp": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz",
+      "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=7.6.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4.6"
+      }
+    },
+    "node_modules/postcss-color-functional-notation": {
+      "version": "4.2.4",
+      "resolved": "https://registry.npmmirror.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz",
+      "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-color-hex-alpha": {
+      "version": "8.0.4",
+      "resolved": "https://registry.npmmirror.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz",
+      "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/postcss-color-rebeccapurple": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz",
+      "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-colormin": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmmirror.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz",
+      "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "caniuse-api": "^3.0.0",
+        "colord": "^2.9.1",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-convert-values": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmmirror.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz",
+      "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-custom-media": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmmirror.com/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz",
+      "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/postcss-custom-properties": {
+      "version": "12.1.11",
+      "resolved": "https://registry.npmmirror.com/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz",
+      "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-custom-selectors": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmmirror.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz",
+      "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.4"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3"
+      }
+    },
+    "node_modules/postcss-dir-pseudo-class": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmmirror.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz",
+      "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-discard-comments": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz",
+      "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-discard-duplicates": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz",
+      "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-discard-empty": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz",
+      "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-discard-overridden": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz",
+      "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-double-position-gradients": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmmirror.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz",
+      "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-env-function": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmmirror.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz",
+      "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/postcss-focus-visible": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmmirror.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz",
+      "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.9"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/postcss-focus-within": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz",
+      "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.9"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/postcss-font-variant": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz",
+      "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==",
+      "dev": true,
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-gap-properties": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmmirror.com/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz",
+      "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==",
+      "dev": true,
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-html": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmmirror.com/postcss-html/-/postcss-html-1.7.0.tgz",
+      "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==",
+      "dev": true,
+      "dependencies": {
+        "htmlparser2": "^8.0.0",
+        "js-tokens": "^9.0.0",
+        "postcss": "^8.4.0",
+        "postcss-safe-parser": "^6.0.0"
+      },
+      "engines": {
+        "node": "^12 || >=14"
+      }
+    },
+    "node_modules/postcss-html/node_modules/js-tokens": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz",
+      "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+      "dev": true
+    },
+    "node_modules/postcss-image-set-function": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmmirror.com/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz",
+      "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-initial": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/postcss-initial/-/postcss-initial-4.0.1.tgz",
+      "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==",
+      "dev": true,
+      "peerDependencies": {
+        "postcss": "^8.0.0"
+      }
+    },
+    "node_modules/postcss-lab-function": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmmirror.com/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz",
+      "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-loader": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmmirror.com/postcss-loader/-/postcss-loader-6.2.1.tgz",
+      "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==",
+      "dev": true,
+      "dependencies": {
+        "cosmiconfig": "^7.0.0",
+        "klona": "^2.0.5",
+        "semver": "^7.3.5"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "postcss": "^7.0.0 || ^8.0.1",
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/postcss-loader/node_modules/cosmiconfig": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+      "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+      "dev": true,
+      "dependencies": {
+        "@types/parse-json": "^4.0.0",
+        "import-fresh": "^3.2.1",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0",
+        "yaml": "^1.10.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/postcss-logical": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmmirror.com/postcss-logical/-/postcss-logical-5.0.4.tgz",
+      "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==",
+      "dev": true,
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4"
+      }
+    },
+    "node_modules/postcss-media-minmax": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz",
+      "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-merge-longhand": {
+      "version": "5.1.7",
+      "resolved": "https://registry.npmmirror.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz",
+      "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0",
+        "stylehacks": "^5.1.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-merge-rules": {
+      "version": "5.1.4",
+      "resolved": "https://registry.npmmirror.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz",
+      "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "caniuse-api": "^3.0.0",
+        "cssnano-utils": "^3.1.0",
+        "postcss-selector-parser": "^6.0.5"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-minify-font-values": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz",
+      "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-minify-gradients": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz",
+      "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==",
+      "dev": true,
+      "dependencies": {
+        "colord": "^2.9.1",
+        "cssnano-utils": "^3.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-minify-params": {
+      "version": "5.1.4",
+      "resolved": "https://registry.npmmirror.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz",
+      "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "cssnano-utils": "^3.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-minify-selectors": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz",
+      "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.5"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-modules-extract-imports": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
+      "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-local-by-default": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz",
+      "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==",
+      "dev": true,
+      "dependencies": {
+        "icss-utils": "^5.0.0",
+        "postcss-selector-parser": "^7.0.0",
+        "postcss-value-parser": "^4.1.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
+      "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
+      "dev": true,
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-modules-scope": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+      "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^7.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
+      "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
+      "dev": true,
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-modules-values": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
+      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
+      "dev": true,
+      "dependencies": {
+        "icss-utils": "^5.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >= 14"
+      },
+      "peerDependencies": {
+        "postcss": "^8.1.0"
+      }
+    },
+    "node_modules/postcss-nesting": {
+      "version": "10.2.0",
+      "resolved": "https://registry.npmmirror.com/postcss-nesting/-/postcss-nesting-10.2.0.tgz",
+      "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/selector-specificity": "^2.0.0",
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-normalize-charset": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz",
+      "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==",
+      "dev": true,
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-display-values": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz",
+      "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-positions": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz",
+      "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-repeat-style": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz",
+      "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-string": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz",
+      "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-timing-functions": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz",
+      "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-unicode": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz",
+      "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-url": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz",
+      "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==",
+      "dev": true,
+      "dependencies": {
+        "normalize-url": "^6.0.1",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-normalize-whitespace": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz",
+      "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-opacity-percentage": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz",
+      "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "kofi",
+          "url": "https://ko-fi.com/mrcgrtz"
+        },
+        {
+          "type": "liberapay",
+          "url": "https://liberapay.com/mrcgrtz"
+        }
+      ],
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-ordered-values": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmmirror.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz",
+      "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==",
+      "dev": true,
+      "dependencies": {
+        "cssnano-utils": "^3.1.0",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-overflow-shorthand": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz",
+      "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-page-break": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz",
+      "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==",
+      "dev": true,
+      "peerDependencies": {
+        "postcss": "^8"
+      }
+    },
+    "node_modules/postcss-place": {
+      "version": "7.0.5",
+      "resolved": "https://registry.npmmirror.com/postcss-place/-/postcss-place-7.0.5.tgz",
+      "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-preset-env": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmmirror.com/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz",
+      "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==",
+      "dev": true,
+      "dependencies": {
+        "@csstools/postcss-cascade-layers": "^1.1.1",
+        "@csstools/postcss-color-function": "^1.1.1",
+        "@csstools/postcss-font-format-keywords": "^1.0.1",
+        "@csstools/postcss-hwb-function": "^1.0.2",
+        "@csstools/postcss-ic-unit": "^1.0.1",
+        "@csstools/postcss-is-pseudo-class": "^2.0.7",
+        "@csstools/postcss-nested-calc": "^1.0.0",
+        "@csstools/postcss-normalize-display-values": "^1.0.1",
+        "@csstools/postcss-oklab-function": "^1.1.1",
+        "@csstools/postcss-progressive-custom-properties": "^1.3.0",
+        "@csstools/postcss-stepped-value-functions": "^1.0.1",
+        "@csstools/postcss-text-decoration-shorthand": "^1.0.0",
+        "@csstools/postcss-trigonometric-functions": "^1.0.2",
+        "@csstools/postcss-unset-value": "^1.0.2",
+        "autoprefixer": "^10.4.13",
+        "browserslist": "^4.21.4",
+        "css-blank-pseudo": "^3.0.3",
+        "css-has-pseudo": "^3.0.4",
+        "css-prefers-color-scheme": "^6.0.3",
+        "cssdb": "^7.1.0",
+        "postcss-attribute-case-insensitive": "^5.0.2",
+        "postcss-clamp": "^4.1.0",
+        "postcss-color-functional-notation": "^4.2.4",
+        "postcss-color-hex-alpha": "^8.0.4",
+        "postcss-color-rebeccapurple": "^7.1.1",
+        "postcss-custom-media": "^8.0.2",
+        "postcss-custom-properties": "^12.1.10",
+        "postcss-custom-selectors": "^6.0.3",
+        "postcss-dir-pseudo-class": "^6.0.5",
+        "postcss-double-position-gradients": "^3.1.2",
+        "postcss-env-function": "^4.0.6",
+        "postcss-focus-visible": "^6.0.4",
+        "postcss-focus-within": "^5.0.4",
+        "postcss-font-variant": "^5.0.0",
+        "postcss-gap-properties": "^3.0.5",
+        "postcss-image-set-function": "^4.0.7",
+        "postcss-initial": "^4.0.1",
+        "postcss-lab-function": "^4.2.1",
+        "postcss-logical": "^5.0.4",
+        "postcss-media-minmax": "^5.0.0",
+        "postcss-nesting": "^10.2.0",
+        "postcss-opacity-percentage": "^1.1.2",
+        "postcss-overflow-shorthand": "^3.0.4",
+        "postcss-page-break": "^3.0.4",
+        "postcss-place": "^7.0.5",
+        "postcss-pseudo-class-any-link": "^7.1.6",
+        "postcss-replace-overflow-wrap": "^4.0.0",
+        "postcss-selector-not": "^6.0.1",
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-pseudo-class-any-link": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmmirror.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz",
+      "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-reduce-initial": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmmirror.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz",
+      "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "caniuse-api": "^3.0.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-reduce-transforms": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz",
+      "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-replace-overflow-wrap": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz",
+      "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==",
+      "dev": true,
+      "peerDependencies": {
+        "postcss": "^8.0.3"
+      }
+    },
+    "node_modules/postcss-safe-parser": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
+      "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/postcss/"
+      },
+      "peerDependencies": {
+        "postcss": "^8.3.3"
+      }
+    },
+    "node_modules/postcss-scss": {
+      "version": "4.0.9",
+      "resolved": "https://registry.npmmirror.com/postcss-scss/-/postcss-scss-4.0.9.tgz",
+      "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss-scss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "engines": {
+        "node": ">=12.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4.29"
+      }
+    },
+    "node_modules/postcss-selector-not": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz",
+      "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.10"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >=16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/csstools"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2"
+      }
+    },
+    "node_modules/postcss-selector-parser": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+      "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+      "dev": true,
+      "dependencies": {
+        "cssesc": "^3.0.0",
+        "util-deprecate": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/postcss-svgo": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz",
+      "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-value-parser": "^4.2.0",
+        "svgo": "^2.7.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-unique-selectors": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz",
+      "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==",
+      "dev": true,
+      "dependencies": {
+        "postcss-selector-parser": "^6.0.5"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/postcss-value-parser": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
+      "dev": true
+    },
+    "node_modules/preact": {
+      "version": "10.25.1",
+      "resolved": "https://registry.npmmirror.com/preact/-/preact-10.25.1.tgz",
+      "integrity": "sha512-frxeZV2vhQSohQwJ7FvlqC40ze89+8friponWUFeVEkaCfhC6Eu4V0iND5C9CXz8JLndV07QRDeXzH1+Anz5Og==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/preact"
+      }
+    },
+    "node_modules/prelude-ls": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz",
+      "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/prettier": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmmirror.com/prettier/-/prettier-2.8.1.tgz",
+      "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==",
+      "dev": true,
+      "bin": {
+        "prettier": "bin-prettier.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "url": "https://github.com/prettier/prettier?sponsor=1"
+      }
+    },
+    "node_modules/prettier-linter-helpers": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+      "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+      "dev": true,
+      "dependencies": {
+        "fast-diff": "^1.1.2"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/pretty-error": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/pretty-error/-/pretty-error-4.0.0.tgz",
+      "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==",
+      "dev": true,
+      "dependencies": {
+        "lodash": "^4.17.20",
+        "renderkid": "^3.0.0"
+      }
+    },
+    "node_modules/print-js": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/print-js/-/print-js-1.6.0.tgz",
+      "integrity": "sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg=="
+    },
+    "node_modules/prismjs": {
+      "version": "1.29.0",
+      "resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.29.0.tgz",
+      "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
+      "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
+    "node_modules/process-nextick-args": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+      "dev": true
+    },
+    "node_modules/progress-webpack-plugin": {
+      "version": "1.0.16",
+      "resolved": "https://registry.npmmirror.com/progress-webpack-plugin/-/progress-webpack-plugin-1.0.16.tgz",
+      "integrity": "sha512-sdiHuuKOzELcBANHfrupYo+r99iPRyOnw15qX+rNlVUqXGfjXdH4IgxriKwG1kNJwVswKQHMdj1hYZMcb9jFaA==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^2.1.0",
+        "figures": "^2.0.0",
+        "log-update": "^2.3.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "peerDependencies": {
+        "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
+      }
+    },
+    "node_modules/progress-webpack-plugin/node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/progress-webpack-plugin/node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/progress-webpack-plugin/node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/progress-webpack-plugin/node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+      "dev": true
+    },
+    "node_modules/progress-webpack-plugin/node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/progress-webpack-plugin/node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/progress-webpack-plugin/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/proxy-addr": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmmirror.com/proxy-addr/-/proxy-addr-2.0.7.tgz",
+      "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+      "dev": true,
+      "dependencies": {
+        "forwarded": "0.2.0",
+        "ipaddr.js": "1.9.1"
+      },
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/proxy-addr/node_modules/ipaddr.js": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+      "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
+    "node_modules/pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==",
+      "dev": true
+    },
+    "node_modules/public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "dependencies": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "node_modules/public-encrypt/node_modules/bn.js": {
+      "version": "4.12.1",
+      "resolved": "https://registry.npmmirror.com/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
+      "dev": true
+    },
+    "node_modules/pump": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.2.tgz",
+      "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
+      "dev": true,
+      "dependencies": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "node_modules/punycode": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qrcode": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.0.tgz",
+      "integrity": "sha512-9MgRpgVc+/+47dFvQeD6U2s0Z92EsKzcHogtum4QB+UNd025WOJSHvn/hjk9xmzj7Stj95CyUAs31mrjxliEsQ==",
+      "dependencies": {
+        "dijkstrajs": "^1.0.1",
+        "encode-utf8": "^1.0.3",
+        "pngjs": "^5.0.0",
+        "yargs": "^15.3.1"
+      },
+      "bin": {
+        "qrcode": "bin/qrcode"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/qrcode/node_modules/cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      }
+    },
+    "node_modules/qrcode/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/qrcode/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/qrcode/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/qrcode/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/qrcode/node_modules/wrap-ansi": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/qrcode/node_modules/y18n": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+    },
+    "node_modules/qrcode/node_modules/yargs": {
+      "version": "15.4.1",
+      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
+      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "dependencies": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^18.1.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/qrcode/node_modules/yargs-parser": {
+      "version": "18.1.3",
+      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
+      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/qs": {
+      "version": "6.13.1",
+      "resolved": "https://registry.npmmirror.com/qs/-/qs-6.13.1.tgz",
+      "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==",
+      "dev": true,
+      "dependencies": {
+        "side-channel": "^1.0.6"
+      },
+      "engines": {
+        "node": ">=0.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmmirror.com/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4.x"
+      }
+    },
+    "node_modules/queue-microtask": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
+      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dependencies": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "dependencies": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "node_modules/range-parser": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
+      "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/raw-body": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.2.tgz",
+      "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+      "dev": true,
+      "dependencies": {
+        "bytes": "3.1.2",
+        "http-errors": "2.0.0",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/read-pkg": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmmirror.com/read-pkg/-/read-pkg-5.2.0.tgz",
+      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+      "dev": true,
+      "dependencies": {
+        "@types/normalize-package-data": "^2.4.0",
+        "normalize-package-data": "^2.5.0",
+        "parse-json": "^5.0.0",
+        "type-fest": "^0.6.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+      "dev": true,
+      "dependencies": {
+        "find-up": "^4.1.0",
+        "read-pkg": "^5.2.0",
+        "type-fest": "^0.8.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg-up/node_modules/type-fest": {
+      "version": "0.8.1",
+      "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.8.1.tgz",
+      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/read-pkg/node_modules/type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/readable-stream": {
+      "version": "4.5.2",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-4.5.2.tgz",
+      "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
+      "dev": true,
+      "dependencies": {
+        "abort-controller": "^3.0.0",
+        "buffer": "^6.0.3",
+        "events": "^3.3.0",
+        "process": "^0.11.10",
+        "string_decoder": "^1.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
+    },
+    "node_modules/readdirp": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+      "dev": true,
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/reflect.getprototypeof": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.7.tgz",
+      "integrity": "sha512-bMvFGIUKlc/eSfXNX+aZ+EL95/EgZzuwA0OBPTbZZDEJw/0AkentjMuM1oiRfwHrshqk4RzdgiTg5CcDalXN5g==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.5",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.4",
+        "gopd": "^1.0.1",
+        "which-builtin-type": "^1.1.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/regenerate": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/regenerate/-/regenerate-1.4.2.tgz",
+      "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+      "dev": true
+    },
+    "node_modules/regenerate-unicode-properties": {
+      "version": "10.2.0",
+      "resolved": "https://registry.npmmirror.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz",
+      "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==",
+      "dev": true,
+      "dependencies": {
+        "regenerate": "^1.4.2"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
+    "node_modules/regenerator-transform": {
+      "version": "0.15.2",
+      "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz",
+      "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==",
+      "dev": true,
+      "dependencies": {
+        "@babel/runtime": "^7.8.4"
+      }
+    },
+    "node_modules/regexp.prototype.flags": {
+      "version": "1.5.3",
+      "resolved": "https://registry.npmmirror.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
+      "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-errors": "^1.3.0",
+        "set-function-name": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/regexpu-core": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-6.2.0.tgz",
+      "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==",
+      "dev": true,
+      "dependencies": {
+        "regenerate": "^1.4.2",
+        "regenerate-unicode-properties": "^10.2.0",
+        "regjsgen": "^0.8.0",
+        "regjsparser": "^0.12.0",
+        "unicode-match-property-ecmascript": "^2.0.0",
+        "unicode-match-property-value-ecmascript": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/regjsgen": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmmirror.com/regjsgen/-/regjsgen-0.8.0.tgz",
+      "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==",
+      "dev": true
+    },
+    "node_modules/regjsparser": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.12.0.tgz",
+      "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
+      "dev": true,
+      "dependencies": {
+        "jsesc": "~3.0.2"
+      },
+      "bin": {
+        "regjsparser": "bin/parser"
+      }
+    },
+    "node_modules/relateurl": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmmirror.com/relateurl/-/relateurl-0.2.7.tgz",
+      "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
+    "node_modules/renderkid": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/renderkid/-/renderkid-3.0.0.tgz",
+      "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==",
+      "dev": true,
+      "dependencies": {
+        "css-select": "^4.1.3",
+        "dom-converter": "^0.2.0",
+        "htmlparser2": "^6.1.0",
+        "lodash": "^4.17.21",
+        "strip-ansi": "^6.0.1"
+      }
+    },
+    "node_modules/renderkid/node_modules/dom-serializer": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-1.4.1.tgz",
+      "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.2.0",
+        "entities": "^2.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+      }
+    },
+    "node_modules/renderkid/node_modules/domhandler": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/domhandler/-/domhandler-4.3.1.tgz",
+      "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+      "dev": true,
+      "dependencies": {
+        "domelementtype": "^2.2.0"
+      },
+      "engines": {
+        "node": ">= 4"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domhandler?sponsor=1"
+      }
+    },
+    "node_modules/renderkid/node_modules/domutils": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmmirror.com/domutils/-/domutils-2.8.0.tgz",
+      "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+      "dev": true,
+      "dependencies": {
+        "dom-serializer": "^1.0.1",
+        "domelementtype": "^2.2.0",
+        "domhandler": "^4.2.0"
+      },
+      "funding": {
+        "url": "https://github.com/fb55/domutils?sponsor=1"
+      }
+    },
+    "node_modules/renderkid/node_modules/entities": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/entities/-/entities-2.2.0.tgz",
+      "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/fb55/entities?sponsor=1"
+      }
+    },
+    "node_modules/renderkid/node_modules/htmlparser2": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz",
+      "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+      "dev": true,
+      "funding": [
+        "https://github.com/fb55/htmlparser2?sponsor=1",
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/fb55"
+        }
+      ],
+      "dependencies": {
+        "domelementtype": "^2.0.1",
+        "domhandler": "^4.0.0",
+        "domutils": "^2.5.2",
+        "entities": "^2.0.0"
+      }
+    },
+    "node_modules/require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+    },
+    "node_modules/requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+      "dev": true
+    },
+    "node_modules/resolve": {
+      "version": "1.22.8",
+      "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz",
+      "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+      "dev": true,
+      "dependencies": {
+        "is-core-module": "^2.13.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/resolve-from": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/resolve-pkg-maps": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+      "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+      }
+    },
+    "node_modules/restore-cursor": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz",
+      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+      "dev": true,
+      "dependencies": {
+        "onetime": "^5.1.0",
+        "signal-exit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/retry": {
+      "version": "0.13.1",
+      "resolved": "https://registry.npmmirror.com/retry/-/retry-0.13.1.tgz",
+      "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
+    },
+    "node_modules/reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true,
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/rimraf": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
+      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "deprecated": "Rimraf versions prior to v4 are no longer supported",
+      "dev": true,
+      "dependencies": {
+        "glob": "^7.1.3"
+      },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "dependencies": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "node_modules/run-parallel": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz",
+      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
+        "queue-microtask": "^1.2.2"
+      }
+    },
+    "node_modules/safe-array-concat": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+      "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "get-intrinsic": "^1.2.4",
+        "has-symbols": "^1.0.3",
+        "isarray": "^2.0.5"
+      },
+      "engines": {
+        "node": ">=0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/safe-buffer": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
+    },
+    "node_modules/safe-regex-test": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+      "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.6",
+        "es-errors": "^1.3.0",
+        "is-regex": "^1.1.4"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "node_modules/sass": {
+      "version": "1.82.0",
+      "resolved": "https://registry.npmmirror.com/sass/-/sass-1.82.0.tgz",
+      "integrity": "sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q==",
+      "dev": true,
+      "dependencies": {
+        "chokidar": "^4.0.0",
+        "immutable": "^5.0.2",
+        "source-map-js": ">=0.6.2 <2.0.0"
+      },
+      "bin": {
+        "sass": "sass.js"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "optionalDependencies": {
+        "@parcel/watcher": "^2.4.1"
+      }
+    },
+    "node_modules/sass-loader": {
+      "version": "12.6.0",
+      "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-12.6.0.tgz",
+      "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==",
+      "dev": true,
+      "dependencies": {
+        "klona": "^2.0.4",
+        "neo-async": "^2.6.2"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "fibers": ">= 3.1.0",
+        "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
+        "sass": "^1.3.0",
+        "sass-embedded": "*",
+        "webpack": "^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "fibers": {
+          "optional": true
+        },
+        "node-sass": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/sass/node_modules/chokidar": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.1.tgz",
+      "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
+      "dev": true,
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/sass/node_modules/readdirp": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.0.2.tgz",
+      "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/sax": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
+      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
+    },
+    "node_modules/saxen": {
+      "version": "8.1.2",
+      "resolved": "https://registry.npmmirror.com/saxen/-/saxen-8.1.2.tgz",
+      "integrity": "sha512-xUOiiFbc3Ow7p8KMxwsGICPx46ZQvy3+qfNVhrkwfz3Vvq45eGt98Ft5IQaA1R/7Tb5B5MKh9fUR9x3c3nDTxw==",
+      "dev": true
+    },
+    "node_modules/schema-utils": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.1.tgz",
+      "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.5",
+        "ajv": "^6.12.4",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 8.9.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/scroll-into-view-if-needed": {
+      "version": "2.2.31",
+      "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
+      "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
+      "dependencies": {
+        "compute-scroll-into-view": "^1.0.20"
+      }
+    },
+    "node_modules/scroll-tabs": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/scroll-tabs/-/scroll-tabs-1.0.1.tgz",
+      "integrity": "sha512-W4xjEwNS4QAyQnaJ450vQTcKpbnalBAfsTDV926WrxEMOqjyj2To8uv2d0Cp0oxMdk5TkygtzXmctPNc2zgBcg==",
+      "dev": true,
+      "dependencies": {
+        "min-dash": "^3.1.0",
+        "min-dom": "^3.1.0",
+        "mitt": "^1.1.3"
+      }
+    },
+    "node_modules/scroll-tabs/node_modules/min-dash": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmmirror.com/min-dash/-/min-dash-3.8.1.tgz",
+      "integrity": "sha512-evumdlmIlg9mbRVPbC4F5FuRhNmcMS5pvuBUbqb1G9v09Ro0ImPEgz5n3khir83lFok1inKqVDjnKEg3GpDxQg==",
+      "dev": true
+    },
+    "node_modules/scule": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
+      "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
+      "dev": true
+    },
+    "node_modules/select": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz",
+      "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
+    },
+    "node_modules/select-hose": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz",
+      "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+      "dev": true
+    },
+    "node_modules/selection-update": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmmirror.com/selection-update/-/selection-update-0.1.2.tgz",
+      "integrity": "sha512-4jzoJNh7VT2s2tvm/kUSskSw7pD0BVcrrGccbfOMK+3AXLBPz6nIy1yo+pbXgvNoTNII96Pq92+sAY+rF0LUAA==",
+      "dev": true
+    },
+    "node_modules/selfsigned": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmmirror.com/selfsigned/-/selfsigned-2.4.1.tgz",
+      "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==",
+      "dev": true,
+      "dependencies": {
+        "@types/node-forge": "^1.3.0",
+        "node-forge": "^1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/semver": {
+      "version": "7.6.3",
+      "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz",
+      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+      "dev": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/send": {
+      "version": "0.19.0",
+      "resolved": "https://registry.npmmirror.com/send/-/send-0.19.0.tgz",
+      "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+      "dev": true,
+      "dependencies": {
+        "debug": "2.6.9",
+        "depd": "2.0.0",
+        "destroy": "1.2.0",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "2.0.0",
+        "mime": "1.6.0",
+        "ms": "2.1.3",
+        "on-finished": "2.4.1",
+        "range-parser": "~1.2.1",
+        "statuses": "2.0.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/send/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/send/node_modules/debug/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/send/node_modules/encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/serialize-javascript": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+      "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+      "dependencies": {
+        "randombytes": "^2.1.0"
+      }
+    },
+    "node_modules/serve-index": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/serve-index/-/serve-index-1.9.1.tgz",
+      "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+      "dev": true,
+      "dependencies": {
+        "accepts": "~1.3.4",
+        "batch": "0.6.1",
+        "debug": "2.6.9",
+        "escape-html": "~1.0.3",
+        "http-errors": "~1.6.2",
+        "mime-types": "~2.1.17",
+        "parseurl": "~1.3.2"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/serve-index/node_modules/debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "dependencies": {
+        "ms": "2.0.0"
+      }
+    },
+    "node_modules/serve-index/node_modules/depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/serve-index/node_modules/http-errors": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz",
+      "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+      "dev": true,
+      "dependencies": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.0",
+        "statuses": ">= 1.4.0 < 2"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/serve-index/node_modules/inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+      "dev": true
+    },
+    "node_modules/serve-index/node_modules/ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+      "dev": true
+    },
+    "node_modules/serve-index/node_modules/setprototypeof": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+      "dev": true
+    },
+    "node_modules/serve-index/node_modules/statuses": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz",
+      "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/serve-static": {
+      "version": "1.16.2",
+      "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.16.2.tgz",
+      "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+      "dev": true,
+      "dependencies": {
+        "encodeurl": "~2.0.0",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.19.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+    },
+    "node_modules/set-function-length": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
+      "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+      "dev": true,
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2",
+        "get-intrinsic": "^1.2.4",
+        "gopd": "^1.0.1",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/set-function-name": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/set-function-name/-/set-function-name-2.0.2.tgz",
+      "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+      "dev": true,
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
+        "functions-have-names": "^1.2.3",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmmirror.com/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+      "dev": true
+    },
+    "node_modules/setprototypeof": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
+      "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+      "dev": true
+    },
+    "node_modules/sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmmirror.com/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "bin": {
+        "sha.js": "bin.js"
+      }
+    },
+    "node_modules/shallow-clone": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/shallow-clone/-/shallow-clone-3.0.1.tgz",
+      "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+      "dev": true,
+      "dependencies": {
+        "kind-of": "^6.0.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-command": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shebang-regex": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/shell-quote": {
+      "version": "1.8.2",
+      "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.2.tgz",
+      "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/side-channel": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.6.tgz",
+      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.4",
+        "object-inspect": "^1.13.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/signal-exit": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
+      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+      "dev": true
+    },
+    "node_modules/sirv": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/sirv/-/sirv-2.0.4.tgz",
+      "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==",
+      "dev": true,
+      "dependencies": {
+        "@polka/url": "^1.0.0-next.24",
+        "mrmime": "^2.0.0",
+        "totalist": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/slate": {
+      "version": "0.72.8",
+      "resolved": "https://registry.npmmirror.com/slate/-/slate-0.72.8.tgz",
+      "integrity": "sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==",
+      "dependencies": {
+        "immer": "^9.0.6",
+        "is-plain-object": "^5.0.0",
+        "tiny-warning": "^1.0.3"
+      }
+    },
+    "node_modules/slate-history": {
+      "version": "0.66.0",
+      "resolved": "https://registry.npmmirror.com/slate-history/-/slate-history-0.66.0.tgz",
+      "integrity": "sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==",
+      "dependencies": {
+        "is-plain-object": "^5.0.0"
+      },
+      "peerDependencies": {
+        "slate": ">=0.65.3"
+      }
+    },
+    "node_modules/smob": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmmirror.com/smob/-/smob-1.5.0.tgz",
+      "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig=="
+    },
+    "node_modules/snabbdom": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmmirror.com/snabbdom/-/snabbdom-3.6.2.tgz",
+      "integrity": "sha512-ig5qOnCDbugFntKi6c7Xlib8bA6xiJVk8O+WdFrV3wxbMqeHO0hXFQC4nAhPVWfZfi8255lcZkNhtIBINCc4+Q==",
+      "engines": {
+        "node": ">=12.17.0"
+      }
+    },
+    "node_modules/sockjs": {
+      "version": "0.3.24",
+      "resolved": "https://registry.npmmirror.com/sockjs/-/sockjs-0.3.24.tgz",
+      "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==",
+      "dev": true,
+      "dependencies": {
+        "faye-websocket": "^0.11.3",
+        "uuid": "^8.3.2",
+        "websocket-driver": "^0.7.4"
+      }
+    },
+    "node_modules/source-map": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/source-map-support": {
+      "version": "0.5.21",
+      "resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
+      "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "dependencies": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      }
+    },
+    "node_modules/spdx-correct": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.2.0.tgz",
+      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+      "dev": true,
+      "dependencies": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-exceptions": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+      "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+      "dev": true
+    },
+    "node_modules/spdx-expression-parse": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+      "dev": true,
+      "dependencies": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "node_modules/spdx-license-ids": {
+      "version": "3.0.20",
+      "resolved": "https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz",
+      "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==",
+      "dev": true
+    },
+    "node_modules/spdy": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/spdy/-/spdy-4.0.2.tgz",
+      "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.1.0",
+        "handle-thing": "^2.0.0",
+        "http-deceiver": "^1.2.7",
+        "select-hose": "^2.0.0",
+        "spdy-transport": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/spdy-transport": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/spdy-transport/-/spdy-transport-3.0.0.tgz",
+      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.1.0",
+        "detect-node": "^2.0.4",
+        "hpack.js": "^2.1.6",
+        "obuf": "^1.1.2",
+        "readable-stream": "^3.0.6",
+        "wbuf": "^1.7.3"
+      }
+    },
+    "node_modules/spdy-transport/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/ssr-window": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/ssr-window/-/ssr-window-3.0.0.tgz",
+      "integrity": "sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA=="
+    },
+    "node_modules/ssri": {
+      "version": "8.0.1",
+      "resolved": "https://registry.npmmirror.com/ssri/-/ssri-8.0.1.tgz",
+      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
+      "dev": true,
+      "dependencies": {
+        "minipass": "^3.1.1"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/stable": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmmirror.com/stable/-/stable-0.1.8.tgz",
+      "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
+    },
+    "node_modules/stable-hash": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmmirror.com/stable-hash/-/stable-hash-0.0.4.tgz",
+      "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==",
+      "dev": true
+    },
+    "node_modules/stackframe": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmmirror.com/stackframe/-/stackframe-1.3.4.tgz",
+      "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
+      "dev": true
+    },
+    "node_modules/statuses": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz",
+      "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/stream-browserify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/stream-browserify/-/stream-browserify-3.0.0.tgz",
+      "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "~2.0.4",
+        "readable-stream": "^3.5.0"
+      }
+    },
+    "node_modules/stream-browserify/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/stream-http": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmmirror.com/stream-http/-/stream-http-3.2.0.tgz",
+      "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==",
+      "dev": true,
+      "dependencies": {
+        "builtin-status-codes": "^3.0.0",
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "xtend": "^4.0.2"
+      }
+    },
+    "node_modules/stream-http/node_modules/readable-stream": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
+      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "string_decoder": "^1.1.1",
+        "util-deprecate": "^1.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/string_decoder": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
+      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+      "dev": true,
+      "dependencies": {
+        "safe-buffer": "~5.2.0"
+      }
+    },
+    "node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/string.prototype.trim": {
+      "version": "1.2.9",
+      "resolved": "https://registry.npmmirror.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+      "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-abstract": "^1.23.0",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimend": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+      "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/string.prototype.trimstart": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+      "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
+      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-bom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-3.0.0.tgz",
+      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/strip-indent": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/strip-indent/-/strip-indent-2.0.0.tgz",
+      "integrity": "sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/strip-json-comments": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+      "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/strip-literal": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-2.1.1.tgz",
+      "integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==",
+      "dev": true,
+      "dependencies": {
+        "js-tokens": "^9.0.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/strip-literal/node_modules/js-tokens": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz",
+      "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+      "dev": true
+    },
+    "node_modules/stylehacks": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz",
+      "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==",
+      "dev": true,
+      "dependencies": {
+        "browserslist": "^4.21.4",
+        "postcss-selector-parser": "^6.0.4"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/svg-tags": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/svg-tags/-/svg-tags-1.0.0.tgz",
+      "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
+      "dev": true
+    },
+    "node_modules/svg.js": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmmirror.com/svg.js/-/svg.js-2.7.1.tgz",
+      "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
+    },
+    "node_modules/svgo": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmmirror.com/svgo/-/svgo-2.8.0.tgz",
+      "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==",
+      "dev": true,
+      "dependencies": {
+        "@trysound/sax": "0.2.0",
+        "commander": "^7.2.0",
+        "css-select": "^4.1.3",
+        "css-tree": "^1.1.3",
+        "csso": "^4.2.0",
+        "picocolors": "^1.0.0",
+        "stable": "^0.1.8"
+      },
+      "bin": {
+        "svgo": "bin/svgo"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/svgo/node_modules/commander": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz",
+      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/tapable": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz",
+      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/terser": {
+      "version": "5.36.0",
+      "resolved": "https://registry.npmmirror.com/terser/-/terser-5.36.0.tgz",
+      "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==",
+      "dependencies": {
+        "@jridgewell/source-map": "^0.3.3",
+        "acorn": "^8.8.2",
+        "commander": "^2.20.0",
+        "source-map-support": "~0.5.20"
+      },
+      "bin": {
+        "terser": "bin/terser"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/terser-webpack-plugin": {
+      "version": "5.3.10",
+      "resolved": "https://registry.npmmirror.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
+      "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.20",
+        "jest-worker": "^27.4.5",
+        "schema-utils": "^3.1.1",
+        "serialize-javascript": "^6.0.1",
+        "terser": "^5.26.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^5.1.0"
+      },
+      "peerDependenciesMeta": {
+        "@swc/core": {
+          "optional": true
+        },
+        "esbuild": {
+          "optional": true
+        },
+        "uglify-js": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/terser/node_modules/commander": {
+      "version": "2.20.3",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+    },
+    "node_modules/text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmmirror.com/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+      "dev": true
+    },
+    "node_modules/thenify": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz",
+      "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+      "dev": true,
+      "dependencies": {
+        "any-promise": "^1.0.0"
+      }
+    },
+    "node_modules/thenify-all": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz",
+      "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+      "dev": true,
+      "dependencies": {
+        "thenify": ">= 3.1.0 < 4"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/thread-loader": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/thread-loader/-/thread-loader-3.0.4.tgz",
+      "integrity": "sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==",
+      "dev": true,
+      "dependencies": {
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^4.1.0",
+        "loader-utils": "^2.0.0",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^3.0.0"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^4.27.0 || ^5.0.0"
+      }
+    },
+    "node_modules/thread-loader/node_modules/loader-utils": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+      "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+      "dev": true,
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      }
+    },
+    "node_modules/thread-loader/node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/thunky": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/thunky/-/thunky-1.1.0.tgz",
+      "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+      "dev": true
+    },
+    "node_modules/timers-browserify": {
+      "version": "2.0.12",
+      "resolved": "https://registry.npmmirror.com/timers-browserify/-/timers-browserify-2.0.12.tgz",
+      "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
+      "dev": true,
+      "dependencies": {
+        "setimmediate": "^1.0.4"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/tiny-emitter": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+      "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
+    },
+    "node_modules/tiny-svg": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmmirror.com/tiny-svg/-/tiny-svg-2.2.4.tgz",
+      "integrity": "sha512-NOi39lBknf4UdDEahNkbEAJnzhu1ZcN2j75IS2vLRmIhsfxdZpTChfLKBcN1ShplVmPIXJAIafk6YY5/Aa80lQ=="
+    },
+    "node_modules/tiny-warning": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/tiny-warning/-/tiny-warning-1.0.3.tgz",
+      "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+    },
+    "node_modules/tinyglobby": {
+      "version": "0.2.10",
+      "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.10.tgz",
+      "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==",
+      "dev": true,
+      "dependencies": {
+        "fdir": "^6.4.2",
+        "picomatch": "^4.0.2"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      }
+    },
+    "node_modules/tinyglobby/node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/to-regex-range": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+      "dev": true,
+      "dependencies": {
+        "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
+      }
+    },
+    "node_modules/toidentifier": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
+      "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.6"
+      }
+    },
+    "node_modules/totalist": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz",
+      "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/tr46": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+      "dev": true
+    },
+    "node_modules/ts-loader": {
+      "version": "9.5.1",
+      "resolved": "https://registry.npmmirror.com/ts-loader/-/ts-loader-9.5.1.tgz",
+      "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^4.1.0",
+        "enhanced-resolve": "^5.0.0",
+        "micromatch": "^4.0.0",
+        "semver": "^7.3.4",
+        "source-map": "^0.7.4"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "peerDependencies": {
+        "typescript": "*",
+        "webpack": "^5.0.0"
+      }
+    },
+    "node_modules/ts-loader/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/ts-loader/node_modules/source-map": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.7.4.tgz",
+      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/tsconfig-paths": {
+      "version": "3.15.0",
+      "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+      "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json5": "^0.0.29",
+        "json5": "^1.0.2",
+        "minimist": "^1.2.6",
+        "strip-bom": "^3.0.0"
+      }
+    },
+    "node_modules/tsconfig-paths/node_modules/json5": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
+      "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+      "dev": true,
+      "dependencies": {
+        "minimist": "^1.2.0"
+      },
+      "bin": {
+        "json5": "lib/cli.js"
+      }
+    },
+    "node_modules/tslib": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
+    },
+    "node_modules/tsutils": {
+      "version": "3.21.0",
+      "resolved": "https://registry.npmmirror.com/tsutils/-/tsutils-3.21.0.tgz",
+      "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+      "dev": true,
+      "dependencies": {
+        "tslib": "^1.8.1"
+      },
+      "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"
+      }
+    },
+    "node_modules/tsutils/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+      "dev": true
+    },
+    "node_modules/tty-browserify": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmmirror.com/tty-browserify/-/tty-browserify-0.0.1.tgz",
+      "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==",
+      "dev": true
+    },
+    "node_modules/type": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmmirror.com/type/-/type-2.7.3.tgz",
+      "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
+    },
+    "node_modules/type-check": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/type-check/-/type-check-0.4.0.tgz",
+      "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+      "dev": true,
+      "dependencies": {
+        "prelude-ls": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
+      }
+    },
+    "node_modules/type-fest": {
+      "version": "4.30.0",
+      "resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-4.30.0.tgz",
+      "integrity": "sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==",
+      "dev": true,
+      "engines": {
+        "node": ">=16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "dependencies": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/typed-array-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "es-errors": "^1.3.0",
+        "is-typed-array": "^1.1.13"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/typed-array-byte-length": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+      "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typed-array-byte-offset": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz",
+      "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==",
+      "dev": true,
+      "dependencies": {
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.7",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13",
+        "reflect.getprototypeof": "^1.0.6"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typed-array-length": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.7.tgz",
+      "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "is-typed-array": "^1.1.13",
+        "possible-typed-array-names": "^1.0.0",
+        "reflect.getprototypeof": "^1.0.6"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "4.9.5",
+      "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
+    "node_modules/ufo": {
+      "version": "1.5.4",
+      "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.5.4.tgz",
+      "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
+      "dev": true
+    },
+    "node_modules/unbox-primitive": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "has-bigints": "^1.0.2",
+        "has-symbols": "^1.0.3",
+        "which-boxed-primitive": "^1.0.2"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/undici-types": {
+      "version": "5.26.5",
+      "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz",
+      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
+    },
+    "node_modules/unicode-canonical-property-names-ecmascript": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz",
+      "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-match-property-ecmascript": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+      "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+      "dev": true,
+      "dependencies": {
+        "unicode-canonical-property-names-ecmascript": "^2.0.0",
+        "unicode-property-aliases-ecmascript": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-match-property-value-ecmascript": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz",
+      "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unicode-property-aliases-ecmascript": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+      "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/unimport": {
+      "version": "3.14.3",
+      "resolved": "https://registry.npmmirror.com/unimport/-/unimport-3.14.3.tgz",
+      "integrity": "sha512-yEJps4GW7jBdoQlxEV0ElBCJsJmH8FdZtk4oog0y++8hgLh0dGnDpE4oaTc0Lfx4N5rRJiGFUWHrBqC8CyUBmQ==",
+      "dev": true,
+      "dependencies": {
+        "@rollup/pluginutils": "^5.1.3",
+        "acorn": "^8.14.0",
+        "escape-string-regexp": "^5.0.0",
+        "estree-walker": "^3.0.3",
+        "local-pkg": "^0.5.1",
+        "magic-string": "^0.30.14",
+        "mlly": "^1.7.3",
+        "pathe": "^1.1.2",
+        "picomatch": "^4.0.2",
+        "pkg-types": "^1.2.1",
+        "scule": "^1.3.0",
+        "strip-literal": "^2.1.1",
+        "tinyglobby": "^0.2.10",
+        "unplugin": "^1.16.0"
+      }
+    },
+    "node_modules/unimport/node_modules/escape-string-regexp": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+      "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/unimport/node_modules/estree-walker": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz",
+      "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "^1.0.0"
+      }
+    },
+    "node_modules/unimport/node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/universalify": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10.0.0"
+      }
+    },
+    "node_modules/unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/unplugin": {
+      "version": "1.16.0",
+      "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-1.16.0.tgz",
+      "integrity": "sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==",
+      "dev": true,
+      "dependencies": {
+        "acorn": "^8.14.0",
+        "webpack-virtual-modules": "^0.6.2"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/unplugin-auto-import": {
+      "version": "0.16.7",
+      "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-0.16.7.tgz",
+      "integrity": "sha512-w7XmnRlchq6YUFJVFGSvG1T/6j8GrdYN6Em9Wf0Ye+HXgD/22kont+WnuCAA0UaUoxtuvRR1u/mXKy63g/hfqQ==",
+      "dev": true,
+      "dependencies": {
+        "@antfu/utils": "^0.7.6",
+        "@rollup/pluginutils": "^5.0.5",
+        "fast-glob": "^3.3.1",
+        "local-pkg": "^0.5.0",
+        "magic-string": "^0.30.5",
+        "minimatch": "^9.0.3",
+        "unimport": "^3.4.0",
+        "unplugin": "^1.5.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@nuxt/kit": "^3.2.2",
+        "@vueuse/core": "*"
+      },
+      "peerDependenciesMeta": {
+        "@nuxt/kit": {
+          "optional": true
+        },
+        "@vueuse/core": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/unplugin-auto-import/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/unplugin-auto-import/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/unplugin-vue-components": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-0.25.2.tgz",
+      "integrity": "sha512-OVmLFqILH6w+eM8fyt/d/eoJT9A6WO51NZLf1vC5c1FZ4rmq2bbGxTy8WP2Jm7xwFdukaIdv819+UI7RClPyCA==",
+      "dev": true,
+      "dependencies": {
+        "@antfu/utils": "^0.7.5",
+        "@rollup/pluginutils": "^5.0.2",
+        "chokidar": "^3.5.3",
+        "debug": "^4.3.4",
+        "fast-glob": "^3.3.0",
+        "local-pkg": "^0.4.3",
+        "magic-string": "^0.30.1",
+        "minimatch": "^9.0.3",
+        "resolve": "^1.22.2",
+        "unplugin": "^1.4.0"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@babel/parser": "^7.15.8",
+        "@nuxt/kit": "^3.2.2",
+        "vue": "2 || 3"
+      },
+      "peerDependenciesMeta": {
+        "@babel/parser": {
+          "optional": true
+        },
+        "@nuxt/kit": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/unplugin-vue-components/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/unplugin-vue-components/node_modules/local-pkg": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
+      "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      }
+    },
+    "node_modules/unplugin-vue-components/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/unplugin/node_modules/webpack-virtual-modules": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
+      "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
+      "dev": true
+    },
+    "node_modules/update-browserslist-db": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+      "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.2.0",
+        "picocolors": "^1.1.0"
+      },
+      "bin": {
+        "update-browserslist-db": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
+    "node_modules/uri-js": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "node_modules/url": {
+      "version": "0.11.4",
+      "resolved": "https://registry.npmmirror.com/url/-/url-0.11.4.tgz",
+      "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==",
+      "dev": true,
+      "dependencies": {
+        "punycode": "^1.4.1",
+        "qs": "^6.12.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/url/node_modules/punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==",
+      "dev": true
+    },
+    "node_modules/util": {
+      "version": "0.12.5",
+      "resolved": "https://registry.npmmirror.com/util/-/util-0.12.5.tgz",
+      "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+      "dev": true,
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "is-arguments": "^1.0.4",
+        "is-generator-function": "^1.0.7",
+        "is-typed-array": "^1.1.3",
+        "which-typed-array": "^1.1.2"
+      }
+    },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "dev": true
+    },
+    "node_modules/utila": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/utila/-/utila-0.4.0.tgz",
+      "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==",
+      "dev": true
+    },
+    "node_modules/utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4.0"
+      }
+    },
+    "node_modules/uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+      "dev": true,
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
+    },
+    "node_modules/validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "dependencies": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "node_modules/vant": {
+      "version": "4.9.9",
+      "resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.9.tgz",
+      "integrity": "sha512-sEw3ljwCza5dazpJqh04b38vCjNr2Id8vb7LOkYQQR/94iERDIm5jcQinhmwlRnwoGCa+JkNwm0jrCafzZJiwA==",
+      "dependencies": {
+        "@vant/popperjs": "^1.3.0",
+        "@vant/use": "^1.6.0",
+        "@vue/shared": "^3.5.12"
+      },
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
+    "node_modules/vm-browserify": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/vm-browserify/-/vm-browserify-1.1.2.tgz",
+      "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+      "dev": true
+    },
+    "node_modules/vue": {
+      "version": "3.5.13",
+      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz",
+      "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
+      "dependencies": {
+        "@vue/compiler-dom": "3.5.13",
+        "@vue/compiler-sfc": "3.5.13",
+        "@vue/runtime-dom": "3.5.13",
+        "@vue/server-renderer": "3.5.13",
+        "@vue/shared": "3.5.13"
+      },
+      "peerDependencies": {
+        "typescript": "*"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-demi": {
+      "version": "0.14.10",
+      "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
+      "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+      "hasInstallScript": true,
+      "bin": {
+        "vue-demi-fix": "bin/vue-demi-fix.js",
+        "vue-demi-switch": "bin/vue-demi-switch.js"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antfu"
+      },
+      "peerDependencies": {
+        "@vue/composition-api": "^1.0.0-rc.1",
+        "vue": "^3.0.0-0 || ^2.6.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-draggable-plus": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmmirror.com/vue-draggable-plus/-/vue-draggable-plus-0.3.1.tgz",
+      "integrity": "sha512-Ubo0O8/D+hZPHb1bcDTjOE42a//OjLQwj+bQwfxa1WnEKTJdS7MU0A4auUcNjyIkhTN1xuETOR4mT+BGZCPL2g==",
+      "peerDependencies": {
+        "@types/sortablejs": "^1.15.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-eslint-parser": {
+      "version": "9.4.3",
+      "resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
+      "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
+      "dev": true,
+      "dependencies": {
+        "debug": "^4.3.4",
+        "eslint-scope": "^7.1.1",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.3.1",
+        "esquery": "^1.4.0",
+        "lodash": "^4.17.21",
+        "semver": "^7.3.6"
+      },
+      "engines": {
+        "node": "^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mysticatea"
+      },
+      "peerDependencies": {
+        "eslint": ">=6.0.0"
+      }
+    },
+    "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
+      "version": "7.2.2",
+      "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+      "dev": true,
+      "dependencies": {
+        "esrecurse": "^4.3.0",
+        "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/vue-eslint-parser/node_modules/estraverse": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmmirror.com/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
+    },
+    "node_modules/vue-hot-reload-api": {
+      "version": "2.3.4",
+      "resolved": "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
+      "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
+      "dev": true
+    },
+    "node_modules/vue-i18n": {
+      "version": "9.6.3",
+      "resolved": "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.6.3.tgz",
+      "integrity": "sha512-8uTI7mW0JoB6lZkQySxJEINkjGSfqj7PsrCG5YULJ2l6jSqIoN5BruQCLNuFJduOVG8SIsuAs3bHIco/D3swGg==",
+      "dependencies": {
+        "@intlify/core-base": "9.6.3",
+        "@intlify/shared": "9.6.3",
+        "@vue/devtools-api": "^6.5.0"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      },
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
+    "node_modules/vue-json-viewer": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmmirror.com/vue-json-viewer/-/vue-json-viewer-3.0.4.tgz",
+      "integrity": "sha512-pnC080rTub6YjccthVSNQod2z9Sl5IUUq46srXtn6rxwhW8QM4rlYn+CTSLFKXWfw+N3xv77Cioxw7B4XUKIbQ==",
+      "dependencies": {
+        "clipboard": "^2.0.4"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.2"
+      }
+    },
+    "node_modules/vue-loader": {
+      "version": "17.4.2",
+      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.4.2.tgz",
+      "integrity": "sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==",
+      "dev": true,
+      "dependencies": {
+        "chalk": "^4.1.0",
+        "hash-sum": "^2.0.0",
+        "watchpack": "^2.4.0"
+      },
+      "peerDependencies": {
+        "webpack": "^4.1.0 || ^5.0.0-0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/compiler-sfc": {
+          "optional": true
+        },
+        "vue": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/vue-loader/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/vue-router": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz",
+      "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==",
+      "dependencies": {
+        "@vue/devtools-api": "^6.6.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/posva"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.0"
+      }
+    },
+    "node_modules/vue-style-loader": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
+      "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==",
+      "dev": true,
+      "dependencies": {
+        "hash-sum": "^1.0.2",
+        "loader-utils": "^1.0.2"
+      }
+    },
+    "node_modules/vue-style-loader/node_modules/hash-sum": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/hash-sum/-/hash-sum-1.0.2.tgz",
+      "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+      "dev": true
+    },
+    "node_modules/vue-template-es2015-compiler": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
+      "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
+      "dev": true
+    },
+    "node_modules/vxe-table": {
+      "version": "4.6.25",
+      "resolved": "https://registry.npmmirror.com/vxe-table/-/vxe-table-4.6.25.tgz",
+      "integrity": "sha512-rFhGh8w+420cdnIasQKisiKagz9F/iNieB/z6v0j4GcsMfGHEmSJ72YrHcXogQh4wNlCzKVfb7rl7nREL5eIOg==",
+      "dependencies": {
+        "dom-zindex": "^1.0.6",
+        "xe-utils": "^3.5.31"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.28"
+      }
+    },
+    "node_modules/watchpack": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.2.tgz",
+      "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
+      "dev": true,
+      "dependencies": {
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.1.2"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/wbuf": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmmirror.com/wbuf/-/wbuf-1.7.3.tgz",
+      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+      "dev": true,
+      "dependencies": {
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "node_modules/wcwidth": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",
+      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
+      "dev": true,
+      "dependencies": {
+        "defaults": "^1.0.3"
+      }
+    },
+    "node_modules/webidl-conversions": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+      "dev": true
+    },
+    "node_modules/webpack": {
+      "version": "5.97.0",
+      "resolved": "https://registry.npmmirror.com/webpack/-/webpack-5.97.0.tgz",
+      "integrity": "sha512-CWT8v7ShSfj7tGs4TLRtaOLmOCPWhoKEvp+eA7FVx8Xrjb3XfT0aXdxDItnRZmE8sHcH+a8ayDrJCOjXKxVFfQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/eslint-scope": "^3.7.7",
+        "@types/estree": "^1.0.6",
+        "@webassemblyjs/ast": "^1.14.1",
+        "@webassemblyjs/wasm-edit": "^1.14.1",
+        "@webassemblyjs/wasm-parser": "^1.14.1",
+        "acorn": "^8.14.0",
+        "browserslist": "^4.24.0",
+        "chrome-trace-event": "^1.0.2",
+        "enhanced-resolve": "^5.17.1",
+        "es-module-lexer": "^1.2.1",
+        "eslint-scope": "5.1.1",
+        "events": "^3.2.0",
+        "glob-to-regexp": "^0.4.1",
+        "graceful-fs": "^4.2.11",
+        "json-parse-even-better-errors": "^2.3.1",
+        "loader-runner": "^4.2.0",
+        "mime-types": "^2.1.27",
+        "neo-async": "^2.6.2",
+        "schema-utils": "^3.2.0",
+        "tapable": "^2.1.1",
+        "terser-webpack-plugin": "^5.3.10",
+        "watchpack": "^2.4.1",
+        "webpack-sources": "^3.2.3"
+      },
+      "bin": {
+        "webpack": "bin/webpack.js"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependenciesMeta": {
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-bundle-analyzer": {
+      "version": "4.10.2",
+      "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz",
+      "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==",
+      "dev": true,
+      "dependencies": {
+        "@discoveryjs/json-ext": "0.5.7",
+        "acorn": "^8.0.4",
+        "acorn-walk": "^8.0.0",
+        "commander": "^7.2.0",
+        "debounce": "^1.2.1",
+        "escape-string-regexp": "^4.0.0",
+        "gzip-size": "^6.0.0",
+        "html-escaper": "^2.0.2",
+        "opener": "^1.5.2",
+        "picocolors": "^1.0.0",
+        "sirv": "^2.0.3",
+        "ws": "^7.3.1"
+      },
+      "bin": {
+        "webpack-bundle-analyzer": "lib/bin/analyzer.js"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      }
+    },
+    "node_modules/webpack-bundle-analyzer/node_modules/commander": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz",
+      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/webpack-chain": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmmirror.com/webpack-chain/-/webpack-chain-6.5.1.tgz",
+      "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==",
+      "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+      "dev": true,
+      "dependencies": {
+        "deepmerge": "^1.5.2",
+        "javascript-stringify": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/webpack-chain/node_modules/deepmerge": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-1.5.2.tgz",
+      "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/webpack-dev-middleware": {
+      "version": "5.3.4",
+      "resolved": "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+      "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
+      "dev": true,
+      "dependencies": {
+        "colorette": "^2.0.10",
+        "memfs": "^3.4.3",
+        "mime-types": "^2.1.31",
+        "range-parser": "^1.2.1",
+        "schema-utils": "^4.0.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^4.0.0 || ^5.0.0"
+      }
+    },
+    "node_modules/webpack-dev-middleware/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/webpack-dev-middleware/node_modules/schema-utils": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz",
+      "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/webpack-dev-server": {
+      "version": "4.15.2",
+      "resolved": "https://registry.npmmirror.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz",
+      "integrity": "sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==",
+      "dev": true,
+      "dependencies": {
+        "@types/bonjour": "^3.5.9",
+        "@types/connect-history-api-fallback": "^1.3.5",
+        "@types/express": "^4.17.13",
+        "@types/serve-index": "^1.9.1",
+        "@types/serve-static": "^1.13.10",
+        "@types/sockjs": "^0.3.33",
+        "@types/ws": "^8.5.5",
+        "ansi-html-community": "^0.0.8",
+        "bonjour-service": "^1.0.11",
+        "chokidar": "^3.5.3",
+        "colorette": "^2.0.10",
+        "compression": "^1.7.4",
+        "connect-history-api-fallback": "^2.0.0",
+        "default-gateway": "^6.0.3",
+        "express": "^4.17.3",
+        "graceful-fs": "^4.2.6",
+        "html-entities": "^2.3.2",
+        "http-proxy-middleware": "^2.0.3",
+        "ipaddr.js": "^2.0.1",
+        "launch-editor": "^2.6.0",
+        "open": "^8.0.9",
+        "p-retry": "^4.5.0",
+        "rimraf": "^3.0.2",
+        "schema-utils": "^4.0.0",
+        "selfsigned": "^2.1.1",
+        "serve-index": "^1.9.1",
+        "sockjs": "^0.3.24",
+        "spdy": "^4.0.2",
+        "webpack-dev-middleware": "^5.3.4",
+        "ws": "^8.13.0"
+      },
+      "bin": {
+        "webpack-dev-server": "bin/webpack-dev-server.js"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      },
+      "peerDependencies": {
+        "webpack": "^4.37.0 || ^5.0.0"
+      },
+      "peerDependenciesMeta": {
+        "webpack": {
+          "optional": true
+        },
+        "webpack-cli": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-dev-server/node_modules/ajv": {
+      "version": "8.17.1",
+      "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.17.1.tgz",
+      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3",
+        "fast-uri": "^3.0.1",
+        "json-schema-traverse": "^1.0.0",
+        "require-from-string": "^2.0.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
+      }
+    },
+    "node_modules/webpack-dev-server/node_modules/ajv-keywords": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
+      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
+      "dev": true,
+      "dependencies": {
+        "fast-deep-equal": "^3.1.3"
+      },
+      "peerDependencies": {
+        "ajv": "^8.8.2"
+      }
+    },
+    "node_modules/webpack-dev-server/node_modules/json-schema-traverse": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
+      "dev": true
+    },
+    "node_modules/webpack-dev-server/node_modules/schema-utils": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz",
+      "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.9",
+        "ajv": "^8.9.0",
+        "ajv-formats": "^2.1.1",
+        "ajv-keywords": "^5.1.0"
+      },
+      "engines": {
+        "node": ">= 12.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/webpack-dev-server/node_modules/ws": {
+      "version": "8.18.0",
+      "resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.0.tgz",
+      "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": ">=5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/webpack-merge": {
+      "version": "5.10.0",
+      "resolved": "https://registry.npmmirror.com/webpack-merge/-/webpack-merge-5.10.0.tgz",
+      "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+      "dev": true,
+      "dependencies": {
+        "clone-deep": "^4.0.1",
+        "flat": "^5.0.2",
+        "wildcard": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10.0.0"
+      }
+    },
+    "node_modules/webpack-merge/node_modules/wildcard": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/wildcard/-/wildcard-2.0.1.tgz",
+      "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==",
+      "dev": true
+    },
+    "node_modules/webpack-sources": {
+      "version": "3.2.3",
+      "resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz",
+      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/webpack-virtual-modules": {
+      "version": "0.4.6",
+      "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.4.6.tgz",
+      "integrity": "sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA==",
+      "dev": true
+    },
+    "node_modules/webpack/node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/webpack"
+      }
+    },
+    "node_modules/websocket-driver": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmmirror.com/websocket-driver/-/websocket-driver-0.7.4.tgz",
+      "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+      "dev": true,
+      "dependencies": {
+        "http-parser-js": ">=0.5.1",
+        "safe-buffer": ">=5.1.0",
+        "websocket-extensions": ">=0.1.1"
+      },
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/websocket-extensions": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmmirror.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+      "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.0"
+      }
+    },
+    "node_modules/whatwg-fetch": {
+      "version": "3.6.20",
+      "resolved": "https://registry.npmmirror.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz",
+      "integrity": "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==",
+      "dev": true
+    },
+    "node_modules/whatwg-url": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+      "dev": true,
+      "dependencies": {
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
+      }
+    },
+    "node_modules/which": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/which-boxed-primitive": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/which-boxed-primitive/-/which-boxed-primitive-1.1.0.tgz",
+      "integrity": "sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==",
+      "dev": true,
+      "dependencies": {
+        "is-bigint": "^1.1.0",
+        "is-boolean-object": "^1.2.0",
+        "is-number-object": "^1.1.0",
+        "is-string": "^1.1.0",
+        "is-symbol": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-builtin-type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/which-builtin-type/-/which-builtin-type-1.2.0.tgz",
+      "integrity": "sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "function.prototype.name": "^1.1.6",
+        "has-tostringtag": "^1.0.2",
+        "is-async-function": "^2.0.0",
+        "is-date-object": "^1.0.5",
+        "is-finalizationregistry": "^1.1.0",
+        "is-generator-function": "^1.0.10",
+        "is-regex": "^1.1.4",
+        "is-weakref": "^1.0.2",
+        "isarray": "^2.0.5",
+        "which-boxed-primitive": "^1.0.2",
+        "which-collection": "^1.0.2",
+        "which-typed-array": "^1.1.15"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-collection": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/which-collection/-/which-collection-1.0.2.tgz",
+      "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
+      "dev": true,
+      "dependencies": {
+        "is-map": "^2.0.3",
+        "is-set": "^2.0.3",
+        "is-weakmap": "^2.0.2",
+        "is-weakset": "^2.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/which-module": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
+      "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
+    },
+    "node_modules/which-typed-array": {
+      "version": "1.1.16",
+      "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.16.tgz",
+      "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==",
+      "dev": true,
+      "dependencies": {
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.7",
+        "for-each": "^0.3.3",
+        "gopd": "^1.0.1",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/wildcard": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/wildcard/-/wildcard-1.1.2.tgz",
+      "integrity": "sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng=="
+    },
+    "node_modules/word-wrap": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.5.tgz",
+      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+      "dev": true
+    },
+    "node_modules/ws": {
+      "version": "7.5.10",
+      "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.10.tgz",
+      "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8.3.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": "^5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/xe-utils": {
+      "version": "3.5.32",
+      "resolved": "https://registry.npmmirror.com/xe-utils/-/xe-utils-3.5.32.tgz",
+      "integrity": "sha512-R8ZT2lRnRBQO3pchM1za/Aru+/29DVDWD/OmOFODWWGkiQYz0iVIr8Bq8uKXS6zMhEsSqVCrn46bXzfe/Agjcw=="
+    },
+    "node_modules/xml-js": {
+      "version": "1.6.11",
+      "resolved": "https://registry.npmmirror.com/xml-js/-/xml-js-1.6.11.tgz",
+      "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
+      "dependencies": {
+        "sax": "^1.2.4"
+      },
+      "bin": {
+        "xml-js": "bin/cli.js"
+      }
+    },
+    "node_modules/xml-name-validator": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+      "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/xtend": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz",
+      "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.4"
+      }
+    },
+    "node_modules/y18n": {
+      "version": "5.0.8",
+      "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
+      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yallist": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
+    },
+    "node_modules/yaml": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
+      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yargs-parser": {
+      "version": "20.2.9",
+      "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz",
+      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/yorkie": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmmirror.com/yorkie/-/yorkie-2.0.0.tgz",
+      "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "dependencies": {
+        "execa": "^0.8.0",
+        "is-ci": "^1.0.10",
+        "normalize-path": "^1.0.0",
+        "strip-indent": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/yorkie/node_modules/cross-spawn": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-5.1.0.tgz",
+      "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^4.0.1",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      }
+    },
+    "node_modules/yorkie/node_modules/execa": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmmirror.com/execa/-/execa-0.8.0.tgz",
+      "integrity": "sha512-zDWS+Rb1E8BlqqhALSt9kUhss8Qq4nN3iof3gsOdyINksElaPyNBtKUMTR62qhvgVWR0CqCX7sdnKe4MnUbFEA==",
+      "dev": true,
+      "dependencies": {
+        "cross-spawn": "^5.0.1",
+        "get-stream": "^3.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/yorkie/node_modules/get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/yorkie/node_modules/lru-cache": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-4.1.5.tgz",
+      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+      "dev": true,
+      "dependencies": {
+        "pseudomap": "^1.0.2",
+        "yallist": "^2.1.2"
+      }
+    },
+    "node_modules/yorkie/node_modules/normalize-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-1.0.0.tgz",
+      "integrity": "sha512-7WyT0w8jhpDStXRq5836AMmihQwq2nrUVQrgjvUo/p/NZf9uy/MeJ246lBJVmWuYXMlJuG9BNZHF0hWjfTbQUA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/yorkie/node_modules/shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+      "dev": true,
+      "dependencies": {
+        "shebang-regex": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/yorkie/node_modules/shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/yorkie/node_modules/which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmmirror.com/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "dev": true,
+      "dependencies": {
+        "isexe": "^2.0.0"
+      },
+      "bin": {
+        "which": "bin/which"
+      }
+    },
+    "node_modules/yorkie/node_modules/yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmmirror.com/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
+      "dev": true
+    },
+    "node_modules/zrender": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
+      "integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==",
+      "dependencies": {
+        "tslib": "2.3.0"
+      }
+    }
+  }
+}

+ 34 - 2
src/api/generated/index.ts

@@ -52,7 +52,23 @@ import TourCarOrderController from './tourCarOrderController';
 import TourCarContractMenuController from './tourCarContractMenuController';
 import TourCarCategoryController from './tourCarCategoryController';
 import TourBusinessBannerController from './tourBusinessBannerController';
-import VisaMetarialsListController from "./visaMetarialsListController"
+import VisaMetarialsListController from "./visaMetarialsListController";
+import TourFansController from './tourFansController';
+import TourBrowseRecordsController from './tourBrowseRecordsController';
+import TourImComplaintTypeController from './tourImComplaintTypeController';
+import TourImComplaitController from './tourImComplaitController';
+import TourImSensitiveWordAllowController from './tourImSensitiveWordAllowController';
+import TourImSensitiveWordDenyController from './tourImSensitiveWordDenyController';
+import TourImGroupTypeController from './tourImGroupTypeController';
+import TourImGroupInvitationController from './tourImGroupInvitationController';
+import TourImMemberController from './tourImMemberController';
+import TourImMessageController from './tourImMessageController';
+import TourImGroupController from './tourImGroupController';
+import TourProjectGroupPurchaseController from './tourProjectGroupPurchaseController';
+import TourProjectGroupPurchaseDetailController from './tourProjectGroupPurchaseDetailController';
+import TourProjectGroupPurchaseApplyController from './tourProjectGroupPurchaseApplyController';
+import TourProjectGroupPurchaseBannerController from './tourProjectGroupPurchaseBannerController';
+import TourProjectGroupPurchaseRebateController from './tourProjectGroupPurchaseRebateController';
 export {
   SysUserController,
   SysDeptController,
@@ -108,5 +124,21 @@ export {
   TourCarModelController,
   TourCarCategoryController,
   TourBusinessBannerController,
-  VisaMetarialsListController
+  VisaMetarialsListController,
+  TourFansController,
+  TourBrowseRecordsController,
+  TourImComplaintTypeController,
+  TourImComplaitController,
+  TourImSensitiveWordAllowController,
+  TourImSensitiveWordDenyController,
+  TourImGroupTypeController,
+  TourImGroupInvitationController,
+  TourImMemberController,
+  TourImMessageController,
+  TourImGroupController,
+  TourProjectGroupPurchaseController,
+  TourProjectGroupPurchaseDetailController,
+  TourProjectGroupPurchaseApplyController,
+  TourProjectGroupPurchaseBannerController,
+  TourProjectGroupPurchaseRebateController,
 };

+ 43 - 0
src/api/generated/tourBrowseRecordsController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourBrowseRecords from '@/types/table/tourBrowseRecords';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourBrowseRecordsData extends TourBrowseRecords {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourBrowseRecordsController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourBrowseRecordsData>>(API_CONTEXT + '/app/tourBrowseRecords/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourBrowseRecordsData>(API_CONTEXT + '/app/tourBrowseRecords/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourBrowseRecords/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourBrowseRecords/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourBrowseRecords/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourBrowseRecords/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourBrowseRecords/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourBrowseRecords/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourBrowseRecords/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourFansController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourFans from '@/types/table/tourFans';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourFansData extends TourFans {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourFansController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourFansData>>(API_CONTEXT + '/app/tourFans/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourFansData>(API_CONTEXT + '/app/tourFans/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourFans/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourFans/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourFans/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourFans/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourFans/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourFans/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourFans/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImComplaintTypeController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImComplaintType from '@/types/table/tourImComplaintType';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImComplaintTypeData extends TourImComplaintType {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImComplaintTypeController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImComplaintTypeData>>(API_CONTEXT + '/app/tourImComplaintType/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImComplaintTypeData>(API_CONTEXT + '/app/tourImComplaintType/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImComplaintType/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImComplaintType/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImComplaintType/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplaintType/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplaintType/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplaintType/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplaintType/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImComplaitController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImComplait from '@/types/table/tourImComplait';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImComplaitData extends TourImComplait {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImComplaitController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImComplaitData>>(API_CONTEXT + '/app/tourImComplait/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImComplaitData>(API_CONTEXT + '/app/tourImComplait/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImComplait/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImComplait/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImComplait/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplait/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplait/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplait/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImComplait/deleteBatch', params, httpOptions);
+  }
+}

+ 53 - 0
src/api/generated/tourImGroupController.ts

@@ -0,0 +1,53 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImGroup from '@/types/table/tourImGroup';
+import { TourImGroupInvitationData } from '@/api/generated/tourImGroupInvitationController';
+import { TourImMemberData } from '@/api/generated/tourImMemberController';
+import { TourImMessageData } from '@/api/generated/tourImMessageController';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImGroupData extends TourImGroup {
+  tourImGroupInvitationList?: TourImGroupInvitationData[];
+  tourImMemberList?: TourImMemberData[];
+  tourImMessageList?: TourImMessageData[];
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImGroupController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImGroupData>>(API_CONTEXT + '/app/tourImGroup/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImGroupData>(API_CONTEXT + '/app/tourImGroup/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImGroup/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImGroup/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImGroup/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroup/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroup/update', params, httpOptions);
+  }
+
+  static updateBan(params: ANY_OBJECT, httpOptions?: RequestOption){
+    return super.post(API_CONTEXT + '/app/tourImGroup/updateBan', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroup/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroup/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImGroupInvitationController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImGroupInvitation from '@/types/table/tourImGroupInvitation';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImGroupInvitationData extends TourImGroupInvitation {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImGroupInvitationController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImGroupInvitationData>>(API_CONTEXT + '/app/tourImGroupInvitation/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImGroupInvitationData>(API_CONTEXT + '/app/tourImGroupInvitation/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImGroupInvitation/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImGroupInvitation/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImGroupInvitation/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupInvitation/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupInvitation/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupInvitation/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupInvitation/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImGroupTypeController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImGroupType from '@/types/table/tourImGroupType';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImGroupTypeData extends TourImGroupType {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImGroupTypeController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImGroupTypeData>>(API_CONTEXT + '/app/tourImGroupType/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImGroupTypeData>(API_CONTEXT + '/app/tourImGroupType/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImGroupType/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImGroupType/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImGroupType/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupType/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupType/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupType/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImGroupType/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImMemberController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImMember from '@/types/table/tourImMember';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImMemberData extends TourImMember {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImMemberController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImMemberData>>(API_CONTEXT + '/app/tourImMember/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImMemberData>(API_CONTEXT + '/app/tourImMember/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImMember/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImMember/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImMember/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMember/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMember/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMember/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMember/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImMessageController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImMessage from '@/types/table/tourImMessage';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImMessageData extends TourImMessage {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImMessageController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImMessageData>>(API_CONTEXT + '/app/tourImMessage/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImMessageData>(API_CONTEXT + '/app/tourImMessage/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImMessage/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImMessage/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImMessage/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMessage/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMessage/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMessage/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImMessage/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImSensitiveWordAllowController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImSensitiveWordAllow from '@/types/table/tourImSensitiveWordAllow';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImSensitiveWordAllowData extends TourImSensitiveWordAllow {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImSensitiveWordAllowController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImSensitiveWordAllowData>>(API_CONTEXT + '/app/tourImSensitiveWordAllow/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImSensitiveWordAllowData>(API_CONTEXT + '/app/tourImSensitiveWordAllow/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImSensitiveWordAllow/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImSensitiveWordAllow/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImSensitiveWordAllow/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordAllow/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordAllow/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordAllow/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordAllow/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourImSensitiveWordDenyController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourImSensitiveWordDeny from '@/types/table/tourImSensitiveWordDeny';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourImSensitiveWordDenyData extends TourImSensitiveWordDeny {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourImSensitiveWordDenyController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourImSensitiveWordDenyData>>(API_CONTEXT + '/app/tourImSensitiveWordDeny/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourImSensitiveWordDenyData>(API_CONTEXT + '/app/tourImSensitiveWordDeny/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourImSensitiveWordDeny/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourImSensitiveWordDeny/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourImSensitiveWordDeny/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordDeny/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordDeny/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordDeny/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourImSensitiveWordDeny/deleteBatch', params, httpOptions);
+  }
+}

+ 6 - 3
src/api/generated/tourOrderController.ts

@@ -9,17 +9,17 @@ import { API_CONTEXT } from '../config';
 
 const { buildGetUrl } = useUrlBuilder();
 
-export interface tourOrderData extends tourOrder {
+export interface TourOrderData extends tourOrder {
   tourOrderPassenageList?: TourOrderPassenageData[];
   __cascade_add_temp_id__?: string | number | undefined;
 }
 
 export default class tourOrderController extends BaseController {
   static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
-    return super.post<TableData<tourOrderData>>(API_CONTEXT + '/app/tourOrder/list', params, httpOptions);
+    return super.post<TableData<TourOrderData>>(API_CONTEXT + '/app/tourOrder/list', params, httpOptions);
   }
   static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
-    return super.get<tourOrderData>(API_CONTEXT + '/app/tourOrder/view', params, httpOptions);
+    return super.get<TourOrderData>(API_CONTEXT + '/app/tourOrder/view', params, httpOptions);
   }
   static export(params: ANY_OBJECT, fileName: string) {
     return super.download(API_CONTEXT + '/app/tourOrder/export', params, fileName);
@@ -42,4 +42,7 @@ export default class tourOrderController extends BaseController {
   static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
     return super.post(API_CONTEXT + '/app/tourOrder/deleteBatch', params, httpOptions);
   }
+  static clearRebate(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourOrder/clearRebate', params, httpOptions);
+  }
 }

+ 47 - 0
src/api/generated/tourProjectGroupPurchaseApplyController.ts

@@ -0,0 +1,47 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourProjectGroupPurchaseApply from '@/types/table/tourProjectGroupPurchaseApply';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourUserData } from '@/api/generated/tourUserController';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourProjectGroupPurchaseApplyData extends TourProjectGroupPurchaseApply {
+  tourismProject?: TourismProjectData;
+  tourUser?: TourUserData;
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourProjectGroupPurchaseApplyController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourProjectGroupPurchaseApplyData>>(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourProjectGroupPurchaseApplyData>(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseApply/deleteBatch', params, httpOptions);
+  }
+}

+ 43 - 0
src/api/generated/tourProjectGroupPurchaseBannerController.ts

@@ -0,0 +1,43 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourProjectGroupPurchaseBanner from '@/types/table/tourProjectGroupPurchaseBanner';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourProjectGroupPurchaseBannerData extends TourProjectGroupPurchaseBanner {
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourProjectGroupPurchaseBannerController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourProjectGroupPurchaseBannerData>>(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourProjectGroupPurchaseBannerData>(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseBanner/deleteBatch', params, httpOptions);
+  }
+}

+ 47 - 0
src/api/generated/tourProjectGroupPurchaseController.ts

@@ -0,0 +1,47 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourProjectGroupPurchase from '@/types/table/tourProjectGroupPurchase';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseDetailData } from '@/api/generated/tourProjectGroupPurchaseDetailController';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourProjectGroupPurchaseData extends TourProjectGroupPurchase {
+  tourismProject?: TourismProjectData;
+  tourProjectGroupPurchaseDetailList?: TourProjectGroupPurchaseDetailData[];
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourProjectGroupPurchaseController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourProjectGroupPurchaseData>>(API_CONTEXT + '/app/tourProjectGroupPurchase/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourProjectGroupPurchaseData>(API_CONTEXT + '/app/tourProjectGroupPurchase/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourProjectGroupPurchase/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourProjectGroupPurchase/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourProjectGroupPurchase/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchase/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchase/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchase/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchase/deleteBatch', params, httpOptions);
+  }
+}

+ 45 - 0
src/api/generated/tourProjectGroupPurchaseDetailController.ts

@@ -0,0 +1,45 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourProjectGroupPurchaseDetail from '@/types/table/tourProjectGroupPurchaseDetail';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourProjectGroupPurchaseDetailData extends TourProjectGroupPurchaseDetail {
+  tourProjectGroupPurchase?: TourProjectGroupPurchaseData;
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourProjectGroupPurchaseDetailController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourProjectGroupPurchaseDetailData>>(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourProjectGroupPurchaseDetailData>(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseDetail/deleteBatch', params, httpOptions);
+  }
+}

+ 49 - 0
src/api/generated/tourProjectGroupPurchaseRebateController.ts

@@ -0,0 +1,49 @@
+import { BaseController } from '@/api/BaseController';
+import { RequestOption } from '@/common/http/types';
+import { ANY_OBJECT } from '@/types/generic';
+import { TableData } from '@/common/types/table';
+import { useUrlBuilder } from '@/common/hooks/useUrl';
+import TourProjectGroupPurchaseRebate from '@/types/table/tourProjectGroupPurchaseRebate';
+import { TourUserData } from '@/api/generated/tourUserController';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { TourOrderData } from '@/api/generated/tourOrderController';
+import { API_CONTEXT } from '../config';
+
+const { buildGetUrl } = useUrlBuilder();
+
+export interface TourProjectGroupPurchaseRebateData extends TourProjectGroupPurchaseRebate {
+  tourUser?: TourUserData;
+  tourProjectGroupPurchase?: TourProjectGroupPurchaseData;
+  tourOrder?: TourOrderData;
+  __cascade_add_temp_id__?: string | number | undefined;
+}
+
+export default class TourProjectGroupPurchaseRebateController extends BaseController {
+  static list(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post<TableData<TourProjectGroupPurchaseRebateData>>(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/list', params, httpOptions);
+  }
+  static view(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.get<TourProjectGroupPurchaseRebateData>(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/view', params, httpOptions);
+  }
+  static export(params: ANY_OBJECT, fileName: string) {
+    return super.download(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/export', params, fileName);
+  }
+  static import(params: ANY_OBJECT) {
+    return super.upload(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/import', params);
+  }
+  static printUrl(params: ANY_OBJECT) {
+    return buildGetUrl(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/print', params);
+  }
+  static add(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/add', params, httpOptions);
+  }
+  static update(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/update', params, httpOptions);
+  }
+  static delete(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/delete', params, httpOptions);
+  }
+  static deleteBatch(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return super.post(API_CONTEXT + '/app/tourProjectGroupPurchaseRebate/deleteBatch', params, httpOptions);
+  }
+}

+ 55 - 0
src/api/system/DictionaryController.ts

@@ -387,4 +387,59 @@ export default class DictionaryController extends BaseController {
         });
     });
   }
+  static dictTourImComplaintType(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return new Promise<DictionaryBase>((resolve, reject) => {
+      super.get<DictData[]>('/admin/app/tourImComplaintType/listDict', params, httpOptions)
+        .then(res => {
+          let dictData = new DictionaryBase('投诉类型字典', res.data);
+          resolve(dictData);
+        }).catch(err => {
+          reject(err);
+        });
+    });
+  }
+  static dictTourImGroup(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return new Promise<DictionaryBase>((resolve, reject) => {
+      super.get<DictData[]>('/admin/app/tourImGroup/listDict', params, httpOptions)
+        .then(res => {
+          let dictData = new DictionaryBase('群聊字典表', res.data);
+          resolve(dictData);
+        }).catch(err => {
+          reject(err);
+        });
+    });
+  }
+  static dictTourImGroupType(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return new Promise<DictionaryBase>((resolve, reject) => {
+      super.get<DictData[]>('/admin/app/tourImGroupType/listDict', params, httpOptions)
+        .then(res => {
+          let dictData = new DictionaryBase('聊天群聊类型字典表', res.data);
+          resolve(dictData);
+        }).catch(err => {
+          reject(err);
+        });
+    });
+  }
+  static dictTourImGroupTypeByParentId(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return new Promise<DictionaryBase>((resolve, reject) => {
+      super.get<DictData[]>('/admin/app/tourImGroupType/listDictByParentId', params, httpOptions)
+        .then(res => {
+          let dictData = new DictionaryBase('聊天群聊类型字典表', res.data);
+          resolve(dictData);
+        }).catch(err => {
+          reject(err);
+        });
+    });
+  }
+  static dictDirectoryInfoByType(params: ANY_OBJECT, httpOptions?: RequestOption) {
+    return new Promise<DictionaryBase>((resolve, reject) => {
+      super.get<DictData[]>('/admin/app/directoryInfo/listDictByType', params, httpOptions)
+        .then(res => {
+          let dictData = new DictionaryBase('门户菜单字典', res.data);
+          resolve(dictData);
+        }).catch(err => {
+          reject(err);
+        });
+    });
+  }
 }

+ 47 - 0
src/common/staticDict/index.ts

@@ -1264,6 +1264,19 @@ const Type = new DictionaryBase('banner类型', [
   }
 ]);
 
+const BannerType = new DictionaryBase('banner类型', [
+  {
+    id: 0,
+    name: 'PC',
+    symbol: 'BANNER_PC'
+  },
+  {
+    id: 1,
+    name: 'H5',
+    symbol: 'BANNER_H5'
+  }
+]);
+
 const Hotspot = new DictionaryBase('是否热点数据', [
   {
     id: 0,
@@ -1720,6 +1733,37 @@ const VisaIndexFlag = new DictionaryBase('签证顾问显示列表字典', [
   }
 ]);
 
+const Success = new DictionaryBase('拼团是否成功', [
+  {
+    id: 0,
+    name: '正在拼团',
+    symbol: 'FAIL'
+  },
+  {
+    id: 1,
+    name: '成功',
+    symbol: 'SUCCESS'
+  }
+]);
+
+const GroupPurchaseRebate = new DictionaryBase('拼团返利类型', [
+  {
+    id: 0,
+    name: '邀请用户',
+    symbol: 'INVITE_USER'
+  },
+  {
+    id: 1,
+    name: '邀请的用户取消订单',
+    symbol: 'INVITE_USER_CANCEL'
+  },
+  {
+    id: 2,
+    name: '系统核销返利',
+    symbol: 'SYSTEM_RETURN_ZERO'
+  }
+]);
+
 export {
   SysDataPermType,
   SysOperationType,
@@ -1746,6 +1790,7 @@ export {
   SysUserType,
   CompanyType,
   Enable,
+  BannerType,
   Hotspot,
   Type,
   IsFirst,
@@ -1779,4 +1824,6 @@ export {
   VisaOrderState,
   VisaConsoluerLevel,
   VisaIndexFlag,
+  Success,
+  GroupPurchaseRebate
 };

+ 1 - 1
src/components/Dialog/types.d.ts

@@ -1,5 +1,5 @@
 export interface DialogProp<T> {
   index: string;
   cancel: () => void;
-  submit: (data: T) => void;
+  submit: (data: any) => void;
 }

+ 301 - 0
src/pages/ImComplaint/formEditTourImComplaintType.vue

@@ -0,0 +1,301 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImComplaintTypeRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="类型名称" prop="TourImComplaintType.typeName">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImComplaintType.typeName"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="类型描述" prop="TourImComplaintType.description">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImComplaintType.description"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="是否启用" prop="TourImComplaintType.enable">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImComplaintType.enable"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="enableWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in enableWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImComplaintTypeClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImComplaintType',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImComplaintTypeData } from '@/api/generated/tourImComplaintTypeController';
+import { TourImComplaintTypeController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImComplaintTypeRef = ref();
+// 表单数据定义
+type FormEditTourImComplaintTypeData = {
+  TourImComplaintType: TourImComplaintTypeData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImComplaintTypeData>({
+  TourImComplaintType: {
+    // id
+    id: undefined,
+    // 类型名称
+    typeName: undefined,
+    // 类型描述
+    description: undefined,
+    // 是否启用
+    enable: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImComplaintType.description': [
+    {required: true, message: '请输入类型描述', trigger: 'blur'}
+  ],
+  'TourImComplaintType.enable': [
+    {required: true, message: '请选择是否启用', trigger: 'blur'}
+  ],
+  'TourImComplaintType.typeName': [
+    {required: true, message: '请输入类型名称', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImComplaintTypeData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImComplaintType = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImComplaintTypeController.view(params).then(res => {
+      formData.TourImComplaintType = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 是否启用下拉数据获取函数
+ */
+const loadEnableDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 是否启用配置参数
+const enableOptions: DropdownOptions<DictData> = {
+  loadData: loadEnableDropdownList,
+  isTree: false,
+};
+// 是否启用下拉组件
+const enableWidget = useDropdown(enableOptions);
+const { dropdownList: enableWidgetDropdownList } = enableWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImComplaintType = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImComplaintType = () => {
+  refreshFormEditTourImComplaintType();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImComplaintType();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImComplaintTypeClick = () => {
+  formEditTourImComplaintTypeRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImComplaintType
+      };
+    retFormData.enableDictMap = findItemFromList(enableWidgetDropdownList.value, retFormData.enable, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImComplaintTypeDto: {
+        id: formData.TourImComplaintType.id,
+        description: formData.TourImComplaintType.description,
+        typeName: formData.TourImComplaintType.typeName,
+        enable: formData.TourImComplaintType.enable,
+        createUserId: formData.TourImComplaintType.createUserId,
+        createTime: formData.TourImComplaintType.createTime,
+        updateTime: formData.TourImComplaintType.updateTime,
+        updateUserId: formData.TourImComplaintType.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImComplaintTypeController.update : TourImComplaintTypeController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImComplaintTypeData().then(res => {
+    enableWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshFormEditTourImComplaintType();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 493 - 0
src/pages/ImComplaint/formEditTourImComplait.vue

@@ -0,0 +1,493 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImComplaitRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="用户" prop="TourImComplait.userId">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImComplait.userId"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="userIdWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in userIdWidgetDropdownList"
+                  :key="item.userId"
+                  :label="item.showName"
+                  :value="item.userId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="群组" prop="TourImComplait.groupId">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImComplait.groupId"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="groupIdWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in groupIdWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="举报类型" prop="TourImComplait.typeId">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImComplait.typeId"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="typeId_copyWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in typeId_copyWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="举报对象" prop="TourImComplait.objectType">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImComplait.objectType"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="objectTypeWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in objectTypeWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="其他违规理由" prop="TourImComplait.elseTypeReason">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImComplait.elseTypeReason"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="举报描述" prop="TourImComplait.description">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImComplait.description"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="举报图片" prop="TourImComplait.image">
+              <custom-upload
+                v-model="imageWidgetFileList"
+                name="uploadFile"
+                :size="layoutStore.defaultFormItemSize"
+                type="expand"
+                :headers="getUploadHeaders"
+                :action="getUploadActionUrl('/admin/app/tourImComplait/upload')"
+                :data="{fieldName: 'image', asImage: true}"
+                :limit="imageWidgetMaxCount"
+                @change="onImageChange"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImComplaitClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImComplait',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImComplaitData } from '@/api/generated/tourImComplaitController';
+import {TourImComplaitController, TourUserController} from '@/api/generated';
+import TourUser from "@/types/table/tourUser";
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImComplaitRef = ref();
+// 表单数据定义
+type FormEditTourImComplaitData = {
+  TourImComplait: TourImComplaitData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImComplaitData>({
+  TourImComplait: {
+    // id
+    id: undefined,
+    // 举报类型id
+    typeId: undefined,
+    // 类型为其他违规的理由
+    elseTypeReason: undefined,
+    // 举报对象 1用户 2群组
+    objectType: undefined,
+    // 举报描述
+    description: undefined,
+    // 举报图片 最多三张
+    image: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 用户id
+    userId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 群组id
+    groupId: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImComplait.groupId': [
+  ],
+  'TourImComplait.elseTypeReason': [
+  ],
+  'TourImComplait.typeId': [
+    {required: true, message: '请输入举报类型', trigger: 'blur'}
+  ],
+  'TourImComplait.objectType': [
+    {required: true, message: '请输入举报对象', trigger: 'blur'}
+  ],
+  'TourImComplait.userId': [
+  ],
+  'TourImComplait.image': [
+  ],
+  'TourImComplait.description': [
+    {required: true, message: '请输入举报描述', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImComplaitData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImComplait = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImComplaitController.view(params).then(res => {
+      formData.TourImComplait = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 用户下拉数据获取函数
+ */
+const loadUserIdDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 用户配置参数
+const userIdOptions: DropdownOptions<TourUser> = {
+  loadData: loadUserIdDropdownList,
+  isTree: false,
+};
+// 用户下拉组件
+const userIdWidget = useDropdown(userIdOptions);
+const { dropdownList: userIdWidgetDropdownList } = userIdWidget
+/**
+ * 群组下拉数据获取函数
+ */
+const loadGroupIdDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroup(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 群组配置参数
+const groupIdOptions: DropdownOptions<DictData> = {
+  loadData: loadGroupIdDropdownList,
+  isTree: false,
+};
+// 群组下拉组件
+const groupIdWidget = useDropdown(groupIdOptions);
+const { dropdownList: groupIdWidgetDropdownList } = groupIdWidget
+/**
+ * 举报类型下拉数据获取函数
+ */
+const loadTypeId_copyDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImComplaintType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 举报类型配置参数
+const typeId_copyOptions: DropdownOptions<DictData> = {
+  loadData: loadTypeId_copyDropdownList,
+  isTree: false,
+};
+// 举报类型下拉组件
+const typeId_copyWidget = useDropdown(typeId_copyOptions);
+const { dropdownList: typeId_copyWidgetDropdownList } = typeId_copyWidget
+/**
+ * 举报对象下拉数据获取函数
+ */
+const loadObjectTypeDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'ComplaintObjectType', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 举报对象配置参数
+const objectTypeOptions: DropdownOptions<DictData> = {
+  loadData: loadObjectTypeDropdownList,
+  isTree: false,
+};
+// 举报对象下拉组件
+const objectTypeWidget = useDropdown(objectTypeOptions);
+const { dropdownList: objectTypeWidgetDropdownList } = objectTypeWidget
+/**
+ * 举报图片上传文件改变
+ */
+const onImageChange = val => {
+  formData.TourImComplait.image = fileListToJson(val);
+};
+// 举报图片上传文件组件
+const imageWidget = useUploadWidget(3);
+const { fileList: imageWidgetFileList, maxCount: imageWidgetMaxCount } = imageWidget;
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImComplait = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImComplait = () => {
+  refreshFormEditTourImComplait();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImComplait();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImComplaitClick = () => {
+  formEditTourImComplaitRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImComplait
+      };
+    retFormData.userIdDictMap = findItemFromList(userIdWidgetDropdownList.value, retFormData.userId, 'id');
+    retFormData.groupIdDictMap = findItemFromList(groupIdWidgetDropdownList.value, retFormData.groupId, 'id');
+    retFormData.typeIdDictMap = findItemFromList(typeId_copyWidgetDropdownList.value, retFormData.typeId, 'id');
+    retFormData.objectTypeDictMap = findItemFromList(objectTypeWidgetDropdownList.value, retFormData.objectType, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImComplaitDto: {
+        id: formData.TourImComplait.id,
+        objectType: formData.TourImComplait.objectType,
+        userId: formData.TourImComplait.userId,
+        groupId: formData.TourImComplait.groupId,
+        typeId: formData.TourImComplait.typeId,
+        elseTypeReason: formData.TourImComplait.elseTypeReason,
+        description: formData.TourImComplait.description,
+        image: formData.TourImComplait.image,
+        createUserId: formData.TourImComplait.createUserId,
+        createTime: formData.TourImComplait.createTime,
+        updateTime: formData.TourImComplait.updateTime,
+        updateUserId: formData.TourImComplait.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImComplaitController.update : TourImComplaitController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImComplaitData().then(res => {
+    userIdWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    groupIdWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    typeId_copyWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    objectTypeWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    let imageDownloadParams = {
+      id: formData.TourImComplait.id,
+      fieldName: 'image',
+      asImage: true
+    };
+    imageWidgetFileList.value = parseUploadData(formData.TourImComplait.image, imageDownloadParams);
+    if (isEdit.value) refreshFormEditTourImComplait();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 409 - 0
src/pages/ImComplaint/formTourImComplaintType.vue

@@ -0,0 +1,409 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImComplaintTypeRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImComplaintType()" @reset="resetFormTourImComplaintType">
+        <el-form-item label="类型名称">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.typeNameFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+        <el-form-item label="是否启用">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.enableFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="enableFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in enableFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImComplaintTypeTable"
+      class="page-table"
+      :data="formTourImComplaintTypeTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImComplaintTypeTableWidgetCurrentPage - 1) * formTourImComplaintTypeTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImComplaintTypeTableWidget.onSortChange"
+      @refresh="formTourImComplaintTypeTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImComplaintType:formTourImComplaintType:addTourImComplaintType')"
+          @click="onAddTourImComplaintTypeClick()"
+          >
+          新建
+        </el-button>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImComplaintType:formTourImComplaintType:exportTourImComplaintType')"
+          @click="onExportTourImComplaintTypeClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :disabled="!checkPermCodeExist('formTourImComplaintType:formTourImComplaintType:importTourImComplaintType')"
+          :on-change="onImportTourImComplaintTypeClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+              :disabled="!checkPermCodeExist('formTourImComplaintType:formTourImComplaintType:importTourImComplaintType')"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImComplaintTypeTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="类型名称" field="typeName" />
+      <vxe-column title="类型描述" field="description" />
+      <vxe-column title="是否启用" field="enableDictMap.name" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImComplaintTypeClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImComplaintType:formTourImComplaintType:editTourImComplaintType')"
+          >
+            编辑
+          </el-button>
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            :size="layoutStore.defaultFormItemSize"-->
+<!--            @click.stop="onDeleteTourImComplaintTypeClick(scope.row)"-->
+<!--            :disabled="!checkPermCodeExist('formTourImComplaintType:formTourImComplaintType:deleteTourImComplaintType')"-->
+<!--          >-->
+<!--            删除-->
+<!--          </el-button>-->
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImComplaintTypeTableWidgetTotalCount"
+            :current-page="formTourImComplaintTypeTableWidgetCurrentPage"
+            :page-size="formTourImComplaintTypeTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImComplaintTypeTableWidget.onCurrentPageChange"
+            @size-change="formTourImComplaintTypeTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImComplaintType',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImComplaintTypeData } from '@/api/generated/tourImComplaintTypeController';
+import { TourImComplaintTypeController } from '@/api/generated';
+import FormEditTourImComplaintType from '@/pages/ImComplaint/formEditTourImComplaintType.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 类型名称
+  typeNameFilter: undefined,
+  // 是否启用
+  enableFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 类型名称
+  typeNameFilter: undefined,
+  // 是否启用
+  enableFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImComplaintType();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImComplaintTypeTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImComplaintTypeDtoFilter: {
+      typeName: formFilter.typeNameFilter,
+      enable: formFilter.enableFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImComplaintTypeController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImComplaintTypeTableVerify = () => {
+  formFilterCopy.typeNameFilter = formFilter.typeNameFilter;
+  formFilterCopy.enableFilter = formFilter.enableFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourImComplaintTypeClick = (row?: TourImComplaintTypeData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImComplaintType, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImComplaintTypeTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourImComplaintTypeClick = (row?: TourImComplaintTypeData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImComplaintType, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImComplaintTypeTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImComplaintTypeClick = (row?: TourImComplaintTypeData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImComplaintTypeController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImComplaintTypeClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImComplaintTypeController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImComplaintTypeTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImComplaintTypeClick = (row?: TourImComplaintTypeData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImComplaintTypeController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImComplaintTypeTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImComplaintTypeTableOptions: TableOptions<TourImComplaintTypeData> = {
+  loadTableData: loadFormTourImComplaintTypeTableWidgetData,
+  verifyTableParameter: loadFormTourImComplaintTypeTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImComplaintTypeTable = ref();
+const formTourImComplaintTypeTableWidget = useTable(formTourImComplaintTypeTableOptions);
+const {
+  dataList: formTourImComplaintTypeTableWidgetDataList,
+  currentPage: formTourImComplaintTypeTableWidgetCurrentPage,
+  pageSize: formTourImComplaintTypeTableWidgetPageSize,
+  totalCount: formTourImComplaintTypeTableWidgetTotalCount,
+} = formTourImComplaintTypeTableWidget;
+/**
+ * 是否启用下拉数据获取函数
+ */
+const loadEnableFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 是否启用配置参数
+const enableFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadEnableFilterDropdownList,
+  isTree: false,
+};
+// 是否启用下拉组件
+const enableFilterWidget = useDropdown(enableFilterOptions);
+const { dropdownList: enableFilterWidgetDropdownList } = enableFilterWidget
+const refreshFormTourImComplaintType = () => {
+  // 刷新段落
+  formTourImComplaintTypeTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImComplaintType = () => {
+  formFilter.typeNameFilter = undefined;
+  formFilterCopy.typeNameFilter = undefined;
+  formFilter.enableFilter = undefined;
+  formFilterCopy.enableFilter = undefined;
+  refreshFormTourImComplaintType();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImComplaintType();
+};
+const formInit = () => {
+  enableFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImComplaintType();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 546 - 0
src/pages/ImComplaint/formTourImComplait.vue

@@ -0,0 +1,546 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImComplaitRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImComplait()" @reset="resetFormTourImComplait">
+        <el-form-item label="举报类型">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.typeIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="typeIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in typeIdFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="举报对象">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.objectTypeFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="objectTypeFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in objectTypeFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="举报描述">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.descriptionFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImComplaitTable"
+      class="page-table"
+      :data="formTourImComplaitTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImComplaitTableWidgetCurrentPage - 1) * formTourImComplaitTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImComplaitTableWidget.onSortChange"
+      @refresh="formTourImComplaitTableWidget.refreshTable()"
+    >
+      <template #operator>
+       <!-- <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:addTourImComplait')"
+          @click="onAddTourImComplaitClick()"
+          >
+          新建
+        </el-button> -->
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:exportTourImComplait')"
+          @click="onExportTourImComplaitClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:importTourImComplait')"
+          :on-change="onImportTourImComplaitClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+              :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:importTourImComplait')"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImComplaitTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="举报类型" field="typeIdDictMap.name" />
+      <vxe-column title="举报对象类型" field="objectTypeDictMap.name" />
+      <vxe-column title="举报对象名称" field="objectTypeDictMap.name">
+        <template v-slot="scope">
+          <span v-if="scope.row.objectType == 2">
+            <span v-if="scope.row.groupIdDictMap">{{ scope.row.groupIdDictMap.name }}</span>
+          </span>
+          <span v-if="scope.row.objectType == 1">
+            <span v-if="scope.row.userIdDictMap">{{ scope.row.userIdDictMap.name }}</span>
+          <span v-else>-</span>
+        </span>
+        </template>
+      </vxe-column>
+
+<!--      <vxe-column title="举报对象id" field="userIdDictMap.name">
+        <template v-slot="scope">
+    <span v-if="scope.row.objectType == 1">
+      {{ scope.row.userId }}
+    </span>
+          <span v-if="scope.row.objectType == 2">
+      {{ scope.row.groupId }}
+    </span>
+        </template>
+      </vxe-column> -->
+
+      <vxe-column title="其他违规理由" field="elseTypeReason" />
+      <vxe-column title="举报描述" field="description" />
+      <vxe-column title="举报图片">
+        <template v-slot="scope">
+          <upload-file-list
+            :file-list="
+              parseUploadData(scope.row.image, {
+                id: scope.row.id,
+                fieldName: 'image',
+                asImage: true
+              })
+            "
+            type="card"
+            direction="horizontal"
+            :readonly="true"
+          />
+        </template>
+      </vxe-column>
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+        <!--  <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImComplaitClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:editTourImComplait')"
+          >
+            编辑
+          </el-button> -->
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourImComplaitClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:deleteTourImComplait')"
+          >
+            删除
+          </el-button>
+          <el-button  link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onBanTourImComplaitClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImComplait:formTourImComplait:deleteTourImComplait')">
+            封禁
+
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImComplaitTableWidgetTotalCount"
+            :current-page="formTourImComplaitTableWidgetCurrentPage"
+            :page-size="formTourImComplaitTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImComplaitTableWidget.onCurrentPageChange"
+            @size-change="formTourImComplaitTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImComplait',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImComplaitData } from '@/api/generated/tourImComplaitController';
+import {TourImComplaitController, TourImGroupController} from '@/api/generated';
+import FormEditTourImComplait from '@/pages/ImComplaint/formEditTourImComplait.vue';
+import "./formTourImComplait.vue";
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 举报类型
+  typeIdFilter: undefined,
+  // 举报对象
+  objectTypeFilter: undefined,
+  // 举报描述
+  descriptionFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 举报类型
+  typeIdFilter: undefined,
+  // 举报对象
+  objectTypeFilter: undefined,
+  // 举报描述
+  descriptionFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImComplait();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImComplaitTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImComplaitDtoFilter: {
+      typeId: formFilter.typeIdFilter,
+      objectType: formFilter.objectTypeFilter,
+      description: formFilter.descriptionFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImComplaitController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImComplaitTableVerify = () => {
+  formFilterCopy.typeIdFilter = formFilter.typeIdFilter;
+  formFilterCopy.objectTypeFilter = formFilter.objectTypeFilter;
+  formFilterCopy.descriptionFilter = formFilter.descriptionFilter;
+  return true;
+};
+
+const onBanTourImComplaitClick = (row?:any)=>{
+  ElMessageBox.confirm('确定封禁该群吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  }).then(() => {
+    let groupId = row?.groupId;
+    TourImGroupController.updateBan({tourImGroupDto:{id:groupId,bannedStatus:0}})
+      .then(res=>{
+        if (res?.success && res?.data){
+          ElMessage.success('封禁成功');
+          formTourImComplaitTableWidget.refreshTable();
+          return;
+        }
+        ElMessage.error("封禁失败");
+      })
+      .catch(res=>{
+        console.log(res)
+      })
+
+    // TourImComplaitController.ban(row?.id).then(res => {
+    //   ElMessage.success('封禁成功');
+    //   formTourImComplaitTableWidget.refreshTable();
+    // }).catch(e => {
+    //   ElMessage.error(e.errorMessage);
+    // })
+  })
+    .catch(() => {
+
+    })
+}
+/**
+ * 新建
+ */
+const onAddTourImComplaitClick = (row?: TourImComplaitData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImComplait, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImComplaitTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourImComplaitClick = (row?: TourImComplaitData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImComplait, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImComplaitTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImComplaitClick = (row?: TourImComplaitData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImComplaitController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImComplaitClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImComplaitController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImComplaitTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImComplaitClick = (row?: TourImComplaitData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImComplaitController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImComplaitTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImComplaitTableOptions: TableOptions<TourImComplaitData> = {
+  loadTableData: loadFormTourImComplaitTableWidgetData,
+  verifyTableParameter: loadFormTourImComplaitTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImComplaitTable = ref();
+const formTourImComplaitTableWidget = useTable(formTourImComplaitTableOptions);
+const {
+  dataList: formTourImComplaitTableWidgetDataList,
+  currentPage: formTourImComplaitTableWidgetCurrentPage,
+  pageSize: formTourImComplaitTableWidgetPageSize,
+  totalCount: formTourImComplaitTableWidgetTotalCount,
+} = formTourImComplaitTableWidget;
+/**
+ * 举报类型下拉数据获取函数
+ */
+const loadTypeIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImComplaintType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 举报类型配置参数
+const typeIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadTypeIdFilterDropdownList,
+  isTree: false,
+};
+// 举报类型下拉组件
+const typeIdFilterWidget = useDropdown(typeIdFilterOptions);
+const { dropdownList: typeIdFilterWidgetDropdownList } = typeIdFilterWidget
+/**
+ * 举报对象下拉数据获取函数
+ */
+const loadObjectTypeFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'ComplaintObjectType', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 举报对象配置参数
+const objectTypeFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadObjectTypeFilterDropdownList,
+  isTree: false,
+};
+// 举报对象下拉组件
+const objectTypeFilterWidget = useDropdown(objectTypeFilterOptions);
+const { dropdownList: objectTypeFilterWidgetDropdownList } = objectTypeFilterWidget
+const refreshFormTourImComplait = () => {
+  // 刷新段落
+  formTourImComplaitTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImComplait = () => {
+  formFilter.typeIdFilter = undefined;
+  formFilterCopy.typeIdFilter = undefined;
+  formFilter.objectTypeFilter = undefined;
+  formFilterCopy.objectTypeFilter = undefined;
+  formFilter.descriptionFilter = undefined;
+  formFilterCopy.descriptionFilter = undefined;
+  refreshFormTourImComplait();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImComplait();
+};
+const formInit = () => {
+  typeIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  objectTypeFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImComplait();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 607 - 0
src/pages/ImGroup/formEditTourImGroup.vue

@@ -0,0 +1,607 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImGroupRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="群主" prop="TourImGroup.leaderId">-->
+<!--              <el-select-->
+<!--                class="input-item"-->
+<!--                v-model="formData.TourImGroup.leaderId"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :filterable="true"-->
+<!--                @visible-change="leaderIdWidget.onVisibleChange"-->
+<!--              >-->
+<!--                <el-option-->
+<!--                  v-for="item in leaderIdWidgetDropdownList"-->
+<!--                  :key="item.id"-->
+<!--                  :label="item.name"-->
+<!--                  :value="item.id"-->
+<!--                />-->
+<!--              </el-select>-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="群聊所属类型" prop="TourImGroup.belongTypeId">-->
+<!--              <el-cascader-->
+<!--                class="input-item"-->
+<!--                v-model="belongTypeIdPath"-->
+<!--                :options="belongTypeIdWidgetDropdownList"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :filterable="true"-->
+<!--                :show-all-levels="false"-->
+<!--                :props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"-->
+<!--                @change="onBelongTypeIdValueChange"-->
+<!--              />-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="群聊名称" prop="TourImGroup.groupName">-->
+<!--              <el-input-->
+<!--                class="input-item"-->
+<!--                v-model="formData.TourImGroup.groupName"-->
+<!--                type="text"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :show-word-limit="false"-->
+<!--                maxlength=""-->
+<!--              />-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="群聊头像" prop="TourImGroup.groupAvatar">-->
+<!--              <custom-upload-->
+<!--                v-model="groupAvatarWidgetFileList"-->
+<!--                name="uploadFile"-->
+<!--                :size="layoutStore.defaultFormItemSize"-->
+<!--                type="expand"-->
+<!--                :headers="getUploadHeaders"-->
+<!--                :action="getUploadActionUrl('/admin/app/tourImGroup/upload')"-->
+<!--                :data="{fieldName: 'groupAvatar', asImage: true}"-->
+<!--                :limit="groupAvatarWidgetMaxCount"-->
+<!--                @change="onGroupAvatarChange"-->
+<!--              />-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="群聊描述" prop="TourImGroup.description">-->
+<!--              <el-input-->
+<!--                class="input-item"-->
+<!--                v-model="formData.TourImGroup.description"-->
+<!--                type="text"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :show-word-limit="false"-->
+<!--                maxlength=""-->
+<!--              />-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="是否公开展示" prop="TourImGroup.isPublic">-->
+<!--              <el-select-->
+<!--                class="input-item"-->
+<!--                v-model="formData.TourImGroup.isPublic"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :filterable="true"-->
+<!--                @visible-change="isPublicWidget.onVisibleChange"-->
+<!--              >-->
+<!--                <el-option-->
+<!--                  v-for="item in isPublicWidgetDropdownList"-->
+<!--                  :key="item.id"-->
+<!--                  :label="item.name"-->
+<!--                  :value="item.id"-->
+<!--                />-->
+<!--              </el-select>-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="是否开启群聊邀请确认" prop="TourImGroup.isNeedConfirm">-->
+<!--              <el-select-->
+<!--                class="input-item"-->
+<!--                v-model="formData.TourImGroup.isNeedConfirm"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :filterable="true"-->
+<!--                @visible-change="isNeedConfirmWidget.onVisibleChange"-->
+<!--              >-->
+<!--                <el-option-->
+<!--                  v-for="item in isNeedConfirmWidgetDropdownList"-->
+<!--                  :key="item.id"-->
+<!--                  :label="item.name"-->
+<!--                  :value="item.id"-->
+<!--                />-->
+<!--              </el-select>-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+<!--          <el-col :span="12">-->
+<!--            <el-form-item label="通知分类 " prop="TourImGroup.noticeType">-->
+<!--              <el-select-->
+<!--                class="input-item"-->
+<!--                v-model="formData.TourImGroup.noticeType"-->
+<!--                placeholder=""-->
+<!--                :clearable="true"-->
+<!--                :filterable="true"-->
+<!--                @visible-change="noticeTypeWidget.onVisibleChange"-->
+<!--              >-->
+<!--                <el-option-->
+<!--                  v-for="item in noticeTypeWidgetDropdownList"-->
+<!--                  :key="item.id"-->
+<!--                  :label="item.name"-->
+<!--                  :value="item.id"-->
+<!--                />-->
+<!--              </el-select>-->
+<!--            </el-form-item>-->
+<!--          </el-col>-->
+          <el-col :span="12">
+            <el-form-item label="是否封禁 " prop="TourImGroup.bannedStatus">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImGroup.bannedStatus"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="bannedStatusWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in bannedStatusWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="热度值" prop="TourImGroup.hotValue">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourImGroup.hotValue"
+                placeholder=""
+                :clearable="true"
+                :step="1"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImGroupClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImGroup',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImMemberData } from '@/api/generated/tourImMemberController';
+import { TourImGroupInvitationData } from '@/api/generated/tourImGroupInvitationController';
+import { TourImMessageData } from '@/api/generated/tourImMessageController';
+import { TourImGroupData } from '@/api/generated/tourImGroupController';
+import { TourImMemberController, TourImGroupInvitationController, TourImMessageController, TourImGroupController } from '@/api/generated';
+import TourUser from "@/types/table/tourUser";
+import {TourUserController} from '@/api/generated';
+
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImGroupRef = ref();
+// 表单数据定义
+type FormEditTourImGroupData = {
+  TourImGroup: TourImGroupData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImGroupData>({
+  TourImGroup: {
+    // id
+    id: undefined,
+    // 群聊所属类型id
+    belongTypeId: undefined,
+    // 群主id
+    leaderId: undefined,
+    // 群聊名称
+    groupName: undefined,
+    // 群聊头像
+    groupAvatar: undefined,
+    // 群聊描述
+    description: undefined,
+    // 是否公开展示 0隐藏 1公开
+    isPublic: undefined,
+    // 是否开启群聊邀请确认 0不开启 1开启
+    isNeedConfirm: undefined,
+    // 通知分类 0单聊 1群聊
+    noticeType: undefined,
+    // 是否封禁 0封禁 1正常
+    bannedStatus: undefined,
+    // 热度值
+    hotValue: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+    // 聊天去聊邀请数据
+    tourImGroupInvitationList: [],
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImGroup.groupName': [
+    {required: true, message: '请输入群聊名称', trigger: 'blur'}
+  ],
+  'TourImGroup.groupAvatar': [
+    {required: true, message: '请输入群聊头像', trigger: 'blur'}
+  ],
+  'TourImGroup.belongTypeId': [
+    {required: true, message: '请输入群聊所属类型', trigger: 'blur'}
+  ],
+  'TourImGroup.leaderId': [
+    {required: true, message: '请输入群主', trigger: 'blur'}
+  ],
+  'TourImGroup.isNeedConfirm': [
+  ],
+  'TourImGroup.description': [
+  ],
+  'TourImGroup.isPublic': [
+  ],
+  'TourImGroup.bannedStatus': [
+    {required: true, message: '请输入是否封禁 ', trigger: 'blur'}
+  ],
+  'TourImGroup.noticeType': [
+    {required: true, message: '请输入通知分类 ', trigger: 'blur'}
+  ],
+  'TourImGroup.hotValue': [
+    {required: true, message: '请输入热度值', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImGroupData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImGroup = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImGroupController.view(params).then(res => {
+      formData.TourImGroup = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 群主下拉数据获取函数
+ */
+const loadLeaderIdDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 群主配置参数
+const leaderIdOptions: DropdownOptions<TourUser> = {
+  loadData: loadLeaderIdDropdownList,
+  isTree: false,
+};
+// 群主下拉组件
+const leaderIdWidget = useDropdown(leaderIdOptions);
+const { dropdownList: leaderIdWidgetDropdownList } = leaderIdWidget
+/**
+ * 群聊所属类型下拉数据获取函数
+ */
+const loadBelongTypeIdDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroupType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 群聊所属类型选中值改变
+ */
+const onBelongTypeIdValueChange = (value) => {
+  formData.TourImGroup.belongTypeId = Array.isArray(value) ? value[value.length - 1] : value;
+};
+// 群聊所属类型配置参数
+const belongTypeIdOptions: DropdownOptions<DictData> = {
+  loadData: loadBelongTypeIdDropdownList,
+  isTree: true,
+};
+// 群聊所属类型选中数据
+const belongTypeIdPath = ref<Array<string | number>>([]);
+// 群聊所属类型下拉组件
+const belongTypeIdWidget = useDropdown(belongTypeIdOptions);
+const { dropdownList: belongTypeIdWidgetDropdownList } = belongTypeIdWidget
+/**
+ * 群聊头像上传文件改变
+ */
+const onGroupAvatarChange = val => {
+  formData.TourImGroup.groupAvatar = fileListToJson(val);
+};
+// 群聊头像上传文件组件
+const groupAvatarWidget = useUploadWidget(1);
+const { fileList: groupAvatarWidgetFileList, maxCount: groupAvatarWidgetMaxCount } = groupAvatarWidget;
+/**
+ * 是否公开展示下拉数据获取函数
+ */
+const loadIsPublicDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 是否公开展示配置参数
+const isPublicOptions: DropdownOptions<DictData> = {
+  loadData: loadIsPublicDropdownList,
+  isTree: false,
+};
+// 是否公开展示下拉组件
+const isPublicWidget = useDropdown(isPublicOptions);
+const { dropdownList: isPublicWidgetDropdownList } = isPublicWidget
+/**
+ * 是否开启群聊邀请确认下拉数据获取函数
+ */
+const loadIsNeedConfirmDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 是否开启群聊邀请确认配置参数
+const isNeedConfirmOptions: DropdownOptions<DictData> = {
+  loadData: loadIsNeedConfirmDropdownList,
+  isTree: false,
+};
+// 是否开启群聊邀请确认下拉组件
+const isNeedConfirmWidget = useDropdown(isNeedConfirmOptions);
+const { dropdownList: isNeedConfirmWidgetDropdownList } = isNeedConfirmWidget
+/**
+ * 通知分类 下拉数据获取函数
+ */
+const loadNoticeTypeDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'TourImSingleOrGroup', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 通知分类 配置参数
+const noticeTypeOptions: DropdownOptions<DictData> = {
+  loadData: loadNoticeTypeDropdownList,
+  isTree: false,
+};
+// 通知分类 下拉组件
+const noticeTypeWidget = useDropdown(noticeTypeOptions);
+const { dropdownList: noticeTypeWidgetDropdownList } = noticeTypeWidget
+/**
+ * 是否封禁 下拉数据获取函数
+ */
+const loadBannedStatusDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 是否封禁 配置参数
+const bannedStatusOptions: DropdownOptions<DictData> = {
+  loadData: loadBannedStatusDropdownList,
+  isTree: false,
+};
+// 是否封禁 下拉组件
+const bannedStatusWidget = useDropdown(bannedStatusOptions);
+const { dropdownList: bannedStatusWidgetDropdownList } = bannedStatusWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImGroup = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImGroup = () => {
+  refreshFormEditTourImGroup();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImGroup();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImGroupClick = () => {
+  formEditTourImGroupRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImGroup
+      };
+    retFormData.leaderIdDictMap = findItemFromList(leaderIdWidgetDropdownList.value, retFormData.leaderId, 'id');
+    retFormData.belongTypeIdDictMap = findTreeNode(belongTypeIdWidgetDropdownList.value, retFormData.belongTypeId, 'id');
+    retFormData.isPublicDictMap = findItemFromList(isPublicWidgetDropdownList.value, retFormData.isPublic, 'id');
+    retFormData.isNeedConfirmDictMap = findItemFromList(isNeedConfirmWidgetDropdownList.value, retFormData.isNeedConfirm, 'id');
+    retFormData.noticeTypeDictMap = findItemFromList(noticeTypeWidgetDropdownList.value, retFormData.noticeType, 'id');
+    retFormData.bannedStatusDictMap = findItemFromList(bannedStatusWidgetDropdownList.value, retFormData.bannedStatus, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImGroupDto: {
+        id: formData.TourImGroup.id,
+        noticeType: formData.TourImGroup.noticeType,
+        belongTypeId: formData.TourImGroup.belongTypeId,
+        leaderId: formData.TourImGroup.leaderId,
+        groupName: formData.TourImGroup.groupName,
+        groupAvatar: formData.TourImGroup.groupAvatar,
+        description: formData.TourImGroup.description,
+        isPublic: formData.TourImGroup.isPublic,
+        isNeedConfirm: formData.TourImGroup.isNeedConfirm,
+        bannedStatus: formData.TourImGroup.bannedStatus,
+        hotValue: formData.TourImGroup.hotValue,
+        createUserId: formData.TourImGroup.createUserId,
+        createTime: formData.TourImGroup.createTime,
+        updateTime: formData.TourImGroup.updateTime,
+        updateUserId: formData.TourImGroup.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImGroupController.update : TourImGroupController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImGroupData().then(res => {
+    leaderIdWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    belongTypeIdWidget.onVisibleChange(true).then(res => {
+      // TODO: 获取级联选中路径
+      belongTypeIdPath.value = findTreeNodePath(res, formData.TourImGroup.belongTypeId);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+    let groupAvatarDownloadParams = {
+      id: formData.TourImGroup.id,
+      fieldName: 'groupAvatar',
+      asImage: true
+    };
+    groupAvatarWidgetFileList.value = parseUploadData(formData.TourImGroup.groupAvatar, groupAvatarDownloadParams);
+    isPublicWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    isNeedConfirmWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    noticeTypeWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    bannedStatusWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshFormEditTourImGroup();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 278 - 0
src/pages/ImGroup/formEditTourImGroupInvitation.vue

@@ -0,0 +1,278 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImGroupInvitationRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="邀请状态 " prop="TourImGroupInvitation.status">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImGroupInvitation.status"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="statusWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in statusWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImGroupInvitationClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImGroupInvitation',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImGroupInvitationData } from '@/api/generated/tourImGroupInvitationController';
+import { TourImGroupInvitationController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImGroupInvitationRef = ref();
+// 表单数据定义
+type FormEditTourImGroupInvitationData = {
+  TourImGroupInvitation: TourImGroupInvitationData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImGroupInvitationData>({
+  TourImGroupInvitation: {
+    // id
+    id: undefined,
+    // 聊天群组id
+    groupId: undefined,
+    // 邀请人id
+    inviter: undefined,
+    // 被邀请人id
+    invitee: undefined,
+    // 邀请状态 1待确认 2同意 3不同意
+    status: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImGroupInvitation.status': [
+    {required: true, message: '请输入邀请状态 ', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImGroupInvitationData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImGroupInvitation = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImGroupInvitationController.view(params).then(res => {
+      formData.TourImGroupInvitation = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 邀请状态 下拉数据获取函数
+ */
+const loadStatusDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'GroupInvitationStatus', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 邀请状态 配置参数
+const statusOptions: DropdownOptions<DictData> = {
+  loadData: loadStatusDropdownList,
+  isTree: false,
+};
+// 邀请状态 下拉组件
+const statusWidget = useDropdown(statusOptions);
+const { dropdownList: statusWidgetDropdownList } = statusWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImGroupInvitation = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImGroupInvitation = () => {
+  refreshFormEditTourImGroupInvitation();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImGroupInvitation();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImGroupInvitationClick = () => {
+  formEditTourImGroupInvitationRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImGroupInvitation
+      };
+    retFormData.statusDictMap = findItemFromList(statusWidgetDropdownList.value, retFormData.status, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImGroupInvitationDto: {
+        id: formData.TourImGroupInvitation.id,
+        groupId: formData.TourImGroupInvitation.groupId,
+        inviter: formData.TourImGroupInvitation.inviter,
+        invitee: formData.TourImGroupInvitation.invitee,
+        status: formData.TourImGroupInvitation.status,
+        createUserId: formData.TourImGroupInvitation.createUserId,
+        createTime: formData.TourImGroupInvitation.createTime,
+        updateTime: formData.TourImGroupInvitation.updateTime,
+        updateUserId: formData.TourImGroupInvitation.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImGroupInvitationController.update : TourImGroupInvitationController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImGroupInvitationData().then(res => {
+    statusWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshFormEditTourImGroupInvitation();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 382 - 0
src/pages/ImGroup/formEditTourImGroupType.vue

@@ -0,0 +1,382 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImGroupTypeRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-alert
+                type="warning"
+                title="*如果一级类型不选择,二级类型将自动变成一级类型"
+                :closable="false"
+                style="margin-bottom: 10px;margin-left: 50px; border-color: #FFA500; color: #FFA500; background-color: rgba(255, 165, 0, 0.1);"
+            />
+          <el-col :span="12">
+            <el-form-item label="一级类型" prop="TourImGroupType.parentId">
+              <el-cascader
+                class="input-item"
+                v-model="parentIdPath"
+                :options="parentIdWidgetDropdownList"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                :show-all-levels="false"
+                :props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"
+                @change="onParentIdValueChange"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="二级类型" prop="TourImGroupType.typeName">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImGroupType.typeName"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="类型图标" prop="TourImGroupType.typeIcon">
+              <custom-upload
+                v-model="typeIconWidgetFileList"
+                name="uploadFile"
+                :size="layoutStore.defaultFormItemSize"
+                type="expand"
+                :headers="getUploadHeaders"
+                :action="getUploadActionUrl('/admin/app/tourImGroupType/upload')"
+                :data="{fieldName: 'typeIcon', asImage: true}"
+                :limit="typeIconWidgetMaxCount"
+                @change="onTypeIconChange"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="是否启用 " prop="TourImGroupType.enable">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImGroupType.enable"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="enableWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in enableWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImGroupTypeClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImGroupType',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImGroupTypeData } from '@/api/generated/tourImGroupTypeController';
+import { TourImGroupTypeController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImGroupTypeRef = ref();
+// 表单数据定义
+type FormEditTourImGroupTypeData = {
+  TourImGroupType: TourImGroupTypeData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImGroupTypeData>({
+  TourImGroupType: {
+    // id
+    id: undefined,
+    // 父级id
+    parentId: undefined,
+    // 类型名称
+    typeName: undefined,
+    // 类型图标
+    typeIcon: undefined,
+    // 是否启用 0否 1是
+    enable: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImGroupType.enable': [
+  ],
+  'TourImGroupType.parentId': [
+  ],
+  'TourImGroupType.typeIcon': [
+  ],
+  'TourImGroupType.typeName': [
+    {required: true, message: '请输入二级类型', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImGroupTypeData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImGroupType = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImGroupTypeController.view(params).then(res => {
+      formData.TourImGroupType = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 一级类型下拉数据获取函数
+ */
+const loadParentIdDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroupType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 一级类型选中值改变
+ */
+const onParentIdValueChange = (value) => {
+  formData.TourImGroupType.parentId = Array.isArray(value) ? value[value.length - 1] : value;
+};
+// 一级类型配置参数
+const parentIdOptions: DropdownOptions<DictData> = {
+  loadData: loadParentIdDropdownList,
+  isTree: true,
+};
+// 一级类型选中数据
+const parentIdPath = ref<Array<string | number>>([]);
+// 一级类型下拉组件
+const parentIdWidget = useDropdown(parentIdOptions);
+const { dropdownList: parentIdWidgetDropdownList } = parentIdWidget
+/**
+ * 类型图标上传文件改变
+ */
+const onTypeIconChange = val => {
+  formData.TourImGroupType.typeIcon = fileListToJson(val);
+};
+// 类型图标上传文件组件
+const typeIconWidget = useUploadWidget(1);
+const { fileList: typeIconWidgetFileList, maxCount: typeIconWidgetMaxCount } = typeIconWidget;
+/**
+ * 是否启用 下拉数据获取函数
+ */
+const loadEnableDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 是否启用 配置参数
+const enableOptions: DropdownOptions<DictData> = {
+  loadData: loadEnableDropdownList,
+  isTree: false,
+};
+// 是否启用 下拉组件
+const enableWidget = useDropdown(enableOptions);
+const { dropdownList: enableWidgetDropdownList } = enableWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImGroupType = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImGroupType = () => {
+  refreshFormEditTourImGroupType();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImGroupType();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImGroupTypeClick = () => {
+  formEditTourImGroupTypeRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImGroupType
+      };
+    retFormData.parentIdDictMap = findTreeNode(parentIdWidgetDropdownList.value, retFormData.parentId, 'id');
+    retFormData.enableDictMap = findItemFromList(enableWidgetDropdownList.value, retFormData.enable, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImGroupTypeDto: {
+        id: formData.TourImGroupType.id,
+        parentId: formData.TourImGroupType.parentId,
+        typeName: formData.TourImGroupType.typeName,
+        typeIcon: formData.TourImGroupType.typeIcon,
+        enable: formData.TourImGroupType.enable,
+        createUserId: formData.TourImGroupType.createUserId,
+        createTime: formData.TourImGroupType.createTime,
+        updateTime: formData.TourImGroupType.updateTime,
+        updateUserId: formData.TourImGroupType.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImGroupTypeController.update : TourImGroupTypeController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImGroupTypeData().then(res => {
+    parentIdWidget.onVisibleChange(true).then(res => {
+      // TODO: 获取级联选中路径
+      parentIdPath.value = findTreeNodePath(res, formData.TourImGroupType.parentId);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+    let typeIconDownloadParams = {
+      id: formData.TourImGroupType.id,
+      fieldName: 'typeIcon',
+      asImage: true
+    };
+    typeIconWidgetFileList.value = parseUploadData(formData.TourImGroupType.typeIcon, typeIconDownloadParams);
+    enableWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshFormEditTourImGroupType();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 260 - 0
src/pages/ImGroup/formEditTourImMember.vue

@@ -0,0 +1,260 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImMemberRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="删除标记 " prop="TourImMember.dataState">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourImMember.dataState"
+                placeholder=""
+                :clearable="true"
+                :step="1"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImMemberClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImMember',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImMemberData } from '@/api/generated/tourImMemberController';
+import { TourImMemberController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImMemberRef = ref();
+// 表单数据定义
+type FormEditTourImMemberData = {
+  TourImMember: TourImMemberData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImMemberData>({
+  TourImMember: {
+    // id
+    id: undefined,
+    // 聊天群组id
+    groupId: undefined,
+    // 成员角色 1群主 2管理员 3普通成员
+    groupRole: undefined,
+    // 用户id
+    userId: undefined,
+    // 会话是否显示(每个群在聊天列表要不要展示) 0不显示 1显示
+    isShow: undefined,
+    // 会话是否置顶 (每个群在聊天列表要不要置顶)  0不置顶 1 置顶
+    isTop: undefined,
+    // 会话是否开启免打扰 0不开启免打扰 1 开启免打扰
+    isNotDisturb: undefined,
+    // 自己在群里的昵称
+    groupNickname: undefined,
+    // 群备注
+    groupRemark: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 聊天背景
+    groupBackImage: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImMember.dataState': [
+    {required: true, message: '请输入删除标记 ', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImMemberData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImMember = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImMemberController.view(params).then(res => {
+      formData.TourImMember = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImMember = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImMember = () => {
+  refreshFormEditTourImMember();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImMember();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImMemberClick = () => {
+  formEditTourImMemberRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImMember
+      };
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImMemberDto: {
+        id: formData.TourImMember.id,
+        groupId: formData.TourImMember.groupId,
+        groupRole: formData.TourImMember.groupRole,
+        isShow: formData.TourImMember.isShow,
+        isTop: formData.TourImMember.isTop,
+        isNotDisturb: formData.TourImMember.isNotDisturb,
+        groupNickname: formData.TourImMember.groupNickname,
+        groupRemark: formData.TourImMember.groupRemark,
+        createUserId: formData.TourImMember.createUserId,
+        createTime: formData.TourImMember.createTime,
+        updateTime: formData.TourImMember.updateTime,
+        updateUserId: formData.TourImMember.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImMemberController.update : TourImMemberController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImMemberData().then(res => {
+    if (isEdit.value) refreshFormEditTourImMember();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 524 - 0
src/pages/ImGroup/formEditTourImMessage.vue

@@ -0,0 +1,524 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImMessageRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="通知消息类型 " prop="TourImMessage.noticeType">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImMessage.noticeType"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="noticeType_copyWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in noticeType_copyWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="消息内容" prop="TourImMessage.messageContent">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImMessage.messageContent"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="消息类型" prop="TourImMessage.messageType">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImMessage.messageType"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="messageTypeWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in messageTypeWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="聊天群组" prop="TourImMessage.groupId">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImMessage.groupId"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="groupIdWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in groupIdWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="消息置顶/公告" prop="TourImMessage.isTop">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImMessage.isTop"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="isTopWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in isTopWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="撤回标记 " prop="TourImMessage.revocationTag">
+              <el-select
+                class="input-item"
+                v-model="formData.TourImMessage.revocationTag"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="revocationTagWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in revocationTagWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="已经删除该条消息的用户" prop="TourImMessage.deletedByUsers">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImMessage.deletedByUsers"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="已读该条消息的用户" prop="TourImMessage.readByUsers">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImMessage.readByUsers"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="删除标记" prop="TourImMessage.dataState">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourImMessage.dataState"
+                placeholder=""
+                :clearable="true"
+                :step="1"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImMessageClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImMessage',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImMessageData } from '@/api/generated/tourImMessageController';
+import { TourImMessageController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImMessageRef = ref();
+// 表单数据定义
+type FormEditTourImMessageData = {
+  TourImMessage: TourImMessageData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImMessageData>({
+  TourImMessage: {
+    // id
+    id: undefined,
+    // 消息内容
+    messageContent: undefined,
+    // 消息类型 0文字 1文件 2系统消息
+    messageType: undefined,
+    // 聊天群组id
+    groupId: undefined,
+    // 通知消息类型 1.单聊消息 2 群聊消息 3系统消息 4关注信息 5点赞 6评论 7评论区艾特 8文章内艾特 9访问
+    noticeType: undefined,
+    // 消息置顶/公告 0不置顶 1置顶
+    isTop: undefined,
+    // 撤回标记 0不撤回 1撤回
+    revocationTag: undefined,
+    // 已经删除该条消息的用户
+    deletedByUsers: undefined,
+    // 已读该条消息的用户
+    readByUsers: undefined,
+    // 删除标记 1正常 -1删除
+    dataState: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImMessage.noticeType': [
+    {required: true, message: '请输入通知消息类型 ', trigger: 'blur'}
+  ],
+  'TourImMessage.messageContent': [
+    {required: true, message: '请输入消息内容', trigger: 'blur'}
+  ],
+  'TourImMessage.messageType': [
+    {required: true, message: '请输入消息类型', trigger: 'blur'}
+  ],
+  'TourImMessage.groupId': [
+    {required: true, message: '请输入聊天群组', trigger: 'blur'}
+  ],
+  'TourImMessage.isTop': [
+    {required: true, message: '请输入消息置顶/公告', trigger: 'blur'}
+  ],
+  'TourImMessage.readByUsers': [
+  ],
+  'TourImMessage.dataState': [
+    {required: true, message: '请输入删除标记', trigger: 'blur'}
+  ],
+  'TourImMessage.revocationTag': [
+    {required: true, message: '请输入撤回标记 ', trigger: 'blur'}
+  ],
+  'TourImMessage.deletedByUsers': [
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImMessageData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImMessage = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImMessageController.view(params).then(res => {
+      formData.TourImMessage = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 通知消息类型 下拉数据获取函数
+ */
+const loadNoticeType_copyDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'TourImNoticeType', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 通知消息类型 配置参数
+const noticeType_copyOptions: DropdownOptions<DictData> = {
+  loadData: loadNoticeType_copyDropdownList,
+  isTree: false,
+};
+// 通知消息类型 下拉组件
+const noticeType_copyWidget = useDropdown(noticeType_copyOptions);
+const { dropdownList: noticeType_copyWidgetDropdownList } = noticeType_copyWidget
+/**
+ * 消息类型下拉数据获取函数
+ */
+const loadMessageTypeDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'MessageType', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 消息类型配置参数
+const messageTypeOptions: DropdownOptions<DictData> = {
+  loadData: loadMessageTypeDropdownList,
+  isTree: false,
+};
+// 消息类型下拉组件
+const messageTypeWidget = useDropdown(messageTypeOptions);
+const { dropdownList: messageTypeWidgetDropdownList } = messageTypeWidget
+/**
+ * 聊天群组下拉数据获取函数
+ */
+const loadGroupIdDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroup(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 聊天群组配置参数
+const groupIdOptions: DropdownOptions<DictData> = {
+  loadData: loadGroupIdDropdownList,
+  isTree: false,
+};
+// 聊天群组下拉组件
+const groupIdWidget = useDropdown(groupIdOptions);
+const { dropdownList: groupIdWidgetDropdownList } = groupIdWidget
+/**
+ * 消息置顶/公告下拉数据获取函数
+ */
+const loadIsTopDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 消息置顶/公告配置参数
+const isTopOptions: DropdownOptions<DictData> = {
+  loadData: loadIsTopDropdownList,
+  isTree: false,
+};
+// 消息置顶/公告下拉组件
+const isTopWidget = useDropdown(isTopOptions);
+const { dropdownList: isTopWidgetDropdownList } = isTopWidget
+/**
+ * 撤回标记 下拉数据获取函数
+ */
+const loadRevocationTagDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 撤回标记 配置参数
+const revocationTagOptions: DropdownOptions<DictData> = {
+  loadData: loadRevocationTagDropdownList,
+  isTree: false,
+};
+// 撤回标记 下拉组件
+const revocationTagWidget = useDropdown(revocationTagOptions);
+const { dropdownList: revocationTagWidgetDropdownList } = revocationTagWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImMessage = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImMessage = () => {
+  refreshFormEditTourImMessage();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImMessage();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImMessageClick = () => {
+  formEditTourImMessageRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImMessage
+      };
+    retFormData.noticeTypeDictMap = findItemFromList(noticeType_copyWidgetDropdownList.value, retFormData.noticeType, 'id');
+    retFormData.messageTypeDictMap = findItemFromList(messageTypeWidgetDropdownList.value, retFormData.messageType, 'id');
+    retFormData.groupIdDictMap = findItemFromList(groupIdWidgetDropdownList.value, retFormData.groupId, 'id');
+    retFormData.isTopDictMap = findItemFromList(isTopWidgetDropdownList.value, retFormData.isTop, 'id');
+    retFormData.revocationTagDictMap = findItemFromList(revocationTagWidgetDropdownList.value, retFormData.revocationTag, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImMessageDto: {
+        id: formData.TourImMessage.id,
+        messageContent: formData.TourImMessage.messageContent,
+        messageType: formData.TourImMessage.messageType,
+        groupId: formData.TourImMessage.groupId,
+        isTop: formData.TourImMessage.isTop,
+        revocationTag: formData.TourImMessage.revocationTag,
+        deletedByUsers: formData.TourImMessage.deletedByUsers,
+        readByUsers: formData.TourImMessage.readByUsers,
+        createUserId: formData.TourImMessage.createUserId,
+        createTime: formData.TourImMessage.createTime,
+        updateTime: formData.TourImMessage.updateTime,
+        updateUserId: formData.TourImMessage.updateUserId,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImMessageController.update : TourImMessageController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImMessageData().then(res => {
+    noticeType_copyWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    messageTypeWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    groupIdWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    isTopWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    revocationTagWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshFormEditTourImMessage();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 789 - 0
src/pages/ImGroup/formTourImGroup.vue

@@ -0,0 +1,789 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImGroupRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImGroup()" @reset="resetFormTourImGroup">
+<!--        <el-form-item label="群聊所属类型">-->
+<!--          <el-cascader-->
+<!--            class="filter-item"-->
+<!--            v-model="belongTypeIdFilterPath"-->
+<!--            :options="belongTypeIdFilterWidgetDropdownList"-->
+<!--            placeholder=""-->
+<!--            :clearable="true"-->
+<!--            :filterable="true"-->
+<!--            :show-all-levels="false"-->
+<!--            :props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"-->
+<!--            @change="onBelongTypeIdFilterValueChange"-->
+<!--          />-->
+<!--        </el-form-item>-->
+        <el-form-item label="群主">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.leaderIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="leaderIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in leaderIdFilterWidgetDropdownList"
+              :key="item.userId"
+              :label="item.showName"
+              :value="item.userId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="群聊名称">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.groupNameFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+<!--        <el-form-item label="群聊描述">-->
+<!--          <el-input-->
+<!--            class="filter-item"-->
+<!--            v-model="formFilter.descriptionFilter"-->
+<!--            type="text"-->
+<!--            placeholder=""-->
+<!--            :clearable="true"-->
+<!--            :show-word-limit="false"-->
+<!--            maxlength=""-->
+<!--          />-->
+<!--        </el-form-item>-->
+<!--        <el-form-item label="单聊群聊">-->
+<!--          <el-select-->
+<!--            class="filter-item"-->
+<!--            v-model="formFilter.noticeTypeFilter"-->
+<!--            placeholder=""-->
+<!--            :clearable="true"-->
+<!--            :filterable="true"-->
+<!--            @visible-change="noticeTypeFilterWidget.onVisibleChange"-->
+<!--          >-->
+<!--            <el-option-->
+<!--              v-for="item in noticeTypeFilterWidgetDropdownList"-->
+<!--              :key="item.id"-->
+<!--              :label="item.name"-->
+<!--              :value="item.id"-->
+<!--            />-->
+<!--          </el-select>-->
+<!--        </el-form-item>-->
+<!--        <el-form-item label="是否公开展示">-->
+<!--          <el-select-->
+<!--            class="filter-item"-->
+<!--            v-model="formFilter.isPublicFilter"-->
+<!--            placeholder=""-->
+<!--            :clearable="true"-->
+<!--            :filterable="true"-->
+<!--            @visible-change="isPublicFilterWidget.onVisibleChange"-->
+<!--          >-->
+<!--            <el-option-->
+<!--              v-for="item in isPublicFilterWidgetDropdownList"-->
+<!--              :key="item.id"-->
+<!--              :label="item.name"-->
+<!--              :value="item.id"-->
+<!--            />-->
+<!--          </el-select>-->
+<!--        </el-form-item>-->
+<!--        <el-form-item label="是否开启群聊邀请">-->
+<!--          <el-select-->
+<!--            class="filter-item"-->
+<!--            v-model="formFilter.isNeedConfirmFilter"-->
+<!--            placeholder=""-->
+<!--            :clearable="true"-->
+<!--            :filterable="true"-->
+<!--            @visible-change="isNeedConfirmFilterWidget.onVisibleChange"-->
+<!--          >-->
+<!--            <el-option-->
+<!--              v-for="item in isNeedConfirmFilterWidgetDropdownList"-->
+<!--              :key="item.id"-->
+<!--              :label="item.name"-->
+<!--              :value="item.id"-->
+<!--            />-->
+<!--          </el-select>-->
+<!--        </el-form-item>-->
+        <el-form-item label="是否封禁 ">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.bannedStatusFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="bannedStatusFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in bannedStatusFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="热度值">
+          <input-number-range
+            class="filter-item"
+            v-model="formFilter.hotValueFilter"
+            startPlaceholder=""
+            endPlaceholder=""
+            :step="1"
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImGroupTable"
+      class="page-table"
+      :data="formTourImGroupTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImGroupTableWidgetCurrentPage - 1) * formTourImGroupTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImGroupTableWidget.onSortChange"
+      @refresh="formTourImGroupTableWidget.refreshTable()"
+    >
+      <template #operator>
+<!--        <el-button-->
+<!--          type="primary"-->
+<!--          :size="layoutStore.defaultFormItemSize"-->
+<!--          @click="onAddTourImGroupClick()"-->
+<!--          >-->
+<!--          新建-->
+<!--        </el-button>-->
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onExportTourImGroupClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :on-change="onImportTourImGroupClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImGroupTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="群聊类型" field="belongTypeIdDictMap.name" />
+<!--      <vxe-column title="单聊群聊" field="belongTypeIdDictMap.name" />-->
+      <vxe-column title="群主" field="leaderIdDictMap.name" />
+      <vxe-column title="群聊名称" field="groupName" />
+      <vxe-column title="群聊头像">
+        <template v-slot="scope">
+          <upload-file-list
+            :file-list="
+              parseUploadData(scope.row.groupAvatar, {
+                id: scope.row.id,
+                fieldName: 'groupAvatar',
+                asImage: true
+              })
+            "
+            type="card"
+            direction="horizontal"
+            :readonly="true"
+          />
+        </template>
+      </vxe-column>
+      <vxe-column title="群聊描述" field="description" />
+<!--      <vxe-column title="是否公开展示" field="isPublicDictMap.name" />-->
+<!--      <vxe-column title="是否开启群聊邀请确认" field="isNeedConfirmDictMap.name" />-->
+<!--      <vxe-column title="通知分类 " field="noticeTypeDictMap.name" />-->
+      <vxe-column title="是否封禁 " field="bannedStatusDictMap.name" />
+      <vxe-column title="热度值" field="hotValue" />
+<!--      <vxe-column title="创建人id" field="createUserId" />-->
+      <vxe-column title="创建时间" field="createTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            :size="layoutStore.defaultFormItemSize"-->
+<!--            @click.stop="onListTourImGroupInvitationClick(scope.row)"-->
+<!--          >-->
+<!--            聊天去聊邀请-->
+<!--          </el-button>-->
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onListTourImMemberClick(scope.row)"
+          >
+            聊天群聊成员
+          </el-button>
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            :size="layoutStore.defaultFormItemSize"-->
+<!--            @click.stop="onListTourImMessageClick(scope.row)"-->
+<!--          >-->
+<!--            聊天群聊消息-->
+<!--          </el-button>-->
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImGroupClick(scope.row)"
+          >
+            编辑
+          </el-button>
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            :size="layoutStore.defaultFormItemSize"-->
+<!--            @click.stop="onDeleteTourImGroupClick(scope.row)"-->
+<!--          >-->
+<!--            删除-->
+<!--          </el-button>-->
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImGroupTableWidgetTotalCount"
+            :current-page="formTourImGroupTableWidgetCurrentPage"
+            :page-size="formTourImGroupTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImGroupTableWidget.onCurrentPageChange"
+            @size-change="formTourImGroupTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImGroup',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImMemberData } from '@/api/generated/tourImMemberController';
+import { TourImGroupInvitationData } from '@/api/generated/tourImGroupInvitationController';
+import { TourImMessageData } from '@/api/generated/tourImMessageController';
+import { TourImGroupData } from '@/api/generated/tourImGroupController';
+import {
+  TourImMemberController,
+  TourImGroupInvitationController,
+  TourImMessageController,
+  TourImGroupController,
+  TourUserController
+} from '@/api/generated';
+import FormTourImGroupInvitation from '@/pages/ImGroup/formTourImGroupInvitation.vue';
+import FormEditTourImGroup from '@/pages/ImGroup/formEditTourImGroup.vue';
+import FormTourImMessage from '@/pages/ImGroup/formTourImMessage.vue';
+import FormTourImMember from '@/pages/ImGroup/formTourImMember.vue';
+import TourUser from "@/types/table/tourUser";
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    groupId?: ANY_OBJECT;
+  }>(),
+  {
+    subPage: 0,
+    groupId: undefined,
+  },
+);
+
+const formFilter = reactive({
+  // 群聊所属类型
+  belongTypeIdFilter: undefined,
+  // 群主
+  leaderIdFilter: undefined,
+  // 群聊名称
+  groupNameFilter: undefined,
+  // 群聊描述
+  descriptionFilter: undefined,
+  // 通知分类
+  noticeTypeFilter: undefined,
+  // 是否公开展示
+  isPublicFilter: undefined,
+  // 是否开启群聊邀请
+  isNeedConfirmFilter: undefined,
+  // 是否封禁
+  bannedStatusFilter: undefined,
+  // 热度值
+  hotValueFilter: [],
+});
+const formFilterCopy = reactive({
+  // 群聊所属类型
+  belongTypeIdFilter: undefined,
+  // 群主
+  leaderIdFilter: undefined,
+  // 群聊名称
+  groupNameFilter: undefined,
+  // 群聊描述
+  descriptionFilter: undefined,
+  // 通知分类
+  noticeTypeFilter: undefined,
+  // 是否公开展示
+  isPublicFilter: undefined,
+  // 是否开启群聊邀请
+  isNeedConfirmFilter: undefined,
+  // 是否封禁
+  bannedStatusFilter: undefined,
+  // 热度值
+  hotValueFilter: [],
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImGroup();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImGroupTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImGroupDtoFilter: {
+      leaderId: formFilter.leaderIdFilter,
+      noticeType: formFilter.noticeTypeFilter,
+      groupName: formFilter.groupNameFilter,
+      description: formFilter.descriptionFilter,
+      isPublic: formFilter.isPublicFilter,
+      isNeedConfirm: formFilter.isNeedConfirmFilter,
+      bannedStatus: formFilter.bannedStatusFilter,
+      hotValueStart: Array.isArray(formFilter.hotValueFilter) ? formFilter.hotValueFilter[0] : formFilter.hotValueFilter,
+      hotValueEnd: Array.isArray(formFilter.hotValueFilter) ? formFilter.hotValueFilter[1] : formFilter.hotValueFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImGroupController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImGroupTableVerify = () => {
+  formFilterCopy.belongTypeIdFilter = formFilter.belongTypeIdFilter;
+  formFilterCopy.leaderIdFilter = formFilter.leaderIdFilter;
+  formFilterCopy.groupNameFilter = formFilter.groupNameFilter;
+  formFilterCopy.descriptionFilter = formFilter.descriptionFilter;
+  formFilterCopy.noticeTypeFilter = formFilter.noticeTypeFilter;
+  formFilterCopy.isPublicFilter = formFilter.isPublicFilter;
+  formFilterCopy.isNeedConfirmFilter = formFilter.isNeedConfirmFilter;
+  formFilterCopy.bannedStatusFilter = formFilter.bannedStatusFilter;
+  formFilterCopy.hotValueFilter = formFilter.hotValueFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourImGroupClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImGroup, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImGroupTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 聊天去聊邀请
+ */
+const onListTourImGroupInvitationClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+    groupId: row?.id,
+  };
+
+  router.push({
+    name: 'formTourImGroupInvitation',
+    query: { ...params, subPage: true }
+  });
+};
+/**
+ * 聊天群聊成员
+ */
+const onListTourImMemberClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+    groupId: row?.id,
+  };
+
+  router.push({
+    name: 'formTourImMember',
+    query: { ...params, subPage: true }
+  });
+};
+/**
+ * 聊天群聊消息
+ */
+const onListTourImMessageClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+    groupId: row?.id,
+  };
+
+  router.push({
+    name: 'formTourImMessage',
+    query: { ...params, subPage: true }
+  });
+};
+/**
+ * 编辑
+ */
+const onEditTourImGroupClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImGroup, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImGroupTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImGroupClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImGroupController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImGroupClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImGroupController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImGroupTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImGroupClick = (row?: TourImGroupData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImGroupController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImGroupTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImGroupTableOptions: TableOptions<TourImGroupData> = {
+  loadTableData: loadFormTourImGroupTableWidgetData,
+  verifyTableParameter: loadFormTourImGroupTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImGroupTable = ref();
+const formTourImGroupTableWidget = useTable(formTourImGroupTableOptions);
+const {
+  dataList: formTourImGroupTableWidgetDataList,
+  currentPage: formTourImGroupTableWidgetCurrentPage,
+  pageSize: formTourImGroupTableWidgetPageSize,
+  totalCount: formTourImGroupTableWidgetTotalCount,
+} = formTourImGroupTableWidget;
+/**
+ * 群聊所属类型下拉数据获取函数
+ */
+const loadBelongTypeIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroupType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 群聊所属类型选中值改变
+ */
+const onBelongTypeIdFilterValueChange = (value) => {
+  formFilter.belongTypeIdFilter = Array.isArray(value) ? value[value.length - 1] : value;
+};
+// 群聊所属类型配置参数
+const belongTypeIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadBelongTypeIdFilterDropdownList,
+  isTree: true,
+};
+// 群聊所属类型选中数据
+const belongTypeIdFilterPath = ref<Array<string | number>>([]);
+// 群聊所属类型下拉组件
+const belongTypeIdFilterWidget = useDropdown(belongTypeIdFilterOptions);
+const { dropdownList: belongTypeIdFilterWidgetDropdownList } = belongTypeIdFilterWidget
+/**
+ * 群主下拉数据获取函数
+ */
+const loadLeaderIdFilterDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 群主配置参数
+const leaderIdFilterOptions: DropdownOptions<TourUser> = {
+  loadData: loadLeaderIdFilterDropdownList,
+  isTree: false,
+};
+// 群主下拉组件
+const leaderIdFilterWidget = useDropdown(leaderIdFilterOptions);
+const { dropdownList: leaderIdFilterWidgetDropdownList } = leaderIdFilterWidget
+/**
+ * 通知分类下拉数据获取函数
+ */
+const loadNoticeTypeFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'TourImSingleOrGroup', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 通知分类配置参数
+const noticeTypeFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadNoticeTypeFilterDropdownList,
+  isTree: false,
+};
+// 通知分类下拉组件
+const noticeTypeFilterWidget = useDropdown(noticeTypeFilterOptions);
+const { dropdownList: noticeTypeFilterWidgetDropdownList } = noticeTypeFilterWidget
+/**
+ * 是否公开展示下拉数据获取函数
+ */
+const loadIsPublicFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 是否公开展示配置参数
+const isPublicFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIsPublicFilterDropdownList,
+  isTree: false,
+};
+// 是否公开展示下拉组件
+const isPublicFilterWidget = useDropdown(isPublicFilterOptions);
+const { dropdownList: isPublicFilterWidgetDropdownList } = isPublicFilterWidget
+/**
+ * 是否开启群聊邀请下拉数据获取函数
+ */
+const loadIsNeedConfirmFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 是否开启群聊邀请配置参数
+const isNeedConfirmFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIsNeedConfirmFilterDropdownList,
+  isTree: false,
+};
+// 是否开启群聊邀请下拉组件
+const isNeedConfirmFilterWidget = useDropdown(isNeedConfirmFilterOptions);
+const { dropdownList: isNeedConfirmFilterWidgetDropdownList } = isNeedConfirmFilterWidget
+/**
+ * 是否封禁 下拉数据获取函数
+ */
+const loadBannedStatusFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 是否封禁 配置参数
+const bannedStatusFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadBannedStatusFilterDropdownList,
+  isTree: false,
+};
+// 是否封禁 下拉组件
+const bannedStatusFilterWidget = useDropdown(bannedStatusFilterOptions);
+const { dropdownList: bannedStatusFilterWidgetDropdownList } = bannedStatusFilterWidget
+const refreshFormTourImGroup = () => {
+  // 刷新段落
+  formTourImGroupTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImGroup = () => {
+  formFilter.belongTypeIdFilter = undefined;
+  formFilterCopy.belongTypeIdFilter = undefined;
+  belongTypeIdFilterPath.value = [];
+  formFilter.leaderIdFilter = undefined;
+  formFilterCopy.leaderIdFilter = undefined;
+  formFilter.groupNameFilter = undefined;
+  formFilterCopy.groupNameFilter = undefined;
+  formFilter.descriptionFilter = undefined;
+  formFilterCopy.descriptionFilter = undefined;
+  formFilter.noticeTypeFilter = undefined;
+  formFilterCopy.noticeTypeFilter = undefined;
+  formFilter.isPublicFilter = undefined;
+  formFilterCopy.isPublicFilter = undefined;
+  formFilter.isNeedConfirmFilter = undefined;
+  formFilterCopy.isNeedConfirmFilter = undefined;
+  formFilter.bannedStatusFilter = undefined;
+  formFilterCopy.bannedStatusFilter = undefined;
+  formFilter.hotValueFilter = undefined;
+  formFilterCopy.hotValueFilter = undefined;
+  refreshFormTourImGroup();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImGroup();
+};
+const formInit = () => {
+  belongTypeIdFilterWidget.onVisibleChange(true).then(res => {
+    // TODO: 获取级联选中路径
+    belongTypeIdFilterPath.value = findTreeNodePath(res, formFilter.belongTypeIdFilter);
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+  leaderIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  noticeTypeFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  isPublicFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  isNeedConfirmFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  bannedStatusFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImGroup();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 528 - 0
src/pages/ImGroup/formTourImGroupInvitation.vue

@@ -0,0 +1,528 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImGroupInvitationRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImGroupInvitation()" @reset="resetFormTourImGroupInvitation">
+        <el-form-item label="聊天群组">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.groupIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="groupIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in groupIdFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="邀请人">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.inviterFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="inviterFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in inviterFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="被邀请人">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.inviteeFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="inviteeFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in inviteeFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="邀请状态 ">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.statusFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="statusFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in statusFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImGroupInvitationTable"
+      class="page-table"
+      :data="formTourImGroupInvitationTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImGroupInvitationTableWidgetCurrentPage - 1) * formTourImGroupInvitationTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImGroupInvitationTableWidget.onSortChange"
+      @refresh="formTourImGroupInvitationTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onExportTourImGroupInvitationClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :on-change="onImportTourImGroupInvitationClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImGroupInvitationTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="聊天群组" field="groupIdDictMap.name" />
+      <vxe-column title="邀请人" field="inviterDictMap.name" />
+      <vxe-column title="被邀请人" field="inviteeDictMap.name" />
+      <vxe-column title="邀请状态" field="statusDictMap.name" />
+      <vxe-column title="创建人" field="createUserId" />
+      <vxe-column title="创建时间" field="createTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImGroupInvitationClick(scope.row)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourImGroupInvitationClick(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImGroupInvitationTableWidgetTotalCount"
+            :current-page="formTourImGroupInvitationTableWidgetCurrentPage"
+            :page-size="formTourImGroupInvitationTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImGroupInvitationTableWidget.onCurrentPageChange"
+            @size-change="formTourImGroupInvitationTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImGroupInvitation',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImGroupInvitationData } from '@/api/generated/tourImGroupInvitationController';
+import { TourImGroupInvitationController } from '@/api/generated';
+import FormEditTourImGroupInvitation from '@/pages/ImGroup/formEditTourImGroupInvitation.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    groupId?: ANY_OBJECT;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    groupId: undefined,
+  },
+);
+
+const formFilter = reactive({
+  // 聊天群组
+  groupIdFilter: undefined,
+  // 邀请人
+  inviterFilter: undefined,
+  // 被邀请人
+  inviteeFilter: undefined,
+  // 邀请状态 
+  statusFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 聊天群组
+  groupIdFilter: undefined,
+  // 邀请人
+  inviterFilter: undefined,
+  // 被邀请人
+  inviteeFilter: undefined,
+  // 邀请状态 
+  statusFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImGroupInvitation();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImGroupInvitationTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImGroupInvitationDtoFilter: {
+      groupId: props.groupId,
+      inviter: formFilter.inviterFilter,
+      invitee: formFilter.inviteeFilter,
+      status: formFilter.statusFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImGroupInvitationController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImGroupInvitationTableVerify = () => {
+  formFilterCopy.groupIdFilter = formFilter.groupIdFilter;
+  formFilterCopy.inviterFilter = formFilter.inviterFilter;
+  formFilterCopy.inviteeFilter = formFilter.inviteeFilter;
+  formFilterCopy.statusFilter = formFilter.statusFilter;
+  return true;
+};
+/**
+ * 编辑
+ */
+const onEditTourImGroupInvitationClick = (row?: TourImGroupInvitationData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImGroupInvitation, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImGroupInvitationTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImGroupInvitationClick = (row?: TourImGroupInvitationData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImGroupInvitationController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImGroupInvitationClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImGroupInvitationController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImGroupInvitationTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImGroupInvitationClick = (row?: TourImGroupInvitationData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImGroupInvitationController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImGroupInvitationTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImGroupInvitationTableOptions: TableOptions<TourImGroupInvitationData> = {
+  loadTableData: loadFormTourImGroupInvitationTableWidgetData,
+  verifyTableParameter: loadFormTourImGroupInvitationTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImGroupInvitationTable = ref();
+const formTourImGroupInvitationTableWidget = useTable(formTourImGroupInvitationTableOptions);
+const {
+  dataList: formTourImGroupInvitationTableWidgetDataList,
+  currentPage: formTourImGroupInvitationTableWidgetCurrentPage,
+  pageSize: formTourImGroupInvitationTableWidgetPageSize,
+  totalCount: formTourImGroupInvitationTableWidgetTotalCount,
+} = formTourImGroupInvitationTableWidget;
+/**
+ * 聊天群组下拉数据获取函数
+ */
+const loadGroupIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroup(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 聊天群组配置参数
+const groupIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadGroupIdFilterDropdownList,
+  isTree: false,
+};
+// 聊天群组下拉组件
+const groupIdFilterWidget = useDropdown(groupIdFilterOptions);
+const { dropdownList: groupIdFilterWidgetDropdownList } = groupIdFilterWidget
+/**
+ * 邀请人下拉数据获取函数
+ */
+const loadInviterFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourUser(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 邀请人配置参数
+const inviterFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadInviterFilterDropdownList,
+  isTree: false,
+};
+// 邀请人下拉组件
+const inviterFilterWidget = useDropdown(inviterFilterOptions);
+const { dropdownList: inviterFilterWidgetDropdownList } = inviterFilterWidget
+/**
+ * 被邀请人下拉数据获取函数
+ */
+const loadInviteeFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourUser(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 被邀请人配置参数
+const inviteeFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadInviteeFilterDropdownList,
+  isTree: false,
+};
+// 被邀请人下拉组件
+const inviteeFilterWidget = useDropdown(inviteeFilterOptions);
+const { dropdownList: inviteeFilterWidgetDropdownList } = inviteeFilterWidget
+/**
+ * 邀请状态 下拉数据获取函数
+ */
+const loadStatusFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'GroupInvitationStatus', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 邀请状态 配置参数
+const statusFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadStatusFilterDropdownList,
+  isTree: false,
+};
+// 邀请状态 下拉组件
+const statusFilterWidget = useDropdown(statusFilterOptions);
+const { dropdownList: statusFilterWidgetDropdownList } = statusFilterWidget
+const refreshFormTourImGroupInvitation = () => {
+  // 刷新段落
+  formTourImGroupInvitationTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImGroupInvitation = () => {
+  formFilter.groupIdFilter = undefined;
+  formFilterCopy.groupIdFilter = undefined;
+  formFilter.inviterFilter = undefined;
+  formFilterCopy.inviterFilter = undefined;
+  formFilter.inviteeFilter = undefined;
+  formFilterCopy.inviteeFilter = undefined;
+  formFilter.statusFilter = undefined;
+  formFilterCopy.statusFilter = undefined;
+  refreshFormTourImGroupInvitation();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImGroupInvitation();
+};
+const formInit = () => {
+  groupIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  inviterFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  inviteeFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  statusFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImGroupInvitation();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 558 - 0
src/pages/ImGroup/formTourImGroupType.vue

@@ -0,0 +1,558 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImGroupTypeRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImGroupType()" @reset="resetFormTourImGroupType">
+<!--        <el-form-item label="类型选择">-->
+<!--          <el-cascader-->
+<!--            class="filter-item"-->
+<!--            v-model="idFilterPath"-->
+<!--            :options="idFilterWidgetDropdownList"-->
+<!--            placeholder=""-->
+<!--            :clearable="true"-->
+<!--            :filterable="true"-->
+<!--            :show-all-levels="false"-->
+<!--            :props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"-->
+<!--            @change="onIdFilterValueChange"-->
+<!--          />-->
+<!--        </el-form-item>-->
+       <!-- <el-form-item label="一级类型选择">
+          <el-cascader
+            class="filter-item"
+            v-model="parentIdFilter_copyPath"
+            :options="parentIdFilter_copyWidgetDropdownList"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            :show-all-levels="false"
+            :props="{ value: 'id', label: 'name', children: 'children', checkStrictly: true }"
+            @change="onParentIdFilter_copyValueChange"
+          />
+        </el-form-item> -->
+        <el-form-item label="类型名称">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.typeNameFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+        <el-form-item label="是否启用 ">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.enableFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="enableFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in enableFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImGroupTypeTable"
+      class="page-table"
+      :data="formTourImGroupTypeTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImGroupTypeTableWidgetCurrentPage - 1) * formTourImGroupTypeTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImGroupTypeTableWidget.onSortChange"
+      @refresh="formTourImGroupTypeTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImGroupType:formTourImGroupType:addTourImGroupType')"
+          @click="onAddTourImGroupTypeClick()"
+          >
+          新建
+        </el-button>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImGroupType:formTourImGroupType:exportTourImGroupType')"
+          @click="onExportTourImGroupTypeClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :disabled="!checkPermCodeExist('formTourImGroupType:formTourImGroupType:importTourImGroupType')"
+          :on-change="onImportTourImGroupTypeClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+              :disabled="!checkPermCodeExist('formTourImGroupType:formTourImGroupType:importTourImGroupType')"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImGroupTypeTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="父级类型" field="parentIdDictMap.name" >
+        <template v-slot="scope">
+          <span>{{scope.row?.parentIdDictMap?.name ?? '-'}}</span>
+        </template>
+      </vxe-column>>
+
+      <vxe-column title="类型名称" field="typeName" />
+      <vxe-column title="一级类型图标">
+        <template v-slot="scope">
+          <upload-file-list
+            :file-list="
+              parseUploadData(scope.row.typeIcon, {
+                id: scope.row.id,
+                fieldName: 'typeIcon',
+                asImage: true
+              })
+            "
+            type="card"
+            direction="horizontal"
+            :readonly="true"
+          />
+        </template>
+      </vxe-column>
+      <vxe-column title="是否启用 " field="enableDictMap.name" />
+<!--      <vxe-column title="创建人id" field="createUserId" />-->
+      <vxe-column title="创建时间" field="createTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImGroupTypeClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImGroupType:formTourImGroupType:editTourImGroupType')"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourImGroupTypeClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImGroupType:formTourImGroupType:deleteTourImGroupType')"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImGroupTypeTableWidgetTotalCount"
+            :current-page="formTourImGroupTypeTableWidgetCurrentPage"
+            :page-size="formTourImGroupTypeTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImGroupTypeTableWidget.onCurrentPageChange"
+            @size-change="formTourImGroupTypeTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImGroupType',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImGroupTypeData } from '@/api/generated/tourImGroupTypeController';
+import { TourImGroupTypeController } from '@/api/generated';
+import FormEditTourImGroupType from '@/pages/ImGroup/formEditTourImGroupType.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 类型选择
+  idFilter: undefined,
+  // 一级类型选择
+  parentIdFilter_copy: undefined,
+  // 类型名称
+  typeNameFilter: undefined,
+  // 是否启用
+  enableFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 类型选择
+  idFilter: undefined,
+  // 一级类型选择
+  parentIdFilter_copy: undefined,
+  // 类型名称
+  typeNameFilter: undefined,
+  // 是否启用
+  enableFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImGroupType();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImGroupTypeTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImGroupTypeDtoFilter: {
+      id: formFilter.idFilter,
+      parentId: formFilter.parentIdFilter_copy,
+      typeName: formFilter.typeNameFilter,
+      enable: formFilter.enableFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImGroupTypeController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImGroupTypeTableVerify = () => {
+  formFilterCopy.idFilter = formFilter.idFilter;
+  formFilterCopy.parentIdFilter_copy = formFilter.parentIdFilter_copy;
+  formFilterCopy.typeNameFilter = formFilter.typeNameFilter;
+  formFilterCopy.enableFilter = formFilter.enableFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourImGroupTypeClick = (row?: TourImGroupTypeData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImGroupType, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImGroupTypeTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourImGroupTypeClick = (row?: TourImGroupTypeData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImGroupType, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImGroupTypeTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImGroupTypeClick = (row?: TourImGroupTypeData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImGroupTypeController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImGroupTypeClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImGroupTypeController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImGroupTypeTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImGroupTypeClick = (row?: TourImGroupTypeData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImGroupTypeController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImGroupTypeTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImGroupTypeTableOptions: TableOptions<TourImGroupTypeData> = {
+  loadTableData: loadFormTourImGroupTypeTableWidgetData,
+  verifyTableParameter: loadFormTourImGroupTypeTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImGroupTypeTable = ref();
+const formTourImGroupTypeTableWidget = useTable(formTourImGroupTypeTableOptions);
+const {
+  dataList: formTourImGroupTypeTableWidgetDataList,
+  currentPage: formTourImGroupTypeTableWidgetCurrentPage,
+  pageSize: formTourImGroupTypeTableWidgetPageSize,
+  totalCount: formTourImGroupTypeTableWidgetTotalCount,
+} = formTourImGroupTypeTableWidget;
+/**
+ * 类型选择下拉数据获取函数
+ */
+const loadIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroupType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 类型选择选中值改变
+ */
+const onIdFilterValueChange = (value) => {
+  formFilter.idFilter = Array.isArray(value) ? value[value.length - 1] : value;
+};
+// 类型选择配置参数
+const idFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIdFilterDropdownList,
+  isTree: true,
+};
+// 类型选择选中数据
+const idFilterPath = ref<Array<string | number>>([]);
+// 类型选择下拉组件
+const idFilterWidget = useDropdown(idFilterOptions);
+const { dropdownList: idFilterWidgetDropdownList } = idFilterWidget
+/**
+ * 一级类型选择下拉数据获取函数
+ */
+const loadParentIdFilter_copyDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroupType(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 一级类型选择选中值改变
+ */
+const onParentIdFilter_copyValueChange = (value) => {
+  formFilter.parentIdFilter_copy = Array.isArray(value) ? value[value.length - 1] : value;
+};
+// 一级类型选择配置参数
+const parentIdFilter_copyOptions: DropdownOptions<DictData> = {
+  loadData: loadParentIdFilter_copyDropdownList,
+  isTree: true,
+};
+// 一级类型选择选中数据
+const parentIdFilter_copyPath = ref<Array<string | number>>([]);
+// 一级类型选择下拉组件
+const parentIdFilter_copyWidget = useDropdown(parentIdFilter_copyOptions);
+const { dropdownList: parentIdFilter_copyWidgetDropdownList } = parentIdFilter_copyWidget
+/**
+ * 是否启用 下拉数据获取函数
+ */
+const loadEnableFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 是否启用 配置参数
+const enableFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadEnableFilterDropdownList,
+  isTree: false,
+};
+// 是否启用 下拉组件
+const enableFilterWidget = useDropdown(enableFilterOptions);
+const { dropdownList: enableFilterWidgetDropdownList } = enableFilterWidget
+const refreshFormTourImGroupType = () => {
+  // 刷新段落
+  formTourImGroupTypeTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImGroupType = () => {
+  formFilter.idFilter = undefined;
+  formFilterCopy.idFilter = undefined;
+  idFilterPath.value = [];
+  formFilter.parentIdFilter_copy = undefined;
+  formFilterCopy.parentIdFilter_copy = undefined;
+  parentIdFilter_copyPath.value = [];
+  formFilter.typeNameFilter = undefined;
+  formFilterCopy.typeNameFilter = undefined;
+  formFilter.enableFilter = undefined;
+  formFilterCopy.enableFilter = undefined;
+  refreshFormTourImGroupType();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImGroupType();
+};
+const formInit = () => {
+  idFilterWidget.onVisibleChange(true).then(res => {
+    // TODO: 获取级联选中路径
+    idFilterPath.value = findTreeNodePath(res, formFilter.idFilter);
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+  parentIdFilter_copyWidget.onVisibleChange(true).then(res => {
+    // TODO: 获取级联选中路径
+    parentIdFilter_copyPath.value = findTreeNodePath(res, formFilter.parentIdFilter_copy);
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+  enableFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImGroupType();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 595 - 0
src/pages/ImGroup/formTourImMember.vue

@@ -0,0 +1,595 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImMemberRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImMember()" @reset="resetFormTourImMember">
+        <el-form-item label="群名称">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.groupIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="groupIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in groupIdFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="成员名称">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.userIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="userIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in userIdFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="成员角色">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.groupRoleFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="groupRoleFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in groupRoleFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="会话是否显示">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.isShowFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="isShowFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in isShowFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="会话是否置顶 ">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.isTopFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="isTopFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in isTopFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImMemberTable"
+      class="page-table"
+      :data="formTourImMemberTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImMemberTableWidgetCurrentPage - 1) * formTourImMemberTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImMemberTableWidget.onSortChange"
+      @refresh="formTourImMemberTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onExportTourImMemberClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :on-change="onImportTourImMemberClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImMemberTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="聊天群组" field="groupIdDictMap.name" />
+      <vxe-column title="成员角色" field="groupRoleDictMap.name" />
+      <vxe-column title="用户" field="userIdDictMap.name" />
+      <vxe-column title="是否显示" field="isShowDictMap.name" />
+      <vxe-column title="是否置顶 " field="isTopDictMap.name" />
+      <vxe-column title="是免打扰 " field="isNotDisturbDictMap.name" />
+      <vxe-column title="群昵称" field="groupNickname" />
+      <vxe-column title="群备注" field="groupRemark" />
+
+      <vxe-column title="聊天背景">
+        <template v-slot="scope">
+          <upload-file-list
+              :file-list="
+              parseUploadData(scope.row.groupBackImage, {
+                id: scope.row.id,
+                fieldName: 'groupBackImage',
+                asImage: true
+              })
+            "
+              type="card"
+              direction="horizontal"
+              :readonly="true"
+          />
+        </template>
+      </vxe-column>
+
+<!--      <vxe-column title="聊天背景">-->
+<!--        <template v-slot="scope">-->
+<!--          <upload-file-list-->
+<!--            :file-list="-->
+<!--              parseUploadData(scope.row.groupBackImage, {-->
+<!--                id: scope.row.id,-->
+<!--                fieldName: 'groupBackImage',-->
+<!--                asImage: true-->
+<!--              })-->
+<!--            "-->
+<!--            type="card"-->
+<!--            direction="horizontal"-->
+<!--            :readonly="true"-->
+<!--          />-->
+<!--        </template>-->
+<!--      </vxe-column>-->
+<!--      <vxe-column title="操作" fixed="right">-->
+<!--        <template v-slot="scope">-->
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            :size="layoutStore.defaultFormItemSize"-->
+<!--            @click.stop="onEditTourImMemberClick(scope.row)"-->
+<!--          >-->
+<!--            编辑-->
+<!--          </el-button>-->
+<!--          <el-button-->
+<!--            link-->
+<!--            type="primary"-->
+<!--            :size="layoutStore.defaultFormItemSize"-->
+<!--            @click.stop="onDeleteTourImMemberClick(scope.row)"-->
+<!--          >-->
+<!--            删除-->
+<!--          </el-button>-->
+<!--        </template>-->
+<!--      </vxe-column>-->
+      <vxe-column title="进群时间" field="createTime" />
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImMemberTableWidgetTotalCount"
+            :current-page="formTourImMemberTableWidgetCurrentPage"
+            :page-size="formTourImMemberTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImMemberTableWidget.onCurrentPageChange"
+            @size-change="formTourImMemberTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImMember',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImMemberData } from '@/api/generated/tourImMemberController';
+import { TourImMemberController } from '@/api/generated';
+import FormEditTourImMember from '@/pages/ImGroup/formEditTourImMember.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    groupId?: ANY_OBJECT;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    groupId: undefined,
+  },
+);
+
+const formFilter = reactive({
+  // 群名称
+  groupIdFilter: undefined,
+  // 成员名称
+  userIdFilter: undefined,
+  // 成员角色
+  groupRoleFilter: undefined,
+  // 会话是否显示
+  isShowFilter: undefined,
+  // 会话是否置顶
+  isTopFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 群名称
+  groupIdFilter: undefined,
+  // 成员名称
+  userIdFilter: undefined,
+  // 成员角色
+  groupRoleFilter: undefined,
+  // 会话是否显示
+  isShowFilter: undefined,
+  // 会话是否置顶
+  isTopFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImMember();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImMemberTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImMemberDtoFilter: {
+      groupId: props.groupId,
+      groupRole: formFilter.groupRoleFilter,
+      userId: formFilter.userIdFilter,
+      isShow: formFilter.isShowFilter,
+      isTop: formFilter.isTopFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImMemberController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImMemberTableVerify = () => {
+  formFilterCopy.groupIdFilter = formFilter.groupIdFilter;
+  formFilterCopy.userIdFilter = formFilter.userIdFilter;
+  formFilterCopy.groupRoleFilter = formFilter.groupRoleFilter;
+  formFilterCopy.isShowFilter = formFilter.isShowFilter;
+  formFilterCopy.isTopFilter = formFilter.isTopFilter;
+  return true;
+};
+/**
+ * 编辑
+ */
+const onEditTourImMemberClick = (row?: TourImMemberData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImMember, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImMemberTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImMemberClick = (row?: TourImMemberData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImMemberController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImMemberClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImMemberController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImMemberTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImMemberClick = (row?: TourImMemberData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImMemberController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImMemberTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImMemberTableOptions: TableOptions<TourImMemberData> = {
+  loadTableData: loadFormTourImMemberTableWidgetData,
+  verifyTableParameter: loadFormTourImMemberTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImMemberTable = ref();
+const formTourImMemberTableWidget = useTable(formTourImMemberTableOptions);
+const {
+  dataList: formTourImMemberTableWidgetDataList,
+  currentPage: formTourImMemberTableWidgetCurrentPage,
+  pageSize: formTourImMemberTableWidgetPageSize,
+  totalCount: formTourImMemberTableWidgetTotalCount,
+} = formTourImMemberTableWidget;
+/**
+ * 群名称下拉数据获取函数
+ */
+const loadGroupIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroup(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 群名称配置参数
+const groupIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadGroupIdFilterDropdownList,
+  isTree: false,
+};
+// 群名称下拉组件
+const groupIdFilterWidget = useDropdown(groupIdFilterOptions);
+const { dropdownList: groupIdFilterWidgetDropdownList } = groupIdFilterWidget
+/**
+ * 成员名称下拉数据获取函数
+ */
+const loadUserIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictSysUser(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 成员名称配置参数
+const userIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadUserIdFilterDropdownList,
+  isTree: false,
+};
+// 成员名称下拉组件
+const userIdFilterWidget = useDropdown(userIdFilterOptions);
+const { dropdownList: userIdFilterWidgetDropdownList } = userIdFilterWidget
+/**
+ * 成员角色下拉数据获取函数
+ */
+const loadGroupRoleFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'GroupRole', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 成员角色配置参数
+const groupRoleFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadGroupRoleFilterDropdownList,
+  isTree: false,
+};
+// 成员角色下拉组件
+const groupRoleFilterWidget = useDropdown(groupRoleFilterOptions);
+const { dropdownList: groupRoleFilterWidgetDropdownList } = groupRoleFilterWidget
+/**
+ * 会话是否显示下拉数据获取函数
+ */
+const loadIsShowFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 会话是否显示配置参数
+const isShowFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIsShowFilterDropdownList,
+  isTree: false,
+};
+// 会话是否显示下拉组件
+const isShowFilterWidget = useDropdown(isShowFilterOptions);
+const { dropdownList: isShowFilterWidgetDropdownList } = isShowFilterWidget
+/**
+ * 会话是否置顶 下拉数据获取函数
+ */
+const loadIsTopFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 会话是否置顶 配置参数
+const isTopFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIsTopFilterDropdownList,
+  isTree: false,
+};
+// 会话是否置顶 下拉组件
+const isTopFilterWidget = useDropdown(isTopFilterOptions);
+const { dropdownList: isTopFilterWidgetDropdownList } = isTopFilterWidget
+const refreshFormTourImMember = () => {
+  // 刷新段落
+  formTourImMemberTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImMember = () => {
+  formFilter.groupIdFilter = undefined;
+  formFilterCopy.groupIdFilter = undefined;
+  formFilter.userIdFilter = undefined;
+  formFilterCopy.userIdFilter = undefined;
+  formFilter.groupRoleFilter = undefined;
+  formFilterCopy.groupRoleFilter = undefined;
+  formFilter.isShowFilter = undefined;
+  formFilterCopy.isShowFilter = undefined;
+  formFilter.isTopFilter = undefined;
+  formFilterCopy.isTopFilter = undefined;
+  refreshFormTourImMember();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImMember();
+};
+const formInit = () => {
+  groupIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  userIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  groupRoleFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  isShowFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  isTopFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImMember();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 559 - 0
src/pages/ImGroup/formTourImMessage.vue

@@ -0,0 +1,559 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImMessageRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImMessage()" @reset="resetFormTourImMessage">
+        <el-form-item label="消息内容">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.messageContentFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+        <el-form-item label="消息类型">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.messageTypeFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="messageTypeFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in messageTypeFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="聊天群组">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.groupIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="groupIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in groupIdFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="消息置顶/公告">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.isTopFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="isTopFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in isTopFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="撤回标记 ">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.revocationTagFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="revocationTagFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in revocationTagFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImMessageTable"
+      class="page-table"
+      :data="formTourImMessageTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImMessageTableWidgetCurrentPage - 1) * formTourImMessageTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImMessageTableWidget.onSortChange"
+      @refresh="formTourImMessageTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onAddTourImMessageClick()"
+          >
+          新建
+        </el-button>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onExportTourImMessageClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :on-change="onImportTourImMessageClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImMessageTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="消息内容" field="messageContent" />
+      <vxe-column title="消息类型" field="messageTypeDictMap.name" />
+      <vxe-column title="聊天群组" field="groupIdDictMap.name" />
+      <vxe-column title="消息置顶/公告" field="isTopDictMap.name" />
+      <vxe-column title="撤回标记 " field="revocationTagDictMap.name" />
+      <vxe-column title="已经删除该条消息的用户" field="deletedByUsers" />
+      <vxe-column title="已读该条消息的用户" field="readByUsers" />
+      <vxe-column title="删除标记" field="dataState" />
+      <vxe-column title="创建人" field="createUserIdDictMap.name" />
+      <vxe-column title="创建时间" field="createTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.createTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImMessageClick(scope.row)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourImMessageClick(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImMessageTableWidgetTotalCount"
+            :current-page="formTourImMessageTableWidgetCurrentPage"
+            :page-size="formTourImMessageTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImMessageTableWidget.onCurrentPageChange"
+            @size-change="formTourImMessageTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImMessage',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImMessageData } from '@/api/generated/tourImMessageController';
+import { TourImMessageController } from '@/api/generated';
+import FormEditTourImMessage from '@/pages/ImGroup/formEditTourImMessage.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    groupId?: ANY_OBJECT;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    groupId: undefined,
+  },
+);
+
+const formFilter = reactive({
+  // 消息内容
+  messageContentFilter: undefined,
+  // 消息类型
+  messageTypeFilter: undefined,
+  // 聊天群组
+  groupIdFilter: undefined,
+  // 消息置顶/公告
+  isTopFilter: undefined,
+  // 撤回标记 
+  revocationTagFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 消息内容
+  messageContentFilter: undefined,
+  // 消息类型
+  messageTypeFilter: undefined,
+  // 聊天群组
+  groupIdFilter: undefined,
+  // 消息置顶/公告
+  isTopFilter: undefined,
+  // 撤回标记 
+  revocationTagFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImMessage();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImMessageTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImMessageDtoFilter: {
+      messageContent: formFilter.messageContentFilter,
+      messageType: formFilter.messageTypeFilter,
+      groupId: props.groupId,
+      noticeType: formFilter.messageTypeFilter,
+      isTop: formFilter.isTopFilter,
+      revocationTag: formFilter.revocationTagFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImMessageController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImMessageTableVerify = () => {
+  formFilterCopy.messageContentFilter = formFilter.messageContentFilter;
+  formFilterCopy.messageTypeFilter = formFilter.messageTypeFilter;
+  formFilterCopy.groupIdFilter = formFilter.groupIdFilter;
+  formFilterCopy.isTopFilter = formFilter.isTopFilter;
+  formFilterCopy.revocationTagFilter = formFilter.revocationTagFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourImMessageClick = (row?: TourImMessageData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImMessage, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImMessageTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourImMessageClick = (row?: TourImMessageData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImMessage, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImMessageTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImMessageClick = (row?: TourImMessageData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImMessageController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImMessageClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImMessageController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImMessageTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImMessageClick = (row?: TourImMessageData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImMessageController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImMessageTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImMessageTableOptions: TableOptions<TourImMessageData> = {
+  loadTableData: loadFormTourImMessageTableWidgetData,
+  verifyTableParameter: loadFormTourImMessageTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImMessageTable = ref();
+const formTourImMessageTableWidget = useTable(formTourImMessageTableOptions);
+const {
+  dataList: formTourImMessageTableWidgetDataList,
+  currentPage: formTourImMessageTableWidgetCurrentPage,
+  pageSize: formTourImMessageTableWidgetPageSize,
+  totalCount: formTourImMessageTableWidgetTotalCount,
+} = formTourImMessageTableWidget;
+/**
+ * 消息类型下拉数据获取函数
+ */
+const loadMessageTypeFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'MessageType', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 消息类型配置参数
+const messageTypeFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadMessageTypeFilterDropdownList,
+  isTree: false,
+};
+// 消息类型下拉组件
+const messageTypeFilterWidget = useDropdown(messageTypeFilterOptions);
+const { dropdownList: messageTypeFilterWidgetDropdownList } = messageTypeFilterWidget
+/**
+ * 聊天群组下拉数据获取函数
+ */
+const loadGroupIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    DictionaryController.dictTourImGroup(params).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 聊天群组配置参数
+const groupIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadGroupIdFilterDropdownList,
+  isTree: false,
+};
+// 聊天群组下拉组件
+const groupIdFilterWidget = useDropdown(groupIdFilterOptions);
+const { dropdownList: groupIdFilterWidgetDropdownList } = groupIdFilterWidget
+/**
+ * 消息置顶/公告下拉数据获取函数
+ */
+const loadIsTopFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 消息置顶/公告配置参数
+const isTopFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIsTopFilterDropdownList,
+  isTree: false,
+};
+// 消息置顶/公告下拉组件
+const isTopFilterWidget = useDropdown(isTopFilterOptions);
+const { dropdownList: isTopFilterWidgetDropdownList } = isTopFilterWidget
+/**
+ * 撤回标记 下拉数据获取函数
+ */
+const loadRevocationTagFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.IsTrue.getList(),
+  });
+};
+// 撤回标记 配置参数
+const revocationTagFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadRevocationTagFilterDropdownList,
+  isTree: false,
+};
+// 撤回标记 下拉组件
+const revocationTagFilterWidget = useDropdown(revocationTagFilterOptions);
+const { dropdownList: revocationTagFilterWidgetDropdownList } = revocationTagFilterWidget
+const refreshFormTourImMessage = () => {
+  // 刷新段落
+  formTourImMessageTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImMessage = () => {
+  formFilter.messageContentFilter = undefined;
+  formFilterCopy.messageContentFilter = undefined;
+  formFilter.messageTypeFilter = undefined;
+  formFilterCopy.messageTypeFilter = undefined;
+  formFilter.groupIdFilter = undefined;
+  formFilterCopy.groupIdFilter = undefined;
+  formFilter.isTopFilter = undefined;
+  formFilterCopy.isTopFilter = undefined;
+  formFilter.revocationTagFilter = undefined;
+  formFilterCopy.revocationTagFilter = undefined;
+  refreshFormTourImMessage();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImMessage();
+};
+const formInit = () => {
+  messageTypeFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  groupIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  isTopFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  revocationTagFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourImMessage();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 225 - 0
src/pages/SensitiveWord/formEditTourImSensitiveWordAllow.vue

@@ -0,0 +1,225 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImSensitiveWordAllowRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="白名单词汇" prop="TourImSensitiveWordAllow.word">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImSensitiveWordAllow.word"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImSensitiveWordAllowClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImSensitiveWordAllow',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImSensitiveWordAllowData } from '@/api/generated/tourImSensitiveWordAllowController';
+import { TourImSensitiveWordAllowController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImSensitiveWordAllowRef = ref();
+// 表单数据定义
+type FormEditTourImSensitiveWordAllowData = {
+  TourImSensitiveWordAllow: TourImSensitiveWordAllowData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImSensitiveWordAllowData>({
+  TourImSensitiveWordAllow: {
+    // id
+    id: undefined,
+    // 白名单词汇
+    word: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImSensitiveWordAllow.word': [
+    {required: true, message: '请输入白名单词汇', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImSensitiveWordAllowData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImSensitiveWordAllow = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImSensitiveWordAllowController.view(params).then(res => {
+      formData.TourImSensitiveWordAllow = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImSensitiveWordAllow = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImSensitiveWordAllow = () => {
+  refreshFormEditTourImSensitiveWordAllow();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImSensitiveWordAllow();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImSensitiveWordAllowClick = () => {
+  formEditTourImSensitiveWordAllowRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImSensitiveWordAllow
+      };
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImSensitiveWordAllowDto: {
+        id: formData.TourImSensitiveWordAllow.id,
+        word: formData.TourImSensitiveWordAllow.word,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImSensitiveWordAllowController.update : TourImSensitiveWordAllowController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImSensitiveWordAllowData().then(res => {
+    if (isEdit.value) refreshFormEditTourImSensitiveWordAllow();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 225 - 0
src/pages/SensitiveWord/formEditTourImSensitiveWordDeny.vue

@@ -0,0 +1,225 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourImSensitiveWordDenyRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="黑名单词汇" prop="TourImSensitiveWordDeny.word">
+              <el-input
+                class="input-item"
+                v-model="formData.TourImSensitiveWordDeny.word"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourImSensitiveWordDenyClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourImSensitiveWordDeny',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImSensitiveWordDenyData } from '@/api/generated/tourImSensitiveWordDenyController';
+import { TourImSensitiveWordDenyController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourImSensitiveWordDenyRef = ref();
+// 表单数据定义
+type FormEditTourImSensitiveWordDenyData = {
+  TourImSensitiveWordDeny: TourImSensitiveWordDenyData;
+};
+// 表单数据
+const formData = reactive<FormEditTourImSensitiveWordDenyData>({
+  TourImSensitiveWordDeny: {
+    // id
+    id: undefined,
+    // 黑名单词汇
+    word: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourImSensitiveWordDeny.word': [
+    {required: true, message: '请输入黑名单词汇', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourImSensitiveWordDenyData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourImSensitiveWordDeny = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourImSensitiveWordDenyController.view(params).then(res => {
+      formData.TourImSensitiveWordDeny = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourImSensitiveWordDeny = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourImSensitiveWordDeny = () => {
+  refreshFormEditTourImSensitiveWordDeny();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourImSensitiveWordDeny();
+};
+/**
+ * 保存
+ */
+const onSubmitTourImSensitiveWordDenyClick = () => {
+  formEditTourImSensitiveWordDenyRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourImSensitiveWordDeny
+      };
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourImSensitiveWordDenyDto: {
+        id: formData.TourImSensitiveWordDeny.id,
+        word: formData.TourImSensitiveWordDeny.word,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourImSensitiveWordDenyController.update : TourImSensitiveWordDenyController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourImSensitiveWordDenyData().then(res => {
+    if (isEdit.value) refreshFormEditTourImSensitiveWordDeny();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 365 - 0
src/pages/SensitiveWord/formTourImSensitiveWordAllow.vue

@@ -0,0 +1,365 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImSensitiveWordAllowRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImSensitiveWordAllow()" @reset="resetFormTourImSensitiveWordAllow">
+        <el-form-item label="白名单词汇">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.wordFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImSensitiveWordAllowTable"
+      class="page-table"
+      :data="formTourImSensitiveWordAllowTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImSensitiveWordAllowTableWidgetCurrentPage - 1) * formTourImSensitiveWordAllowTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImSensitiveWordAllowTableWidget.onSortChange"
+      @refresh="formTourImSensitiveWordAllowTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImSensitiveWordAllow:formTourImSensitiveWordAllow:addTourImSensitiveWordAllow')"
+          @click="onAddTourImSensitiveWordAllowClick()"
+          >
+          新建
+        </el-button>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImSensitiveWordAllow:formTourImSensitiveWordAllow:exportTourImSensitiveWordAllow')"
+          @click="onExportTourImSensitiveWordAllowClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :disabled="!checkPermCodeExist('formTourImSensitiveWordAllow:formTourImSensitiveWordAllow:importTourImSensitiveWordAllow')"
+          :on-change="onImportTourImSensitiveWordAllowClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+              :disabled="!checkPermCodeExist('formTourImSensitiveWordAllow:formTourImSensitiveWordAllow:importTourImSensitiveWordAllow')"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImSensitiveWordAllowTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="白名单词汇" field="word" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImSensitiveWordAllowClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImSensitiveWordAllow:formTourImSensitiveWordAllow:editTourImSensitiveWordAllow')"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourImSensitiveWordAllowClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImSensitiveWordAllow:formTourImSensitiveWordAllow:deleteTourImSensitiveWordAllow')"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImSensitiveWordAllowTableWidgetTotalCount"
+            :current-page="formTourImSensitiveWordAllowTableWidgetCurrentPage"
+            :page-size="formTourImSensitiveWordAllowTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImSensitiveWordAllowTableWidget.onCurrentPageChange"
+            @size-change="formTourImSensitiveWordAllowTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImSensitiveWordAllow',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImSensitiveWordAllowData } from '@/api/generated/tourImSensitiveWordAllowController';
+import { TourImSensitiveWordAllowController } from '@/api/generated';
+import FormEditTourImSensitiveWordAllow from '@/pages/SensitiveWord/formEditTourImSensitiveWordAllow.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 白名单词汇
+  wordFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 白名单词汇
+  wordFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImSensitiveWordAllow();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImSensitiveWordAllowTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImSensitiveWordAllowDtoFilter: {
+      word: formFilter.wordFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImSensitiveWordAllowController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImSensitiveWordAllowTableVerify = () => {
+  formFilterCopy.wordFilter = formFilter.wordFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourImSensitiveWordAllowClick = (row?: TourImSensitiveWordAllowData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImSensitiveWordAllow, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImSensitiveWordAllowTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourImSensitiveWordAllowClick = (row?: TourImSensitiveWordAllowData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImSensitiveWordAllow, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImSensitiveWordAllowTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImSensitiveWordAllowClick = (row?: TourImSensitiveWordAllowData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImSensitiveWordAllowController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImSensitiveWordAllowClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImSensitiveWordAllowController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImSensitiveWordAllowTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImSensitiveWordAllowClick = (row?: TourImSensitiveWordAllowData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImSensitiveWordAllowController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImSensitiveWordAllowTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImSensitiveWordAllowTableOptions: TableOptions<TourImSensitiveWordAllowData> = {
+  loadTableData: loadFormTourImSensitiveWordAllowTableWidgetData,
+  verifyTableParameter: loadFormTourImSensitiveWordAllowTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImSensitiveWordAllowTable = ref();
+const formTourImSensitiveWordAllowTableWidget = useTable(formTourImSensitiveWordAllowTableOptions);
+const {
+  dataList: formTourImSensitiveWordAllowTableWidgetDataList,
+  currentPage: formTourImSensitiveWordAllowTableWidgetCurrentPage,
+  pageSize: formTourImSensitiveWordAllowTableWidgetPageSize,
+  totalCount: formTourImSensitiveWordAllowTableWidgetTotalCount,
+} = formTourImSensitiveWordAllowTableWidget;
+const refreshFormTourImSensitiveWordAllow = () => {
+  // 刷新段落
+  formTourImSensitiveWordAllowTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImSensitiveWordAllow = () => {
+  formFilter.wordFilter = undefined;
+  formFilterCopy.wordFilter = undefined;
+  refreshFormTourImSensitiveWordAllow();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImSensitiveWordAllow();
+};
+const formInit = () => {
+  refreshFormTourImSensitiveWordAllow();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 365 - 0
src/pages/SensitiveWord/formTourImSensitiveWordDeny.vue

@@ -0,0 +1,365 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourImSensitiveWordDenyRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourImSensitiveWordDeny()" @reset="resetFormTourImSensitiveWordDeny">
+        <el-form-item label="黑名单词汇">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.wordFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourImSensitiveWordDenyTable"
+      class="page-table"
+      :data="formTourImSensitiveWordDenyTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourImSensitiveWordDenyTableWidgetCurrentPage - 1) * formTourImSensitiveWordDenyTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourImSensitiveWordDenyTableWidget.onSortChange"
+      @refresh="formTourImSensitiveWordDenyTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImSensitiveWordDeny:formTourImSensitiveWordDeny:addTourImSensitiveWordDeny')"
+          @click="onAddTourImSensitiveWordDenyClick()"
+          >
+          新建
+        </el-button>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourImSensitiveWordDeny:formTourImSensitiveWordDeny:exportTourImSensitiveWordDeny')"
+          @click="onExportTourImSensitiveWordDenyClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :disabled="!checkPermCodeExist('formTourImSensitiveWordDeny:formTourImSensitiveWordDeny:importTourImSensitiveWordDeny')"
+          :on-change="onImportTourImSensitiveWordDenyClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+              :disabled="!checkPermCodeExist('formTourImSensitiveWordDeny:formTourImSensitiveWordDeny:importTourImSensitiveWordDeny')"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourImSensitiveWordDenyTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="黑名单词汇" field="word" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourImSensitiveWordDenyClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImSensitiveWordDeny:formTourImSensitiveWordDeny:editTourImSensitiveWordDeny')"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourImSensitiveWordDenyClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourImSensitiveWordDeny:formTourImSensitiveWordDeny:deleteTourImSensitiveWordDeny')"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourImSensitiveWordDenyTableWidgetTotalCount"
+            :current-page="formTourImSensitiveWordDenyTableWidgetCurrentPage"
+            :page-size="formTourImSensitiveWordDenyTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourImSensitiveWordDenyTableWidget.onCurrentPageChange"
+            @size-change="formTourImSensitiveWordDenyTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourImSensitiveWordDeny',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourImSensitiveWordDenyData } from '@/api/generated/tourImSensitiveWordDenyController';
+import { TourImSensitiveWordDenyController } from '@/api/generated';
+import FormEditTourImSensitiveWordDeny from '@/pages/SensitiveWord/formEditTourImSensitiveWordDeny.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 黑名单词汇
+  wordFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 黑名单词汇
+  wordFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourImSensitiveWordDeny();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourImSensitiveWordDenyTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourImSensitiveWordDenyDtoFilter: {
+      word: formFilter.wordFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourImSensitiveWordDenyController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourImSensitiveWordDenyTableVerify = () => {
+  formFilterCopy.wordFilter = formFilter.wordFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourImSensitiveWordDenyClick = (row?: TourImSensitiveWordDenyData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourImSensitiveWordDeny, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImSensitiveWordDenyTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourImSensitiveWordDenyClick = (row?: TourImSensitiveWordDenyData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', FormEditTourImSensitiveWordDeny, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourImSensitiveWordDenyTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourImSensitiveWordDenyClick = (row?: TourImSensitiveWordDenyData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourImSensitiveWordDenyController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourImSensitiveWordDenyClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourImSensitiveWordDenyController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourImSensitiveWordDenyTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourImSensitiveWordDenyClick = (row?: TourImSensitiveWordDenyData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourImSensitiveWordDenyController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourImSensitiveWordDenyTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourImSensitiveWordDenyTableOptions: TableOptions<TourImSensitiveWordDenyData> = {
+  loadTableData: loadFormTourImSensitiveWordDenyTableWidgetData,
+  verifyTableParameter: loadFormTourImSensitiveWordDenyTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourImSensitiveWordDenyTable = ref();
+const formTourImSensitiveWordDenyTableWidget = useTable(formTourImSensitiveWordDenyTableOptions);
+const {
+  dataList: formTourImSensitiveWordDenyTableWidgetDataList,
+  currentPage: formTourImSensitiveWordDenyTableWidgetCurrentPage,
+  pageSize: formTourImSensitiveWordDenyTableWidgetPageSize,
+  totalCount: formTourImSensitiveWordDenyTableWidgetTotalCount,
+} = formTourImSensitiveWordDenyTableWidget;
+const refreshFormTourImSensitiveWordDeny = () => {
+  // 刷新段落
+  formTourImSensitiveWordDenyTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourImSensitiveWordDeny = () => {
+  formFilter.wordFilter = undefined;
+  formFilterCopy.wordFilter = undefined;
+  refreshFormTourImSensitiveWordDeny();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourImSensitiveWordDeny();
+};
+const formInit = () => {
+  refreshFormTourImSensitiveWordDeny();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 363 - 0
src/pages/TourBrowseRecords/formTourBrowseRecords.vue

@@ -0,0 +1,363 @@
+<!-- <template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourBrowseRecordsRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourBrowseRecords()" @reset="resetFormTourBrowseRecords">
+        <el-form-item label="浏览者id">
+          <el-input-number
+            class="filter-item"
+            v-model="formFilter.visitorIdFilter"
+            placeholder=""
+            :clearable="true"
+            :step="1"
+            :controls="true"
+          />
+        </el-form-item>
+        <el-form-item label="浏览项目类型">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.itemTypeIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="itemTypeIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in itemTypeIdFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourBrowseRecordsTable"
+      class="page-table"
+      :data="formTourBrowseRecordsTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourBrowseRecordsTableWidgetCurrentPage - 1) * formTourBrowseRecordsTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourBrowseRecordsTableWidget.onSortChange"
+      @refresh="formTourBrowseRecordsTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourBrowseRecords:formTourBrowseRecords:exportTourBrowseRecords')"
+          @click="onExportTourBrowseRecordsClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :disabled="!checkPermCodeExist('formTourBrowseRecords:formTourBrowseRecords:importTourBrowseRecords')"
+          :on-change="onImportTourBrowseRecordsClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+              :disabled="!checkPermCodeExist('formTourBrowseRecords:formTourBrowseRecords:importTourBrowseRecords')"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourBrowseRecordsTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="浏览者id" field="visitorId" />
+      <vxe-column title="项目id" field="itemId" />
+      <vxe-column title="浏览项目类型" field="itemTypeIdDictMap.name" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourBrowseRecordsClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourBrowseRecords:formTourBrowseRecords:deleteTourBrowseRecords')"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourBrowseRecordsTableWidgetTotalCount"
+            :current-page="formTourBrowseRecordsTableWidgetCurrentPage"
+            :page-size="formTourBrowseRecordsTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourBrowseRecordsTableWidget.onCurrentPageChange"
+            @size-change="formTourBrowseRecordsTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourBrowseRecords',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourBrowseRecordsData } from '@/api/generated/tourBrowseRecordsController';
+import { TourBrowseRecordsController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 浏览者id
+  visitorIdFilter: undefined,
+  // 浏览项目类型
+  itemTypeIdFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 浏览者id
+  visitorIdFilter: undefined,
+  // 浏览项目类型
+  itemTypeIdFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourBrowseRecords();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourBrowseRecordsTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourBrowseRecordsDtoFilter: {
+      visitorId: formFilter.visitorIdFilter,
+      itemTypeId: formFilter.itemTypeIdFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourBrowseRecordsController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourBrowseRecordsTableVerify = () => {
+  formFilterCopy.visitorIdFilter = formFilter.visitorIdFilter;
+  formFilterCopy.itemTypeIdFilter = formFilter.itemTypeIdFilter;
+  return true;
+};
+/**
+ * 导出
+ */
+const onExportTourBrowseRecordsClick = (row?: TourBrowseRecordsData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourBrowseRecordsController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourBrowseRecordsClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourBrowseRecordsController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourBrowseRecordsTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourBrowseRecordsClick = (row?: TourBrowseRecordsData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourBrowseRecordsController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourBrowseRecordsTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourBrowseRecordsTableOptions: TableOptions<TourBrowseRecordsData> = {
+  loadTableData: loadFormTourBrowseRecordsTableWidgetData,
+  verifyTableParameter: loadFormTourBrowseRecordsTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourBrowseRecordsTable = ref();
+const formTourBrowseRecordsTableWidget = useTable(formTourBrowseRecordsTableOptions);
+const {
+  dataList: formTourBrowseRecordsTableWidgetDataList,
+  currentPage: formTourBrowseRecordsTableWidgetCurrentPage,
+  pageSize: formTourBrowseRecordsTableWidgetPageSize,
+  totalCount: formTourBrowseRecordsTableWidgetTotalCount,
+} = formTourBrowseRecordsTableWidget;
+/**
+ * 浏览项目类型下拉数据获取函数
+ */
+const loadItemTypeIdFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'ViewItemType', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 浏览项目类型配置参数
+const itemTypeIdFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadItemTypeIdFilterDropdownList,
+  isTree: false,
+};
+// 浏览项目类型下拉组件
+const itemTypeIdFilterWidget = useDropdown(itemTypeIdFilterOptions);
+const { dropdownList: itemTypeIdFilterWidgetDropdownList } = itemTypeIdFilterWidget
+const refreshFormTourBrowseRecords = () => {
+  // 刷新段落
+  formTourBrowseRecordsTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourBrowseRecords = () => {
+  formFilter.visitorIdFilter = undefined;
+  formFilterCopy.visitorIdFilter = undefined;
+  formFilter.itemTypeIdFilter = undefined;
+  formFilterCopy.itemTypeIdFilter = undefined;
+  refreshFormTourBrowseRecords();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourBrowseRecords();
+};
+const formInit = () => {
+  itemTypeIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourBrowseRecords();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script> -->

+ 319 - 0
src/pages/tourFans/formEditTourFans.vue

@@ -0,0 +1,319 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourFansRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="被关注人" prop="TourFans.attentionId">
+              <el-select
+                class="input-item"
+                v-model="formData.TourFans.attentionId"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="attentionIdWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in attentionIdWidgetDropdownList"
+                  :key="item.userId"
+                  :label="item.showName"
+                  :value="item.userId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="关注人" prop="TourFans.createUserId">
+              <el-select
+                class="input-item"
+                v-model="formData.TourFans.createUserId"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="createUserIdWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in createUserIdWidgetDropdownList"
+                  :key="item.userId"
+                  :label="item.showName"
+                  :value="item.userId"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSubmitTourFansClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourFans',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourFansData } from '@/api/generated/tourFansController';
+import {TourFansController, TourUserController} from '@/api/generated';
+import TourUser from "@/types/table/tourUser";
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourFansRef = ref();
+// 表单数据定义
+type FormEditTourFansData = {
+  TourFans: TourFansData;
+};
+// 表单数据
+const formData = reactive<FormEditTourFansData>({
+  TourFans: {
+    // 粉丝表id
+    id: undefined,
+    // 被关注人id
+    attentionId: undefined,
+    // 是否删除
+    deleteFlag: undefined,
+    // 创建人id
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新人id
+    updateUserId: undefined,
+    // 更新时间
+    updateTime: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourFans.attentionId': [
+    {required: true, message: '请输入被关注人', trigger: 'blur'}
+  ],
+  'TourFans.createUserId': [
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourFansData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourFans = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourFansController.view(params).then(res => {
+      formData.TourFans = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 被关注人下拉数据获取函数
+ */
+const loadAttentionIdDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 被关注人配置参数
+const attentionIdOptions: DropdownOptions<TourUser> = {
+  loadData: loadAttentionIdDropdownList,
+  isTree: false,
+};
+// 被关注人下拉组件
+const attentionIdWidget = useDropdown(attentionIdOptions);
+const { dropdownList: attentionIdWidgetDropdownList } = attentionIdWidget
+/**
+ * 关注人下拉数据获取函数
+ */
+const loadCreateUserIdDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 关注人配置参数
+const createUserIdOptions: DropdownOptions<TourUser> = {
+  loadData: loadCreateUserIdDropdownList,
+  isTree: false,
+};
+// 关注人下拉组件
+const createUserIdWidget = useDropdown(createUserIdOptions);
+const { dropdownList: createUserIdWidgetDropdownList } = createUserIdWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshFormEditTourFans = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourFans = () => {
+  refreshFormEditTourFans();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourFans();
+};
+/**
+ * 保存
+ */
+const onSubmitTourFansClick = () => {
+  formEditTourFansRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourFans
+      };
+    retFormData.attentionIdDictMap = attentionIdWidgetDropdownList.value.filter(item=>item.userId == formData.TourFans.attentionId)[0];
+    retFormData.createUserIdDictMap = createUserIdWidgetDropdownList.value.filter(item=>item.userId == formData.TourFans.createUserId)[0];
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourFansDto: {
+        id: formData.TourFans.id,
+        attentionId: formData.TourFans.attentionId,
+        createUserId: formData.TourFans.createUserId,
+        createTime: formData.TourFans.createTime,
+        updateUserId: formData.TourFans.updateUserId,
+        updateTime: formData.TourFans.updateTime,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourFansController.update : TourFansController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourFansData().then(res => {
+    attentionIdWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    createUserIdWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshFormEditTourFans();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 437 - 0
src/pages/tourFans/formTourFans.vue

@@ -0,0 +1,437 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourFansRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourFans()" @reset="resetFormTourFans">
+        <el-form-item label="被关注人">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.attentionIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="attentionIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in attentionIdFilterWidgetDropdownList"
+              :key="item.userId"
+              :label="item.showName"
+              :value="item.userId"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="关注人">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.createUserIdFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="createUserIdFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in createUserIdFilterWidgetDropdownList"
+              :key="item.userId"
+              :label="item.showName"
+              :value="item.userId"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="formTourFansTable"
+      class="page-table"
+      :data="formTourFansTableWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((formTourFansTableWidgetCurrentPage - 1) * formTourFansTableWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="formTourFansTableWidget.onSortChange"
+      @refresh="formTourFansTableWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onAddTourFansClick()"
+          >
+          新建
+        </el-button>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onExportTourFansClick()"
+          >
+          导出
+        </el-button>
+        <el-upload
+          class="btn-import"
+          :auto-upload="false"
+          action=""
+          :show-file-list="false"
+          accept=".xls,.xlsx"
+          style="display: inline-block;"
+          :on-change="onImportTourFansClick"
+        >
+          <template #trigger>
+            <el-button
+              type="primary"
+              :size="layoutStore.defaultFormItemSize"
+            >
+              导入
+            </el-button>
+          </template>
+        </el-upload>
+      </template>
+      <vxe-column title="序号" type="seq" :index="formTourFansTableWidget.getTableIndex" :width="80" />
+      <vxe-column title="被关注人" field="attentionIdDictMap.name" />
+      <vxe-column title="关注人" field="createUserIdDictMap.name" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditTourFansClick(scope.row)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteTourFansClick(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="formTourFansTableWidgetTotalCount"
+            :current-page="formTourFansTableWidgetCurrentPage"
+            :page-size="formTourFansTableWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="formTourFansTableWidget.onCurrentPageChange"
+            @size-change="formTourFansTableWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourFans',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourFansData } from '@/api/generated/tourFansController';
+import { TourFansController,TourUserController } from '@/api/generated';
+import FormEditTourFans from '@/pages/tourFans/formEditTourFans.vue';
+import {TourVisaData} from "@/api/generated/tourVisaController";
+import TourUser from "@/types/table/tourUser";
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const {
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 被关注人
+  attentionIdFilter: undefined,
+  // 关注人
+  createUserIdFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 被关注人
+  attentionIdFilter: undefined,
+  // 关注人
+  createUserIdFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourFans();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadFormTourFansTableWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourFansDtoFilter: {
+      attentionId: formFilter.attentionIdFilter,
+      createUserId: formFilter.createUserIdFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourFansController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadFormTourFansTableVerify = () => {
+  formFilterCopy.attentionIdFilter = formFilter.attentionIdFilter;
+  formFilterCopy.createUserIdFilter = formFilter.createUserIdFilter;
+  return true;
+};
+/**
+ * 新建
+ */
+const onAddTourFansClick = (row?: TourFansData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新建', FormEditTourFans, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourFansTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditTourFansClick = (row?: TourFansData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+  Dialog
+    .show('编辑', FormEditTourFans, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      formTourFansTableWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 导出
+ */
+const onExportTourFansClick = (row?: TourFansData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  TourFansController.export(params, '表格组件.xlsx').then(res => {
+    ElMessage.success('导出成功');
+  }).catch(e => {
+    ElMessage.error(e.errorMessage);
+  });
+};
+/**
+ * 导入
+ */
+const onImportTourFansClick = (file) => {
+  let params: ANY_OBJECT = {
+    importFile: file.raw,
+    // 是否忽略表头
+    skipHeader: false
+  };
+
+  TourFansController.import(params).then(res => {
+    ElMessage.success('导入成功');
+    formTourFansTableWidget.refreshTable();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+/**
+ * 删除
+ */
+const onDeleteTourFansClick = (row?: TourFansData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除此记录?').then(res => {
+    TourFansController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      formTourFansTableWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const formTourFansTableOptions: TableOptions<TourFansData> = {
+  loadTableData: loadFormTourFansTableWidgetData,
+  verifyTableParameter: loadFormTourFansTableVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const formTourFansTable = ref();
+const formTourFansTableWidget = useTable(formTourFansTableOptions);
+const {
+  dataList: formTourFansTableWidgetDataList,
+  currentPage: formTourFansTableWidgetCurrentPage,
+  pageSize: formTourFansTableWidgetPageSize,
+  totalCount: formTourFansTableWidgetTotalCount,
+} = formTourFansTableWidget;
+/**
+ * 被关注人下拉数据获取函数
+ */
+const loadAttentionIdFilterDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 被关注人配置参数
+const attentionIdFilterOptions: DropdownOptions<TourUser> = {
+  loadData: loadAttentionIdFilterDropdownList,
+  isTree: false,
+};
+// 被关注人下拉组件
+const attentionIdFilterWidget = useDropdown(attentionIdFilterOptions);
+const { dropdownList: attentionIdFilterWidgetDropdownList } = attentionIdFilterWidget
+/**
+ * 关注人下拉数据获取函数
+ */
+const loadCreateUserIdFilterDropdownList = (): Promise<ListData<TourUser>> => {
+  return new Promise((resolve, reject) => {
+    const params = {
+    };
+    TourUserController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 关注人配置参数
+const createUserIdFilterOptions: DropdownOptions<TourUser> = {
+  loadData: loadCreateUserIdFilterDropdownList,
+  isTree: false,
+};
+// 关注人下拉组件
+const createUserIdFilterWidget = useDropdown(createUserIdFilterOptions);
+const { dropdownList: createUserIdFilterWidgetDropdownList } = createUserIdFilterWidget
+const refreshFormTourFans = () => {
+  // 刷新段落
+  formTourFansTableWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourFans = () => {
+  formFilter.attentionIdFilter = undefined;
+  formFilterCopy.attentionIdFilter = undefined;
+  formFilter.createUserIdFilter = undefined;
+  formFilterCopy.createUserIdFilter = undefined;
+  refreshFormTourFans();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourFans();
+};
+const formInit = () => {
+  attentionIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  createUserIdFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourFans();
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 2 - 2
src/pages/tourHouseRentInfo/formTourHouseRentInfo.vue

@@ -291,7 +291,7 @@ const route = useRoute();
 const layoutStore = useLayoutStore();
 const { downloadFile } = useDownload();
 const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
-const { 
+const {
   Delete,
   Search,
   Edit,
@@ -722,4 +722,4 @@ const formInit = () => {
 onMounted(() => {
   formInit();
 });
-</script>
+</script>

+ 6 - 0
src/pages/tourOrder/formEditTourOrder.vue

@@ -386,6 +386,10 @@ const formData = reactive<FormEditTourOrderData>({
     updateTime: undefined,
     // 删除标记(1: 正常 -1: 已删除)
     dataState: undefined,
+    // 拼团的id
+    groupPurchaseProgressId: undefined,
+    //订单的类型(0.普通订单;1.拼团的订单)
+    type: undefined,
     tourismProject: {
       // 主键id
       id: undefined,
@@ -668,6 +672,8 @@ const onSaveClick = () => {
         customerMobile: formData.tourOrder.customerMobile,
         customerWechat: formData.tourOrder.customerWechat,
         customerMobileStandby: formData.tourOrder.customerMobileStandby,
+        groupPurchaseProgressId: formData.tourOrder.groupPurchaseProgressId,
+        type: formData.tourOrder.type,
         createUserId: formData.tourOrder.createUserId,
         createTime: formData.tourOrder.createTime,
         updateUserId: formData.tourOrder.updateUserId,

+ 276 - 0
src/pages/tourOrder/formEditTourOrderRebate.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="formEditTourOrderRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="最高返利金额" prop="tourOrder.rebateSumPrice">
+              <el-input-number
+                class="input-item"
+                v-model="formData.tourOrder.rebateSumPrice"
+                placeholder=""
+                :clearable="true"
+                :step="1"
+                :controls="true"
+                :disabled="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="核销返利金额" prop="tourOrder.rebatePrice">
+              <el-input-number
+                class="input-item"
+                v-model="formData.tourOrder.rebatePrice"
+                placeholder=""
+                :clearable="true"
+                :step="1"
+                :controls="true"
+                :min="0"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onRebate()">核销</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formEditTourOrderRebate',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode } from '@/common/utils';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourOrderPassenageData } from '@/api/generated/tourOrderPassenageController';
+import { TourOrderData } from '@/api/generated/tourOrderController';
+import { TourismProjectController, TourOrderPassenageController, tourOrderController } from '@/api/generated';
+import FormSelectTourProject from '@/pages/tourOrder/formSelectTourProject/index.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const formEditTourOrderRef = ref();
+// 表单数据定义
+type FormEditTourOrderData = {
+  tourOrder: TourOrderData;
+};
+// 表单数据
+const formData = reactive<FormEditTourOrderData>({
+  tourOrder: {
+    // ID主键
+    id: undefined,
+    // 订单号
+    orderNo: undefined,
+    // 出发日期
+    departureDate: undefined,
+    // 结束日期
+    endDate: undefined,
+    // 成人数量
+    adultNumber: undefined,
+    // 儿童数量
+    childrenNumber: undefined,
+    // 总天数
+    countTimes: undefined,
+    // 币种
+    currency: undefined,
+    // 项目标题
+    projectTitle: undefined,
+    // 订单总金额
+    totalAmount: undefined,
+    // 儿童价格
+    childrenPrice: undefined,
+    // 成人价格
+    adultPrice: undefined,
+    // 房间数量
+    roomNumber: undefined,
+    // 车辆信息
+    carId: undefined,
+    // 车辆金额
+    carAmount: undefined,
+    // 预定日期
+    orderDate: undefined,
+    // 订单状态
+    orderStatus: undefined,
+    // 旅游项目
+    projectId: undefined,
+    // 项目简述
+    projectResume: undefined,
+    // 顾客姓名
+    customerName: undefined,
+    // 顾客手机号
+    customerMobile: undefined,
+    // 顾客微信号
+    customerWechat: undefined,
+    // 顾客备用手机号
+    customerMobileStandby: undefined,
+    // 创建用户
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新用户
+    updateUserId: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 删除标记(1: 正常 -1: 已删除)
+    dataState: undefined,
+    //核销金额
+    rebatePrice: undefined,
+    // 返利金额
+    rebateSumPrice: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'tourOrder.rebatePrice': [
+    {required: true, message: '请输入核销的金额', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+// 初始化页面数据
+const loadtourOrderData = () => {
+  return new Promise<void>((resolve, reject) => {
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    tourOrderController.view(params).then(res => {
+      formData.tourOrder = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+const refreshFormEditTourOrder = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetFormEditTourOrder = () => {
+  refreshFormEditTourOrder();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormEditTourOrder();
+};
+/**
+ * 核销
+ */
+const onRebate = () => {
+  formEditTourOrderRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let formData = {
+        ...formData.tourOrder
+      };
+  props.dialog?.submit(formData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourOrderDto: {
+        id: formData.tourOrder.id,
+        rebatePrice: formData.tourOrder.rebatePrice,
+      }
+    };
+
+    tourOrderController.clearRebate(params).then(res => {
+      ElMessage.success('核销成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadtourOrderData().then(res => {
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 50 - 8
src/pages/tourOrder/formTourOrder.vue

@@ -122,6 +122,8 @@
       </template> -->
       <vxe-column title="序号" type="seq" :index="tourOrderWidget.getTableIndex" :width="80" />
       <vxe-column title="订单号" field="orderNo" />
+      <vxe-column title="顾客姓名" field="customerName" />
+      <vxe-column title="顾客手机号" field="customerMobile" />
       <vxe-column title="出发日期" field="departureDate">
         <template v-slot="scope">
           <span>{{formatDateByStatsType(scope.row.departureDate, 'day')}}</span>
@@ -139,6 +141,7 @@
       </vxe-column> -->
       <vxe-column title="订单总金额" field="totalAmount" />
       <vxe-column title="币种" field="currency" />
+      <vxe-column title="最高返利金额" field="rebateSumPrice" />
       <vxe-column title="预定日期" field="orderDate">
         <template v-slot="scope">
           <span>{{formatDateByStatsType(scope.row.orderDate, 'day')}}</span>
@@ -165,6 +168,15 @@
           >
             删除
           </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onClearRebateClick(scope.row)"
+            :disabled="scope.row.orderStatus != 1 || !checkPermCodeExist('formTourOrder:formTourOrder:clearRebate')"
+          >
+            核销返利
+          </el-button>
           <!-- <el-button
             link
             type="primary"
@@ -227,9 +239,10 @@ import { useUploadWidget } from '@/common/hooks/useUploadWidget';
 import { DictionaryController } from '@/api/system';
 import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode } from '@/common/utils';
 import { TourOrderPassenageData } from '@/api/generated/tourOrderPassenageController';
-import { tourOrderData } from '@/api/generated/tourOrderController';
+import { TourOrderData } from '@/api/generated/tourOrderController';
 import { TourOrderPassenageController, tourOrderController } from '@/api/generated';
 import FormEditTourOrder from '@/pages/tourOrder/formEditTourOrder.vue';
+import FormEditTourOrderRebate from '@/pages/tourOrder/formEditTourOrderRebate.vue';
 import FormTourOrderPassenger from '@/pages/tourOrder/formTourOrderPassenger.vue';
 import FormSelectTourProject from '@/pages/tourOrder/formSelectTourProject/formSelectTourProject.vue';
 
@@ -238,7 +251,7 @@ const route = useRoute();
 const layoutStore = useLayoutStore();
 const { downloadFile } = useDownload();
 const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
-const { 
+const {
   Delete,
   Search,
   Edit,
@@ -355,7 +368,7 @@ const loadtourOrderVerify = () => {
 /**
  * 新增
  */
-const onAddClick = (row?: tourOrderData) => {
+const onAddClick = (row?: TourOrderData) => {
   let params: ANY_OBJECT = {
   };
 
@@ -371,7 +384,7 @@ const onAddClick = (row?: tourOrderData) => {
 /**
  * 编辑
  */
-const onEditClick = (row?: tourOrderData) => {
+const onEditClick = (row?: TourOrderData) => {
   let params: ANY_OBJECT = {
     id: row?.id,
   };
@@ -388,7 +401,7 @@ const onEditClick = (row?: tourOrderData) => {
 /**
  * 删除
  */
-const onDeleteClick = (row?: tourOrderData) => {
+const onDeleteClick = (row?: TourOrderData) => {
   let params: ANY_OBJECT = {
     id: row?.id,
   };
@@ -402,9 +415,38 @@ const onDeleteClick = (row?: tourOrderData) => {
   });
 };
 /**
+ * 核销返利
+ */
+const onClearRebateClick = (row?: TourOrderData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('核销返利', FormEditTourOrderRebate, { area: ['900px', '650px'] }, { ...params, subPage: true })
+    .then(res => {
+      tourOrderWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  // ElMessageBox.confirm('是否核销返利金额?').then(res => {
+  //   tourOrderController.clearRebate(params).then(res => {
+  //     ElMessage.success('核销成功');
+  //     tourOrderWidget.refreshTable(false, 1);
+  //   }).catch(e => {
+  //     // TODO: 异常处理
+  //     console.error(e);
+  //   });
+  // }).catch(e => {
+  //   // TODO: 异常处理
+  //   console.error(e);
+  // });
+};
+/**
  * 订单游客
  */
-const onFormTourOrderPassengerClick = (row?: tourOrderData) => {
+const onFormTourOrderPassengerClick = (row?: TourOrderData) => {
   let params: ANY_OBJECT = {
     orderId: row?.id,
   };
@@ -415,7 +457,7 @@ const onFormTourOrderPassengerClick = (row?: tourOrderData) => {
   });
 };
 // 表格组件表格组件参数
-const tourOrderOptions: TableOptions<tourOrderData> = {
+const tourOrderOptions: TableOptions<TourOrderData> = {
   loadTableData: loadtourOrderWidgetData,
   verifyTableParameter: loadtourOrderVerify,
   paged: true,
@@ -492,4 +534,4 @@ const formInit = () => {
 onMounted(() => {
   formInit();
 });
-</script>
+</script>

+ 311 - 0
src/pages/tourProjectGroupPurchase/editFormProjectGroupPurchaseDetail.vue

@@ -0,0 +1,311 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="editFormProjectGroupPurchaseDetailRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="成人价格" prop="TourProjectGroupPurchaseDetail.adultPrice">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseDetail.adultPrice"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="2"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="儿童价格" prop="TourProjectGroupPurchaseDetail.childrenPrice">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseDetail.childrenPrice"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="2"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="人数(下限包含)" prop="TourProjectGroupPurchaseDetail.minCount" width="180px">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseDetail.minCount"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="0"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="人数(上限包含)" prop="TourProjectGroupPurchaseDetail.maxCount">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseDetail.maxCount"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="0"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSaveClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'editFormProjectGroupPurchaseDetail',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { TourProjectGroupPurchaseDetailData } from '@/api/generated/tourProjectGroupPurchaseDetailController';
+import { TourProjectGroupPurchaseController, TourProjectGroupPurchaseDetailController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    groupPurchaseCode?: ANY_OBJECT;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    groupPurchaseCode: undefined,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const editFormProjectGroupPurchaseDetailRef = ref();
+// 表单数据定义
+type EditFormProjectGroupPurchaseDetailData = {
+  TourProjectGroupPurchaseDetail: TourProjectGroupPurchaseDetailData;
+};
+// 表单数据
+const formData = reactive<EditFormProjectGroupPurchaseDetailData>({
+  TourProjectGroupPurchaseDetail: {
+    // 主键id
+    id: undefined,
+    // 关联 拼团设置的id
+    groupPurchaseCode: undefined,
+    // 创建用户
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新用户
+    updateUserId: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 删除标记(1: 正常 -1: 已删除)
+    dataState: undefined,
+    // 成人价格
+    adultPrice: undefined,
+    // 儿童价格
+    childrenPrice: undefined,
+    // 阶梯的人数(下限)
+    minCount: undefined,
+    // 阶梯的人数(上限)
+    maxCount: undefined,
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourProjectGroupPurchaseDetail.maxCount': [
+    {required: true, message: '请输入阶梯的人数(上限)', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseDetail.minCount': [
+    {required: true, message: '请输入阶梯的人数(下限)', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseDetail.childrenPrice': [
+  {required: true, message: '请输入儿童价格', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseDetail.adultPrice': [
+    {required: true, message: '请输入成人价格', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourProjectGroupPurchaseDetailData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourProjectGroupPurchaseDetail = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourProjectGroupPurchaseDetailController.view(params).then(res => {
+      formData.TourProjectGroupPurchaseDetail = { ...res.data };
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshEditFormProjectGroupPurchaseDetail = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetEditFormProjectGroupPurchaseDetail = () => {
+  refreshEditFormProjectGroupPurchaseDetail();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetEditFormProjectGroupPurchaseDetail();
+};
+/**
+ * 保存
+ */
+const onSaveClick = () => {
+  editFormProjectGroupPurchaseDetailRef.value.validate((valid) => {
+    if (!valid) return;
+    //判断人数上下限是否合理
+    if (formData.TourProjectGroupPurchaseDetail.maxCount < formData.TourProjectGroupPurchaseDetail.minCount) {
+      ElMessage.error('阶梯的人数(上限)不能小于阶梯的人数(下限)');
+      return;
+    }
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourProjectGroupPurchaseDetail
+      };
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourProjectGroupPurchaseDetailDto: {
+        id: formData.TourProjectGroupPurchaseDetail.id,
+        groupPurchaseCode: props.groupPurchaseCode,
+        createUserId: formData.TourProjectGroupPurchaseDetail.createUserId,
+        createTime: formData.TourProjectGroupPurchaseDetail.createTime,
+        updateUserId: formData.TourProjectGroupPurchaseDetail.updateUserId,
+        updateTime: formData.TourProjectGroupPurchaseDetail.updateTime,
+        adultPrice: formData.TourProjectGroupPurchaseDetail.adultPrice,
+        childrenPrice: formData.TourProjectGroupPurchaseDetail.childrenPrice,
+        minCount: formData.TourProjectGroupPurchaseDetail.minCount,
+        maxCount: formData.TourProjectGroupPurchaseDetail.maxCount,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourProjectGroupPurchaseDetailController.update : TourProjectGroupPurchaseDetailController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourProjectGroupPurchaseDetailData().then(res => {
+    if (isEdit.value) refreshEditFormProjectGroupPurchaseDetail();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 636 - 0
src/pages/tourProjectGroupPurchase/editTourProjectGroupPurchase.vue

@@ -0,0 +1,636 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="editTourProjectGroupPurchaseRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="选择旅游项目" prop="TourProjectGroupPurchase.projectId">
+              <SelectBookTourismProject
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.projectId"
+                placeholder=""
+                :required="true"
+                :disabled="false"
+                :props="{
+                  label: 'projectTitle',
+                  value: 'id'
+                }"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="拼团截至时间" prop="TourProjectGroupPurchase.endTime">
+              <el-date-picker
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.endTime"
+                type="date"
+                placeholder=""
+                :clearable="true"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="出行开始时间" prop="TourProjectGroupPurchase.travelStartTime">
+              <el-date-picker
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.travelStartTime"
+                type="date"
+                placeholder=""
+                :clearable="true"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+              />
+            </el-form-item>
+          </el-col>
+          <!-- <el-col :span="12">
+            <el-form-item label="出行结束时间" prop="TourProjectGroupPurchase.travelEndTime">
+              <el-date-picker
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.travelEndTime"
+                type="date"
+                placeholder=""
+                :clearable="true"
+                format="YYYY-MM-DD"
+                value-format="YYYY-MM-DD"
+              />
+            </el-form-item>
+          </el-col> -->
+          <el-col :span="12">
+            <el-form-item label="拼团人数上限" prop="TourProjectGroupPurchase.maxCount">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.maxCount"
+                placeholder=""
+                :clearable="true"
+                :min="3"
+                :max="9"
+                :step="1"
+                :precision="0"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="拼团状态" prop="TourProjectGroupPurchase.state">
+              <el-select
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.state"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="stateWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in stateWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="儿童最低价格" prop="TourProjectGroupPurchase.childrenPrice">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.childrenPrice"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="2"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="成人最低价格" prop="TourProjectGroupPurchase.adultPrice">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.adultPrice"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="2"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="价格单位" prop="TourProjectGroupPurchase.priceUnit">
+              <el-input
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.priceUnit"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="返利价格/人" prop="TourProjectGroupPurchase.singleRebate">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.singleRebate"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="2"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="显示顺序" prop="TourProjectGroupPurchase.showOrder">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.showOrder"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :precision="0"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="拼团标题" prop="TourProjectGroupPurchase.title">
+              <el-input
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchase.title"
+                type="textarea"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="背景图" prop="TourProjectGroupPurchase.image">
+              <custom-upload
+                v-model="imageWidgetFileList"
+                name="uploadFile"
+                :size="layoutStore.defaultFormItemSize"
+                type="expand"
+                :headers="getUploadHeaders"
+                :action="getUploadActionUrl('/admin/app/tourProjectGroupPurchase/upload')"
+                :data="{fieldName: 'image', asImage: true}"
+                :limit="imageWidgetMaxCount"
+                @change="onImageChange"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSaveClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'editTourProjectGroupPurchase',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseDetailData } from '@/api/generated/tourProjectGroupPurchaseDetailController';
+import { TourProjectGroupPurchaseController, TourismProjectController, TourProjectGroupPurchaseDetailController } from '@/api/generated';
+import SelectBookTourismProject from '@/pages/tourTourismBookInfo/selectBookTourismProject/index.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const editTourProjectGroupPurchaseRef = ref();
+// 表单数据定义
+type EditTourProjectGroupPurchaseData = {
+  TourProjectGroupPurchase: TourProjectGroupPurchaseData;
+};
+// 表单数据
+const formData = reactive<EditTourProjectGroupPurchaseData>({
+  TourProjectGroupPurchase: {
+    // 主键id
+    id: undefined,
+    // 项目id
+    projectId: undefined,
+    // 拼团结束时间
+    endTime: undefined,
+    // 出行开始时间
+    travelStartTime: undefined,
+    // 出行结束时间
+    travelEndTime: undefined,
+    // 拼团状态(0禁用,1启用)
+    state: undefined,
+    // 创建用户
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新用户
+    updateUserId: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 删除标记(1: 正常 -1: 已删除)
+    dataState: undefined,
+    // 拼团人数上限
+    maxCount: undefined,
+    // 成人价格
+    adultPrice: undefined,
+    // 儿童价格
+    childrenPrice: undefined,
+    // 显示顺序
+    showOrder: undefined,
+    // 关联字段(与从表)
+    code: undefined,
+    // 当前拼团的人数
+    nowCount: undefined,
+    // 拼团是否成功(0.失败;1.成功)
+    success: undefined,
+    // 拼团标题
+    title: undefined,
+    // 图片url
+    image: undefined,
+    // 价格单位
+    priceUnit: undefined,
+    // 拼团返利/人
+    singleRebate: undefined,
+    tourismProject: {
+      // 主键id
+      id: undefined,
+      // 项目标题
+      projectTitle: undefined,
+      // 项目简述
+      remarks: undefined,
+      // 是否热点
+      isHotspot: undefined,
+      // 标签
+      projectLabel: undefined,
+      // 显示顺序
+      showOrder: undefined,
+      // 是否启用
+      enable: undefined,
+      // 所属分类
+      belongTab: undefined,
+      // 出发地
+      startPlace: undefined,
+      // 目的地
+      endPlace: undefined,
+      // 总天数
+      countTimes: undefined,
+      // 项目价格
+      price: undefined,
+      // 项目展示图片
+      tourismUrl: undefined,
+      // 创建用户
+      createUserId: undefined,
+      // 创建时间
+      createTime: undefined,
+      // 更新用户
+      updateUserId: undefined,
+      // 更新时间
+      updateTime: undefined,
+      // 删除标记(1: 正常 -1: 已删除)
+      dataState: undefined,
+      // 价格单位
+      priceUnit: undefined,
+      // 服务保障
+      serviceEnsure: undefined,
+      // 联系电话
+      contactNumber: undefined,
+      // 产品卖点
+      sellingPoint: undefined,
+      // 短标题
+      shortTitle: undefined,
+      // 短描述
+      shortDescription: undefined,
+      // 首页热门图片
+      homeHotPicture: undefined,
+      // 联系人描述
+      contactDescription: undefined,
+      // 游记banner
+      travelNotesBanner: undefined,
+      // 点赞量
+      likeCount: undefined,
+      // 浏览量
+      pageViewCount: undefined,
+      // 人物关系
+      role: undefined,
+      // 出发时间
+      departureTime: undefined,
+      // 人均费用
+      averageCost: undefined,
+      // 推荐指数
+      recommendationRate: undefined,
+      // 上传的联系二维码
+      contactCode: undefined,
+    },
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourProjectGroupPurchase.childrenPrice': [
+    {required: true, message: '请输入儿童价格', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.priceUnit': [
+    {required: true, message: '请输入价格单位', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.adultPrice': [
+    {required: true, message: '请输入成人价格', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.maxCount': [
+    {required: true, message: '请输入拼团人数上限', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.showOrder': [
+    {required: true, message: '请输入显示顺序', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.state': [
+    {required: true, message: '请输入拼团状态', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.endTime': [
+    {required: true, message: '请输入拼团截至时间', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.projectId': [
+    {required: true, message: '请输入选择旅游项目', trigger: 'blur'}
+  ],
+  // 'TourProjectGroupPurchase.travelEndTime': [
+  //   {required: true, message: '请输入出行结束时间', trigger: 'blur'}
+  // ],
+  'TourProjectGroupPurchase.title': [
+    {required: true, message: '请输入拼团标题', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.image': [
+    {required: true, message: '请输入背景图', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.travelStartTime': [
+    {required: true, message: '请输入出行开始时间', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchase.singleRebate': [
+    {required: true, message: '请输入拼团返利/人', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourProjectGroupPurchaseData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourProjectGroupPurchase = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourProjectGroupPurchaseController.view(params).then(res => {
+      formData.TourProjectGroupPurchase = { ...res.data };
+      if (formData.TourProjectGroupPurchase.tourismProject == null) {
+        formData.TourProjectGroupPurchase.tourismProject = {
+          id: undefined,
+          projectTitle: undefined,
+          remarks: undefined,
+          isHotspot: undefined,
+          projectLabel: undefined,
+          showOrder: undefined,
+          enable: undefined,
+          belongTab: undefined,
+          startPlace: undefined,
+          endPlace: undefined,
+          countTimes: undefined,
+          price: undefined,
+          tourismUrl: undefined,
+          createUserId: undefined,
+          createTime: undefined,
+          updateUserId: undefined,
+          updateTime: undefined,
+          dataState: undefined,
+          priceUnit: undefined,
+          serviceEnsure: undefined,
+          contactNumber: undefined,
+          sellingPoint: undefined,
+          shortTitle: undefined,
+          shortDescription: undefined,
+          homeHotPicture: undefined,
+          contactDescription: undefined,
+          travelNotesBanner: undefined,
+          likeCount: undefined,
+          pageViewCount: undefined,
+          role: undefined,
+          departureTime: undefined,
+          averageCost: undefined,
+          recommendationRate: undefined,
+          contactCode: undefined
+        };
+      }
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 拼团状态下拉数据获取函数
+ */
+const loadStateDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 拼团状态配置参数
+const stateOptions: DropdownOptions<DictData> = {
+  loadData: loadStateDropdownList,
+  isTree: false,
+};
+// 拼团状态下拉组件
+const stateWidget = useDropdown(stateOptions);
+const { dropdownList: stateWidgetDropdownList } = stateWidget
+/**
+ * 背景图上传文件改变
+ */
+const onImageChange = val => {
+  formData.TourProjectGroupPurchase.image = fileListToJson(val);
+};
+// 背景图上传文件组件
+const imageWidget = useUploadWidget(1);
+const { fileList: imageWidgetFileList, maxCount: imageWidgetMaxCount } = imageWidget;
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshEditTourProjectGroupPurchase = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetEditTourProjectGroupPurchase = () => {
+  refreshEditTourProjectGroupPurchase();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetEditTourProjectGroupPurchase();
+};
+/**
+ * 保存
+ */
+const onSaveClick = () => {
+  editTourProjectGroupPurchaseRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourProjectGroupPurchase
+      };
+    retFormData.stateDictMap = findItemFromList(stateWidgetDropdownList.value, retFormData.state, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourProjectGroupPurchaseDto: {
+        id: formData.TourProjectGroupPurchase.id,
+        showOrder: formData.TourProjectGroupPurchase.showOrder,
+        code: formData.TourProjectGroupPurchase.code,
+        nowCount: formData.TourProjectGroupPurchase.nowCount,
+        success: formData.TourProjectGroupPurchase.success,
+        title: formData.TourProjectGroupPurchase.title,
+        image: formData.TourProjectGroupPurchase.image,
+        priceUnit: formData.TourProjectGroupPurchase.priceUnit,
+        singleRebate: formData.TourProjectGroupPurchase.singleRebate,
+        projectId: formData.TourProjectGroupPurchase.projectId,
+        endTime: formData.TourProjectGroupPurchase.endTime,
+        travelStartTime: formData.TourProjectGroupPurchase.travelStartTime,
+        travelEndTime: formData.TourProjectGroupPurchase.travelEndTime,
+        state: formData.TourProjectGroupPurchase.state,
+        createUserId: formData.TourProjectGroupPurchase.createUserId,
+        createTime: formData.TourProjectGroupPurchase.createTime,
+        updateUserId: formData.TourProjectGroupPurchase.updateUserId,
+        updateTime: formData.TourProjectGroupPurchase.updateTime,
+        maxCount: formData.TourProjectGroupPurchase.maxCount,
+        adultPrice: formData.TourProjectGroupPurchase.adultPrice,
+        childrenPrice: formData.TourProjectGroupPurchase.childrenPrice,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourProjectGroupPurchaseController.update : TourProjectGroupPurchaseController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourProjectGroupPurchaseData().then(res => {
+    stateWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    let imageDownloadParams = {
+      id: formData.TourProjectGroupPurchase.id,
+      fieldName: 'image',
+      asImage: true
+    };
+    imageWidgetFileList.value = parseUploadData(formData.TourProjectGroupPurchase.image, imageDownloadParams);
+    if (isEdit.value) refreshEditTourProjectGroupPurchase();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 279 - 0
src/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseDetail.vue

@@ -0,0 +1,279 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <table-box
+      ref="tourProjectGroupPurchaseDetail"
+      class="page-table"
+      :data="tourProjectGroupPurchaseDetailWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((tourProjectGroupPurchaseDetailWidgetCurrentPage - 1) * tourProjectGroupPurchaseDetailWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="tourProjectGroupPurchaseDetailWidget.onSortChange"
+      @refresh="tourProjectGroupPurchaseDetailWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          @click="onAddClick()"
+          >
+          新增
+        </el-button>
+      </template>
+      <vxe-column title="序号" type="seq" :index="tourProjectGroupPurchaseDetailWidget.getTableIndex" :width="80" />
+      <vxe-column title="成人价格" field="adultPrice" />
+      <vxe-column title="儿童价格" field="childrenPrice" />
+      <vxe-column title="阶梯的人数(下限包含)" field="minCount" />
+      <vxe-column title="阶梯的人数(上限包含)" field="maxCount" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditClick(scope.row)"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteClick(scope.row)"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="tourProjectGroupPurchaseDetailWidgetTotalCount"
+            :current-page="tourProjectGroupPurchaseDetailWidgetCurrentPage"
+            :page-size="tourProjectGroupPurchaseDetailWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="tourProjectGroupPurchaseDetailWidget.onCurrentPageChange"
+            @size-change="tourProjectGroupPurchaseDetailWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourProjectGroupPurchaseDetail',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { TourProjectGroupPurchaseDetailData } from '@/api/generated/tourProjectGroupPurchaseDetailController';
+import { TourProjectGroupPurchaseController, TourProjectGroupPurchaseDetailController } from '@/api/generated';
+import EditFormProjectGroupPurchaseDetail from '@/pages/tourProjectGroupPurchase/editFormProjectGroupPurchaseDetail.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    groupPurchaseCode?: ANY_OBJECT;
+  }>(),
+  {
+    subPage: 0,
+    groupPurchaseCode: undefined,
+  },
+);
+
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourProjectGroupPurchaseDetail();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadTourProjectGroupPurchaseDetailWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourProjectGroupPurchaseDetailDtoFilter:{
+      groupPurchaseCode : props.groupPurchaseCode
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourProjectGroupPurchaseDetailController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount,
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadTourProjectGroupPurchaseDetailVerify = () => {
+  return true;
+};
+/**
+ * 新增
+ */
+const onAddClick = (row?: TourProjectGroupPurchaseDetailData) => {
+  let params: ANY_OBJECT = {
+    groupPurchaseCode: props.groupPurchaseCode,
+  };
+
+  Dialog
+    .show('新增', EditFormProjectGroupPurchaseDetail, { area: ['900px', '700px'] }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseDetailWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditClick = (row?: TourProjectGroupPurchaseDetailData) => {
+  let params: ANY_OBJECT = {
+    groupPurchaseCode: props.groupPurchaseCode,
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', EditFormProjectGroupPurchaseDetail, { area: ['900px', '700px'] }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseDetailWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 删除
+ */
+const onDeleteClick = (row?: TourProjectGroupPurchaseDetailData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除该条数据?').then(res => {
+    TourProjectGroupPurchaseDetailController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      tourProjectGroupPurchaseDetailWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const tourProjectGroupPurchaseDetailOptions: TableOptions<TourProjectGroupPurchaseDetailData> = {
+  loadTableData: loadTourProjectGroupPurchaseDetailWidgetData,
+  verifyTableParameter: loadTourProjectGroupPurchaseDetailVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const tourProjectGroupPurchaseDetail = ref();
+const tourProjectGroupPurchaseDetailWidget = useTable(tourProjectGroupPurchaseDetailOptions);
+const {
+  dataList: tourProjectGroupPurchaseDetailWidgetDataList,
+  currentPage: tourProjectGroupPurchaseDetailWidgetCurrentPage,
+  pageSize: tourProjectGroupPurchaseDetailWidgetPageSize,
+  totalCount: tourProjectGroupPurchaseDetailWidgetTotalCount,
+} = tourProjectGroupPurchaseDetailWidget;
+const refreshFormTourProjectGroupPurchaseDetail = () => {
+  // 刷新段落
+  tourProjectGroupPurchaseDetailWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourProjectGroupPurchaseDetail = () => {
+  refreshFormTourProjectGroupPurchaseDetail();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourProjectGroupPurchaseDetail();
+};
+const formInit = () => {
+  refreshFormTourProjectGroupPurchaseDetail();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 500 - 0
src/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseInfo.vue

@@ -0,0 +1,500 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourProjectGroupPurchaseInfoRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourProjectGroupPurchaseInfo()" @reset="resetFormTourProjectGroupPurchaseInfo">
+        <el-form-item label="选择旅游项目">
+          <SelectBookTourismProject
+            class="filter-item"
+            v-model="formFilter.projectIdFilter"
+            placeholder=""
+            :required="false"
+            :disabled="false"
+            :props="{
+              label: 'projectTitle',
+              value: 'id'
+            }"
+          />
+        </el-form-item>
+        <el-form-item label="拼团截止时间">
+          <el-date-picker
+            class="filter-item"
+            v-model="formFilter.endTimeFilter"
+            type="daterange"
+            start-placeholder=""
+            end-placeholder=""
+            :clearable="true"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            :default-time="[new Date().setHours(0, 0, 0, 0), new Date().setHours(23, 59, 59, 999)]"
+          />
+        </el-form-item>
+        <el-form-item label="出行开始时间">
+          <el-date-picker
+            class="filter-item"
+            v-model="formFilter.travelStartTimeFilter"
+            type="daterange"
+            start-placeholder=""
+            end-placeholder=""
+            :clearable="true"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            :default-time="[new Date().setHours(0, 0, 0, 0), new Date().setHours(23, 59, 59, 999)]"
+          />
+        </el-form-item>
+        <!-- <el-form-item label="出行结束时间">
+          <el-date-picker
+            class="filter-item"
+            v-model="formFilter.travelEndTimeFilter"
+            type="daterange"
+            start-placeholder=""
+            end-placeholder=""
+            :clearable="true"
+            format="YYYY-MM-DD"
+            value-format="YYYY-MM-DD HH:mm:ss"
+            :default-time="[new Date().setHours(0, 0, 0, 0), new Date().setHours(23, 59, 59, 999)]"
+          />
+        </el-form-item> -->
+        <el-form-item label="拼团状态">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.stateFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="stateFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in stateFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="拼团人数上限">
+          <input-number-range
+            class="filter-item"
+            v-model="formFilter.maxCountFilter"
+            startPlaceholder=""
+            endPlaceholder=""
+            :step="1"
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="tourProjectGroupPurchase"
+      class="page-table"
+      :data="tourProjectGroupPurchaseWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((tourProjectGroupPurchaseWidgetCurrentPage - 1) * tourProjectGroupPurchaseWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="tourProjectGroupPurchaseWidget.onSortChange"
+      @refresh="tourProjectGroupPurchaseWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseInfo:formTourProjectGroupPurchaseInfo:add')"
+          @click="onAddClick()"
+          >
+          新增
+        </el-button>
+      </template>
+      <vxe-column title="序号" type="seq" :index="tourProjectGroupPurchaseWidget.getTableIndex" :width="80" />
+      <vxe-column title="拼团项目标题" field="tourismProject.projectTitle" />
+      <vxe-column title="拼团截止时间" field="endTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.endTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <vxe-column title="出行开始时间" field="travelStartTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.travelStartTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <!-- <vxe-column title="出行结束时间" field="travelEndTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.travelEndTime, 'day')}}</span>
+        </template>
+      </vxe-column> -->
+      <vxe-column title="拼团状态" field="stateDictMap.name" />
+      <vxe-column title="拼团人数上限" field="maxCount" />
+      <vxe-column title="成人价格" field="adultPrice" />
+      <vxe-column title="儿童价格" field="childrenPrice" />
+      <vxe-column title="价格单位" field="priceUnit" />
+      <vxe-column title="返利价格/人" field="singleRebate" />
+      <vxe-column title="显示顺序" field="showOrder" />
+      <vxe-column title="当前拼团的人数" field="nowCount" />
+      <vxe-column title="拼团是否成功" field="successDictMap.name" />
+      <vxe-column title="拼团标题" field="title" />
+      <vxe-column title="图片url">
+        <template v-slot="scope">
+          <upload-file-list
+            :file-list="
+              parseUploadData(scope.row.image, {
+                id: scope.row.id,
+                fieldName: 'image',
+                asImage: true
+              })
+            "
+            type="card"
+            direction="horizontal"
+            :readonly="true"
+          />
+        </template>
+      </vxe-column>
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseInfo:formTourProjectGroupPurchaseInfo:edit')"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onFormTourProjectGroupPurchaseDetailClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseInfo:formTourProjectGroupPurchaseInfo:formTourProjectGroupPurchaseDetail')"
+          >
+            拼团设置从表管理
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="tourProjectGroupPurchaseWidgetTotalCount"
+            :current-page="tourProjectGroupPurchaseWidgetCurrentPage"
+            :page-size="tourProjectGroupPurchaseWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="tourProjectGroupPurchaseWidget.onCurrentPageChange"
+            @size-change="tourProjectGroupPurchaseWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourProjectGroupPurchaseInfo',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseDetailData } from '@/api/generated/tourProjectGroupPurchaseDetailController';
+import { TourProjectGroupPurchaseController, TourismProjectController, TourProjectGroupPurchaseDetailController } from '@/api/generated';
+import FormTourProjectGroupPurchaseDetail from '@/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseDetail.vue';
+import EditTourProjectGroupPurchase from '@/pages/tourProjectGroupPurchase/editTourProjectGroupPurchase.vue';
+import SelectBookTourismProject from '@/pages/tourTourismBookInfo/selectBookTourismProject/index.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 选择旅游项目
+  projectIdFilter: undefined,
+  // 拼团截止时间
+  endTimeFilter: [],
+  // 出行开始时间
+  travelStartTimeFilter: [],
+  // 出行结束时间
+  travelEndTimeFilter: [],
+  // 拼团状态
+  stateFilter: undefined,
+  // 拼团人数上限
+  maxCountFilter: [],
+});
+const formFilterCopy = reactive({
+  // 选择旅游项目
+  projectIdFilter: undefined,
+  // 拼团截止时间
+  endTimeFilter: [],
+  // 出行开始时间
+  travelStartTimeFilter: [],
+  // 出行结束时间
+  travelEndTimeFilter: [],
+  // 拼团状态
+  stateFilter: undefined,
+  // 拼团人数上限
+  maxCountFilter: [],
+});
+// 表格行内编辑用到的所有字典数据
+const inlineTableDictList = ref({
+  enableDataList: [],
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourProjectGroupPurchaseInfo();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadTourProjectGroupPurchaseWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourProjectGroupPurchaseDtoFilter: {
+      projectId: formFilter.projectIdFilter,
+      endTimeStart: Array.isArray(formFilter.endTimeFilter) ? formFilter.endTimeFilter[0] : formFilter.endTimeFilter,
+      endTimeEnd: Array.isArray(formFilter.endTimeFilter) ? formFilter.endTimeFilter[1] : formFilter.endTimeFilter,
+      travelStartTimeStart: Array.isArray(formFilter.travelStartTimeFilter) ? formFilter.travelStartTimeFilter[0] : formFilter.travelStartTimeFilter,
+      travelStartTimeEnd: Array.isArray(formFilter.travelStartTimeFilter) ? formFilter.travelStartTimeFilter[1] : formFilter.travelStartTimeFilter,
+      travelEndTimeStart: Array.isArray(formFilter.travelEndTimeFilter) ? formFilter.travelEndTimeFilter[0] : formFilter.travelEndTimeFilter,
+      travelEndTimeEnd: Array.isArray(formFilter.travelEndTimeFilter) ? formFilter.travelEndTimeFilter[1] : formFilter.travelEndTimeFilter,
+      state: formFilter.stateFilter,
+      maxCountStart: Array.isArray(formFilter.maxCountFilter) ? formFilter.maxCountFilter[0] : formFilter.maxCountFilter,
+      maxCountEnd: Array.isArray(formFilter.maxCountFilter) ? formFilter.maxCountFilter[1] : formFilter.maxCountFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourProjectGroupPurchaseController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadTourProjectGroupPurchaseVerify = () => {
+  formFilterCopy.projectIdFilter = formFilter.projectIdFilter;
+  formFilterCopy.endTimeFilter = formFilter.endTimeFilter;
+  formFilterCopy.travelStartTimeFilter = formFilter.travelStartTimeFilter;
+  formFilterCopy.travelEndTimeFilter = formFilter.travelEndTimeFilter;
+  formFilterCopy.stateFilter = formFilter.stateFilter;
+  formFilterCopy.maxCountFilter = formFilter.maxCountFilter;
+  return true;
+};
+/**
+ * 新增
+ */
+const onAddClick = (row?: TourProjectGroupPurchaseData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新增', EditTourProjectGroupPurchase, { area: ['900px', '700px'] }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditClick = (row?: TourProjectGroupPurchaseData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', EditTourProjectGroupPurchase, { area: ['900px', '700px'] }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 拼团设置从表管理
+ */
+const onFormTourProjectGroupPurchaseDetailClick = (row?: TourProjectGroupPurchaseData) => {
+  let params: ANY_OBJECT = {
+    groupPurchaseCode: row?.code,
+  };
+
+  router.push({
+    name: 'formTourProjectGroupPurchaseDetail',
+    query: { ...params, subPage: true }
+  });
+};
+// 表格组件表格组件参数
+const tourProjectGroupPurchaseOptions: TableOptions<TourProjectGroupPurchaseData> = {
+  loadTableData: loadTourProjectGroupPurchaseWidgetData,
+  verifyTableParameter: loadTourProjectGroupPurchaseVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const tourProjectGroupPurchase = ref();
+const tourProjectGroupPurchaseWidget = useTable(tourProjectGroupPurchaseOptions);
+const {
+  dataList: tourProjectGroupPurchaseWidgetDataList,
+  currentPage: tourProjectGroupPurchaseWidgetCurrentPage,
+  pageSize: tourProjectGroupPurchaseWidgetPageSize,
+  totalCount: tourProjectGroupPurchaseWidgetTotalCount,
+} = tourProjectGroupPurchaseWidget;
+/**
+ * 拼团状态下拉数据获取函数
+ */
+const loadStateFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 拼团状态配置参数
+const stateFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadStateFilterDropdownList,
+  isTree: false,
+};
+// 拼团状态下拉组件
+const stateFilterWidget = useDropdown(stateFilterOptions);
+const { dropdownList: stateFilterWidgetDropdownList } = stateFilterWidget
+const refreshFormTourProjectGroupPurchaseInfo = () => {
+  // 刷新段落
+  tourProjectGroupPurchaseWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourProjectGroupPurchaseInfo = () => {
+  formFilter.projectIdFilter = undefined;
+  formFilterCopy.projectIdFilter = undefined;
+  formFilter.endTimeFilter = undefined;
+  formFilterCopy.endTimeFilter = undefined;
+  formFilter.travelStartTimeFilter = undefined;
+  formFilterCopy.travelStartTimeFilter = undefined;
+  formFilter.travelEndTimeFilter = undefined;
+  formFilterCopy.travelEndTimeFilter = undefined;
+  formFilter.stateFilter = undefined;
+  formFilterCopy.stateFilter = undefined;
+  formFilter.maxCountFilter = undefined;
+  formFilterCopy.maxCountFilter = undefined;
+  refreshFormTourProjectGroupPurchaseInfo();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourProjectGroupPurchaseInfo();
+};
+const loadInlineEnableData = () => {
+  return new Promise((resolve, reject) => {
+    inlineTableDictList.value.enableDataList = StaticDict.Enable.getList();
+    inlineTableDictList.value.enableDataList.forEach(item => {
+      item.id = item.id.toString();
+    });
+    resolve();
+  });
+};
+const loadAllInlineTableDictData = () => {
+  return new Promise((resolve, reject) => {
+    let promises = [
+      loadInlineEnableData(),
+    ];
+    Promise.all(promises).then(() => {
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+const formInit = () => {
+  stateFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourProjectGroupPurchaseInfo();
+};
+
+onMounted(() => {
+  loadAllInlineTableDictData().then(() => {
+    formInit();
+  }).catch(() => {
+    formInit();
+  });
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 456 - 0
src/pages/tourProjectGroupPurchaseApply/editTourProjectGroupPurchaseState.vue

@@ -0,0 +1,456 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="editTourProjectGroupPurchaseStateRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="是否处理" prop="TourProjectGroupPurchaseApply.isHandle">
+              <el-select
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseApply.isHandle"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="isHandleWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in isHandleWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="备注" prop="TourProjectGroupPurchaseApply.remark">
+              <el-input
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseApply.remark"
+                type="textarea"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength=""
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSaveClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'editTourProjectGroupPurchaseState',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseApplyData } from '@/api/generated/tourProjectGroupPurchaseApplyController';
+import { TourUserData } from '@/api/generated/tourUserController';
+import { TourismProjectController, TourProjectGroupPurchaseApplyController, TourUserController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const editTourProjectGroupPurchaseStateRef = ref();
+// 表单数据定义
+type EditTourProjectGroupPurchaseStateData = {
+  TourProjectGroupPurchaseApply: TourProjectGroupPurchaseApplyData;
+};
+// 表单数据
+const formData = reactive<EditTourProjectGroupPurchaseStateData>({
+  TourProjectGroupPurchaseApply: {
+    // 主键id
+    id: undefined,
+    // 项目id
+    projectId: undefined,
+    // 用户Id
+    tourUserId: undefined,
+    // 申请时间
+    applyTime: undefined,
+    // 是否处理(0:未处理 1:已处理)
+    isHandle: undefined,
+    // 创建用户
+    createUserId: undefined,
+    // 备注
+    remark: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 更新用户
+    updateUserId: undefined,
+    // 更新时间
+    updateTime: undefined,
+    // 删除标记(1: 正常 -1: 已删除)
+    dataState: undefined,
+    tourismProject: {
+      // 主键id
+      id: undefined,
+      // 项目标题
+      projectTitle: undefined,
+      // 项目简述
+      remarks: undefined,
+      // 是否热点
+      isHotspot: undefined,
+      // 标签
+      projectLabel: undefined,
+      // 显示顺序
+      showOrder: undefined,
+      // 是否启用
+      enable: undefined,
+      // 所属分类
+      belongTab: undefined,
+      // 出发地
+      startPlace: undefined,
+      // 目的地
+      endPlace: undefined,
+      // 总天数
+      countTimes: undefined,
+      // 项目价格
+      price: undefined,
+      // 项目展示图片
+      tourismUrl: undefined,
+      // 创建用户
+      createUserId: undefined,
+      // 创建时间
+      createTime: undefined,
+      // 更新用户
+      updateUserId: undefined,
+      // 更新时间
+      updateTime: undefined,
+      // 删除标记(1: 正常 -1: 已删除)
+      dataState: undefined,
+      // 价格单位
+      priceUnit: undefined,
+      // 服务保障
+      serviceEnsure: undefined,
+      // 联系电话
+      contactNumber: undefined,
+      // 产品卖点
+      sellingPoint: undefined,
+      // 短标题
+      shortTitle: undefined,
+      // 短描述
+      shortDescription: undefined,
+      // 首页热门图片
+      homeHotPicture: undefined,
+      // 联系人描述
+      contactDescription: undefined,
+      // 游记banner
+      travelNotesBanner: undefined,
+      // 点赞量
+      likeCount: undefined,
+      // 浏览量
+      pageViewCount: undefined,
+      // 人物关系
+      role: undefined,
+      // 出发时间
+      departureTime: undefined,
+      // 人均费用
+      averageCost: undefined,
+      // 推荐指数
+      recommendationRate: undefined,
+      // 上传的联系二维码
+      contactCode: undefined,
+    },
+    tourUser: {
+      // 主键Id
+      userId: undefined,
+      // 用户登录名称
+      loginName: undefined,
+      // 密码
+      password: undefined,
+      // 昵称
+      showName: undefined,
+      // 用户头像的Url
+      headImageUrl: undefined,
+      // 状态(0: 正常 1: 锁定)
+      userStatus: undefined,
+      // 用户邮箱
+      email: undefined,
+      // 用户手机
+      mobile: undefined,
+      // 性别(1:男 2:女 3:其它)
+      sex: undefined,
+      // 生日
+      birthday: undefined,
+      // 创建者Id
+      createUserId: undefined,
+      // 创建时间
+      createTime: undefined,
+      // 更新者Id
+      updateUserId: undefined,
+      // 最后更新时间
+      updateTime: undefined,
+      // 删除标记(1: 正常 -1: 已删除)
+      deletedFlag: undefined,
+    },
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourProjectGroupPurchaseApply.remark': [
+  ],
+  'TourProjectGroupPurchaseApply.isHandle': [
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourProjectGroupPurchaseApplyData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourProjectGroupPurchaseApply = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourProjectGroupPurchaseApplyController.view(params).then(res => {
+      formData.TourProjectGroupPurchaseApply = { ...res.data };
+      if (formData.TourProjectGroupPurchaseApply.tourismProject == null) {
+        formData.TourProjectGroupPurchaseApply.tourismProject = {
+          id: undefined,
+          projectTitle: undefined,
+          remarks: undefined,
+          isHotspot: undefined,
+          projectLabel: undefined,
+          showOrder: undefined,
+          enable: undefined,
+          belongTab: undefined,
+          startPlace: undefined,
+          endPlace: undefined,
+          countTimes: undefined,
+          price: undefined,
+          tourismUrl: undefined,
+          createUserId: undefined,
+          createTime: undefined,
+          updateUserId: undefined,
+          updateTime: undefined,
+          dataState: undefined,
+          priceUnit: undefined,
+          serviceEnsure: undefined,
+          contactNumber: undefined,
+          sellingPoint: undefined,
+          shortTitle: undefined,
+          shortDescription: undefined,
+          homeHotPicture: undefined,
+          contactDescription: undefined,
+          travelNotesBanner: undefined,
+          likeCount: undefined,
+          pageViewCount: undefined,
+          role: undefined,
+          departureTime: undefined,
+          averageCost: undefined,
+          recommendationRate: undefined,
+          contactCode: undefined
+        };
+      }
+      if (formData.TourProjectGroupPurchaseApply.tourUser == null) {
+        formData.TourProjectGroupPurchaseApply.tourUser = {
+          userId: undefined,
+          loginName: undefined,
+          password: undefined,
+          showName: undefined,
+          headImageUrl: undefined,
+          userStatus: undefined,
+          email: undefined,
+          mobile: undefined,
+          sex: undefined,
+          birthday: undefined,
+          createUserId: undefined,
+          createTime: undefined,
+          updateUserId: undefined,
+          updateTime: undefined,
+          deletedFlag: undefined
+        };
+      }
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 是否处理下拉数据获取函数
+ */
+const loadIsHandleDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'IsHandle', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 是否处理配置参数
+const isHandleOptions: DropdownOptions<DictData> = {
+  loadData: loadIsHandleDropdownList,
+  isTree: false,
+};
+// 是否处理下拉组件
+const isHandleWidget = useDropdown(isHandleOptions);
+const { dropdownList: isHandleWidgetDropdownList } = isHandleWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshEditTourProjectGroupPurchaseState = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetEditTourProjectGroupPurchaseState = () => {
+  refreshEditTourProjectGroupPurchaseState();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetEditTourProjectGroupPurchaseState();
+};
+/**
+ * 保存
+ */
+const onSaveClick = () => {
+  editTourProjectGroupPurchaseStateRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourProjectGroupPurchaseApply
+      };
+    retFormData.isHandleDictMap = findItemFromList(isHandleWidgetDropdownList.value, retFormData.isHandle, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourProjectGroupPurchaseApplyDto: {
+        id: formData.TourProjectGroupPurchaseApply.id,
+        remark: formData.TourProjectGroupPurchaseApply.remark,
+        projectId: formData.TourProjectGroupPurchaseApply.projectId,
+        tourUserId: formData.TourProjectGroupPurchaseApply.tourUserId,
+        applyTime: formData.TourProjectGroupPurchaseApply.applyTime,
+        isHandle: formData.TourProjectGroupPurchaseApply.isHandle,
+        createUserId: formData.TourProjectGroupPurchaseApply.createUserId,
+        createTime: formData.TourProjectGroupPurchaseApply.createTime,
+        updateUserId: formData.TourProjectGroupPurchaseApply.updateUserId,
+        updateTime: formData.TourProjectGroupPurchaseApply.updateTime,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourProjectGroupPurchaseApplyController.update : TourProjectGroupPurchaseApplyController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourProjectGroupPurchaseApplyData().then(res => {
+    isHandleWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshEditTourProjectGroupPurchaseState();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 313 - 0
src/pages/tourProjectGroupPurchaseApply/formTourProjectGroupPurchaseApply.vue

@@ -0,0 +1,313 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourProjectGroupPurchaseApplyRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourProjectGroupPurchaseApply()" @reset="resetFormTourProjectGroupPurchaseApply">
+        <el-form-item label="选择旅游项目">
+          <SelectBookTourismProject
+            class="filter-item"
+            v-model="formFilter.projectIdFilter"
+            placeholder=""
+            :required="false"
+            :disabled="false"
+            :props="{
+              label: 'projectTitle',
+              value: 'id'
+            }"
+          />
+        </el-form-item>
+        <el-form-item label="是否处理">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.isHandleFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="isHandleFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in isHandleFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="tourProjectGroupPurchaseApply"
+      class="page-table"
+      :data="tourProjectGroupPurchaseApplyWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((tourProjectGroupPurchaseApplyWidgetCurrentPage - 1) * tourProjectGroupPurchaseApplyWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="false"
+      @sort-change="tourProjectGroupPurchaseApplyWidget.onSortChange"
+      @refresh="tourProjectGroupPurchaseApplyWidget.refreshTable()"
+    >
+      <vxe-column title="序号" type="seq" :index="tourProjectGroupPurchaseApplyWidget.getTableIndex" :width="80" />
+      <vxe-column title="项目标题" field="tourismProject.projectTitle" />
+      <vxe-column title="项目状态" field="tourismProject.enableDictMap.name" />
+      <vxe-column title="用户昵称" field="tourUser.showName" />
+      <vxe-column title="用户联系方式" field="tourUser.mobile" />
+      <vxe-column title="申请时间" field="applyTime">
+        <template v-slot="scope">
+          <span>{{formatDateByStatsType(scope.row.applyTime, 'day')}}</span>
+        </template>
+      </vxe-column>
+      <vxe-column title="是否处理" field="isHandleDictMap.name" />
+      <vxe-column title="备注" field="remark" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseApply:formTourProjectGroupPurchaseApply:edit')"
+          >
+            编辑状态
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="tourProjectGroupPurchaseApplyWidgetTotalCount"
+            :current-page="tourProjectGroupPurchaseApplyWidgetCurrentPage"
+            :page-size="tourProjectGroupPurchaseApplyWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="tourProjectGroupPurchaseApplyWidget.onCurrentPageChange"
+            @size-change="tourProjectGroupPurchaseApplyWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourProjectGroupPurchaseApply',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseApplyData } from '@/api/generated/tourProjectGroupPurchaseApplyController';
+import { TourUserData } from '@/api/generated/tourUserController';
+import { TourismProjectController, TourProjectGroupPurchaseApplyController, TourUserController } from '@/api/generated';
+import EditTourProjectGroupPurchaseState from '@/pages/tourProjectGroupPurchaseApply/editTourProjectGroupPurchaseState.vue';
+import SelectBookTourismProject from '@/pages/tourTourismBookInfo/selectBookTourismProject/index.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 选择旅游项目
+  projectIdFilter: undefined,
+  // 是否处理
+  isHandleFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // 选择旅游项目
+  projectIdFilter: undefined,
+  // 是否处理
+  isHandleFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourProjectGroupPurchaseApply();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadTourProjectGroupPurchaseApplyWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourProjectGroupPurchaseApplyDtoFilter: {
+      projectId: formFilter.projectIdFilter,
+      isHandle: formFilter.isHandleFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourProjectGroupPurchaseApplyController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadTourProjectGroupPurchaseApplyVerify = () => {
+  formFilterCopy.projectIdFilter = formFilter.projectIdFilter;
+  formFilterCopy.isHandleFilter = formFilter.isHandleFilter;
+  return true;
+};
+/**
+ * 编辑状态
+ */
+const onEditClick = (row?: TourProjectGroupPurchaseApplyData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑状态', EditTourProjectGroupPurchaseState, { area: ['900px', '700px'] }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseApplyWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+// 表格组件表格组件参数
+const tourProjectGroupPurchaseApplyOptions: TableOptions<TourProjectGroupPurchaseApplyData> = {
+  loadTableData: loadTourProjectGroupPurchaseApplyWidgetData,
+  verifyTableParameter: loadTourProjectGroupPurchaseApplyVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const tourProjectGroupPurchaseApply = ref();
+const tourProjectGroupPurchaseApplyWidget = useTable(tourProjectGroupPurchaseApplyOptions);
+const {
+  dataList: tourProjectGroupPurchaseApplyWidgetDataList,
+  currentPage: tourProjectGroupPurchaseApplyWidgetCurrentPage,
+  pageSize: tourProjectGroupPurchaseApplyWidgetPageSize,
+  totalCount: tourProjectGroupPurchaseApplyWidgetTotalCount,
+} = tourProjectGroupPurchaseApplyWidget;
+/**
+ * 是否处理下拉数据获取函数
+ */
+const loadIsHandleFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return new Promise((resolve, reject) => {
+    DictionaryController.dictGlobalDict({ dictCode: 'IsHandle', itemIdType: 'Integer' }).then(res => {
+      resolve({
+        dataList: res.getList(),
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+// 是否处理配置参数
+const isHandleFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadIsHandleFilterDropdownList,
+  isTree: false,
+};
+// 是否处理下拉组件
+const isHandleFilterWidget = useDropdown(isHandleFilterOptions);
+const { dropdownList: isHandleFilterWidgetDropdownList } = isHandleFilterWidget
+const refreshFormTourProjectGroupPurchaseApply = () => {
+  // 刷新段落
+  tourProjectGroupPurchaseApplyWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourProjectGroupPurchaseApply = () => {
+  formFilter.projectIdFilter = undefined;
+  formFilterCopy.projectIdFilter = undefined;
+  formFilter.isHandleFilter = undefined;
+  formFilterCopy.isHandleFilter = undefined;
+  refreshFormTourProjectGroupPurchaseApply();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourProjectGroupPurchaseApply();
+};
+const formInit = () => {
+  isHandleFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourProjectGroupPurchaseApply();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 511 - 0
src/pages/tourProjectGroupPurchaseBanner/editTourProjectGroupPurchaseBanner.vue

@@ -0,0 +1,511 @@
+<template>
+  <div class="dialog-box" style="position: relative">
+    <el-scrollbar class="custom-scroll content-box">
+      <el-form
+        ref="editTourProjectGroupPurchaseBannerRef"
+        :model="formData"
+        :size="layoutStore.defaultFormItemSize"
+        :rules="rules"
+        label-width="120px"
+        label-position="right"
+        @submit.prevent
+      >
+        <el-row :gutter="16">
+          <el-col :span="12">
+            <el-form-item label="banner名称" prop="TourProjectGroupPurchaseBanner.bannerName">
+              <el-input
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseBanner.bannerName"
+                type="text"
+                placeholder=""
+                :clearable="true"
+                :show-word-limit="false"
+                maxlength="255"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="选择旅游项目" prop="TourProjectGroupPurchaseBanner.projectId">
+              <SelectBookTourismProject
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseBanner.projectId"
+                placeholder=""
+                :required="true"
+                :disabled="false"
+                :props="{
+                  label: 'projectTitle',
+                  value: 'id'
+                }"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="是否启用" prop="TourProjectGroupPurchaseBanner.enable">
+              <el-select
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseBanner.enable"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="enableWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in enableWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="图片URL" prop="TourProjectGroupPurchaseBanner.imgUrl">
+              <custom-upload
+                v-model="imgUrlWidgetFileList"
+                name="uploadFile"
+                :size="layoutStore.defaultFormItemSize"
+                type="expand"
+                :headers="getUploadHeaders"
+                :action="getUploadActionUrl('/admin/app/tourProjectGroupPurchaseBanner/upload')"
+                :data="{fieldName: 'imgUrl', asImage: true}"
+                :limit="imgUrlWidgetMaxCount"
+                @change="onImgUrlChange"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="banner排序" prop="TourProjectGroupPurchaseBanner.showOrder">
+              <el-input-number
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseBanner.showOrder"
+                placeholder=""
+                :clearable="true"
+                :min="0"
+                :step="1"
+                :controls="true"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="类型" prop="TourProjectGroupPurchaseBanner.type">
+              <el-select
+                class="input-item"
+                v-model="formData.TourProjectGroupPurchaseBanner.type"
+                placeholder=""
+                :clearable="true"
+                :filterable="true"
+                @visible-change="typeWidget.onVisibleChange"
+              >
+                <el-option
+                  v-for="item in typeWidgetDropdownList"
+                  :key="item.id"
+                  :label="item.name"
+                  :value="item.id"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+    </el-scrollbar>
+    <el-row class="footer-box" type="flex" justify="end" align="middle">
+      <el-button :size="layoutStore.defaultFormItemSize" @click="onCancel()">取消</el-button>
+      <el-button :size="layoutStore.defaultFormItemSize" type="primary" @click="onSaveClick()">保存</el-button>
+    </el-row>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'editTourProjectGroupPurchaseBanner',
+};
+</script>
+
+<script setup lang="ts">
+import { DialogProp } from '@/components/Dialog/types';
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseBannerData } from '@/api/generated/tourProjectGroupPurchaseBannerController';
+import { TourismProjectController, TourProjectGroupPurchaseBannerController } from '@/api/generated';
+import SelectBookTourismProject from '@/pages/tourTourismBookInfo/selectBookTourismProject/index.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+    id?: ANY_OBJECT;
+    saveOnSubmit?: boolean;
+    rowData?: ANY_OBJECT;
+    // 当使用Dialog.show弹出组件时,须定义该prop属性,以便对dialog进行回调
+    dialog?: DialogProp<ANY_OBJECT[]>;
+  }>(),
+  {
+    subPage: 0,
+    id: undefined,
+    saveOnSubmit: true,
+    rowData: undefined,
+    dialog: undefined,
+  },
+);
+
+const editTourProjectGroupPurchaseBannerRef = ref();
+// 表单数据定义
+type EditTourProjectGroupPurchaseBannerData = {
+  TourProjectGroupPurchaseBanner: TourProjectGroupPurchaseBannerData;
+};
+// 表单数据
+const formData = reactive<EditTourProjectGroupPurchaseBannerData>({
+  TourProjectGroupPurchaseBanner: {
+    // 主键
+    id: undefined,
+    // banner名称
+    bannerName: undefined,
+    // 是否启用,0否,1是
+    enable: undefined,
+    // 图片URL
+    imgUrl: undefined,
+    // 旅游项目id
+    projectId: undefined,
+    // banner排序
+    showOrder: undefined,
+    // 类型(0.PC;1.H5)
+    type: undefined,
+    // 删除标记(1: 正常 -1: 已删除)
+    dataState: undefined,
+    // 创建人
+    createUserId: undefined,
+    // 创建时间
+    createTime: undefined,
+    // 修改人
+    updateUserId: undefined,
+    // 修改时间
+    updateTime: undefined,
+    tourismProject: {
+      // 主键id
+      id: undefined,
+      // 项目标题
+      projectTitle: undefined,
+      // 项目简述
+      remarks: undefined,
+      // 是否热点
+      isHotspot: undefined,
+      // 标签
+      projectLabel: undefined,
+      // 显示顺序
+      showOrder: undefined,
+      // 是否启用
+      enable: undefined,
+      // 所属分类
+      belongTab: undefined,
+      // 出发地
+      startPlace: undefined,
+      // 目的地
+      endPlace: undefined,
+      // 总天数
+      countTimes: undefined,
+      // 项目价格
+      price: undefined,
+      // 项目展示图片
+      tourismUrl: undefined,
+      // 创建用户
+      createUserId: undefined,
+      // 创建时间
+      createTime: undefined,
+      // 更新用户
+      updateUserId: undefined,
+      // 更新时间
+      updateTime: undefined,
+      // 删除标记(1: 正常 -1: 已删除)
+      dataState: undefined,
+      // 价格单位
+      priceUnit: undefined,
+      // 服务保障
+      serviceEnsure: undefined,
+      // 联系电话
+      contactNumber: undefined,
+      // 产品卖点
+      sellingPoint: undefined,
+      // 短标题
+      shortTitle: undefined,
+      // 短描述
+      shortDescription: undefined,
+      // 首页热门图片
+      homeHotPicture: undefined,
+      // 联系人描述
+      contactDescription: undefined,
+      // 游记banner
+      travelNotesBanner: undefined,
+      // 点赞量
+      likeCount: undefined,
+      // 浏览量
+      pageViewCount: undefined,
+      // 人物关系
+      role: undefined,
+      // 出发时间
+      departureTime: undefined,
+      // 人均费用
+      averageCost: undefined,
+      // 推荐指数
+      recommendationRate: undefined,
+      // 上传的联系二维码
+      contactCode: undefined,
+    },
+  },
+},
+);
+// 表单验证规则
+const rules = reactive({
+  'TourProjectGroupPurchaseBanner.bannerName': [
+    {required: true, message: '请输入banner名称', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseBanner.enable': [
+    {required: true, message: '请输入是否启用', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseBanner.imgUrl': [
+    {required: true, message: '请输入图片URL', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseBanner.projectId': [
+    {required: true, message: '请输入选择旅游项目', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseBanner.showOrder': [
+    {required: true, message: '请输入banner排序', trigger: 'blur'}
+  ],
+  'TourProjectGroupPurchaseBanner.type': [
+    {required: true, message: '请输入类型', trigger: 'blur'}
+  ],
+});
+
+const onCancel = () => {
+  if (props.dialog) {
+    props.dialog.cancel();
+  }
+};
+
+const isEdit = computed(() => {
+  return props.saveOnSubmit ? props.id != null : props.rowData != null;
+});
+
+// 初始化页面数据
+const loadTourProjectGroupPurchaseBannerData = () => {
+  return new Promise<void>((resolve, reject) => {
+    if (!isEdit.value) {
+      resolve();
+      return;
+    }
+    if (!props.saveOnSubmit && props.rowData != null) {
+      formData.TourProjectGroupPurchaseBanner = JSON.parse(JSON.stringify(props.rowData));
+      resolve();
+      return;
+    }
+    let params: ANY_OBJECT = {
+      id: props.id
+    };
+    TourProjectGroupPurchaseBannerController.view(params).then(res => {
+      formData.TourProjectGroupPurchaseBanner = { ...res.data };
+      if (formData.TourProjectGroupPurchaseBanner.tourismProject == null) {
+        formData.TourProjectGroupPurchaseBanner.tourismProject = {
+          id: undefined,
+          projectTitle: undefined,
+          remarks: undefined,
+          isHotspot: undefined,
+          projectLabel: undefined,
+          showOrder: undefined,
+          enable: undefined,
+          belongTab: undefined,
+          startPlace: undefined,
+          endPlace: undefined,
+          countTimes: undefined,
+          price: undefined,
+          tourismUrl: undefined,
+          createUserId: undefined,
+          createTime: undefined,
+          updateUserId: undefined,
+          updateTime: undefined,
+          dataState: undefined,
+          priceUnit: undefined,
+          serviceEnsure: undefined,
+          contactNumber: undefined,
+          sellingPoint: undefined,
+          shortTitle: undefined,
+          shortDescription: undefined,
+          homeHotPicture: undefined,
+          contactDescription: undefined,
+          travelNotesBanner: undefined,
+          likeCount: undefined,
+          pageViewCount: undefined,
+          role: undefined,
+          departureTime: undefined,
+          averageCost: undefined,
+          recommendationRate: undefined,
+          contactCode: undefined
+        };
+      }
+      resolve();
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 是否启用下拉数据获取函数
+ */
+const loadEnableDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 是否启用配置参数
+const enableOptions: DropdownOptions<DictData> = {
+  loadData: loadEnableDropdownList,
+  isTree: false,
+};
+// 是否启用下拉组件
+const enableWidget = useDropdown(enableOptions);
+const { dropdownList: enableWidgetDropdownList } = enableWidget
+/**
+ * 图片URL上传文件改变
+ */
+const onImgUrlChange = val => {
+  formData.TourProjectGroupPurchaseBanner.imgUrl = fileListToJson(val);
+};
+// 图片URL上传文件组件
+const imgUrlWidget = useUploadWidget(1);
+const { fileList: imgUrlWidgetFileList, maxCount: imgUrlWidgetMaxCount } = imgUrlWidget;
+/**
+ * 类型下拉数据获取函数
+ */
+const loadTypeDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.BannerType.getList(),
+  });
+};
+// 类型配置参数
+const typeOptions: DropdownOptions<DictData> = {
+  loadData: loadTypeDropdownList,
+  isTree: false,
+};
+// 类型下拉组件
+const typeWidget = useDropdown(typeOptions);
+const { dropdownList: typeWidgetDropdownList } = typeWidget
+const onUploadError = () => {
+  ElMessage.error('文件上传失败');
+};
+const onUploadLimit = () => {
+  ElMessage.error('已经超出最大上传个数限制');
+};
+const refreshEditTourProjectGroupPurchaseBanner = () => {
+  // 刷新段落
+};
+/**
+ * 重置过滤值
+ */
+const resetEditTourProjectGroupPurchaseBanner = () => {
+  refreshEditTourProjectGroupPurchaseBanner();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetEditTourProjectGroupPurchaseBanner();
+};
+/**
+ * 保存
+ */
+const onSaveClick = () => {
+  editTourProjectGroupPurchaseBannerRef.value.validate((valid) => {
+    if (!valid) return;
+    // 级联操作
+    if (!props.saveOnSubmit) {
+      let retFormData = {
+        ...formData.TourProjectGroupPurchaseBanner
+      };
+    retFormData.enableDictMap = findItemFromList(enableWidgetDropdownList.value, retFormData.enable, 'id');
+    retFormData.typeDictMap = findItemFromList(typeWidgetDropdownList.value, retFormData.type, 'id');
+  props.dialog?.submit(retFormData);
+      return;
+    }
+    let params: ANY_OBJECT = {
+      tourProjectGroupPurchaseBannerDto: {
+        id: formData.TourProjectGroupPurchaseBanner.id,
+        bannerName: formData.TourProjectGroupPurchaseBanner.bannerName,
+        enable: formData.TourProjectGroupPurchaseBanner.enable,
+        imgUrl: formData.TourProjectGroupPurchaseBanner.imgUrl,
+        projectId: formData.TourProjectGroupPurchaseBanner.projectId,
+        showOrder: formData.TourProjectGroupPurchaseBanner.showOrder,
+        type: formData.TourProjectGroupPurchaseBanner.type,
+        createUserId: formData.TourProjectGroupPurchaseBanner.createUserId,
+        createTime: formData.TourProjectGroupPurchaseBanner.createTime,
+        updateUserId: formData.TourProjectGroupPurchaseBanner.updateUserId,
+        updateTime: formData.TourProjectGroupPurchaseBanner.updateTime,
+      }
+    };
+
+    let httpCall = isEdit.value ? TourProjectGroupPurchaseBannerController.update : TourProjectGroupPurchaseBannerController.add;
+    httpCall(params).then(res => {
+      ElMessage.success('保存成功');
+      props.dialog?.submit();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  });
+};
+const formInit = () => {
+  loadTourProjectGroupPurchaseBannerData().then(res => {
+    enableWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    let imgUrlDownloadParams = {
+      id: formData.TourProjectGroupPurchaseBanner.id,
+      fieldName: 'imgUrl',
+      asImage: true
+    };
+    imgUrlWidgetFileList.value = parseUploadData(formData.TourProjectGroupPurchaseBanner.imgUrl, imgUrlDownloadParams);
+    typeWidget.onVisibleChange(true).catch(e => {console.error(e)});
+    if (isEdit.value) refreshEditTourProjectGroupPurchaseBanner();
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+
+onMounted(() => {
+  formInit();
+});
+</script>

+ 433 - 0
src/pages/tourProjectGroupPurchaseBanner/formTourProjectGroupPurchaseBannerInfo.vue

@@ -0,0 +1,433 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourProjectGroupPurchaseBannerInfoRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourProjectGroupPurchaseBannerInfo()" @reset="resetFormTourProjectGroupPurchaseBannerInfo">
+        <el-form-item label="banner名称">
+          <el-input
+            class="filter-item"
+            v-model="formFilter.bannerNameFilter"
+            type="text"
+            placeholder=""
+            :clearable="true"
+            :show-word-limit="false"
+            maxlength=""
+          />
+        </el-form-item>
+        <el-form-item label="是否启用">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.enableFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="enableFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in enableFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="banner类型">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.typeFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="typeFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in typeFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="选择旅游项目">
+          <SelectBookTourismProject
+            class="filter-item"
+            v-model="formFilter.projectIdFilter"
+            placeholder=""
+            :required="false"
+            :disabled="false"
+            :props="{
+              label: 'projectTitle',
+              value: 'id'
+            }"
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="tourProjectGroupPurchaseBanner"
+      class="page-table"
+      :data="tourProjectGroupPurchaseBannerWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((tourProjectGroupPurchaseBannerWidgetCurrentPage - 1) * tourProjectGroupPurchaseBannerWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="true"
+      @sort-change="tourProjectGroupPurchaseBannerWidget.onSortChange"
+      @refresh="tourProjectGroupPurchaseBannerWidget.refreshTable()"
+    >
+      <template #operator>
+        <el-button
+          type="primary"
+          :size="layoutStore.defaultFormItemSize"
+          :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseBannerInfo:formTourProjectGroupPurchaseBannerInfo:add')"
+          @click="onAddClick()"
+          >
+          新增
+        </el-button>
+      </template>
+      <vxe-column title="序号" type="seq" :index="tourProjectGroupPurchaseBannerWidget.getTableIndex" :width="80" />
+      <vxe-column title="banner名称" field="bannerName" />
+      <vxe-column title="旅游项目标题" field="tourismProject.projectTitle" />
+      <vxe-column title="是否启用" field="enableDictMap.name" />
+      <vxe-column title="图片URL">
+        <template v-slot="scope">
+          <upload-file-list
+            :file-list="
+              parseUploadData(scope.row.imgUrl, {
+                id: scope.row.id,
+                fieldName: 'imgUrl',
+                asImage: true
+              })
+            "
+            type="card"
+            direction="horizontal"
+            :readonly="true"
+          />
+        </template>
+      </vxe-column>
+      <vxe-column title="banner排序" field="showOrder" />
+      <vxe-column title="banner类型" field="typeDictMap.name" />
+      <vxe-column title="操作" fixed="right">
+        <template v-slot="scope">
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onEditClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseBannerInfo:formTourProjectGroupPurchaseBannerInfo:edit')"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="primary"
+            :size="layoutStore.defaultFormItemSize"
+            @click.stop="onDeleteClick(scope.row)"
+            :disabled="!checkPermCodeExist('formTourProjectGroupPurchaseBannerInfo:formTourProjectGroupPurchaseBannerInfo:delete')"
+          >
+            删除
+          </el-button>
+        </template>
+      </vxe-column>
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="tourProjectGroupPurchaseBannerWidgetTotalCount"
+            :current-page="tourProjectGroupPurchaseBannerWidgetCurrentPage"
+            :page-size="tourProjectGroupPurchaseBannerWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="tourProjectGroupPurchaseBannerWidget.onCurrentPageChange"
+            @size-change="tourProjectGroupPurchaseBannerWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourProjectGroupPurchaseBannerInfo',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourismProjectData } from '@/api/generated/tourismProjectController';
+import { TourProjectGroupPurchaseBannerData } from '@/api/generated/tourProjectGroupPurchaseBannerController';
+import { TourismProjectController, TourProjectGroupPurchaseBannerController } from '@/api/generated';
+import EditTourProjectGroupPurchaseBanner from '@/pages/tourProjectGroupPurchaseBanner/editTourProjectGroupPurchaseBanner.vue';
+import SelectBookTourismProject from '@/pages/tourTourismBookInfo/selectBookTourismProject/index.vue';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // banner名称
+  bannerNameFilter: undefined,
+  // 是否启用
+  enableFilter: undefined,
+  // banner类型
+  typeFilter: undefined,
+  // 旅游项目id
+  projectIdFilter: undefined,
+});
+const formFilterCopy = reactive({
+  // banner名称
+  bannerNameFilter: undefined,
+  // 是否启用
+  enableFilter: undefined,
+  // banner类型
+  typeFilter: undefined,
+  // 旅游项目id
+  projectIdFilter: undefined,
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourProjectGroupPurchaseBannerInfo();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadTourProjectGroupPurchaseBannerWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourProjectGroupPurchaseBannerDtoFilter: {
+      bannerName: formFilter.bannerNameFilter,
+      enable: formFilter.enableFilter,
+      type: formFilter.typeFilter,
+      projectId: formFilter.projectIdFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourProjectGroupPurchaseBannerController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadTourProjectGroupPurchaseBannerVerify = () => {
+  formFilterCopy.bannerNameFilter = formFilter.bannerNameFilter;
+  formFilterCopy.enableFilter = formFilter.enableFilter;
+  formFilterCopy.typeFilter = formFilter.typeFilter;
+  formFilterCopy.projectIdFilter = formFilter.projectIdFilter;
+  return true;
+};
+/**
+ * 新增
+ */
+const onAddClick = (row?: TourProjectGroupPurchaseBannerData) => {
+  let params: ANY_OBJECT = {
+  };
+
+  Dialog
+    .show('新增', EditTourProjectGroupPurchaseBanner, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseBannerWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 编辑
+ */
+const onEditClick = (row?: TourProjectGroupPurchaseBannerData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  Dialog
+    .show('编辑', EditTourProjectGroupPurchaseBanner, { area: '900px' }, { ...params, subPage: true })
+    .then(res => {
+      tourProjectGroupPurchaseBannerWidget.refreshTable();
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+};
+/**
+ * 删除
+ */
+const onDeleteClick = (row?: TourProjectGroupPurchaseBannerData) => {
+  let params: ANY_OBJECT = {
+    id: row?.id,
+  };
+
+  ElMessageBox.confirm('是否删除该条数据?').then(res => {
+    TourProjectGroupPurchaseBannerController.delete(params).then(res => {
+      ElMessage.success('删除成功');
+      tourProjectGroupPurchaseBannerWidget.refreshTable(false, 1);
+    }).catch(e => {
+      // TODO: 异常处理
+      console.error(e);
+    });
+  }).catch(e => {
+    // TODO: 异常处理
+    console.error(e);
+  });
+};
+// 表格组件表格组件参数
+const tourProjectGroupPurchaseBannerOptions: TableOptions<TourProjectGroupPurchaseBannerData> = {
+  loadTableData: loadTourProjectGroupPurchaseBannerWidgetData,
+  verifyTableParameter: loadTourProjectGroupPurchaseBannerVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const tourProjectGroupPurchaseBanner = ref();
+const tourProjectGroupPurchaseBannerWidget = useTable(tourProjectGroupPurchaseBannerOptions);
+const {
+  dataList: tourProjectGroupPurchaseBannerWidgetDataList,
+  currentPage: tourProjectGroupPurchaseBannerWidgetCurrentPage,
+  pageSize: tourProjectGroupPurchaseBannerWidgetPageSize,
+  totalCount: tourProjectGroupPurchaseBannerWidgetTotalCount,
+} = tourProjectGroupPurchaseBannerWidget;
+/**
+ * 是否启用下拉数据获取函数
+ */
+const loadEnableFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.Enable.getList(),
+  });
+};
+// 是否启用配置参数
+const enableFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadEnableFilterDropdownList,
+  isTree: false,
+};
+// 是否启用下拉组件
+const enableFilterWidget = useDropdown(enableFilterOptions);
+const { dropdownList: enableFilterWidgetDropdownList } = enableFilterWidget
+/**
+ * banner类型下拉数据获取函数
+ */
+const loadTypeFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.BannerType.getList(),
+  });
+};
+// banner类型配置参数
+const typeFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadTypeFilterDropdownList,
+  isTree: false,
+};
+// banner类型下拉组件
+const typeFilterWidget = useDropdown(typeFilterOptions);
+const { dropdownList: typeFilterWidgetDropdownList } = typeFilterWidget
+const refreshFormTourProjectGroupPurchaseBannerInfo = () => {
+  // 刷新段落
+  tourProjectGroupPurchaseBannerWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourProjectGroupPurchaseBannerInfo = () => {
+  formFilter.bannerNameFilter = undefined;
+  formFilterCopy.bannerNameFilter = undefined;
+  formFilter.enableFilter = undefined;
+  formFilterCopy.enableFilter = undefined;
+  formFilter.typeFilter = undefined;
+  formFilterCopy.typeFilter = undefined;
+  formFilter.projectIdFilter = undefined;
+  formFilterCopy.projectIdFilter = undefined;
+  refreshFormTourProjectGroupPurchaseBannerInfo();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourProjectGroupPurchaseBannerInfo();
+};
+const formInit = () => {
+  enableFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  typeFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourProjectGroupPurchaseBannerInfo();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 270 - 0
src/pages/tourProjectGroupPurchaseRebate/formTourProjectGroupPurchaseRebate.vue

@@ -0,0 +1,270 @@
+<template>
+  <div class="page-box" style="position: relative;">
+    <el-form
+      ref="formTourProjectGroupPurchaseRebateRef"
+      :size="layoutStore.defaultFormItemSize"
+      label-width="120px"
+      label-position="right"
+      @submit.prevent
+    >
+      <filter-box :item-width="350" @search="refreshFormTourProjectGroupPurchaseRebate()" @reset="resetFormTourProjectGroupPurchaseRebate">
+        <el-form-item label="返利变化的原因">
+          <el-select
+            class="filter-item"
+            v-model="formFilter.reasonFilter"
+            placeholder=""
+            :clearable="true"
+            :filterable="true"
+            @visible-change="reasonFilterWidget.onVisibleChange"
+          >
+            <el-option
+              v-for="item in reasonFilterWidgetDropdownList"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="返利的金额">
+          <input-number-range
+            class="filter-item"
+            v-model="formFilter.priceFilter"
+            startPlaceholder=""
+            endPlaceholder=""
+            :step="1"
+          />
+        </el-form-item>
+      </filter-box>
+    </el-form>
+    <table-box
+      ref="tourProjectGroupPurchaseRebate"
+      class="page-table"
+      :data="tourProjectGroupPurchaseRebateWidgetDataList"
+      :size="layoutStore.defaultFormItemSize"
+      :row-config="{isCurrent: false, isHover: true}"
+      :seq-config="{startIndex: ((tourProjectGroupPurchaseRebateWidgetCurrentPage - 1) * tourProjectGroupPurchaseRebateWidgetPageSize)}"
+      :sort-config="{remote: true}"
+      :hasExtend="false"
+      @sort-change="tourProjectGroupPurchaseRebateWidget.onSortChange"
+      @refresh="tourProjectGroupPurchaseRebateWidget.refreshTable()"
+    >
+      <vxe-column title="序号" type="seq" :index="tourProjectGroupPurchaseRebateWidget.getTableIndex" :width="80" />
+      <vxe-column title="用户昵称" field="tourUser.showName" />
+      <vxe-column title="拼团的标题" field="tourProjectGroupPurchase.title" />
+      <vxe-column title="拼团的状态" field="tourProjectGroupPurchase.stateDictMap.name" />
+      <vxe-column title="拼团是否成功" field="tourProjectGroupPurchase.successDictMap.name" />
+      <vxe-column title="返利的金额(+为增加;-为减少)" field="price" />
+      <vxe-column title="返利金额的单位" field="priceUnit" />
+      <vxe-column title="返利变化的原因" field="reasonDictMap.name" />
+      <!-- <vxe-column title="返利变化的关联用户" field="reasonRelationUserid" /> -->
+      <template slot="empty">
+        <div class="table-empty unified-font">
+          <img src="@/assets/img/empty.png">
+          <span>暂无数据</span>
+        </div>
+      </template>
+      <!-- 分页 -->
+      <template #pagination>
+        <el-row type="flex" justify="end" style="margin-top: 10px;">
+          <el-pagination
+            :total="tourProjectGroupPurchaseRebateWidgetTotalCount"
+            :current-page="tourProjectGroupPurchaseRebateWidgetCurrentPage"
+            :page-size="tourProjectGroupPurchaseRebateWidgetPageSize"
+            :page-sizes="[10, 20, 50, 100]"
+            layout="total, prev, pager, next, sizes"
+            @current-change="tourProjectGroupPurchaseRebateWidget.onCurrentPageChange"
+            @size-change="tourProjectGroupPurchaseRebateWidget.onPageSizeChange">
+          </el-pagination>
+        </el-row>
+      </template>
+    </table-box>
+    <label v-if="subPage" class="page-close-box" @click="onCancel()">
+      <img src="@/assets/img/back2.png" alt="">
+    </label>
+  </div>
+</template>
+
+<script lang="ts">
+export default {
+  name: 'formTourProjectGroupPurchaseRebate',
+};
+</script>
+
+<script setup lang="ts">
+import { VxeColumn, VxeTable } from 'vxe-table';
+import { ANY_OBJECT } from '@/types/generic';
+import { DictData, DictionaryBase } from '@/common/staticDict/types';
+import { ElMessage, ElMessageBox, UploadFile } from 'element-plus';
+import { useRoute, useRouter } from 'vue-router';
+import { useCommon } from '@/common/hooks/useCommon';
+import { useLayoutStore, useStaticDictStore } from '@/store';
+import { useDownload } from '@/common/hooks/useDownload';
+import { useDropdown } from '@/common/hooks/useDropdown';
+import { DropdownOptions, ListData } from '@/common/types/list';
+import { useTable } from '@/common/hooks/useTable';
+import { TableOptions } from '@/common/types/pagination';
+import { useUpload } from '@/common/hooks/useUpload';
+import { useUploadWidget } from '@/common/hooks/useUploadWidget';
+import { DictionaryController } from '@/api/system';
+import { treeDataTranslate, findItemFromList, findTreeNodePath, findTreeNode, stringCase } from '@/common/utils';
+import { TourProjectGroupPurchaseData } from '@/api/generated/tourProjectGroupPurchaseController';
+import { TourOrderData } from '@/api/generated/tourOrderController';
+import { TourProjectGroupPurchaseRebateData } from '@/api/generated/tourProjectGroupPurchaseRebateController';
+import { TourUserData } from '@/api/generated/tourUserController';
+import { TourProjectGroupPurchaseController, TourOrderController, TourProjectGroupPurchaseRebateController, TourUserController } from '@/api/generated';
+
+const router = useRouter();
+const route = useRoute();
+const layoutStore = useLayoutStore();
+const { downloadFile } = useDownload();
+const { getUploadHeaders, getUploadActionUrl, fileListToJson, parseUploadData, getPictureList } = useUpload();
+const { 
+  Delete,
+  Search,
+  Edit,
+  Plus,
+  Refresh,
+  Picture,
+  Dialog,
+  mainContextHeight,
+  clientHeight,
+  checkPermCodeExist,
+  parseParams,
+  parseArrayParams,
+  formatDateByStatsType,
+  getDateRangeFilter,
+} = useCommon();
+// 静态字典
+const { staticDict: StaticDict } = useStaticDictStore();
+
+const props = withDefaults(
+  defineProps<{
+    subPage?: number | string | boolean;
+  }>(),
+  {
+    subPage: 0,
+  },
+);
+
+const formFilter = reactive({
+  // 返利变化的原因
+  reasonFilter: undefined,
+  // 返利的金额
+  priceFilter: [],
+});
+const formFilterCopy = reactive({
+  // 返利变化的原因
+  reasonFilter: undefined,
+  // 返利的金额
+  priceFilter: [],
+});
+
+const onCancel = () => {
+  router.go(-1);
+  layoutStore.removeCachePage(route.fullPath as string);
+  route.meta.refreshParentCachedPage = true;
+};
+
+const onResume = () => {
+  refreshFormTourProjectGroupPurchaseRebate();
+};
+
+/**
+ * 表格组件数据获取函数,返回Promise
+ */
+const loadTourProjectGroupPurchaseRebateWidgetData = (params: ANY_OBJECT) => {
+  if (params == null) params = {};
+  params = {
+    ...params,
+    tourProjectGroupPurchaseRebateDtoFilter: {
+      priceStart: Array.isArray(formFilter.priceFilter) ? formFilter.priceFilter[0] : formFilter.priceFilter,
+      priceEnd: Array.isArray(formFilter.priceFilter) ? formFilter.priceFilter[1] : formFilter.priceFilter,
+      reason: formFilter.reasonFilter,
+    }
+  };
+  return new Promise((resolve, reject) => {
+    TourProjectGroupPurchaseRebateController.list(params).then(res => {
+      resolve({
+        dataList: res.data.dataList,
+        totalCount: res.data.totalCount
+      });
+    }).catch(e => {
+      reject(e);
+    });
+  });
+};
+/**
+ * 表格组件数据获取检测函数,返回true正常获取数据,返回false停止获取数据
+ */
+const loadTourProjectGroupPurchaseRebateVerify = () => {
+  formFilterCopy.reasonFilter = formFilter.reasonFilter;
+  formFilterCopy.priceFilter = formFilter.priceFilter;
+  return true;
+};
+// 表格组件表格组件参数
+const tourProjectGroupPurchaseRebateOptions: TableOptions<TourProjectGroupPurchaseRebateData> = {
+  loadTableData: loadTourProjectGroupPurchaseRebateWidgetData,
+  verifyTableParameter: loadTourProjectGroupPurchaseRebateVerify,
+  paged: true,
+  rowSelection: false,
+  orderFieldName: undefined,
+  ascending: true,
+};
+// 表格组件表格组件
+const tourProjectGroupPurchaseRebate = ref();
+const tourProjectGroupPurchaseRebateWidget = useTable(tourProjectGroupPurchaseRebateOptions);
+const {
+  dataList: tourProjectGroupPurchaseRebateWidgetDataList,
+  currentPage: tourProjectGroupPurchaseRebateWidgetCurrentPage,
+  pageSize: tourProjectGroupPurchaseRebateWidgetPageSize,
+  totalCount: tourProjectGroupPurchaseRebateWidgetTotalCount,
+} = tourProjectGroupPurchaseRebateWidget;
+/**
+ * 返利变化的原因下拉数据获取函数
+ */
+const loadReasonFilterDropdownList = (): Promise<ListData<DictData>> => {
+  return Promise.resolve({
+    dataList: StaticDict.GroupPurchaseRebate.getList(),
+  });
+};
+// 返利变化的原因配置参数
+const reasonFilterOptions: DropdownOptions<DictData> = {
+  loadData: loadReasonFilterDropdownList,
+  isTree: false,
+};
+// 返利变化的原因下拉组件
+const reasonFilterWidget = useDropdown(reasonFilterOptions);
+const { dropdownList: reasonFilterWidgetDropdownList } = reasonFilterWidget
+const refreshFormTourProjectGroupPurchaseRebate = () => {
+  // 刷新段落
+  tourProjectGroupPurchaseRebateWidget.refreshTable();
+};
+/**
+ * 重置过滤值
+ */
+const resetFormTourProjectGroupPurchaseRebate = () => {
+  formFilter.reasonFilter = undefined;
+  formFilterCopy.reasonFilter = undefined;
+  formFilter.priceFilter = undefined;
+  formFilterCopy.priceFilter = undefined;
+  refreshFormTourProjectGroupPurchaseRebate();
+};
+/**
+ * 重置所有过滤值
+ */
+const resetFilter = () => {
+  resetFormTourProjectGroupPurchaseRebate();
+};
+const formInit = () => {
+  reasonFilterWidget.onVisibleChange(true).catch(e => {console.error(e)});
+  refreshFormTourProjectGroupPurchaseRebate();
+};
+
+onMounted(() => {
+  formInit();
+});
+
+onActivated(() => {
+  onResume();
+});
+</script>

+ 7 - 0
src/pages/tourTourismBookInfo/selectBookTourismProject/selectBookTourismProject.vue

@@ -92,6 +92,7 @@
       <vxe-column title="所属分类" field="belongTabDictMap.name" />
       <vxe-column title="项目价格" field="price" />
       <vxe-column title="是否热点" field="isHotspotDictMap.name" />
+      <vxe-column title="是否启用" field="enableDictMap.name" />
       <vxe-column title="标签" field="projectLabel" />
       <vxe-column title="总天数" field="countTimes" />
       <vxe-column title="项目图片" min-width="100px">
@@ -269,6 +270,12 @@ const loadTourismProjectWidgetData = (params: ANY_OBJECT) => {
   if (params == null) params = {};
   params = {
     ...params,
+    tourismProjectDtoFilter: {
+      projectTitle: formFilter.projectTitleFilter,
+      belongTab: formFilter.belongTabFilter,
+      isHotspot: formFilter.isHotspotFilter,
+      enable: formFilter.enableFilter
+    }
   };
   return new Promise((resolve, reject) => {
     TourismProjectController.list(params).then(res => {

+ 1 - 1
src/pages/tourismProject/formTourismProject.vue

@@ -623,7 +623,7 @@ const loadBelongTabFilterDropdownList = (): Promise<ListData<DictData>> => {
     const params = {
       directoryType: 1,
     };
-    DictionaryController.dictDirectoryInfoBytype(params)
+    DictionaryController.dictDirectoryInfoByType(params)
       .then(res => {
         resolve({
           dataList: res.getList(),

+ 2 - 2
src/pages/tourismProject/verifyTourismProjectDatePrice.vue

@@ -93,7 +93,7 @@ const gridOptions = reactive<VxeGridProps>({
       field: 'adultPrice',
       width: 150,
       editRender: {},
-      title: '成人价格(元/人)',
+      title: '成人价格',
       slots: {
         edit({ row }) {
           return (
@@ -110,7 +110,7 @@ const gridOptions = reactive<VxeGridProps>({
       field: 'childrenPrice',
       width: 150,
       editRender: {},
-      title: '儿童价格(元/人)',
+      title: '儿童价格',
       slots: {
         edit({ row }) {
           return (

+ 112 - 0
src/router/systemRouters.ts

@@ -600,6 +600,118 @@ export const routers: Array<RouteRecordRaw> = [
         props: getProps,
         meta: {title: '签证基础资料管理管理'}
       },
+      {
+        path: 'formTourProjectGroupPurchaseInfo',
+        component: () => import('@/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseInfo.vue'),
+        name: 'formTourProjectGroupPurchaseInfo',
+        props: getProps,
+        meta: {title: '拼团设置信息', keepalive: true}
+      },
+      {
+        path: 'formTourProjectGroupPurchaseDetail',
+        component: () => import('@/pages/tourProjectGroupPurchase/formTourProjectGroupPurchaseDetail.vue'),
+        name: 'formTourProjectGroupPurchaseDetail',
+        props: getProps,
+        meta: {title: '拼团设置从表管理', keepalive: true}
+      },
+      {
+        path: 'formTourProjectGroupPurchaseApply',
+        component: () => import('@/pages/tourProjectGroupPurchaseApply/formTourProjectGroupPurchaseApply.vue'),
+        name: 'formTourProjectGroupPurchaseApply',
+        props: getProps,
+        meta: {title: '开团申请信息', keepalive: true}
+      },
+      {
+        path: 'formTourProjectGroupPurchaseBannerInfo',
+        component: () => import('@/pages/tourProjectGroupPurchaseBanner/formTourProjectGroupPurchaseBannerInfo.vue'),
+        name: 'formTourProjectGroupPurchaseBannerInfo',
+        props: getProps,
+        meta: {title: '拼团首页banner信息', keepalive: true}
+      },
+      {
+        path: 'formTourProjectGroupPurchaseRebate',
+        component: () => import('@/pages/tourProjectGroupPurchaseRebate/formTourProjectGroupPurchaseRebate.vue'),
+        name: 'formTourProjectGroupPurchaseRebate',
+        props: getProps,
+        meta: {title: '拼团返利记录', keepalive: true}
+      },
+      {
+        path: 'formTourFans',
+        component: () => import('@/pages/tourFans/formTourFans.vue'),
+        name: 'formTourFans',
+        props: getProps,
+        meta: {title: '关注粉丝管理管理', keepalive: true}
+      },
+      // {
+      //   path: 'formTourBrowseRecords',
+      //   component: () => import('@/pages/TourBrowseRecords/formTourBrowseRecords.vue'),
+      //   name: 'formTourBrowseRecords',
+      //   props: getProps,
+      //   meta: {title: '用户浏览记录表管理', keepalive: true}
+      // },
+      {
+        path: 'formTourImComplaintType',
+        component: () => import('@/pages/ImComplaint/formTourImComplaintType.vue'),
+        name: 'formTourImComplaintType',
+        props: getProps,
+        meta: {title: '投诉类型管理管理', keepalive: true}
+      },
+      {
+        path: 'formTourImComplait',
+        component: () => import('@/pages/ImComplaint/formTourImComplait.vue'),
+        name: 'formTourImComplait',
+        props: getProps,
+        meta: {title: '投诉内容管理管理', keepalive: true}
+      },
+      {
+        path: 'formTourImSensitiveWordAllow',
+        component: () => import('@/pages/SensitiveWord/formTourImSensitiveWordAllow.vue'),
+        name: 'formTourImSensitiveWordAllow',
+        props: getProps,
+        meta: {title: '聊天敏感词白名单管理', keepalive: true}
+      },
+      {
+        path: 'formTourImSensitiveWordDeny',
+        component: () => import('@/pages/SensitiveWord/formTourImSensitiveWordDeny.vue'),
+        name: 'formTourImSensitiveWordDeny',
+        props: getProps,
+        meta: {title: '聊天敏感词黑名单管理', keepalive: true}
+      },
+      {
+        path: 'formTourImGroupType',
+        component: () => import('@/pages/ImGroup/formTourImGroupType.vue'),
+        name: 'formTourImGroupType',
+        props: getProps,
+        meta: {title: '聊天群聊类型管理管理', keepalive: true}
+      },
+      {
+        path: 'formTourImGroup',
+        component: () => import('@/pages/ImGroup/formTourImGroup.vue'),
+        name: 'formTourImGroup',
+        props: getProps,
+        meta: {title: '聊天群聊管理管理', keepalive: true}
+      },
+      {
+        path: 'formTourImGroupInvitation',
+        component: () => import('@/pages/ImGroup/formTourImGroupInvitation.vue'),
+        name: 'formTourImGroupInvitation',
+        props: getProps,
+        meta: {title: '聊天去聊邀请管理', keepalive: true}
+      },
+      {
+        path: 'formTourImMember',
+        component: () => import('@/pages/ImGroup/formTourImMember.vue'),
+        name: 'formTourImMember',
+        props: getProps,
+        meta: {title: '聊天群聊成员管理', keepalive: true}
+      },
+      {
+        path: 'formTourImMessage',
+        component: () => import('@/pages/ImGroup/formTourImMessage.vue'),
+        name: 'formTourImMessage',
+        props: getProps,
+        meta: {title: '聊天群聊消息管理', keepalive: true}
+      },
     ],
   },
   // TODO 第三方接入路由

+ 8 - 0
src/types/table/TourOrder.d.ts

@@ -58,6 +58,14 @@ interface TourOrder {
   childrenPrice?: number | undefined;
   // 成人价格
   adultPrice?: number | undefined;
+  // 返利金额
+  rebateSumPrice?: number | undefined;
+  //核销金额
+  rebatePrice?: number | undefined;
+  //团购id
+  groupPurchaseProgressId: number | undefined;
+  //订单的类型(0.普通订单;1.拼团的订单)
+  type: number | undefined;
 }
 
 export default TourOrder;

+ 27 - 0
src/types/table/tourBrowseRecords.d.ts

@@ -0,0 +1,27 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourBrowseRecords {
+  // id
+  id?: number | undefined;
+  // 浏览者id
+  visitorId?: number | undefined;
+  // 原创游记作者id
+  writerId?: number | undefined;
+  // 游记、项目、签证id
+  itemId?: number | undefined;
+  // 浏览项目类型id  1游记 2项目 3签证
+  itemTypeId?: number | undefined;
+  itemTypeIdDictMap?: DictData,
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourBrowseRecords;

+ 23 - 0
src/types/table/tourFans.d.ts

@@ -0,0 +1,23 @@
+import { DictData } from '@/common/staticDict/types';
+import TourUser from "@/types/table/tourUser";
+
+interface TourFans {
+  // 粉丝表id
+  id?: number | undefined;
+  // 被关注人id
+  attentionId?: number | undefined;
+  attentionIdDictMap?: TourUser,
+  // 是否删除
+  deleteFlag?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  createUserIdDictMap?: TourUser,
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+}
+
+export default TourFans;

+ 25 - 0
src/types/table/tourImComplaintType.d.ts

@@ -0,0 +1,25 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImComplaintType {
+  // id
+  id?: number | undefined;
+  // 类型名称
+  typeName?: string | undefined;
+  // 类型描述
+  description?: string | undefined;
+  // 是否启用
+  enable?: number | undefined;
+  enableDictMap?: DictData,
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImComplaintType;

+ 30 - 0
src/types/table/tourImComplait.d.ts

@@ -0,0 +1,30 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImComplait {
+  // id
+  id?: number | undefined;
+  // 举报类型id
+  typeId?: number | undefined;
+  typeIdDictMap?: DictData,
+  // 类型为其他违规的理由
+  elseTypeReason?: string | undefined;
+  // 举报对象 1用户 2群组
+  objectType?: number | undefined;
+  objectTypeDictMap?: DictData,
+  // 举报描述
+  description?: string | undefined;
+  // 举报图片 最多三张
+  image?: string | undefined;
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImComplait;

+ 44 - 0
src/types/table/tourImGroup.d.ts

@@ -0,0 +1,44 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImGroup {
+  // id
+  id?: number | undefined;
+  // 群聊所属类型id
+  belongTypeId?: number | undefined;
+  belongTypeIdDictMap?: DictData,
+  // 群主id
+  leaderId?: number | undefined;
+  leaderIdDictMap?: DictData,
+  // 群聊名称
+  groupName?: string | undefined;
+  // 群聊头像
+  groupAvatar?: string | undefined;
+  // 群聊描述
+  description?: string | undefined;
+  // 是否公开展示 0隐藏 1公开
+  isPublic?: number | undefined;
+  isPublicDictMap?: DictData,
+  // 是否开启群聊邀请确认 0不开启 1开启
+  isNeedConfirm?: number | undefined;
+  isNeedConfirmDictMap?: DictData,
+  // 通知分类 0单聊 1群聊
+  noticeType?: number | undefined;
+  noticeTypeDictMap?: DictData,
+  // 是否封禁 0封禁 1正常
+  bannedStatus?: number | undefined;
+  bannedStatusDictMap?: DictData,
+  // 热度值
+  hotValue?: number | undefined;
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImGroup;

+ 30 - 0
src/types/table/tourImGroupInvitation.d.ts

@@ -0,0 +1,30 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImGroupInvitation {
+  // id
+  id?: number | undefined;
+  // 聊天群组id
+  groupId?: number | undefined;
+  groupIdDictMap?: DictData,
+  // 邀请人id
+  inviter?: number | undefined;
+  inviterDictMap?: DictData,
+  // 被邀请人id
+  invitee?: number | undefined;
+  inviteeDictMap?: DictData,
+  // 邀请状态 1待确认 2同意 3不同意
+  status?: number | undefined;
+  statusDictMap?: DictData,
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImGroupInvitation;

+ 28 - 0
src/types/table/tourImGroupType.d.ts

@@ -0,0 +1,28 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImGroupType {
+  // id
+  id?: number | undefined;
+  // 父级id
+  parentId?: number | undefined;
+  parentIdDictMap?: DictData,
+  // 类型名称
+  typeName?: string | undefined;
+  // 类型图标
+  typeIcon?: string | undefined;
+  // 是否启用 0否 1是
+  enable?: number | undefined;
+  enableDictMap?: DictData,
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImGroupType;

+ 42 - 0
src/types/table/tourImMember.d.ts

@@ -0,0 +1,42 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImMember {
+  // id
+  id?: number | undefined;
+  // 聊天群组id
+  groupId?: number | undefined;
+  groupIdDictMap?: DictData,
+  // 成员角色 1群主 2管理员 3普通成员
+  groupRole?: number | undefined;
+  groupRoleDictMap?: DictData,
+  // 用户id
+  userId?: number | undefined;
+  userIdDictMap?: DictData,
+  // 会话是否显示(每个群在聊天列表要不要展示) 0不显示 1显示
+  isShow?: number | undefined;
+  isShowDictMap?: DictData,
+  // 会话是否置顶 (每个群在聊天列表要不要置顶)  0不置顶 1 置顶
+  isTop?: number | undefined;
+  isTopDictMap?: DictData,
+  // 会话是否开启免打扰 0不开启免打扰 1 开启免打扰
+  isNotDisturb?: number | undefined;
+  isNotDisturbDictMap?: DictData,
+  // 自己在群里的昵称
+  groupNickname?: string | undefined;
+  // 群备注
+  groupRemark?: string | undefined;
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 聊天背景
+  groupBackImage?: string | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImMember;

+ 40 - 0
src/types/table/tourImMessage.d.ts

@@ -0,0 +1,40 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImMessage {
+  // id
+  id?: number | undefined;
+  // 消息内容
+  messageContent?: string | undefined;
+  // 消息类型 0文字 1文件 2系统消息
+  messageType?: number | undefined;
+  messageTypeDictMap?: DictData,
+  // 聊天群组id
+  groupId?: number | undefined;
+  groupIdDictMap?: DictData,
+  // 通知消息类型 1.单聊消息 2 群聊消息 3系统消息 4关注信息 5点赞 6评论 7评论区艾特 8文章内艾特 9访问
+  noticeType?: number | undefined;
+  noticeTypeDictMap?: DictData,
+  // 消息置顶/公告 0不置顶 1置顶
+  isTop?: number | undefined;
+  isTopDictMap?: DictData,
+  // 撤回标记 0不撤回 1撤回
+  revocationTag?: number | undefined;
+  revocationTagDictMap?: DictData,
+  // 已经删除该条消息的用户
+  deletedByUsers?: string | undefined;
+  // 已读该条消息的用户
+  readByUsers?: string | undefined;
+  // 删除标记 1正常 -1删除
+  dataState?: number | undefined;
+  // 创建人id
+  createUserId?: number | undefined;
+  createUserIdDictMap?: DictData,
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 更新人id
+  updateUserId?: number | undefined;
+}
+
+export default TourImMessage;

+ 10 - 0
src/types/table/tourImSensitiveWordAllow.d.ts

@@ -0,0 +1,10 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImSensitiveWordAllow {
+  // id
+  id?: number | undefined;
+  // 白名单词汇
+  word?: string | undefined;
+}
+
+export default TourImSensitiveWordAllow;

+ 10 - 0
src/types/table/tourImSensitiveWordDeny.d.ts

@@ -0,0 +1,10 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourImSensitiveWordDeny {
+  // id
+  id?: number | undefined;
+  // 黑名单词汇
+  word?: string | undefined;
+}
+
+export default TourImSensitiveWordDeny;

+ 53 - 0
src/types/table/tourProjectGroupPurchase.d.ts

@@ -0,0 +1,53 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourProjectGroupPurchase {
+  // 主键id
+  id?: number | undefined;
+  // 项目id
+  projectId?: number | undefined;
+  projectIdDictMap?: DictData,
+  // 拼团结束时间
+  endTime?: string | undefined;
+  // 出行开始时间
+  travelStartTime?: string | undefined;
+  // 出行结束时间
+  travelEndTime?: string | undefined;
+  // 拼团状态(0禁用,1启用)
+  state?: number | undefined;
+  stateDictMap?: DictData,
+  // 创建用户
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新用户
+  updateUserId?: number | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 删除标记(1: 正常 -1: 已删除)
+  dataState?: number | undefined;
+  // 拼团人数上限
+  maxCount?: number | undefined;
+  // 成人价格
+  adultPrice?: number | undefined;
+  // 儿童价格
+  childrenPrice?: number | undefined;
+  // 显示顺序
+  showOrder?: number | undefined;
+  // 关联字段(与从表)
+  code?: number | undefined;
+  // 当前拼团的人数
+  nowCount?: number | undefined;
+  // 拼团是否成功(0.失败;1.成功)
+  success?: number | undefined;
+  successDictMap?: DictData,
+  // 拼团标题
+  title?: string | undefined;
+  // 图片url
+  image?: string | undefined;
+  // 价格单位
+  priceUnit?: string | undefined;
+  // 返利价格/人
+  singleRebate?: number | undefined;
+}
+
+export default TourProjectGroupPurchase;

+ 29 - 0
src/types/table/tourProjectGroupPurchaseApply.d.ts

@@ -0,0 +1,29 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourProjectGroupPurchaseApply {
+  // 主键id
+  id?: number | undefined;
+  // 项目id
+  projectId?: number | undefined;
+  // 用户Id
+  tourUserId?: number | undefined;
+  // 申请时间
+  applyTime?: string | undefined;
+  // 是否处理(0:未处理 1:已处理)
+  isHandle?: number | undefined;
+  isHandleDictMap?: DictData,
+  // 创建用户
+  createUserId?: number | undefined;
+  // 备注
+  remark?: string | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新用户
+  updateUserId?: number | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 删除标记(1: 正常 -1: 已删除)
+  dataState?: number | undefined;
+}
+
+export default TourProjectGroupPurchaseApply;

+ 32 - 0
src/types/table/tourProjectGroupPurchaseBanner.d.ts

@@ -0,0 +1,32 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourProjectGroupPurchaseBanner {
+  // 主键
+  id?: number | undefined;
+  // banner名称
+  bannerName?: string | undefined;
+  // 是否启用,0否,1是
+  enable?: number | undefined;
+  enableDictMap?: DictData,
+  // 图片URL
+  imgUrl?: string | undefined;
+  // 旅游项目id
+  projectId?: number | undefined;
+  // banner排序
+  showOrder?: number | undefined;
+  // 类型(0.PC;1.H5)
+  type?: number | undefined;
+  typeDictMap?: DictData,
+  // 删除标记(1: 正常 -1: 已删除)
+  dataState?: number | undefined;
+  // 创建人
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 修改人
+  updateUserId?: number | undefined;
+  // 修改时间
+  updateTime?: string | undefined;
+}
+
+export default TourProjectGroupPurchaseBanner;

+ 28 - 0
src/types/table/tourProjectGroupPurchaseDetail.d.ts

@@ -0,0 +1,28 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourProjectGroupPurchaseDetail {
+  // 主键id
+  id?: number | undefined;
+  // 关联 拼团设置的id
+  groupPurchaseCode?: number | undefined;
+  // 创建用户
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新用户
+  updateUserId?: number | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 删除标记(1: 正常 -1: 已删除)
+  dataState?: number | undefined;
+  // 成人价格
+  adultPrice?: number | undefined;
+  // 儿童价格
+  childrenPrice?: number | undefined;
+  // 阶梯的人数(下限)
+  minCount?: number | undefined;
+  // 阶梯的人数(上限)
+  maxCount?: number | undefined;
+}
+
+export default TourProjectGroupPurchaseDetail;

+ 33 - 0
src/types/table/tourProjectGroupPurchaseRebate.d.ts

@@ -0,0 +1,33 @@
+import { DictData } from '@/common/staticDict/types';
+
+interface TourProjectGroupPurchaseRebate {
+  // 主键id
+  id?: number | undefined;
+  // 用户id
+  userId?: number | undefined;
+  // 拼团的id
+  groupPurchaseProgressId?: number | undefined;
+  // 订单id
+  orderId?: number | undefined;
+  // 返利的金额(+为增加;-为减少)
+  price?: number | undefined;
+  // 返利变化的原因(0.邀请用户;1.邀请的用户取消;2.清空返利)
+  reason?: number | undefined;
+  reasonDictMap?: DictData,
+  // 返利变化的关联用户
+  reasonRelationUserid?: number | undefined;
+  // 创建用户
+  createUserId?: number | undefined;
+  // 创建时间
+  createTime?: string | undefined;
+  // 更新用户
+  updateUserId?: number | undefined;
+  // 更新时间
+  updateTime?: string | undefined;
+  // 删除标记(1: 正常 -1: 已删除)
+  dataState?: number | undefined;
+  // 返利的金额的单位
+  priceUnit?: string | undefined;
+}
+
+export default TourProjectGroupPurchaseRebate;