From b9e1e0ee5f01334bfa7f2467b86e5ea1b1dc71fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20G=C3=B6bel?= <dgoebel@techfak.uni-bielefeld.de>
Date: Tue, 5 Mar 2024 15:45:21 +0100
Subject: [PATCH] Resolve "Adapt UI to new Resoruce creation flow"

---
 .gitlab-ci.yml                                |    4 +-
 index.html                                    |    6 +-
 package-lock.json                             | 2086 +++++++++--------
 package.json                                  |   32 +-
 src/App.vue                                   |   18 +-
 src/client/auth/services/UserService.ts       |    3 +
 src/client/resource/index.ts                  |    4 +
 src/client/resource/models/FileTree.ts        |   19 +
 src/client/resource/models/ResourceIn.ts      |    4 +
 src/client/resource/models/ResourceOut.ts     |    4 +
 src/client/resource/models/Status.ts          |    5 +-
 .../resource/models/UserRequestAnswer.ts      |   15 +
 .../models/UserSynchronizationRequestIn.ts    |   11 +
 .../models/UserSynchronizationRequestOut.ts   |   23 +
 .../resource/services/ResourceService.ts      |   50 +-
 .../services/ResourceVersionService.ts        |  136 +-
 .../services/BucketPermissionService.ts       |   21 +-
 src/client/s3proxy/services/BucketService.ts  |   12 +-
 src/client/s3proxy/services/S3KeyService.ts   |   12 +-
 src/client/workflow/index.ts                  |    4 +
 .../models/ParameterExtension_Input.ts        |   16 +
 .../models/ParameterExtension_Output.ts       |   16 +
 .../workflow/models/ResourcePath_Input.ts     |   16 +
 .../workflow/models/ResourcePath_Output.ts    |   16 +
 src/client/workflow/models/WorkflowOut.ts     |    2 +-
 src/client/workflow/models/WorkflowVersion.ts |    5 +
 .../services/WorkflowCredentialsService.ts    |    9 +-
 .../services/WorkflowExecutionService.ts      |   21 +-
 .../workflow/services/WorkflowModeService.ts  |    3 +-
 .../workflow/services/WorkflowService.ts      |  249 +-
 .../services/WorkflowVersionService.ts        |   59 +-
 .../{FooterBottom.vue => AppFooter.vue}       |    0
 .../{NavbarTop.vue => AppHeader.vue}          |    9 +-
 src/components/BootstrapToast.vue             |   16 +-
 src/components/CopyToClipboardIcon.vue        |    6 +-
 src/components/modals/BootstrapModal.vue      |    2 +-
 src/components/modals/ReasonModal.vue         |   84 +
 .../ParameterSchemaFormComponent.vue          |    6 +-
 .../resources/RequestReviewButton.vue         |   44 +
 src/components/resources/ResourceCard.vue     |  115 +-
 .../resources/modals/CreateResourceModal.vue  |   25 +
 .../{ => modals}/ResourceVersionInfoModal.vue |    2 +-
 .../modals/UploadResourceInfoModal.vue        |   73 +-
 .../workflows/WorkflowWithVersionsCard.vue    |   71 +-
 src/router/adminRoutes.ts                     |    9 +
 src/router/index.ts                           |    9 +-
 src/stores/resources.ts                       |  107 +-
 src/stores/users.ts                           |   14 +-
 src/views/ImprintView.vue                     |    6 +-
 src/views/PrivacyPolicyView.vue               |    6 +-
 src/views/TermsOfUsageView.vue                |    6 +-
 src/views/admin/AdminResourcesView.vue        |   52 +-
 src/views/admin/AdminSyncRequestsView.vue     |  271 +++
 src/views/resources/ListResourcesView.vue     |   77 +-
 src/views/resources/MyResourcesView.vue       |   44 +
 src/views/resources/ReviewResourceView.vue    |   77 +-
 src/views/workflows/MyWorkflowsView.vue       |    2 +-
 src/views/workflows/ReviewWorkflowsView.vue   |    8 +-
 src/views/workflows/WorkflowView.vue          |    9 +
 tsconfig.config.json                          |   10 +-
 tsconfig.json                                 |   21 +-
 61 files changed, 2477 insertions(+), 1585 deletions(-)
 create mode 100644 src/client/resource/models/FileTree.ts
 create mode 100644 src/client/resource/models/UserRequestAnswer.ts
 create mode 100644 src/client/resource/models/UserSynchronizationRequestIn.ts
 create mode 100644 src/client/resource/models/UserSynchronizationRequestOut.ts
 create mode 100644 src/client/workflow/models/ParameterExtension_Input.ts
 create mode 100644 src/client/workflow/models/ParameterExtension_Output.ts
 create mode 100644 src/client/workflow/models/ResourcePath_Input.ts
 create mode 100644 src/client/workflow/models/ResourcePath_Output.ts
 rename src/components/{FooterBottom.vue => AppFooter.vue} (100%)
 rename src/components/{NavbarTop.vue => AppHeader.vue} (98%)
 create mode 100644 src/components/modals/ReasonModal.vue
 create mode 100644 src/components/resources/RequestReviewButton.vue
 rename src/components/resources/{ => modals}/ResourceVersionInfoModal.vue (99%)
 create mode 100644 src/views/admin/AdminSyncRequestsView.vue

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7f2ea9f..15d4639 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -37,7 +37,7 @@ build:
 publish-main-docker-container-job:
   stage: deploy
   image:
-    name: gcr.io/kaniko-project/executor:v1.20.0-debug
+    name: gcr.io/kaniko-project/executor:v1.21.0-debug
     entrypoint: [""]
   only:
     refs:
@@ -54,7 +54,7 @@ publish-main-docker-container-job:
 publish-docker-container-job:
   stage: deploy
   image:
-    name: gcr.io/kaniko-project/executor:v1.20.0-debug
+    name: gcr.io/kaniko-project/executor:v1.21.0-debug
     entrypoint: [""]
   only:
     - tags
diff --git a/index.html b/index.html
index a951d42..4d31d40 100644
--- a/index.html
+++ b/index.html
@@ -5,11 +5,13 @@
     <link rel="icon" href="/favicon.ico"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
     <title>CloWM</title>
-    <meta name="description" content="The Cloud-based Workflow Manager (CloWM) is a service hosted at Bielefeld University that can transform your Nextflow workflow into a public webservice and provide compute and storage resources for executing your registered workflow"/>
+    <meta name="description"
+          content="The Cloud-based Workflow Manager (CloWM) is a service hosted at Bielefeld University that can transform your Nextflow workflow into a public webservice and provide compute and storage resources for executing your registered workflow"/>
     <script src="/env.js"></script>
 </head>
 <body>
+<div id="global-toast-container" class="toast-container position-fixed end-0 p-3" style="top: 4rem"></div>
 <div id="app" class="d-flex flex-column justify-content-between" style="min-height: 100vh"></div>
 <script type="module" src="/src/main.ts"></script>
 </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c6d6190..be12f6a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,21 +20,21 @@
         "chartjs-plugin-zoom": "~2.0.1",
         "dayjs": "~1.11.0",
         "dompurify": "~3.0.5",
-        "filesize": "~10.0.12",
+        "filesize": "~10.1.0",
         "idb-keyval": "^6.2.1",
         "pinia": "~2.1.0",
-        "semver": "~7.5.0",
+        "semver": "~7.6.0",
         "showdown": "~2.1.0",
         "sortablejs": "^1.15.2",
         "vue": "~3.4.0",
         "vue-matomo": "^4.2.0",
-        "vue-router": "~4.2.0",
+        "vue-router": "~4.3.0",
         "vue3-cookies": "~1.0.0"
       },
       "devDependencies": {
         "@esbuild-plugins/node-globals-polyfill": "~0.2.3",
         "@esbuild-plugins/node-modules-polyfill": "~0.2.2",
-        "@rushstack/eslint-patch": "~1.2.0",
+        "@rushstack/eslint-patch": "~1.7.0",
         "@tsconfig/node18": "^18.2.1",
         "@types/bootstrap": "~5.2.0",
         "@types/dompurify": "~3.0.0",
@@ -43,21 +43,21 @@
         "@types/showdown": "~2.0.1",
         "@types/sortablejs": "^1.15.7",
         "@vitejs/plugin-vue": "~5.0.0",
-        "@vue/eslint-config-prettier": "~8.0.0",
-        "@vue/eslint-config-typescript": "~11.0.3",
+        "@vue/eslint-config-prettier": "~9.0.0",
+        "@vue/eslint-config-typescript": "~12.0.0",
         "@vue/tsconfig": "~0.5.0",
         "axios": "~1.6.0",
-        "eslint": "~8.48.0",
-        "eslint-plugin-vue": "~9.19.0",
+        "eslint": "~8.57.0",
+        "eslint-plugin-vue": "~9.22.0",
         "highlight.js": "^11.9.0",
         "npm-run-all": "~4.1.5",
         "openapi-typescript-codegen": "^0.27.0",
         "prettier": "~3.2.0",
         "rollup-plugin-node-polyfills": "~0.2.1",
-        "sass": "~1.66.1",
-        "typescript": "~5.1.6",
-        "vite": "~5.0.0",
-        "vue-tsc": "~1.8.0"
+        "sass": "^1.66.0",
+        "typescript": "~5.3.0",
+        "vite": "~5.1.0",
+        "vue-tsc": "~2.0.0"
       }
     },
     "node_modules/@aashutoshrathi/word-wrap": {
@@ -214,66 +214,66 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
     },
     "node_modules/@aws-sdk/client-s3": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.515.0.tgz",
-      "integrity": "sha512-K527n83hrMUdosxOYTzL63wtlJtmN5SUJZnGY1sUR6UyOrnOr9lS6t3AB6BgHqLFRFZJqSqmhflv2cOD7P1UPg==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.525.0.tgz",
+      "integrity": "sha512-hoMGH8G9rezZDiJPsMjsyRVNfVHHa4u6lcZ09SQMmtFHWK0FUcC0DIKR5ripV5qGDbnV54i2JotXlLzAv0aNCQ==",
       "dependencies": {
         "@aws-crypto/sha1-browser": "3.0.0",
         "@aws-crypto/sha256-browser": "3.0.0",
         "@aws-crypto/sha256-js": "3.0.0",
-        "@aws-sdk/client-sts": "3.515.0",
-        "@aws-sdk/core": "3.513.0",
-        "@aws-sdk/credential-provider-node": "3.515.0",
-        "@aws-sdk/middleware-bucket-endpoint": "3.515.0",
-        "@aws-sdk/middleware-expect-continue": "3.515.0",
-        "@aws-sdk/middleware-flexible-checksums": "3.515.0",
-        "@aws-sdk/middleware-host-header": "3.515.0",
-        "@aws-sdk/middleware-location-constraint": "3.515.0",
-        "@aws-sdk/middleware-logger": "3.515.0",
-        "@aws-sdk/middleware-recursion-detection": "3.515.0",
-        "@aws-sdk/middleware-sdk-s3": "3.515.0",
-        "@aws-sdk/middleware-signing": "3.515.0",
-        "@aws-sdk/middleware-ssec": "3.515.0",
-        "@aws-sdk/middleware-user-agent": "3.515.0",
-        "@aws-sdk/region-config-resolver": "3.515.0",
-        "@aws-sdk/signature-v4-multi-region": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@aws-sdk/util-endpoints": "3.515.0",
-        "@aws-sdk/util-user-agent-browser": "3.515.0",
-        "@aws-sdk/util-user-agent-node": "3.515.0",
-        "@aws-sdk/xml-builder": "3.496.0",
-        "@smithy/config-resolver": "^2.1.1",
-        "@smithy/core": "^1.3.2",
-        "@smithy/eventstream-serde-browser": "^2.1.1",
-        "@smithy/eventstream-serde-config-resolver": "^2.1.1",
-        "@smithy/eventstream-serde-node": "^2.1.1",
-        "@smithy/fetch-http-handler": "^2.4.1",
-        "@smithy/hash-blob-browser": "^2.1.1",
-        "@smithy/hash-node": "^2.1.1",
-        "@smithy/hash-stream-node": "^2.1.1",
-        "@smithy/invalid-dependency": "^2.1.1",
-        "@smithy/md5-js": "^2.1.1",
-        "@smithy/middleware-content-length": "^2.1.1",
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/middleware-retry": "^2.1.1",
-        "@smithy/middleware-serde": "^2.1.1",
-        "@smithy/middleware-stack": "^2.1.1",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/node-http-handler": "^2.3.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/url-parser": "^2.1.1",
+        "@aws-sdk/client-sts": "3.525.0",
+        "@aws-sdk/core": "3.525.0",
+        "@aws-sdk/credential-provider-node": "3.525.0",
+        "@aws-sdk/middleware-bucket-endpoint": "3.525.0",
+        "@aws-sdk/middleware-expect-continue": "3.523.0",
+        "@aws-sdk/middleware-flexible-checksums": "3.523.0",
+        "@aws-sdk/middleware-host-header": "3.523.0",
+        "@aws-sdk/middleware-location-constraint": "3.523.0",
+        "@aws-sdk/middleware-logger": "3.523.0",
+        "@aws-sdk/middleware-recursion-detection": "3.523.0",
+        "@aws-sdk/middleware-sdk-s3": "3.525.0",
+        "@aws-sdk/middleware-signing": "3.523.0",
+        "@aws-sdk/middleware-ssec": "3.523.0",
+        "@aws-sdk/middleware-user-agent": "3.525.0",
+        "@aws-sdk/region-config-resolver": "3.525.0",
+        "@aws-sdk/signature-v4-multi-region": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@aws-sdk/util-endpoints": "3.525.0",
+        "@aws-sdk/util-user-agent-browser": "3.523.0",
+        "@aws-sdk/util-user-agent-node": "3.525.0",
+        "@aws-sdk/xml-builder": "3.523.0",
+        "@smithy/config-resolver": "^2.1.4",
+        "@smithy/core": "^1.3.5",
+        "@smithy/eventstream-serde-browser": "^2.1.3",
+        "@smithy/eventstream-serde-config-resolver": "^2.1.3",
+        "@smithy/eventstream-serde-node": "^2.1.3",
+        "@smithy/fetch-http-handler": "^2.4.3",
+        "@smithy/hash-blob-browser": "^2.1.3",
+        "@smithy/hash-node": "^2.1.3",
+        "@smithy/hash-stream-node": "^2.1.3",
+        "@smithy/invalid-dependency": "^2.1.3",
+        "@smithy/md5-js": "^2.1.3",
+        "@smithy/middleware-content-length": "^2.1.3",
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/middleware-retry": "^2.1.4",
+        "@smithy/middleware-serde": "^2.1.3",
+        "@smithy/middleware-stack": "^2.1.3",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/node-http-handler": "^2.4.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/url-parser": "^2.1.3",
         "@smithy/util-base64": "^2.1.1",
         "@smithy/util-body-length-browser": "^2.1.1",
         "@smithy/util-body-length-node": "^2.2.1",
-        "@smithy/util-defaults-mode-browser": "^2.1.1",
-        "@smithy/util-defaults-mode-node": "^2.2.0",
-        "@smithy/util-endpoints": "^1.1.1",
-        "@smithy/util-retry": "^2.1.1",
-        "@smithy/util-stream": "^2.1.1",
+        "@smithy/util-defaults-mode-browser": "^2.1.4",
+        "@smithy/util-defaults-mode-node": "^2.2.3",
+        "@smithy/util-endpoints": "^1.1.4",
+        "@smithy/util-retry": "^2.1.3",
+        "@smithy/util-stream": "^2.1.3",
         "@smithy/util-utf8": "^2.1.1",
-        "@smithy/util-waiter": "^2.1.1",
+        "@smithy/util-waiter": "^2.1.3",
         "fast-xml-parser": "4.2.5",
         "tslib": "^2.5.0"
       },
@@ -282,46 +282,46 @@
       }
     },
     "node_modules/@aws-sdk/client-sso": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.515.0.tgz",
-      "integrity": "sha512-4oGBLW476zmkdN98lAns3bObRNO+DLOfg4MDUSR6l6GYBV/zGAtoy2O/FhwYKgA2L5h2ZtElGopLlk/1Q0ePLw==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.525.0.tgz",
+      "integrity": "sha512-6KwGQWFoNLH1UupdWPFdKPfTgjSz1kN8/r8aCzuvvXBe4Pz+iDUZ6FEJzGWNc9AapjvZDNO1hs23slomM9rTaA==",
       "dependencies": {
         "@aws-crypto/sha256-browser": "3.0.0",
         "@aws-crypto/sha256-js": "3.0.0",
-        "@aws-sdk/core": "3.513.0",
-        "@aws-sdk/middleware-host-header": "3.515.0",
-        "@aws-sdk/middleware-logger": "3.515.0",
-        "@aws-sdk/middleware-recursion-detection": "3.515.0",
-        "@aws-sdk/middleware-user-agent": "3.515.0",
-        "@aws-sdk/region-config-resolver": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@aws-sdk/util-endpoints": "3.515.0",
-        "@aws-sdk/util-user-agent-browser": "3.515.0",
-        "@aws-sdk/util-user-agent-node": "3.515.0",
-        "@smithy/config-resolver": "^2.1.1",
-        "@smithy/core": "^1.3.2",
-        "@smithy/fetch-http-handler": "^2.4.1",
-        "@smithy/hash-node": "^2.1.1",
-        "@smithy/invalid-dependency": "^2.1.1",
-        "@smithy/middleware-content-length": "^2.1.1",
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/middleware-retry": "^2.1.1",
-        "@smithy/middleware-serde": "^2.1.1",
-        "@smithy/middleware-stack": "^2.1.1",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/node-http-handler": "^2.3.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/url-parser": "^2.1.1",
+        "@aws-sdk/core": "3.525.0",
+        "@aws-sdk/middleware-host-header": "3.523.0",
+        "@aws-sdk/middleware-logger": "3.523.0",
+        "@aws-sdk/middleware-recursion-detection": "3.523.0",
+        "@aws-sdk/middleware-user-agent": "3.525.0",
+        "@aws-sdk/region-config-resolver": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@aws-sdk/util-endpoints": "3.525.0",
+        "@aws-sdk/util-user-agent-browser": "3.523.0",
+        "@aws-sdk/util-user-agent-node": "3.525.0",
+        "@smithy/config-resolver": "^2.1.4",
+        "@smithy/core": "^1.3.5",
+        "@smithy/fetch-http-handler": "^2.4.3",
+        "@smithy/hash-node": "^2.1.3",
+        "@smithy/invalid-dependency": "^2.1.3",
+        "@smithy/middleware-content-length": "^2.1.3",
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/middleware-retry": "^2.1.4",
+        "@smithy/middleware-serde": "^2.1.3",
+        "@smithy/middleware-stack": "^2.1.3",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/node-http-handler": "^2.4.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/url-parser": "^2.1.3",
         "@smithy/util-base64": "^2.1.1",
         "@smithy/util-body-length-browser": "^2.1.1",
         "@smithy/util-body-length-node": "^2.2.1",
-        "@smithy/util-defaults-mode-browser": "^2.1.1",
-        "@smithy/util-defaults-mode-node": "^2.2.0",
-        "@smithy/util-endpoints": "^1.1.1",
-        "@smithy/util-middleware": "^2.1.1",
-        "@smithy/util-retry": "^2.1.1",
+        "@smithy/util-defaults-mode-browser": "^2.1.4",
+        "@smithy/util-defaults-mode-node": "^2.2.3",
+        "@smithy/util-endpoints": "^1.1.4",
+        "@smithy/util-middleware": "^2.1.3",
+        "@smithy/util-retry": "^2.1.3",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
       },
@@ -330,47 +330,47 @@
       }
     },
     "node_modules/@aws-sdk/client-sso-oidc": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.515.0.tgz",
-      "integrity": "sha512-zACa8LNlPUdlNUBqQRf5a3MfouLNtcBfm84v2c8M976DwJrMGONPe1QjyLLsD38uESQiXiVQRruj/b000iMXNw==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.525.0.tgz",
+      "integrity": "sha512-zz13k/6RkjPSLmReSeGxd8wzGiiZa4Odr2Tv3wTcxClM4wOjD+zOgGv4Fe32b9AMqaueiCdjbvdu7AKcYxFA4A==",
       "dependencies": {
         "@aws-crypto/sha256-browser": "3.0.0",
         "@aws-crypto/sha256-js": "3.0.0",
-        "@aws-sdk/client-sts": "3.515.0",
-        "@aws-sdk/core": "3.513.0",
-        "@aws-sdk/middleware-host-header": "3.515.0",
-        "@aws-sdk/middleware-logger": "3.515.0",
-        "@aws-sdk/middleware-recursion-detection": "3.515.0",
-        "@aws-sdk/middleware-user-agent": "3.515.0",
-        "@aws-sdk/region-config-resolver": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@aws-sdk/util-endpoints": "3.515.0",
-        "@aws-sdk/util-user-agent-browser": "3.515.0",
-        "@aws-sdk/util-user-agent-node": "3.515.0",
-        "@smithy/config-resolver": "^2.1.1",
-        "@smithy/core": "^1.3.2",
-        "@smithy/fetch-http-handler": "^2.4.1",
-        "@smithy/hash-node": "^2.1.1",
-        "@smithy/invalid-dependency": "^2.1.1",
-        "@smithy/middleware-content-length": "^2.1.1",
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/middleware-retry": "^2.1.1",
-        "@smithy/middleware-serde": "^2.1.1",
-        "@smithy/middleware-stack": "^2.1.1",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/node-http-handler": "^2.3.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/url-parser": "^2.1.1",
+        "@aws-sdk/client-sts": "3.525.0",
+        "@aws-sdk/core": "3.525.0",
+        "@aws-sdk/middleware-host-header": "3.523.0",
+        "@aws-sdk/middleware-logger": "3.523.0",
+        "@aws-sdk/middleware-recursion-detection": "3.523.0",
+        "@aws-sdk/middleware-user-agent": "3.525.0",
+        "@aws-sdk/region-config-resolver": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@aws-sdk/util-endpoints": "3.525.0",
+        "@aws-sdk/util-user-agent-browser": "3.523.0",
+        "@aws-sdk/util-user-agent-node": "3.525.0",
+        "@smithy/config-resolver": "^2.1.4",
+        "@smithy/core": "^1.3.5",
+        "@smithy/fetch-http-handler": "^2.4.3",
+        "@smithy/hash-node": "^2.1.3",
+        "@smithy/invalid-dependency": "^2.1.3",
+        "@smithy/middleware-content-length": "^2.1.3",
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/middleware-retry": "^2.1.4",
+        "@smithy/middleware-serde": "^2.1.3",
+        "@smithy/middleware-stack": "^2.1.3",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/node-http-handler": "^2.4.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/url-parser": "^2.1.3",
         "@smithy/util-base64": "^2.1.1",
         "@smithy/util-body-length-browser": "^2.1.1",
         "@smithy/util-body-length-node": "^2.2.1",
-        "@smithy/util-defaults-mode-browser": "^2.1.1",
-        "@smithy/util-defaults-mode-node": "^2.2.0",
-        "@smithy/util-endpoints": "^1.1.1",
-        "@smithy/util-middleware": "^2.1.1",
-        "@smithy/util-retry": "^2.1.1",
+        "@smithy/util-defaults-mode-browser": "^2.1.4",
+        "@smithy/util-defaults-mode-node": "^2.2.3",
+        "@smithy/util-endpoints": "^1.1.4",
+        "@smithy/util-middleware": "^2.1.3",
+        "@smithy/util-retry": "^2.1.3",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
       },
@@ -378,50 +378,50 @@
         "node": ">=14.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/credential-provider-node": "^3.515.0"
+        "@aws-sdk/credential-provider-node": "^3.525.0"
       }
     },
     "node_modules/@aws-sdk/client-sts": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.515.0.tgz",
-      "integrity": "sha512-ScYuvaIDgip3atOJIA1FU2n0gJkEdveu1KrrCPathoUCV5zpK8qQmO/n+Fj/7hKFxeKdFbB+4W4CsJWYH94nlg==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.525.0.tgz",
+      "integrity": "sha512-a8NUGRvO6rkfTZCbMaCsjDjLbERCwIUU9dIywFYcRgbFhkupJ7fSaZz3Het98U51M9ZbTEpaTa3fz0HaJv8VJw==",
       "dependencies": {
         "@aws-crypto/sha256-browser": "3.0.0",
         "@aws-crypto/sha256-js": "3.0.0",
-        "@aws-sdk/core": "3.513.0",
-        "@aws-sdk/middleware-host-header": "3.515.0",
-        "@aws-sdk/middleware-logger": "3.515.0",
-        "@aws-sdk/middleware-recursion-detection": "3.515.0",
-        "@aws-sdk/middleware-user-agent": "3.515.0",
-        "@aws-sdk/region-config-resolver": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@aws-sdk/util-endpoints": "3.515.0",
-        "@aws-sdk/util-user-agent-browser": "3.515.0",
-        "@aws-sdk/util-user-agent-node": "3.515.0",
-        "@smithy/config-resolver": "^2.1.1",
-        "@smithy/core": "^1.3.2",
-        "@smithy/fetch-http-handler": "^2.4.1",
-        "@smithy/hash-node": "^2.1.1",
-        "@smithy/invalid-dependency": "^2.1.1",
-        "@smithy/middleware-content-length": "^2.1.1",
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/middleware-retry": "^2.1.1",
-        "@smithy/middleware-serde": "^2.1.1",
-        "@smithy/middleware-stack": "^2.1.1",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/node-http-handler": "^2.3.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/url-parser": "^2.1.1",
+        "@aws-sdk/core": "3.525.0",
+        "@aws-sdk/middleware-host-header": "3.523.0",
+        "@aws-sdk/middleware-logger": "3.523.0",
+        "@aws-sdk/middleware-recursion-detection": "3.523.0",
+        "@aws-sdk/middleware-user-agent": "3.525.0",
+        "@aws-sdk/region-config-resolver": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@aws-sdk/util-endpoints": "3.525.0",
+        "@aws-sdk/util-user-agent-browser": "3.523.0",
+        "@aws-sdk/util-user-agent-node": "3.525.0",
+        "@smithy/config-resolver": "^2.1.4",
+        "@smithy/core": "^1.3.5",
+        "@smithy/fetch-http-handler": "^2.4.3",
+        "@smithy/hash-node": "^2.1.3",
+        "@smithy/invalid-dependency": "^2.1.3",
+        "@smithy/middleware-content-length": "^2.1.3",
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/middleware-retry": "^2.1.4",
+        "@smithy/middleware-serde": "^2.1.3",
+        "@smithy/middleware-stack": "^2.1.3",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/node-http-handler": "^2.4.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/url-parser": "^2.1.3",
         "@smithy/util-base64": "^2.1.1",
         "@smithy/util-body-length-browser": "^2.1.1",
         "@smithy/util-body-length-node": "^2.2.1",
-        "@smithy/util-defaults-mode-browser": "^2.1.1",
-        "@smithy/util-defaults-mode-node": "^2.2.0",
-        "@smithy/util-endpoints": "^1.1.1",
-        "@smithy/util-middleware": "^2.1.1",
-        "@smithy/util-retry": "^2.1.1",
+        "@smithy/util-defaults-mode-browser": "^2.1.4",
+        "@smithy/util-defaults-mode-node": "^2.2.3",
+        "@smithy/util-endpoints": "^1.1.4",
+        "@smithy/util-middleware": "^2.1.3",
+        "@smithy/util-retry": "^2.1.3",
         "@smithy/util-utf8": "^2.1.1",
         "fast-xml-parser": "4.2.5",
         "tslib": "^2.5.0"
@@ -430,19 +430,19 @@
         "node": ">=14.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/credential-provider-node": "^3.515.0"
+        "@aws-sdk/credential-provider-node": "^3.525.0"
       }
     },
     "node_modules/@aws-sdk/core": {
-      "version": "3.513.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.513.0.tgz",
-      "integrity": "sha512-L+9DL4apWuqNKVOMJ8siAuWoRM9rZf9w1iPv8S2o83WO2jVK7E/m+rNW1dFo9HsA5V1ccDl2H2qLXx24HiHmOw==",
-      "dependencies": {
-        "@smithy/core": "^1.3.2",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/signature-v4": "^2.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.525.0.tgz",
+      "integrity": "sha512-E3LtEtMWCriQOFZpVKpLYzbdw/v2PAOEAMhn2VRRZ1g0/g1TXzQrfhEU2yd8l/vQEJaCJ82ooGGg7YECviBUxA==",
+      "dependencies": {
+        "@smithy/core": "^1.3.5",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/signature-v4": "^2.1.3",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -450,13 +450,13 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-env": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.515.0.tgz",
-      "integrity": "sha512-45vxdyqhTAaUMERYVWOziG3K8L2TV9G4ryQS/KZ84o7NAybE9GMdoZRVmGHAO7mJJ1wQiYCM/E+i5b3NW9JfNA==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.523.0.tgz",
+      "integrity": "sha512-Y6DWdH6/OuMDoNKVzZlNeBc6f1Yjk1lYMjANKpIhMbkRCvLJw/PYZKOZa8WpXbTYdgg9XLjKybnLIb3ww3uuzA==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -464,18 +464,18 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-http": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.515.0.tgz",
-      "integrity": "sha512-Ba6FXK77vU4WyheiamNjEuTFmir0eAXuJGPO27lBaA8g+V/seXGHScsbOG14aQGDOr2P02OPwKGZrWWA7BFpfQ==",
-      "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/fetch-http-handler": "^2.4.1",
-        "@smithy/node-http-handler": "^2.3.1",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/util-stream": "^2.1.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.525.0.tgz",
+      "integrity": "sha512-RNWQGuSBQZhl3iqklOslUEfQ4br1V3DCPboMpeqFtddUWJV3m2u2extFur9/4Uy+1EHVF120IwZUKtd8dF+ibw==",
+      "dependencies": {
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/fetch-http-handler": "^2.4.3",
+        "@smithy/node-http-handler": "^2.4.1",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/util-stream": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -483,20 +483,20 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-ini": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.515.0.tgz",
-      "integrity": "sha512-ouDlNZdv2TKeVEA/YZk2+XklTXyAAGdbWnl4IgN9ItaodWI+lZjdIoNC8BAooVH+atIV/cZgoGTGQL7j2TxJ9A==",
-      "dependencies": {
-        "@aws-sdk/client-sts": "3.515.0",
-        "@aws-sdk/credential-provider-env": "3.515.0",
-        "@aws-sdk/credential-provider-process": "3.515.0",
-        "@aws-sdk/credential-provider-sso": "3.515.0",
-        "@aws-sdk/credential-provider-web-identity": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/credential-provider-imds": "^2.2.1",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.525.0.tgz",
+      "integrity": "sha512-JDnccfK5JRb9jcgpc9lirL9PyCwGIqY0nKdw3LlX5WL5vTpTG4E1q7rLAlpNh7/tFD1n66Itarfv2tsyHMIqCw==",
+      "dependencies": {
+        "@aws-sdk/client-sts": "3.525.0",
+        "@aws-sdk/credential-provider-env": "3.523.0",
+        "@aws-sdk/credential-provider-process": "3.523.0",
+        "@aws-sdk/credential-provider-sso": "3.525.0",
+        "@aws-sdk/credential-provider-web-identity": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/credential-provider-imds": "^2.2.3",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/shared-ini-file-loader": "^2.3.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -504,21 +504,21 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-node": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.515.0.tgz",
-      "integrity": "sha512-Y4kHSpbxksiCZZNcvsiKUd8Fb2XlyUuONEwqWFNL82ZH6TCCjBGS31wJQCSxBHqYcOL3tiORUEJkoO7uS30uQA==",
-      "dependencies": {
-        "@aws-sdk/credential-provider-env": "3.515.0",
-        "@aws-sdk/credential-provider-http": "3.515.0",
-        "@aws-sdk/credential-provider-ini": "3.515.0",
-        "@aws-sdk/credential-provider-process": "3.515.0",
-        "@aws-sdk/credential-provider-sso": "3.515.0",
-        "@aws-sdk/credential-provider-web-identity": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/credential-provider-imds": "^2.2.1",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.525.0.tgz",
+      "integrity": "sha512-RJXlO8goGXpnoHQAyrCcJ0QtWEOFa34LSbfdqBIjQX/fwnjUuEmiGdXTV3AZmwYQ7juk49tfBneHbtOP3AGqsQ==",
+      "dependencies": {
+        "@aws-sdk/credential-provider-env": "3.523.0",
+        "@aws-sdk/credential-provider-http": "3.525.0",
+        "@aws-sdk/credential-provider-ini": "3.525.0",
+        "@aws-sdk/credential-provider-process": "3.523.0",
+        "@aws-sdk/credential-provider-sso": "3.525.0",
+        "@aws-sdk/credential-provider-web-identity": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/credential-provider-imds": "^2.2.3",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/shared-ini-file-loader": "^2.3.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -526,14 +526,14 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-process": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.515.0.tgz",
-      "integrity": "sha512-pSjiOA2FM63LHRKNDvEpBRp80FVGT0Mw/gzgbqFXP+sewk0WVonYbEcMDTJptH3VsLPGzqH/DQ1YL/aEIBuXFQ==",
-      "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.523.0.tgz",
+      "integrity": "sha512-f0LP9KlFmMvPWdKeUKYlZ6FkQAECUeZMmISsv6NKtvPCI9e4O4cLTeR09telwDK8P0HrgcRuZfXM7E30m8re0Q==",
+      "dependencies": {
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/shared-ini-file-loader": "^2.3.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -541,16 +541,16 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-sso": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.515.0.tgz",
-      "integrity": "sha512-j7vUkiSmuhpBvZYoPTRTI4ePnQbiZMFl6TNhg9b9DprC1zHkucsZnhRhqjOVlrw/H6J4jmcPGcHHTZ5WQNI5xQ==",
-      "dependencies": {
-        "@aws-sdk/client-sso": "3.515.0",
-        "@aws-sdk/token-providers": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.525.0.tgz",
+      "integrity": "sha512-7V7ybtufxdD3plxeIeB6aqHZeFIUlAyPphXIUgXrGY10iNcosL970rQPBeggsohe4gCM6UvY2TfMeEcr+ZE8FA==",
+      "dependencies": {
+        "@aws-sdk/client-sso": "3.525.0",
+        "@aws-sdk/token-providers": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/shared-ini-file-loader": "^2.3.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -558,14 +558,14 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-web-identity": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.515.0.tgz",
-      "integrity": "sha512-66+2g4z3fWwdoGReY8aUHvm6JrKZMTRxjuizljVmMyOBttKPeBYXvUTop/g3ZGUx1f8j+C5qsGK52viYBvtjuQ==",
-      "dependencies": {
-        "@aws-sdk/client-sts": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.525.0.tgz",
+      "integrity": "sha512-sAukOjR1oKb2JXG4nPpuBFpSwGUhrrY17PG/xbTy8NAoLLhrqRwnErcLfdTfmj6tH+3094k6ws/Sh8a35ae7fA==",
+      "dependencies": {
+        "@aws-sdk/client-sts": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -573,13 +573,13 @@
       }
     },
     "node_modules/@aws-sdk/lib-storage": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.515.0.tgz",
-      "integrity": "sha512-/7z/3KnMs1ODNS9c8Skj/DFTsy6/v7n17clh1IGOcTYhhioCMA3MIzIZecWFeLjPYcUSkNQHIIjKFQt1nhZkwA==",
+      "version": "3.525.1",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.525.1.tgz",
+      "integrity": "sha512-q0y4+bc5GsE10F1HyA1D24maRyy2H3Ph3o+1eK7/kzKrk0nBbISLGbZ8XNqtWwi+9KdsqWNKMoN9+zsDaE6d/w==",
       "dependencies": {
-        "@smithy/abort-controller": "^2.1.1",
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/smithy-client": "^2.3.1",
+        "@smithy/abort-controller": "^2.1.3",
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/smithy-client": "^2.4.2",
         "buffer": "5.6.0",
         "events": "3.3.0",
         "stream-browserify": "3.0.0",
@@ -593,15 +593,15 @@
       }
     },
     "node_modules/@aws-sdk/middleware-bucket-endpoint": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.515.0.tgz",
-      "integrity": "sha512-Vm423j3udFrhKPaKiXtie+6aF05efjX8lhAu5VOruIvbam7olvdWNdkH7sGWlz1ko3CVa7PwOYjGHiOOhxpEOA==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.525.0.tgz",
+      "integrity": "sha512-nYfQ2Xspfef7j8mZO7varUWLPH6HQlXateH7tBVtBNUAazyQE4UJEvC0fbQ+Y01e+FKlirim/m2umkdMXqAlTg==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
+        "@aws-sdk/types": "3.523.0",
         "@aws-sdk/util-arn-parser": "3.495.0",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-config-provider": "^2.2.1",
         "tslib": "^2.5.0"
       },
@@ -610,13 +610,13 @@
       }
     },
     "node_modules/@aws-sdk/middleware-expect-continue": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.515.0.tgz",
-      "integrity": "sha512-TWCXulivab4reOMx/vxa/IwnPX78fLwI9NUoAxjsqB6W9qjmSnPD43BSVeGvbbl/YNmgk7XfMbZb6IgxW7RyzA==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.523.0.tgz",
+      "integrity": "sha512-E5DyRAHU39VHaAlQLqXYS/IKpgk3vsryuU6kkOcIIK8Dgw0a2tjoh5AOCaNa8pD+KgAGrFp35JIMSX1zui5diA==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -624,16 +624,16 @@
       }
     },
     "node_modules/@aws-sdk/middleware-flexible-checksums": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.515.0.tgz",
-      "integrity": "sha512-ydGjnqNeYlJaAkmQeQnS4pZRAAvzefdm8c234Qh0Fg55xRwHTNLp7uYsdfkTjrdAlj6YIO3Zr6vK6VJ6MGCwug==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.523.0.tgz",
+      "integrity": "sha512-lIa1TdWY9q4zsDFarfSnYcdrwPR+nypaU4n6hb95i620/1F5M5s6H8P0hYtwTNNvx+slrR8F3VBML9pjBtzAHw==",
       "dependencies": {
         "@aws-crypto/crc32": "3.0.0",
         "@aws-crypto/crc32c": "3.0.0",
-        "@aws-sdk/types": "3.515.0",
+        "@aws-sdk/types": "3.523.0",
         "@smithy/is-array-buffer": "^2.1.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
       },
@@ -642,13 +642,13 @@
       }
     },
     "node_modules/@aws-sdk/middleware-host-header": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.515.0.tgz",
-      "integrity": "sha512-I1MwWPzdRKM1luvdDdjdGsDjNVPhj9zaIytEchjTY40NcKOg+p2evLD2y69ozzg8pyXK63r8DdvDGOo9QPuh0A==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.523.0.tgz",
+      "integrity": "sha512-4g3q7Ta9sdD9TMUuohBAkbx/e3I/juTqfKi7TPgP+8jxcYX72MOsgemAMHuP6CX27eyj4dpvjH+w4SIVDiDSmg==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -656,12 +656,12 @@
       }
     },
     "node_modules/@aws-sdk/middleware-location-constraint": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.515.0.tgz",
-      "integrity": "sha512-ORFC5oijjTJsHhUXy9o52/vl5Irf6e83bE/8tBp+sVVx81+E8zTTWZbysoa41c0B5Ycd0H3wCWutvjdXT16ydQ==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.523.0.tgz",
+      "integrity": "sha512-1QAUXX3U0jkARnU0yyjk81EO4Uw5dCeQOtvUY5s3bUOHatR3ThosQeIr6y9BCsbXHzNnDe1ytCjqAPyo8r/bYw==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -669,12 +669,12 @@
       }
     },
     "node_modules/@aws-sdk/middleware-logger": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.515.0.tgz",
-      "integrity": "sha512-qXomJzg2m/5seQOxHi/yOXOKfSjwrrJSmEmfwJKJyQgdMbBcjz3Cz0H/1LyC6c5hHm6a/SZgSTzDAbAoUmyL+Q==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.523.0.tgz",
+      "integrity": "sha512-PeDNJNhfiaZx54LBaLTXzUaJ9LXFwDFFIksipjqjvxMafnoVcQwKbkoPUWLe5ytT4nnL1LogD3s55mERFUsnwg==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -682,13 +682,13 @@
       }
     },
     "node_modules/@aws-sdk/middleware-recursion-detection": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.515.0.tgz",
-      "integrity": "sha512-dokHLbTV3IHRIBrw9mGoxcNTnQsjlm7TpkJhPdGT9T4Mq399EyQo51u6IsVMm07RXLl2Zw7u+u9p+qWBFzmFRA==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.523.0.tgz",
+      "integrity": "sha512-nZ3Vt7ehfSDYnrcg/aAfjjvpdE+61B3Zk68i6/hSUIegT3IH9H1vSW67NDKVp+50hcEfzWwM2HMPXxlzuyFyrw==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -696,17 +696,17 @@
       }
     },
     "node_modules/@aws-sdk/middleware-sdk-s3": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.515.0.tgz",
-      "integrity": "sha512-vB8JwiTEAqm1UT9xfugnCgl0H0dtBLUQQK99JwQEWjHPZmQ3HQuVkykmJRY3X0hzKMEgqXodz0hZOvf3Hq1mvQ==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.525.0.tgz",
+      "integrity": "sha512-ewFyyFM6wdFTOqCiId5GQNi7owDdLEonQhB4h8tF6r3HV52bRlDvZA4aDos+ft6N/XY2J6L0qlFTFq+/oiurXw==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
+        "@aws-sdk/types": "3.523.0",
         "@aws-sdk/util-arn-parser": "3.495.0",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/signature-v4": "^2.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/signature-v4": "^2.1.3",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-config-provider": "^2.2.1",
         "tslib": "^2.5.0"
       },
@@ -715,16 +715,16 @@
       }
     },
     "node_modules/@aws-sdk/middleware-signing": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.515.0.tgz",
-      "integrity": "sha512-SdjCyQCL702I07KhCiBFcoh6+NYtnruHJQIzWwMpBteuYHnCHW1k9uZ6pqacsS+Y6qpAKfTVNpQx2zP2s6QoHA==",
-      "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/signature-v4": "^2.1.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/util-middleware": "^2.1.1",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.523.0.tgz",
+      "integrity": "sha512-pFXV4don6qcmew/OvEjLUr2foVjzoJ8o5k57Oz9yAHz8INx3RHK8MP/K4mVhHo6n0SquRcWrm4kY/Tw+89gkEA==",
+      "dependencies": {
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/signature-v4": "^2.1.3",
+        "@smithy/types": "^2.10.1",
+        "@smithy/util-middleware": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -732,12 +732,12 @@
       }
     },
     "node_modules/@aws-sdk/middleware-ssec": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.515.0.tgz",
-      "integrity": "sha512-0qLjKiorosVBzzaV/o7MEyS9xqLLu02qGbP564Z/FZY74JUQEpBNedgveMUbb6lqr85RnOuwZ0GZ0cBRfH2brQ==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.523.0.tgz",
+      "integrity": "sha512-FaqAZQeF5cQzZLOIboIJRaWVOQ2F2pJZAXGF5D7nJsxYNFChotA0O0iWimBRxU35RNn7yirVxz35zQzs20ddIw==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -745,14 +745,14 @@
       }
     },
     "node_modules/@aws-sdk/middleware-user-agent": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.515.0.tgz",
-      "integrity": "sha512-nOqZjGA/GkjuJ5fUshec9Fv6HFd7ovOTxMJbw3MfAhqXuVZ6dKF41lpVJ4imNsgyFt3shUg9WDY8zGFjlYMB3g==",
-      "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@aws-sdk/util-endpoints": "3.515.0",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.525.0.tgz",
+      "integrity": "sha512-4al/6uO+t/QIYXK2OgqzDKQzzLAYJza1vWFS+S0lJ3jLNGyLB5BMU5KqWjDzevYZ4eCnz2Nn7z0FveUTNz8YdQ==",
+      "dependencies": {
+        "@aws-sdk/types": "3.523.0",
+        "@aws-sdk/util-endpoints": "3.525.0",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -760,15 +760,15 @@
       }
     },
     "node_modules/@aws-sdk/region-config-resolver": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.515.0.tgz",
-      "integrity": "sha512-RIRx9loxMgEAc/r1wPfnfShOuzn4RBi8pPPv6/jhhITEeMnJe6enAh2k5y9DdiVDDgCWZgVFSv0YkAIfzAFsnQ==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.525.0.tgz",
+      "integrity": "sha512-8kFqXk6UyKgTMi7N7QlhA6qM4pGPWbiUXqEY2RgUWngtxqNFGeM9JTexZeuavQI+qLLe09VPShPNX71fEDcM6w==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-config-provider": "^2.2.1",
-        "@smithy/util-middleware": "^2.1.1",
+        "@smithy/util-middleware": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -776,17 +776,17 @@
       }
     },
     "node_modules/@aws-sdk/s3-request-presigner": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.515.0.tgz",
-      "integrity": "sha512-B6RcXWJTOHSqZDII/sYeM89MWc//AwA7iIcZk+oXyUSdVTl03z6raJMxWqY0dPx7KuBjLTnZPqUXKCCoQvnp/g==",
-      "dependencies": {
-        "@aws-sdk/signature-v4-multi-region": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@aws-sdk/util-format-url": "3.515.0",
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.525.0.tgz",
+      "integrity": "sha512-EllqWqzzzLs8QgUENgOF8qlSuZI6QiPypazSVbCuaAR5B6+s6E8XuBPlX99bV28pGbmtG06d/qqwu2pzXORbBg==",
+      "dependencies": {
+        "@aws-sdk/signature-v4-multi-region": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@aws-sdk/util-format-url": "3.523.0",
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -794,15 +794,15 @@
       }
     },
     "node_modules/@aws-sdk/signature-v4-multi-region": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.515.0.tgz",
-      "integrity": "sha512-5lrCn4DSE0zL41k0L6moqcdExZhWdAnV0/oMEagrISzQYoia+aNTEeyVD3xqJhRbEW4gCj3Uoyis6c8muf7b9g==",
-      "dependencies": {
-        "@aws-sdk/middleware-sdk-s3": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/signature-v4": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.525.0.tgz",
+      "integrity": "sha512-j8gkdfiokaherRgokfZBl2azYBMHlegT7pOnR/3Y79TSz6G+bJeIkuNk8aUbJArr6R8nvAM1j4dt1rBM+efolQ==",
+      "dependencies": {
+        "@aws-sdk/middleware-sdk-s3": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/signature-v4": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -810,15 +810,15 @@
       }
     },
     "node_modules/@aws-sdk/token-providers": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.515.0.tgz",
-      "integrity": "sha512-MQuf04rIcTXqwDzmyHSpFPF1fKEzRl64oXtCRUF3ddxTdK6wxXkePfK6wNCuL+GEbEcJAoCtIGIRpzGPJvQjHA==",
-      "dependencies": {
-        "@aws-sdk/client-sso-oidc": "3.515.0",
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.525.0.tgz",
+      "integrity": "sha512-puVjbxuK0Dq7PTQ2HdddHy2eQjOH8GZbump74yWJa6JVpRW84LlOcNmP+79x4Kscvz2ldWB8XDFw/pcCiSDe5A==",
+      "dependencies": {
+        "@aws-sdk/client-sso-oidc": "3.525.0",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/shared-ini-file-loader": "^2.3.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -826,11 +826,11 @@
       }
     },
     "node_modules/@aws-sdk/types": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.515.0.tgz",
-      "integrity": "sha512-B3gUpiMlpT6ERaLvZZ61D0RyrQPsFYDkCncLPVkZOKkCOoFU46zi1o6T5JcYiz8vkx1q9RGloQ5exh79s5pU/w==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.523.0.tgz",
+      "integrity": "sha512-AqGIu4u+SxPiUuNBp2acCVcq80KDUFjxe6e3cMTvKWTzCbrVk1AXv0dAaJnCmdkWIha6zJDWxpIk/aL4EGhZ9A==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -849,13 +849,13 @@
       }
     },
     "node_modules/@aws-sdk/util-endpoints": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.515.0.tgz",
-      "integrity": "sha512-UJi+jdwcGFV/F7d3+e2aQn5yZOVpDiAgfgNhPnEtgV0WozJ5/ZUeZBgWvSc/K415N4A4D/9cbBc7+I+35qzcDQ==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.525.0.tgz",
+      "integrity": "sha512-DIW7WWU5tIGkeeKX6NJUyrEIdWMiqjLQG3XBzaUj+ufIENwNjdAHhlD8l2vX7Yr3JZRT6yN/84wBCj7Tw1xd1g==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/types": "^2.9.1",
-        "@smithy/util-endpoints": "^1.1.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/types": "^2.10.1",
+        "@smithy/util-endpoints": "^1.1.4",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -863,13 +863,13 @@
       }
     },
     "node_modules/@aws-sdk/util-format-url": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.515.0.tgz",
-      "integrity": "sha512-7BgmUldmECebZU2qUAxOoEkHnji5NZX/j6TcgY4xgl1tUycw72BeKdcQYLUt4YoXQmIGZHiBL8L/TfO48W+FpA==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.523.0.tgz",
+      "integrity": "sha512-OWi+8bsEfxG4DvHkWauxyWVZMbYrezC49DbGDEu1lJgk9eqQALlyGkZHt9O8KKfyT/mdqQbR8qbpkxqYcGuHVA==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/querystring-builder": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/querystring-builder": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -888,24 +888,24 @@
       }
     },
     "node_modules/@aws-sdk/util-user-agent-browser": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.515.0.tgz",
-      "integrity": "sha512-pTWQb0JCafTmLHLDv3Qqs/nAAJghcPdGQIBpsCStb0YEzg3At/dOi2AIQ683yYnXmeOxLXJDzmlsovfVObJScw==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.523.0.tgz",
+      "integrity": "sha512-6ZRNdGHX6+HQFqTbIA5+i8RWzxFyxsZv8D3soRfpdyWIKkzhSz8IyRKXRciwKBJDaC7OX2jzGE90wxRQft27nA==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/types": "^2.10.1",
         "bowser": "^2.11.0",
         "tslib": "^2.5.0"
       }
     },
     "node_modules/@aws-sdk/util-user-agent-node": {
-      "version": "3.515.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.515.0.tgz",
-      "integrity": "sha512-A/KJ+/HTohHyVXLH+t/bO0Z2mPrQgELbQO8tX+B2nElo8uklj70r5cT7F8ETsI9oOy+HDVpiL5/v45ZgpUOiPg==",
+      "version": "3.525.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.525.0.tgz",
+      "integrity": "sha512-88Wjt4efyUSBGcyIuh1dvoMqY1k15jpJc5A/3yi67clBQEFsu9QCodQCQPqmRjV3VRcMtBOk+jeCTiUzTY5dRQ==",
       "dependencies": {
-        "@aws-sdk/types": "3.515.0",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/types": "^2.9.1",
+        "@aws-sdk/types": "3.523.0",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -929,11 +929,11 @@
       }
     },
     "node_modules/@aws-sdk/xml-builder": {
-      "version": "3.496.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.496.0.tgz",
-      "integrity": "sha512-GvEjh537IIeOw1ZkZuB37sV12u+ipS5Z1dwjEC/HAvhl5ac23ULtTr1/n+U1gLNN+BAKSWjKiQ2ksj8DiUzeyw==",
+      "version": "3.523.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.523.0.tgz",
+      "integrity": "sha512-wfvyVymj2TUw7SuDor9IuFcAzJZvWRBZotvY/wQJOlYa3UP3Oezzecy64N4FWfBJEsZdrTN+HOZFl+IzTWWnUA==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -941,9 +941,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.23.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
-      "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
+      "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
       "bin": {
         "parser": "bin/babel-parser.js"
       },
@@ -1427,16 +1427,38 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
+    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
     "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
       "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
       "dev": true
     },
+    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/@eslint/js": {
-      "version": "8.48.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz",
-      "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==",
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+      "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1465,6 +1487,28 @@
         "node": ">=10.10.0"
       }
     },
+    "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/@humanwhocodes/module-importer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
@@ -1726,17 +1770,17 @@
       ]
     },
     "node_modules/@rushstack/eslint-patch": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz",
-      "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==",
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz",
+      "integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==",
       "dev": true
     },
     "node_modules/@smithy/abort-controller": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.1.1.tgz",
-      "integrity": "sha512-1+qdrUqLhaALYL0iOcN43EP6yAXXQ2wWZ6taf4S2pNGowmOc5gx+iMQv+E42JizNJjB0+gEadOXeV1Bf7JWL1Q==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-2.1.3.tgz",
+      "integrity": "sha512-c2aYH2Wu1RVE3rLlVgg2kQOBJGM0WbjReQi5DnPTm2Zb7F0gk7J2aeQeaX2u/lQZoHl6gv8Oac7mt9alU3+f4A==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1761,14 +1805,14 @@
       }
     },
     "node_modules/@smithy/config-resolver": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.1.1.tgz",
-      "integrity": "sha512-lxfLDpZm+AWAHPFZps5JfDoO9Ux1764fOgvRUBpHIO8HWHcSN1dkgsago1qLRVgm1BZ8RCm8cgv99QvtaOWIhw==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-2.1.4.tgz",
+      "integrity": "sha512-AW2WUZmBAzgO3V3ovKtsUbI3aBNMeQKFDumoqkNxaVDWF/xfnxAWqBKDr/NuG7c06N2Rm4xeZLPiJH/d+na0HA==",
       "dependencies": {
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-config-provider": "^2.2.1",
-        "@smithy/util-middleware": "^2.1.1",
+        "@smithy/util-middleware": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1776,17 +1820,17 @@
       }
     },
     "node_modules/@smithy/core": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.2.tgz",
-      "integrity": "sha512-tYDmTp0f2TZVE18jAOH1PnmkngLQ+dOGUlMd1u67s87ieueNeyqhja6z/Z4MxhybEiXKOWFOmGjfTZWFxljwJw==",
-      "dependencies": {
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/middleware-retry": "^2.1.1",
-        "@smithy/middleware-serde": "^2.1.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/util-middleware": "^2.1.1",
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/@smithy/core/-/core-1.3.5.tgz",
+      "integrity": "sha512-Rrc+e2Jj6Gu7Xbn0jvrzZlSiP2CZocIOfZ9aNUA82+1sa6GBnxqL9+iZ9EKHeD9aqD1nU8EK4+oN2EiFpSv7Yw==",
+      "dependencies": {
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/middleware-retry": "^2.1.4",
+        "@smithy/middleware-serde": "^2.1.3",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/util-middleware": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1794,14 +1838,14 @@
       }
     },
     "node_modules/@smithy/credential-provider-imds": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.1.tgz",
-      "integrity": "sha512-7XHjZUxmZYnONheVQL7j5zvZXga+EWNgwEAP6OPZTi7l8J4JTeNh9aIOfE5fKHZ/ee2IeNOh54ZrSna+Vc6TFA==",
-      "dependencies": {
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/url-parser": "^2.1.1",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-2.2.4.tgz",
+      "integrity": "sha512-DdatjmBZQnhGe1FhI8gO98f7NmvQFSDiZTwC3WMvLTCKQUY+Y1SVkhJqIuLu50Eb7pTheoXQmK+hKYUgpUWsNA==",
+      "dependencies": {
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/types": "^2.10.1",
+        "@smithy/url-parser": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1809,23 +1853,23 @@
       }
     },
     "node_modules/@smithy/eventstream-codec": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.1.1.tgz",
-      "integrity": "sha512-E8KYBxBIuU4c+zrpR22VsVrOPoEDzk35bQR3E+xm4k6Pa6JqzkDOdMyf9Atac5GPNKHJBdVaQ4JtjdWX2rl/nw==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-2.1.3.tgz",
+      "integrity": "sha512-rGlCVuwSDv6qfKH4/lRxFjcZQnIE0LZ3D4lkMHg7ZSltK9rA74r0VuGSvWVQ4N/d70VZPaniFhp4Z14QYZsa+A==",
       "dependencies": {
         "@aws-crypto/crc32": "3.0.0",
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-hex-encoding": "^2.1.1",
         "tslib": "^2.5.0"
       }
     },
     "node_modules/@smithy/eventstream-serde-browser": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.1.1.tgz",
-      "integrity": "sha512-JvEdCmGlZUay5VtlT8/kdR6FlvqTDUiJecMjXsBb0+k1H/qc9ME5n2XKPo8q/MZwEIA1GmGgYMokKGjVvMiDow==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-2.1.3.tgz",
+      "integrity": "sha512-qAgKbZ9m2oBfSyJWWurX/MvQFRPrYypj79cDSleEgDwBoez6Tfd+FTpu2L/j3ZeC3mDlDHIKWksoeaXZpLLAHw==",
       "dependencies": {
-        "@smithy/eventstream-serde-universal": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/eventstream-serde-universal": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1833,11 +1877,11 @@
       }
     },
     "node_modules/@smithy/eventstream-serde-config-resolver": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.1.1.tgz",
-      "integrity": "sha512-EqNqXYp3+dk//NmW3NAgQr9bEQ7fsu/CcxQmTiq07JlaIcne/CBWpMZETyXm9w5LXkhduBsdXdlMscfDUDn2fA==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-2.1.3.tgz",
+      "integrity": "sha512-48rvsNv/MgAFCxOE0qwR7ZwKhaEdDoTxqH5HM+T6SDxICmPGb7gEuQzjTxQhcieCPgqyXeZFW8cU0QJxdowuIg==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1845,12 +1889,12 @@
       }
     },
     "node_modules/@smithy/eventstream-serde-node": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.1.1.tgz",
-      "integrity": "sha512-LF882q/aFidFNDX7uROAGxq3H0B7rjyPkV6QDn6/KDQ+CG7AFkRccjxRf1xqajq/Pe4bMGGr+VKAaoF6lELIQw==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-2.1.3.tgz",
+      "integrity": "sha512-RPJWWDhj8isk3NtGfm3Xt1WdHyX9ZE42V+m1nLU1I0zZ1hEol/oawHsTnhva/VR5bn+bJ2zscx+BYr0cEPRtmg==",
       "dependencies": {
-        "@smithy/eventstream-serde-universal": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/eventstream-serde-universal": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1858,12 +1902,12 @@
       }
     },
     "node_modules/@smithy/eventstream-serde-universal": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.1.1.tgz",
-      "integrity": "sha512-LR0mMT+XIYTxk4k2fIxEA1BPtW3685QlqufUEUAX1AJcfFfxNDKEvuCRZbO8ntJb10DrIFVJR9vb0MhDCi0sAQ==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-2.1.3.tgz",
+      "integrity": "sha512-ssvSMk1LX2jRhiOVgVLGfNJXdB8SvyjieKcJDHq698Gi3LOog6g/+l7ggrN+hZxyjUiDF4cUxgKaZTBUghzhLw==",
       "dependencies": {
-        "@smithy/eventstream-codec": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/eventstream-codec": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1871,34 +1915,34 @@
       }
     },
     "node_modules/@smithy/fetch-http-handler": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.4.1.tgz",
-      "integrity": "sha512-VYGLinPsFqH68lxfRhjQaSkjXM7JysUOJDTNjHBuN/ykyRb2f1gyavN9+VhhPTWCy32L4yZ2fdhpCs/nStEicg==",
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-2.4.3.tgz",
+      "integrity": "sha512-Fn/KYJFo6L5I4YPG8WQb2hOmExgRmNpVH5IK2zU3JKrY5FKW7y9ar5e0BexiIC9DhSKqKX+HeWq/Y18fq7Dkpw==",
       "dependencies": {
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/querystring-builder": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/querystring-builder": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-base64": "^2.1.1",
         "tslib": "^2.5.0"
       }
     },
     "node_modules/@smithy/hash-blob-browser": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.1.1.tgz",
-      "integrity": "sha512-jizu1+2PAUjiGIfRtlPEU8Yo6zn+d78ti/ZHDesdf1SUn2BuZW433JlPoCOLH3dBoEEvTgLvQ8tUGSoTTALA+A==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-2.1.3.tgz",
+      "integrity": "sha512-sHLTM5xQYw5Wxz07DFo+eh1PVC6P5+kazQRF1k5nsvOhZG5VnkIy4LZ7N0ZNWqJx16g9otGd5MvqUOpb3WWtgA==",
       "dependencies": {
         "@smithy/chunked-blob-reader": "^2.1.1",
         "@smithy/chunked-blob-reader-native": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       }
     },
     "node_modules/@smithy/hash-node": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.1.1.tgz",
-      "integrity": "sha512-Qhoq0N8f2OtCnvUpCf+g1vSyhYQrZjhSwvJ9qvR8BUGOtTXiyv2x1OD2e6jVGmlpC4E4ax1USHoyGfV9JFsACg==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-2.1.3.tgz",
+      "integrity": "sha512-FsAPCUj7VNJIdHbSxMd5uiZiF20G2zdSDgrgrDrHqIs/VMxK85Vqk5kMVNNDMCZmMezp6UKnac0B4nAyx7HJ9g==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-buffer-from": "^2.1.1",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
@@ -1908,11 +1952,11 @@
       }
     },
     "node_modules/@smithy/hash-stream-node": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.1.1.tgz",
-      "integrity": "sha512-VgDaKcfCy0iHcmtAZgZ3Yw9g37Gkn2JsQiMtFQXUh8Wmo3GfNgDwLOtdhJ272pOT7DStzpe9cNr+eV5Au8KfQA==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-2.1.3.tgz",
+      "integrity": "sha512-fWpUx2ca/u5lcD5RhNJogEG5FD7H0RDDpYmfQgxFqIUv3Ow7bZsapMukh8uzQPVO8R+NDAvSdxmgXoy4Hz8sFw==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
       },
@@ -1921,11 +1965,11 @@
       }
     },
     "node_modules/@smithy/invalid-dependency": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.1.1.tgz",
-      "integrity": "sha512-7WTgnKw+VPg8fxu2v9AlNOQ5yaz6RA54zOVB4f6vQuR0xFKd+RzlCpt0WidYTsye7F+FYDIaS/RnJW4pxjNInw==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-2.1.3.tgz",
+      "integrity": "sha512-wkra7d/G4CbngV4xsjYyAYOvdAhahQje/WymuQdVEnXFExJopEu7fbL5AEAlBPgWHXwu94VnCSG00gVzRfExyg==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       }
     },
@@ -1941,22 +1985,22 @@
       }
     },
     "node_modules/@smithy/md5-js": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.1.1.tgz",
-      "integrity": "sha512-L3MbIYBIdLlT+MWTYrdVSv/dow1+6iZ1Ad7xS0OHxTTs17d753ZcpOV4Ro7M7tRAVWML/sg2IAp/zzCb6aAttg==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-2.1.3.tgz",
+      "integrity": "sha512-zmn3M6+mP4IJlSmXBN9964AztgkIO8b5lRzAgdJn9AdCFwA6xLkcW2B6uEnpBjvotxtQMmXTUP19tIO7NmFPpw==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
       }
     },
     "node_modules/@smithy/middleware-content-length": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.1.1.tgz",
-      "integrity": "sha512-rSr9ezUl9qMgiJR0UVtVOGEZElMdGFyl8FzWEF5iEKTlcWxGr2wTqGfDwtH3LAB7h+FPkxqv4ZU4cpuCN9Kf/g==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-2.1.3.tgz",
+      "integrity": "sha512-aJduhkC+dcXxdnv5ZpM3uMmtGmVFKx412R1gbeykS5HXDmRU6oSsyy2SoHENCkfOGKAQOjVE2WVqDJibC0d21g==",
       "dependencies": {
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1964,16 +2008,16 @@
       }
     },
     "node_modules/@smithy/middleware-endpoint": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.1.tgz",
-      "integrity": "sha512-XPZTb1E2Oav60Ven3n2PFx+rX9EDsU/jSTA8VDamt7FXks67ekjPY/XrmmPDQaFJOTUHJNKjd8+kZxVO5Ael4Q==",
-      "dependencies": {
-        "@smithy/middleware-serde": "^2.1.1",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/url-parser": "^2.1.1",
-        "@smithy/util-middleware": "^2.1.1",
+      "version": "2.4.4",
+      "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-2.4.4.tgz",
+      "integrity": "sha512-4yjHyHK2Jul4JUDBo2sTsWY9UshYUnXeb/TAK/MTaPEb8XQvDmpwSFnfIRDU45RY1a6iC9LCnmJNg/yHyfxqkw==",
+      "dependencies": {
+        "@smithy/middleware-serde": "^2.1.3",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/shared-ini-file-loader": "^2.3.4",
+        "@smithy/types": "^2.10.1",
+        "@smithy/url-parser": "^2.1.3",
+        "@smithy/util-middleware": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -1981,17 +2025,17 @@
       }
     },
     "node_modules/@smithy/middleware-retry": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.1.1.tgz",
-      "integrity": "sha512-eMIHOBTXro6JZ+WWzZWd/8fS8ht5nS5KDQjzhNMHNRcG5FkNTqcKpYhw7TETMYzbLfhO5FYghHy1vqDWM4FLDA==",
-      "dependencies": {
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/service-error-classification": "^2.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/util-middleware": "^2.1.1",
-        "@smithy/util-retry": "^2.1.1",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-2.1.4.tgz",
+      "integrity": "sha512-Cyolv9YckZTPli1EkkaS39UklonxMd08VskiuMhURDjC0HHa/AD6aK/YoD21CHv9s0QLg0WMLvk9YeLTKkXaFQ==",
+      "dependencies": {
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/service-error-classification": "^2.1.3",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
+        "@smithy/util-middleware": "^2.1.3",
+        "@smithy/util-retry": "^2.1.3",
         "tslib": "^2.5.0",
         "uuid": "^8.3.2"
       },
@@ -2000,11 +2044,11 @@
       }
     },
     "node_modules/@smithy/middleware-serde": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.1.1.tgz",
-      "integrity": "sha512-D8Gq0aQBeE1pxf3cjWVkRr2W54t+cdM2zx78tNrVhqrDykRA7asq8yVJij1u5NDtKzKqzBSPYh7iW0svUKg76g==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-2.1.3.tgz",
+      "integrity": "sha512-s76LId+TwASrHhUa9QS4k/zeXDUAuNuddKklQzRgumbzge5BftVXHXIqL4wQxKGLocPwfgAOXWx+HdWhQk9hTg==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2012,11 +2056,11 @@
       }
     },
     "node_modules/@smithy/middleware-stack": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.1.1.tgz",
-      "integrity": "sha512-KPJhRlhsl8CjgGXK/DoDcrFGfAqoqvuwlbxy+uOO4g2Azn1dhH+GVfC3RAp+6PoL5PWPb+vt6Z23FP+Mr6qeCw==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-2.1.3.tgz",
+      "integrity": "sha512-opMFufVQgvBSld/b7mD7OOEBxF6STyraVr1xel1j0abVILM8ALJvRoFbqSWHGmaDlRGIiV9Q5cGbWi0sdiEaLQ==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2024,13 +2068,13 @@
       }
     },
     "node_modules/@smithy/node-config-provider": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.2.1.tgz",
-      "integrity": "sha512-epzK3x1xNxA9oJgHQ5nz+2j6DsJKdHfieb+YgJ7ATWxzNcB7Hc+Uya2TUck5MicOPhDV8HZImND7ZOecVr+OWg==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-2.2.4.tgz",
+      "integrity": "sha512-nqazHCp8r4KHSFhRQ+T0VEkeqvA0U+RhehBSr1gunUuNW3X7j0uDrWBxB2gE9eutzy6kE3Y7L+Dov/UXT871vg==",
       "dependencies": {
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/shared-ini-file-loader": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/shared-ini-file-loader": "^2.3.4",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2038,14 +2082,14 @@
       }
     },
     "node_modules/@smithy/node-http-handler": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.3.1.tgz",
-      "integrity": "sha512-gLA8qK2nL9J0Rk/WEZSvgin4AppvuCYRYg61dcUo/uKxvMZsMInL5I5ZdJTogOvdfVug3N2dgI5ffcUfS4S9PA==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-2.4.1.tgz",
+      "integrity": "sha512-HCkb94soYhJMxPCa61wGKgmeKpJ3Gftx1XD6bcWEB2wMV1L9/SkQu/6/ysKBnbOzWRE01FGzwrTxucHypZ8rdg==",
       "dependencies": {
-        "@smithy/abort-controller": "^2.1.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/querystring-builder": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/abort-controller": "^2.1.3",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/querystring-builder": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2053,11 +2097,11 @@
       }
     },
     "node_modules/@smithy/property-provider": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.1.1.tgz",
-      "integrity": "sha512-FX7JhhD/o5HwSwg6GLK9zxrMUrGnb3PzNBrcthqHKBc3dH0UfgEAU24xnJ8F0uow5mj17UeBEOI6o3CF2k7Mhw==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.1.3.tgz",
+      "integrity": "sha512-bMz3se+ySKWNrgm7eIiQMa2HO/0fl2D0HvLAdg9pTMcpgp4SqOAh6bz7Ik6y7uQqSrk4rLjIKgbQ6yzYgGehCQ==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2065,11 +2109,11 @@
       }
     },
     "node_modules/@smithy/protocol-http": {
-      "version": "3.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.1.1.tgz",
-      "integrity": "sha512-6ZRTSsaXuSL9++qEwH851hJjUA0OgXdQFCs+VDw4tGH256jQ3TjYY/i34N4vd24RV3nrjNsgd1yhb57uMoKbzQ==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-3.2.1.tgz",
+      "integrity": "sha512-KLrQkEw4yJCeAmAH7hctE8g9KwA7+H2nSJwxgwIxchbp/L0B5exTdOQi9D5HinPLlothoervGmhpYKelZ6AxIA==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2077,11 +2121,11 @@
       }
     },
     "node_modules/@smithy/querystring-builder": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.1.1.tgz",
-      "integrity": "sha512-C/ko/CeEa8jdYE4gt6nHO5XDrlSJ3vdCG0ZAc6nD5ZIE7LBp0jCx4qoqp7eoutBu7VrGMXERSRoPqwi1WjCPbg==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-2.1.3.tgz",
+      "integrity": "sha512-kFD3PnNqKELe6m9GRHQw/ftFFSZpnSeQD4qvgDB6BQN6hREHELSosVFUMPN4M3MDKN2jAwk35vXHLoDrNfKu0A==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-uri-escape": "^2.1.1",
         "tslib": "^2.5.0"
       },
@@ -2090,11 +2134,11 @@
       }
     },
     "node_modules/@smithy/querystring-parser": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.1.1.tgz",
-      "integrity": "sha512-H4+6jKGVhG1W4CIxfBaSsbm98lOO88tpDWmZLgkJpt8Zkk/+uG0FmmqMuCAc3HNM2ZDV+JbErxr0l5BcuIf/XQ==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-2.1.3.tgz",
+      "integrity": "sha512-3+CWJoAqcBMR+yvz6D+Fc5VdoGFtfenW6wqSWATWajrRMGVwJGPT3Vy2eb2bnMktJc4HU4bpjeovFa566P3knQ==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2102,22 +2146,22 @@
       }
     },
     "node_modules/@smithy/service-error-classification": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.1.tgz",
-      "integrity": "sha512-txEdZxPUgM1PwGvDvHzqhXisrc5LlRWYCf2yyHfvITWioAKat7srQvpjMAvgzf0t6t7j8yHrryXU9xt7RZqFpw==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.3.tgz",
+      "integrity": "sha512-iUrpSsem97bbXHHT/v3s7vaq8IIeMo6P6cXdeYHrx0wOJpMeBGQF7CB0mbJSiTm3//iq3L55JiEm8rA7CTVI8A==",
       "dependencies": {
-        "@smithy/types": "^2.9.1"
+        "@smithy/types": "^2.10.1"
       },
       "engines": {
         "node": ">=14.0.0"
       }
     },
     "node_modules/@smithy/shared-ini-file-loader": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.1.tgz",
-      "integrity": "sha512-2E2kh24igmIznHLB6H05Na4OgIEilRu0oQpYXo3LCNRrawHAcfDKq9004zJs+sAMt2X5AbY87CUCJ7IpqpSgdw==",
+      "version": "2.3.4",
+      "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-2.3.4.tgz",
+      "integrity": "sha512-CiZmPg9GeDKbKmJGEFvJBsJcFnh0AQRzOtQAzj1XEa8N/0/uSN/v1LYzgO7ry8hhO8+9KB7+DhSW0weqBra4Aw==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2125,15 +2169,15 @@
       }
     },
     "node_modules/@smithy/signature-v4": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.1.1.tgz",
-      "integrity": "sha512-Hb7xub0NHuvvQD3YwDSdanBmYukoEkhqBjqoxo+bSdC0ryV9cTfgmNjuAQhTPYB6yeU7hTR+sPRiFMlxqv6kmg==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.1.3.tgz",
+      "integrity": "sha512-Jq4iPPdCmJojZTsPePn4r1ULShh6ONkokLuxp1Lnk4Sq7r7rJp4HlA1LbPBq4bD64TIzQezIpr1X+eh5NYkNxw==",
       "dependencies": {
-        "@smithy/eventstream-codec": "^2.1.1",
+        "@smithy/eventstream-codec": "^2.1.3",
         "@smithy/is-array-buffer": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-hex-encoding": "^2.1.1",
-        "@smithy/util-middleware": "^2.1.1",
+        "@smithy/util-middleware": "^2.1.3",
         "@smithy/util-uri-escape": "^2.1.1",
         "@smithy/util-utf8": "^2.1.1",
         "tslib": "^2.5.0"
@@ -2143,15 +2187,15 @@
       }
     },
     "node_modules/@smithy/smithy-client": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.3.1.tgz",
-      "integrity": "sha512-YsTdU8xVD64r2pLEwmltrNvZV6XIAC50LN6ivDopdt+YiF/jGH6PY9zUOu0CXD/d8GMB8gbhnpPsdrjAXHS9QA==",
-      "dependencies": {
-        "@smithy/middleware-endpoint": "^2.4.1",
-        "@smithy/middleware-stack": "^2.1.1",
-        "@smithy/protocol-http": "^3.1.1",
-        "@smithy/types": "^2.9.1",
-        "@smithy/util-stream": "^2.1.1",
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-2.4.2.tgz",
+      "integrity": "sha512-ntAFYN51zu3N3mCd95YFcFi/8rmvm//uX+HnK24CRbI6k5Rjackn0JhgKz5zOx/tbNvOpgQIwhSX+1EvEsBLbA==",
+      "dependencies": {
+        "@smithy/middleware-endpoint": "^2.4.4",
+        "@smithy/middleware-stack": "^2.1.3",
+        "@smithy/protocol-http": "^3.2.1",
+        "@smithy/types": "^2.10.1",
+        "@smithy/util-stream": "^2.1.3",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2159,9 +2203,9 @@
       }
     },
     "node_modules/@smithy/types": {
-      "version": "2.9.1",
-      "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.9.1.tgz",
-      "integrity": "sha512-vjXlKNXyprDYDuJ7UW5iobdmyDm6g8dDG+BFUncAg/3XJaN45Gy5RWWWUVgrzIK7S4R1KWgIX5LeJcfvSI24bw==",
+      "version": "2.10.1",
+      "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.10.1.tgz",
+      "integrity": "sha512-hjQO+4ru4cQ58FluQvKKiyMsFg0A6iRpGm2kqdH8fniyNd2WyanoOsYJfMX/IFLuLxEoW6gnRkNZy1y6fUUhtA==",
       "dependencies": {
         "tslib": "^2.5.0"
       },
@@ -2170,12 +2214,12 @@
       }
     },
     "node_modules/@smithy/url-parser": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.1.1.tgz",
-      "integrity": "sha512-qC9Bv8f/vvFIEkHsiNrUKYNl8uKQnn4BdhXl7VzQRP774AwIjiSMMwkbT+L7Fk8W8rzYVifzJNYxv1HwvfBo3Q==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-2.1.3.tgz",
+      "integrity": "sha512-X1NRA4WzK/ihgyzTpeGvI9Wn45y8HmqF4AZ/FazwAv8V203Ex+4lXqcYI70naX9ETqbqKVzFk88W6WJJzCggTQ==",
       "dependencies": {
-        "@smithy/querystring-parser": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/querystring-parser": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       }
     },
@@ -2234,13 +2278,13 @@
       }
     },
     "node_modules/@smithy/util-defaults-mode-browser": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.1.tgz",
-      "integrity": "sha512-lqLz/9aWRO6mosnXkArtRuQqqZBhNpgI65YDpww4rVQBuUT7qzKbDLG5AmnQTCiU4rOquaZO/Kt0J7q9Uic7MA==",
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-2.1.4.tgz",
+      "integrity": "sha512-J6XAVY+/g7jf03QMnvqPyU+8jqGrrtXoKWFVOS+n1sz0Lg8HjHJ1ANqaDN+KTTKZRZlvG8nU5ZrJOUL6VdwgcQ==",
       "dependencies": {
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
         "bowser": "^2.11.0",
         "tslib": "^2.5.0"
       },
@@ -2249,16 +2293,16 @@
       }
     },
     "node_modules/@smithy/util-defaults-mode-node": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.0.tgz",
-      "integrity": "sha512-iFJp/N4EtkanFpBUtSrrIbtOIBf69KNuve03ic1afhJ9/korDxdM0c6cCH4Ehj/smI9pDCfVv+bqT3xZjF2WaA==",
-      "dependencies": {
-        "@smithy/config-resolver": "^2.1.1",
-        "@smithy/credential-provider-imds": "^2.2.1",
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/property-provider": "^2.1.1",
-        "@smithy/smithy-client": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-2.2.3.tgz",
+      "integrity": "sha512-ttUISrv1uVOjTlDa3nznX33f0pthoUlP+4grhTvOzcLhzArx8qHB94/untGACOG3nlf8vU20nI2iWImfzoLkYA==",
+      "dependencies": {
+        "@smithy/config-resolver": "^2.1.4",
+        "@smithy/credential-provider-imds": "^2.2.4",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/property-provider": "^2.1.3",
+        "@smithy/smithy-client": "^2.4.2",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2266,12 +2310,12 @@
       }
     },
     "node_modules/@smithy/util-endpoints": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.1.1.tgz",
-      "integrity": "sha512-sI4d9rjoaekSGEtq3xSb2nMjHMx8QXcz2cexnVyRWsy4yQ9z3kbDpX+7fN0jnbdOp0b3KSTZJZ2Yb92JWSanLw==",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-1.1.4.tgz",
+      "integrity": "sha512-/qAeHmK5l4yQ4/bCIJ9p49wDe9rwWtOzhPHblu386fwPNT3pxmodgcs9jDCV52yK9b4rB8o9Sj31P/7Vzka1cg==",
       "dependencies": {
-        "@smithy/node-config-provider": "^2.2.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/node-config-provider": "^2.2.4",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2290,11 +2334,11 @@
       }
     },
     "node_modules/@smithy/util-middleware": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.1.1.tgz",
-      "integrity": "sha512-mKNrk8oz5zqkNcbcgAAepeJbmfUW6ogrT2Z2gDbIUzVzNAHKJQTYmH9jcy0jbWb+m7ubrvXKb6uMjkSgAqqsFA==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.1.3.tgz",
+      "integrity": "sha512-/+2fm7AZ2ozl5h8wM++ZP0ovE9/tiUUAHIbCfGfb3Zd3+Dyk17WODPKXBeJ/TnK5U+x743QmA0xHzlSm8I/qhw==",
       "dependencies": {
-        "@smithy/types": "^2.9.1",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2302,12 +2346,12 @@
       }
     },
     "node_modules/@smithy/util-retry": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.1.1.tgz",
-      "integrity": "sha512-Mg+xxWPTeSPrthpC5WAamJ6PW4Kbo01Fm7lWM1jmGRvmrRdsd3192Gz2fBXAMURyXpaNxyZf6Hr/nQ4q70oVEA==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.1.3.tgz",
+      "integrity": "sha512-Kbvd+GEMuozbNUU3B89mb99tbufwREcyx2BOX0X2+qHjq6Gvsah8xSDDgxISDwcOHoDqUWO425F0Uc/QIRhYkg==",
       "dependencies": {
-        "@smithy/service-error-classification": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/service-error-classification": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2315,13 +2359,13 @@
       }
     },
     "node_modules/@smithy/util-stream": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.1.1.tgz",
-      "integrity": "sha512-J7SMIpUYvU4DQN55KmBtvaMc7NM3CZ2iWICdcgaovtLzseVhAqFRYqloT3mh0esrFw+3VEK6nQFteFsTqZSECQ==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-2.1.3.tgz",
+      "integrity": "sha512-HvpEQbP8raTy9n86ZfXiAkf3ezp1c3qeeO//zGqwZdrfaoOpGKQgF2Sv1IqZp7wjhna7pvczWaGUHjcOPuQwKw==",
       "dependencies": {
-        "@smithy/fetch-http-handler": "^2.4.1",
-        "@smithy/node-http-handler": "^2.3.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/fetch-http-handler": "^2.4.3",
+        "@smithy/node-http-handler": "^2.4.1",
+        "@smithy/types": "^2.10.1",
         "@smithy/util-base64": "^2.1.1",
         "@smithy/util-buffer-from": "^2.1.1",
         "@smithy/util-hex-encoding": "^2.1.1",
@@ -2356,12 +2400,12 @@
       }
     },
     "node_modules/@smithy/util-waiter": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.1.1.tgz",
-      "integrity": "sha512-kYy6BLJJNif+uqNENtJqWdXcpqo1LS+nj1AfXcDhOpqpSHJSAkVySLyZV9fkmuVO21lzGoxjvd1imGGJHph/IA==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-2.1.3.tgz",
+      "integrity": "sha512-3R0wNFAQQoH9e4m+bVLDYNOst2qNxtxFgq03WoNHWTBOqQT3jFnOBRj1W51Rf563xDA5kwqjziksxn6RKkHB+Q==",
       "dependencies": {
-        "@smithy/abort-controller": "^2.1.1",
-        "@smithy/types": "^2.9.1",
+        "@smithy/abort-controller": "^2.1.3",
+        "@smithy/types": "^2.10.1",
         "tslib": "^2.5.0"
       },
       "engines": {
@@ -2420,18 +2464,18 @@
       }
     },
     "node_modules/@types/node": {
-      "version": "18.19.17",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.17.tgz",
-      "integrity": "sha512-SzyGKgwPzuWp2SHhlpXKzCX0pIOfcI4V2eF37nNBJOhwlegQ83omtVQ1XxZpDE06V/d6AQvfQdPfnw0tRC//Ng==",
+      "version": "18.19.21",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.21.tgz",
+      "integrity": "sha512-2Q2NeB6BmiTFQi4DHBzncSoq/cJMLDdhPaAoJFnFCyD9a8VPZRf7a1GAwp1Edb7ROaZc5Jz/tnZyL6EsWMRaqw==",
       "dev": true,
       "dependencies": {
         "undici-types": "~5.26.4"
       }
     },
     "node_modules/@types/semver": {
-      "version": "7.5.7",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz",
-      "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==",
+      "version": "7.5.8",
+      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+      "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
       "dev": true
     },
     "node_modules/@types/showdown": {
@@ -2453,32 +2497,33 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
-      "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+      "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
       "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",
+        "@eslint-community/regexpp": "^4.5.1",
+        "@typescript-eslint/scope-manager": "6.21.0",
+        "@typescript-eslint/type-utils": "6.21.0",
+        "@typescript-eslint/utils": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.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"
+        "ignore": "^5.2.4",
+        "natural-compare": "^1.4.0",
+        "semver": "^7.5.4",
+        "ts-api-utils": "^1.0.1"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.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"
+        "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+        "eslint": "^7.0.0 || ^8.0.0"
       },
       "peerDependenciesMeta": {
         "typescript": {
@@ -2487,25 +2532,26 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
-      "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+      "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.62.0",
-        "@typescript-eslint/types": "5.62.0",
-        "@typescript-eslint/typescript-estree": "5.62.0",
+        "@typescript-eslint/scope-manager": "6.21.0",
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/typescript-estree": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0",
         "debug": "^4.3.4"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/typescript-eslint"
       },
       "peerDependencies": {
-        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+        "eslint": "^7.0.0 || ^8.0.0"
       },
       "peerDependenciesMeta": {
         "typescript": {
@@ -2514,16 +2560,16 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
-      "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+      "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.62.0",
-        "@typescript-eslint/visitor-keys": "5.62.0"
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
@@ -2531,25 +2577,25 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz",
-      "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+      "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "5.62.0",
-        "@typescript-eslint/utils": "5.62.0",
+        "@typescript-eslint/typescript-estree": "6.21.0",
+        "@typescript-eslint/utils": "6.21.0",
         "debug": "^4.3.4",
-        "tsutils": "^3.21.0"
+        "ts-api-utils": "^1.0.1"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/typescript-eslint"
       },
       "peerDependencies": {
-        "eslint": "*"
+        "eslint": "^7.0.0 || ^8.0.0"
       },
       "peerDependenciesMeta": {
         "typescript": {
@@ -2558,12 +2604,12 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
-      "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+      "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
       "dev": true,
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
@@ -2571,21 +2617,22 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
-      "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+      "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.62.0",
-        "@typescript-eslint/visitor-keys": "5.62.0",
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/visitor-keys": "6.21.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
-        "semver": "^7.3.7",
-        "tsutils": "^3.21.0"
+        "minimatch": "9.0.3",
+        "semver": "^7.5.4",
+        "ts-api-utils": "^1.0.1"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
@@ -2598,48 +2645,53 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
-      "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+      "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
       "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"
+        "@eslint-community/eslint-utils": "^4.4.0",
+        "@types/json-schema": "^7.0.12",
+        "@types/semver": "^7.5.0",
+        "@typescript-eslint/scope-manager": "6.21.0",
+        "@typescript-eslint/types": "6.21.0",
+        "@typescript-eslint/typescript-estree": "6.21.0",
+        "semver": "^7.5.4"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/typescript-eslint"
       },
       "peerDependencies": {
-        "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+        "eslint": "^7.0.0 || ^8.0.0"
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "5.62.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
-      "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+      "version": "6.21.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+      "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.62.0",
-        "eslint-visitor-keys": "^3.3.0"
+        "@typescript-eslint/types": "6.21.0",
+        "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
-        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+        "node": "^16.0.0 || >=18.0.0"
       },
       "funding": {
         "type": "opencollective",
         "url": "https://opencollective.com/typescript-eslint"
       }
     },
+    "node_modules/@ungap/structured-clone": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+      "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+      "dev": true
+    },
     "node_modules/@vitejs/plugin-vue": {
       "version": "5.0.4",
       "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
@@ -2654,40 +2706,40 @@
       }
     },
     "node_modules/@volar/language-core": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-1.11.1.tgz",
-      "integrity": "sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.1.0.tgz",
+      "integrity": "sha512-BrYEgYHx92ocpt1OUxJs2x3TAXEjpPLxsQoARb96g2GdF62xnfRQUqCNBwiU7Z3MQ/0tOAdqdHNYNmrFtx6q4A==",
       "dev": true,
       "dependencies": {
-        "@volar/source-map": "1.11.1"
+        "@volar/source-map": "2.1.0"
       }
     },
     "node_modules/@volar/source-map": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-1.11.1.tgz",
-      "integrity": "sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.1.0.tgz",
+      "integrity": "sha512-VPyi+DTv67cvUOkUewzsOQJY3VUhjOjQxigT487z/H7tEI8ZFd5RksC5afk3JelOK+a/3Y8LRDbKmYKu1dz87g==",
       "dev": true,
       "dependencies": {
-        "muggle-string": "^0.3.1"
+        "muggle-string": "^0.4.0"
       }
     },
     "node_modules/@volar/typescript": {
-      "version": "1.11.1",
-      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-1.11.1.tgz",
-      "integrity": "sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.1.0.tgz",
+      "integrity": "sha512-2cicVoW4q6eU/omqfOBv+6r9JdrF5bBelujbJhayPNKiOj/xwotSJ/DM8IeMvTZvtkOZkm6suyOCLEokLY0w2w==",
       "dev": true,
       "dependencies": {
-        "@volar/language-core": "1.11.1",
+        "@volar/language-core": "2.1.0",
         "path-browserify": "^1.0.1"
       }
     },
     "node_modules/@vue/compiler-core": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz",
-      "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
+      "integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
       "dependencies": {
         "@babel/parser": "^7.23.9",
-        "@vue/shared": "3.4.19",
+        "@vue/shared": "3.4.21",
         "entities": "^4.5.0",
         "estree-walker": "^2.0.2",
         "source-map-js": "^1.0.2"
@@ -2699,27 +2751,27 @@
       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
     },
     "node_modules/@vue/compiler-dom": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz",
-      "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
+      "integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
       "dependencies": {
-        "@vue/compiler-core": "3.4.19",
-        "@vue/shared": "3.4.19"
+        "@vue/compiler-core": "3.4.21",
+        "@vue/shared": "3.4.21"
       }
     },
     "node_modules/@vue/compiler-sfc": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz",
-      "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
+      "integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
       "dependencies": {
         "@babel/parser": "^7.23.9",
-        "@vue/compiler-core": "3.4.19",
-        "@vue/compiler-dom": "3.4.19",
-        "@vue/compiler-ssr": "3.4.19",
-        "@vue/shared": "3.4.19",
+        "@vue/compiler-core": "3.4.21",
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-ssr": "3.4.21",
+        "@vue/shared": "3.4.21",
         "estree-walker": "^2.0.2",
-        "magic-string": "^0.30.6",
-        "postcss": "^8.4.33",
+        "magic-string": "^0.30.7",
+        "postcss": "^8.4.35",
         "source-map-js": "^1.0.2"
       }
     },
@@ -2729,9 +2781,9 @@
       "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
     },
     "node_modules/@vue/compiler-sfc/node_modules/magic-string": {
-      "version": "0.30.7",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
-      "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
+      "version": "0.30.8",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+      "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
       "dependencies": {
         "@jridgewell/sourcemap-codec": "^1.4.15"
       },
@@ -2740,12 +2792,12 @@
       }
     },
     "node_modules/@vue/compiler-ssr": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz",
-      "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
+      "integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
       "dependencies": {
-        "@vue/compiler-dom": "3.4.19",
-        "@vue/shared": "3.4.19"
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/shared": "3.4.21"
       }
     },
     "node_modules/@vue/devtools-api": {
@@ -2754,12 +2806,12 @@
       "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA=="
     },
     "node_modules/@vue/eslint-config-prettier": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-8.0.0.tgz",
-      "integrity": "sha512-55dPqtC4PM/yBjhAr+yEw6+7KzzdkBuLmnhBrDfp4I48+wy+Giqqj9yUr5T2uD/BkBROjjmqnLZmXRdOx/VtQg==",
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/@vue/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
+      "integrity": "sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==",
       "dev": true,
       "dependencies": {
-        "eslint-config-prettier": "^8.8.0",
+        "eslint-config-prettier": "^9.0.0",
         "eslint-plugin-prettier": "^5.0.0"
       },
       "peerDependencies": {
@@ -2768,14 +2820,14 @@
       }
     },
     "node_modules/@vue/eslint-config-typescript": {
-      "version": "11.0.3",
-      "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-11.0.3.tgz",
-      "integrity": "sha512-dkt6W0PX6H/4Xuxg/BlFj5xHvksjpSlVjtkQCpaYJBIEuKj2hOVU7r+TIe+ysCwRYFz/lGqvklntRkCAibsbPw==",
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz",
+      "integrity": "sha512-StxLFet2Qe97T8+7L8pGlhYBBr8Eg05LPuTDVopQV6il+SK6qqom59BA/rcFipUef2jD8P2X44Vd8tMFytfvlg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/eslint-plugin": "^5.59.1",
-        "@typescript-eslint/parser": "^5.59.1",
-        "vue-eslint-parser": "^9.1.1"
+        "@typescript-eslint/eslint-plugin": "^6.7.0",
+        "@typescript-eslint/parser": "^6.7.0",
+        "vue-eslint-parser": "^9.3.1"
       },
       "engines": {
         "node": "^14.17.0 || >=16.0.0"
@@ -2792,18 +2844,16 @@
       }
     },
     "node_modules/@vue/language-core": {
-      "version": "1.8.27",
-      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-1.8.27.tgz",
-      "integrity": "sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.4.tgz",
+      "integrity": "sha512-IYlVEICXKRWYjRQ4JyPlXhydU/p0C7uY5LpqXyJzzJHWo44LWHZtTP3USfWNQif3VAK5QZpdZKQ5HYIeQL3BJQ==",
       "dev": true,
       "dependencies": {
-        "@volar/language-core": "~1.11.1",
-        "@volar/source-map": "~1.11.1",
-        "@vue/compiler-dom": "^3.3.0",
-        "@vue/shared": "^3.3.0",
+        "@volar/language-core": "~2.1.0",
+        "@vue/compiler-dom": "^3.4.0",
+        "@vue/shared": "^3.4.0",
         "computeds": "^0.0.1",
         "minimatch": "^9.0.3",
-        "muggle-string": "^0.3.1",
         "path-browserify": "^1.0.1",
         "vue-template-compiler": "^2.7.14"
       },
@@ -2816,73 +2866,49 @@
         }
       }
     },
-    "node_modules/@vue/language-core/node_modules/brace-expansion": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
-      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
-      "dev": true,
-      "dependencies": {
-        "balanced-match": "^1.0.0"
-      }
-    },
-    "node_modules/@vue/language-core/node_modules/minimatch": {
-      "version": "9.0.3",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
-      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
-      "dev": true,
-      "dependencies": {
-        "brace-expansion": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=16 || 14 >=14.17"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
     "node_modules/@vue/reactivity": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz",
-      "integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
+      "integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
       "dependencies": {
-        "@vue/shared": "3.4.19"
+        "@vue/shared": "3.4.21"
       }
     },
     "node_modules/@vue/runtime-core": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz",
-      "integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
+      "integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
       "dependencies": {
-        "@vue/reactivity": "3.4.19",
-        "@vue/shared": "3.4.19"
+        "@vue/reactivity": "3.4.21",
+        "@vue/shared": "3.4.21"
       }
     },
     "node_modules/@vue/runtime-dom": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz",
-      "integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
+      "integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
       "dependencies": {
-        "@vue/runtime-core": "3.4.19",
-        "@vue/shared": "3.4.19",
+        "@vue/runtime-core": "3.4.21",
+        "@vue/shared": "3.4.21",
         "csstype": "^3.1.3"
       }
     },
     "node_modules/@vue/server-renderer": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz",
-      "integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
+      "integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
       "dependencies": {
-        "@vue/compiler-ssr": "3.4.19",
-        "@vue/shared": "3.4.19"
+        "@vue/compiler-ssr": "3.4.21",
+        "@vue/shared": "3.4.21"
       },
       "peerDependencies": {
-        "vue": "3.4.19"
+        "vue": "3.4.21"
       }
     },
     "node_modules/@vue/shared": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz",
-      "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw=="
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
+      "integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g=="
     },
     "node_modules/@vue/tsconfig": {
       "version": "0.5.1",
@@ -3023,10 +3049,13 @@
       "dev": true
     },
     "node_modules/available-typed-arrays": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz",
-      "integrity": "sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/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"
       },
@@ -3086,9 +3115,9 @@
       "dev": true
     },
     "node_modules/bootstrap": {
-      "version": "5.3.2",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
-      "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
+      "version": "5.3.3",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
+      "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
       "funding": [
         {
           "type": "github",
@@ -3109,13 +3138,12 @@
       "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="
     },
     "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
       "dev": true,
       "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
+        "balanced-match": "^1.0.0"
       }
     },
     "node_modules/braces": {
@@ -3196,14 +3224,14 @@
       }
     },
     "node_modules/chart.js": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.1.tgz",
-      "integrity": "sha512-C74QN1bxwV1v2PEujhmKjOZ7iUM4w6BWs23Md/6aOZZSlwMzeCIDGuZay++rBgChYru7/+QFeoQW0fQoP534Dg==",
+      "version": "4.4.2",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
+      "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
       "dependencies": {
         "@kurkle/color": "^0.3.0"
       },
       "engines": {
-        "pnpm": ">=7"
+        "pnpm": ">=8"
       }
     },
     "node_modules/chartjs-plugin-zoom": {
@@ -3437,9 +3465,9 @@
       }
     },
     "node_modules/dompurify": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.8.tgz",
-      "integrity": "sha512-b7uwreMYL2eZhrSCRC4ahLTeZcPZxSmYfmcQGXGkXiZSNW1X85v+SDM5KsWcpivIiUBH47Ji7NtyUdpLeF5JZQ=="
+      "version": "3.0.9",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.9.tgz",
+      "integrity": "sha512-uyb4NDIvQ3hRn6NiC+SIFaP4mJ/MdXlvtunaqK9Bn6dD3RuB/1S/gasEjDHD8eiaqdSael2vBv+hOs7Y+jhYOQ=="
     },
     "node_modules/entities": {
       "version": "4.5.0",
@@ -3462,18 +3490,18 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.22.4",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
-      "integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
+      "version": "1.22.5",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz",
+      "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==",
       "dev": true,
       "dependencies": {
         "array-buffer-byte-length": "^1.0.1",
         "arraybuffer.prototype.slice": "^1.0.3",
-        "available-typed-arrays": "^1.0.6",
+        "available-typed-arrays": "^1.0.7",
         "call-bind": "^1.0.7",
         "es-define-property": "^1.0.0",
         "es-errors": "^1.3.0",
-        "es-set-tostringtag": "^2.0.2",
+        "es-set-tostringtag": "^2.0.3",
         "es-to-primitive": "^1.2.1",
         "function.prototype.name": "^1.1.6",
         "get-intrinsic": "^1.2.4",
@@ -3481,15 +3509,15 @@
         "globalthis": "^1.0.3",
         "gopd": "^1.0.1",
         "has-property-descriptors": "^1.0.2",
-        "has-proto": "^1.0.1",
+        "has-proto": "^1.0.3",
         "has-symbols": "^1.0.3",
         "hasown": "^2.0.1",
         "internal-slot": "^1.0.7",
         "is-array-buffer": "^3.0.4",
         "is-callable": "^1.2.7",
-        "is-negative-zero": "^2.0.2",
+        "is-negative-zero": "^2.0.3",
         "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.2",
+        "is-shared-array-buffer": "^1.0.3",
         "is-string": "^1.0.7",
         "is-typed-array": "^1.1.13",
         "is-weakref": "^1.0.2",
@@ -3502,10 +3530,10 @@
         "string.prototype.trim": "^1.2.8",
         "string.prototype.trimend": "^1.0.7",
         "string.prototype.trimstart": "^1.0.7",
-        "typed-array-buffer": "^1.0.1",
-        "typed-array-byte-length": "^1.0.0",
-        "typed-array-byte-offset": "^1.0.0",
-        "typed-array-length": "^1.0.4",
+        "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.5",
         "unbox-primitive": "^1.0.2",
         "which-typed-array": "^1.1.14"
       },
@@ -3538,14 +3566,14 @@
       }
     },
     "node_modules/es-set-tostringtag": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
-      "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+      "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
       "dev": true,
       "dependencies": {
-        "get-intrinsic": "^1.2.2",
-        "has-tostringtag": "^1.0.0",
-        "hasown": "^2.0.0"
+        "get-intrinsic": "^1.2.4",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.1"
       },
       "engines": {
         "node": ">= 0.4"
@@ -3620,18 +3648,19 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.48.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz",
-      "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==",
+      "version": "8.57.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+      "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.6.1",
-        "@eslint/eslintrc": "^2.1.2",
-        "@eslint/js": "8.48.0",
-        "@humanwhocodes/config-array": "^0.11.10",
+        "@eslint/eslintrc": "^2.1.4",
+        "@eslint/js": "8.57.0",
+        "@humanwhocodes/config-array": "^0.11.14",
         "@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",
@@ -3674,9 +3703,9 @@
       }
     },
     "node_modules/eslint-config-prettier": {
-      "version": "8.10.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
-      "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
+      "version": "9.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
+      "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
       "dev": true,
       "bin": {
         "eslint-config-prettier": "bin/cli.js"
@@ -3716,17 +3745,17 @@
       }
     },
     "node_modules/eslint-plugin-vue": {
-      "version": "9.19.2",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.19.2.tgz",
-      "integrity": "sha512-CPDqTOG2K4Ni2o4J5wixkLVNwgctKXFu6oBpVJlpNq7f38lh9I80pRTouZSJ2MAebPJlINU/KTFSXyQfBUlymA==",
+      "version": "9.22.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.22.0.tgz",
+      "integrity": "sha512-7wCXv5zuVnBtZE/74z4yZ0CM8AjH6bk4MQGm7hZjUC2DBppKU5ioeOk5LGSg/s9a1ZJnIsdPLJpXnu1Rc+cVHg==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
         "natural-compare": "^1.4.0",
         "nth-check": "^2.1.1",
-        "postcss-selector-parser": "^6.0.13",
-        "semver": "^7.5.4",
-        "vue-eslint-parser": "^9.3.1",
+        "postcss-selector-parser": "^6.0.15",
+        "semver": "^7.6.0",
+        "vue-eslint-parser": "^9.4.2",
         "xml-name-validator": "^4.0.0"
       },
       "engines": {
@@ -3737,16 +3766,19 @@
       }
     },
     "node_modules/eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
       "dev": true,
       "dependencies": {
         "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
+        "estraverse": "^5.2.0"
       },
       "engines": {
-        "node": ">=8.0.0"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/eslint-visitor-keys": {
@@ -3777,29 +3809,14 @@
         "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "node_modules/eslint/node_modules/eslint-scope": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
-      "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+    "node_modules/eslint/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
       "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.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
     "node_modules/eslint/node_modules/json-schema-traverse": {
@@ -3808,6 +3825,18 @@
       "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
       "dev": true
     },
+    "node_modules/eslint/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/espree": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
@@ -3837,15 +3866,6 @@
         "node": ">=0.10"
       }
     },
-    "node_modules/esquery/node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/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.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
@@ -3858,7 +3878,7 @@
         "node": ">=4.0"
       }
     },
-    "node_modules/esrecurse/node_modules/estraverse": {
+    "node_modules/estraverse": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
       "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
@@ -3867,15 +3887,6 @@
         "node": ">=4.0"
       }
     },
-    "node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
     "node_modules/estree-walker": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
@@ -3993,9 +4004,9 @@
       }
     },
     "node_modules/filesize": {
-      "version": "10.0.12",
-      "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.0.12.tgz",
-      "integrity": "sha512-6RS9gDchbn+qWmtV2uSjo5vmKizgfCQeb5jKmqx8HyzA3MoLqqyQxN+QcjkGBJt7FjJ9qFce67Auyya5rRRbpw==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/filesize/-/filesize-10.1.0.tgz",
+      "integrity": "sha512-GTLKYyBSDz3nPhlLVPjPWZCnhkd9TrrRArNcy8Z+J2cqScB7h2McAzR6NBX6nYOoWafql0roY8hrocxnZBv9CQ==",
       "engines": {
         "node": ">= 10.4.0"
       }
@@ -4043,9 +4054,9 @@
       }
     },
     "node_modules/flatted": {
-      "version": "3.2.9",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
-      "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
+      "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
       "dev": true
     },
     "node_modules/follow-redirects": {
@@ -4229,6 +4240,28 @@
         "node": ">=10.13.0"
       }
     },
+    "node_modules/glob/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/glob/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/globals": {
       "version": "13.24.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
@@ -4363,9 +4396,9 @@
       }
     },
     "node_modules/has-proto": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
-      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+      "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
       "dev": true,
       "engines": {
         "node": ">= 0.4"
@@ -4653,9 +4686,9 @@
       }
     },
     "node_modules/is-negative-zero": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
-      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+      "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
       "dev": true,
       "engines": {
         "node": ">= 0.4"
@@ -4714,12 +4747,15 @@
       }
     },
     "node_modules/is-shared-array-buffer": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
-      "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+      "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2"
+        "call-bind": "^1.0.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -4984,15 +5020,18 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "version": "9.0.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
       "dev": true,
       "dependencies": {
-        "brace-expansion": "^1.1.7"
+        "brace-expansion": "^2.0.1"
       },
       "engines": {
-        "node": "*"
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/minimist": {
@@ -5011,9 +5050,9 @@
       "dev": true
     },
     "node_modules/muggle-string": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.3.1.tgz",
-      "integrity": "sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
+      "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
       "dev": true
     },
     "node_modules/nanoid": {
@@ -5039,12 +5078,6 @@
       "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
       "dev": true
     },
-    "node_modules/natural-compare-lite": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
-      "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
-      "dev": true
-    },
     "node_modules/neo-async": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@@ -5124,6 +5157,16 @@
         "node": ">=4"
       }
     },
+    "node_modules/npm-run-all/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
     "node_modules/npm-run-all/node_modules/chalk": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
@@ -5187,6 +5230,18 @@
         "node": ">=4"
       }
     },
+    "node_modules/npm-run-all/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/npm-run-all/node_modules/path-key": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
@@ -5531,6 +5586,15 @@
         }
       }
     },
+    "node_modules/possible-typed-array-names": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/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.35",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
@@ -5909,9 +5973,9 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.66.1",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.66.1.tgz",
-      "integrity": "sha512-50c+zTsZOJVgFfTgwwEzkjA3/QACgdNsKueWPyAR0mRINIvLAStVQBbPg14iuqEQ74NPDbXzJARJ/O4SI1zftA==",
+      "version": "1.71.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz",
+      "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -5926,9 +5990,9 @@
       }
     },
     "node_modules/semver": {
-      "version": "7.5.4",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-      "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+      "version": "7.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
       "dependencies": {
         "lru-cache": "^6.0.0"
       },
@@ -5957,14 +6021,15 @@
       }
     },
     "node_modules/set-function-name": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
-      "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+      "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
       "dev": true,
       "dependencies": {
-        "define-data-property": "^1.0.1",
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
         "functions-have-names": "^1.2.3",
-        "has-property-descriptors": "^1.0.0"
+        "has-property-descriptors": "^1.0.2"
       },
       "engines": {
         "node": ">= 0.4"
@@ -6024,12 +6089,12 @@
       }
     },
     "node_modules/side-channel": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz",
-      "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==",
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+      "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "es-errors": "^1.3.0",
         "get-intrinsic": "^1.2.4",
         "object-inspect": "^1.13.1"
@@ -6286,31 +6351,22 @@
         "node": ">=8.0"
       }
     },
-    "node_modules/tslib": {
-      "version": "2.6.2",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
-      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
-    },
-    "node_modules/tsutils": {
-      "version": "3.21.0",
-      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
-      "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+    "node_modules/ts-api-utils": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
+      "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
       "dev": true,
-      "dependencies": {
-        "tslib": "^1.8.1"
-      },
       "engines": {
-        "node": ">= 6"
+        "node": ">=16"
       },
       "peerDependencies": {
-        "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+        "typescript": ">=4.2.0"
       }
     },
-    "node_modules/tsutils/node_modules/tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "dev": true
+    "node_modules/tslib": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
     },
     "node_modules/type-check": {
       "version": "0.4.0",
@@ -6337,12 +6393,12 @@
       }
     },
     "node_modules/typed-array-buffer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.1.tgz",
-      "integrity": "sha512-RSqu1UEuSlrBhHTWC8O9FnPjOduNs4M7rJ4pRKoEjtx1zUNOPN2sSXHLDX+Y2WPbHIxbvg4JFo2DNAEfPIKWoQ==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.6",
+        "call-bind": "^1.0.7",
         "es-errors": "^1.3.0",
         "is-typed-array": "^1.1.13"
       },
@@ -6351,15 +6407,16 @@
       }
     },
     "node_modules/typed-array-byte-length": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
-      "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+      "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2",
+        "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
-        "has-proto": "^1.0.1",
-        "is-typed-array": "^1.1.10"
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13"
       },
       "engines": {
         "node": ">= 0.4"
@@ -6369,16 +6426,16 @@
       }
     },
     "node_modules/typed-array-byte-offset": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz",
-      "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+      "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
       "dev": true,
       "dependencies": {
-        "available-typed-arrays": "^1.0.6",
+        "available-typed-arrays": "^1.0.7",
         "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
         "gopd": "^1.0.1",
-        "has-proto": "^1.0.1",
+        "has-proto": "^1.0.3",
         "is-typed-array": "^1.1.13"
       },
       "engines": {
@@ -6389,23 +6446,29 @@
       }
     },
     "node_modules/typed-array-length": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
-      "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz",
+      "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.2",
+        "call-bind": "^1.0.7",
         "for-each": "^0.3.3",
-        "is-typed-array": "^1.1.9"
+        "gopd": "^1.0.1",
+        "has-proto": "^1.0.3",
+        "is-typed-array": "^1.1.13",
+        "possible-typed-array-names": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/typescript": {
-      "version": "5.1.6",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
-      "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
+      "version": "5.3.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
+      "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
       "devOptional": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -6490,13 +6553,13 @@
       }
     },
     "node_modules/vite": {
-      "version": "5.0.12",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz",
-      "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==",
+      "version": "5.1.4",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz",
+      "integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==",
       "dev": true,
       "dependencies": {
         "esbuild": "^0.19.3",
-        "postcss": "^8.4.32",
+        "postcss": "^8.4.35",
         "rollup": "^4.2.0"
       },
       "bin": {
@@ -6951,15 +7014,15 @@
       }
     },
     "node_modules/vue": {
-      "version": "3.4.19",
-      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz",
-      "integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==",
+      "version": "3.4.21",
+      "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
+      "integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
       "dependencies": {
-        "@vue/compiler-dom": "3.4.19",
-        "@vue/compiler-sfc": "3.4.19",
-        "@vue/runtime-dom": "3.4.19",
-        "@vue/server-renderer": "3.4.19",
-        "@vue/shared": "3.4.19"
+        "@vue/compiler-dom": "3.4.21",
+        "@vue/compiler-sfc": "3.4.21",
+        "@vue/runtime-dom": "3.4.21",
+        "@vue/server-renderer": "3.4.21",
+        "@vue/shared": "3.4.21"
       },
       "peerDependencies": {
         "typescript": "*"
@@ -6994,31 +7057,6 @@
         "eslint": ">=6.0.0"
       }
     },
-    "node_modules/vue-eslint-parser/node_modules/eslint-scope": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/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.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
     "node_modules/vue-matomo": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/vue-matomo/-/vue-matomo-4.2.0.tgz",
@@ -7029,11 +7067,11 @@
       }
     },
     "node_modules/vue-router": {
-      "version": "4.2.5",
-      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz",
-      "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz",
+      "integrity": "sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==",
       "dependencies": {
-        "@vue/devtools-api": "^6.5.0"
+        "@vue/devtools-api": "^6.5.1"
       },
       "funding": {
         "url": "https://github.com/sponsors/posva"
@@ -7053,13 +7091,13 @@
       }
     },
     "node_modules/vue-tsc": {
-      "version": "1.8.27",
-      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-1.8.27.tgz",
-      "integrity": "sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==",
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.4.tgz",
+      "integrity": "sha512-FJk+F1QhqROr6DK8raTuWk5ezNw1/kZ+7TYhc08k+cpvb1fmi7wguPZHX0svIhT4bAxCGDtF8534It8fiAkScg==",
       "dev": true,
       "dependencies": {
-        "@volar/typescript": "~1.11.1",
-        "@vue/language-core": "1.8.27",
+        "@volar/typescript": "~2.1.0",
+        "@vue/language-core": "2.0.4",
         "semver": "^7.5.4"
       },
       "bin": {
diff --git a/package.json b/package.json
index 7d9b3d8..1a5a59c 100644
--- a/package.json
+++ b/package.json
@@ -10,10 +10,10 @@
     "build-only": "vite build",
     "type-check": "vue-tsc --noEmit",
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
-    "generate-s3-client": "openapi --input https://clowm-staging.bi.denbi.de/api/s3proxy-service/openapi.json --output src/client/s3proxy --client axios",
-    "generate-auth-client": "openapi --input https://clowm-staging.bi.denbi.de/api/auth-service/openapi.json --output src/client/auth --client axios",
-    "generate-workflow-client": "openapi --input https://clowm-staging.bi.denbi.de/api/workflow-service/openapi.json --output src/client/workflow --client axios",
-    "generate-resource-client": "openapi --input https://clowm-staging.bi.denbi.de/api/resource-service/openapi.json --output src/client/resource --client axios"
+    "generate-s3-client": "openapi --input http://localhost:9999/api/s3proxy-service/openapi.json --output src/client/s3proxy --client axios",
+    "generate-auth-client": "openapi --input http://localhost:9999/api/auth-service/openapi.json --output src/client/auth --client axios",
+    "generate-workflow-client": "openapi --input http://localhost:9999/api/workflow-service/openapi.json --output src/client/workflow --client axios",
+    "generate-resource-client": "openapi --input http://localhost:9999/api/resource-service/openapi.json --output src/client/resource --client axios"
   },
   "dependencies": {
     "@aws-sdk/client-s3": "^3.440.0",
@@ -27,21 +27,21 @@
     "chartjs-plugin-zoom": "~2.0.1",
     "dayjs": "~1.11.0",
     "dompurify": "~3.0.5",
-    "filesize": "~10.0.12",
+    "filesize": "~10.1.0",
     "idb-keyval": "^6.2.1",
     "pinia": "~2.1.0",
-    "semver": "~7.5.0",
+    "semver": "~7.6.0",
     "showdown": "~2.1.0",
     "sortablejs": "^1.15.2",
     "vue": "~3.4.0",
     "vue-matomo": "^4.2.0",
-    "vue-router": "~4.2.0",
+    "vue-router": "~4.3.0",
     "vue3-cookies": "~1.0.0"
   },
   "devDependencies": {
     "@esbuild-plugins/node-globals-polyfill": "~0.2.3",
     "@esbuild-plugins/node-modules-polyfill": "~0.2.2",
-    "@rushstack/eslint-patch": "~1.2.0",
+    "@rushstack/eslint-patch": "~1.7.0",
     "@tsconfig/node18": "^18.2.1",
     "@types/bootstrap": "~5.2.0",
     "@types/dompurify": "~3.0.0",
@@ -50,20 +50,20 @@
     "@types/showdown": "~2.0.1",
     "@types/sortablejs": "^1.15.7",
     "@vitejs/plugin-vue": "~5.0.0",
-    "@vue/eslint-config-prettier": "~8.0.0",
-    "@vue/eslint-config-typescript": "~11.0.3",
+    "@vue/eslint-config-prettier": "~9.0.0",
+    "@vue/eslint-config-typescript": "~12.0.0",
     "@vue/tsconfig": "~0.5.0",
     "axios": "~1.6.0",
-    "eslint": "~8.48.0",
-    "eslint-plugin-vue": "~9.19.0",
+    "eslint": "~8.57.0",
+    "eslint-plugin-vue": "~9.22.0",
     "highlight.js": "^11.9.0",
     "npm-run-all": "~4.1.5",
     "openapi-typescript-codegen": "^0.27.0",
     "prettier": "~3.2.0",
     "rollup-plugin-node-polyfills": "~0.2.1",
-    "sass": "~1.66.1",
-    "typescript": "~5.1.6",
-    "vite": "~5.0.0",
-    "vue-tsc": "~1.8.0"
+    "sass": "^1.66.0",
+    "typescript": "~5.3.0",
+    "vite": "~5.1.0",
+    "vue-tsc": "~2.0.0"
   }
 }
diff --git a/src/App.vue b/src/App.vue
index a2f074b..0ba8e44 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import NavbarTop from "@/components/NavbarTop.vue";
 import { onBeforeMount } from "vue";
 import { useCookies } from "vue3-cookies";
 import { useAuthStore } from "@/stores/users";
@@ -9,9 +8,10 @@ import { OpenAPI as AuthOpenAPI } from "@/client/auth";
 import { OpenAPI as WorkflowOpenAPI } from "@/client/workflow";
 import { OpenAPI as ResourceOpenAPI } from "@/client/resource";
 import { environment } from "@/environment";
-import FooterBottom from "@/components/FooterBottom.vue";
 import axios from "axios";
 import { useNameStore } from "@/stores/names";
+import AppHeader from "@/components/AppHeader.vue";
+import AppFooter from "@/components/AppFooter.vue";
 
 const { cookies } = useCookies();
 const store = useAuthStore();
@@ -98,19 +98,11 @@ onBeforeMount(() => {
 </script>
 
 <template>
-  <NavbarTop />
+  <AppHeader />
   <div class="container-xxl mt-4 flex-grow-1 py-2">
-    <div
-      id="global-toast-container"
-      class="toast-container position-fixed top-toast end-0 p-3"
-    ></div>
     <router-view></router-view>
   </div>
-  <FooterBottom />
+  <AppFooter />
 </template>
 
-<style scoped>
-.top-toast {
-  top: 4rem;
-}
-</style>
+<style scoped></style>
diff --git a/src/client/auth/services/UserService.ts b/src/client/auth/services/UserService.ts
index 0e52ed2..99bdb40 100644
--- a/src/client/auth/services/UserService.ts
+++ b/src/client/auth/services/UserService.ts
@@ -21,6 +21,7 @@ export class UserService {
             url: '/users/me',
             errors: {
                 400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
                 403: `Not Authorized`,
                 404: `Entity not Found`,
             },
@@ -53,6 +54,7 @@ export class UserService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
                 403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
@@ -84,6 +86,7 @@ export class UserService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
+                401: `Not Authenticated`,
                 403: `Not Authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
diff --git a/src/client/resource/index.ts b/src/client/resource/index.ts
index b091455..52dfc0e 100644
--- a/src/client/resource/index.ts
+++ b/src/client/resource/index.ts
@@ -8,12 +8,16 @@ export { OpenAPI } from './core/OpenAPI';
 export type { OpenAPIConfig } from './core/OpenAPI';
 
 export type { ErrorDetail } from './models/ErrorDetail';
+export { FileTree } from './models/FileTree';
 export type { HTTPValidationError } from './models/HTTPValidationError';
 export type { ResourceIn } from './models/ResourceIn';
 export type { ResourceOut } from './models/ResourceOut';
 export type { ResourceVersionIn } from './models/ResourceVersionIn';
 export type { ResourceVersionOut } from './models/ResourceVersionOut';
 export { Status } from './models/Status';
+export type { UserRequestAnswer } from './models/UserRequestAnswer';
+export type { UserSynchronizationRequestIn } from './models/UserSynchronizationRequestIn';
+export type { UserSynchronizationRequestOut } from './models/UserSynchronizationRequestOut';
 export type { ValidationError } from './models/ValidationError';
 
 export { ResourceService } from './services/ResourceService';
diff --git a/src/client/resource/models/FileTree.ts b/src/client/resource/models/FileTree.ts
new file mode 100644
index 0000000..351cd81
--- /dev/null
+++ b/src/client/resource/models/FileTree.ts
@@ -0,0 +1,19 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type FileTree = {
+    type: FileTree.type;
+    name: string;
+    target?: (string | null);
+    contents?: (Array<FileTree> | null);
+    size: number;
+};
+export namespace FileTree {
+    export enum type {
+        FILE = 'file',
+        DIRECTORY = 'directory',
+        LINK = 'link',
+    }
+}
+
diff --git a/src/client/resource/models/ResourceIn.ts b/src/client/resource/models/ResourceIn.ts
index bb3eddc..6610580 100644
--- a/src/client/resource/models/ResourceIn.ts
+++ b/src/client/resource/models/ResourceIn.ts
@@ -19,5 +19,9 @@ export type ResourceIn = {
      * A link or similar where the resource originates from
      */
     source: string;
+    /**
+     * Flag if this resource should be default visible in the UI
+     */
+    private?: boolean;
 };
 
diff --git a/src/client/resource/models/ResourceOut.ts b/src/client/resource/models/ResourceOut.ts
index dcb3455..f708c6b 100644
--- a/src/client/resource/models/ResourceOut.ts
+++ b/src/client/resource/models/ResourceOut.ts
@@ -16,6 +16,10 @@ export type ResourceOut = {
      * A link or similar where the resource originates from
      */
     source: string;
+    /**
+     * Flag if this resource should be default visible in the UI
+     */
+    private?: boolean;
     /**
      * ID of the resource
      */
diff --git a/src/client/resource/models/Status.ts b/src/client/resource/models/Status.ts
index fd3e997..e6f9517 100644
--- a/src/client/resource/models/Status.ts
+++ b/src/client/resource/models/Status.ts
@@ -7,8 +7,10 @@
  */
 export enum Status {
     RESOURCE_REQUESTED = 'RESOURCE_REQUESTED',
-    SYNC_REQUESTED = 'SYNC_REQUESTED',
+    WAIT_FOR_REVIEW = 'WAIT_FOR_REVIEW',
     DENIED = 'DENIED',
+    APPROVED = 'APPROVED',
+    SYNC_REQUESTED = 'SYNC_REQUESTED',
     SYNCHRONIZING = 'SYNCHRONIZING',
     SYNC_ERROR = 'SYNC_ERROR',
     SYNCHRONIZED = 'SYNCHRONIZED',
@@ -16,7 +18,6 @@ export enum Status {
     LATEST = 'LATEST',
     CLUSTER_DELETING = 'CLUSTER_DELETING',
     CLUSTER_DELETE_ERROR = 'CLUSTER_DELETE_ERROR',
-    CLUSTER_DELETED = 'CLUSTER_DELETED',
     S3_DELETING = 'S3_DELETING',
     S3_DELETE_ERROR = 'S3_DELETE_ERROR',
     S3_DELETED = 'S3_DELETED',
diff --git a/src/client/resource/models/UserRequestAnswer.ts b/src/client/resource/models/UserRequestAnswer.ts
new file mode 100644
index 0000000..daf61d2
--- /dev/null
+++ b/src/client/resource/models/UserRequestAnswer.ts
@@ -0,0 +1,15 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type UserRequestAnswer = {
+    /**
+     * Flag to indicate if the request was denied.
+     */
+    deny?: boolean;
+    /**
+     * Reason why the request was denied or approved. Required if request is denied.
+     */
+    reason?: (string | null);
+};
+
diff --git a/src/client/resource/models/UserSynchronizationRequestIn.ts b/src/client/resource/models/UserSynchronizationRequestIn.ts
new file mode 100644
index 0000000..702eed7
--- /dev/null
+++ b/src/client/resource/models/UserSynchronizationRequestIn.ts
@@ -0,0 +1,11 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type UserSynchronizationRequestIn = {
+    /**
+     * Reason why the request was requested.
+     */
+    reason: string;
+};
+
diff --git a/src/client/resource/models/UserSynchronizationRequestOut.ts b/src/client/resource/models/UserSynchronizationRequestOut.ts
new file mode 100644
index 0000000..7ad5039
--- /dev/null
+++ b/src/client/resource/models/UserSynchronizationRequestOut.ts
@@ -0,0 +1,23 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type UserSynchronizationRequestOut = {
+    /**
+     * Reason why the request was requested.
+     */
+    reason: string;
+    /**
+     * ID of the resource version
+     */
+    resource_version_id: string;
+    /**
+     * ID of the resource
+     */
+    resource_id: string;
+    /**
+     * ID of the user that requested this resource synchronization
+     */
+    requester_id: string;
+};
+
diff --git a/src/client/resource/services/ResourceService.ts b/src/client/resource/services/ResourceService.ts
index 2050b84..7edb063 100644
--- a/src/client/resource/services/ResourceService.ts
+++ b/src/client/resource/services/ResourceService.ts
@@ -5,6 +5,7 @@
 import type { ResourceIn } from '../models/ResourceIn';
 import type { ResourceOut } from '../models/ResourceOut';
 import type { Status } from '../models/Status';
+import type { UserSynchronizationRequestOut } from '../models/UserSynchronizationRequestOut';
 import type { CancelablePromise } from '../core/CancelablePromise';
 import { OpenAPI } from '../core/OpenAPI';
 import { request as __request } from '../core/request';
@@ -15,8 +16,9 @@ export class ResourceService {
      *
      * Permission `resource:list` required.
      * @param maintainerId Filter for resource by maintainer. If current user is the same as maintainer ID, permission `resource:list` required, otherwise `resource:list_filter`.
-     * @param versionStatus Which versions of the resource to include in the response. Permission `resource:list_filter` required, unless `maintainer_id` is provided and current user is maintainer, then only permission `resource:list` required. Default `LATEST`, `SYNCHRONIZED` and `SETTING_LATEST`.
-     * @param nameSubstring
+     * @param versionStatus Which versions of the resource to include in the response. Permission `resource:list_filter` required if None or querying for non-public resources, otherwise only permission `resource:list` required.
+     * @param nameSubstring Filter resources by a substring in their name.
+     * @param _public Filter resources to by the public flag
      * @returns ResourceOut Successful Response
      * @throws ApiError
      */
@@ -24,6 +26,7 @@ export class ResourceService {
         maintainerId?: string,
         versionStatus?: Array<Status>,
         nameSubstring?: string,
+        _public?: boolean,
     ): CancelablePromise<Array<ResourceOut>> {
         return __request(OpenAPI, {
             method: 'GET',
@@ -32,10 +35,12 @@ export class ResourceService {
                 'maintainer_id': maintainerId,
                 'version_status': versionStatus,
                 'name_substring': nameSubstring,
+                'public': _public,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -59,20 +64,41 @@ export class ResourceService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
         });
     }
+    /**
+     * List resource sync requests
+     * List all resource sync requests.
+     *
+     * Permission `resource:sync` required.
+     * @returns UserSynchronizationRequestOut Successful Response
+     * @throws ApiError
+     */
+    public static resourceListSyncRequests(): CancelablePromise<Array<UserSynchronizationRequestOut>> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/resources/sync_requests',
+            errors: {
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
+                404: `Entity not Found`,
+            },
+        });
+    }
     /**
      * Get a resource
      * Get a specific resource.
      *
      * Permission `resource:read` required.
      * @param rid
-     * @param versionStatus Which versions of the resource to include in the response. Permission `resource:read_any` required, unless the current user is the maintainer, then only permission `resource:read` required. Default `LATEST` and `SYNCHRONIZED`.
+     * @param versionStatus Which versions of the resource to include in the response. Permission `resource:read_any` required if None or querying for non-public resources, otherwise only permission `resource:read` required.
      * @returns ResourceOut Successful Response
      * @throws ApiError
      */
@@ -90,8 +116,9 @@ export class ResourceService {
                 'version_status': versionStatus,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -116,8 +143,9 @@ export class ResourceService {
                 'rid': rid,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/resource/services/ResourceVersionService.ts b/src/client/resource/services/ResourceVersionService.ts
index ced4ef7..5043026 100644
--- a/src/client/resource/services/ResourceVersionService.ts
+++ b/src/client/resource/services/ResourceVersionService.ts
@@ -2,9 +2,12 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
+import type { FileTree } from '../models/FileTree';
 import type { ResourceVersionIn } from '../models/ResourceVersionIn';
 import type { ResourceVersionOut } from '../models/ResourceVersionOut';
 import type { Status } from '../models/Status';
+import type { UserRequestAnswer } from '../models/UserRequestAnswer';
+import type { UserSynchronizationRequestIn } from '../models/UserSynchronizationRequestIn';
 import type { CancelablePromise } from '../core/CancelablePromise';
 import { OpenAPI } from '../core/OpenAPI';
 import { request as __request } from '../core/request';
@@ -15,7 +18,7 @@ export class ResourceVersionService {
      *
      * Permission 'resource:read' required.
      * @param rid
-     * @param versionStatus Which versions to include in the response. Permission `resource:read_any` required, current user is the maintainer, then only permission `resource:read` required. Default `LATEST`, `SYNCHRONIZED` and `SETTING_LATEST`.
+     * @param versionStatus Which versions of the resource to include in the response. Permission `resource:read_any` required if None or querying for non-public resources, otherwise only permission `resource:read` required.
      * @returns ResourceVersionOut Successful Response
      * @throws ApiError
      */
@@ -33,8 +36,9 @@ export class ResourceVersionService {
                 'version_status': versionStatus,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -63,8 +67,9 @@ export class ResourceVersionService {
             body: requestBody,
             mediaType: 'application/json',
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -93,8 +98,69 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * Download folder structure of resource
+     * Get the folder structure of the resources. Only available if the resource was previously downloaded to the cluster.
+     *
+     * Permission `resource:read` required.
+     * @param rvid
+     * @param rid
+     * @returns FileTree Successful Response
+     * @throws ApiError
+     */
+    public static resourceVersionResourceFileTree(
+        rvid: string,
+        rid: string,
+    ): CancelablePromise<Array<FileTree>> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/resources/{rid}/versions/{rvid}/tree',
+            path: {
+                'rvid': rvid,
+                'rid': rid,
+            },
+            errors: {
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * Request resource version review
+     * Request the review of a resource version.
+     *
+     * Permission `resource:request_review` required.
+     * @param rid
+     * @param rvid
+     * @returns ResourceVersionOut Successful Response
+     * @throws ApiError
+     */
+    public static resourceVersionRequestResourceVersionReview(
+        rid: string,
+        rvid: string,
+    ): CancelablePromise<ResourceVersionOut> {
+        return __request(OpenAPI, {
+            method: 'PUT',
+            url: '/resources/{rid}/versions/{rvid}/request_review',
+            path: {
+                'rid': rid,
+                'rvid': rvid,
+            },
+            errors: {
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -104,15 +170,17 @@ export class ResourceVersionService {
      * Request resource version synchronization
      * Request the synchronization of a resource version to the cluster.
      *
-     * Permission `resource:request_sync` required if current user is the maintainer, `resource:request_sync_any` otherwise.
+     * Permission `resource:request_sync` required.
      * @param rid
      * @param rvid
+     * @param requestBody
      * @returns ResourceVersionOut Successful Response
      * @throws ApiError
      */
     public static resourceVersionRequestResourceVersionSync(
         rid: string,
         rvid: string,
+        requestBody: UserSynchronizationRequestIn,
     ): CancelablePromise<ResourceVersionOut> {
         return __request(OpenAPI, {
             method: 'PUT',
@@ -121,38 +189,46 @@ export class ResourceVersionService {
                 'rid': rid,
                 'rvid': rvid,
             },
+            body: requestBody,
+            mediaType: 'application/json',
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
         });
     }
     /**
-     * Deny synchronization request to cluster
-     * Deny the synchronization request of the resource version to the cluster.
+     * Review resource version
+     * Review answer the resource version.
      *
-     * Permission `resource:sync` required.
+     * Permission `resource:review` required.
      * @param rid
      * @param rvid
+     * @param requestBody
      * @returns ResourceVersionOut Successful Response
      * @throws ApiError
      */
-    public static resourceVersionResourceVersionSyncDeny(
+    public static resourceVersionResourceVersionReview(
         rid: string,
         rvid: string,
+        requestBody: UserRequestAnswer,
     ): CancelablePromise<ResourceVersionOut> {
         return __request(OpenAPI, {
             method: 'PUT',
-            url: '/resources/{rid}/versions/{rvid}/deny',
+            url: '/resources/{rid}/versions/{rvid}/review',
             path: {
                 'rid': rid,
                 'rvid': rvid,
             },
+            body: requestBody,
+            mediaType: 'application/json',
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -162,15 +238,17 @@ export class ResourceVersionService {
      * Synchronize resource version with cluster
      * Synchronize the resource version to the cluster.
      *
-     * Permission `resource:sync` required and `resource:sync_denied` if the status is `DENIED`.
+     * Permission `resource:sync` required.
      * @param rid
      * @param rvid
+     * @param requestBody
      * @returns ResourceVersionOut Successful Response
      * @throws ApiError
      */
     public static resourceVersionResourceVersionSync(
         rid: string,
         rvid: string,
+        requestBody: UserRequestAnswer,
     ): CancelablePromise<ResourceVersionOut> {
         return __request(OpenAPI, {
             method: 'PUT',
@@ -179,9 +257,12 @@ export class ResourceVersionService {
                 'rid': rid,
                 'rvid': rvid,
             },
+            body: requestBody,
+            mediaType: 'application/json',
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -209,8 +290,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -238,8 +320,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -267,8 +350,9 @@ export class ResourceVersionService {
                 'rvid': rvid,
             },
             errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                400: `Error in request parameters`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/s3proxy/services/BucketPermissionService.ts b/src/client/s3proxy/services/BucketPermissionService.ts
index 57eae34..cc7df4b 100644
--- a/src/client/s3proxy/services/BucketPermissionService.ts
+++ b/src/client/s3proxy/services/BucketPermissionService.ts
@@ -34,7 +34,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -59,7 +60,8 @@ export class BucketPermissionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -94,7 +96,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -129,7 +132,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -161,7 +165,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -193,7 +198,8 @@ export class BucketPermissionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -226,7 +232,8 @@ export class BucketPermissionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/s3proxy/services/BucketService.ts b/src/client/s3proxy/services/BucketService.ts
index 2f78147..5f73fa5 100644
--- a/src/client/s3proxy/services/BucketService.ts
+++ b/src/client/s3proxy/services/BucketService.ts
@@ -33,7 +33,8 @@ export class BucketService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -62,7 +63,8 @@ export class BucketService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -89,7 +91,8 @@ export class BucketService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -121,7 +124,8 @@ export class BucketService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/s3proxy/services/S3KeyService.ts b/src/client/s3proxy/services/S3KeyService.ts
index e8f3135..1d08223 100644
--- a/src/client/s3proxy/services/S3KeyService.ts
+++ b/src/client/s3proxy/services/S3KeyService.ts
@@ -27,7 +27,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -53,7 +54,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -82,7 +84,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -111,7 +114,8 @@ export class S3KeyService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/index.ts b/src/client/workflow/index.ts
index 6d265a3..b7f6660 100644
--- a/src/client/workflow/index.ts
+++ b/src/client/workflow/index.ts
@@ -14,6 +14,10 @@ export { DocumentationEnum } from './models/DocumentationEnum';
 export type { ErrorDetail } from './models/ErrorDetail';
 export type { HTTPValidationError } from './models/HTTPValidationError';
 export type { IconUpdateOut } from './models/IconUpdateOut';
+export type { ParameterExtension_Input } from './models/ParameterExtension_Input';
+export type { ParameterExtension_Output } from './models/ParameterExtension_Output';
+export type { ResourcePath_Input } from './models/ResourcePath_Input';
+export type { ResourcePath_Output } from './models/ResourcePath_Output';
 export { Status } from './models/Status';
 export type { ValidationError } from './models/ValidationError';
 export type { WorkflowCredentialsIn } from './models/WorkflowCredentialsIn';
diff --git a/src/client/workflow/models/ParameterExtension_Input.ts b/src/client/workflow/models/ParameterExtension_Input.ts
new file mode 100644
index 0000000..a9b61ae
--- /dev/null
+++ b/src/client/workflow/models/ParameterExtension_Input.ts
@@ -0,0 +1,16 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { ResourcePath_Input } from './ResourcePath_Input';
+export type ParameterExtension_Input = {
+    /**
+     * The inner dictionary contains the display name as key and the parameter value as value. The outer dictionary has the parameter name as key.
+     */
+    mapping?: Record<string, Record<string, (ResourcePath_Input | string | number)>>;
+    /**
+     * Dictionary with parameter name as key and default value as value
+     */
+    defaults?: Record<string, (ResourcePath_Input | string | number | boolean)>;
+};
+
diff --git a/src/client/workflow/models/ParameterExtension_Output.ts b/src/client/workflow/models/ParameterExtension_Output.ts
new file mode 100644
index 0000000..da3a66e
--- /dev/null
+++ b/src/client/workflow/models/ParameterExtension_Output.ts
@@ -0,0 +1,16 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { ResourcePath_Output } from './ResourcePath_Output';
+export type ParameterExtension_Output = {
+    /**
+     * The inner dictionary contains the display name as key and the parameter value as value. The outer dictionary has the parameter name as key.
+     */
+    mapping?: Record<string, Record<string, (ResourcePath_Output | string | number)>>;
+    /**
+     * Dictionary with parameter name as key and default value as value
+     */
+    defaults?: Record<string, (ResourcePath_Output | string | number | boolean)>;
+};
+
diff --git a/src/client/workflow/models/ResourcePath_Input.ts b/src/client/workflow/models/ResourcePath_Input.ts
new file mode 100644
index 0000000..c42ec4e
--- /dev/null
+++ b/src/client/workflow/models/ResourcePath_Input.ts
@@ -0,0 +1,16 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type ResourcePath_Input = {
+    /**
+     * ID of the resource version
+     */
+    resource_version_id: string;
+    /**
+     * ID of the resource
+     */
+    resource_id: string;
+    suffix?: (string | null);
+};
+
diff --git a/src/client/workflow/models/ResourcePath_Output.ts b/src/client/workflow/models/ResourcePath_Output.ts
new file mode 100644
index 0000000..e985b79
--- /dev/null
+++ b/src/client/workflow/models/ResourcePath_Output.ts
@@ -0,0 +1,16 @@
+/* generated using openapi-typescript-codegen -- do no edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type ResourcePath_Output = {
+    /**
+     * ID of the resource version
+     */
+    resource_version_id: string;
+    /**
+     * ID of the resource
+     */
+    resource_id: string;
+    suffix?: (string | null);
+};
+
diff --git a/src/client/workflow/models/WorkflowOut.ts b/src/client/workflow/models/WorkflowOut.ts
index 79bc468..90fbae3 100644
--- a/src/client/workflow/models/WorkflowOut.ts
+++ b/src/client/workflow/models/WorkflowOut.ts
@@ -27,7 +27,7 @@ export type WorkflowOut = {
     /**
      * ID of developer of the workflow
      */
-    developer_id?: (string | null);
+    developer_id: string;
     /**
      * Flag if the workflow is hosted in a private git repository
      */
diff --git a/src/client/workflow/models/WorkflowVersion.ts b/src/client/workflow/models/WorkflowVersion.ts
index f8bc153..5f2f0d1 100644
--- a/src/client/workflow/models/WorkflowVersion.ts
+++ b/src/client/workflow/models/WorkflowVersion.ts
@@ -2,6 +2,7 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
+import type { ParameterExtension_Output } from './ParameterExtension_Output';
 import type { Status } from './Status';
 export type WorkflowVersion = {
     /**
@@ -32,5 +33,9 @@ export type WorkflowVersion = {
      * Optional modes his workflow version has
      */
     modes?: Array<string>;
+    /**
+     * Parameter extension specific for this CloWM instance
+     */
+    parameter_extension?: (ParameterExtension_Output | null);
 };
 
diff --git a/src/client/workflow/services/WorkflowCredentialsService.ts b/src/client/workflow/services/WorkflowCredentialsService.ts
index 749fb5e..6e664ec 100644
--- a/src/client/workflow/services/WorkflowCredentialsService.ts
+++ b/src/client/workflow/services/WorkflowCredentialsService.ts
@@ -28,7 +28,8 @@ export class WorkflowCredentialsService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -58,7 +59,8 @@ export class WorkflowCredentialsService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -84,7 +86,8 @@ export class WorkflowCredentialsService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowExecutionService.ts b/src/client/workflow/services/WorkflowExecutionService.ts
index 3e07b04..1b785be 100644
--- a/src/client/workflow/services/WorkflowExecutionService.ts
+++ b/src/client/workflow/services/WorkflowExecutionService.ts
@@ -30,7 +30,8 @@ export class WorkflowExecutionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -63,7 +64,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -92,7 +94,8 @@ export class WorkflowExecutionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -119,7 +122,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -146,7 +150,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -173,7 +178,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -200,7 +206,8 @@ export class WorkflowExecutionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowModeService.ts b/src/client/workflow/services/WorkflowModeService.ts
index 2a3eb2a..c6f1174 100644
--- a/src/client/workflow/services/WorkflowModeService.ts
+++ b/src/client/workflow/services/WorkflowModeService.ts
@@ -27,7 +27,8 @@ export class WorkflowModeService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowService.ts b/src/client/workflow/services/WorkflowService.ts
index 3e68041..dbed2cf 100644
--- a/src/client/workflow/services/WorkflowService.ts
+++ b/src/client/workflow/services/WorkflowService.ts
@@ -3,16 +3,12 @@
 /* tslint:disable */
 /* eslint-disable */
 import type { AnonymizedWorkflowExecution } from '../models/AnonymizedWorkflowExecution';
-import type { Body_Workflow_Version_upload_workflow_version_icon } from '../models/Body_Workflow_Version_upload_workflow_version_icon';
-import type { DocumentationEnum } from '../models/DocumentationEnum';
-import type { IconUpdateOut } from '../models/IconUpdateOut';
 import type { Status } from '../models/Status';
 import type { WorkflowIn } from '../models/WorkflowIn';
 import type { WorkflowOut } from '../models/WorkflowOut';
 import type { WorkflowStatistic } from '../models/WorkflowStatistic';
 import type { WorkflowUpdate } from '../models/WorkflowUpdate';
 import type { WorkflowVersion } from '../models/WorkflowVersion';
-import type { WorkflowVersionStatus } from '../models/WorkflowVersionStatus';
 import type { CancelablePromise } from '../core/CancelablePromise';
 import { OpenAPI } from '../core/OpenAPI';
 import { request as __request } from '../core/request';
@@ -43,7 +39,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -72,7 +69,8 @@ export class WorkflowService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -108,7 +106,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -139,7 +138,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -165,7 +165,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -191,7 +192,8 @@ export class WorkflowService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -221,231 +223,8 @@ export class WorkflowService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Get all versions of a workflow
-     * List all versions of a Workflow.
-     *
-     * Permission `workflow:list` required.
-     * @param wid ID of a workflow
-     * @param versionStatus Which versions of the workflow to include in the response. Permission `workflow:list_filter` required if you are not the developer of this workflow. Default `PUBLISHED` and `DEPRECATED`
-     * @returns WorkflowVersion Successful Response
-     * @throws ApiError
-     */
-    public static workflowVersionListWorkflowVersion(
-        wid: string,
-        versionStatus?: Array<Status>,
-    ): CancelablePromise<Array<WorkflowVersion>> {
-        return __request(OpenAPI, {
-            method: 'GET',
-            url: '/workflows/{wid}/versions',
-            path: {
-                'wid': wid,
-            },
-            query: {
-                'version_status': versionStatus,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Get a workflow version
-     * Get a specific version of a workflow.
-     *
-     * Permission `workflow:read` required if the version is public or you are the developer of the workflow,
-     * otherwise `workflow:read_any`
-     * @param gitCommitHash Git commit `git_commit_hash` of specific version or `latest`.
-     * @param wid ID of a workflow
-     * @returns WorkflowVersion Successful Response
-     * @throws ApiError
-     */
-    public static workflowVersionGetWorkflowVersion(
-        gitCommitHash: string,
-        wid: string,
-    ): CancelablePromise<WorkflowVersion> {
-        return __request(OpenAPI, {
-            method: 'GET',
-            url: '/workflows/{wid}/versions/{git_commit_hash}',
-            path: {
-                'git_commit_hash': gitCommitHash,
-                'wid': wid,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Update status of workflow version
-     * Update the status of a workflow version.
-     *
-     * Permission `workflow:update_status`
-     * @param gitCommitHash Git commit git_commit_hash of specific version.
-     * @param wid ID of a workflow
-     * @param requestBody
-     * @returns WorkflowVersion Successful Response
-     * @throws ApiError
-     */
-    public static workflowVersionUpdateWorkflowVersionStatus(
-        gitCommitHash: string,
-        wid: string,
-        requestBody: WorkflowVersionStatus,
-    ): CancelablePromise<WorkflowVersion> {
-        return __request(OpenAPI, {
-            method: 'PATCH',
-            url: '/workflows/{wid}/versions/{git_commit_hash}/status',
-            path: {
-                'git_commit_hash': gitCommitHash,
-                'wid': wid,
-            },
-            body: requestBody,
-            mediaType: 'application/json',
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Deprecate a workflow version
-     * Deprecate a workflow version.
-     *
-     * Permission `workflow:update` required if you are the developer of the workflow,
-     * otherwise `workflow:read_status`
-     * @param wid ID of a workflow
-     * @param gitCommitHash Git commit git_commit_hash of specific version.
-     * @returns WorkflowVersion Successful Response
-     * @throws ApiError
-     */
-    public static workflowVersionDeprecateWorkflowVersion(
-        wid: string,
-        gitCommitHash: string,
-    ): CancelablePromise<WorkflowVersion> {
-        return __request(OpenAPI, {
-            method: 'POST',
-            url: '/workflows/{wid}/versions/{git_commit_hash}/deprecate',
-            path: {
-                'wid': wid,
-                'git_commit_hash': gitCommitHash,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Fetch documentation for a workflow version
-     * Get the documentation for a specific workflow version.
-     * Streams the response directly from the right git repository.
-     *
-     * Permission `workflow:read` required.
-     * @param wid ID of a workflow
-     * @param gitCommitHash Git commit git_commit_hash of specific version.
-     * @param document Specify which type of documentation the client wants to fetch
-     * @param modeId Workflow Mode
-     * @returns any Successful Response
-     * @throws ApiError
-     */
-    public static workflowVersionDownloadWorkflowDocumentation(
-        wid: string,
-        gitCommitHash: string,
-        document?: DocumentationEnum,
-        modeId?: string,
-    ): CancelablePromise<any> {
-        return __request(OpenAPI, {
-            method: 'GET',
-            url: '/workflows/{wid}/versions/{git_commit_hash}/documentation',
-            path: {
-                'wid': wid,
-                'git_commit_hash': gitCommitHash,
-            },
-            query: {
-                'document': document,
-                'mode_id': modeId,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Upload icon for workflow version
-     * Upload an icon for the workflow version and returns the new icon URL.
-     *
-     * Permission `workflow:update` required.
-     * @param wid ID of a workflow
-     * @param gitCommitHash Git commit git_commit_hash of specific version.
-     * @param formData
-     * @returns IconUpdateOut Successful Response
-     * @throws ApiError
-     */
-    public static workflowVersionUploadWorkflowVersionIcon(
-        wid: string,
-        gitCommitHash: string,
-        formData: Body_Workflow_Version_upload_workflow_version_icon,
-    ): CancelablePromise<IconUpdateOut> {
-        return __request(OpenAPI, {
-            method: 'POST',
-            url: '/workflows/{wid}/versions/{git_commit_hash}/icon',
-            path: {
-                'wid': wid,
-                'git_commit_hash': gitCommitHash,
-            },
-            formData: formData,
-            mediaType: 'multipart/form-data',
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
-                404: `Entity not Found`,
-                422: `Validation Error`,
-            },
-        });
-    }
-    /**
-     * Delete icon of workflow version
-     * Delete the icon of the workflow version.
-     *
-     * Permission `workflow:update` required.
-     * @param wid ID of a workflow
-     * @param gitCommitHash Git commit git_commit_hash of specific version.
-     * @returns void
-     * @throws ApiError
-     */
-    public static workflowVersionDeleteWorkflowVersionIcon(
-        wid: string,
-        gitCommitHash: string,
-    ): CancelablePromise<void> {
-        return __request(OpenAPI, {
-            method: 'DELETE',
-            url: '/workflows/{wid}/versions/{git_commit_hash}/icon',
-            path: {
-                'wid': wid,
-                'git_commit_hash': gitCommitHash,
-            },
-            errors: {
-                400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/client/workflow/services/WorkflowVersionService.ts b/src/client/workflow/services/WorkflowVersionService.ts
index ce08361..ca8d357 100644
--- a/src/client/workflow/services/WorkflowVersionService.ts
+++ b/src/client/workflow/services/WorkflowVersionService.ts
@@ -5,6 +5,7 @@
 import type { Body_Workflow_Version_upload_workflow_version_icon } from '../models/Body_Workflow_Version_upload_workflow_version_icon';
 import type { DocumentationEnum } from '../models/DocumentationEnum';
 import type { IconUpdateOut } from '../models/IconUpdateOut';
+import type { ParameterExtension_Input } from '../models/ParameterExtension_Input';
 import type { Status } from '../models/Status';
 import type { WorkflowVersion } from '../models/WorkflowVersion';
 import type { WorkflowVersionStatus } from '../models/WorkflowVersionStatus';
@@ -37,7 +38,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -67,7 +69,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -100,7 +103,8 @@ export class WorkflowVersionService {
             mediaType: 'application/json',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -122,7 +126,7 @@ export class WorkflowVersionService {
         gitCommitHash: string,
     ): CancelablePromise<WorkflowVersion> {
         return __request(OpenAPI, {
-            method: 'POST',
+            method: 'PATCH',
             url: '/workflows/{wid}/versions/{git_commit_hash}/deprecate',
             path: {
                 'wid': wid,
@@ -130,7 +134,43 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
+                404: `Entity not Found`,
+                422: `Validation Error`,
+            },
+        });
+    }
+    /**
+     * Deprecate a workflow version
+     * Update the parameter extension of a workflow version.
+     *
+     *
+     * Permission `workflow:update` required.
+     * @param wid ID of a workflow
+     * @param gitCommitHash Git commit git_commit_hash of specific version.
+     * @param requestBody
+     * @returns WorkflowVersion Successful Response
+     * @throws ApiError
+     */
+    public static workflowVersionUpdateWorkflowVersionParameterExtension(
+        wid: string,
+        gitCommitHash: string,
+        requestBody: ParameterExtension_Input,
+    ): CancelablePromise<WorkflowVersion> {
+        return __request(OpenAPI, {
+            method: 'PATCH',
+            url: '/workflows/{wid}/versions/{git_commit_hash}/parameter-extension',
+            path: {
+                'wid': wid,
+                'git_commit_hash': gitCommitHash,
+            },
+            body: requestBody,
+            mediaType: 'application/json',
+            errors: {
+                400: `Error decoding JWT Token`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -168,7 +208,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -201,7 +242,8 @@ export class WorkflowVersionService {
             mediaType: 'multipart/form-data',
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
@@ -230,7 +272,8 @@ export class WorkflowVersionService {
             },
             errors: {
                 400: `Error decoding JWT Token`,
-                403: `Not authenticated`,
+                401: `Not authenticated`,
+                403: `Not authorized`,
                 404: `Entity not Found`,
                 422: `Validation Error`,
             },
diff --git a/src/components/FooterBottom.vue b/src/components/AppFooter.vue
similarity index 100%
rename from src/components/FooterBottom.vue
rename to src/components/AppFooter.vue
diff --git a/src/components/NavbarTop.vue b/src/components/AppHeader.vue
similarity index 98%
rename from src/components/NavbarTop.vue
rename to src/components/AppHeader.vue
index 4a85939..254d218 100644
--- a/src/components/NavbarTop.vue
+++ b/src/components/AppHeader.vue
@@ -216,8 +216,6 @@ watch(
                   >Users
                 </router-link>
               </li>
-              <li><a class="dropdown-item disabled" href="#">Bucket</a></li>
-              <li><a class="dropdown-item disabled" href="#">Workflow</a></li>
               <li>
                 <router-link
                   class="dropdown-item"
@@ -225,6 +223,13 @@ watch(
                   >Resources
                 </router-link>
               </li>
+              <li>
+                <router-link
+                  class="dropdown-item"
+                  :to="{ name: 'admin-sync-requests' }"
+                  >Resources Synchronization
+                </router-link>
+              </li>
             </ul>
           </li>
         </ul>
diff --git a/src/components/BootstrapToast.vue b/src/components/BootstrapToast.vue
index e664cae..000cdda 100644
--- a/src/components/BootstrapToast.vue
+++ b/src/components/BootstrapToast.vue
@@ -1,9 +1,21 @@
 <script setup lang="ts">
-import { useSlots, computed } from "vue";
+import { useSlots, computed, type PropType } from "vue";
+
+type colors =
+  | "primary"
+  | "secondary"
+  | "success"
+  | "warning"
+  | "danger"
+  | "info";
 
 const slots = useSlots();
 const props = defineProps({
-  colorClass: { type: String, required: false, default: "success" },
+  colorClass: {
+    type: String as PropType<colors>,
+    required: false,
+    default: "success",
+  },
   toastId: { type: String, required: true },
 });
 
diff --git a/src/components/CopyToClipboardIcon.vue b/src/components/CopyToClipboardIcon.vue
index 6e85078..6b9f65d 100644
--- a/src/components/CopyToClipboardIcon.vue
+++ b/src/components/CopyToClipboardIcon.vue
@@ -45,7 +45,11 @@ onMounted(() => {
     color-class="danger"
     >Can't copy to clipboard
   </bootstrap-toast>
-  <button v-if="props.button" @click="copyToClipboard" class="btn btn-primary">
+  <button
+    v-if="props.button"
+    @click="copyToClipboard"
+    class="btn btn-primary btn-sm"
+  >
     Copy to Clipboard
     <font-awesome-icon icon="fa-solid fa-clipboard" class="ms-1" />
   </button>
diff --git a/src/components/modals/BootstrapModal.vue b/src/components/modals/BootstrapModal.vue
index a6652b3..63806ef 100644
--- a/src/components/modals/BootstrapModal.vue
+++ b/src/components/modals/BootstrapModal.vue
@@ -43,7 +43,7 @@ function trackModalShow() {
       :class="[modalSizeClass]"
     >
       <div class="modal-content">
-        <div class="modal-header">
+        <div class="modal-header justify-content-between">
           <div class="modal-title fs-5" :id="modalLabel">
             <slot name="header" />
           </div>
diff --git a/src/components/modals/ReasonModal.vue b/src/components/modals/ReasonModal.vue
new file mode 100644
index 0000000..561c27a
--- /dev/null
+++ b/src/components/modals/ReasonModal.vue
@@ -0,0 +1,84 @@
+<script setup lang="ts">
+import BootstrapModal from "@/components/modals/BootstrapModal.vue";
+import { reactive, ref } from "vue";
+
+type reasonfor = "request" | "rejection";
+
+const props = defineProps<{
+  modalId: string;
+  modalLabel: string;
+  loading: boolean;
+  purpose: reasonfor;
+}>();
+
+const formState = reactive<{
+  reason: string;
+  validated: boolean;
+}>({
+  reason: "",
+  validated: false,
+});
+
+const reasonForm = ref<HTMLFormElement | undefined>(undefined);
+const randomIDSuffix = Math.random().toString(16).substring(2, 8);
+
+const emit = defineEmits<{
+  (e: "save", reason: string): void;
+}>();
+
+function sendSaveEvent() {
+  formState.validated = true;
+  formState.reason = formState.reason.trim();
+  if (reasonForm.value?.checkValidity()) {
+    emit("save", formState.reason);
+  }
+}
+</script>
+
+<template>
+  <bootstrap-modal
+    :modal-id="props.modalId"
+    :modal-label="props.modalLabel"
+    size-modifier="lg"
+  >
+    <template #header>
+      <slot name="header" />
+    </template>
+    <template #body>
+      <form
+        :id="'reason-modal-form-' + randomIDSuffix"
+        ref="reasonForm"
+        :class="{ 'was-validated': formState.validated }"
+      >
+        <label :for="'reason-modal-input-' + randomIDSuffix" class="form-label"
+          >Reason for {{ props.purpose }}</label
+        >
+        <textarea
+          class="form-control"
+          :id="'reason-modal-input-' + randomIDSuffix"
+          rows="3"
+          minlength="16"
+          maxlength="512"
+          :placeholder="'State your reason for the ' + props.purpose"
+          v-model="formState.reason"
+        ></textarea>
+      </form>
+    </template>
+    <template #footer>
+      <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
+        Close
+      </button>
+      <button
+        type="submit"
+        :form="'reason-modal-form-' + randomIDSuffix"
+        class="btn btn-primary"
+        :disabled="formState.reason.length < 1 || props.loading"
+        @click.prevent="sendSaveEvent"
+      >
+        Save
+      </button>
+    </template>
+  </bootstrap-modal>
+</template>
+
+<style scoped></style>
diff --git a/src/components/parameter-schema/ParameterSchemaFormComponent.vue b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
index b7947f7..3a77eaf 100644
--- a/src/components/parameter-schema/ParameterSchemaFormComponent.vue
+++ b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
@@ -437,7 +437,7 @@ onMounted(() => {
             :checked="props.viewMode === 'simple'"
             @click="
               router.replace({
-                query: { viewMode: 'simple' },
+                query: { ...route.query, viewMode: 'simple' },
                 hash: route.hash,
               })
             "
@@ -454,7 +454,7 @@ onMounted(() => {
             :checked="props.viewMode === 'advanced'"
             @click="
               router.replace({
-                query: { viewMode: 'advanced' },
+                query: { ...route.query, viewMode: 'advanced' },
                 hash: route.hash,
               })
             "
@@ -471,7 +471,7 @@ onMounted(() => {
             :checked="props.viewMode === 'expert'"
             @click="
               router.replace({
-                query: { viewMode: 'expert' },
+                query: { ...route.query, viewMode: 'expert' },
                 hash: route.hash,
               })
             "
diff --git a/src/components/resources/RequestReviewButton.vue b/src/components/resources/RequestReviewButton.vue
new file mode 100644
index 0000000..fa7599d
--- /dev/null
+++ b/src/components/resources/RequestReviewButton.vue
@@ -0,0 +1,44 @@
+<script setup lang="ts">
+import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
+import { onMounted } from "vue";
+import { Tooltip } from "bootstrap";
+
+const props = defineProps<{
+  disabled?: boolean;
+}>();
+
+const emit = defineEmits<{
+  (e: "click-review"): void;
+  (e: "click-refresh"): void;
+}>();
+const randomIDSuffix = Math.random().toString(16).substring(2, 8);
+
+onMounted(() => {
+  new Tooltip("#refresh-s3-" + randomIDSuffix);
+});
+</script>
+
+<template>
+  <div class="btn-group" role="group">
+    <button
+      type="button"
+      class="btn btn-primary"
+      :disabled="props.disabled"
+      @click="emit('click-review')"
+    >
+      Request Review
+    </button>
+    <button
+      :id="'refresh-s3-' + randomIDSuffix"
+      type="button"
+      class="btn btn-primary"
+      @click="emit('click-refresh')"
+      data-bs-toggle="tooltip"
+      data-bs-title="Check if uploaded resource is ready"
+    >
+      <font-awesome-icon icon="fa-solid fa-arrow-rotate-right" />
+    </button>
+  </div>
+</template>
+
+<style scoped></style>
diff --git a/src/components/resources/ResourceCard.vue b/src/components/resources/ResourceCard.vue
index d96ef21..1f7292e 100644
--- a/src/components/resources/ResourceCard.vue
+++ b/src/components/resources/ResourceCard.vue
@@ -12,6 +12,7 @@ import { useS3ObjectStore } from "@/stores/s3objects";
 import { useResourceStore } from "@/stores/resources";
 import { Tooltip } from "bootstrap";
 import { useNameStore } from "@/stores/names";
+import RequestReviewButton from "@/components/resources/RequestReviewButton.vue";
 
 const randomIDSuffix: string = Math.random().toString(16).substring(2, 8);
 const objectRepository = useS3ObjectStore();
@@ -26,25 +27,27 @@ const props = defineProps<{
 let refreshTimeout: NodeJS.Timeout | undefined = undefined;
 
 const stateToUIMapping: Record<Status, string> = {
+  APPROVED: "Resource approved",
+  WAIT_FOR_REVIEW: "Wait for review",
   CLUSTER_DELETE_ERROR: "Error deleting resource on cluster",
   CLUSTER_DELETING: "Resource deletion on cluster in progress",
   S3_DELETE_ERROR: "Error deleting tarball in S3",
   S3_DELETING: "Tarball deletion in S3 in progress",
   SETTING_LATEST: "Resource available",
   SYNC_ERROR: "Error syncing to cluster",
-  CLUSTER_DELETED: "Resource deleted on cluster",
   DENIED: "Resource creation rejected by reviewer",
   RESOURCE_REQUESTED: "Resource creation requested",
   S3_DELETED: "Tarball deleted in S3",
   SYNCHRONIZED: "Resource available",
   SYNCHRONIZING: "Synchronizing to cluster in progress",
-  SYNC_REQUESTED: "Wait for reviewer approval",
+  SYNC_REQUESTED: "Synchronization to cluster requested",
   LATEST: "Resource available (latest)",
 };
 
 const emit = defineEmits<{
   (e: "click-info", resourceVersion: ResourceVersionOut): void;
   (e: "click-update", resource: ResourceOut): void;
+  (e: "click-request-sync", resourceVersion: ResourceVersionOut): void;
 }>();
 
 const resourceVersionS3Ready = ref<Record<string, boolean>>({});
@@ -75,12 +78,16 @@ function clickCheckS3Resource(resourceVersion: ResourceVersionOut) {
   }, 500);
 }
 
-function requestSynchronization(resourceVersion: ResourceVersionOut) {
-  resourceRepository.requestSynchronization(resourceVersion);
+function requestReview(resourceVersion: ResourceVersionOut) {
+  resourceRepository.requestReview(resourceVersion);
 }
 
 onMounted(() => {
   if (!props.loading) {
+    new Tooltip("#resource-name-" + props.resource.resource_id);
+    if (props.resource.private) {
+      new Tooltip("#resource-private-icon-" + props.resource.resource_id);
+    }
     for (const r of props.resource.versions) {
       if (r.status == Status.RESOURCE_REQUESTED) {
         checkS3Resource(r);
@@ -92,7 +99,7 @@ onMounted(() => {
       ...(document
         .querySelector("#resource-card-" + randomIDSuffix)
         ?.querySelectorAll("[data-bs-toggle='tooltip']") ?? []),
-    ].map((el) => new Tooltip(el));
+    ].forEach((el) => new Tooltip(el));
   }
 });
 </script>
@@ -109,8 +116,21 @@ onMounted(() => {
         <div v-if="props.loading" class="placeholder-glow w-100">
           <span class="placeholder col-6"></span>
         </div>
-        <div v-else>
-          <span>{{ props.resource.name }}</span>
+        <div v-else class="d-inline-flex align-items-center text-truncate">
+          <span
+            :id="'resource-name-' + props.resource.resource_id"
+            data-bs-toggle="tooltip"
+            :data-bs-title="props.resource.name"
+            >{{ props.resource.name }}</span
+          >
+          <font-awesome-icon
+            v-if="props.resource.private"
+            :id="'resource-private-icon-' + props.resource.resource_id"
+            icon="fa-solid fa-lock"
+            class="fs-5 ms-2 tooltip-private-repository"
+            data-bs-toggle="tooltip"
+            data-bs-title="Private resource"
+          />
         </div>
         <button
           v-if="props.extended"
@@ -179,60 +199,58 @@ onMounted(() => {
               }"
               :data-bs-parent="'#accordion-' + props.resource.resource_id"
             >
-              <div class="accordion-body">
+              <div class="accordion-body d-flex flex-column">
                 <div>
                   Registered at:
                   {{
                     dayjs.unix(resourceVersion.created_at).format("DD MMM YYYY")
                   }}
                 </div>
+                <div
+                  v-if="resourceVersion.status == Status.APPROVED"
+                  class="d-grid gap-2"
+                >
+                  <button
+                    type="button"
+                    class="btn btn-primary"
+                    @click="emit('click-request-sync', resourceVersion)"
+                    data-bs-toggle="modal"
+                    data-bs-target="#request-synchronization-modal"
+                  >
+                    Request synchronization
+                  </button>
+                </div>
                 <div
                   v-if="
                     props.extended &&
-                    (resourceVersion.status == Status.RESOURCE_REQUESTED ||
-                      resourceVersion.status == Status.CLUSTER_DELETED)
+                    resourceVersion.status == Status.RESOURCE_REQUESTED
                   "
+                  class="d-flex justify-content-between align-items-center"
                 >
-                  <div class="btn-group" role="group">
-                    <button
-                      type="button"
-                      class="btn btn-primary"
-                      data-bs-toggle="modal"
-                      data-bs-target="#uploadResourceInfoModal"
-                      @click="emit('click-info', resourceVersion)"
-                    >
-                      <font-awesome-icon icon="fa-solid fa-circle-question" />
-                    </button>
-                    <button
-                      type="button"
-                      class="btn btn-primary"
-                      :disabled="
-                        !resourceVersionS3Ready[
-                          resourceVersion.resource_version_id
-                        ]
-                      "
-                      @click="requestSynchronization(resourceVersion)"
-                    >
-                      Request Synchronization
-                    </button>
-                    <button
-                      v-if="resourceVersion.status == Status.RESOURCE_REQUESTED"
-                      type="button"
-                      class="btn btn-primary"
-                      @click="clickCheckS3Resource(resourceVersion)"
-                    >
-                      <font-awesome-icon
-                        icon="fa-solid fa-arrow-rotate-right"
-                      />
-                    </button>
-                  </div>
+                  <request-review-button
+                    :disabled="
+                      !resourceVersionS3Ready[
+                        resourceVersion.resource_version_id
+                      ]
+                    "
+                    @click-refresh="clickCheckS3Resource(resourceVersion)"
+                    @click-review="requestReview(resourceVersion)"
+                  />
+                  <button
+                    type="button"
+                    class="btn btn-info btn-sm"
+                    data-bs-toggle="modal"
+                    data-bs-target="#uploadResourceInfoModal"
+                    @click="emit('click-info', resourceVersion)"
+                  >
+                    What to do next?
+                  </button>
                 </div>
                 <div
                   v-if="
                     resourceVersion.status === Status.SYNCHRONIZED ||
                     resourceVersion.status === Status.LATEST
                   "
-                  class="my-1"
                 >
                   <label
                     :for="
@@ -242,7 +260,7 @@ onMounted(() => {
                     class="form-label"
                     >Nextflow Access Path:</label
                   >
-                  <div class="input-group fs-4 mb-3">
+                  <div class="input-group fs-4">
                     <div
                       class="input-group-text hover-info"
                       :id="
@@ -274,9 +292,8 @@ onMounted(() => {
                 <div
                   v-if="
                     props.extended &&
-                    resourceVersion.status !== Status.S3_DELETED
+                    resourceVersion.status === Status.RESOURCE_REQUESTED
                   "
-                  class="my-1"
                 >
                   <label
                     :for="
@@ -340,4 +357,8 @@ onMounted(() => {
   transform: translate(0, -5px);
   box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
 }
+
+.accordion-body > div:not(:last-child) {
+  margin-bottom: 0.5rem !important;
+}
 </style>
diff --git a/src/components/resources/modals/CreateResourceModal.vue b/src/components/resources/modals/CreateResourceModal.vue
index cdb044b..8087bec 100644
--- a/src/components/resources/modals/CreateResourceModal.vue
+++ b/src/components/resources/modals/CreateResourceModal.vue
@@ -17,6 +17,7 @@ const resource = reactive<ResourceIn>({
   description: "",
   release: "",
   source: "",
+  private: true,
 });
 
 const formState = reactive<{
@@ -51,6 +52,7 @@ function createResource() {
         resource.description = "";
         resource.source = "";
         resource.release = "";
+        resource.private = true;
         formState.resourceNameTaken = false;
         formState.validated = false;
       })
@@ -82,6 +84,7 @@ onMounted(() => {
   createResourceModal = new Modal("#" + props.modalId);
   new Tooltip("#tooltip-new-resource-source");
   new Tooltip("#tooltip-new-resource-release");
+  new Tooltip("#tooltip-new-resource-private");
 });
 </script>
 
@@ -201,6 +204,28 @@ onMounted(() => {
             </div>
           </div>
         </div>
+        <div class="mb-3">
+          <div class="form-check fs-5">
+            <input
+              class="form-check-input"
+              type="checkbox"
+              v-model="resource.private"
+              id="resourcePrivateInput"
+              :true-value="false"
+              :false-value="true"
+            />
+            <label
+              class="form-check-label"
+              for="resourcePrivateInput"
+              id="tooltip-new-resource-private"
+              data-bs-toggle="tooltip"
+              data-bs-placement="bottom"
+              data-bs-title="Flag if the resource should should be used by other workflow developer"
+            >
+              Public Resource
+            </label>
+          </div>
+        </div>
       </form>
     </template>
     <template v-slot:footer>
diff --git a/src/components/resources/ResourceVersionInfoModal.vue b/src/components/resources/modals/ResourceVersionInfoModal.vue
similarity index 99%
rename from src/components/resources/ResourceVersionInfoModal.vue
rename to src/components/resources/modals/ResourceVersionInfoModal.vue
index 1fb0e2f..ce39b06 100644
--- a/src/components/resources/ResourceVersionInfoModal.vue
+++ b/src/components/resources/modals/ResourceVersionInfoModal.vue
@@ -237,7 +237,7 @@ const resourceVersion = computed<ResourceVersionOut | undefined>(
           /></span>
         </div>
       </div>
-      <div class="mb-3">
+      <div class="mb-3" v-if="resourceVersion?.cluster_path">
         <label
           for="resource-version-info-modal-resource-version-cluster-path"
           class="form-label"
diff --git a/src/components/resources/modals/UploadResourceInfoModal.vue b/src/components/resources/modals/UploadResourceInfoModal.vue
index f25e179..3b33bd3 100644
--- a/src/components/resources/modals/UploadResourceInfoModal.vue
+++ b/src/components/resources/modals/UploadResourceInfoModal.vue
@@ -10,6 +10,7 @@ import { useS3ObjectStore } from "@/stores/s3objects";
 import { useResourceStore } from "@/stores/resources";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { Modal } from "bootstrap";
+import RequestReviewButton from "@/components/resources/RequestReviewButton.vue";
 
 const props = defineProps<{
   modalId: string;
@@ -33,7 +34,7 @@ watch(
   () => props.resourceVersion,
   (newVersion, oldVersion) => {
     if (newVersion?.resource_version_id !== oldVersion?.resource_version_id) {
-      resourceSynchronizationEnabled.value = false;
+      resourceReviewEnabled.value = false;
       if (newVersion?.status === Status.RESOURCE_REQUESTED) {
         checkS3Resource(newVersion);
       }
@@ -42,7 +43,7 @@ watch(
 );
 
 const activeTool = ref<Tool>(Tool.S5CMD);
-const resourceSynchronizationEnabled = ref<boolean>(false);
+const resourceReviewEnabled = ref<boolean>(false);
 
 const resourceS3Path = computed<string>(() => {
   return (
@@ -107,10 +108,10 @@ function checkS3Resource(resourceVersion: ResourceVersionOut) {
   objectRepository
     .fetchS3ObjectMeta(bucket, key)
     .then(() => {
-      resourceSynchronizationEnabled.value = true;
+      resourceReviewEnabled.value = true;
     })
     .catch(() => {
-      resourceSynchronizationEnabled.value = false;
+      resourceReviewEnabled.value = false;
     });
 }
 
@@ -121,8 +122,8 @@ function clickCheckS3Resource(resourceVersion: ResourceVersionOut) {
   }, 500);
 }
 
-function requestSynchronization(resourceVersion: ResourceVersionOut) {
-  resourceRepository.requestSynchronization(resourceVersion).then(() => {
+function requestReview(resourceVersion: ResourceVersionOut) {
+  resourceRepository.requestReview(resourceVersion).then(() => {
     infoResourceModal?.hide();
   });
 }
@@ -160,12 +161,13 @@ onMounted(() => {
           </p>
         </li>
         <li
+          class="pb-2"
           :class="{
-            'text-decoration-line-through': resourceSynchronizationEnabled,
+            'text-decoration-line-through': resourceReviewEnabled,
           }"
         >
           <h6>Upload the resource</h6>
-          <template v-if="!resourceSynchronizationEnabled">
+          <template v-if="!resourceReviewEnabled">
             <p>
               Upload the tar archive to the provided S3 path with a tool of your
               choice.
@@ -298,48 +300,45 @@ s3 = boto3.resource(
               />
             </b>
           </template>
+          <copy-to-clipboard-icon
+            v-if="props.resourceVersion && !resourceReviewEnabled"
+            button
+            :text="codeExample"
+          />
         </li>
         <li>
-          <h6>Request synchronization</h6>
+          <h6>Request review</h6>
           <p>
-            Click <b>Request Synchronization</b> to request the synchronization
-            to CloWM's compute cluster.
+            Click <b>Request Review</b> to request a review of the resource.
+          </p>
+          <request-review-button
+            v-if="props.resourceVersion?.status === Status.RESOURCE_REQUESTED"
+            class="mb-2"
+            :disabled="!resourceReviewEnabled"
+            @click-review="requestReview(props.resourceVersion)"
+            @click-refresh="clickCheckS3Resource(props.resourceVersion)"
+          />
+        </li>
+        <li>
+          <h6>Request resource synchronization</h6>
+          <p>
+            Once a Reviewer approves your resource, the resource will be
+            publicly visible in CloWM. To use it in during a workflow execution,
+            you can request the synchronization of the resource to the cluster.
           </p>
-          <div class="btn-group mb-2" role="group" v-if="props.resourceVersion">
-            <button
-              type="button"
-              class="btn btn-primary"
-              :disabled="!resourceSynchronizationEnabled"
-              @click="requestSynchronization(props.resourceVersion)"
-            >
-              Request Synchronization
-            </button>
-            <button
-              v-if="props.resourceVersion.status === Status.RESOURCE_REQUESTED"
-              type="button"
-              class="btn btn-primary"
-              @click="clickCheckS3Resource(props.resourceVersion)"
-            >
-              <font-awesome-icon icon="fa-solid fa-arrow-rotate-right" />
-            </button>
-          </div>
         </li>
         <li>
           <h6>Resource availability</h6>
           <p>
-            Once a Reviewer approves your resource synchronization request, the
-            resource will be made available in CloWM and is accessible for every
-            workflow via its <b>Nextflow Access Path</b>.
+            When an administrator approves the synchronization request and the
+            resource is download to the cluster, the resource will now available
+            for a workflow execution and is accessible for every workflow via
+            its <b>Nextflow Access Path</b>.
           </p>
         </li>
       </ol>
     </template>
     <template #footer>
-      <copy-to-clipboard-icon
-        v-if="props.resourceVersion && !resourceSynchronizationEnabled"
-        button
-        :text="codeExample"
-      />
       <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
         Close
       </button>
diff --git a/src/components/workflows/WorkflowWithVersionsCard.vue b/src/components/workflows/WorkflowWithVersionsCard.vue
index a9a63de..1afe153 100644
--- a/src/components/workflows/WorkflowWithVersionsCard.vue
+++ b/src/components/workflows/WorkflowWithVersionsCard.vue
@@ -114,16 +114,16 @@ onMounted(() => {
         <div v-if="props.loading" class="placeholder-glow w-100">
           <span class="placeholder col-6"></span>
         </div>
-        <div v-else class="text-truncate">
+        <div v-else class="text-truncate d-inline-flex align-items-center">
+          <span>{{ props.workflow.name }}</span>
           <font-awesome-icon
             v-if="props.workflow.private"
             icon="fa-solid fa-lock"
-            class="fs-5 me-2 tooltip-private-repository"
+            class="fs-5 ms-2 tooltip-private-repository"
             :id="'tooltip-' + randomIDSuffix"
             data-bs-toggle="tooltip"
-            data-bs-title="Private Git Repository"
+            data-bs-title="Private Git repository"
           />
-          <span>{{ props.workflow.name }}</span>
         </div>
         <div class="btn-group">
           <button
@@ -139,6 +139,7 @@ onMounted(() => {
           <button
             type="button"
             class="btn btn-success dropdown-toggle dropdown-toggle-split"
+            style="filter: brightness(85%)"
             data-bs-toggle="dropdown"
             aria-expanded="false"
           >
@@ -217,7 +218,7 @@ onMounted(() => {
                 <th scope="col">Updated at</th>
                 <th scope="col" class="text-align-center">Usage</th>
                 <th scope="col" class="text-align-center">Icon</th>
-                <th scope="col">Link</th>
+                <th scope="col"></th>
               </tr>
             </thead>
             <tbody class="table-group-divider">
@@ -286,31 +287,45 @@ onMounted(() => {
                     data-bs-toggle="modal"
                     data-bs-target="#updateWorkflowVersionIconModal"
                   />
+                </td>
+                <td class="text-end">
                   <font-awesome-icon
-                    v-else
-                    icon="fa-solid fa-circle-plus"
-                    class="add-icon-hover cursor-pointer"
-                    @click="emit('workflow-update-icon-click', version)"
-                    data-bs-toggle="modal"
-                    data-bs-target="#updateWorkflowVersionIconModal"
+                    icon="fa-solid fa-bars"
+                    data-bs-toggle="dropdown"
+                    aria-expanded="false"
+                    class="cursor-pointer p-1"
                   />
-                </td>
-                <td>
-                  <router-link
-                    class="w-fit mx-0"
-                    :to="{
-                      name: 'workflow-version',
-                      params: {
-                        workflowId: props.workflow.workflow_id,
-                        versionId: version.workflow_version_id,
-                      },
-                      query: {
-                        workflowModeId: version.modes?.[0] ?? undefined,
-                        developerView: 'true',
-                      },
-                    }"
-                    >View
-                  </router-link>
+                  <ul class="dropdown-menu dropdown-menu-end">
+                    <li>
+                      <router-link
+                        class="dropdown-item"
+                        :to="{
+                          name: 'workflow-version',
+                          params: {
+                            workflowId: props.workflow.workflow_id,
+                            versionId: version.workflow_version_id,
+                          },
+                          query: {
+                            workflowModeId: version.modes?.[0] ?? undefined,
+                            developerView: 'true',
+                          },
+                        }"
+                        >View
+                      </router-link>
+                    </li>
+                    <li>
+                      <a
+                        class="dropdown-item"
+                        href="#"
+                        data-bs-toggle="modal"
+                        data-bs-target="#updateWorkflowVersionIconModal"
+                        @click.prevent="
+                          emit('workflow-update-icon-click', version)
+                        "
+                        >Update icon</a
+                      >
+                    </li>
+                  </ul>
                 </td>
               </tr>
               <tr>
diff --git a/src/router/adminRoutes.ts b/src/router/adminRoutes.ts
index 4015a57..00093a7 100644
--- a/src/router/adminRoutes.ts
+++ b/src/router/adminRoutes.ts
@@ -19,4 +19,13 @@ export const adminRoutes: RouteRecordRaw[] = [
       title: "Manage Users",
     },
   },
+  {
+    path: "admin/sync-requests",
+    name: "admin-sync-requests",
+    component: () => import("../views/admin/AdminSyncRequestsView.vue"),
+    meta: {
+      requiresAdminRole: true,
+      title: "Sync Requests",
+    },
+  },
 ];
diff --git a/src/router/index.ts b/src/router/index.ts
index 53a4e46..7c4188f 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -5,6 +5,9 @@ import { workflowRoutes } from "@/router/workflowRoutes";
 import { s3Routes } from "@/router/s3Routes";
 import { resourceRoutes } from "@/router/resourceRoutes";
 import { adminRoutes } from "@/router/adminRoutes";
+import ImprintView from "@/views/ImprintView.vue";
+import PrivacyPolicyView from "@/views/PrivacyPolicyView.vue";
+import TermsOfUsageView from "@/views/TermsOfUsageView.vue";
 
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
@@ -44,7 +47,7 @@ const router = createRouter({
       meta: {
         title: "Privacy Policy",
       },
-      component: import("../views/PrivacyPolicyView.vue"),
+      component: PrivacyPolicyView,
     },
     {
       path: "/terms",
@@ -52,7 +55,7 @@ const router = createRouter({
       meta: {
         title: "Terms of Usage",
       },
-      component: import("../views/TermsOfUsageView.vue"),
+      component: TermsOfUsageView,
     },
     {
       path: "/imprint",
@@ -60,7 +63,7 @@ const router = createRouter({
       meta: {
         title: "Imprint",
       },
-      component: import("../views/ImprintView.vue"),
+      component: ImprintView,
     },
     {
       path: "/:pathMatch(.*)",
diff --git a/src/stores/resources.ts b/src/stores/resources.ts
index e0377b4..9cf7688 100644
--- a/src/stores/resources.ts
+++ b/src/stores/resources.ts
@@ -4,6 +4,9 @@ import type {
   ResourceOut,
   ResourceVersionIn,
   ResourceVersionOut,
+  UserRequestAnswer,
+  UserSynchronizationRequestIn,
+  UserSynchronizationRequestOut,
 } from "@/client/resource";
 import {
   ResourceService,
@@ -20,10 +23,14 @@ export const useResourceStore = defineStore({
       resourceMapping: {},
       ownResourceMapping: {},
       reviewableResourceMapping: {},
+      syncRequestMapping: {},
+      __syncRequestsFetched: false,
     }) as {
       resourceMapping: Record<string, ResourceOut>;
       ownResourceMapping: Record<string, ResourceOut>;
       reviewableResourceMapping: Record<string, ResourceOut>;
+      syncRequestMapping: Record<string, UserSynchronizationRequestOut>;
+      __syncRequestsFetched: boolean;
     },
   getters: {
     resources(): ResourceOut[] {
@@ -35,6 +42,9 @@ export const useResourceStore = defineStore({
     reviewableResources(): ResourceOut[] {
       return Object.values(this.reviewableResourceMapping);
     },
+    syncRequests(): UserSynchronizationRequestOut[] {
+      return Object.values(this.syncRequestMapping);
+    },
   },
   actions: {
     fetchResource(
@@ -56,15 +66,35 @@ export const useResourceStore = defineStore({
         return resource;
       });
     },
+    fetchSyncRequests(
+      onFinally?: () => void,
+    ): Promise<UserSynchronizationRequestOut[]> {
+      if (this.__syncRequestsFetched) {
+        onFinally?.();
+      }
+      return ResourceService.resourceListSyncRequests()
+        .then((requests) => {
+          this.__syncRequestsFetched = true;
+          const newMapping: Record<string, UserSynchronizationRequestOut> = {};
+          for (const request of requests) {
+            newMapping[request.resource_version_id] = request;
+          }
+          this.syncRequestMapping = newMapping;
+          return requests;
+        })
+        .finally(onFinally);
+    },
     fetchResources(
       maintainerId?: string,
       versionStatus?: Status[],
       searchString?: string,
+      _public?: boolean,
     ): Promise<ResourceOut[]> {
       return ResourceService.resourceListResources(
         maintainerId,
         versionStatus,
         searchString,
+        _public,
       ).then((resources) => {
         const nameStore = useNameStore();
         for (const resource of resources) {
@@ -83,10 +113,7 @@ export const useResourceStore = defineStore({
       if (Object.keys(this.reviewableResourceMapping).length > 0) {
         onFinally?.();
       }
-      return this.fetchResources(undefined, [
-        Status.SYNC_REQUESTED,
-        Status.SYNCHRONIZING,
-      ])
+      return this.fetchResources(undefined, [Status.WAIT_FOR_REVIEW])
         .then((resources) => {
           const newMapping: Record<string, ResourceOut> = {};
           for (const resource of resources) {
@@ -101,7 +128,16 @@ export const useResourceStore = defineStore({
       if (this.resources.length > 0) {
         onFinally?.();
       }
-      return this.fetchResources()
+      return this.fetchResources(undefined, [
+        Status.APPROVED,
+        Status.SYNC_REQUESTED,
+        Status.SYNCHRONIZING,
+        Status.SYNC_ERROR,
+        Status.SYNCHRONIZED,
+        Status.SETTING_LATEST,
+        Status.LATEST,
+        Status.CLUSTER_DELETE_ERROR,
+      ])
         .then((resources) => {
           const newMapping: Record<string, ResourceOut> = {};
           for (const resource of resources) {
@@ -119,7 +155,7 @@ export const useResourceStore = defineStore({
       if (this.ownResourceMapping[resource_id]) {
         onFinally?.();
       }
-      return this.fetchResource(resource_id, Object.values(Status))
+      return this.fetchResource(resource_id)
         .then((resource) => {
           this.ownResourceMapping[resource.resource_id] = resource;
           return resource;
@@ -131,7 +167,7 @@ export const useResourceStore = defineStore({
       if (this.ownResources.length > 0) {
         onFinally?.();
       }
-      return this.fetchResources(authStore.currentUID, Object.values(Status))
+      return this.fetchResources(authStore.currentUID)
         .then((resources) => {
           const newMapping: Record<string, ResourceOut> = {};
           for (const resource of resources) {
@@ -160,10 +196,50 @@ export const useResourceStore = defineStore({
     },
     requestSynchronization(
       resourceVersion: ResourceVersionOut,
+      request: UserSynchronizationRequestIn,
     ): Promise<ResourceVersionOut> {
       return ResourceVersionService.resourceVersionRequestResourceVersionSync(
         resourceVersion.resource_id,
         resourceVersion.resource_version_id,
+        request,
+      )
+        .then((changedResourceVersion) => {
+          const versionIndex = this.resourceMapping[
+            changedResourceVersion.resource_id
+          ]?.versions?.findIndex(
+            (version) =>
+              version.resource_version_id ==
+              changedResourceVersion.resource_version_id,
+          );
+          if (versionIndex != undefined && versionIndex > -1) {
+            this.resourceMapping[changedResourceVersion.resource_id].versions[
+              versionIndex
+            ] = changedResourceVersion;
+          }
+          return changedResourceVersion;
+        })
+        .then((changedResourceVersion) => {
+          const versionIndex = this.ownResourceMapping[
+            changedResourceVersion.resource_id
+          ]?.versions?.findIndex(
+            (version) =>
+              version.resource_version_id ==
+              changedResourceVersion.resource_version_id,
+          );
+          if (versionIndex != undefined && versionIndex > -1) {
+            this.ownResourceMapping[
+              changedResourceVersion.resource_id
+            ].versions[versionIndex] = changedResourceVersion;
+          }
+          return changedResourceVersion;
+        });
+    },
+    requestReview(
+      resourceVersion: ResourceVersionOut,
+    ): Promise<ResourceVersionOut> {
+      return ResourceVersionService.resourceVersionRequestResourceVersionReview(
+        resourceVersion.resource_id,
+        resourceVersion.resource_version_id,
       ).then((changedResourceVersion) => {
         if (
           this.ownResourceMapping[changedResourceVersion.resource_id] ==
@@ -213,21 +289,28 @@ export const useResourceStore = defineStore({
         return versionOut;
       });
     },
-    syncResource(
+    reviewResource(
       resourceVersion: ResourceVersionOut,
+      requestAnswer: UserRequestAnswer,
     ): Promise<ResourceVersionOut> {
-      return ResourceVersionService.resourceVersionResourceVersionSync(
+      return ResourceVersionService.resourceVersionResourceVersionReview(
         resourceVersion.resource_id,
         resourceVersion.resource_version_id,
+        requestAnswer,
       ).then(this._updateReviewableResourceVersion);
     },
-    denyResource(
+    syncResource(
       resourceVersion: ResourceVersionOut,
+      requestAnswer: UserRequestAnswer,
     ): Promise<ResourceVersionOut> {
-      return ResourceVersionService.resourceVersionResourceVersionSyncDeny(
+      return ResourceVersionService.resourceVersionResourceVersionSync(
         resourceVersion.resource_id,
         resourceVersion.resource_version_id,
-      ).then(this._updateReviewableResourceVersion);
+        requestAnswer,
+      ).then((version) => {
+        delete this.syncRequestMapping[version.resource_version_id];
+        return version;
+      });
     },
     _updateReviewableResourceVersion(
       version: ResourceVersionOut,
diff --git a/src/stores/users.ts b/src/stores/users.ts
index 0bd5dde..016203d 100644
--- a/src/stores/users.ts
+++ b/src/stores/users.ts
@@ -20,12 +20,6 @@ type DecodedToken = {
   sub: string;
 };
 
-export type RootState = {
-  token: string | null;
-  decodedToken: DecodedToken | null;
-  user: User | null;
-};
-
 function parseJwt(token: string): DecodedToken {
   const base64Url = token.split(".")[1];
   const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
@@ -49,7 +43,11 @@ export const useAuthStore = defineStore({
       token: null,
       decodedToken: null,
       user: null,
-    }) as RootState,
+    }) as {
+      token: string | null;
+      decodedToken: DecodedToken | null;
+      user: User | null;
+    },
   getters: {
     roles(): string[] {
       return (
@@ -60,7 +58,7 @@ export const useAuthStore = defineStore({
     },
     authenticated: (state) => state.token != null,
     currentUID(): string {
-      return this.decodedToken?.["sub"] ?? "";
+      return this.user?.uid ?? this.decodedToken?.["sub"] ?? "";
     },
     foreignUser: (state) =>
       state.user?.roles?.includes(RoleEnum.FOREIGN_USER) ??
diff --git a/src/views/ImprintView.vue b/src/views/ImprintView.vue
index 8e4188c..4ea27c7 100644
--- a/src/views/ImprintView.vue
+++ b/src/views/ImprintView.vue
@@ -1,8 +1,10 @@
 <script setup lang="ts"></script>
 
 <template>
-  <h2>Impressum</h2>
-  <p>TBD</p>
+  <div>
+    <h2>Impressum</h2>
+    <p>TBD</p>
+  </div>
 </template>
 
 <style scoped></style>
diff --git a/src/views/PrivacyPolicyView.vue b/src/views/PrivacyPolicyView.vue
index 3656b66..d6d98a1 100644
--- a/src/views/PrivacyPolicyView.vue
+++ b/src/views/PrivacyPolicyView.vue
@@ -1,8 +1,10 @@
 <script setup lang="ts"></script>
 
 <template>
-  <h2>Privacy Policy</h2>
-  <p>TBD</p>
+  <div>
+    <h2>Privacy Policy</h2>
+    <p>TBD</p>
+  </div>
 </template>
 
 <style scoped></style>
diff --git a/src/views/TermsOfUsageView.vue b/src/views/TermsOfUsageView.vue
index 21503d7..5d6374d 100644
--- a/src/views/TermsOfUsageView.vue
+++ b/src/views/TermsOfUsageView.vue
@@ -1,8 +1,10 @@
 <script setup lang="ts"></script>
 
 <template>
-  <h2>Terms of Usage</h2>
-  <p>TBD</p>
+  <div>
+    <h2>Terms of Usage</h2>
+    <p>TBD</p>
+  </div>
 </template>
 
 <style scoped></style>
diff --git a/src/views/admin/AdminResourcesView.vue b/src/views/admin/AdminResourcesView.vue
index 9528652..409ae18 100644
--- a/src/views/admin/AdminResourcesView.vue
+++ b/src/views/admin/AdminResourcesView.vue
@@ -11,7 +11,7 @@ import type { User } from "@/client/auth";
 import { useNameStore } from "@/stores/names";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import dayjs from "dayjs";
-import ResourceVersionInfoModal from "@/components/resources/ResourceVersionInfoModal.vue";
+import ResourceVersionInfoModal from "@/components/resources/modals/ResourceVersionInfoModal.vue";
 
 const resourceRepository = useResourceStore();
 const nameRepository = useNameStore();
@@ -110,17 +110,7 @@ function deleteInS3(resourceVersion: ResourceVersionOut) {
 function syncToCluster(resourceVersion: ResourceVersionOut) {
   resourceState.loading = true;
   resourceRepository
-    .syncResource(resourceVersion)
-    .then(replaceResourceVersion)
-    .finally(() => {
-      resourceState.loading = false;
-    });
-}
-
-function denyResource(resourceVersion: ResourceVersionOut) {
-  resourceState.loading = true;
-  resourceRepository
-    .denyResource(resourceVersion)
+    .syncResource(resourceVersion, { deny: false })
     .then(replaceResourceVersion)
     .finally(() => {
       resourceState.loading = false;
@@ -313,11 +303,26 @@ function resetForm() {
                             Set to Latest
                           </button>
                         </li>
+                        <li v-if="version.status === Status.WAIT_FOR_REVIEW">
+                          <router-link
+                            class="dropdown-item"
+                            :to="{ name: 'resource-review' }"
+                          >
+                            Review Resource
+                          </router-link>
+                        </li>
+                        <li v-if="version.status === Status.SYNC_REQUESTED">
+                          <router-link
+                            class="dropdown-item"
+                            :to="{ name: 'admin-sync-requests' }"
+                          >
+                            Review sync request
+                          </router-link>
+                        </li>
                         <li
                           v-if="
-                            version.status === Status.CLUSTER_DELETED ||
-                            version.status === Status.SYNC_REQUESTED ||
-                            version.status === Status.DENIED
+                            version.status === Status.APPROVED ||
+                            version.status === Status.SYNC_ERROR
                           "
                         >
                           <button
@@ -331,22 +336,10 @@ function resetForm() {
                             <span class="ms-1">Sync to Cluster</span>
                           </button>
                         </li>
-                        <li v-if="version.status === Status.SYNC_REQUESTED">
-                          <button
-                            class="dropdown-item"
-                            type="button"
-                            @click="denyResource(version)"
-                          >
-                            <font-awesome-icon
-                              icon="fa-solid fa-xmark"
-                              class="text-danger"
-                            />
-                            <span class="ms-1">Deny Synchronization</span>
-                          </button>
-                        </li>
                         <li
                           v-if="
                             version.status === Status.SYNCHRONIZED ||
+                            version.status === Status.CLUSTER_DELETE_ERROR ||
                             version.status === Status.LATEST
                           "
                         >
@@ -361,7 +354,8 @@ function resetForm() {
                         </li>
                         <li
                           v-if="
-                            version.status === Status.CLUSTER_DELETED ||
+                            version.status === Status.APPROVED ||
+                            version.status === Status.S3_DELETE_ERROR ||
                             version.status === Status.DENIED
                           "
                         >
diff --git a/src/views/admin/AdminSyncRequestsView.vue b/src/views/admin/AdminSyncRequestsView.vue
new file mode 100644
index 0000000..bb7c0f6
--- /dev/null
+++ b/src/views/admin/AdminSyncRequestsView.vue
@@ -0,0 +1,271 @@
+<script setup lang="ts">
+import BootstrapToast from "@/components/BootstrapToast.vue";
+import ReasonModal from "@/components/modals/ReasonModal.vue";
+import ResourceVersionInfoModal from "@/components/resources/modals/ResourceVersionInfoModal.vue";
+import { onMounted, reactive } from "vue";
+import {
+  type ResourceOut,
+  type ResourceVersionOut,
+  Status,
+  type UserSynchronizationRequestOut,
+} from "@/client/resource";
+import { useResourceStore } from "@/stores/resources";
+import { useNameStore } from "@/stores/names";
+import { useAuthStore } from "@/stores/users";
+import { Modal, Toast } from "bootstrap";
+import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
+
+const resourceState = reactive<{
+  sendingRequest: boolean;
+  loading: boolean;
+  resources: Record<string, ResourceOut>;
+  inspectResource?: ResourceOut;
+  rejectResource?: ResourceVersionOut;
+  inspectVersionIndex: number;
+}>({
+  sendingRequest: false,
+  loading: true,
+  resources: {},
+  inspectResource: undefined,
+  rejectResource: undefined,
+  inspectVersionIndex: 0,
+});
+
+const resourceRepository = useResourceStore();
+const nameRepository = useNameStore();
+const userRepository = useAuthStore();
+
+let rejectReasonModal: Modal | null = null;
+let successToast: Toast | null = null;
+let rejectToast: Toast | null = null;
+let refreshTimeout: NodeJS.Timeout | undefined = undefined;
+
+function rejectSyncRequest(
+  reason: string,
+  resourceVersion?: ResourceVersionOut,
+) {
+  if (resourceVersion != undefined) {
+    resourceState.sendingRequest = true;
+    resourceRepository
+      .syncResource(resourceVersion, { deny: true, reason })
+      .then(() => {
+        rejectReasonModal?.hide();
+        rejectToast?.show();
+      })
+      .finally(() => {
+        resourceState.sendingRequest = false;
+      });
+  }
+}
+
+function syncVersion(resourceId: string, resourceVersionId: string) {
+  resourceState.sendingRequest = true;
+  resourceRepository
+    .syncResource(
+      {
+        resource_version_id: resourceVersionId,
+        resource_id: resourceId,
+        release: "",
+        created_at: 0,
+        s3_path: "",
+        cluster_path: "",
+        status: Status.SYNC_REQUESTED,
+      },
+      { deny: false },
+    )
+    .then(() => {
+      successToast?.show();
+      delete resourceState.resources[resourceId];
+    })
+    .finally(() => {
+      resourceState.sendingRequest = false;
+    });
+}
+
+function fetchResources(
+  syncRequests: UserSynchronizationRequestOut[],
+): Promise<ResourceOut[]> {
+  return Promise.all(
+    syncRequests.map((request) =>
+      resourceRepository.fetchResource(request.resource_id, [
+        Status.SYNC_REQUESTED,
+      ]),
+    ),
+  );
+}
+
+function fetchUserNames(
+  syncRequests: UserSynchronizationRequestOut[],
+): UserSynchronizationRequestOut[] {
+  userRepository.fetchUsernames(
+    syncRequests.map((request) => request.requester_id),
+  );
+  return syncRequests;
+}
+
+function fetchRequests() {
+  resourceState.loading = true;
+  resourceRepository
+    .fetchSyncRequests(() => {
+      resourceState.loading = false;
+    })
+    .then(fetchUserNames)
+    .then(fetchResources)
+    .then((resources) => {
+      const newMapping: Record<string, ResourceOut> = {};
+      for (const resource of resources) {
+        newMapping[resource.resource_id] = resource;
+      }
+      resourceState.resources = newMapping;
+    });
+}
+
+function clickRefreshRequests() {
+  clearTimeout(refreshTimeout);
+  refreshTimeout = setTimeout(() => {
+    fetchRequests();
+  }, 500);
+}
+
+onMounted(() => {
+  fetchRequests();
+
+  rejectReasonModal = new Modal("#sync-request-reject-modal");
+  successToast = new Toast("#accept-sync-request-toast");
+  rejectToast = new Toast("#reject-sync-request-toast");
+});
+</script>
+
+<template>
+  <bootstrap-toast toast-id="accept-sync-request-toast" color-class="success">
+    Syncing resource to the cluster
+  </bootstrap-toast>
+  <bootstrap-toast toast-id="reject-sync-request-toast" color-class="danger">
+    Rejected resource synchronization request
+  </bootstrap-toast>
+  <resource-version-info-modal
+    modal-id="sync-request-resource-version-info-modal"
+    :resource-version-index="resourceState.inspectVersionIndex"
+    :resource="resourceState.inspectResource"
+  />
+  <reason-modal
+    modal-id="sync-request-reject-modal"
+    modal-label="Resource Synchronization Request Reject Modal"
+    :loading="resourceState.sendingRequest"
+    purpose="rejection"
+    @save="(reason) => rejectSyncRequest(reason, resourceState.rejectResource)"
+  >
+    <template #header>
+      Reject Resource Synchronization Request
+      <b>{{ resourceState.rejectResource?.release }}</b>
+    </template>
+  </reason-modal>
+  <div
+    class="row border-bottom mb-4 justify-content-between align-items-center"
+  >
+    <h2 class="w-fit">Review resource synchronization requests</h2>
+    <span
+      class="w-fit"
+      tabindex="0"
+      data-bs-title="Refresh Reviewable Resources"
+      data-bs-toggle="tooltip"
+      id="refreshReviewableResourcesButton"
+    >
+      <button
+        type="button"
+        class="btn btn-primary btn-light me-2 shadow-sm border w-fit"
+        :disabled="resourceState.loading || resourceState.sendingRequest"
+        @click="clickRefreshRequests"
+      >
+        <font-awesome-icon icon="fa-solid fa-arrow-rotate-right" />
+        <span class="visually-hidden">Refresh Reviewable Resources</span>
+      </button>
+    </span>
+  </div>
+  <div v-if="resourceState.loading" class="text-center mt-5">
+    <div class="spinner-border" style="width: 3rem; height: 3rem" role="status">
+      <span class="visually-hidden">Loading...</span>
+    </div>
+  </div>
+  <div
+    v-else-if="resourceRepository.syncRequests.length === 0"
+    class="text-center mt-5 fs-4"
+  >
+    There are currently no resource synchronization requests
+  </div>
+  <div v-else class="d-flex flex-column">
+    <div
+      class="border p-2 pb-0 rounded mb-2 d-flex hover-card"
+      v-for="request in resourceRepository.syncRequests"
+      :key="request.resource_version_id"
+    >
+      <div class="flex-grow-1">
+        <h6>
+          {{ nameRepository.getName(request.resource_id) }}@{{
+            nameRepository.getName(request.resource_version_id)
+          }}
+        </h6>
+        <div>
+          <b>Requester</b>: {{ nameRepository.getName(request.requester_id) }}
+        </div>
+        <div><b>Reason</b>:</div>
+        <p>{{ request.reason }}</p>
+      </div>
+      <div class="d-flex flex-column justify-content-evenly align-items-center">
+        <button
+          type="button"
+          class="btn btn-secondary btn-sm"
+          data-bs-toggle="modal"
+          data-bs-target="#sync-request-resource-version-info-modal"
+          @click="
+            resourceState.inspectResource =
+              resourceState.resources[request.resource_id];
+            resourceState.inspectVersionIndex = resourceState.resources[
+              request.resource_id
+            ].versions.findIndex(
+              (version) =>
+                version.resource_version_id === request.resource_version_id,
+            );
+          "
+        >
+          Inspect Resource
+        </button>
+        <div class="btn-group">
+          <button
+            type="button"
+            class="btn btn-success btn-sm"
+            :disabled="resourceState.sendingRequest"
+            @click="
+              syncVersion(request.resource_id, request.resource_version_id)
+            "
+          >
+            Accept
+          </button>
+          <button
+            type="button"
+            class="btn btn-danger btn-sm"
+            @click="
+              resourceState.rejectResource = resourceState.resources[
+                request.resource_id
+              ].versions.find(
+                (version) =>
+                  version.resource_version_id === request.resource_version_id,
+              )
+            "
+            data-bs-toggle="modal"
+            data-bs-target="#sync-request-reject-modal"
+            :disabled="resourceState.sendingRequest"
+          >
+            Reject
+          </button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+.hover-card:hover {
+  box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
+}
+</style>
diff --git a/src/views/resources/ListResourcesView.vue b/src/views/resources/ListResourcesView.vue
index e559b59..7cea20a 100644
--- a/src/views/resources/ListResourcesView.vue
+++ b/src/views/resources/ListResourcesView.vue
@@ -5,19 +5,28 @@ import ResourceCard from "@/components/resources/ResourceCard.vue";
 import CardTransitionGroup from "@/components/transitions/CardTransitionGroup.vue";
 import { useAuthStore } from "@/stores/users";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import type { ResourceOut } from "@/client/resource";
+import type { ResourceOut, ResourceVersionOut } from "@/client/resource";
+import ReasonModal from "@/components/modals/ReasonModal.vue";
+import { Modal, Toast } from "bootstrap";
+import BootstrapToast from "@/components/BootstrapToast.vue";
 
 const resourceRepository = useResourceStore();
 const userRepository = useAuthStore();
+let requestReasonModal: Modal | null = null;
+let syncRequestSuccessToast: Toast | null = null;
 
 const resourceState = reactive<{
   loading: boolean;
   filterString: string;
   sortDesc: boolean;
+  showPrivate: boolean;
+  syncResourceVersion?: ResourceVersionOut;
 }>({
   loading: true,
   filterString: "",
   sortDesc: true,
+  showPrivate: false,
+  syncResourceVersion: undefined,
 });
 
 const sortedResourcesByName = computed<ResourceOut[]>(() => {
@@ -34,14 +43,34 @@ const sortedResources = computed<ResourceOut[]>(() => {
 });
 
 const filteredSortedResources = computed<ResourceOut[]>(() => {
-  return sortedResources.value.filter((resource) => {
-    return resourceState.filterString.length > 0
-      ? resource.name.includes(resourceState.filterString)
-      : true;
-  });
+  return sortedResources.value
+    .filter((resource) => !resource.private || resourceState.showPrivate)
+    .filter((resource) => {
+      return resourceState.filterString.length > 0
+        ? resource.name.includes(resourceState.filterString)
+        : true;
+    });
 });
 
+function requestResourceSync(
+  reason: string,
+  resourceVersion?: ResourceVersionOut,
+) {
+  if (resourceVersion != undefined) {
+    resourceRepository
+      .requestSynchronization(resourceVersion, {
+        reason: reason,
+      })
+      .then(() => {
+        requestReasonModal?.hide();
+        syncRequestSuccessToast?.show();
+      });
+  }
+}
+
 onMounted(() => {
+  requestReasonModal = new Modal("#request-synchronization-modal");
+  syncRequestSuccessToast = new Toast("#request-sync-toast");
   resourceRepository
     .fetchPublicResources(() => {
       resourceState.loading = false;
@@ -53,6 +82,20 @@ onMounted(() => {
 </script>
 
 <template>
+  <bootstrap-toast toast-id="request-sync-toast" color-class="success">
+    Requested resource synchronization
+  </bootstrap-toast>
+  <reason-modal
+    modal-id="request-synchronization-modal"
+    modal-label=""
+    :loading="false"
+    purpose="request"
+    @save="
+      (reason) => requestResourceSync(reason, resourceState.syncResourceVersion)
+    "
+  >
+    <template #header> Request resource synchronization</template>
+  </reason-modal>
   <div class="row border-bottom mb-4">
     <h2 class="mb-2">Available Resources</h2>
   </div>
@@ -75,6 +118,17 @@ onMounted(() => {
         />
       </div>
     </div>
+    <div class="form-check form-check-reverse form-check-inline fs-6 ms-auto">
+      <input
+        class="form-check-input"
+        type="checkbox"
+        v-model="resourceState.showPrivate"
+        id="public-resources-checkbox"
+      />
+      <label class="form-check-label" for="public-resources-checkbox">
+        Show only public resources
+      </label>
+    </div>
     <font-awesome-icon
       :icon="
         resourceState.sortDesc
@@ -82,7 +136,7 @@ onMounted(() => {
           : 'fa-solid fa-arrow-up-wide-short'
       "
       @click="resourceState.sortDesc = !resourceState.sortDesc"
-      class="fs-5 ms-3 cursor-pointer"
+      class="fs-5 cursor-pointer ms-2"
     />
   </div>
   <div v-if="!resourceState.loading">
@@ -95,7 +149,11 @@ onMounted(() => {
         class="my-5 fs-0"
         style="color: var(--bs-secondary)"
       />
-      <p>There are no resources in the system. Please come again later.</p>
+      <p>
+        There are no resources
+        <span v-if="resourceState.showPrivate">public</span> in the system.
+        Please come again later.
+      </p>
     </div>
     <div
       v-else-if="filteredSortedResources.length === 0"
@@ -122,6 +180,9 @@ onMounted(() => {
         :resource="resource"
         :loading="false"
         style="min-width: 47%; max-width: 48%"
+        @click-request-sync="
+          (version) => (resourceState.syncResourceVersion = version)
+        "
       />
     </CardTransitionGroup>
   </div>
diff --git a/src/views/resources/MyResourcesView.vue b/src/views/resources/MyResourcesView.vue
index 72aaf6b..227cd37 100644
--- a/src/views/resources/MyResourcesView.vue
+++ b/src/views/resources/MyResourcesView.vue
@@ -9,17 +9,24 @@ import { useS3KeyStore } from "@/stores/s3keys";
 import type { ResourceVersionOut, ResourceOut } from "@/client/resource";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import UpdateResourceModal from "@/components/resources/modals/UpdateResourceModal.vue";
+import ReasonModal from "@/components/modals/ReasonModal.vue";
+import BootstrapToast from "@/components/BootstrapToast.vue";
+import { Modal, Toast } from "bootstrap";
 
 const resourceRepository = useResourceStore();
 const s3KeyRepository = useS3KeyStore();
+let requestReasonModal: Modal | null = null;
+let syncRequestSuccessToast: Toast | null = null;
 
 const resourceState = reactive<{
   loading: boolean;
   resourceVersionInfo?: ResourceVersionOut;
   updateResource: ResourceOut;
+  syncResourceVersion?: ResourceVersionOut;
 }>({
   loading: true,
   resourceVersionInfo: undefined,
+  syncResourceVersion: undefined,
   updateResource: {
     name: "",
     description: "",
@@ -38,8 +45,30 @@ function setResourceUpdate(resource: ResourceOut) {
   resourceState.updateResource = resource;
 }
 
+function setResourceSync(version: ResourceVersionOut) {
+  resourceState.syncResourceVersion = version;
+}
+
+function requestResourceSync(
+  reason: string,
+  resourceVersion?: ResourceVersionOut,
+) {
+  if (resourceVersion != undefined) {
+    resourceRepository
+      .requestSynchronization(resourceVersion, {
+        reason: reason,
+      })
+      .then(() => {
+        requestReasonModal?.hide();
+        syncRequestSuccessToast?.show();
+      });
+  }
+}
+
 onMounted(() => {
   let fetchedResources = false;
+  requestReasonModal = new Modal("#request-synchronization-modal");
+  syncRequestSuccessToast = new Toast("#request-sync-toast");
   s3KeyRepository.fetchS3Keys(() => {
     if (!fetchedResources) {
       fetchedResources = true;
@@ -52,6 +81,20 @@ onMounted(() => {
 </script>
 
 <template>
+  <bootstrap-toast toast-id="request-sync-toast" color-class="success">
+    Requested resource synchronization
+  </bootstrap-toast>
+  <reason-modal
+    modal-id="request-synchronization-modal"
+    modal-label=""
+    :loading="false"
+    purpose="request"
+    @save="
+      (reason) => requestResourceSync(reason, resourceState.syncResourceVersion)
+    "
+  >
+    <template #header> Request resource synchronization</template>
+  </reason-modal>
   <create-resource-modal modal-id="createResourceModal" />
   <upload-resource-info-modal
     modal-id="uploadResourceInfoModal"
@@ -109,6 +152,7 @@ onMounted(() => {
         extended
         @click-info="setResourceVersionInfo"
         @click-update="setResourceUpdate"
+        @click-request-sync="setResourceSync"
       />
     </CardTransitionGroup>
   </div>
diff --git a/src/views/resources/ReviewResourceView.vue b/src/views/resources/ReviewResourceView.vue
index e682c79..5b7c226 100644
--- a/src/views/resources/ReviewResourceView.vue
+++ b/src/views/resources/ReviewResourceView.vue
@@ -7,23 +7,30 @@ import {
   Status,
 } from "@/client/resource";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import { Tooltip } from "bootstrap";
-import ResourceVersionInfoModal from "@/components/resources/ResourceVersionInfoModal.vue";
+import { Modal, Toast, Tooltip } from "bootstrap";
+import ResourceVersionInfoModal from "@/components/resources/modals/ResourceVersionInfoModal.vue";
 import { useNameStore } from "@/stores/names";
+import BootstrapToast from "@/components/BootstrapToast.vue";
+import ReasonModal from "@/components/modals/ReasonModal.vue";
 
 const resourceRepository = useResourceStore();
 const nameRepository = useNameStore();
 let refreshTimeout: NodeJS.Timeout | undefined = undefined;
+let rejectReasonModal: Modal | null = null;
+let successToast: Toast | null = null;
+let rejectToast: Toast | null = null;
 
 const resourceState = reactive<{
   sendingRequest: boolean;
   loading: boolean;
   inspectResource?: ResourceOut;
+  rejectResource?: ResourceVersionOut;
   inspectVersionIndex: number;
 }>({
   sendingRequest: false,
   loading: true,
   inspectResource: undefined,
+  rejectResource: undefined,
   inspectVersionIndex: 0,
 });
 
@@ -48,32 +55,68 @@ function clickRefreshResources() {
   }, 500);
 }
 
-function syncResource(resourceVersion: ResourceVersionOut) {
+function acceptReview(resourceVersion: ResourceVersionOut) {
   resourceState.sendingRequest = true;
-  resourceRepository.syncResource(resourceVersion).finally(() => {
-    resourceState.sendingRequest = false;
-  });
+  resourceRepository
+    .reviewResource(resourceVersion, { deny: false })
+    .then(() => {
+      successToast?.show();
+    })
+    .finally(() => {
+      resourceState.sendingRequest = false;
+    });
 }
 
-function denyResource(resourceVersion: ResourceVersionOut) {
-  resourceState.sendingRequest = true;
-  resourceRepository.denyResource(resourceVersion).finally(() => {
-    resourceState.sendingRequest = false;
-  });
+function rejectReview(reason: string, resourceVersion?: ResourceVersionOut) {
+  if (resourceVersion) {
+    resourceState.sendingRequest = true;
+    resourceRepository
+      .reviewResource(resourceVersion, { deny: true, reason: reason })
+      .then(() => {
+        rejectReasonModal?.hide();
+        rejectToast?.show();
+      })
+      .finally(() => {
+        resourceState.sendingRequest = false;
+      });
+  }
 }
 
 onMounted(() => {
   fetchResources();
   new Tooltip("#refreshReviewableResourcesButton");
+  rejectReasonModal = new Modal("#review-reject-modal");
+  successToast = new Toast("#accept-resource-review-toast");
+  rejectToast = new Toast("#reject-resource-review-toast");
 });
 </script>
 
 <template>
+  <bootstrap-toast
+    toast-id="accept-resource-review-toast"
+    color-class="success"
+  >
+    Accepted resource review
+  </bootstrap-toast>
+  <bootstrap-toast toast-id="reject-resource-review-toast" color-class="danger">
+    Rejected resource review
+  </bootstrap-toast>
   <resource-version-info-modal
     modal-id="review-resource-version-info-modal"
     :resource-version-index="resourceState.inspectVersionIndex"
     :resource="resourceState.inspectResource"
   />
+  <reason-modal
+    modal-id="review-reject-modal"
+    modal-label="Resource Review Reject Modal"
+    :loading="resourceState.sendingRequest"
+    purpose="rejection"
+    @save="(reason) => rejectReview(reason, resourceState.rejectResource)"
+  >
+    <template #header>
+      Reject Resource Review <b>{{ resourceState.rejectResource?.release }}</b>
+    </template>
+  </reason-modal>
   <div
     class="row border-bottom mb-4 justify-content-between align-items-center"
   >
@@ -151,24 +194,26 @@ onMounted(() => {
           </th>
           <th class="text-end">
             <div
-              v-if="version.status === Status.SYNC_REQUESTED"
+              v-if="version.status === Status.WAIT_FOR_REVIEW"
               class="btn-group"
             >
               <button
                 type="button"
                 class="btn btn-success btn-sm"
                 :disabled="resourceState.sendingRequest"
-                @click="syncResource(version)"
+                @click="acceptReview(version)"
               >
-                Synchronize
+                Accept
               </button>
               <button
                 type="button"
                 class="btn btn-danger btn-sm"
-                @click="denyResource(version)"
+                @click="resourceState.rejectResource = version"
+                data-bs-toggle="modal"
+                data-bs-target="#review-reject-modal"
                 :disabled="resourceState.sendingRequest"
               >
-                Deny
+                Reject
               </button>
             </div>
             <div
diff --git a/src/views/workflows/MyWorkflowsView.vue b/src/views/workflows/MyWorkflowsView.vue
index 89632a1..34fb0c0 100644
--- a/src/views/workflows/MyWorkflowsView.vue
+++ b/src/views/workflows/MyWorkflowsView.vue
@@ -114,7 +114,7 @@ onMounted(() => {
     modal-id="updateWorkflowCredentialsModal"
   />
   <div
-    class="row border-bottom mb-4 justify-content-between align-items-center pb-2"
+    class="row border-bottom mb-4 justify-content-between align-items-center pb-2 pe-2"
   >
     <h2 class="w-fit">My Workflows</h2>
     <button
diff --git a/src/views/workflows/ReviewWorkflowsView.vue b/src/views/workflows/ReviewWorkflowsView.vue
index ad15851..e8420b3 100644
--- a/src/views/workflows/ReviewWorkflowsView.vue
+++ b/src/views/workflows/ReviewWorkflowsView.vue
@@ -35,10 +35,6 @@ function updateWorkflowVersionStatus(
     });
 }
 
-function isDefined<T>(argument: T | undefined | null): argument is T {
-  return argument != undefined;
-}
-
 onMounted(() => {
   workflowRepository
     .fetchReviewableWorkflows(() => {
@@ -55,9 +51,7 @@ onMounted(() => {
       }, 1000);
       return workflows;
     })
-    .then((workflows) =>
-      workflows.map((workflow) => workflow.developer_id).filter(isDefined),
-    )
+    .then((workflows) => workflows.map((workflow) => workflow.developer_id))
     .then(userRepository.fetchUsernames);
 });
 </script>
diff --git a/src/views/workflows/WorkflowView.vue b/src/views/workflows/WorkflowView.vue
index 28d53d4..32dfd64 100644
--- a/src/views/workflows/WorkflowView.vue
+++ b/src/views/workflows/WorkflowView.vue
@@ -16,9 +16,11 @@ import {
 import { determineGitIcon } from "@/utils/GitRepository";
 import { useAuthStore } from "@/stores/users";
 import { useWorkflowStore } from "@/stores/workflows";
+import { useNameStore } from "@/stores/names";
 
 const workflowRepository = useWorkflowStore();
 const userRepository = useAuthStore();
+const nameRepository = useNameStore();
 
 // Props
 // =============================================================================
@@ -132,6 +134,10 @@ function updateWorkflow(workflowId: string) {
       workflowState.loading = false;
       workflowState.initialOpen = false;
     })
+    .then((workflow) => {
+      userRepository.fetchUsernames([workflow.developer_id]);
+      return workflow;
+    })
     .then((workflow) => {
       document.title = workflow.name + " - CloWM";
       if (props.versionId == undefined) {
@@ -230,6 +236,9 @@ onMounted(() => {
       <h3 class="w-fit">
         {{ workflow.name }}
         <span v-if="activeVersionString">@{{ activeVersionString }}</span>
+        <span v-if="nameRepository.getName(workflow.developer_id)" class="fs-4">
+          by {{ nameRepository.getName(workflow.developer_id) }}</span
+        >
       </h3>
       <img
         v-if="activeVersionIcon != null"
diff --git a/tsconfig.config.json b/tsconfig.config.json
index c2d3a30..776b880 100644
--- a/tsconfig.config.json
+++ b/tsconfig.config.json
@@ -1,8 +1,14 @@
 {
   "extends": "@vue/tsconfig/tsconfig.node.json",
-  "include": ["vite.config.*", "vitest.config.*", "cypress.config.*"],
+  "include": [
+    "vite.config.*",
+    "vitest.config.*",
+    "cypress.config.*"
+  ],
   "compilerOptions": {
     "composite": true,
-    "types": ["node"]
+    "types": [
+      "node"
+    ]
   }
 }
diff --git a/tsconfig.json b/tsconfig.json
index 32d333f..3714ea8 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,14 +3,25 @@
     "@tsconfig/node18/tsconfig.json",
     "@vue/tsconfig/tsconfig.json"
   ],
-  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+  "include": [
+    "env.d.ts",
+    "src/**/*",
+    "src/**/*.vue"
+  ],
   "compilerOptions": {
-    "lib": ["...", "dom"],
+    "lib": [
+      "ES2020",
+      "dom"
+    ],
     "allowSyntheticDefaultImports": true,
     "baseUrl": ".",
-    "types": ["node"],
+    "types": [
+      "node"
+    ],
     "paths": {
-      "@/*": ["./src/*"]
+      "@/*": [
+        "./src/*"
+      ]
     }
-  },
+  }
 }
-- 
GitLab