You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/05/19 05:19:54 UTC

(superset) branch feat/glyph-single-file updated: fix(docker): make docker compose up build reliably

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch feat/glyph-single-file
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/feat/glyph-single-file by this push:
     new 79eb91da964 fix(docker): make docker compose up build reliably
79eb91da964 is described below

commit 79eb91da964f93cc03bd3165e88da67ca42a7e7b
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Tue May 19 00:19:40 2026 -0500

    fix(docker): make docker compose up build reliably
    
    Three interlocking fixes so the full dev stack comes up cleanly:
    
    1. Bind-mount Python package metadata (pyproject.toml, setup.py,
       MANIFEST.in, README.md) into /app in docker-compose.yml. Without
       these mounts, docker-bootstrap.sh's `uv pip install -e .` reads the
       stale metadata baked into the image at build time. After bumping
       apache-superset-core's sqlglot pin (>=28.10.0,<29), the bind mount
       ensures the editable install always sees the host's current pins
       instead of the image's older snapshot — which had been causing
       "apache-superset==0.0.0.dev0 depends on sqlglot>=27.15.2,<28" type
       resolver failures.
    
    2. Bump @superset-ui/glyph-core's react peer from ^17.0.2 to ^18.2.0.
       Root and every other workspace package are on react 18; the
       stranded peer caused ERESOLVE during the in-container `npm install`
       (Docker doesn't use --legacy-peer-deps).
    
    3. Restore the legacy-plugin-chart-partition multi-file plugin
       (controlPanel.tsx, transformProps.ts, index.ts) from master. They
       were missing on our branch; webpack resolves @superset-ui/legacy-
       plugin-chart-* via the tsconfig path mapping to plugins/.../src/,
       and without index.ts the partition entrypoint was unreachable.
       MainPreset.ts imports it.
    
    Verified: docker compose down -v && docker compose build --no-cache &&
    docker compose up brings the full stack up, /health returns OK, and
    nginx serves the frontend on http://localhost/ (HTTP 302 login).
    
    Co-Authored-By: Claude Sonnet 4.6 <no...@anthropic.com>
---
 docker-compose.yml                                 |    8 +
 superset-frontend/package-lock.json                | 1010 ++++++++++++++------
 .../packages/superset-ui-glyph-core/package.json   |    2 +-
 .../src/controlPanel.tsx                           |  401 ++++++++
 .../legacy-plugin-chart-partition/src/index.ts     |   48 +
 .../src/transformProps.ts                          |   56 ++
 6 files changed, 1257 insertions(+), 268 deletions(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index bd474a83ef4..ec4af94a6c6 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -34,6 +34,14 @@ x-superset-volumes: &superset-volumes
   - superset_home:/app/superset_home
   - ./tests:/app/tests
   - superset_data:/app/data
+  # Python package metadata for the editable `uv pip install -e .` that
+  # docker-bootstrap.sh runs at container start. Without these bind mounts
+  # the editable install reads stale metadata baked into the image at
+  # build time and may conflict with apache-superset-core's current pins.
+  - ./pyproject.toml:/app/pyproject.toml
+  - ./setup.py:/app/setup.py
+  - ./MANIFEST.in:/app/MANIFEST.in
+  - ./README.md:/app/README.md
 x-common-build: &common-build
   context: .
   target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 99b3df833bb..e5db463e5ea 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -345,7 +345,6 @@
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.1.tgz",
       "integrity": "sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@ant-design/colors": {
@@ -501,27 +500,6 @@
         "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
       }
     },
-    "node_modules/@asamuzakjp/dom-selector/node_modules/css-tree": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
-      "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "mdn-data": "2.27.1",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
-      }
-    },
-    "node_modules/@asamuzakjp/dom-selector/node_modules/mdn-data": {
-      "version": "2.27.1",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
-      "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
-      "dev": true,
-      "license": "CC0-1.0"
-    },
     "node_modules/@asamuzakjp/generational-cache": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@asamuzakjp/generational-cache/-/generational-cache-1.0.1.tgz",
@@ -2694,20 +2672,6 @@
         "specificity": "bin/cli.js"
       }
     },
-    "node_modules/@bramus/specificity/node_modules/css-tree": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
-      "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "mdn-data": "2.12.2",
-        "source-map-js": "^1.0.1"
-      },
-      "engines": {
-        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
-      }
-    },
     "node_modules/@cspotcode/source-map-support": {
       "version": "0.8.1",
       "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
@@ -3031,6 +2995,20 @@
         "react-dom": ">=16.3.0"
       }
     },
+    "node_modules/@deck.gl/widgets": {
+      "version": "9.2.11",
+      "resolved": "https://registry.npmjs.org/@deck.gl/widgets/-/widgets-9.2.11.tgz",
+      "integrity": "sha512-90HWlQPsiRyTPWR4aYfLwnYDrJdHG2mqCzRcyMUKewWBNQLu4upB//l4ewIkUeXXCzAprjjVeRnNb7wdYj2CXQ==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "preact": "^10.17.0"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "~9.2.0",
+        "@luma.gl/core": "~9.2.6"
+      }
+    },
     "node_modules/@discoveryjs/json-ext": {
       "version": "0.6.3",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
@@ -7292,13 +7270,15 @@
       }
     },
     "node_modules/@noble/hashes": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
-      "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz",
+      "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==",
       "dev": true,
       "license": "MIT",
+      "optional": true,
+      "peer": true,
       "engines": {
-        "node": ">= 16"
+        "node": ">= 20.19.0"
       },
       "funding": {
         "url": "https://paulmillr.com/funding/"
@@ -9226,6 +9206,84 @@
       "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==",
       "license": "MIT"
     },
+    "node_modules/@react-spring/animated": {
+      "version": "9.7.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz",
+      "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "@react-spring/shared": "~9.7.5",
+        "@react-spring/types": "~9.7.5"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
+    "node_modules/@react-spring/core": {
+      "version": "9.7.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz",
+      "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "@react-spring/animated": "~9.7.5",
+        "@react-spring/shared": "~9.7.5",
+        "@react-spring/types": "~9.7.5"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/react-spring/donate"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
+    "node_modules/@react-spring/rafz": {
+      "version": "9.7.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz",
+      "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==",
+      "license": "MIT",
+      "peer": true
+    },
+    "node_modules/@react-spring/shared": {
+      "version": "9.7.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz",
+      "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "@react-spring/rafz": "~9.7.5",
+        "@react-spring/types": "~9.7.5"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
+    "node_modules/@react-spring/types": {
+      "version": "9.7.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz",
+      "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==",
+      "license": "MIT",
+      "peer": true
+    },
+    "node_modules/@react-spring/web": {
+      "version": "9.7.5",
+      "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz",
+      "integrity": "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "@react-spring/animated": "~9.7.5",
+        "@react-spring/core": "~9.7.5",
+        "@react-spring/shared": "~9.7.5",
+        "@react-spring/types": "~9.7.5"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+        "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
     "node_modules/@reduxjs/toolkit": {
       "version": "1.9.7",
       "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.7.tgz",
@@ -13345,7 +13403,7 @@
       "version": "1.15.33",
       "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.33.tgz",
       "integrity": "sha512-jOlwnFV2xhuuZeAUILGFULeR6vDPfijEJ57evfocwznQldLU3w2cZ9bSDryY9ip+AsM3r1NJKzf47V2NXebkeQ==",
-      "dev": true,
+      "devOptional": true,
       "hasInstallScript": true,
       "license": "Apache-2.0",
       "dependencies": {
@@ -13389,7 +13447,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13406,7 +13463,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13423,7 +13479,6 @@
       "cpu": [
         "arm"
       ],
-      "dev": true,
       "license": "Apache-2.0",
       "optional": true,
       "os": [
@@ -13440,7 +13495,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13457,7 +13511,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13474,7 +13527,6 @@
       "cpu": [
         "ppc64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13491,7 +13543,6 @@
       "cpu": [
         "s390x"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13508,7 +13559,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13525,7 +13575,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13542,7 +13591,6 @@
       "cpu": [
         "arm64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13559,7 +13607,6 @@
       "cpu": [
         "ia32"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13576,7 +13623,6 @@
       "cpu": [
         "x64"
       ],
-      "dev": true,
       "license": "Apache-2.0 AND MIT",
       "optional": true,
       "os": [
@@ -13590,7 +13636,7 @@
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
       "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0"
     },
     "node_modules/@swc/jest": {
@@ -13635,7 +13681,7 @@
       "version": "0.1.26",
       "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.26.tgz",
       "integrity": "sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==",
-      "dev": true,
+      "devOptional": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@swc/counter": "^0.1.3"
@@ -13645,7 +13691,6 @@
       "version": "9.3.4",
       "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz",
       "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "^7.10.4",
@@ -13665,7 +13710,6 @@
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
       "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ansi-styles": "^4.1.0",
@@ -13682,7 +13726,6 @@
       "version": "6.9.1",
       "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
       "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@adobe/css-tools": "^4.4.0",
@@ -13702,14 +13745,12 @@
       "version": "0.6.3",
       "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz",
       "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@testing-library/react": {
       "version": "14.3.1",
       "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz",
       "integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.12.5",
@@ -13728,7 +13769,6 @@
       "version": "12.8.3",
       "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-12.8.3.tgz",
       "integrity": "sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.12.5"
@@ -13954,7 +13994,6 @@
       "version": "5.0.4",
       "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
       "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@types/babel__core": {
@@ -14883,7 +14922,6 @@
       "version": "5.5.11",
       "resolved": "https://registry.npmjs.org/@types/react-loadable/-/react-loadable-5.5.11.tgz",
       "integrity": "sha512-/tq2IJ853MoIFRBmqVOxnGsRRjER5TmEKzsZtaAkiXAWoDeKgR/QNOT1vd9k0p9h/F616X21cpNh3hu4RutzRQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@types/react": "*",
@@ -14894,7 +14932,6 @@
       "version": "4.41.40",
       "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.40.tgz",
       "integrity": "sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@types/node": "*",
@@ -14909,7 +14946,6 @@
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">=0.10.0"
@@ -14991,7 +15027,6 @@
       "version": "1.8.8",
       "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
       "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@types/react": "*"
@@ -15105,7 +15140,6 @@
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.6.tgz",
       "integrity": "sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@types/stack-utils": {
@@ -15128,14 +15162,12 @@
       "version": "1.0.12",
       "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.12.tgz",
       "integrity": "sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@types/tinycolor2": {
       "version": "1.4.6",
       "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.6.tgz",
       "integrity": "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@types/tough-cookie": {
@@ -15156,7 +15188,6 @@
       "version": "3.17.5",
       "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.17.5.tgz",
       "integrity": "sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "source-map": "^0.6.1"
@@ -15166,7 +15197,6 @@
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">=0.10.0"
@@ -15223,7 +15253,6 @@
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-3.2.3.tgz",
       "integrity": "sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@types/node": "*",
@@ -17135,6 +17164,29 @@
       "dev": true,
       "license": "BSD-2-Clause"
     },
+    "node_modules/@yeoman/types": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/@yeoman/types/-/types-1.11.1.tgz",
+      "integrity": "sha512-27CI5hHQAHfq8ohYILmLNzClbdzBJzu+ny9AzUVV6naJO0l4/+t+67QDKlwQvt+TW3oE5j74I/Mh4Kn14rsVXA==",
+      "license": "MIT",
+      "peer": true,
+      "engines": {
+        "node": "^16.13.0 || >=18.12.0"
+      },
+      "peerDependencies": {
+        "@types/node": ">=16.18.26",
+        "@yeoman/adapter": "^1.6.0 || ^2.0.0-beta.0 || ^3.0.0 || ^4.0.0",
+        "mem-fs": "^3.0.0 || ^4.0.0-beta.1"
+      },
+      "peerDependenciesMeta": {
+        "@yeoman/adapter": {
+          "optional": true
+        },
+        "mem-fs": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/@zarrita/storage": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/@zarrita/storage/-/storage-0.2.0.tgz",
@@ -17206,10 +17258,16 @@
         "node": ">= 0.6"
       }
     },
+    "node_modules/ace-builds": {
+      "version": "1.44.0",
+      "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.44.0.tgz",
+      "integrity": "sha512-PFNMSYqFdEUkul2Ntud0HvA09AgY+F1ag0UYdpMH60wNI/qOA8cB8tlTgoALMEwIdUPJK2CjrIQ7OnbiSS/ugQ==",
+      "license": "BSD-3-Clause"
+    },
     "node_modules/acorn": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
-      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+      "version": "8.16.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
       "license": "MIT",
       "bin": {
         "acorn": "bin/acorn"
@@ -17253,18 +17311,6 @@
         "node": ">=0.4.0"
       }
     },
-    "node_modules/acorn-walk/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/add-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz",
@@ -17437,7 +17483,6 @@
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
@@ -17447,7 +17492,6 @@
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
       "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "color-convert": "^2.0.1"
@@ -17542,7 +17586,6 @@
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
       "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
-      "dev": true,
       "license": "ISC",
       "dependencies": {
         "normalize-path": "^3.0.0",
@@ -17598,7 +17641,6 @@
       "version": "5.1.3",
       "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
       "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
-      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "deep-equal": "^2.0.5"
@@ -21476,26 +21518,19 @@
       }
     },
     "node_modules/css-tree": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
-      "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
+      "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "mdn-data": "2.0.30",
-        "source-map-js": "^1.0.1"
+        "mdn-data": "2.27.1",
+        "source-map-js": "^1.2.1"
       },
       "engines": {
         "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
       }
     },
-    "node_modules/css-tree/node_modules/mdn-data": {
-      "version": "2.0.30",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
-      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
-      "dev": true,
-      "license": "CC0-1.0"
-    },
     "node_modules/css-what": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
@@ -21513,7 +21548,6 @@
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
       "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/csscolorparser": {
@@ -22136,7 +22170,6 @@
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
       "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "array-buffer-byte-length": "^1.0.0",
@@ -22606,7 +22639,6 @@
       "version": "0.5.16",
       "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
       "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/dom-align": {
@@ -23232,7 +23264,6 @@
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
       "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind": "^1.0.2",
@@ -24337,19 +24368,6 @@
         "url": "https://opencollective.com/eslint"
       }
     },
-    "node_modules/espree/node_modules/acorn": {
-      "version": "8.14.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
-      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/espree/node_modules/eslint-visitor-keys": {
       "version": "3.4.3",
       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
@@ -24646,6 +24664,18 @@
         "node": ">=0.4.0"
       }
     },
+    "node_modules/falafel/node_modules/acorn": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+      "license": "MIT",
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -26849,7 +26879,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
@@ -27980,7 +28009,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
       "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
@@ -28142,7 +28170,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz",
       "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bound": "^1.0.2",
@@ -30126,19 +30153,6 @@
         }
       }
     },
-    "node_modules/jest-environment-jsdom/node_modules/acorn": {
-      "version": "8.14.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
-      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/jest-environment-jsdom/node_modules/acorn-globals": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz",
@@ -32686,20 +32700,6 @@
         }
       }
     },
-    "node_modules/jsdom/node_modules/css-tree": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz",
-      "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "mdn-data": "2.27.1",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
-      }
-    },
     "node_modules/jsdom/node_modules/entities": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz",
@@ -32723,13 +32723,6 @@
         "node": "20 || >=22"
       }
     },
-    "node_modules/jsdom/node_modules/mdn-data": {
-      "version": "2.27.1",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
-      "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
-      "dev": true,
-      "license": "CC0-1.0"
-    },
     "node_modules/jsdom/node_modules/parse5": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz",
@@ -34422,7 +34415,6 @@
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
       "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
-      "dev": true,
       "license": "MIT",
       "bin": {
         "lz-string": "bin/bin.js"
@@ -34909,9 +34901,9 @@
       }
     },
     "node_modules/mdn-data": {
-      "version": "2.12.2",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
-      "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
+      "version": "2.27.1",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz",
+      "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==",
       "dev": true,
       "license": "CC0-1.0"
     },
@@ -35477,7 +35469,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
       "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=4"
@@ -36800,6 +36791,421 @@
         "node": ">=12"
       }
     },
+    "node_modules/nyc": {
+      "version": "18.0.0",
+      "resolved": "https://registry.npmjs.org/nyc/-/nyc-18.0.0.tgz",
+      "integrity": "sha512-G5UyHinFkB1BxqGTrmZdB6uIYH0+v7ZnVssuflUDi+J+RhKWyAhRT1RCehBSI6jLFLuUUgFDyLt49mUtdO1XeQ==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "dependencies": {
+        "@istanbuljs/load-nyc-config": "^1.0.0",
+        "@istanbuljs/schema": "^0.1.2",
+        "caching-transform": "^4.0.0",
+        "convert-source-map": "^1.7.0",
+        "decamelize": "^1.2.0",
+        "find-cache-dir": "^3.2.0",
+        "find-up": "^4.1.0",
+        "foreground-child": "^3.3.0",
+        "get-package-type": "^0.1.0",
+        "glob": "^13.0.6",
+        "istanbul-lib-coverage": "^3.0.0",
+        "istanbul-lib-hook": "^3.0.0",
+        "istanbul-lib-instrument": "^6.0.2",
+        "istanbul-lib-processinfo": "^3.0.0",
+        "istanbul-lib-report": "^3.0.0",
+        "istanbul-lib-source-maps": "^4.0.0",
+        "istanbul-reports": "^3.0.2",
+        "make-dir": "^3.0.0",
+        "node-preload": "^0.2.1",
+        "p-map": "^3.0.0",
+        "process-on-spawn": "^1.0.0",
+        "resolve-from": "^5.0.0",
+        "rimraf": "^6.1.3",
+        "signal-exit": "^3.0.2",
+        "spawn-wrap": "^3.0.0",
+        "test-exclude": "^8.0.0",
+        "yargs": "^15.0.2"
+      },
+      "bin": {
+        "nyc": "bin/nyc.js"
+      },
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/nyc/node_modules/balanced-match": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+      "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    "node_modules/nyc/node_modules/brace-expansion": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+      "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "balanced-match": "^4.0.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    "node_modules/nyc/node_modules/camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/nyc/node_modules/cliui": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+      "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^6.2.0"
+      }
+    },
+    "node_modules/nyc/node_modules/convert-source-map": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true
+    },
+    "node_modules/nyc/node_modules/find-cache-dir": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz",
+      "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "commondir": "^1.0.1",
+        "make-dir": "^3.0.2",
+        "pkg-dir": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+      }
+    },
+    "node_modules/nyc/node_modules/find-up": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "locate-path": "^5.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/glob": {
+      "version": "13.0.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+      "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "minimatch": "^10.2.2",
+        "minipass": "^7.1.3",
+        "path-scurry": "^2.0.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/nyc/node_modules/istanbul-lib-processinfo": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-3.0.0.tgz",
+      "integrity": "sha512-P7nLXRRlo7Sqinty6lNa7+4o9jBUYGpqtejqCOZKfgXlRoxY/QArflcB86YO500Ahj4pDJEG34JjMRbQgePLnQ==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "dependencies": {
+        "archy": "^1.0.0",
+        "cross-spawn": "^7.0.3",
+        "istanbul-lib-coverage": "^3.2.0",
+        "p-map": "^3.0.0",
+        "rimraf": "^6.1.3",
+        "uuid": "^8.3.2"
+      },
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/nyc/node_modules/locate-path": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "p-locate": "^4.1.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/lru-cache": {
+      "version": "11.4.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz",
+      "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/nyc/node_modules/make-dir": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+      "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "semver": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/nyc/node_modules/minimatch": {
+      "version": "10.2.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+      "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "brace-expansion": "^5.0.5"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/nyc/node_modules/p-limit": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "p-try": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/nyc/node_modules/p-locate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "p-limit": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/p-map": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "aggregate-error": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/path-scurry": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+      "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "lru-cache": "^11.0.0",
+        "minipass": "^7.1.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/nyc/node_modules/semver": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "bin": {
+        "semver": "bin/semver.js"
+      }
+    },
+    "node_modules/nyc/node_modules/spawn-wrap": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-3.0.0.tgz",
+      "integrity": "sha512-z+s5vv4KzFPJVddGab0xX2n7kQPGMdNUX5l9T8EJqsXdKTWpcxmAqWHpsgHEXoC1taGBCc7b79bi62M5kdbrxQ==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.6",
+        "foreground-child": "^2.0.0",
+        "is-windows": "^1.0.2",
+        "make-dir": "^3.0.0",
+        "rimraf": "^6.1.3",
+        "signal-exit": "^3.0.2",
+        "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/spawn-wrap/node_modules/foreground-child": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+      "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "dependencies": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
+    "node_modules/nyc/node_modules/test-exclude": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-8.0.0.tgz",
+      "integrity": "sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "dependencies": {
+        "@istanbuljs/schema": "^0.1.2",
+        "glob": "^13.0.6",
+        "minimatch": "^10.2.2"
+      },
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/nyc/node_modules/uuid": {
+      "version": "8.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+      "deprecated": "uuid@10 and below is no longer supported.  For ESM codebases, update to uuid@latest.  For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
+    },
+    "node_modules/nyc/node_modules/y18n": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+      "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true
+    },
+    "node_modules/nyc/node_modules/yargs": {
+      "version": "15.4.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+      "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "cliui": "^6.0.0",
+        "decamelize": "^1.2.0",
+        "find-up": "^4.1.0",
+        "get-caller-file": "^2.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^4.2.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^18.1.2"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/nyc/node_modules/yargs-parser": {
+      "version": "18.1.3",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+      "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+      "dev": true,
+      "license": "ISC",
+      "peer": true,
+      "dependencies": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -36825,7 +37231,6 @@
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
       "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind": "^1.0.7",
@@ -38121,6 +38526,19 @@
         "node": ">=16.0.0"
       }
     },
+    "node_modules/pkijs/node_modules/@noble/hashes": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz",
+      "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
     "node_modules/playwright": {
       "version": "1.60.0",
       "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz",
@@ -38188,7 +38606,6 @@
       "version": "4.3.1",
       "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz",
       "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.17.8"
@@ -38851,6 +39268,17 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/preact": {
+      "version": "10.29.2",
+      "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.2.tgz",
+      "integrity": "sha512-7tNmwg/7mzzAoB/8kSg6Hl37JraAZw3Z3A0JSY7VXlZwo82Xn0G7wKbNNs2qoF4ZEEsQGTwDAroNdqKs1ofJxQ==",
+      "license": "MIT",
+      "peer": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/preact"
+      }
+    },
     "node_modules/prelude-ls": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -38923,7 +39351,6 @@
       "version": "27.5.1",
       "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
       "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1",
@@ -38938,7 +39365,6 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
       "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=10"
@@ -38951,7 +39377,6 @@
       "version": "17.0.2",
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/pretty-ms": {
@@ -40153,6 +40578,24 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/react-ace": {
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/react-ace/-/react-ace-10.1.0.tgz",
+      "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "ace-builds": "^1.4.14",
+        "diff-match-patch": "^1.0.5",
+        "lodash.get": "^4.4.2",
+        "lodash.isequal": "^4.5.0",
+        "prop-types": "^15.7.2"
+      },
+      "peerDependencies": {
+        "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+        "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+      }
+    },
     "node_modules/react-arborist": {
       "version": "3.6.1",
       "resolved": "https://registry.npmjs.org/react-arborist/-/react-arborist-3.6.1.tgz",
@@ -41136,7 +41579,6 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
       "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "indent-string": "^4.0.0",
@@ -41150,7 +41592,6 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
       "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "min-indent": "^1.0.0"
@@ -42488,6 +42929,117 @@
         "node": ">= 0.8.15"
       }
     },
+    "node_modules/rimraf": {
+      "version": "6.1.3",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz",
+      "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "glob": "^13.0.3",
+        "package-json-from-dist": "^1.0.1"
+      },
+      "bin": {
+        "rimraf": "dist/esm/bin.mjs"
+      },
+      "engines": {
+        "node": "20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/balanced-match": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+      "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    "node_modules/rimraf/node_modules/brace-expansion": {
+      "version": "5.0.6",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+      "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+      "dev": true,
+      "license": "MIT",
+      "peer": true,
+      "dependencies": {
+        "balanced-match": "^4.0.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      }
+    },
+    "node_modules/rimraf/node_modules/glob": {
+      "version": "13.0.6",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+      "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "minimatch": "^10.2.2",
+        "minipass": "^7.1.3",
+        "path-scurry": "^2.0.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/lru-cache": {
+      "version": "11.4.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz",
+      "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "engines": {
+        "node": "20 || >=22"
+      }
+    },
+    "node_modules/rimraf/node_modules/minimatch": {
+      "version": "10.2.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+      "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "brace-expansion": "^5.0.5"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/path-scurry": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+      "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+      "dev": true,
+      "license": "BlueOak-1.0.0",
+      "peer": true,
+      "dependencies": {
+        "lru-cache": "^11.0.0",
+        "minipass": "^7.1.2"
+      },
+      "engines": {
+        "node": "18 || 20 || >=22"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/rison": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/rison/-/rison-0.1.1.tgz",
@@ -43494,7 +44046,6 @@
       "version": "0.7.6",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
       "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==",
-      "dev": true,
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">= 12"
@@ -44486,7 +45037,6 @@
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
       "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "has-flag": "^4.0.0"
@@ -44560,6 +45110,27 @@
         "node": ">= 10"
       }
     },
+    "node_modules/svgo/node_modules/css-tree": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+      "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "mdn-data": "2.0.30",
+        "source-map-js": "^1.0.1"
+      },
+      "engines": {
+        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+      }
+    },
+    "node_modules/svgo/node_modules/mdn-data": {
+      "version": "2.0.30",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+      "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+      "dev": true,
+      "license": "CC0-1.0"
+    },
     "node_modules/swc-loader": {
       "version": "0.2.7",
       "resolved": "https://registry.npmjs.org/swc-loader/-/swc-loader-0.2.7.tgz",
@@ -44839,19 +45410,6 @@
         "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
-    "node_modules/terser/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/terser/node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -45445,18 +46003,6 @@
         }
       }
     },
-    "node_modules/ts-node/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/ts-node/node_modules/diff": {
       "version": "4.0.4",
       "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
@@ -46203,7 +46749,6 @@
       "version": "5.4.5",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
       "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
-      "dev": true,
       "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
@@ -46713,19 +47258,6 @@
         "node": ">=14.0.0"
       }
     },
-    "node_modules/unplugin/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/unrs-resolver": {
       "version": "1.9.2",
       "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.9.2.tgz",
@@ -47284,18 +47816,6 @@
         "node": ">=6.0"
       }
     },
-    "node_modules/vm2/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/w3c-xmlserializer": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
@@ -47594,19 +48114,6 @@
         "node": ">= 20.9.0"
       }
     },
-    "node_modules/webpack-bundle-analyzer/node_modules/acorn": {
-      "version": "8.14.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
-      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/webpack-bundle-analyzer/node_modules/commander": {
       "version": "14.0.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
@@ -48092,19 +48599,6 @@
         "mkdirp": "bin/cmd.js"
       }
     },
-    "node_modules/webpack/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "dev": true,
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/webpack/node_modules/es-module-lexer": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
@@ -49680,12 +50174,6 @@
       "dev": true,
       "license": "MIT"
     },
-    "packages/superset-ui-core/node_modules/ace-builds": {
-      "version": "1.44.0",
-      "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.44.0.tgz",
-      "integrity": "sha512-PFNMSYqFdEUkul2Ntud0HvA09AgY+F1ag0UYdpMH60wNI/qOA8cB8tlTgoALMEwIdUPJK2CjrIQ7OnbiSS/ugQ==",
-      "license": "BSD-3-Clause"
-    },
     "packages/superset-ui-core/node_modules/core-js": {
       "version": "3.49.0",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz",
@@ -50615,7 +51103,7 @@
         "@apache-superset/core": "*",
         "@superset-ui/chart-controls": "*",
         "@superset-ui/core": "*",
-        "react": "^17.0.2"
+        "react": "^18.2.0"
       }
     },
     "packages/superset-ui-switchboard": {
@@ -51057,18 +51545,6 @@
         "react": "^18.2.0"
       }
     },
-    "plugins/plugin-chart-echarts/node_modules/acorn": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
-      "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
-      "license": "MIT",
-      "bin": {
-        "acorn": "bin/acorn"
-      },
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "plugins/plugin-chart-echarts/node_modules/d3-array": {
       "version": "3.2.4",
       "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
diff --git a/superset-frontend/packages/superset-ui-glyph-core/package.json b/superset-frontend/packages/superset-ui-glyph-core/package.json
index cc747c71ac8..1b7a19197b8 100644
--- a/superset-frontend/packages/superset-ui-glyph-core/package.json
+++ b/superset-frontend/packages/superset-ui-glyph-core/package.json
@@ -33,6 +33,6 @@
     "@apache-superset/core": "*",
     "@superset-ui/chart-controls": "*",
     "@superset-ui/core": "*",
-    "react": "^17.0.2"
+    "react": "^18.2.0"
   }
 }
diff --git a/superset-frontend/plugins/legacy-plugin-chart-partition/src/controlPanel.tsx b/superset-frontend/plugins/legacy-plugin-chart-partition/src/controlPanel.tsx
new file mode 100644
index 00000000000..ece7cbe0259
--- /dev/null
+++ b/superset-frontend/plugins/legacy-plugin-chart-partition/src/controlPanel.tsx
@@ -0,0 +1,401 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { t } from '@apache-superset/core/translation';
+import { validateNonEmpty } from '@superset-ui/core';
+import {
+  ColumnMeta,
+  ControlPanelConfig,
+  ControlSubSectionHeader,
+  D3_FORMAT_DOCS,
+  D3_FORMAT_OPTIONS,
+  D3_TIME_FORMAT_OPTIONS,
+  getStandardizedControls,
+} from '@superset-ui/chart-controls';
+import OptionDescription from './OptionDescription';
+
+const config: ControlPanelConfig = {
+  controlPanelSections: [
+    {
+      label: t('Query'),
+      expanded: true,
+      controlSetRows: [
+        ['metrics'],
+        ['adhoc_filters'],
+        ['groupby'],
+        ['limit'],
+        ['timeseries_limit_metric'],
+        ['order_desc'],
+        [
+          {
+            name: 'contribution',
+            config: {
+              type: 'CheckboxControl',
+              label: t('Contribution'),
+              default: false,
+              description: t('Compute the contribution to the total'),
+            },
+          },
+        ],
+        ['row_limit'],
+      ],
+    },
+    {
+      label: t('Time Series Options'),
+      expanded: true,
+      controlSetRows: [
+        [
+          {
+            name: 'time_series_option',
+            config: {
+              type: 'SelectControl',
+              label: t('Options'),
+              validators: [validateNonEmpty],
+              default: 'not_time',
+              valueKey: 'value',
+              options: [
+                {
+                  label: t('Not Time Series'),
+                  value: 'not_time',
+                  description: t('Ignore time'),
+                },
+                {
+                  label: t('Time Series'),
+                  value: 'time_series',
+                  description: t('Standard time series'),
+                },
+                {
+                  label: t('Aggregate Mean'),
+                  value: 'agg_mean',
+                  description: t('Mean of values over specified period'),
+                },
+                {
+                  label: t('Aggregate Sum'),
+                  value: 'agg_sum',
+                  description: t('Sum of values over specified period'),
+                },
+                {
+                  label: t('Difference'),
+                  value: 'point_diff',
+                  description: t(
+                    'Metric change in value from `since` to `until`',
+                  ),
+                },
+                {
+                  label: t('Percent Change'),
+                  value: 'point_percent',
+                  description: t(
+                    'Metric percent change in value from `since` to `until`',
+                  ),
+                },
+                {
+                  label: t('Factor'),
+                  value: 'point_factor',
+                  description: t(
+                    'Metric factor change from `since` to `until`',
+                  ),
+                },
+                {
+                  label: t('Advanced Analytics'),
+                  value: 'adv_anal',
+                  description: t('Use the Advanced Analytics options below'),
+                },
+              ],
+              optionRenderer: (op: ColumnMeta) => (
+                <OptionDescription option={op} />
+              ),
+              valueRenderer: (op: ColumnMeta) => (
+                <OptionDescription option={op} />
+              ),
+              description: t('Settings for time series'),
+            },
+          },
+        ],
+      ],
+    },
+    {
+      label: t('Chart Options'),
+      expanded: true,
+      tabOverride: 'customize',
+      controlSetRows: [
+        ['color_scheme'],
+        [
+          {
+            name: 'number_format',
+            config: {
+              type: 'SelectControl',
+              freeForm: true,
+              label: t('Number format'),
+              renderTrigger: true,
+              default: 'SMART_NUMBER',
+              choices: D3_FORMAT_OPTIONS,
+              description: D3_FORMAT_DOCS,
+            },
+          },
+          {
+            name: 'date_time_format',
+            config: {
+              type: 'SelectControl',
+              freeForm: true,
+              label: t('Date Time Format'),
+              renderTrigger: true,
+              default: 'smart_date',
+              choices: D3_TIME_FORMAT_OPTIONS,
+              description: D3_FORMAT_DOCS,
+            },
+          },
+        ],
+        [
+          {
+            name: 'partition_limit',
+            config: {
+              type: 'TextControl',
+              label: t('Partition Limit'),
+              isInt: true,
+              default: '5',
+              description: t(
+                'The maximum number of subdivisions of each group; ' +
+                  'lower values are pruned first',
+              ),
+            },
+          },
+          {
+            name: 'partition_threshold',
+            config: {
+              type: 'TextControl',
+              label: t('Partition Threshold'),
+              isFloat: true,
+              default: '0.05',
+              description: t(
+                'Partitions whose height to parent height proportions are ' +
+                  'below this value are pruned',
+              ),
+            },
+          },
+        ],
+        [
+          {
+            name: 'log_scale',
+            config: {
+              type: 'CheckboxControl',
+              label: t('Log Scale'),
+              default: false,
+              renderTrigger: true,
+              description: t('Use a log scale'),
+            },
+          },
+        ],
+        [
+          {
+            name: 'equal_date_size',
+            config: {
+              type: 'CheckboxControl',
+              label: t('Equal Date Sizes'),
+              default: true,
+              renderTrigger: true,
+              description: t(
+                'Check to force date partitions to have the same height',
+              ),
+            },
+          },
+        ],
+        [
+          {
+            name: 'rich_tooltip',
+            config: {
+              type: 'CheckboxControl',
+              label: t('Rich Tooltip'),
+              renderTrigger: true,
+              default: true,
+              description: t(
+                'The rich tooltip shows a list of all series for that point in time',
+              ),
+            },
+          },
+        ],
+      ],
+    },
+    {
+      label: t('Advanced Analytics'),
+      tabOverride: 'data',
+      description: t(
+        'This section contains options ' +
+          'that allow for advanced analytical post processing ' +
+          'of query results',
+      ),
+      controlSetRows: [
+        // eslint-disable-next-line react/jsx-key
+        [
+          <ControlSubSectionHeader>
+            {t('Rolling Window')}
+          </ControlSubSectionHeader>,
+        ],
+        [
+          {
+            name: 'rolling_type',
+            config: {
+              type: 'SelectControl',
+              label: t('Rolling Function'),
+              default: 'None',
+              choices: [
+                ['None', t('None')],
+                ['mean', t('mean')],
+                ['sum', t('sum')],
+                ['std', t('std')],
+                ['cumsum', t('cumsum')],
+              ],
+              description: t(
+                'Defines a rolling window function to apply, works along ' +
+                  'with the [Periods] text box',
+              ),
+            },
+          },
+        ],
+        [
+          {
+            name: 'rolling_periods',
+            config: {
+              type: 'TextControl',
+              label: t('Periods'),
+              isInt: true,
+              description: t(
+                'Defines the size of the rolling window function, ' +
+                  'relative to the time granularity selected',
+              ),
+            },
+          },
+          {
+            name: 'min_periods',
+            config: {
+              type: 'TextControl',
+              label: t('Min Periods'),
+              isInt: true,
+              description: t(
+                'The minimum number of rolling periods required to show ' +
+                  'a value. For instance if you do a cumulative sum on 7 days ' +
+                  'you may want your "Min Period" to be 7, so that all data points ' +
+                  'shown are the total of 7 periods. This will hide the "ramp up" ' +
+                  'taking place over the first 7 periods',
+              ),
+            },
+          },
+        ],
+        // eslint-disable-next-line react/jsx-key
+        [
+          <ControlSubSectionHeader>
+            {t('Time Comparison')}
+          </ControlSubSectionHeader>,
+        ],
+        [
+          {
+            name: 'time_compare',
+            config: {
+              type: 'SelectControl',
+              multi: true,
+              freeForm: true,
+              label: t('Time Shift'),
+              choices: [
+                ['1 day', t('1 day')],
+                ['1 week', t('1 week')],
+                ['28 days', t('28 days')],
+                ['30 days', t('30 days')],
+                ['52 weeks', t('52 weeks')],
+                ['1 year', t('1 year')],
+                ['104 weeks', t('104 weeks')],
+                ['2 years', t('2 years')],
+                ['156 weeks', t('156 weeks')],
+                ['3 years', t('3 years')],
+              ],
+              description: t(
+                'Overlay one or more timeseries from a ' +
+                  'relative time period. Expects relative time deltas ' +
+                  'in natural language (example: 24 hours, 7 days, ' +
+                  '52 weeks, 365 days). Free text is supported.',
+              ),
+            },
+          },
+          {
+            name: 'comparison_type',
+            config: {
+              type: 'SelectControl',
+              label: t('Calculation type'),
+              default: 'values',
+              choices: [
+                ['values', t('Actual Values')],
+                ['absolute', t('Difference')],
+                ['percentage', t('Percentage change')],
+                ['ratio', t('Ratio')],
+              ],
+              description: t(
+                'How to display time shifts: as individual lines; as the ' +
+                  'difference between the main time series and each time shift; ' +
+                  'as the percentage change; or as the ratio between series and time shifts.',
+              ),
+            },
+          },
+        ],
+        [<ControlSubSectionHeader>{t('Resample')}</ControlSubSectionHeader>],
+        [
+          {
+            name: 'resample_rule',
+            config: {
+              type: 'SelectControl',
+              freeForm: true,
+              label: t('Rule'),
+              default: null,
+              choices: [
+                ['1T', t('1T')],
+                ['1H', t('1H')],
+                ['1D', t('1D')],
+                ['7D', t('7D')],
+                ['1M', t('1M')],
+                ['1AS', t('1AS')],
+              ],
+              description: t('Pandas resample rule'),
+            },
+          },
+          {
+            name: 'resample_method',
+            config: {
+              type: 'SelectControl',
+              freeForm: true,
+              label: t('Method'),
+              default: null,
+              choices: [
+                ['asfreq', t('asfreq')],
+                ['bfill', t('bfill')],
+                ['ffill', t('ffill')],
+                ['median', t('median')],
+                ['mean', t('mean')],
+                ['sum', t('sum')],
+              ],
+              description: t('Pandas resample method'),
+            },
+          },
+        ],
+      ],
+    },
+  ],
+  formDataOverrides: formData => ({
+    ...formData,
+    groupby: getStandardizedControls().popAllColumns(),
+    metrics: getStandardizedControls().popAllMetrics(),
+  }),
+};
+
+export default config;
diff --git a/superset-frontend/plugins/legacy-plugin-chart-partition/src/index.ts b/superset-frontend/plugins/legacy-plugin-chart-partition/src/index.ts
new file mode 100644
index 00000000000..0ae654105c5
--- /dev/null
+++ b/superset-frontend/plugins/legacy-plugin-chart-partition/src/index.ts
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { t } from '@apache-superset/core/translation';
+import { ChartMetadata, ChartPlugin } from '@superset-ui/core';
+import transformProps from './transformProps';
+import thumbnail from './images/thumbnail.png';
+import thumbnailDark from './images/thumbnail-dark.png';
+import example from './images/example.jpg';
+import exampleDark from './images/example-dark.jpg';
+import controlPanel from './controlPanel';
+
+const metadata = new ChartMetadata({
+  category: t('Part of a Whole'),
+  description: t('Compare the same summarized metric across multiple groups.'),
+  exampleGallery: [{ url: example, urlDark: exampleDark }],
+  name: t('Partition Chart'),
+  tags: [t('Categorical'), t('Comparison'), t('Legacy'), t('Proportional')],
+  thumbnail,
+  thumbnailDark,
+  useLegacyApi: true,
+});
+
+export default class PartitionChartPlugin extends ChartPlugin {
+  constructor() {
+    super({
+      loadChart: () => import('./ReactPartition'),
+      metadata,
+      transformProps,
+      controlPanel,
+    });
+  }
+}
diff --git a/superset-frontend/plugins/legacy-plugin-chart-partition/src/transformProps.ts b/superset-frontend/plugins/legacy-plugin-chart-partition/src/transformProps.ts
new file mode 100644
index 00000000000..1422701dab2
--- /dev/null
+++ b/superset-frontend/plugins/legacy-plugin-chart-partition/src/transformProps.ts
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { ChartProps } from '@superset-ui/core';
+
+export default function transformProps(chartProps: ChartProps) {
+  const { width, height, datasource, formData, queriesData } = chartProps;
+  const {
+    colorScheme,
+    dateTimeFormat,
+    equalDateSize,
+    groupby,
+    logScale,
+    metrics,
+    numberFormat,
+    partitionLimit,
+    partitionThreshold,
+    richTooltip,
+    timeSeriesOption,
+    sliceId,
+  } = formData;
+  const { verboseMap = {} } = datasource;
+
+  return {
+    width,
+    height,
+    data: queriesData[0].data,
+    colorScheme,
+    dateTimeFormat,
+    equalDateSize,
+    levels: groupby.map((g: string) => verboseMap[g] || g),
+    metrics,
+    numberFormat,
+    partitionLimit: partitionLimit && parseInt(partitionLimit, 10),
+    partitionThreshold: partitionThreshold && parseInt(partitionThreshold, 10),
+    timeSeriesOption,
+    useLogScale: logScale,
+    useRichTooltip: richTooltip,
+    sliceId,
+  };
+}