You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by kg...@apache.org on 2023/08/28 11:56:15 UTC

[superset] branch master updated: chore: Refactor deck.gl plugins to Typescript (#24933)

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

kgabryje pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 4c4fedc452 chore: Refactor deck.gl plugins to Typescript (#24933)
4c4fedc452 is described below

commit 4c4fedc452c89add0f4b23f131138c09b363d185
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Mon Aug 28 13:56:06 2023 +0200

    chore: Refactor deck.gl plugins to Typescript (#24933)
---
 superset-frontend/package-lock.json                | 2597 +++++++++++---------
 .../superset-ui-chart-controls/src/types.ts        |    2 +-
 .../test/utils/columnChoices.test.tsx              |    2 +-
 .../test/utils/defineSavedMetrics.test.tsx         |    2 +-
 .../legacy-preset-chart-deckgl/package.json        |    8 +-
 .../src/AnimatableDeckGLContainer.jsx              |  117 -
 ...ontainer.jsx => CategoricalDeckGLContainer.tsx} |  158 +-
 .../{DeckGLContainer.jsx => DeckGLContainer.tsx}   |   77 +-
 .../legacy-preset-chart-deckgl/src/Multi/Multi.jsx |  147 --
 .../legacy-preset-chart-deckgl/src/Multi/Multi.tsx |  171 ++
 .../src/Multi/{controlPanel.js => controlPanel.ts} |    6 +-
 .../src/Multi/{index.js => index.ts}               |    0
 .../src/{TooltipRow.jsx => TooltipRow.tsx}         |   11 +-
 .../src/components/BootstrapSliderWrapper.jsx      |   41 -
 .../src/components/{Legend.jsx => Legend.tsx}      |  125 +-
 .../src/components/PlaySlider.jsx                  |  232 --
 .../src/components/Tooltip.tsx                     |    4 +-
 .../legacy-preset-chart-deckgl/src/factory.tsx     |   32 +-
 .../src/{index.js => index.ts}                     |    0
 .../src/layers/Arc/{Arc.jsx => Arc.tsx}            |   28 +-
 .../src/layers/Arc/{index.js => index.ts}          |    0
 .../layers/Geojson/{Geojson.jsx => Geojson.tsx}    |  101 +-
 .../src/layers/Geojson/{index.js => index.ts}      |    0
 .../src/layers/Grid/{Grid.jsx => Grid.tsx}         |   30 +-
 .../src/layers/Grid/{index.js => index.ts}         |    0
 .../src/layers/Heatmap/Heatmap.tsx                 |   12 +-
 .../src/layers/Hex/{Hex.jsx => Hex.tsx}            |   32 +-
 .../src/layers/Hex/{index.js => index.ts}          |    0
 .../src/layers/Path/{Path.jsx => Path.tsx}         |   22 +-
 .../src/layers/Path/{index.js => index.ts}         |    0
 .../layers/Polygon/{Polygon.jsx => Polygon.tsx}    |  206 +-
 .../src/layers/Polygon/{index.js => index.ts}      |    0
 .../layers/Scatter/{Scatter.jsx => Scatter.tsx}    |   38 +-
 .../src/layers/Scatter/{index.js => index.ts}      |    0
 .../Screengrid/{Screengrid.jsx => Screengrid.tsx}  |  157 +-
 .../src/layers/Screengrid/{index.js => index.ts}   |    0
 .../src/layers/{common.jsx => common.tsx}          |   44 +-
 .../src/layers/{index.js => index.ts}              |    0
 .../src/{preset.js => preset.ts}                   |    0
 .../src/{transformProps.js => transformProps.ts}   |    5 +-
 .../src/utilities/Shared_DeckGL.jsx                |    2 +-
 .../src/utilities/{controls.jsx => controls.ts}    |   21 +-
 ...sharedDndControls.jsx => sharedDndControls.tsx} |    0
 .../src/utilities/utils.js                         |   90 -
 .../src/{utils/utils.js => utilities/utils.ts}     |   14 +-
 .../src/{utils.js => utils.ts}                     |   89 +-
 .../src/utils/{colors.js => colors.ts}             |    5 +-
 .../src/utils/{explore.js => explore.ts}           |   13 +-
 .../src/utils/fitViewport.ts                       |    2 +-
 .../src/utils/{geo.js => geo.ts}                   |   24 +-
 .../utils/{safeStringify.js => safeStringify.ts}   |    4 +-
 .../src/utils/{sandbox.js => sandbox.ts}           |    8 +-
 .../legacy-preset-chart-deckgl/src/utils/time.js   |  135 -
 .../test/utils/{colors.test.js => colors.test.ts}  |    0
 .../legacy-preset-chart-deckgl/types/external.d.ts |   29 +-
 55 files changed, 2311 insertions(+), 2532 deletions(-)

diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 1e9eca6f27..694cfd9193 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -5072,189 +5072,6 @@
       "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz",
       "integrity": "sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg=="
     },
-    "node_modules/@deck.gl/aggregation-layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.5.2.tgz",
-      "integrity": "sha512-oiqXPmyn2v0lX9tWCvgmWs29stHSLS3tje71Ff2FVXDNmvP5FoZItFa8y7O7KSTkej2/rSwZeSte/a9pri6Njg==",
-      "dependencies": {
-        "@luma.gl/shadertools": "^8.5.4",
-        "@math.gl/web-mercator": "^3.5.3",
-        "d3-hexbin": "^0.2.1"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0",
-        "@deck.gl/layers": "^8.0.0"
-      }
-    },
-    "node_modules/@deck.gl/carto": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/carto/-/carto-8.5.2.tgz",
-      "integrity": "sha512-Kw/3NUM+2NcHjxH6b7IOUYXEwmJ4SNQujFzAVFW5amG4Lut8074NGSF5XHi+4M/zgk7vXDFsGRxLqspsA/dg8w==",
-      "dependencies": {
-        "@loaders.gl/loader-utils": "^3.0.6",
-        "@loaders.gl/mvt": "^3.0.6",
-        "@loaders.gl/tiles": "^3.0.6",
-        "@math.gl/web-mercator": "^3.5.3",
-        "cartocolor": "^4.0.2",
-        "d3-scale": "^3.2.3"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0",
-        "@deck.gl/geo-layers": "^8.0.0",
-        "@deck.gl/layers": "^8.0.0",
-        "@loaders.gl/core": "^3.0.0"
-      }
-    },
-    "node_modules/@deck.gl/carto/node_modules/d3-array": {
-      "version": "2.12.1",
-      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
-      "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
-      "dependencies": {
-        "internmap": "^1.0.0"
-      }
-    },
-    "node_modules/@deck.gl/carto/node_modules/d3-scale": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
-      "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
-      "dependencies": {
-        "d3-array": "^2.3.0",
-        "d3-format": "1 - 2",
-        "d3-interpolate": "1.2.0 - 2",
-        "d3-time": "^2.1.1",
-        "d3-time-format": "2 - 3"
-      }
-    },
-    "node_modules/@deck.gl/carto/node_modules/d3-time": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
-      "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
-      "dependencies": {
-        "d3-array": "2"
-      }
-    },
-    "node_modules/@deck.gl/core": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.5.2.tgz",
-      "integrity": "sha512-SAFv7fKx6k1Rj8R4qTMQO2wEhEfixROzbcoSS6RivxrfES00KYYj6jJ7iNEnq3dFn6qc37LPpxqtYYHO4BcvYA==",
-      "dependencies": {
-        "@loaders.gl/core": "^3.0.6",
-        "@loaders.gl/images": "^3.0.6",
-        "@luma.gl/core": "^8.5.4",
-        "@math.gl/web-mercator": "^3.5.3",
-        "gl-matrix": "^3.0.0",
-        "math.gl": "^3.5.3",
-        "mjolnir.js": "^2.5.0",
-        "probe.gl": "^3.4.0"
-      }
-    },
-    "node_modules/@deck.gl/extensions": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-8.5.2.tgz",
-      "integrity": "sha512-VhbQsMNPM7RCR/ERwb1u1x0rEWAxgXfcCWttW+gYvbiagW/LrAJ22jhOghlRW/wilEmupHYbXQlWkW2V/mYfsg==",
-      "dependencies": {
-        "@luma.gl/shadertools": "^8.5.4"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0",
-        "gl-matrix": "^3.0.0"
-      }
-    },
-    "node_modules/@deck.gl/geo-layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-8.5.2.tgz",
-      "integrity": "sha512-t6+TgAdbKWDw8g9UX1y6D+5twcdJuKaXw4qSib/0yVurWi/Mil5Plihybt1l9uBZuwkr+UcpxPR73zzo+qd9MA==",
-      "dependencies": {
-        "@loaders.gl/3d-tiles": "^3.0.6",
-        "@loaders.gl/gis": "^3.0.6",
-        "@loaders.gl/loader-utils": "^3.0.6",
-        "@loaders.gl/mvt": "^3.0.6",
-        "@loaders.gl/terrain": "^3.0.6",
-        "@loaders.gl/tiles": "^3.0.6",
-        "@luma.gl/experimental": "^8.5.4",
-        "@math.gl/culling": "^3.5.3",
-        "@math.gl/web-mercator": "^3.5.3",
-        "h3-js": "^3.6.0",
-        "long": "^3.2.0",
-        "math.gl": "^3.5.3"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0",
-        "@deck.gl/extensions": "^8.0.0",
-        "@deck.gl/layers": "^8.0.0",
-        "@deck.gl/mesh-layers": "^8.0.0",
-        "@loaders.gl/core": "^3.0.0"
-      }
-    },
-    "node_modules/@deck.gl/google-maps": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-8.5.2.tgz",
-      "integrity": "sha512-Dk3ozenBWgt9nFSYOT4N82urNW/JhiMszfFq6zLt3jUp0N7EJ9d2XO81hclM59BhjIdGWb6drTe96NvtbabVLQ==",
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0"
-      }
-    },
-    "node_modules/@deck.gl/json": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-8.5.2.tgz",
-      "integrity": "sha512-lVS16bvPfLUSidgBURZvGbWEjgK8GjLWlp1iGuLvua2W6TnWIyiKa6a3XoebgeXd8kqwSbQxhNnuSVPX+Di6Rg==",
-      "dependencies": {
-        "d3-dsv": "^1.0.8",
-        "expression-eval": "^2.0.0"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0"
-      }
-    },
-    "node_modules/@deck.gl/layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.5.2.tgz",
-      "integrity": "sha512-HmpE3qf9CI7sU/xa2DMCNg31pzpzK5XuUHyC70dsLq8AV7Sm3vZQz17KMU/CWSZpVr7yQ8uxTeSQARiv/zeOFQ==",
-      "dependencies": {
-        "@loaders.gl/images": "^3.0.6",
-        "@mapbox/tiny-sdf": "^1.1.0",
-        "@math.gl/polygon": "^3.5.3",
-        "earcut": "^2.0.6"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0",
-        "@loaders.gl/core": "^3.0.0"
-      }
-    },
-    "node_modules/@deck.gl/mapbox": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.5.2.tgz",
-      "integrity": "sha512-nMpzfdPFBVthT+EMgIcKo4YO6bZCqADQtqnxIFtfofZIiKS6R5OSuJ3sXPSNZ9ReCJGzdmndEz7/Qtm9Sia/bA==",
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0"
-      }
-    },
-    "node_modules/@deck.gl/mesh-layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-8.5.2.tgz",
-      "integrity": "sha512-dUfQyGjm5CYQg9AQdRsGtEEXGSGHxifPlws0zWWoj1r757wjqM0aZ663TUJEsJQDTLNOvbBLGTiuFeCBUoKO4Q==",
-      "dependencies": {
-        "@loaders.gl/gltf": "^3.0.6",
-        "@luma.gl/experimental": "^8.5.4",
-        "@luma.gl/shadertools": "^8.5.4"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0"
-      }
-    },
-    "node_modules/@deck.gl/react": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.5.2.tgz",
-      "integrity": "sha512-h7AJ9nPY1PTjrAVP7T1fvWDChWZrVOsEfYIoEP4W6ILSjvDqEQfVL0+9RhjUwQV2nKrg0QmpqCmbfOrgKQQbYw==",
-      "dependencies": {
-        "prop-types": "^15.6.0"
-      },
-      "peerDependencies": {
-        "@deck.gl/core": "^8.0.0",
-        "react": ">=16.3",
-        "react-dom": ">=16.3"
-      }
-    },
     "node_modules/@discoveryjs/json-ext": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -10140,186 +9957,272 @@
       }
     },
     "node_modules/@loaders.gl/3d-tiles": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-3.0.8.tgz",
-      "integrity": "sha512-jZeOyDPGD2wEkTLW4Do9A4UUQ+OGjhhNXztB0AsttZ69OpkmsxJXb76xxwevf+eThrsTgSTjZ06eC5DHX0kyXA==",
-      "dependencies": {
-        "@loaders.gl/core": "3.0.8",
-        "@loaders.gl/draco": "3.0.8",
-        "@loaders.gl/gltf": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/math": "3.0.8",
-        "@loaders.gl/tiles": "3.0.8",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-3.4.8.tgz",
+      "integrity": "sha512-v4Ejtp4Pb5RhFQyI37oDy9IZtBKEUZ+2xWNtyDgeV8Vni5ht532hsPVGY8CkUMMZFAyzl3zcDFUQo0cIbiqKKg==",
+      "dependencies": {
+        "@loaders.gl/draco": "3.4.8",
+        "@loaders.gl/gltf": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/math": "3.4.8",
+        "@loaders.gl/tiles": "3.4.8",
         "@math.gl/core": "^3.5.1",
-        "@math.gl/geospatial": "^3.5.1"
+        "@math.gl/geospatial": "^3.5.1",
+        "long": "^5.2.1"
+      },
+      "peerDependencies": {
+        "@loaders.gl/core": "^3.4.0"
       }
     },
+    "node_modules/@loaders.gl/3d-tiles/node_modules/long": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+      "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+    },
     "node_modules/@loaders.gl/core": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-3.0.8.tgz",
-      "integrity": "sha512-FIfbhMkoRX2JonEHXHgClC7jwOSsEwvvmjlaTMRAY+gFKvJPGmegkp4VgUZquLFf6GedJt/1TuMMvAX6gdq1pg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-3.4.8.tgz",
+      "integrity": "sha512-pAaAISNmxiUQn8iz0yDhX5DCt3geaaJtSTxAHgz25G2Z5kWqYS00g5bc7XIGNT2BwqD5pgVLRch+BdTQ/Q8lJA==",
       "dependencies": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/worker-utils": "3.0.8",
-        "probe.gl": "^3.4.0"
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/worker-utils": "3.4.8",
+        "@probe.gl/log": "^4.0.1"
+      }
+    },
+    "node_modules/@loaders.gl/core/node_modules/@probe.gl/env": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-4.0.4.tgz",
+      "integrity": "sha512-sYNGqesDfWD6dFP5oNZtTeFA4Z6ak5T4a8BNPdNhoqy7PK9w70JHrb6mv+RKWqKXq33KiwCDWL7fYxx2HuEH2w==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "node_modules/@loaders.gl/core/node_modules/@probe.gl/log": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-4.0.4.tgz",
+      "integrity": "sha512-WpmXl6njlBMwrm8HBh/b4kSp/xnY1VVmeT4PWUKF+RkVbFuKQbsU11dA1IxoMd7gSY+5DGIwxGfAv1H5OMzA4A==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@probe.gl/env": "4.0.4"
       }
     },
     "node_modules/@loaders.gl/draco": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-3.0.8.tgz",
-      "integrity": "sha512-ZCXzXNHWQ7H0qk/kC+rWzjMWjLzZGzQcDbdpIuy8xJdp4rTpmMkLUseFPby8vhkmIaqxWPwPB6mx/vM7L6JENg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-3.4.8.tgz",
+      "integrity": "sha512-x127QX/CCzbSXTk5IL4WBmL6RjvMZhedzMoEiWE4NhAEiwTFKXvWUZLluoFlGzJhxSL6xiR2KBF8tN1EMv4L1Q==",
       "dependencies": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/schema": "3.0.8",
-        "@loaders.gl/worker-utils": "3.0.8",
-        "draco3d": "1.4.1"
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "@loaders.gl/worker-utils": "3.4.8",
+        "draco3d": "1.5.5"
       }
     },
     "node_modules/@loaders.gl/gis": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-3.0.8.tgz",
-      "integrity": "sha512-7NL+lIb7NezlMupYskVil6M3RZunXJl+TyaVAW82GLbzPSOq+m/G7h3+z0GBa8iv/U/I+cB5BhSN+GZmvFwqEA==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-3.4.8.tgz",
+      "integrity": "sha512-I0Q8n1XhxXfZ6QoHvW6ayUkrOiifARGvSm4xTZxkydFNM5MULp9ICrZkFeqGMAVeevbssR3h9JKR111AmQvrPw==",
       "dependencies": {
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/schema": "3.0.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
         "@mapbox/vector-tile": "^1.3.1",
+        "@math.gl/polygon": "^3.5.1",
         "pbf": "^3.2.1"
       }
     },
     "node_modules/@loaders.gl/gltf": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-3.0.8.tgz",
-      "integrity": "sha512-4PXWTlqyvlbZE2Vp4iQ+Y87ZO1WuRvSlbImDhygd0hoINfmJ9ObxrFS3yJcpJTu007nWxXorNVEOKyuoo+4Iyw==",
-      "dependencies": {
-        "@loaders.gl/core": "3.0.8",
-        "@loaders.gl/draco": "3.0.8",
-        "@loaders.gl/images": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8"
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-3.4.8.tgz",
+      "integrity": "sha512-nvDj0LmkOXtQWUr7MkGShQ2WUmZlUnWTs6PatPxueevdL49vR16SB8VAWTx+8XUPq3Wno+gVZJxG8HBRkFVHng==",
+      "dependencies": {
+        "@loaders.gl/draco": "3.4.8",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/textures": "3.4.8",
+        "@math.gl/core": "^3.5.1"
       }
     },
     "node_modules/@loaders.gl/images": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-3.0.8.tgz",
-      "integrity": "sha512-rO2cIYJYlMs/uO9YSoF4/BEA4p/9xQ3gHZ1sIJkPYVnDqzpbu8nvUjWTQqIdL/MkQBTW8tz3twCdM+B6G9Fa2w==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-3.4.8.tgz",
+      "integrity": "sha512-cKoQ20aMBgBXYKVVJuDLuH1wTeXZyinbG4otSBf4D+gAhQ09Gd3dVMYF7RWIxXp0CdL4jiqGHnJ470y0AvrT4w==",
       "dependencies": {
-        "@loaders.gl/loader-utils": "3.0.8"
+        "@loaders.gl/loader-utils": "3.4.8"
       }
     },
     "node_modules/@loaders.gl/loader-utils": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-3.0.8.tgz",
-      "integrity": "sha512-PW1WyyQ+LXkqoGHBZHsmfNQkKiLAYf1gok+kHnHvY9fCzhJeA1iTNEUKPXGXKgS00m/k5cBTkOWAaOG9KRvBCQ==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-3.4.8.tgz",
+      "integrity": "sha512-/3sZ2J3Y29t50HSo6X6mtLNDYID+s77cmFWxjq+R4/uDekYx2vmgiw/WCFbupKse6NrAKe1KgqEBac1Q7yARSQ==",
       "dependencies": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/worker-utils": "3.0.8",
-        "@probe.gl/stats": "^3.4.0"
+        "@loaders.gl/worker-utils": "3.4.8",
+        "@probe.gl/stats": "^4.0.1"
+      }
+    },
+    "node_modules/@loaders.gl/loader-utils/node_modules/@probe.gl/stats": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.0.4.tgz",
+      "integrity": "sha512-SDuSY/D4yDL6LQDa69l/GCcnZLRiGYdyvYkxWb0CgnzTPdPrcdrzGkzkvpC3zsA4fEFw2smlDje370QGHwlisg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0"
       }
     },
     "node_modules/@loaders.gl/math": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-3.0.8.tgz",
-      "integrity": "sha512-jfFpxxr4Bq5JfOPqLVJc4JJGoGGvVTOCWiJhnTtSAKhaNSwldmNWaZ0w8E2nlgPKPMAHiTRKOQnd9sSY5m66Cw==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-3.4.8.tgz",
+      "integrity": "sha512-+9Hy1k44tj+v8IYKh+Zp0xXOijH94HoT/8ILdt5kG8MdjDU6VYyz2t/D4ZawSM+DBgXLYhDIIKkqrdND5ct2AQ==",
       "dependencies": {
-        "@loaders.gl/images": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
         "@math.gl/core": "^3.5.1"
       }
     },
     "node_modules/@loaders.gl/mvt": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-3.0.8.tgz",
-      "integrity": "sha512-Jk1QTHgpxMsUT01w5IJJ2en9qq0yOZcL2wGXVc7CFp2h6inB22rC3drUwq1mUNGe6iy3EWIo7EeJVd9B+5JyTQ==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-3.4.8.tgz",
+      "integrity": "sha512-JvgSsg7+oypRAhGmUKvLSH8h146HRopxf25c9hzyPWX1MeAPfVWgwTou0syy5TwOyRlrLtGp4Rs/6AmNAWBtnw==",
       "dependencies": {
-        "@loaders.gl/gis": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
+        "@loaders.gl/gis": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
         "@math.gl/polygon": "^3.5.1",
         "pbf": "^3.2.1"
       }
     },
     "node_modules/@loaders.gl/schema": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-3.0.8.tgz",
-      "integrity": "sha512-yne5WE7fZZWFl2zF8fzDlYhPVJua6h6mTCSmlQ5pryaMXTZS9mfzXXIFWRL3kswqnQTu/QNFdyFj1mP0haF24w==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-3.4.8.tgz",
+      "integrity": "sha512-nu+mT8LgeoCF65xs+F9qegJsIWqYOzwkzJLEd7zmHGRMMYqaFDqcp63J3CUQy+UvS4dGTZph38aQuVfncS/fJA==",
       "dependencies": {
-        "@types/geojson": "^7946.0.7",
-        "apache-arrow": "^4.0.0",
-        "d3-dsv": "^1.2.0"
+        "@types/geojson": "^7946.0.7"
       }
     },
     "node_modules/@loaders.gl/terrain": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-3.0.8.tgz",
-      "integrity": "sha512-MtOAYEB/xJB4CN4B0YNPkO4v1ZY332joxiOHQI1x37x4sWVAqOrKLr9jB42sZCB8aINi2WMWGiErtf9wh9L5Pg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-3.4.8.tgz",
+      "integrity": "sha512-bWLePOb6+4N8DNMXP0D3aqkwyU3phuUjzjQLvfoP9dySUuX4E9kwarCcmkaCYyqp2swp57cHaylSd6tHXOFR6w==",
       "dependencies": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/schema": "3.0.8",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
         "@mapbox/martini": "^0.2.0"
       }
     },
+    "node_modules/@loaders.gl/textures": {
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/textures/-/textures-3.4.8.tgz",
+      "integrity": "sha512-lFlV1/3yQqBANP5FoywuQwh+Br++BU3/6eT/Eb/zDbKOqTuqtHp7yAUz207tAO3mRqTkPvtKi9fv+0QrBGoxtw==",
+      "dependencies": {
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "@loaders.gl/worker-utils": "3.4.8",
+        "ktx-parse": "^0.0.4",
+        "texture-compressor": "^1.0.2"
+      }
+    },
     "node_modules/@loaders.gl/tiles": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-3.0.8.tgz",
-      "integrity": "sha512-Rc+yHFdQg2sYmcYkwvszukFWdm9EW354F9HUR7y/oauos6tsdo4YTj31zgytaYR63/EqWQ7kwI29/eePEcutzg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-3.4.8.tgz",
+      "integrity": "sha512-rA3ULOokiUTH6Y3sr37wGaTx3P0g/hRti9yB6q/8kSBy+fE1gSD801O4VluNx6DbOELR2zWkM8TqLTep6sBN1A==",
       "dependencies": {
-        "@loaders.gl/core": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/math": "3.0.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/math": "3.4.8",
         "@math.gl/core": "^3.5.1",
         "@math.gl/culling": "^3.5.1",
         "@math.gl/geospatial": "^3.5.1",
         "@math.gl/web-mercator": "^3.5.1",
-        "@probe.gl/stats": "^3.4.0"
+        "@probe.gl/stats": "^4.0.1"
+      },
+      "peerDependencies": {
+        "@loaders.gl/core": "^3.4.0"
+      }
+    },
+    "node_modules/@loaders.gl/tiles/node_modules/@probe.gl/stats": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.0.4.tgz",
+      "integrity": "sha512-SDuSY/D4yDL6LQDa69l/GCcnZLRiGYdyvYkxWb0CgnzTPdPrcdrzGkzkvpC3zsA4fEFw2smlDje370QGHwlisg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "node_modules/@loaders.gl/wms": {
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/wms/-/wms-3.4.8.tgz",
+      "integrity": "sha512-4ESwVUa6dStmGqHIqdz6XFo/b/uyB6O+A1iy/mhMGTW8JodrzTcPQl5Iq8fA6EEYP0xviXFL652IEn+dR/BsGg==",
+      "dependencies": {
+        "@babel/runtime": "^7.3.1",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "@loaders.gl/xml": "3.4.8",
+        "@turf/rewind": "^5.1.5",
+        "deep-strict-equal": "^0.2.0",
+        "lerc": "^4.0.1"
       }
     },
     "node_modules/@loaders.gl/worker-utils": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-3.0.8.tgz",
-      "integrity": "sha512-Pg72HuXPcL725TrOlOr83xloVUHj6OMWmno1dI8ccuqfOBsgoRjxNZrcSvwBzfK8tFCzuN2X30I+mHl3BkuYLw==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-3.4.8.tgz",
+      "integrity": "sha512-cioo1rKtUkbDPJVQZ5ytEc6r/LdR1eIOCszgRh1VymtYvWGT+prZxfCIAmM1uZBV2SLWYTnH17dR0PR+cNopzA==",
       "dependencies": {
         "@babel/runtime": "^7.3.1"
       }
     },
+    "node_modules/@loaders.gl/xml": {
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/xml/-/xml-3.4.8.tgz",
+      "integrity": "sha512-8lrmdsnaobENpEPalEAzP720UY3kA/w6w7vCUKABB60QHnq+D5Rvw1PLPfQCACMFhYF+vR56KcQjtEbuqhs5wA==",
+      "dependencies": {
+        "@babel/runtime": "^7.3.1",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "fast-xml-parser": "^4.2.5"
+      }
+    },
     "node_modules/@luma.gl/constants": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.5.4.tgz",
-      "integrity": "sha512-lrA4ja92om/gDHYOvM9itL5S7FVzjKulyknDz6S+Y7gmgHgXk2ln1Xar5zUCsLnhAYx4glHITXGH5Y5rdWgT1Q=="
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.5.20.tgz",
+      "integrity": "sha512-5yG+ybkUZ4j6kLPWMZjN4Hun2yLB0MyEpNCRKAUN9/yS9UIWA7unyVxjSf2vnE7k/7dywtxlbXegASNFgNVGxw=="
     },
     "node_modules/@luma.gl/core": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-8.5.4.tgz",
-      "integrity": "sha512-+saDz1D3mcPd53vgbG60ryg1w5CF9Z2wdakKHzR810VoJLw97t4aNdg/eNgyWOvbOHxaKJBPm8K0sGjej67+jw==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-8.5.20.tgz",
+      "integrity": "sha512-xJr96G6vhYcznYHC84fbeOG3fgNM4lFwj9bd0VPcg/Kfe8otUeN1Hl0AKHCCtNn48PiMSg3LKbaiRfNUMhaffQ==",
       "dependencies": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "@luma.gl/engine": "8.5.4",
-        "@luma.gl/gltools": "8.5.4",
-        "@luma.gl/shadertools": "8.5.4",
-        "@luma.gl/webgl": "8.5.4"
+        "@luma.gl/constants": "8.5.20",
+        "@luma.gl/engine": "8.5.20",
+        "@luma.gl/gltools": "8.5.20",
+        "@luma.gl/shadertools": "8.5.20",
+        "@luma.gl/webgl": "8.5.20"
       }
     },
     "node_modules/@luma.gl/engine": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-8.5.4.tgz",
-      "integrity": "sha512-Sfv972IzvR9s9kKWugs67XQUh9jC0e/PpBrzvyGVnPU4XvFq42RZVF73pzEklVU6AlpR8Zg5CPtxGdhyOHtT7w==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-8.5.20.tgz",
+      "integrity": "sha512-+0ryJ/4gL1pWaEgZimY21jUPt1LYiO6Cqte8TNUprCfAHoAStsuzD7jwgEqnM6jJOUEdIxQ3w0z3Dzw/0KIE+w==",
       "dependencies": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "@luma.gl/gltools": "8.5.4",
-        "@luma.gl/shadertools": "8.5.4",
-        "@luma.gl/webgl": "8.5.4",
+        "@luma.gl/constants": "8.5.20",
+        "@luma.gl/gltools": "8.5.20",
+        "@luma.gl/shadertools": "8.5.20",
+        "@luma.gl/webgl": "8.5.20",
         "@math.gl/core": "^3.5.0",
-        "probe.gl": "^3.4.0"
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/stats": "^3.5.0",
+        "@types/offscreencanvas": "^2019.7.0"
       }
     },
     "node_modules/@luma.gl/experimental": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/experimental/-/experimental-8.5.4.tgz",
-      "integrity": "sha512-09waqRhgIrw+Sq0/in4tw4jPag5YsFfV1nEHJaLAg5RFv92S53IEubSJgkuG02HoOBkPxQ7KYvs9VNmriisnYg==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/experimental/-/experimental-8.5.20.tgz",
+      "integrity": "sha512-V1Jp68rYMPtwMdf+50r3NSYsGV3srjwZ+lcK2ew4DshjedDbYwLqTGMWcOyBhY3K3aCl2LH3Fhn0hAY+3NTLGA==",
       "dependencies": {
-        "@luma.gl/constants": "8.5.4",
+        "@luma.gl/constants": "8.5.20",
         "@math.gl/core": "^3.5.0",
         "earcut": "^2.0.6"
       },
@@ -10333,33 +10236,36 @@
       }
     },
     "node_modules/@luma.gl/gltools": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/gltools/-/gltools-8.5.4.tgz",
-      "integrity": "sha512-JotiPuymQz2Xc41AYlS2moJC/EHxU+OX/OMKi0+/MeOlEFLsdochgTA0I64j8yofLTXdeiGCneGtD1Ao8fk+bw==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/gltools/-/gltools-8.5.20.tgz",
+      "integrity": "sha512-5pP6ph9FSX5gHiVWQM1DmYRUnriklzKUG9yaqlQsKEqCFsOcKB0EfK3MfBVXIfsOdP/1bJZ9Dlz/zV19soWVhg==",
       "dependencies": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "probe.gl": "^3.4.0"
+        "@luma.gl/constants": "8.5.20",
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/log": "^3.5.0",
+        "@types/offscreencanvas": "^2019.7.0"
       }
     },
     "node_modules/@luma.gl/shadertools": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-8.5.4.tgz",
-      "integrity": "sha512-rwLBLrACi75aWnuJm8rVKCQnJR2sMTCxHuexfjHJ7Uecl0vVcVJZT7c9EnCFaz5LUTNbdupvuhq0SKNckKiKmw==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-8.5.20.tgz",
+      "integrity": "sha512-q1lrCZy1ncIFb4mMjsYgISLzNP6eMnhLUY+Oltj/qjAMcPEssCeHN2+XGfP/CVtU+O7sC+5JY2bQGaTs6HQ/Qw==",
       "dependencies": {
         "@babel/runtime": "^7.0.0",
         "@math.gl/core": "^3.5.0"
       }
     },
     "node_modules/@luma.gl/webgl": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-8.5.4.tgz",
-      "integrity": "sha512-dWy4dhTbtvDO9zQBdx1Yb+DxNx/1JWV9rhhJxJUtTKbGZSX0RjkASTT6GBWMl5jrH1JYJefS1wswHmmPVXjK0Q==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-8.5.20.tgz",
+      "integrity": "sha512-p/kt9KztywH4l+09XHoZ4cPFOoE7xlZXIBMT8rxRVgfe1w0lvi7QYh4tOG7gk+iixQ34EyDQacoHCsabdpmqQg==",
       "dependencies": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "@luma.gl/gltools": "8.5.4",
-        "probe.gl": "^3.4.0"
+        "@luma.gl/constants": "8.5.20",
+        "@luma.gl/gltools": "8.5.20",
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/stats": "^3.5.0"
       }
     },
     "node_modules/@mapbox/extent": {
@@ -10454,10 +10360,13 @@
       "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
       "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI="
     },
-    "node_modules/@mapbox/tiny-sdf": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz",
-      "integrity": "sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw=="
+    "node_modules/@mapbox/tile-cover": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@mapbox/tile-cover/-/tile-cover-3.0.1.tgz",
+      "integrity": "sha512-R8aoFY/87HWBOL9E2eBqzOY2lpfWYXCcTNgBpIxAv67rqQeD4IfnHD0iPXg/Z1cqXrklegEYZCp/7ZR/RsWqBQ==",
+      "dependencies": {
+        "tilebelt": "^1.0.1"
+      }
     },
     "node_modules/@mapbox/unitbezier": {
       "version": "0.0.0",
@@ -10490,13 +10399,23 @@
       }
     },
     "node_modules/@math.gl/culling": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-3.5.3.tgz",
-      "integrity": "sha512-ABpAcrvoIOLSm1EUkwgDem4RfO28HWPBs/+taZ/ZSpJG6KiVPklpKU1NCK+05HuJStkpFZ+XlWtehWU6FAMCyA==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-3.6.3.tgz",
+      "integrity": "sha512-3UERXHbaPlM6pnTk2MI7LeQ5CoelDZzDzghTTcv+HdQCZsT/EOEuEdYimETHtSxiyiOmsX2Un65UBLYT/rbKZg==",
       "dependencies": {
         "@babel/runtime": "^7.12.0",
-        "@math.gl/core": "3.5.3",
-        "gl-matrix": "^3.0.0"
+        "@math.gl/core": "3.6.3",
+        "gl-matrix": "^3.4.0"
+      }
+    },
+    "node_modules/@math.gl/culling/node_modules/@math.gl/core": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+      "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+      "dependencies": {
+        "@babel/runtime": "^7.12.0",
+        "@math.gl/types": "3.6.3",
+        "gl-matrix": "^3.4.0"
       }
     },
     "node_modules/@math.gl/geospatial": {
@@ -10510,20 +10429,43 @@
       }
     },
     "node_modules/@math.gl/polygon": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-3.5.3.tgz",
-      "integrity": "sha512-VktscmyQg/Rd56nJk0Nj/UyvnPDbsnZNMWCdl3G5AYenYzLWy6h4FEWhLx8pD+Xw7VuFot8LR4WAK2TPzXzrWw==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-3.6.3.tgz",
+      "integrity": "sha512-FivQ1ZnYcAss1wVifOkHP/ZnlfQy1IL/769uzNtiHxwUbW0kZG3yyOZ9I7fwyzR5Hvqt3ErJKHjSYZr0uVlz5g==",
+      "dependencies": {
+        "@math.gl/core": "3.6.3"
+      }
+    },
+    "node_modules/@math.gl/polygon/node_modules/@math.gl/core": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+      "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+      "dependencies": {
+        "@babel/runtime": "^7.12.0",
+        "@math.gl/types": "3.6.3",
+        "gl-matrix": "^3.4.0"
+      }
+    },
+    "node_modules/@math.gl/sun": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/sun/-/sun-3.6.3.tgz",
+      "integrity": "sha512-mrx6CGYYeTNSQttvcw0KVUy+35YDmnjMqpO/o0t06Vcghrt0HNruB/ScRgUSbJrgkbOg1Vcqm23HBd++clzQzw==",
       "dependencies": {
-        "@math.gl/core": "3.5.3"
+        "@babel/runtime": "^7.12.0"
       }
     },
+    "node_modules/@math.gl/types": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/types/-/types-3.6.3.tgz",
+      "integrity": "sha512-3uWLVXHY3jQxsXCr/UCNPSc2BG0hNUljhmOBt9l+lNFDp7zHgm0cK2Tw4kj2XfkJy4TgwZTBGwRDQgWEbLbdTA=="
+    },
     "node_modules/@math.gl/web-mercator": {
-      "version": "3.5.6",
-      "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.5.6.tgz",
-      "integrity": "sha512-siWHLJGp9o8fDEM1t0Rby+JXftl6il0z3927liWGzkHqFftXPHY858ShPy45ThDU8q5lyCftg8aVgrv4nfD+Zw==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.6.3.tgz",
+      "integrity": "sha512-UVrkSOs02YLehKaehrxhAejYMurehIHPfFQvPFZmdJHglHOU4V2cCUApTVEwOksvCp161ypEqVp+9H6mGhTTcw==",
       "dependencies": {
         "@babel/runtime": "^7.12.0",
-        "gl-matrix": "~3.3.0"
+        "gl-matrix": "^3.4.0"
       }
     },
     "node_modules/@mdx-js/loader": {
@@ -12171,10 +12113,27 @@
         "url": "https://opencollective.com/popperjs"
       }
     },
+    "node_modules/@probe.gl/env": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-3.6.0.tgz",
+      "integrity": "sha512-4tTZYUg/8BICC3Yyb9rOeoKeijKbZHRXBEKObrfPmX4sQmYB15ZOUpoVBhAyJkOYVAM8EkPci6Uw5dLCwx2BEQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "node_modules/@probe.gl/log": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-3.6.0.tgz",
+      "integrity": "sha512-hjpyenpEvOdowgZ1qMeCJxfRD4JkKdlXz0RC14m42Un62NtOT+GpWyKA4LssT0+xyLULCByRAtG2fzZorpIAcA==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@probe.gl/env": "3.6.0"
+      }
+    },
     "node_modules/@probe.gl/stats": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.4.0.tgz",
-      "integrity": "sha512-Gl37r9qGuiKadIvTZdSZvzCNOttJYw6RcY1oT0oDuB8r2uhuZAdSMQRQTy9FTinp6MY6O9wngGnV6EpQ8wSBAw==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.6.0.tgz",
+      "integrity": "sha512-JdALQXB44OP4kUBN/UrQgzbJe4qokbVF4Y8lkIA8iVCFnjVowWIgkD/z/0QO65yELT54tTrtepw1jScjKB+rhQ==",
       "dependencies": {
         "@babel/runtime": "^7.0.0"
       }
@@ -19036,6 +18995,56 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/@turf/boolean-clockwise": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-5.1.5.tgz",
+      "integrity": "sha512-FqbmEEOJ4rU4/2t7FKx0HUWmjFEVqR+NJrFP7ymGSjja2SQ7Q91nnBihGuT+yuHHl6ElMjQ3ttsB/eTmyCycxA==",
+      "dependencies": {
+        "@turf/helpers": "^5.1.5",
+        "@turf/invariant": "^5.1.5"
+      }
+    },
+    "node_modules/@turf/clone": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-5.1.5.tgz",
+      "integrity": "sha512-//pITsQ8xUdcQ9pVb4JqXiSqG4dos5Q9N4sYFoWghX21tfOV2dhc5TGqYOhnHrQS7RiKQL1vQ48kIK34gQ5oRg==",
+      "dependencies": {
+        "@turf/helpers": "^5.1.5"
+      }
+    },
+    "node_modules/@turf/helpers": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz",
+      "integrity": "sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw=="
+    },
+    "node_modules/@turf/invariant": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz",
+      "integrity": "sha512-28RCBGvCYsajVkw2EydpzLdcYyhSA77LovuOvgCJplJWaNVyJYH6BOR3HR9w50MEkPqb/Vc/jdo6I6ermlRtQA==",
+      "dependencies": {
+        "@turf/helpers": "^5.1.5"
+      }
+    },
+    "node_modules/@turf/meta": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-5.2.0.tgz",
+      "integrity": "sha512-ZjQ3Ii62X9FjnK4hhdsbT+64AYRpaI8XMBMcyftEOGSmPMUVnkbvuv3C9geuElAXfQU7Zk1oWGOcrGOD9zr78Q==",
+      "dependencies": {
+        "@turf/helpers": "^5.1.5"
+      }
+    },
+    "node_modules/@turf/rewind": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-5.1.5.tgz",
+      "integrity": "sha512-Gdem7JXNu+G4hMllQHXRFRihJl3+pNl7qY+l4qhQFxq+hiU1cQoVFnyoleIqWKIrdK/i2YubaSwc3SCM7N5mMw==",
+      "dependencies": {
+        "@turf/boolean-clockwise": "^5.1.5",
+        "@turf/clone": "^5.1.5",
+        "@turf/helpers": "^5.1.5",
+        "@turf/invariant": "^5.1.5",
+        "@turf/meta": "^5.1.5"
+      }
+    },
     "node_modules/@types/aria-query": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.0.tgz",
@@ -19312,11 +19321,6 @@
       "resolved": "https://registry.npmjs.org/@types/fetch-mock/-/fetch-mock-7.3.5.tgz",
       "integrity": "sha512-sLecm9ohBdGIpYUP9rWk5/XIKY2xHMYTBJIcJuBBM8IJWnYoQ1DAj8F4OVjnfD0API1drlkWEV0LPNk+ACuhsg=="
     },
-    "node_modules/@types/flatbuffers": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz",
-      "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA=="
-    },
     "node_modules/@types/geojson": {
       "version": "7946.0.8",
       "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
@@ -19340,6 +19344,11 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/hammerjs": {
+      "version": "2.0.41",
+      "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
+      "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
+    },
     "node_modules/@types/hast": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
@@ -19458,6 +19467,15 @@
         "@types/lodash": "*"
       }
     },
+    "node_modules/@types/mapbox__geojson-extent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/mapbox__geojson-extent/-/mapbox__geojson-extent-1.0.0.tgz",
+      "integrity": "sha512-RJBeVDv7LDmW4gO3VD8pr/OYuToQtF77H/VRDG733fmA6chzztBTz6yi9/llRD8SpM7fznxhP6B43Izaj4ufoA==",
+      "dev": true,
+      "dependencies": {
+        "@types/geojson": "*"
+      }
+    },
     "node_modules/@types/mapbox-gl": {
       "version": "2.7.6",
       "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.7.6.tgz",
@@ -19538,6 +19556,11 @@
       "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-4.1.4.tgz",
       "integrity": "sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ=="
     },
+    "node_modules/@types/offscreencanvas": {
+      "version": "2019.7.0",
+      "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz",
+      "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg=="
+    },
     "node_modules/@types/overlayscrollbars": {
       "version": "1.12.1",
       "resolved": "https://registry.npmjs.org/@types/overlayscrollbars/-/overlayscrollbars-1.12.1.tgz",
@@ -19859,11 +19882,6 @@
         "@types/jest": "*"
       }
     },
-    "node_modules/@types/text-encoding-utf-8": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz",
-      "integrity": "sha512-AQ6zewa0ucLJvtUi5HsErbOFKAcQfRLt9zFLlUOvcXBy2G36a+ZDpCHSGdzJVUD8aNURtIjh9aSjCStNMRCcRQ=="
-    },
     "node_modules/@types/tinycolor2": {
       "version": "1.4.3",
       "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.3.tgz",
@@ -19885,11 +19903,23 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/@types/underscore": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.6.tgz",
+      "integrity": "sha512-G2oC64I/sR817KDL2b2Mc7+diXyxcibyUeLMyexU4K/sG8hyt/YMlbBK0TVhx/YQ1ehfzgXhLuq2YQHIL4bXUQ==",
+      "dev": true
+    },
     "node_modules/@types/unist": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
       "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ=="
     },
+    "node_modules/@types/urijs": {
+      "version": "1.19.19",
+      "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz",
+      "integrity": "sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg==",
+      "dev": true
+    },
     "node_modules/@types/vinyl": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.6.tgz",
@@ -22574,36 +22604,6 @@
         "normalize-path": "^2.1.1"
       }
     },
-    "node_modules/apache-arrow": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-4.0.1.tgz",
-      "integrity": "sha512-DyF7GXCbSjsw4P5C8b+qW7OnJKa6w9mJI0mhV0+EfZbVZCmhfiF6ffqcnrI/kzBrRqn9hH/Ft9n5+m4DTbBJpg==",
-      "dependencies": {
-        "@types/flatbuffers": "^1.10.0",
-        "@types/node": "^14.14.37",
-        "@types/text-encoding-utf-8": "^1.0.1",
-        "command-line-args": "5.1.1",
-        "command-line-usage": "6.1.1",
-        "flatbuffers": "1.12.0",
-        "json-bignum": "^0.0.3",
-        "pad-left": "^2.1.0",
-        "text-encoding-utf-8": "^1.0.2",
-        "tslib": "^2.2.0"
-      },
-      "bin": {
-        "arrow2csv": "bin/arrow2csv.js"
-      }
-    },
-    "node_modules/apache-arrow/node_modules/@types/node": {
-      "version": "14.17.9",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz",
-      "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g=="
-    },
-    "node_modules/apache-arrow/node_modules/tslib": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
-      "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
-    },
     "node_modules/aphrodite": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.2.5.tgz",
@@ -22743,14 +22743,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/array-back": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
-      "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/array-differ": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
@@ -24509,6 +24501,14 @@
         "node-int64": "^0.4.0"
       }
     },
+    "node_modules/buf-compare": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
+      "integrity": "sha512-Bvx4xH00qweepGc43xFvMs5BKASXTbHaHm6+kDYIK9p/4iFwjATQkmPKHQSgJZzKbAymhztRbXUf1Nqhzl73/Q==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/buffer": {
       "version": "4.9.2",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
@@ -25874,85 +25874,6 @@
         "trim": "0.0.1"
       }
     },
-    "node_modules/command-line-args": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
-      "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
-      "dependencies": {
-        "array-back": "^3.0.1",
-        "find-replace": "^3.0.0",
-        "lodash.camelcase": "^4.3.0",
-        "typical": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/command-line-usage": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz",
-      "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==",
-      "dependencies": {
-        "array-back": "^4.0.1",
-        "chalk": "^2.4.2",
-        "table-layout": "^1.0.1",
-        "typical": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/command-line-usage/node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dependencies": {
-        "color-convert": "^1.9.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/command-line-usage/node_modules/array-back": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
-      "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/command-line-usage/node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/command-line-usage/node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dependencies": {
-        "has-flag": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/command-line-usage/node_modules/typical": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
-      "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -26615,6 +26536,18 @@
         "randombytes": "^2.1.0"
       }
     },
+    "node_modules/core-assert": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
+      "integrity": "sha512-IG97qShIP+nrJCXMCgkNZgH7jZQ4n8RpPyPeXX++T6avR/KhLhgLiHKoEn5Rc1KjfycSfA9DMa6m+4C4eguHhw==",
+      "dependencies": {
+        "buf-compare": "^1.0.0",
+        "is-error": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/core-js": {
       "version": "3.31.1",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.1.tgz",
@@ -28815,24 +28748,6 @@
       "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==",
       "dev": true
     },
-    "node_modules/deck.gl": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-8.5.2.tgz",
-      "integrity": "sha512-tsEyv62Zzc+GT3By0Y1R2gqEJ8K3tGBDaLprAoeAsg7fvIa5ikFBdWEBFHa1UDbgE2UEmYbcBK/yK4GAL8Ia4A==",
-      "dependencies": {
-        "@deck.gl/aggregation-layers": "8.5.2",
-        "@deck.gl/carto": "8.5.2",
-        "@deck.gl/core": "8.5.2",
-        "@deck.gl/extensions": "8.5.2",
-        "@deck.gl/geo-layers": "8.5.2",
-        "@deck.gl/google-maps": "8.5.2",
-        "@deck.gl/json": "8.5.2",
-        "@deck.gl/layers": "8.5.2",
-        "@deck.gl/mapbox": "8.5.2",
-        "@deck.gl/mesh-layers": "8.5.2",
-        "@deck.gl/react": "8.5.2"
-      }
-    },
     "node_modules/decode-named-character-reference": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
@@ -28890,6 +28805,7 @@
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
       "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "devOptional": true,
       "engines": {
         "node": ">=4.0.0"
       }
@@ -28904,6 +28820,17 @@
       "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.0.tgz",
       "integrity": "sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw=="
     },
+    "node_modules/deep-strict-equal": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz",
+      "integrity": "sha512-3daSWyvZ/zwJvuMGlzG1O+Ow0YSadGfb3jsh9xoCutv2tWyB9dA4YvR9L9/fSdDZa2dByYQe+TqapSGUrjnkoA==",
+      "dependencies": {
+        "core-assert": "^0.2.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/deepmerge": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
@@ -29647,9 +29574,9 @@
       "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
     },
     "node_modules/draco3d": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.4.1.tgz",
-      "integrity": "sha512-9Rxonc70xiovBC+Bq1h57SNZIHzWTibU1VfIGp5z3Xx8dPtv4yT5uGhiH7P5uvJRR2jkrvHafRxR7bTANkvfpg=="
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.5.tgz",
+      "integrity": "sha512-JVuNV0EJzD3LBYhGyIXJLeBID/EVtmFO1ZNhAYflTgiMiAJlbhXQmRRda/azjc8MRVMHh0gqGhiqHUo5dIXM8Q=="
     },
     "node_modules/duplexer": {
       "version": "0.1.2",
@@ -32196,6 +32123,27 @@
       "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
       "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
     },
+    "node_modules/fast-xml-parser": {
+      "version": "4.2.7",
+      "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz",
+      "integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
+      "funding": [
+        {
+          "type": "paypal",
+          "url": "https://paypal.me/naturalintelligence"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/NaturalIntelligence"
+        }
+      ],
+      "dependencies": {
+        "strnum": "^1.0.5"
+      },
+      "bin": {
+        "fxparser": "src/cli/cli.js"
+      }
+    },
     "node_modules/fastest-levenshtein": {
       "version": "1.0.12",
       "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@@ -32557,17 +32505,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/find-replace": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
-      "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
-      "dependencies": {
-        "array-back": "^3.0.1"
-      },
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
     "node_modules/find-root": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -32915,11 +32852,6 @@
         "node": "^10.12.0 || >=12.0.0"
       }
     },
-    "node_modules/flatbuffers": {
-      "version": "1.12.0",
-      "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz",
-      "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ=="
-    },
     "node_modules/flatted": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz",
@@ -34204,9 +34136,9 @@
       }
     },
     "node_modules/gl-matrix": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.3.0.tgz",
-      "integrity": "sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA=="
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
+      "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
     },
     "node_modules/glob": {
       "version": "7.2.3",
@@ -36328,6 +36260,11 @@
         "is-window": "^1.0.2"
       }
     },
+    "node_modules/is-error": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+      "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg=="
+    },
     "node_modules/is-extendable": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -40155,14 +40092,6 @@
         "bignumber.js": "^9.0.0"
       }
     },
-    "node_modules/json-bignum": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz",
-      "integrity": "sha1-QRY7UENsdz2CQk28IO1w23YEuNc=",
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
     "node_modules/json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -40391,6 +40320,11 @@
         "node": ">= 8"
       }
     },
+    "node_modules/ktx-parse": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.0.4.tgz",
+      "integrity": "sha512-LY3nrmfXl+wZZdPxgJ3ZmLvG+wkOZZP3/dr4RbQj1Pk3Qwz44esOOSFFVQJcNWpXAtiNIC66WgXufX/SYgYz6A=="
+    },
     "node_modules/language-subtag-registry": {
       "version": "0.3.21",
       "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
@@ -40455,6 +40389,11 @@
       "deprecated": "use String.prototype.padStart()",
       "dev": true
     },
+    "node_modules/lerc": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lerc/-/lerc-4.0.1.tgz",
+      "integrity": "sha512-b351eOjY3DKm1H2hDVhXswsd2RCK6bgREBK6Z639ctClOuYXTi9a44l8yO3zm1pYM2o4WrriloTAKgyrb/0EyA=="
+    },
     "node_modules/lerna": {
       "version": "6.6.2",
       "resolved": "https://registry.npmjs.org/lerna/-/lerna-6.6.2.tgz",
@@ -43895,11 +43834,6 @@
       "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
       "dev": true
     },
-    "node_modules/lodash.camelcase": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
-      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
-    },
     "node_modules/lodash.curry": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz",
@@ -44606,11 +44540,6 @@
       "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz",
       "integrity": "sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw=="
     },
-    "node_modules/mapbox-gl/node_modules/gl-matrix": {
-      "version": "3.4.3",
-      "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
-      "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
-    },
     "node_modules/mapbox-gl/node_modules/supercluster": {
       "version": "7.1.5",
       "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
@@ -44668,11 +44597,21 @@
       "integrity": "sha512-9FbRY3i6U+CbHgrdNbAUaisjWTozkm1ZfupYQJiZ87NtYHk2Zh9DvxMgp/fifxVhqTLpd5fCCLossUbpZxGeKw=="
     },
     "node_modules/math.gl": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.5.3.tgz",
-      "integrity": "sha512-cRQRZlc+XvNHd3bIfu3kdPPPAW0vwDelZJmkjn2TDvCyPcmyDtAiZ2Poo1aFoINP7HzN6oHYxapc/0wV3q6Opg==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.6.3.tgz",
+      "integrity": "sha512-Yq9CyECvSDox9+5ETi2+x1bGTY5WvGUGL3rJfC4KPoCZAM51MGfrCm6rIn4yOJUVfMPs2a5RwMD+yGS/n1g3gg==",
       "dependencies": {
-        "@math.gl/core": "3.5.3"
+        "@math.gl/core": "3.6.3"
+      }
+    },
+    "node_modules/math.gl/node_modules/@math.gl/core": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+      "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+      "dependencies": {
+        "@babel/runtime": "^7.12.0",
+        "@math.gl/types": "3.6.3",
+        "gl-matrix": "^3.4.0"
       }
     },
     "node_modules/mathfn": {
@@ -46294,11 +46233,11 @@
       }
     },
     "node_modules/mjolnir.js": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/mjolnir.js/-/mjolnir.js-2.5.0.tgz",
-      "integrity": "sha512-YkVoyKs7qm9xvAgRgjx3Md/7eYqmq7VXOgTKQNnmuzcBJzMebjdIWa7FdTd0RZBrw3UL6V6TTktsxJwBMLXUNA==",
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/mjolnir.js/-/mjolnir.js-2.7.1.tgz",
+      "integrity": "sha512-72BeUWgTv2cj5aZQKpwL8caNUFhXZ9bDm1hxpNj70XJQ62IBnTZmtv/WPxJvtaVNhzNo+D2U8O6ryNI0zImYcw==",
       "dependencies": {
-        "@babel/runtime": "^7.0.0",
+        "@types/hammerjs": "^2.0.41",
         "hammerjs": "^2.0.8"
       },
       "engines": {
@@ -49210,17 +49149,6 @@
       "resolved": "https://registry.npmjs.org/pad-component/-/pad-component-0.0.1.tgz",
       "integrity": "sha1-rR8izhvw/cDW3dkIrxfzUaQEuKw="
     },
-    "node_modules/pad-left": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz",
-      "integrity": "sha1-FuajstRKjhOMsIOMx8tAOk/J6ZQ=",
-      "dependencies": {
-        "repeat-string": "^1.5.4"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/pako": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -50135,15 +50063,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/probe.gl": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.4.0.tgz",
-      "integrity": "sha512-9CLByZATuhuG/Viq3ckfWU+dAhb7dMmjzsyCy4s7ds9ueTejcVRENxL197/XacOK/AN61YrEERB0QnouB0Qc0Q==",
-      "dependencies": {
-        "@babel/runtime": "^7.0.0",
-        "@probe.gl/stats": "3.4.0"
-      }
-    },
     "node_modules/proc-log": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-1.0.0.tgz",
@@ -50708,6 +50627,17 @@
         "node": ">=0.6"
       }
     },
+    "node_modules/quadbin": {
+      "version": "0.1.9",
+      "resolved": "https://registry.npmjs.org/quadbin/-/quadbin-0.1.9.tgz",
+      "integrity": "sha512-5V6m6+cL/6+uBl3hYL+CWF06rRvlHkIepYKGQjTLYaHhu9InPppql0+0ROiCaOQdz8gPNlgge3glk5Qg1mWOYw==",
+      "dependencies": {
+        "@mapbox/tile-cover": "3.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      }
+    },
     "node_modules/query-string": {
       "version": "6.14.1",
       "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
@@ -52749,14 +52679,6 @@
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
       "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
     },
-    "node_modules/reduce-flatten": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
-      "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==",
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/reduce-function-call": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz",
@@ -56106,6 +56028,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/strnum": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
+      "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
+    },
     "node_modules/strong-log-transformer": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz",
@@ -56452,36 +56379,6 @@
         "node": ">=10.0.0"
       }
     },
-    "node_modules/table-layout": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz",
-      "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==",
-      "dependencies": {
-        "array-back": "^4.0.1",
-        "deep-extend": "~0.6.0",
-        "typical": "^5.2.0",
-        "wordwrapjs": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/table-layout/node_modules/array-back": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
-      "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/table-layout/node_modules/typical": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
-      "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/table/node_modules/ajv": {
       "version": "8.8.0",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.0.tgz",
@@ -57065,11 +56962,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/text-encoding-utf-8": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz",
-      "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg=="
-    },
     "node_modules/text-extensions": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz",
@@ -57096,6 +56988,29 @@
         "url": "https://bevry.me/fund"
       }
     },
+    "node_modules/texture-compressor": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/texture-compressor/-/texture-compressor-1.0.2.tgz",
+      "integrity": "sha512-dStVgoaQ11mA5htJ+RzZ51ZxIZqNOgWKAIvtjLrW1AliQQLCmrDqNzQZ8Jh91YealQ95DXt4MEduLzJmbs6lig==",
+      "dependencies": {
+        "argparse": "^1.0.10",
+        "image-size": "^0.7.4"
+      },
+      "bin": {
+        "texture-compressor": "bin/texture-compressor.js"
+      }
+    },
+    "node_modules/texture-compressor/node_modules/image-size": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
+      "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==",
+      "bin": {
+        "image-size": "bin/image-size.js"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/thread-loader": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz",
@@ -57187,6 +57102,12 @@
       "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
       "devOptional": true
     },
+    "node_modules/tilebelt": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tilebelt/-/tilebelt-1.0.1.tgz",
+      "integrity": "sha512-cxHzpa5JgsugY9NUVRH43gPaGJw/29LecAn4X7UGOP64+kB8pU4VQ3bIhSyfb5Mk4jDxwl3yk330L/EIhbJ5aw==",
+      "deprecated": "This module is now under the @mapbox namespace: install @mapbox/tilebelt instead"
+    },
     "node_modules/timers-browserify": {
       "version": "2.0.12",
       "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -57877,14 +57798,6 @@
         "node": ">=4.2.0"
       }
     },
-    "node_modules/typical": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
-      "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/ua-parser-js": {
       "version": "0.7.33",
       "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
@@ -60383,26 +60296,6 @@
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
       "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
     },
-    "node_modules/wordwrapjs": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
-      "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==",
-      "dependencies": {
-        "reduce-flatten": "^2.0.0",
-        "typical": "^5.2.0"
-      },
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/wordwrapjs/node_modules/typical": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
-      "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/worker-farm": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
@@ -63282,8 +63175,7 @@
         "d3-array": "^1.2.4",
         "d3-color": "^1.4.1",
         "d3-scale": "^3.0.0",
-        "deck.gl": "8.5.2",
-        "jquery": "^3.4.1",
+        "deck.gl": "8.8.27",
         "lodash": "^4.17.15",
         "moment": "^2.20.1",
         "mousetrap": "^1.6.1",
@@ -63293,6 +63185,11 @@
         "urijs": "^1.19.8",
         "xss": "^1.0.10"
       },
+      "devDependencies": {
+        "@types/mapbox__geojson-extent": "^1.0.0",
+        "@types/underscore": "^1.11.6",
+        "@types/urijs": "^1.19.19"
+      },
       "peerDependencies": {
         "@superset-ui/chart-controls": "*",
         "@superset-ui/core": "*",
@@ -63302,6 +63199,272 @@
         "react-map-gl": "^6.1.19"
       }
     },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/aggregation-layers": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.9.22.tgz",
+      "integrity": "sha512-cw2duTxcZI0i0+295ivo/tsLffB6GPhuwkCYhqrVfO61JsK9GFuISGB7C5tMcfSOSxzgN6JwNA4fJEK1bCGozQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@luma.gl/constants": "^8.5.20",
+        "@luma.gl/shadertools": "^8.5.20",
+        "@math.gl/web-mercator": "^3.6.2",
+        "d3-hexbin": "^0.2.1"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@deck.gl/layers": "^8.0.0",
+        "@luma.gl/core": "^8.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/carto": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/carto/-/carto-8.9.22.tgz",
+      "integrity": "sha512-sfSmzUtXrhvMX5JaFiIpQtmfqVHRxcVIxnSZz6F5Q7DtvBhjNMEt3jq3qJ3IWH0EyxX0Xu+HMjmw6ScnsVAcXQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@loaders.gl/gis": "^3.4.2",
+        "@loaders.gl/loader-utils": "^3.4.2",
+        "@loaders.gl/mvt": "^3.4.2",
+        "@loaders.gl/tiles": "^3.4.2",
+        "@luma.gl/constants": "^8.5.20",
+        "@math.gl/web-mercator": "^3.6.2",
+        "cartocolor": "^4.0.2",
+        "d3-array": "^3.2.0",
+        "d3-color": "^3.1.0",
+        "d3-format": "^3.1.0",
+        "d3-scale": "^4.0.0",
+        "h3-js": "^3.7.0",
+        "moment-timezone": "^0.5.33",
+        "pbf": "^3.2.1",
+        "quadbin": "^0.1.9"
+      },
+      "peerDependencies": {
+        "@deck.gl/aggregation-layers": "^8.0.0",
+        "@deck.gl/core": "^8.0.0",
+        "@deck.gl/extensions": "^8.0.0",
+        "@deck.gl/geo-layers": "^8.0.0",
+        "@deck.gl/layers": "^8.0.0",
+        "@loaders.gl/core": "^3.4.2"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/carto/node_modules/d3-array": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+      "dependencies": {
+        "internmap": "1 - 2"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/carto/node_modules/d3-color": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+      "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/carto/node_modules/d3-format": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/carto/node_modules/d3-scale": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+      "dependencies": {
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/core": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.9.22.tgz",
+      "integrity": "sha512-HnUPB6qKgRfKQ3Dstw6vlI7+fyO9Ni4gukh8ysQM94mw89BRLkVcuQV0XvlzbbojrG1Z6QpC7KZmodW0y5o2og==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@loaders.gl/core": "^3.4.2",
+        "@loaders.gl/images": "^3.4.2",
+        "@luma.gl/constants": "^8.5.20",
+        "@luma.gl/core": "^8.5.20",
+        "@luma.gl/webgl": "^8.5.20",
+        "@math.gl/core": "^3.6.2",
+        "@math.gl/sun": "^3.6.2",
+        "@math.gl/web-mercator": "^3.6.2",
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/log": "^3.5.0",
+        "@probe.gl/stats": "^3.5.0",
+        "gl-matrix": "^3.0.0",
+        "math.gl": "^3.6.2",
+        "mjolnir.js": "^2.7.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/extensions": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-8.9.22.tgz",
+      "integrity": "sha512-MYyWjnf94Ibs3BNfTIq/oJJLrNMWUpS2+qkmkQie03EGeO7/wJ9BAQAXWYdFdrbvCykw60mLBX78a68+XLvbmQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@luma.gl/shadertools": "^8.5.20"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@luma.gl/constants": "^8.0.0",
+        "@luma.gl/core": "^8.0.0",
+        "@math.gl/core": "^3.6.2",
+        "@math.gl/web-mercator": "^3.6.2",
+        "gl-matrix": "^3.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/geo-layers": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-8.9.22.tgz",
+      "integrity": "sha512-/P6kGxlWhfRPAaG0UDklANTQpQGevAE1zGTOyFVYEAMyRBws/CetLCq5rKfYibTjWBa5FO2U0u837HzG0PJRUw==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@loaders.gl/3d-tiles": "^3.4.2",
+        "@loaders.gl/gis": "^3.4.2",
+        "@loaders.gl/loader-utils": "^3.4.2",
+        "@loaders.gl/mvt": "^3.4.2",
+        "@loaders.gl/schema": "^3.4.2",
+        "@loaders.gl/terrain": "^3.4.2",
+        "@loaders.gl/tiles": "^3.4.2",
+        "@loaders.gl/wms": "^3.4.2",
+        "@luma.gl/constants": "^8.5.20",
+        "@luma.gl/experimental": "^8.5.20",
+        "@math.gl/core": "^3.6.2",
+        "@math.gl/culling": "^3.6.2",
+        "@math.gl/web-mercator": "^3.6.2",
+        "@types/geojson": "^7946.0.8",
+        "h3-js": "^3.7.0",
+        "long": "^3.2.0"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@deck.gl/extensions": "^8.0.0",
+        "@deck.gl/layers": "^8.0.0",
+        "@deck.gl/mesh-layers": "^8.0.0",
+        "@loaders.gl/core": "^3.4.2",
+        "@luma.gl/core": "^8.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/google-maps": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-8.9.22.tgz",
+      "integrity": "sha512-x+9yqxkjLN0P5uKxYB6GEaM0KV2djBotvHX0BaHL9LbyWzdAvGJP1kmTg4SOpi0I7XG8jdkoca/tAZ2yy7A9RQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@luma.gl/constants": "^8.5.0",
+        "@luma.gl/core": "^8.5.0",
+        "@math.gl/core": "^3.6.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/json": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-8.9.22.tgz",
+      "integrity": "sha512-rYFZqp7mW8XvExtLAfGiAxTV7oLPaLmPVDPTYmMU2owSkfGYE3q6YvwqzHq37k5/5jLfJMA0cZy1fQrfJW3+gg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "d3-dsv": "^1.0.8",
+        "expression-eval": "^2.0.0"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/layers": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.9.22.tgz",
+      "integrity": "sha512-1IipECeORaT2fdU9k8KPnZ3DjUeH02h6oZYl4ffihNAIoVXKNivghgJ8ZeELLiEOkrxlbK+KjoH1zej7yuMwmg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@loaders.gl/images": "^3.4.2",
+        "@loaders.gl/schema": "^3.4.2",
+        "@luma.gl/constants": "^8.5.20",
+        "@mapbox/tiny-sdf": "^2.0.5",
+        "@math.gl/core": "^3.6.2",
+        "@math.gl/polygon": "^3.6.2",
+        "@math.gl/web-mercator": "^3.6.2",
+        "earcut": "^2.2.4"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@loaders.gl/core": "^3.4.2",
+        "@luma.gl/core": "^8.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/mapbox": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.9.22.tgz",
+      "integrity": "sha512-VanA1V/BE6vmHn/W9f8ug4ilMDEfP3JUQWegVaCiG2EA8yjML6QVmO31gNARTefBjgMsfkWDBwm325coIUkxBQ==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@types/mapbox-gl": "^2.6.3"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/mesh-layers": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-8.9.22.tgz",
+      "integrity": "sha512-XJ6WdHphBtdumQYseFQCfGQ8KLRzgOGu89qsiEcuRTQwgW5GxXi4WJSpZmXZGtXObubwuEX6YqrN4BkX3F/nWg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@loaders.gl/gltf": "^3.4.2",
+        "@luma.gl/constants": "^8.5.20",
+        "@luma.gl/experimental": "^8.5.20",
+        "@luma.gl/shadertools": "^8.5.20"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@luma.gl/core": "^8.0.0"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@deck.gl/react": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.9.22.tgz",
+      "integrity": "sha512-NZcWBlOWYPs+DQqYSZQFLxfguFe0GP2AE1ojlrstnckV1N3bsMf1dT6AI5AvX5h9DbiBc216ZrV9iwVhlfkLng==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0"
+      },
+      "peerDependencies": {
+        "@deck.gl/core": "^8.0.0",
+        "@types/react": ">= 16.3",
+        "react": ">=16.3",
+        "react-dom": ">=16.3"
+      }
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@mapbox/tiny-sdf": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz",
+      "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA=="
+    },
+    "plugins/legacy-preset-chart-deckgl/node_modules/@math.gl/core": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+      "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+      "dependencies": {
+        "@babel/runtime": "^7.12.0",
+        "@math.gl/types": "3.6.3",
+        "gl-matrix": "^3.4.0"
+      }
+    },
     "plugins/legacy-preset-chart-deckgl/node_modules/d3-color": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
@@ -63343,6 +63506,25 @@
         "internmap": "^1.0.0"
       }
     },
+    "plugins/legacy-preset-chart-deckgl/node_modules/deck.gl": {
+      "version": "8.9.22",
+      "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-8.9.22.tgz",
+      "integrity": "sha512-CkJ/Wtyquh4wpG7Os6n5j4D9fm0NFROa6Go0hEToVU8kbfQoj6drD76ixBnsx47dOtcHNQ11AVaPaaAeHmnTjg==",
+      "dependencies": {
+        "@babel/runtime": "^7.0.0",
+        "@deck.gl/aggregation-layers": "8.9.22",
+        "@deck.gl/carto": "8.9.22",
+        "@deck.gl/core": "8.9.22",
+        "@deck.gl/extensions": "8.9.22",
+        "@deck.gl/geo-layers": "8.9.22",
+        "@deck.gl/google-maps": "8.9.22",
+        "@deck.gl/json": "8.9.22",
+        "@deck.gl/layers": "8.9.22",
+        "@deck.gl/mapbox": "8.9.22",
+        "@deck.gl/mesh-layers": "8.9.22",
+        "@deck.gl/react": "8.9.22"
+      }
+    },
     "plugins/legacy-preset-chart-nvd3": {
       "name": "@superset-ui/legacy-preset-chart-nvd3",
       "version": "0.18.25",
@@ -67054,151 +67236,6 @@
         }
       }
     },
-    "@deck.gl/aggregation-layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.5.2.tgz",
-      "integrity": "sha512-oiqXPmyn2v0lX9tWCvgmWs29stHSLS3tje71Ff2FVXDNmvP5FoZItFa8y7O7KSTkej2/rSwZeSte/a9pri6Njg==",
-      "requires": {
-        "@luma.gl/shadertools": "^8.5.4",
-        "@math.gl/web-mercator": "^3.5.3",
-        "d3-hexbin": "^0.2.1"
-      }
-    },
-    "@deck.gl/carto": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/carto/-/carto-8.5.2.tgz",
-      "integrity": "sha512-Kw/3NUM+2NcHjxH6b7IOUYXEwmJ4SNQujFzAVFW5amG4Lut8074NGSF5XHi+4M/zgk7vXDFsGRxLqspsA/dg8w==",
-      "requires": {
-        "@loaders.gl/loader-utils": "^3.0.6",
-        "@loaders.gl/mvt": "^3.0.6",
-        "@loaders.gl/tiles": "^3.0.6",
-        "@math.gl/web-mercator": "^3.5.3",
-        "cartocolor": "^4.0.2",
-        "d3-scale": "^3.2.3"
-      },
-      "dependencies": {
-        "d3-array": {
-          "version": "2.12.1",
-          "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
-          "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
-          "requires": {
-            "internmap": "^1.0.0"
-          }
-        },
-        "d3-scale": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz",
-          "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
-          "requires": {
-            "d3-array": "^2.3.0",
-            "d3-format": "1 - 2",
-            "d3-interpolate": "1.2.0 - 2",
-            "d3-time": "^2.1.1",
-            "d3-time-format": "2 - 3"
-          }
-        },
-        "d3-time": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz",
-          "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
-          "requires": {
-            "d3-array": "2"
-          }
-        }
-      }
-    },
-    "@deck.gl/core": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.5.2.tgz",
-      "integrity": "sha512-SAFv7fKx6k1Rj8R4qTMQO2wEhEfixROzbcoSS6RivxrfES00KYYj6jJ7iNEnq3dFn6qc37LPpxqtYYHO4BcvYA==",
-      "requires": {
-        "@loaders.gl/core": "^3.0.6",
-        "@loaders.gl/images": "^3.0.6",
-        "@luma.gl/core": "^8.5.4",
-        "@math.gl/web-mercator": "^3.5.3",
-        "gl-matrix": "^3.0.0",
-        "math.gl": "^3.5.3",
-        "mjolnir.js": "^2.5.0",
-        "probe.gl": "^3.4.0"
-      }
-    },
-    "@deck.gl/extensions": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-8.5.2.tgz",
-      "integrity": "sha512-VhbQsMNPM7RCR/ERwb1u1x0rEWAxgXfcCWttW+gYvbiagW/LrAJ22jhOghlRW/wilEmupHYbXQlWkW2V/mYfsg==",
-      "requires": {
-        "@luma.gl/shadertools": "^8.5.4"
-      }
-    },
-    "@deck.gl/geo-layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-8.5.2.tgz",
-      "integrity": "sha512-t6+TgAdbKWDw8g9UX1y6D+5twcdJuKaXw4qSib/0yVurWi/Mil5Plihybt1l9uBZuwkr+UcpxPR73zzo+qd9MA==",
-      "requires": {
-        "@loaders.gl/3d-tiles": "^3.0.6",
-        "@loaders.gl/gis": "^3.0.6",
-        "@loaders.gl/loader-utils": "^3.0.6",
-        "@loaders.gl/mvt": "^3.0.6",
-        "@loaders.gl/terrain": "^3.0.6",
-        "@loaders.gl/tiles": "^3.0.6",
-        "@luma.gl/experimental": "^8.5.4",
-        "@math.gl/culling": "^3.5.3",
-        "@math.gl/web-mercator": "^3.5.3",
-        "h3-js": "^3.6.0",
-        "long": "^3.2.0",
-        "math.gl": "^3.5.3"
-      }
-    },
-    "@deck.gl/google-maps": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-8.5.2.tgz",
-      "integrity": "sha512-Dk3ozenBWgt9nFSYOT4N82urNW/JhiMszfFq6zLt3jUp0N7EJ9d2XO81hclM59BhjIdGWb6drTe96NvtbabVLQ==",
-      "requires": {}
-    },
-    "@deck.gl/json": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-8.5.2.tgz",
-      "integrity": "sha512-lVS16bvPfLUSidgBURZvGbWEjgK8GjLWlp1iGuLvua2W6TnWIyiKa6a3XoebgeXd8kqwSbQxhNnuSVPX+Di6Rg==",
-      "requires": {
-        "d3-dsv": "^1.0.8",
-        "expression-eval": "^2.0.0"
-      }
-    },
-    "@deck.gl/layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.5.2.tgz",
-      "integrity": "sha512-HmpE3qf9CI7sU/xa2DMCNg31pzpzK5XuUHyC70dsLq8AV7Sm3vZQz17KMU/CWSZpVr7yQ8uxTeSQARiv/zeOFQ==",
-      "requires": {
-        "@loaders.gl/images": "^3.0.6",
-        "@mapbox/tiny-sdf": "^1.1.0",
-        "@math.gl/polygon": "^3.5.3",
-        "earcut": "^2.0.6"
-      }
-    },
-    "@deck.gl/mapbox": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.5.2.tgz",
-      "integrity": "sha512-nMpzfdPFBVthT+EMgIcKo4YO6bZCqADQtqnxIFtfofZIiKS6R5OSuJ3sXPSNZ9ReCJGzdmndEz7/Qtm9Sia/bA==",
-      "requires": {}
-    },
-    "@deck.gl/mesh-layers": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-8.5.2.tgz",
-      "integrity": "sha512-dUfQyGjm5CYQg9AQdRsGtEEXGSGHxifPlws0zWWoj1r757wjqM0aZ663TUJEsJQDTLNOvbBLGTiuFeCBUoKO4Q==",
-      "requires": {
-        "@loaders.gl/gltf": "^3.0.6",
-        "@luma.gl/experimental": "^8.5.4",
-        "@luma.gl/shadertools": "^8.5.4"
-      }
-    },
-    "@deck.gl/react": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.5.2.tgz",
-      "integrity": "sha512-h7AJ9nPY1PTjrAVP7T1fvWDChWZrVOsEfYIoEP4W6ILSjvDqEQfVL0+9RhjUwQV2nKrg0QmpqCmbfOrgKQQbYw==",
-      "requires": {
-        "prop-types": "^15.6.0"
-      }
-    },
     "@discoveryjs/json-ext": {
       "version": "0.5.7",
       "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
@@ -71017,218 +71054,309 @@
       }
     },
     "@loaders.gl/3d-tiles": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-3.0.8.tgz",
-      "integrity": "sha512-jZeOyDPGD2wEkTLW4Do9A4UUQ+OGjhhNXztB0AsttZ69OpkmsxJXb76xxwevf+eThrsTgSTjZ06eC5DHX0kyXA==",
-      "requires": {
-        "@loaders.gl/core": "3.0.8",
-        "@loaders.gl/draco": "3.0.8",
-        "@loaders.gl/gltf": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/math": "3.0.8",
-        "@loaders.gl/tiles": "3.0.8",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/3d-tiles/-/3d-tiles-3.4.8.tgz",
+      "integrity": "sha512-v4Ejtp4Pb5RhFQyI37oDy9IZtBKEUZ+2xWNtyDgeV8Vni5ht532hsPVGY8CkUMMZFAyzl3zcDFUQo0cIbiqKKg==",
+      "requires": {
+        "@loaders.gl/draco": "3.4.8",
+        "@loaders.gl/gltf": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/math": "3.4.8",
+        "@loaders.gl/tiles": "3.4.8",
         "@math.gl/core": "^3.5.1",
-        "@math.gl/geospatial": "^3.5.1"
+        "@math.gl/geospatial": "^3.5.1",
+        "long": "^5.2.1"
+      },
+      "dependencies": {
+        "long": {
+          "version": "5.2.3",
+          "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+          "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+        }
       }
     },
     "@loaders.gl/core": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-3.0.8.tgz",
-      "integrity": "sha512-FIfbhMkoRX2JonEHXHgClC7jwOSsEwvvmjlaTMRAY+gFKvJPGmegkp4VgUZquLFf6GedJt/1TuMMvAX6gdq1pg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/core/-/core-3.4.8.tgz",
+      "integrity": "sha512-pAaAISNmxiUQn8iz0yDhX5DCt3geaaJtSTxAHgz25G2Z5kWqYS00g5bc7XIGNT2BwqD5pgVLRch+BdTQ/Q8lJA==",
       "requires": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/worker-utils": "3.0.8",
-        "probe.gl": "^3.4.0"
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/worker-utils": "3.4.8",
+        "@probe.gl/log": "^4.0.1"
+      },
+      "dependencies": {
+        "@probe.gl/env": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-4.0.4.tgz",
+          "integrity": "sha512-sYNGqesDfWD6dFP5oNZtTeFA4Z6ak5T4a8BNPdNhoqy7PK9w70JHrb6mv+RKWqKXq33KiwCDWL7fYxx2HuEH2w==",
+          "requires": {
+            "@babel/runtime": "^7.0.0"
+          }
+        },
+        "@probe.gl/log": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-4.0.4.tgz",
+          "integrity": "sha512-WpmXl6njlBMwrm8HBh/b4kSp/xnY1VVmeT4PWUKF+RkVbFuKQbsU11dA1IxoMd7gSY+5DGIwxGfAv1H5OMzA4A==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@probe.gl/env": "4.0.4"
+          }
+        }
       }
     },
     "@loaders.gl/draco": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-3.0.8.tgz",
-      "integrity": "sha512-ZCXzXNHWQ7H0qk/kC+rWzjMWjLzZGzQcDbdpIuy8xJdp4rTpmMkLUseFPby8vhkmIaqxWPwPB6mx/vM7L6JENg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/draco/-/draco-3.4.8.tgz",
+      "integrity": "sha512-x127QX/CCzbSXTk5IL4WBmL6RjvMZhedzMoEiWE4NhAEiwTFKXvWUZLluoFlGzJhxSL6xiR2KBF8tN1EMv4L1Q==",
       "requires": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/schema": "3.0.8",
-        "@loaders.gl/worker-utils": "3.0.8",
-        "draco3d": "1.4.1"
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "@loaders.gl/worker-utils": "3.4.8",
+        "draco3d": "1.5.5"
       }
     },
     "@loaders.gl/gis": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-3.0.8.tgz",
-      "integrity": "sha512-7NL+lIb7NezlMupYskVil6M3RZunXJl+TyaVAW82GLbzPSOq+m/G7h3+z0GBa8iv/U/I+cB5BhSN+GZmvFwqEA==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/gis/-/gis-3.4.8.tgz",
+      "integrity": "sha512-I0Q8n1XhxXfZ6QoHvW6ayUkrOiifARGvSm4xTZxkydFNM5MULp9ICrZkFeqGMAVeevbssR3h9JKR111AmQvrPw==",
       "requires": {
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/schema": "3.0.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
         "@mapbox/vector-tile": "^1.3.1",
+        "@math.gl/polygon": "^3.5.1",
         "pbf": "^3.2.1"
       }
     },
     "@loaders.gl/gltf": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-3.0.8.tgz",
-      "integrity": "sha512-4PXWTlqyvlbZE2Vp4iQ+Y87ZO1WuRvSlbImDhygd0hoINfmJ9ObxrFS3yJcpJTu007nWxXorNVEOKyuoo+4Iyw==",
-      "requires": {
-        "@loaders.gl/core": "3.0.8",
-        "@loaders.gl/draco": "3.0.8",
-        "@loaders.gl/images": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8"
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/gltf/-/gltf-3.4.8.tgz",
+      "integrity": "sha512-nvDj0LmkOXtQWUr7MkGShQ2WUmZlUnWTs6PatPxueevdL49vR16SB8VAWTx+8XUPq3Wno+gVZJxG8HBRkFVHng==",
+      "requires": {
+        "@loaders.gl/draco": "3.4.8",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/textures": "3.4.8",
+        "@math.gl/core": "^3.5.1"
       }
     },
     "@loaders.gl/images": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-3.0.8.tgz",
-      "integrity": "sha512-rO2cIYJYlMs/uO9YSoF4/BEA4p/9xQ3gHZ1sIJkPYVnDqzpbu8nvUjWTQqIdL/MkQBTW8tz3twCdM+B6G9Fa2w==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/images/-/images-3.4.8.tgz",
+      "integrity": "sha512-cKoQ20aMBgBXYKVVJuDLuH1wTeXZyinbG4otSBf4D+gAhQ09Gd3dVMYF7RWIxXp0CdL4jiqGHnJ470y0AvrT4w==",
       "requires": {
-        "@loaders.gl/loader-utils": "3.0.8"
+        "@loaders.gl/loader-utils": "3.4.8"
       }
     },
     "@loaders.gl/loader-utils": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-3.0.8.tgz",
-      "integrity": "sha512-PW1WyyQ+LXkqoGHBZHsmfNQkKiLAYf1gok+kHnHvY9fCzhJeA1iTNEUKPXGXKgS00m/k5cBTkOWAaOG9KRvBCQ==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/loader-utils/-/loader-utils-3.4.8.tgz",
+      "integrity": "sha512-/3sZ2J3Y29t50HSo6X6mtLNDYID+s77cmFWxjq+R4/uDekYx2vmgiw/WCFbupKse6NrAKe1KgqEBac1Q7yARSQ==",
       "requires": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/worker-utils": "3.0.8",
-        "@probe.gl/stats": "^3.4.0"
+        "@loaders.gl/worker-utils": "3.4.8",
+        "@probe.gl/stats": "^4.0.1"
+      },
+      "dependencies": {
+        "@probe.gl/stats": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.0.4.tgz",
+          "integrity": "sha512-SDuSY/D4yDL6LQDa69l/GCcnZLRiGYdyvYkxWb0CgnzTPdPrcdrzGkzkvpC3zsA4fEFw2smlDje370QGHwlisg==",
+          "requires": {
+            "@babel/runtime": "^7.0.0"
+          }
+        }
       }
     },
     "@loaders.gl/math": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-3.0.8.tgz",
-      "integrity": "sha512-jfFpxxr4Bq5JfOPqLVJc4JJGoGGvVTOCWiJhnTtSAKhaNSwldmNWaZ0w8E2nlgPKPMAHiTRKOQnd9sSY5m66Cw==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/math/-/math-3.4.8.tgz",
+      "integrity": "sha512-+9Hy1k44tj+v8IYKh+Zp0xXOijH94HoT/8ILdt5kG8MdjDU6VYyz2t/D4ZawSM+DBgXLYhDIIKkqrdND5ct2AQ==",
       "requires": {
-        "@loaders.gl/images": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
         "@math.gl/core": "^3.5.1"
       }
     },
     "@loaders.gl/mvt": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-3.0.8.tgz",
-      "integrity": "sha512-Jk1QTHgpxMsUT01w5IJJ2en9qq0yOZcL2wGXVc7CFp2h6inB22rC3drUwq1mUNGe6iy3EWIo7EeJVd9B+5JyTQ==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/mvt/-/mvt-3.4.8.tgz",
+      "integrity": "sha512-JvgSsg7+oypRAhGmUKvLSH8h146HRopxf25c9hzyPWX1MeAPfVWgwTou0syy5TwOyRlrLtGp4Rs/6AmNAWBtnw==",
       "requires": {
-        "@loaders.gl/gis": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
+        "@loaders.gl/gis": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
         "@math.gl/polygon": "^3.5.1",
         "pbf": "^3.2.1"
       }
     },
     "@loaders.gl/schema": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-3.0.8.tgz",
-      "integrity": "sha512-yne5WE7fZZWFl2zF8fzDlYhPVJua6h6mTCSmlQ5pryaMXTZS9mfzXXIFWRL3kswqnQTu/QNFdyFj1mP0haF24w==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/schema/-/schema-3.4.8.tgz",
+      "integrity": "sha512-nu+mT8LgeoCF65xs+F9qegJsIWqYOzwkzJLEd7zmHGRMMYqaFDqcp63J3CUQy+UvS4dGTZph38aQuVfncS/fJA==",
       "requires": {
-        "@types/geojson": "^7946.0.7",
-        "apache-arrow": "^4.0.0",
-        "d3-dsv": "^1.2.0"
+        "@types/geojson": "^7946.0.7"
       }
     },
     "@loaders.gl/terrain": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-3.0.8.tgz",
-      "integrity": "sha512-MtOAYEB/xJB4CN4B0YNPkO4v1ZY332joxiOHQI1x37x4sWVAqOrKLr9jB42sZCB8aINi2WMWGiErtf9wh9L5Pg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/terrain/-/terrain-3.4.8.tgz",
+      "integrity": "sha512-bWLePOb6+4N8DNMXP0D3aqkwyU3phuUjzjQLvfoP9dySUuX4E9kwarCcmkaCYyqp2swp57cHaylSd6tHXOFR6w==",
       "requires": {
         "@babel/runtime": "^7.3.1",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/schema": "3.0.8",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
         "@mapbox/martini": "^0.2.0"
       }
     },
+    "@loaders.gl/textures": {
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/textures/-/textures-3.4.8.tgz",
+      "integrity": "sha512-lFlV1/3yQqBANP5FoywuQwh+Br++BU3/6eT/Eb/zDbKOqTuqtHp7yAUz207tAO3mRqTkPvtKi9fv+0QrBGoxtw==",
+      "requires": {
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "@loaders.gl/worker-utils": "3.4.8",
+        "ktx-parse": "^0.0.4",
+        "texture-compressor": "^1.0.2"
+      }
+    },
     "@loaders.gl/tiles": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-3.0.8.tgz",
-      "integrity": "sha512-Rc+yHFdQg2sYmcYkwvszukFWdm9EW354F9HUR7y/oauos6tsdo4YTj31zgytaYR63/EqWQ7kwI29/eePEcutzg==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/tiles/-/tiles-3.4.8.tgz",
+      "integrity": "sha512-rA3ULOokiUTH6Y3sr37wGaTx3P0g/hRti9yB6q/8kSBy+fE1gSD801O4VluNx6DbOELR2zWkM8TqLTep6sBN1A==",
       "requires": {
-        "@loaders.gl/core": "3.0.8",
-        "@loaders.gl/loader-utils": "3.0.8",
-        "@loaders.gl/math": "3.0.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/math": "3.4.8",
         "@math.gl/core": "^3.5.1",
         "@math.gl/culling": "^3.5.1",
         "@math.gl/geospatial": "^3.5.1",
         "@math.gl/web-mercator": "^3.5.1",
-        "@probe.gl/stats": "^3.4.0"
+        "@probe.gl/stats": "^4.0.1"
+      },
+      "dependencies": {
+        "@probe.gl/stats": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-4.0.4.tgz",
+          "integrity": "sha512-SDuSY/D4yDL6LQDa69l/GCcnZLRiGYdyvYkxWb0CgnzTPdPrcdrzGkzkvpC3zsA4fEFw2smlDje370QGHwlisg==",
+          "requires": {
+            "@babel/runtime": "^7.0.0"
+          }
+        }
+      }
+    },
+    "@loaders.gl/wms": {
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/wms/-/wms-3.4.8.tgz",
+      "integrity": "sha512-4ESwVUa6dStmGqHIqdz6XFo/b/uyB6O+A1iy/mhMGTW8JodrzTcPQl5Iq8fA6EEYP0xviXFL652IEn+dR/BsGg==",
+      "requires": {
+        "@babel/runtime": "^7.3.1",
+        "@loaders.gl/images": "3.4.8",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "@loaders.gl/xml": "3.4.8",
+        "@turf/rewind": "^5.1.5",
+        "deep-strict-equal": "^0.2.0",
+        "lerc": "^4.0.1"
       }
     },
     "@loaders.gl/worker-utils": {
-      "version": "3.0.8",
-      "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-3.0.8.tgz",
-      "integrity": "sha512-Pg72HuXPcL725TrOlOr83xloVUHj6OMWmno1dI8ccuqfOBsgoRjxNZrcSvwBzfK8tFCzuN2X30I+mHl3BkuYLw==",
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/worker-utils/-/worker-utils-3.4.8.tgz",
+      "integrity": "sha512-cioo1rKtUkbDPJVQZ5ytEc6r/LdR1eIOCszgRh1VymtYvWGT+prZxfCIAmM1uZBV2SLWYTnH17dR0PR+cNopzA==",
       "requires": {
         "@babel/runtime": "^7.3.1"
       }
     },
+    "@loaders.gl/xml": {
+      "version": "3.4.8",
+      "resolved": "https://registry.npmjs.org/@loaders.gl/xml/-/xml-3.4.8.tgz",
+      "integrity": "sha512-8lrmdsnaobENpEPalEAzP720UY3kA/w6w7vCUKABB60QHnq+D5Rvw1PLPfQCACMFhYF+vR56KcQjtEbuqhs5wA==",
+      "requires": {
+        "@babel/runtime": "^7.3.1",
+        "@loaders.gl/loader-utils": "3.4.8",
+        "@loaders.gl/schema": "3.4.8",
+        "fast-xml-parser": "^4.2.5"
+      }
+    },
     "@luma.gl/constants": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.5.4.tgz",
-      "integrity": "sha512-lrA4ja92om/gDHYOvM9itL5S7FVzjKulyknDz6S+Y7gmgHgXk2ln1Xar5zUCsLnhAYx4glHITXGH5Y5rdWgT1Q=="
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/constants/-/constants-8.5.20.tgz",
+      "integrity": "sha512-5yG+ybkUZ4j6kLPWMZjN4Hun2yLB0MyEpNCRKAUN9/yS9UIWA7unyVxjSf2vnE7k/7dywtxlbXegASNFgNVGxw=="
     },
     "@luma.gl/core": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-8.5.4.tgz",
-      "integrity": "sha512-+saDz1D3mcPd53vgbG60ryg1w5CF9Z2wdakKHzR810VoJLw97t4aNdg/eNgyWOvbOHxaKJBPm8K0sGjej67+jw==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/core/-/core-8.5.20.tgz",
+      "integrity": "sha512-xJr96G6vhYcznYHC84fbeOG3fgNM4lFwj9bd0VPcg/Kfe8otUeN1Hl0AKHCCtNn48PiMSg3LKbaiRfNUMhaffQ==",
       "requires": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "@luma.gl/engine": "8.5.4",
-        "@luma.gl/gltools": "8.5.4",
-        "@luma.gl/shadertools": "8.5.4",
-        "@luma.gl/webgl": "8.5.4"
+        "@luma.gl/constants": "8.5.20",
+        "@luma.gl/engine": "8.5.20",
+        "@luma.gl/gltools": "8.5.20",
+        "@luma.gl/shadertools": "8.5.20",
+        "@luma.gl/webgl": "8.5.20"
       }
     },
     "@luma.gl/engine": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-8.5.4.tgz",
-      "integrity": "sha512-Sfv972IzvR9s9kKWugs67XQUh9jC0e/PpBrzvyGVnPU4XvFq42RZVF73pzEklVU6AlpR8Zg5CPtxGdhyOHtT7w==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/engine/-/engine-8.5.20.tgz",
+      "integrity": "sha512-+0ryJ/4gL1pWaEgZimY21jUPt1LYiO6Cqte8TNUprCfAHoAStsuzD7jwgEqnM6jJOUEdIxQ3w0z3Dzw/0KIE+w==",
       "requires": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "@luma.gl/gltools": "8.5.4",
-        "@luma.gl/shadertools": "8.5.4",
-        "@luma.gl/webgl": "8.5.4",
+        "@luma.gl/constants": "8.5.20",
+        "@luma.gl/gltools": "8.5.20",
+        "@luma.gl/shadertools": "8.5.20",
+        "@luma.gl/webgl": "8.5.20",
         "@math.gl/core": "^3.5.0",
-        "probe.gl": "^3.4.0"
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/stats": "^3.5.0",
+        "@types/offscreencanvas": "^2019.7.0"
       }
     },
     "@luma.gl/experimental": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/experimental/-/experimental-8.5.4.tgz",
-      "integrity": "sha512-09waqRhgIrw+Sq0/in4tw4jPag5YsFfV1nEHJaLAg5RFv92S53IEubSJgkuG02HoOBkPxQ7KYvs9VNmriisnYg==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/experimental/-/experimental-8.5.20.tgz",
+      "integrity": "sha512-V1Jp68rYMPtwMdf+50r3NSYsGV3srjwZ+lcK2ew4DshjedDbYwLqTGMWcOyBhY3K3aCl2LH3Fhn0hAY+3NTLGA==",
       "requires": {
-        "@luma.gl/constants": "8.5.4",
+        "@luma.gl/constants": "8.5.20",
         "@math.gl/core": "^3.5.0",
         "earcut": "^2.0.6"
       }
     },
     "@luma.gl/gltools": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/gltools/-/gltools-8.5.4.tgz",
-      "integrity": "sha512-JotiPuymQz2Xc41AYlS2moJC/EHxU+OX/OMKi0+/MeOlEFLsdochgTA0I64j8yofLTXdeiGCneGtD1Ao8fk+bw==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/gltools/-/gltools-8.5.20.tgz",
+      "integrity": "sha512-5pP6ph9FSX5gHiVWQM1DmYRUnriklzKUG9yaqlQsKEqCFsOcKB0EfK3MfBVXIfsOdP/1bJZ9Dlz/zV19soWVhg==",
       "requires": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "probe.gl": "^3.4.0"
+        "@luma.gl/constants": "8.5.20",
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/log": "^3.5.0",
+        "@types/offscreencanvas": "^2019.7.0"
       }
     },
     "@luma.gl/shadertools": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-8.5.4.tgz",
-      "integrity": "sha512-rwLBLrACi75aWnuJm8rVKCQnJR2sMTCxHuexfjHJ7Uecl0vVcVJZT7c9EnCFaz5LUTNbdupvuhq0SKNckKiKmw==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/shadertools/-/shadertools-8.5.20.tgz",
+      "integrity": "sha512-q1lrCZy1ncIFb4mMjsYgISLzNP6eMnhLUY+Oltj/qjAMcPEssCeHN2+XGfP/CVtU+O7sC+5JY2bQGaTs6HQ/Qw==",
       "requires": {
         "@babel/runtime": "^7.0.0",
         "@math.gl/core": "^3.5.0"
       }
     },
     "@luma.gl/webgl": {
-      "version": "8.5.4",
-      "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-8.5.4.tgz",
-      "integrity": "sha512-dWy4dhTbtvDO9zQBdx1Yb+DxNx/1JWV9rhhJxJUtTKbGZSX0RjkASTT6GBWMl5jrH1JYJefS1wswHmmPVXjK0Q==",
+      "version": "8.5.20",
+      "resolved": "https://registry.npmjs.org/@luma.gl/webgl/-/webgl-8.5.20.tgz",
+      "integrity": "sha512-p/kt9KztywH4l+09XHoZ4cPFOoE7xlZXIBMT8rxRVgfe1w0lvi7QYh4tOG7gk+iixQ34EyDQacoHCsabdpmqQg==",
       "requires": {
         "@babel/runtime": "^7.0.0",
-        "@luma.gl/constants": "8.5.4",
-        "@luma.gl/gltools": "8.5.4",
-        "probe.gl": "^3.4.0"
+        "@luma.gl/constants": "8.5.20",
+        "@luma.gl/gltools": "8.5.20",
+        "@probe.gl/env": "^3.5.0",
+        "@probe.gl/stats": "^3.5.0"
       }
     },
     "@mapbox/extent": {
@@ -71309,10 +71437,13 @@
       "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
       "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI="
     },
-    "@mapbox/tiny-sdf": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.2.5.tgz",
-      "integrity": "sha512-cD8A/zJlm6fdJOk6DqPUV8mcpyJkRz2x2R+/fYcWDYG3oWbG7/L7Yl/WqQ1VZCjnL9OTIMAn6c+BC5Eru4sQEw=="
+    "@mapbox/tile-cover": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@mapbox/tile-cover/-/tile-cover-3.0.1.tgz",
+      "integrity": "sha512-R8aoFY/87HWBOL9E2eBqzOY2lpfWYXCcTNgBpIxAv67rqQeD4IfnHD0iPXg/Z1cqXrklegEYZCp/7ZR/RsWqBQ==",
+      "requires": {
+        "tilebelt": "^1.0.1"
+      }
     },
     "@mapbox/unitbezier": {
       "version": "0.0.0",
@@ -71342,13 +71473,25 @@
       }
     },
     "@math.gl/culling": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-3.5.3.tgz",
-      "integrity": "sha512-ABpAcrvoIOLSm1EUkwgDem4RfO28HWPBs/+taZ/ZSpJG6KiVPklpKU1NCK+05HuJStkpFZ+XlWtehWU6FAMCyA==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/culling/-/culling-3.6.3.tgz",
+      "integrity": "sha512-3UERXHbaPlM6pnTk2MI7LeQ5CoelDZzDzghTTcv+HdQCZsT/EOEuEdYimETHtSxiyiOmsX2Un65UBLYT/rbKZg==",
       "requires": {
         "@babel/runtime": "^7.12.0",
-        "@math.gl/core": "3.5.3",
-        "gl-matrix": "^3.0.0"
+        "@math.gl/core": "3.6.3",
+        "gl-matrix": "^3.4.0"
+      },
+      "dependencies": {
+        "@math.gl/core": {
+          "version": "3.6.3",
+          "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+          "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+          "requires": {
+            "@babel/runtime": "^7.12.0",
+            "@math.gl/types": "3.6.3",
+            "gl-matrix": "^3.4.0"
+          }
+        }
       }
     },
     "@math.gl/geospatial": {
@@ -71362,20 +71505,45 @@
       }
     },
     "@math.gl/polygon": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-3.5.3.tgz",
-      "integrity": "sha512-VktscmyQg/Rd56nJk0Nj/UyvnPDbsnZNMWCdl3G5AYenYzLWy6h4FEWhLx8pD+Xw7VuFot8LR4WAK2TPzXzrWw==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/polygon/-/polygon-3.6.3.tgz",
+      "integrity": "sha512-FivQ1ZnYcAss1wVifOkHP/ZnlfQy1IL/769uzNtiHxwUbW0kZG3yyOZ9I7fwyzR5Hvqt3ErJKHjSYZr0uVlz5g==",
       "requires": {
-        "@math.gl/core": "3.5.3"
+        "@math.gl/core": "3.6.3"
+      },
+      "dependencies": {
+        "@math.gl/core": {
+          "version": "3.6.3",
+          "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+          "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+          "requires": {
+            "@babel/runtime": "^7.12.0",
+            "@math.gl/types": "3.6.3",
+            "gl-matrix": "^3.4.0"
+          }
+        }
+      }
+    },
+    "@math.gl/sun": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/sun/-/sun-3.6.3.tgz",
+      "integrity": "sha512-mrx6CGYYeTNSQttvcw0KVUy+35YDmnjMqpO/o0t06Vcghrt0HNruB/ScRgUSbJrgkbOg1Vcqm23HBd++clzQzw==",
+      "requires": {
+        "@babel/runtime": "^7.12.0"
       }
     },
+    "@math.gl/types": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/types/-/types-3.6.3.tgz",
+      "integrity": "sha512-3uWLVXHY3jQxsXCr/UCNPSc2BG0hNUljhmOBt9l+lNFDp7zHgm0cK2Tw4kj2XfkJy4TgwZTBGwRDQgWEbLbdTA=="
+    },
     "@math.gl/web-mercator": {
-      "version": "3.5.6",
-      "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.5.6.tgz",
-      "integrity": "sha512-siWHLJGp9o8fDEM1t0Rby+JXftl6il0z3927liWGzkHqFftXPHY858ShPy45ThDU8q5lyCftg8aVgrv4nfD+Zw==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/@math.gl/web-mercator/-/web-mercator-3.6.3.tgz",
+      "integrity": "sha512-UVrkSOs02YLehKaehrxhAejYMurehIHPfFQvPFZmdJHglHOU4V2cCUApTVEwOksvCp161ypEqVp+9H6mGhTTcw==",
       "requires": {
         "@babel/runtime": "^7.12.0",
-        "gl-matrix": "~3.3.0"
+        "gl-matrix": "^3.4.0"
       }
     },
     "@mdx-js/loader": {
@@ -72624,10 +72792,27 @@
       "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz",
       "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw=="
     },
+    "@probe.gl/env": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@probe.gl/env/-/env-3.6.0.tgz",
+      "integrity": "sha512-4tTZYUg/8BICC3Yyb9rOeoKeijKbZHRXBEKObrfPmX4sQmYB15ZOUpoVBhAyJkOYVAM8EkPci6Uw5dLCwx2BEQ==",
+      "requires": {
+        "@babel/runtime": "^7.0.0"
+      }
+    },
+    "@probe.gl/log": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@probe.gl/log/-/log-3.6.0.tgz",
+      "integrity": "sha512-hjpyenpEvOdowgZ1qMeCJxfRD4JkKdlXz0RC14m42Un62NtOT+GpWyKA4LssT0+xyLULCByRAtG2fzZorpIAcA==",
+      "requires": {
+        "@babel/runtime": "^7.0.0",
+        "@probe.gl/env": "3.6.0"
+      }
+    },
     "@probe.gl/stats": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.4.0.tgz",
-      "integrity": "sha512-Gl37r9qGuiKadIvTZdSZvzCNOttJYw6RcY1oT0oDuB8r2uhuZAdSMQRQTy9FTinp6MY6O9wngGnV6EpQ8wSBAw==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/@probe.gl/stats/-/stats-3.6.0.tgz",
+      "integrity": "sha512-JdALQXB44OP4kUBN/UrQgzbJe4qokbVF4Y8lkIA8iVCFnjVowWIgkD/z/0QO65yELT54tTrtepw1jScjKB+rhQ==",
       "requires": {
         "@babel/runtime": "^7.0.0"
       }
@@ -77799,12 +77984,14 @@
         "@mapbox/geojson-extent": "^1.0.1",
         "@math.gl/web-mercator": "^3.2.2",
         "@types/d3-array": "^2.0.0",
+        "@types/mapbox__geojson-extent": "*",
+        "@types/underscore": "^1.11.6",
+        "@types/urijs": "^1.19.19",
         "bootstrap-slider": "^10.0.0",
         "d3-array": "^1.2.4",
         "d3-color": "^1.4.1",
         "d3-scale": "^3.0.0",
-        "deck.gl": "8.5.2",
-        "jquery": "^3.4.1",
+        "deck.gl": "8.8.27",
         "lodash": "^4.17.15",
         "moment": "^2.20.1",
         "mousetrap": "^1.6.1",
@@ -77815,6 +78002,206 @@
         "xss": "^1.0.10"
       },
       "dependencies": {
+        "@deck.gl/aggregation-layers": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/aggregation-layers/-/aggregation-layers-8.9.22.tgz",
+          "integrity": "sha512-cw2duTxcZI0i0+295ivo/tsLffB6GPhuwkCYhqrVfO61JsK9GFuISGB7C5tMcfSOSxzgN6JwNA4fJEK1bCGozQ==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@luma.gl/constants": "^8.5.20",
+            "@luma.gl/shadertools": "^8.5.20",
+            "@math.gl/web-mercator": "^3.6.2",
+            "d3-hexbin": "^0.2.1"
+          }
+        },
+        "@deck.gl/carto": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/carto/-/carto-8.9.22.tgz",
+          "integrity": "sha512-sfSmzUtXrhvMX5JaFiIpQtmfqVHRxcVIxnSZz6F5Q7DtvBhjNMEt3jq3qJ3IWH0EyxX0Xu+HMjmw6ScnsVAcXQ==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@loaders.gl/gis": "^3.4.2",
+            "@loaders.gl/loader-utils": "^3.4.2",
+            "@loaders.gl/mvt": "^3.4.2",
+            "@loaders.gl/tiles": "^3.4.2",
+            "@luma.gl/constants": "^8.5.20",
+            "@math.gl/web-mercator": "^3.6.2",
+            "cartocolor": "^4.0.2",
+            "d3-array": "^3.2.0",
+            "d3-color": "^3.1.0",
+            "d3-format": "^3.1.0",
+            "d3-scale": "^4.0.0",
+            "h3-js": "^3.7.0",
+            "moment-timezone": "^0.5.33",
+            "pbf": "^3.2.1",
+            "quadbin": "^0.1.9"
+          },
+          "dependencies": {
+            "d3-array": {
+              "version": "3.2.4",
+              "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+              "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+              "requires": {
+                "internmap": "1 - 2"
+              }
+            },
+            "d3-color": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+              "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="
+            },
+            "d3-format": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+              "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="
+            },
+            "d3-scale": {
+              "version": "4.0.2",
+              "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+              "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+              "requires": {
+                "d3-array": "2.10.0 - 3",
+                "d3-format": "1 - 3",
+                "d3-interpolate": "1.2.0 - 3",
+                "d3-time": "2.1.1 - 3",
+                "d3-time-format": "2 - 4"
+              }
+            }
+          }
+        },
+        "@deck.gl/core": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/core/-/core-8.9.22.tgz",
+          "integrity": "sha512-HnUPB6qKgRfKQ3Dstw6vlI7+fyO9Ni4gukh8ysQM94mw89BRLkVcuQV0XvlzbbojrG1Z6QpC7KZmodW0y5o2og==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@loaders.gl/core": "^3.4.2",
+            "@loaders.gl/images": "^3.4.2",
+            "@luma.gl/constants": "^8.5.20",
+            "@luma.gl/core": "^8.5.20",
+            "@luma.gl/webgl": "^8.5.20",
+            "@math.gl/core": "^3.6.2",
+            "@math.gl/sun": "^3.6.2",
+            "@math.gl/web-mercator": "^3.6.2",
+            "@probe.gl/env": "^3.5.0",
+            "@probe.gl/log": "^3.5.0",
+            "@probe.gl/stats": "^3.5.0",
+            "gl-matrix": "^3.0.0",
+            "math.gl": "^3.6.2",
+            "mjolnir.js": "^2.7.0"
+          }
+        },
+        "@deck.gl/extensions": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/extensions/-/extensions-8.9.22.tgz",
+          "integrity": "sha512-MYyWjnf94Ibs3BNfTIq/oJJLrNMWUpS2+qkmkQie03EGeO7/wJ9BAQAXWYdFdrbvCykw60mLBX78a68+XLvbmQ==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@luma.gl/shadertools": "^8.5.20"
+          }
+        },
+        "@deck.gl/geo-layers": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/geo-layers/-/geo-layers-8.9.22.tgz",
+          "integrity": "sha512-/P6kGxlWhfRPAaG0UDklANTQpQGevAE1zGTOyFVYEAMyRBws/CetLCq5rKfYibTjWBa5FO2U0u837HzG0PJRUw==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@loaders.gl/3d-tiles": "^3.4.2",
+            "@loaders.gl/gis": "^3.4.2",
+            "@loaders.gl/loader-utils": "^3.4.2",
+            "@loaders.gl/mvt": "^3.4.2",
+            "@loaders.gl/schema": "^3.4.2",
+            "@loaders.gl/terrain": "^3.4.2",
+            "@loaders.gl/tiles": "^3.4.2",
+            "@loaders.gl/wms": "^3.4.2",
+            "@luma.gl/constants": "^8.5.20",
+            "@luma.gl/experimental": "^8.5.20",
+            "@math.gl/core": "^3.6.2",
+            "@math.gl/culling": "^3.6.2",
+            "@math.gl/web-mercator": "^3.6.2",
+            "@types/geojson": "^7946.0.8",
+            "h3-js": "^3.7.0",
+            "long": "^3.2.0"
+          }
+        },
+        "@deck.gl/google-maps": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/google-maps/-/google-maps-8.9.22.tgz",
+          "integrity": "sha512-x+9yqxkjLN0P5uKxYB6GEaM0KV2djBotvHX0BaHL9LbyWzdAvGJP1kmTg4SOpi0I7XG8jdkoca/tAZ2yy7A9RQ==",
+          "requires": {
+            "@babel/runtime": "^7.0.0"
+          }
+        },
+        "@deck.gl/json": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/json/-/json-8.9.22.tgz",
+          "integrity": "sha512-rYFZqp7mW8XvExtLAfGiAxTV7oLPaLmPVDPTYmMU2owSkfGYE3q6YvwqzHq37k5/5jLfJMA0cZy1fQrfJW3+gg==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "d3-dsv": "^1.0.8",
+            "expression-eval": "^2.0.0"
+          }
+        },
+        "@deck.gl/layers": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/layers/-/layers-8.9.22.tgz",
+          "integrity": "sha512-1IipECeORaT2fdU9k8KPnZ3DjUeH02h6oZYl4ffihNAIoVXKNivghgJ8ZeELLiEOkrxlbK+KjoH1zej7yuMwmg==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@loaders.gl/images": "^3.4.2",
+            "@loaders.gl/schema": "^3.4.2",
+            "@luma.gl/constants": "^8.5.20",
+            "@mapbox/tiny-sdf": "^2.0.5",
+            "@math.gl/core": "^3.6.2",
+            "@math.gl/polygon": "^3.6.2",
+            "@math.gl/web-mercator": "^3.6.2",
+            "earcut": "^2.2.4"
+          }
+        },
+        "@deck.gl/mapbox": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/mapbox/-/mapbox-8.9.22.tgz",
+          "integrity": "sha512-VanA1V/BE6vmHn/W9f8ug4ilMDEfP3JUQWegVaCiG2EA8yjML6QVmO31gNARTefBjgMsfkWDBwm325coIUkxBQ==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@types/mapbox-gl": "^2.6.3"
+          }
+        },
+        "@deck.gl/mesh-layers": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/mesh-layers/-/mesh-layers-8.9.22.tgz",
+          "integrity": "sha512-XJ6WdHphBtdumQYseFQCfGQ8KLRzgOGu89qsiEcuRTQwgW5GxXi4WJSpZmXZGtXObubwuEX6YqrN4BkX3F/nWg==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@loaders.gl/gltf": "^3.4.2",
+            "@luma.gl/constants": "^8.5.20",
+            "@luma.gl/experimental": "^8.5.20",
+            "@luma.gl/shadertools": "^8.5.20"
+          }
+        },
+        "@deck.gl/react": {
+          "version": "8.9.22",
+          "resolved": "https://registry.npmjs.org/@deck.gl/react/-/react-8.9.22.tgz",
+          "integrity": "sha512-NZcWBlOWYPs+DQqYSZQFLxfguFe0GP2AE1ojlrstnckV1N3bsMf1dT6AI5AvX5h9DbiBc216ZrV9iwVhlfkLng==",
+          "requires": {
+            "@babel/runtime": "^7.0.0"
+          }
+        },
+        "@mapbox/tiny-sdf": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.6.tgz",
+          "integrity": "sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA=="
+        },
+        "@math.gl/core": {
+          "version": "3.6.3",
+          "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+          "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+          "requires": {
+            "@babel/runtime": "^7.12.0",
+            "@math.gl/types": "3.6.3",
+            "gl-matrix": "^3.4.0"
+          }
+        },
         "d3-color": {
           "version": "1.4.1",
           "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.1.tgz",
@@ -77859,6 +78246,24 @@
               }
             }
           }
+        },
+        "deck.gl": {
+          "version": "https://registry.npmjs.org/deck.gl/-/deck.gl-8.9.22.tgz",
+          "integrity": "sha512-CkJ/Wtyquh4wpG7Os6n5j4D9fm0NFROa6Go0hEToVU8kbfQoj6drD76ixBnsx47dOtcHNQ11AVaPaaAeHmnTjg==",
+          "requires": {
+            "@babel/runtime": "^7.0.0",
+            "@deck.gl/aggregation-layers": "8.9.22",
+            "@deck.gl/carto": "8.9.22",
+            "@deck.gl/core": "8.9.22",
+            "@deck.gl/extensions": "8.9.22",
+            "@deck.gl/geo-layers": "8.9.22",
+            "@deck.gl/google-maps": "8.9.22",
+            "@deck.gl/json": "8.9.22",
+            "@deck.gl/layers": "8.9.22",
+            "@deck.gl/mapbox": "8.9.22",
+            "@deck.gl/mesh-layers": "8.9.22",
+            "@deck.gl/react": "8.9.22"
+          }
         }
       }
     },
@@ -78393,6 +78798,56 @@
         }
       }
     },
+    "@turf/boolean-clockwise": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-5.1.5.tgz",
+      "integrity": "sha512-FqbmEEOJ4rU4/2t7FKx0HUWmjFEVqR+NJrFP7ymGSjja2SQ7Q91nnBihGuT+yuHHl6ElMjQ3ttsB/eTmyCycxA==",
+      "requires": {
+        "@turf/helpers": "^5.1.5",
+        "@turf/invariant": "^5.1.5"
+      }
+    },
+    "@turf/clone": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-5.1.5.tgz",
+      "integrity": "sha512-//pITsQ8xUdcQ9pVb4JqXiSqG4dos5Q9N4sYFoWghX21tfOV2dhc5TGqYOhnHrQS7RiKQL1vQ48kIK34gQ5oRg==",
+      "requires": {
+        "@turf/helpers": "^5.1.5"
+      }
+    },
+    "@turf/helpers": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz",
+      "integrity": "sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw=="
+    },
+    "@turf/invariant": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.2.0.tgz",
+      "integrity": "sha512-28RCBGvCYsajVkw2EydpzLdcYyhSA77LovuOvgCJplJWaNVyJYH6BOR3HR9w50MEkPqb/Vc/jdo6I6ermlRtQA==",
+      "requires": {
+        "@turf/helpers": "^5.1.5"
+      }
+    },
+    "@turf/meta": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-5.2.0.tgz",
+      "integrity": "sha512-ZjQ3Ii62X9FjnK4hhdsbT+64AYRpaI8XMBMcyftEOGSmPMUVnkbvuv3C9geuElAXfQU7Zk1oWGOcrGOD9zr78Q==",
+      "requires": {
+        "@turf/helpers": "^5.1.5"
+      }
+    },
+    "@turf/rewind": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-5.1.5.tgz",
+      "integrity": "sha512-Gdem7JXNu+G4hMllQHXRFRihJl3+pNl7qY+l4qhQFxq+hiU1cQoVFnyoleIqWKIrdK/i2YubaSwc3SCM7N5mMw==",
+      "requires": {
+        "@turf/boolean-clockwise": "^5.1.5",
+        "@turf/clone": "^5.1.5",
+        "@turf/helpers": "^5.1.5",
+        "@turf/invariant": "^5.1.5",
+        "@turf/meta": "^5.1.5"
+      }
+    },
     "@types/aria-query": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.0.tgz",
@@ -78669,11 +79124,6 @@
       "resolved": "https://registry.npmjs.org/@types/fetch-mock/-/fetch-mock-7.3.5.tgz",
       "integrity": "sha512-sLecm9ohBdGIpYUP9rWk5/XIKY2xHMYTBJIcJuBBM8IJWnYoQ1DAj8F4OVjnfD0API1drlkWEV0LPNk+ACuhsg=="
     },
-    "@types/flatbuffers": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz",
-      "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA=="
-    },
     "@types/geojson": {
       "version": "7946.0.8",
       "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz",
@@ -78697,6 +79147,11 @@
         "@types/node": "*"
       }
     },
+    "@types/hammerjs": {
+      "version": "2.0.41",
+      "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz",
+      "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA=="
+    },
     "@types/hast": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
@@ -78815,6 +79270,15 @@
         "@types/lodash": "*"
       }
     },
+    "@types/mapbox__geojson-extent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@types/mapbox__geojson-extent/-/mapbox__geojson-extent-1.0.0.tgz",
+      "integrity": "sha512-RJBeVDv7LDmW4gO3VD8pr/OYuToQtF77H/VRDG733fmA6chzztBTz6yi9/llRD8SpM7fznxhP6B43Izaj4ufoA==",
+      "dev": true,
+      "requires": {
+        "@types/geojson": "*"
+      }
+    },
     "@types/mapbox-gl": {
       "version": "2.7.6",
       "resolved": "https://registry.npmjs.org/@types/mapbox-gl/-/mapbox-gl-2.7.6.tgz",
@@ -78894,6 +79358,11 @@
       "resolved": "https://registry.npmjs.org/@types/npmlog/-/npmlog-4.1.4.tgz",
       "integrity": "sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ=="
     },
+    "@types/offscreencanvas": {
+      "version": "2019.7.0",
+      "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.0.tgz",
+      "integrity": "sha512-PGcyveRIpL1XIqK8eBsmRBt76eFgtzuPiSTyKHZxnGemp2yzGzWpjYKAfK3wIMiU7eH+851yEpiuP8JZerTmWg=="
+    },
     "@types/overlayscrollbars": {
       "version": "1.12.1",
       "resolved": "https://registry.npmjs.org/@types/overlayscrollbars/-/overlayscrollbars-1.12.1.tgz",
@@ -79217,11 +79686,6 @@
         "@types/jest": "*"
       }
     },
-    "@types/text-encoding-utf-8": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz",
-      "integrity": "sha512-AQ6zewa0ucLJvtUi5HsErbOFKAcQfRLt9zFLlUOvcXBy2G36a+ZDpCHSGdzJVUD8aNURtIjh9aSjCStNMRCcRQ=="
-    },
     "@types/tinycolor2": {
       "version": "1.4.3",
       "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.3.tgz",
@@ -79242,11 +79706,23 @@
         }
       }
     },
+    "@types/underscore": {
+      "version": "1.11.6",
+      "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.6.tgz",
+      "integrity": "sha512-G2oC64I/sR817KDL2b2Mc7+diXyxcibyUeLMyexU4K/sG8hyt/YMlbBK0TVhx/YQ1ehfzgXhLuq2YQHIL4bXUQ==",
+      "dev": true
+    },
     "@types/unist": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
       "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ=="
     },
+    "@types/urijs": {
+      "version": "1.19.19",
+      "resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.19.tgz",
+      "integrity": "sha512-FDJNkyhmKLw7uEvTxx5tSXfPeQpO0iy73Ry+PmYZJvQy0QIWX8a7kJ4kLWRf+EbTPJEPDSgPXHaM7pzr5lmvCg==",
+      "dev": true
+    },
     "@types/vinyl": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.6.tgz",
@@ -81349,35 +81825,6 @@
         "normalize-path": "^2.1.1"
       }
     },
-    "apache-arrow": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-4.0.1.tgz",
-      "integrity": "sha512-DyF7GXCbSjsw4P5C8b+qW7OnJKa6w9mJI0mhV0+EfZbVZCmhfiF6ffqcnrI/kzBrRqn9hH/Ft9n5+m4DTbBJpg==",
-      "requires": {
-        "@types/flatbuffers": "^1.10.0",
-        "@types/node": "^14.14.37",
-        "@types/text-encoding-utf-8": "^1.0.1",
-        "command-line-args": "5.1.1",
-        "command-line-usage": "6.1.1",
-        "flatbuffers": "1.12.0",
-        "json-bignum": "^0.0.3",
-        "pad-left": "^2.1.0",
-        "text-encoding-utf-8": "^1.0.2",
-        "tslib": "^2.2.0"
-      },
-      "dependencies": {
-        "@types/node": {
-          "version": "14.17.9",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz",
-          "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g=="
-        },
-        "tslib": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
-          "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
-        }
-      }
-    },
     "aphrodite": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.2.5.tgz",
@@ -81484,11 +81931,6 @@
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
       "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
     },
-    "array-back": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
-      "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q=="
-    },
     "array-differ": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
@@ -82850,6 +83292,11 @@
         "node-int64": "^0.4.0"
       }
     },
+    "buf-compare": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
+      "integrity": "sha512-Bvx4xH00qweepGc43xFvMs5BKASXTbHaHm6+kDYIK9p/4iFwjATQkmPKHQSgJZzKbAymhztRbXUf1Nqhzl73/Q=="
+    },
     "buffer": {
       "version": "4.9.2",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
@@ -83899,66 +84346,6 @@
         "trim": "0.0.1"
       }
     },
-    "command-line-args": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
-      "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
-      "requires": {
-        "array-back": "^3.0.1",
-        "find-replace": "^3.0.0",
-        "lodash.camelcase": "^4.3.0",
-        "typical": "^4.0.0"
-      }
-    },
-    "command-line-usage": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz",
-      "integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==",
-      "requires": {
-        "array-back": "^4.0.1",
-        "chalk": "^2.4.2",
-        "table-layout": "^1.0.1",
-        "typical": "^5.2.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "array-back": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
-          "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg=="
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        },
-        "typical": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
-          "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
-        }
-      }
-    },
     "commander": {
       "version": "2.20.3",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -84501,6 +84888,15 @@
         }
       }
     },
+    "core-assert": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
+      "integrity": "sha512-IG97qShIP+nrJCXMCgkNZgH7jZQ4n8RpPyPeXX++T6avR/KhLhgLiHKoEn5Rc1KjfycSfA9DMa6m+4C4eguHhw==",
+      "requires": {
+        "buf-compare": "^1.0.0",
+        "is-error": "^2.2.0"
+      }
+    },
     "core-js": {
       "version": "3.31.1",
       "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.1.tgz",
@@ -86166,24 +86562,6 @@
       "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==",
       "dev": true
     },
-    "deck.gl": {
-      "version": "8.5.2",
-      "resolved": "https://registry.npmjs.org/deck.gl/-/deck.gl-8.5.2.tgz",
-      "integrity": "sha512-tsEyv62Zzc+GT3By0Y1R2gqEJ8K3tGBDaLprAoeAsg7fvIa5ikFBdWEBFHa1UDbgE2UEmYbcBK/yK4GAL8Ia4A==",
-      "requires": {
-        "@deck.gl/aggregation-layers": "8.5.2",
-        "@deck.gl/carto": "8.5.2",
-        "@deck.gl/core": "8.5.2",
-        "@deck.gl/extensions": "8.5.2",
-        "@deck.gl/geo-layers": "8.5.2",
-        "@deck.gl/google-maps": "8.5.2",
-        "@deck.gl/json": "8.5.2",
-        "@deck.gl/layers": "8.5.2",
-        "@deck.gl/mapbox": "8.5.2",
-        "@deck.gl/mesh-layers": "8.5.2",
-        "@deck.gl/react": "8.5.2"
-      }
-    },
     "decode-named-character-reference": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
@@ -86233,7 +86611,8 @@
     "deep-extend": {
       "version": "0.6.0",
       "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "devOptional": true
     },
     "deep-is": {
       "version": "0.1.3",
@@ -86245,6 +86624,14 @@
       "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.0.tgz",
       "integrity": "sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw=="
     },
+    "deep-strict-equal": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz",
+      "integrity": "sha512-3daSWyvZ/zwJvuMGlzG1O+Ow0YSadGfb3jsh9xoCutv2tWyB9dA4YvR9L9/fSdDZa2dByYQe+TqapSGUrjnkoA==",
+      "requires": {
+        "core-assert": "^0.2.0"
+      }
+    },
     "deepmerge": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
@@ -86843,9 +87230,9 @@
       }
     },
     "draco3d": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.4.1.tgz",
-      "integrity": "sha512-9Rxonc70xiovBC+Bq1h57SNZIHzWTibU1VfIGp5z3Xx8dPtv4yT5uGhiH7P5uvJRR2jkrvHafRxR7bTANkvfpg=="
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.5.tgz",
+      "integrity": "sha512-JVuNV0EJzD3LBYhGyIXJLeBID/EVtmFO1ZNhAYflTgiMiAJlbhXQmRRda/azjc8MRVMHh0gqGhiqHUo5dIXM8Q=="
     },
     "duplexer": {
       "version": "0.1.2",
@@ -88807,6 +89194,14 @@
       "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
       "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
     },
+    "fast-xml-parser": {
+      "version": "4.2.7",
+      "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz",
+      "integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
+      "requires": {
+        "strnum": "^1.0.5"
+      }
+    },
     "fastest-levenshtein": {
       "version": "1.0.12",
       "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@@ -89099,14 +89494,6 @@
         "pkg-dir": "^3.0.0"
       }
     },
-    "find-replace": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
-      "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
-      "requires": {
-        "array-back": "^3.0.1"
-      }
-    },
     "find-root": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
@@ -89390,11 +89777,6 @@
         "rimraf": "^3.0.2"
       }
     },
-    "flatbuffers": {
-      "version": "1.12.0",
-      "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz",
-      "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ=="
-    },
     "flatted": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz",
@@ -90360,9 +90742,9 @@
       }
     },
     "gl-matrix": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.3.0.tgz",
-      "integrity": "sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA=="
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
+      "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
     },
     "glob": {
       "version": "7.2.3",
@@ -91924,6 +92306,11 @@
         "is-window": "^1.0.2"
       }
     },
+    "is-error": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+      "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg=="
+    },
     "is-extendable": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
@@ -94838,11 +95225,6 @@
         "bignumber.js": "^9.0.0"
       }
     },
-    "json-bignum": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz",
-      "integrity": "sha1-QRY7UENsdz2CQk28IO1w23YEuNc="
-    },
     "json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -95032,6 +95414,11 @@
       "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz",
       "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ=="
     },
+    "ktx-parse": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/ktx-parse/-/ktx-parse-0.0.4.tgz",
+      "integrity": "sha512-LY3nrmfXl+wZZdPxgJ3ZmLvG+wkOZZP3/dr4RbQj1Pk3Qwz44esOOSFFVQJcNWpXAtiNIC66WgXufX/SYgYz6A=="
+    },
     "language-subtag-registry": {
       "version": "0.3.21",
       "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz",
@@ -95089,6 +95476,11 @@
       "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
       "dev": true
     },
+    "lerc": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/lerc/-/lerc-4.0.1.tgz",
+      "integrity": "sha512-b351eOjY3DKm1H2hDVhXswsd2RCK6bgREBK6Z639ctClOuYXTi9a44l8yO3zm1pYM2o4WrriloTAKgyrb/0EyA=="
+    },
     "lerna": {
       "version": "6.6.2",
       "resolved": "https://registry.npmjs.org/lerna/-/lerna-6.6.2.tgz",
@@ -97743,11 +98135,6 @@
       "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=",
       "dev": true
     },
-    "lodash.camelcase": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
-      "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
-    },
     "lodash.curry": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz",
@@ -98312,11 +98699,6 @@
           "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.5.tgz",
           "integrity": "sha512-OhXt2lS//WpLdkqrzo/KwB7SRD8AiNTFFzuo9n14IBupzIMa67yGItcK7I2W9D8Ghpa4T04Sw9FWsKCJG50Bxw=="
         },
-        "gl-matrix": {
-          "version": "3.4.3",
-          "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
-          "integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
-        },
         "supercluster": {
           "version": "7.1.5",
           "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.5.tgz",
@@ -98363,11 +98745,23 @@
       "integrity": "sha512-9FbRY3i6U+CbHgrdNbAUaisjWTozkm1ZfupYQJiZ87NtYHk2Zh9DvxMgp/fifxVhqTLpd5fCCLossUbpZxGeKw=="
     },
     "math.gl": {
-      "version": "3.5.3",
-      "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.5.3.tgz",
-      "integrity": "sha512-cRQRZlc+XvNHd3bIfu3kdPPPAW0vwDelZJmkjn2TDvCyPcmyDtAiZ2Poo1aFoINP7HzN6oHYxapc/0wV3q6Opg==",
+      "version": "3.6.3",
+      "resolved": "https://registry.npmjs.org/math.gl/-/math.gl-3.6.3.tgz",
+      "integrity": "sha512-Yq9CyECvSDox9+5ETi2+x1bGTY5WvGUGL3rJfC4KPoCZAM51MGfrCm6rIn4yOJUVfMPs2a5RwMD+yGS/n1g3gg==",
       "requires": {
-        "@math.gl/core": "3.5.3"
+        "@math.gl/core": "3.6.3"
+      },
+      "dependencies": {
+        "@math.gl/core": {
+          "version": "3.6.3",
+          "resolved": "https://registry.npmjs.org/@math.gl/core/-/core-3.6.3.tgz",
+          "integrity": "sha512-jBABmDkj5uuuE0dTDmwwss7Cup5ZwQ6Qb7h1pgvtkEutTrhkcv8SuItQNXmF45494yIHeoGue08NlyeY6wxq2A==",
+          "requires": {
+            "@babel/runtime": "^7.12.0",
+            "@math.gl/types": "3.6.3",
+            "gl-matrix": "^3.4.0"
+          }
+        }
       }
     },
     "mathfn": {
@@ -99506,11 +99900,11 @@
       }
     },
     "mjolnir.js": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/mjolnir.js/-/mjolnir.js-2.5.0.tgz",
-      "integrity": "sha512-YkVoyKs7qm9xvAgRgjx3Md/7eYqmq7VXOgTKQNnmuzcBJzMebjdIWa7FdTd0RZBrw3UL6V6TTktsxJwBMLXUNA==",
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/mjolnir.js/-/mjolnir.js-2.7.1.tgz",
+      "integrity": "sha512-72BeUWgTv2cj5aZQKpwL8caNUFhXZ9bDm1hxpNj70XJQ62IBnTZmtv/WPxJvtaVNhzNo+D2U8O6ryNI0zImYcw==",
       "requires": {
-        "@babel/runtime": "^7.0.0",
+        "@types/hammerjs": "^2.0.41",
         "hammerjs": "^2.0.8"
       }
     },
@@ -101785,14 +102179,6 @@
       "resolved": "https://registry.npmjs.org/pad-component/-/pad-component-0.0.1.tgz",
       "integrity": "sha1-rR8izhvw/cDW3dkIrxfzUaQEuKw="
     },
-    "pad-left": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-2.1.0.tgz",
-      "integrity": "sha1-FuajstRKjhOMsIOMx8tAOk/J6ZQ=",
-      "requires": {
-        "repeat-string": "^1.5.4"
-      }
-    },
     "pako": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -102460,15 +102846,6 @@
       "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
       "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
     },
-    "probe.gl": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/probe.gl/-/probe.gl-3.4.0.tgz",
-      "integrity": "sha512-9CLByZATuhuG/Viq3ckfWU+dAhb7dMmjzsyCy4s7ds9ueTejcVRENxL197/XacOK/AN61YrEERB0QnouB0Qc0Q==",
-      "requires": {
-        "@babel/runtime": "^7.0.0",
-        "@probe.gl/stats": "3.4.0"
-      }
-    },
     "proc-log": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-1.0.0.tgz",
@@ -102915,6 +103292,14 @@
       "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
       "dev": true
     },
+    "quadbin": {
+      "version": "0.1.9",
+      "resolved": "https://registry.npmjs.org/quadbin/-/quadbin-0.1.9.tgz",
+      "integrity": "sha512-5V6m6+cL/6+uBl3hYL+CWF06rRvlHkIepYKGQjTLYaHhu9InPppql0+0ROiCaOQdz8gPNlgge3glk5Qg1mWOYw==",
+      "requires": {
+        "@mapbox/tile-cover": "3.0.1"
+      }
+    },
     "query-string": {
       "version": "6.14.1",
       "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz",
@@ -104487,11 +104872,6 @@
         }
       }
     },
-    "reduce-flatten": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
-      "integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w=="
-    },
     "reduce-function-call": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz",
@@ -107094,6 +107474,11 @@
         "escape-string-regexp": "^1.0.2"
       }
     },
+    "strnum": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
+      "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
+    },
     "strong-log-transformer": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz",
@@ -107401,29 +107786,6 @@
         }
       }
     },
-    "table-layout": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.2.tgz",
-      "integrity": "sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==",
-      "requires": {
-        "array-back": "^4.0.1",
-        "deep-extend": "~0.6.0",
-        "typical": "^5.2.0",
-        "wordwrapjs": "^4.0.0"
-      },
-      "dependencies": {
-        "array-back": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
-          "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg=="
-        },
-        "typical": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
-          "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
-        }
-      }
-    },
     "taketalk": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/taketalk/-/taketalk-1.0.0.tgz",
@@ -107801,11 +108163,6 @@
         "minimatch": "^3.0.4"
       }
     },
-    "text-encoding-utf-8": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz",
-      "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg=="
-    },
     "text-extensions": {
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz",
@@ -107823,6 +108180,22 @@
       "integrity": "sha512-4cAYwNFNYlIAHBUo7p6zw8POUvWbZor+/R0Tanv+rIhsauEyV9QSrEXL40pI+GfTQxKX8k6Tyw6CmdSDSmASrg==",
       "devOptional": true
     },
+    "texture-compressor": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/texture-compressor/-/texture-compressor-1.0.2.tgz",
+      "integrity": "sha512-dStVgoaQ11mA5htJ+RzZ51ZxIZqNOgWKAIvtjLrW1AliQQLCmrDqNzQZ8Jh91YealQ95DXt4MEduLzJmbs6lig==",
+      "requires": {
+        "argparse": "^1.0.10",
+        "image-size": "^0.7.4"
+      },
+      "dependencies": {
+        "image-size": {
+          "version": "0.7.5",
+          "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
+          "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g=="
+        }
+      }
+    },
     "thread-loader": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-3.0.4.tgz",
@@ -107894,6 +108267,11 @@
       "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
       "devOptional": true
     },
+    "tilebelt": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/tilebelt/-/tilebelt-1.0.1.tgz",
+      "integrity": "sha512-cxHzpa5JgsugY9NUVRH43gPaGJw/29LecAn4X7UGOP64+kB8pU4VQ3bIhSyfb5Mk4jDxwl3yk330L/EIhbJ5aw=="
+    },
     "timers-browserify": {
       "version": "2.0.12",
       "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -108408,11 +108786,6 @@
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
       "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
     },
-    "typical": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
-      "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw=="
-    },
     "ua-parser-js": {
       "version": "0.7.33",
       "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
@@ -110274,22 +110647,6 @@
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
       "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
     },
-    "wordwrapjs": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
-      "integrity": "sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==",
-      "requires": {
-        "reduce-flatten": "^2.0.0",
-        "typical": "^5.2.0"
-      },
-      "dependencies": {
-        "typical": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
-          "integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg=="
-        }
-      }
-    },
     "worker-farm": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
diff --git a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
index 889bc9a47c..09e4f63ee3 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
+++ b/superset-frontend/packages/superset-ui-chart-controls/src/types.ts
@@ -73,7 +73,7 @@ export interface Dataset {
   main_dttm_col: string;
   // eg. ['["ds", true]', 'ds [asc]']
   order_by_choices?: [string, string][] | null;
-  time_grain_sqla?: string;
+  time_grain_sqla?: [string, string][];
   granularity_sqla?: string;
   datasource_name: string | null;
   name?: string;
diff --git a/superset-frontend/packages/superset-ui-chart-controls/test/utils/columnChoices.test.tsx b/superset-frontend/packages/superset-ui-chart-controls/test/utils/columnChoices.test.tsx
index aaaccda95d..70018ddc67 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/test/utils/columnChoices.test.tsx
+++ b/superset-frontend/packages/superset-ui-chart-controls/test/utils/columnChoices.test.tsx
@@ -27,7 +27,7 @@ describe('columnChoices()', () => {
         metrics: [],
         type: DatasourceType.Table,
         main_dttm_col: 'test',
-        time_grain_sqla: 'P1D',
+        time_grain_sqla: [],
         columns: [
           {
             column_name: 'fiz',
diff --git a/superset-frontend/packages/superset-ui-chart-controls/test/utils/defineSavedMetrics.test.tsx b/superset-frontend/packages/superset-ui-chart-controls/test/utils/defineSavedMetrics.test.tsx
index f7ae98520c..218b2e580f 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/test/utils/defineSavedMetrics.test.tsx
+++ b/superset-frontend/packages/superset-ui-chart-controls/test/utils/defineSavedMetrics.test.tsx
@@ -36,7 +36,7 @@ describe('defineSavedMetrics', () => {
       ],
       type: DatasourceType.Table,
       main_dttm_col: 'test',
-      time_grain_sqla: 'P1D',
+      time_grain_sqla: [],
       columns: [],
       verbose_map: {},
       column_formats: {},
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/package.json b/superset-frontend/plugins/legacy-preset-chart-deckgl/package.json
index ed437ec23a..15d2e4ba3f 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/package.json
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/package.json
@@ -31,8 +31,7 @@
     "d3-array": "^1.2.4",
     "d3-color": "^1.4.1",
     "d3-scale": "^3.0.0",
-    "deck.gl": "8.5.2",
-    "jquery": "^3.4.1",
+    "deck.gl": "8.8.27",
     "lodash": "^4.17.15",
     "moment": "^2.20.1",
     "mousetrap": "^1.6.1",
@@ -42,6 +41,11 @@
     "urijs": "^1.19.8",
     "xss": "^1.0.10"
   },
+  "devDependencies": {
+    "@types/mapbox__geojson-extent": "^1.0.0",
+    "@types/underscore": "^1.11.6",
+    "@types/urijs": "^1.19.19"
+  },
   "peerDependencies": {
     "@superset-ui/chart-controls": "*",
     "@superset-ui/core": "*",
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/AnimatableDeckGLContainer.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/AnimatableDeckGLContainer.jsx
deleted file mode 100644
index fc56fc6a3d..0000000000
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/AnimatableDeckGLContainer.jsx
+++ /dev/null
@@ -1,117 +0,0 @@
-/* eslint-disable react/jsx-sort-default-props */
-/* eslint-disable react/sort-prop-types */
-/* eslint-disable react/forbid-prop-types */
-/* eslint-disable react/require-default-props */
-/**
- * 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 React from 'react';
-import PropTypes from 'prop-types';
-
-import { DeckGLContainerStyledWrapper } from './DeckGLContainer';
-import PlaySlider from './components/PlaySlider';
-
-const PLAYSLIDER_HEIGHT = 20; // px
-
-const propTypes = {
-  getLayers: PropTypes.func.isRequired,
-  start: PropTypes.number.isRequired,
-  end: PropTypes.number.isRequired,
-  getStep: PropTypes.func,
-  values: PropTypes.array.isRequired,
-  aggregation: PropTypes.bool,
-  disabled: PropTypes.bool,
-  viewport: PropTypes.object.isRequired,
-  children: PropTypes.node,
-  mapStyle: PropTypes.string,
-  mapboxApiAccessToken: PropTypes.string.isRequired,
-  setControlValue: PropTypes.func,
-  onValuesChange: PropTypes.func,
-  width: PropTypes.number.isRequired,
-  height: PropTypes.number.isRequired,
-};
-
-const defaultProps = {
-  aggregation: false,
-  disabled: false,
-  mapStyle: 'light',
-  setControlValue: () => {},
-  onValuesChange: () => {},
-};
-
-export default class AnimatableDeckGLContainer extends React.PureComponent {
-  containerRef = React.createRef();
-
-  setTooltip = tooltip => {
-    const { current } = this.containerRef;
-    if (current) {
-      current.setTooltip(tooltip);
-    }
-  };
-
-  render() {
-    const {
-      start,
-      end,
-      getStep,
-      disabled,
-      aggregation,
-      children,
-      getLayers,
-      values,
-      onValuesChange,
-      viewport,
-      setControlValue,
-      mapStyle,
-      mapboxApiAccessToken,
-      height,
-      width,
-    } = this.props;
-    const layers = getLayers(values);
-
-    return (
-      <div>
-        <DeckGLContainerStyledWrapper
-          ref={this.containerRef}
-          viewport={viewport}
-          layers={layers}
-          setControlValue={setControlValue}
-          mapStyle={mapStyle}
-          mapboxApiAccessToken={mapboxApiAccessToken}
-          bottomMargin={disabled ? 0 : PLAYSLIDER_HEIGHT}
-          width={width}
-          height={height}
-        />
-        {!disabled && (
-          <PlaySlider
-            start={start}
-            end={end}
-            step={getStep(start)}
-            values={values}
-            range={!aggregation}
-            onChange={onValuesChange}
-          />
-        )}
-        {children}
-      </div>
-    );
-  }
-}
-
-AnimatableDeckGLContainer.propTypes = propTypes;
-AnimatableDeckGLContainer.defaultProps = defaultProps;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/CategoricalDeckGLContainer.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/CategoricalDeckGLContainer.tsx
similarity index 67%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/CategoricalDeckGLContainer.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/CategoricalDeckGLContainer.tsx
index 64bfc0244a..4348bf1561 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/CategoricalDeckGLContainer.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/CategoricalDeckGLContainer.tsx
@@ -25,19 +25,31 @@
 /* eslint no-underscore-dangle: ["error", { "allow": ["", "__timestamp"] }] */
 
 import React from 'react';
-import PropTypes from 'prop-types';
-import { CategoricalColorNamespace } from '@superset-ui/core';
-import AnimatableDeckGLContainer from './AnimatableDeckGLContainer';
+import {
+  CategoricalColorNamespace,
+  Datasource,
+  HandlerFunction,
+  JsonObject,
+  JsonValue,
+  QueryFormData,
+} from '@superset-ui/core';
+import { Layer } from 'deck.gl/typed';
 import Legend from './components/Legend';
 import { hexToRGB } from './utils/colors';
-import { getPlaySliderParams } from './utils/time';
 import sandboxedEval from './utils/sandbox';
 // eslint-disable-next-line import/extensions
-import fitViewport from './utils/fitViewport';
+import fitViewport, { Viewport } from './utils/fitViewport';
+import {
+  DeckGLContainer,
+  DeckGLContainerStyledWrapper,
+} from './DeckGLContainer';
+import { Point } from './types';
+import { getLayerType } from './factory';
+import { TooltipProps } from './components/Tooltip';
 
 const { getScale } = CategoricalColorNamespace;
 
-function getCategories(fd, data) {
+function getCategories(fd: QueryFormData, data: JsonObject[]) {
   const c = fd.color_picker || { r: 0, g: 0, b: 0, a: 1 };
   const fixedColor = [c.r, c.g, c.b, 255 * c.a];
   const colorFn = getScale(fd.color_scheme);
@@ -57,22 +69,31 @@ function getCategories(fd, data) {
   return categories;
 }
 
-const propTypes = {
-  datasource: PropTypes.object.isRequired,
-  formData: PropTypes.object.isRequired,
-  getLayer: PropTypes.func.isRequired,
-  getPoints: PropTypes.func.isRequired,
-  height: PropTypes.number.isRequired,
-  mapboxApiKey: PropTypes.string.isRequired,
-  onAddFilter: PropTypes.func,
-  payload: PropTypes.object.isRequired,
-  setControlValue: PropTypes.func.isRequired,
-  viewport: PropTypes.object.isRequired,
-  width: PropTypes.number.isRequired,
+export type CategoricalDeckGLContainerProps = {
+  datasource: Datasource;
+  formData: QueryFormData;
+  mapboxApiKey: string;
+  getPoints: (data: JsonObject[]) => Point[];
+  height: number;
+  width: number;
+  viewport: Viewport;
+  getLayer: getLayerType<unknown>;
+  payload: JsonObject;
+  onAddFilter?: HandlerFunction;
+  setControlValue: (control: string, value: JsonValue) => void;
 };
 
-export default class CategoricalDeckGLContainer extends React.PureComponent {
-  containerRef = React.createRef();
+export type CategoricalDeckGLContainerState = {
+  formData?: QueryFormData;
+  viewport: Viewport;
+  categories: JsonObject;
+};
+
+export default class CategoricalDeckGLContainer extends React.PureComponent<
+  CategoricalDeckGLContainerProps,
+  CategoricalDeckGLContainerState
+> {
+  containerRef = React.createRef<DeckGLContainer>();
 
   /*
    * A Deck.gl container that handles categories.
@@ -80,34 +101,27 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
    * The container will have an interactive legend, populated from the
    * categories present in the data.
    */
-  constructor(props) {
+  constructor(props: CategoricalDeckGLContainerProps) {
     super(props);
     this.state = this.getStateFromProps(props);
 
     this.getLayers = this.getLayers.bind(this);
-    this.onValuesChange = this.onValuesChange.bind(this);
     this.toggleCategory = this.toggleCategory.bind(this);
     this.showSingleCategory = this.showSingleCategory.bind(this);
   }
 
-  UNSAFE_componentWillReceiveProps(nextProps) {
+  UNSAFE_componentWillReceiveProps(nextProps: CategoricalDeckGLContainerProps) {
     if (nextProps.payload.form_data !== this.state.formData) {
       this.setState({ ...this.getStateFromProps(nextProps) });
     }
   }
 
-  onValuesChange(values) {
-    this.setState({
-      values: Array.isArray(values)
-        ? values
-        : [values, values + this.state.getStep(values)],
-    });
-  }
-
   // eslint-disable-next-line class-methods-use-this
-  getStateFromProps(props, state) {
+  getStateFromProps(
+    props: CategoricalDeckGLContainerProps,
+    state?: CategoricalDeckGLContainerState,
+  ) {
     const features = props.payload.data.features || [];
-    const timestamps = features.map(f => f.__timestamp);
     const categories = getCategories(props.formData, features);
 
     // the state is computed only from the payload; if it hasn't changed, do
@@ -117,18 +131,6 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
       return { ...state, categories };
     }
 
-    // the granularity has to be read from the payload form_data, not the
-    // props formData which comes from the instantaneous controls state
-    const granularity =
-      props.payload.form_data.time_grain_sqla ||
-      props.payload.form_data.granularity ||
-      'P1D';
-
-    const { start, end, getStep, values, disabled } = getPlaySliderParams(
-      timestamps,
-      granularity,
-    );
-
     const { width, height, formData } = props;
     let { viewport } = props;
     if (formData.autozoom) {
@@ -143,11 +145,6 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
     }
 
     return {
-      start,
-      end,
-      getStep,
-      values,
-      disabled,
       viewport,
       selected: [],
       lastClick: 0,
@@ -156,7 +153,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
     };
   }
 
-  getLayers(values) {
+  getLayers() {
     const { getLayer, payload, formData: fd, onAddFilter } = this.props;
     let features = payload.data.features ? [...payload.data.features] : [];
 
@@ -169,23 +166,10 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
       features = jsFnMutator(features);
     }
 
-    // Filter by time
-    if (values[0] === values[1] || values[1] === this.end) {
-      features = features.filter(
-        d => d.__timestamp >= values[0] && d.__timestamp <= values[1],
-      );
-    } else {
-      features = features.filter(
-        d => d.__timestamp >= values[0] && d.__timestamp < values[1],
-      );
-    }
-
     // Show only categories selected in the legend
     const cats = this.state.categories;
     if (fd.dimension) {
-      features = features.filter(
-        d => cats[d.cat_color] && cats[d.cat_color].enabled,
-      );
+      features = features.filter(d => cats[d.cat_color]?.enabled);
     }
 
     const filteredPayload = {
@@ -200,12 +184,12 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
         onAddFilter,
         this.setTooltip,
         this.props.datasource,
-      ),
+      ) as Layer,
     ];
   }
 
   // eslint-disable-next-line class-methods-use-this
-  addColor(data, fd) {
+  addColor(data: JsonObject[], fd: QueryFormData) {
     const c = fd.color_picker || { r: 0, g: 0, b: 0, a: 1 };
     const colorFn = getScale(fd.color_scheme);
 
@@ -221,7 +205,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
     });
   }
 
-  toggleCategory(category) {
+  toggleCategory(category: string) {
     const categoryState = this.state.categories[category];
     const categories = {
       ...this.state.categories,
@@ -241,7 +225,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
     this.setState({ categories });
   }
 
-  showSingleCategory(category) {
+  showSingleCategory(category: string) {
     const categories = { ...this.state.categories };
     /* eslint-disable no-param-reassign */
     Object.values(categories).forEach(v => {
@@ -251,7 +235,7 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
     this.setState({ categories });
   }
 
-  setTooltip = tooltip => {
+  setTooltip = (tooltip: TooltipProps['tooltip']) => {
     const { current } = this.containerRef;
     if (current) {
       current.setTooltip(tooltip);
@@ -261,33 +245,25 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
   render() {
     return (
       <div style={{ position: 'relative' }}>
-        <AnimatableDeckGLContainer
+        <DeckGLContainerStyledWrapper
           ref={this.containerRef}
-          getLayers={this.getLayers}
-          start={this.state.start}
-          end={this.state.end}
-          getStep={this.state.getStep}
-          values={this.state.values}
-          disabled={this.state.disabled}
           viewport={this.state.viewport}
-          mapboxApiAccessToken={this.props.mapboxApiKey}
-          mapStyle={this.props.formData.mapbox_style}
+          layers={this.getLayers()}
           setControlValue={this.props.setControlValue}
+          mapStyle={this.props.formData.mapbox_style}
+          mapboxApiAccessToken={this.props.mapboxApiKey}
           width={this.props.width}
           height={this.props.height}
-        >
-          <Legend
-            forceCategorical
-            categories={this.state.categories}
-            format={this.props.formData.legend_format}
-            position={this.props.formData.legend_position}
-            showSingleCategory={this.showSingleCategory}
-            toggleCategory={this.toggleCategory}
-          />
-        </AnimatableDeckGLContainer>
+        />
+        <Legend
+          forceCategorical
+          categories={this.state.categories}
+          format={this.props.formData.legend_format}
+          position={this.props.formData.legend_position}
+          showSingleCategory={this.showSingleCategory}
+          toggleCategory={this.toggleCategory}
+        />
       </div>
     );
   }
 }
-
-CategoricalDeckGLContainer.propTypes = propTypes;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/DeckGLContainer.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/DeckGLContainer.tsx
similarity index 65%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/DeckGLContainer.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/DeckGLContainer.tsx
index 9bc963c9fc..29672febfb 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/DeckGLContainer.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/DeckGLContainer.tsx
@@ -20,38 +20,41 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import React from 'react';
-import PropTypes from 'prop-types';
+import React, { ReactNode } from 'react';
 import { isEqual } from 'lodash';
 import { StaticMap } from 'react-map-gl';
-import DeckGL from 'deck.gl';
-import { styled } from '@superset-ui/core';
-import Tooltip from './components/Tooltip';
+import DeckGL, { Layer } from 'deck.gl/typed';
+import { JsonObject, JsonValue, styled } from '@superset-ui/core';
+import Tooltip, { TooltipProps } from './components/Tooltip';
 import 'mapbox-gl/dist/mapbox-gl.css';
+import { Viewport } from './utils/fitViewport';
 
 const TICK = 250; // milliseconds
 
-const propTypes = {
-  viewport: PropTypes.object.isRequired,
-  layers: PropTypes.array.isRequired,
-  setControlValue: PropTypes.func,
-  mapStyle: PropTypes.string,
-  mapboxApiAccessToken: PropTypes.string.isRequired,
-  children: PropTypes.node,
-  bottomMargin: PropTypes.number,
-  width: PropTypes.number.isRequired,
-  height: PropTypes.number.isRequired,
-  onViewportChange: PropTypes.func,
+export type DeckGLContainerProps = {
+  viewport: Viewport;
+  setControlValue?: (control: string, value: JsonValue) => void;
+  mapStyle?: string;
+  mapboxApiAccessToken: string;
+  children?: ReactNode;
+  width: number;
+  height: number;
+  layers: (Layer | (() => Layer))[];
+  onViewportChange?: (viewport: Viewport) => void;
 };
-const defaultProps = {
-  mapStyle: 'light',
-  setControlValue: () => {},
-  children: null,
-  bottomMargin: 0,
+
+export type DeckGLContainerState = {
+  lastUpdate: number | null;
+  viewState: Viewport;
+  tooltip: TooltipProps['tooltip'];
+  timer: ReturnType<typeof setInterval>;
 };
 
-export class DeckGLContainer extends React.Component {
-  constructor(props) {
+export class DeckGLContainer extends React.Component<
+  DeckGLContainerProps,
+  DeckGLContainerState
+> {
+  constructor(props: DeckGLContainerProps) {
     super(props);
     this.tick = this.tick.bind(this);
     this.onViewStateChange = this.onViewStateChange.bind(this);
@@ -60,10 +63,11 @@ export class DeckGLContainer extends React.Component {
       timer: setInterval(this.tick, TICK),
       tooltip: null,
       viewState: props.viewport,
+      lastUpdate: null,
     };
   }
 
-  UNSAFE_componentWillReceiveProps(nextProps) {
+  UNSAFE_componentWillReceiveProps(nextProps: DeckGLContainerProps) {
     if (!isEqual(nextProps.viewport, this.props.viewport)) {
       this.setState({ viewState: nextProps.viewport });
     }
@@ -73,8 +77,8 @@ export class DeckGLContainer extends React.Component {
     clearInterval(this.state.timer);
   }
 
-  onViewStateChange({ viewState }) {
-    this.setState({ viewState, lastUpdate: Date.now() });
+  onViewStateChange({ viewState }: { viewState: JsonObject }) {
+    this.setState({ viewState: viewState as Viewport, lastUpdate: Date.now() });
   }
 
   tick() {
@@ -92,31 +96,31 @@ export class DeckGLContainer extends React.Component {
   layers() {
     // Support for layer factory
     if (this.props.layers.some(l => typeof l === 'function')) {
-      return this.props.layers.map(l => (typeof l === 'function' ? l() : l));
+      return this.props.layers.map(l =>
+        typeof l === 'function' ? l() : l,
+      ) as Layer[];
     }
 
-    return this.props.layers;
+    return this.props.layers as Layer[];
   }
 
-  setTooltip = tooltip => {
+  setTooltip = (tooltip: TooltipProps['tooltip']) => {
     this.setState({ tooltip });
   };
 
   render() {
-    const { children, bottomMargin, height, width } = this.props;
+    const { children = null, height, width } = this.props;
     const { viewState, tooltip } = this.state;
-    const adjustedHeight = height - bottomMargin;
 
     const layers = this.layers();
 
     return (
       <>
-        <div style={{ position: 'relative', width, height: adjustedHeight }}>
+        <div style={{ position: 'relative', width, height }}>
           <DeckGL
-            initWebGLParameters
             controller
             width={width}
-            height={adjustedHeight}
+            height={height}
             layers={layers}
             viewState={viewState}
             glOptions={{ preserveDrawingBuffer: true }}
@@ -124,7 +128,7 @@ export class DeckGLContainer extends React.Component {
           >
             <StaticMap
               preserveDrawingBuffer
-              mapStyle={this.props.mapStyle}
+              mapStyle={this.props.mapStyle || 'light'}
               mapboxApiAccessToken={this.props.mapboxApiAccessToken}
             />
           </DeckGL>
@@ -136,9 +140,6 @@ export class DeckGLContainer extends React.Component {
   }
 }
 
-DeckGLContainer.propTypes = propTypes;
-DeckGLContainer.defaultProps = defaultProps;
-
 export const DeckGLContainerStyledWrapper = styled(DeckGLContainer)`
   .deckgl-tooltip > div {
     overflow: hidden;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/Multi.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/Multi.jsx
deleted file mode 100644
index e9f107ed95..0000000000
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/Multi.jsx
+++ /dev/null
@@ -1,147 +0,0 @@
-/* eslint-disable react/jsx-handler-names */
-/* eslint-disable react/no-access-state-in-setstate */
-/* eslint-disable camelcase */
-/**
- * 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 React from 'react';
-import _ from 'lodash';
-import PropTypes from 'prop-types';
-import { SupersetClient } from '@superset-ui/core';
-
-import { DeckGLContainerStyledWrapper } from '../DeckGLContainer';
-import { getExploreLongUrl } from '../utils/explore';
-import layerGenerators from '../layers';
-
-const propTypes = {
-  formData: PropTypes.object.isRequired,
-  payload: PropTypes.object.isRequired,
-  setControlValue: PropTypes.func.isRequired,
-  viewport: PropTypes.object.isRequired,
-  onAddFilter: PropTypes.func,
-  onSelect: PropTypes.func,
-};
-const defaultProps = {
-  onAddFilter() {},
-  onSelect() {},
-};
-
-class DeckMulti extends React.PureComponent {
-  containerRef = React.createRef();
-
-  constructor(props) {
-    super(props);
-    this.state = { subSlicesLayers: {} };
-    this.onViewportChange = this.onViewportChange.bind(this);
-  }
-
-  componentDidMount() {
-    const { formData, payload } = this.props;
-    this.loadLayers(formData, payload);
-  }
-
-  UNSAFE_componentWillReceiveProps(nextProps) {
-    const { formData, payload } = nextProps;
-    const hasChanges = !_.isEqual(
-      this.props.formData.deck_slices,
-      nextProps.formData.deck_slices,
-    );
-    if (hasChanges) {
-      this.loadLayers(formData, payload);
-    }
-  }
-
-  onViewportChange(viewport) {
-    this.setState({ viewport });
-  }
-
-  loadLayers(formData, payload, viewport) {
-    this.setState({ subSlicesLayers: {}, viewport });
-    payload.data.slices.forEach(subslice => {
-      // Filters applied to multi_deck are passed down to underlying charts
-      // note that dashboard contextual information (filter_immune_slices and such) aren't
-      // taken into consideration here
-      const filters = [
-        ...(subslice.form_data.filters || []),
-        ...(formData.filters || []),
-        ...(formData.extra_filters || []),
-      ];
-      const subsliceCopy = {
-        ...subslice,
-        form_data: {
-          ...subslice.form_data,
-          filters,
-        },
-      };
-
-      SupersetClient.get({
-        endpoint: getExploreLongUrl(subsliceCopy.form_data, 'json'),
-      })
-        .then(({ json }) => {
-          const layer = layerGenerators[subsliceCopy.form_data.viz_type](
-            subsliceCopy.form_data,
-            json,
-            this.props.onAddFilter,
-            this.setTooltip,
-            [],
-            this.props.onSelect,
-          );
-          this.setState({
-            subSlicesLayers: {
-              ...this.state.subSlicesLayers,
-              [subsliceCopy.slice_id]: layer,
-            },
-          });
-        })
-        .catch(() => {});
-    });
-  }
-
-  setTooltip = tooltip => {
-    const { current } = this.containerRef;
-    if (current) {
-      current.setTooltip(tooltip);
-    }
-  };
-
-  render() {
-    const { payload, formData, setControlValue, height, width } = this.props;
-    const { subSlicesLayers } = this.state;
-
-    const layers = Object.values(subSlicesLayers);
-
-    return (
-      <DeckGLContainerStyledWrapper
-        ref={this.containerRef}
-        mapboxApiAccessToken={payload.data.mapboxApiKey}
-        viewport={this.state.viewport || this.props.viewport}
-        layers={layers}
-        mapStyle={formData.mapbox_style}
-        setControlValue={setControlValue}
-        onViewportChange={this.onViewportChange}
-        height={height}
-        width={width}
-      />
-    );
-  }
-}
-
-DeckMulti.propTypes = propTypes;
-DeckMulti.defaultProps = defaultProps;
-
-export default DeckMulti;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/Multi.tsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/Multi.tsx
new file mode 100644
index 0000000000..5cfa02f704
--- /dev/null
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/Multi.tsx
@@ -0,0 +1,171 @@
+/* eslint-disable react/jsx-handler-names */
+/* eslint-disable react/no-access-state-in-setstate */
+/* eslint-disable camelcase */
+/**
+ * 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 React from 'react';
+import { isEqual } from 'lodash';
+import {
+  Datasource,
+  HandlerFunction,
+  JsonObject,
+  JsonValue,
+  QueryFormData,
+  SupersetClient,
+} from '@superset-ui/core';
+import { Layer } from 'deck.gl/typed';
+
+import {
+  DeckGLContainer,
+  DeckGLContainerStyledWrapper,
+} from '../DeckGLContainer';
+import { getExploreLongUrl } from '../utils/explore';
+import layerGenerators from '../layers';
+import { Viewport } from '../utils/fitViewport';
+import { TooltipProps } from '../components/Tooltip';
+
+export type DeckMultiProps = {
+  formData: QueryFormData;
+  payload: JsonObject;
+  setControlValue: (control: string, value: JsonValue) => void;
+  viewport: Viewport;
+  onAddFilter: HandlerFunction;
+  height: number;
+  width: number;
+  datasource: Datasource;
+  onSelect: () => void;
+};
+
+export type DeckMultiState = {
+  subSlicesLayers: Record<number, Layer>;
+  viewport?: Viewport;
+};
+
+class DeckMulti extends React.PureComponent<DeckMultiProps, DeckMultiState> {
+  containerRef = React.createRef<DeckGLContainer>();
+
+  constructor(props: DeckMultiProps) {
+    super(props);
+    this.state = { subSlicesLayers: {} };
+    this.onViewportChange = this.onViewportChange.bind(this);
+  }
+
+  componentDidMount() {
+    const { formData, payload } = this.props;
+    this.loadLayers(formData, payload);
+  }
+
+  UNSAFE_componentWillReceiveProps(nextProps: DeckMultiProps) {
+    const { formData, payload } = nextProps;
+    const hasChanges = !isEqual(
+      this.props.formData.deck_slices,
+      nextProps.formData.deck_slices,
+    );
+    if (hasChanges) {
+      this.loadLayers(formData, payload);
+    }
+  }
+
+  onViewportChange(viewport: Viewport) {
+    this.setState({ viewport });
+  }
+
+  loadLayers(
+    formData: QueryFormData,
+    payload: JsonObject,
+    viewport?: Viewport,
+  ) {
+    this.setState({ subSlicesLayers: {}, viewport });
+    payload.data.slices.forEach(
+      (subslice: { slice_id: number } & JsonObject) => {
+        // Filters applied to multi_deck are passed down to underlying charts
+        // note that dashboard contextual information (filter_immune_slices and such) aren't
+        // taken into consideration here
+        const filters = [
+          ...(subslice.form_data.filters || []),
+          ...(formData.filters || []),
+          ...(formData.extra_filters || []),
+        ];
+        const subsliceCopy = {
+          ...subslice,
+          form_data: {
+            ...subslice.form_data,
+            filters,
+          },
+        };
+
+        const url = getExploreLongUrl(subsliceCopy.form_data, 'json');
+
+        if (url) {
+          SupersetClient.get({
+            endpoint: url,
+          })
+            .then(({ json }) => {
+              const layer = layerGenerators[subsliceCopy.form_data.viz_type](
+                subsliceCopy.form_data,
+                json,
+                this.props.onAddFilter,
+                this.setTooltip,
+                this.props.datasource,
+                [],
+                this.props.onSelect,
+              );
+              this.setState({
+                subSlicesLayers: {
+                  ...this.state.subSlicesLayers,
+                  [subsliceCopy.slice_id]: layer,
+                },
+              });
+            })
+            .catch(() => {});
+        }
+      },
+    );
+  }
+
+  setTooltip = (tooltip: TooltipProps['tooltip']) => {
+    const { current } = this.containerRef;
+    if (current) {
+      current.setTooltip(tooltip);
+    }
+  };
+
+  render() {
+    const { payload, formData, setControlValue, height, width } = this.props;
+    const { subSlicesLayers } = this.state;
+
+    const layers = Object.values(subSlicesLayers);
+
+    return (
+      <DeckGLContainerStyledWrapper
+        ref={this.containerRef}
+        mapboxApiAccessToken={payload.data.mapboxApiKey}
+        viewport={this.state.viewport || this.props.viewport}
+        layers={layers}
+        mapStyle={formData.mapbox_style}
+        setControlValue={setControlValue}
+        onViewportChange={this.onViewportChange}
+        height={height}
+        width={width}
+      />
+    );
+  }
+}
+
+export default DeckMulti;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts
similarity index 93%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts
index f4b13521b2..8571fe23d0 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/controlPanel.ts
@@ -44,8 +44,10 @@ export default {
                 '/sliceasync/api/read?_flt_0_viz_type=deck_&_flt_7_viz_type=deck_multi',
               placeholder: t('Select charts'),
               onAsyncErrorMessage: t('Error while fetching charts'),
-              mutator: data => {
-                if (!data || !data.result) {
+              mutator: (data: {
+                result?: { id: number; slice_name: string }[];
+              }) => {
+                if (!data?.result) {
                   return [];
                 }
                 return data.result.map(o => ({
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/Multi/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/TooltipRow.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/TooltipRow.tsx
similarity index 81%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/TooltipRow.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/TooltipRow.tsx
index 0e1138d280..9d72f719fe 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/TooltipRow.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/TooltipRow.tsx
@@ -17,14 +17,13 @@
  * under the License.
  */
 import React from 'react';
-import PropTypes from 'prop-types';
 
-const propTypes = {
-  label: PropTypes.string.isRequired,
-  value: PropTypes.string.isRequired,
+type TooltipRowProps = {
+  label: string;
+  value: string;
 };
 
-export default class TooltipRow extends React.PureComponent {
+export default class TooltipRow extends React.PureComponent<TooltipRowProps> {
   render() {
     const { label, value } = this.props;
 
@@ -36,5 +35,3 @@ export default class TooltipRow extends React.PureComponent {
     );
   }
 }
-
-TooltipRow.propTypes = propTypes;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/BootstrapSliderWrapper.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/BootstrapSliderWrapper.jsx
deleted file mode 100644
index 0ff45f5ea2..0000000000
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/BootstrapSliderWrapper.jsx
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * 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 React from 'react';
-import ReactBootstrapSlider from 'react-bootstrap-slider';
-import 'bootstrap-slider/dist/css/bootstrap-slider.min.css';
-import { styled } from '@superset-ui/core';
-
-const StyledSlider = styled.div`
-  ${({ theme }) => `
-    .slider-selection {
-      background: ${theme.colors.grayscale.light2};
-    }
-    .slider-handle {
-      background: ${theme.colors.grayscale.light1};
-    }
-  `}
-`;
-
-export default function BootstrapSliderWrapper(props) {
-  return (
-    <StyledSlider>
-      <ReactBootstrapSlider {...props} />
-    </StyledSlider>
-  );
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Legend.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Legend.tsx
similarity index 50%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Legend.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Legend.tsx
index 40f13bb514..3b204f2289 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Legend.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Legend.tsx
@@ -19,8 +19,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import React from 'react';
-import PropTypes from 'prop-types';
+import React, { memo } from 'react';
 import { formatNumber, styled } from '@superset-ui/core';
 
 const StyledLegend = styled.div`
@@ -54,91 +53,81 @@ const StyledLegend = styled.div`
 
 const categoryDelimiter = ' - ';
 
-const propTypes = {
-  categories: PropTypes.object,
-  forceCategorical: PropTypes.bool,
-  format: PropTypes.string,
-  position: PropTypes.oneOf([null, 'tl', 'tr', 'bl', 'br']),
-  showSingleCategory: PropTypes.func,
-  toggleCategory: PropTypes.func,
+export type LegendProps = {
+  format: string | null;
+  forceCategorical?: boolean;
+  position?: null | 'tl' | 'tr' | 'bl' | 'br';
+  categories: Record<string, { enabled: boolean; color: number[] }>;
+  toggleCategory?: (key: string) => void;
+  showSingleCategory?: (key: string) => void;
 };
 
-const defaultProps = {
-  categories: {},
-  forceCategorical: false,
-  format: null,
-  position: 'tr',
-  showSingleCategory: () => {},
-  toggleCategory: () => {},
-};
-
-export default class Legend extends React.PureComponent {
-  format(value) {
-    if (!this.props.format || this.props.forceCategorical) {
+const Legend = ({
+  format: d3Format = null,
+  forceCategorical = false,
+  position = 'tr',
+  categories: categoriesObject = {},
+  toggleCategory = () => {},
+  showSingleCategory = () => {},
+}: LegendProps) => {
+  const format = (value: string) => {
+    if (!d3Format || forceCategorical) {
       return value;
     }
 
     const numValue = parseFloat(value);
 
-    return formatNumber(this.props.format, numValue);
-  }
+    return formatNumber(d3Format, numValue);
+  };
 
-  formatCategoryLabel(k) {
-    if (!this.props.format) {
+  const formatCategoryLabel = (k: string) => {
+    if (!d3Format) {
       return k;
     }
 
     if (k.includes(categoryDelimiter)) {
       const values = k.split(categoryDelimiter);
 
-      return (
-        this.format(values[0]) + categoryDelimiter + this.format(values[1])
-      );
+      return format(values[0]) + categoryDelimiter + format(values[1]);
     }
 
-    return this.format(k);
-  }
+    return format(k);
+  };
 
-  render() {
-    if (
-      Object.keys(this.props.categories).length === 0 ||
-      this.props.position === null
-    ) {
-      return null;
-    }
+  if (Object.keys(categoriesObject).length === 0 || position === null) {
+    return null;
+  }
 
-    const categories = Object.entries(this.props.categories).map(([k, v]) => {
-      const style = { color: `rgba(${v.color.join(', ')})` };
-      const icon = v.enabled ? '\u25FC' : '\u25FB';
-
-      return (
-        <li key={k}>
-          <a
-            href="#"
-            onClick={() => this.props.toggleCategory(k)}
-            onDoubleClick={() => this.props.showSingleCategory(k)}
-          >
-            <span style={style}>{icon}</span> {this.formatCategoryLabel(k)}
-          </a>
-        </li>
-      );
-    });
-
-    const vertical = this.props.position.charAt(0) === 't' ? 'top' : 'bottom';
-    const horizontal = this.props.position.charAt(1) === 'r' ? 'right' : 'left';
-    const style = {
-      position: 'absolute',
-      [vertical]: '0px',
-      [horizontal]: '10px',
-    };
+  const categories = Object.entries(categoriesObject).map(([k, v]) => {
+    const style = { color: `rgba(${v.color.join(', ')})` };
+    const icon = v.enabled ? '\u25FC' : '\u25FB';
 
     return (
-      <StyledLegend style={style}>
-        <ul>{categories}</ul>
-      </StyledLegend>
+      <li key={k}>
+        <a
+          href="#"
+          onClick={() => toggleCategory(k)}
+          onDoubleClick={() => showSingleCategory(k)}
+        >
+          <span style={style}>{icon}</span> {formatCategoryLabel(k)}
+        </a>
+      </li>
     );
-  }
-}
+  });
+
+  const vertical = position?.charAt(0) === 't' ? 'top' : 'bottom';
+  const horizontal = position?.charAt(1) === 'r' ? 'right' : 'left';
+  const style = {
+    position: 'absolute' as const,
+    [vertical]: '0px',
+    [horizontal]: '10px',
+  };
+
+  return (
+    <StyledLegend className="dupa" style={style}>
+      <ul>{categories}</ul>
+    </StyledLegend>
+  );
+};
 
-Legend.propTypes = propTypes;
-Legend.defaultProps = defaultProps;
+export default memo(Legend);
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/PlaySlider.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/PlaySlider.jsx
deleted file mode 100644
index 1705b8f533..0000000000
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/PlaySlider.jsx
+++ /dev/null
@@ -1,232 +0,0 @@
-/* eslint-disable react/jsx-sort-default-props */
-/* eslint-disable react/sort-prop-types */
-/* eslint-disable react/jsx-handler-names */
-/* eslint-disable jsx-a11y/click-events-have-key-events */
-/* eslint-disable jsx-a11y/no-static-element-interactions */
-/* eslint-disable no-negated-condition */
-/* eslint-disable react/forbid-prop-types */
-/**
- * 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 React from 'react';
-import PropTypes from 'prop-types';
-import Mousetrap from 'mousetrap';
-import { t, styled } from '@superset-ui/core';
-import BootstrapSliderWrapper from './BootstrapSliderWrapper';
-
-const StyledSlider = styled.div`
-  ${({ theme }) => `
-    display: flex;
-    height: 40px;
-    width: 100%;
-    margin: 0;
-
-    .play-slider-controls {
-      flex: 0 0 80px;
-      text-align: middle;
-    }
-
-    .play-slider-scrobbler {
-      flex: 1;
-    }
-
-    .slider.slider-horizontal {
-      width: 100% !important;
-    }
-
-    .slider-button {
-      color: ${theme.colors.grayscale.light1};
-      margin-right: ${theme.gridUnit}px;
-    }
-
-    div.slider > div.tooltip.tooltip-main.top.in {
-      margin-left: 0 !important;
-    }
-  `}
-`;
-
-const propTypes = {
-  start: PropTypes.number.isRequired,
-  step: PropTypes.number.isRequired,
-  end: PropTypes.number.isRequired,
-  values: PropTypes.array.isRequired,
-  onChange: PropTypes.func,
-  loopDuration: PropTypes.number,
-  maxFrames: PropTypes.number,
-  orientation: PropTypes.oneOf(['horizontal', 'vertical']),
-  reversed: PropTypes.bool,
-  disabled: PropTypes.bool,
-  range: PropTypes.bool,
-};
-
-const defaultProps = {
-  onChange: () => {},
-  loopDuration: 15000,
-  maxFrames: 100,
-  orientation: 'horizontal',
-  reversed: false,
-  disabled: false,
-  range: true,
-};
-
-export default class PlaySlider extends React.PureComponent {
-  constructor(props) {
-    super(props);
-    this.state = { intervalId: null };
-
-    const range = props.end - props.start;
-    const frames = Math.min(props.maxFrames, range / props.step);
-    const width = range / frames;
-    this.intervalMilliseconds = props.loopDuration / frames;
-    this.increment =
-      width < props.step ? props.step : width - (width % props.step);
-
-    this.onChange = this.onChange.bind(this);
-    this.play = this.play.bind(this);
-    this.pause = this.pause.bind(this);
-    this.stepBackward = this.stepBackward.bind(this);
-    this.stepForward = this.stepForward.bind(this);
-    this.getPlayClass = this.getPlayClass.bind(this);
-    this.formatter = this.formatter.bind(this);
-  }
-
-  componentDidMount() {
-    Mousetrap.bind(['space'], this.play);
-  }
-
-  componentWillUnmount() {
-    Mousetrap.unbind(['space']);
-  }
-
-  onChange(event) {
-    this.props.onChange(event.target.value);
-    if (this.state.intervalId != null) {
-      this.pause();
-    }
-  }
-
-  getPlayClass() {
-    if (this.state.intervalId == null) {
-      return 'fa fa-play fa-lg slider-button';
-    }
-
-    return 'fa fa-pause fa-lg slider-button';
-  }
-
-  play() {
-    if (this.props.disabled) {
-      return;
-    }
-    if (this.state.intervalId != null) {
-      this.pause();
-    } else {
-      const id = setInterval(this.stepForward, this.intervalMilliseconds);
-      this.setState({ intervalId: id });
-    }
-  }
-
-  pause() {
-    clearInterval(this.state.intervalId);
-    this.setState({ intervalId: null });
-  }
-
-  stepForward() {
-    const { start, end, step, values, disabled } = this.props;
-
-    if (disabled) {
-      return;
-    }
-
-    const currentValues = Array.isArray(values)
-      ? values
-      : [values, values + step];
-    const nextValues = currentValues.map(value => value + this.increment);
-    const carriageReturn = nextValues[1] > end ? nextValues[0] - start : 0;
-
-    this.props.onChange(nextValues.map(value => value - carriageReturn));
-  }
-
-  stepBackward() {
-    const { start, end, step, values, disabled } = this.props;
-
-    if (disabled) {
-      return;
-    }
-
-    const currentValues = Array.isArray(values)
-      ? values
-      : [values, values + step];
-    const nextValues = currentValues.map(value => value - this.increment);
-    const carriageReturn = nextValues[0] < start ? end - nextValues[1] : 0;
-
-    this.props.onChange(nextValues.map(value => value + carriageReturn));
-  }
-
-  formatter(values) {
-    if (this.props.disabled) {
-      return t('Data has no time steps');
-    }
-
-    let parts = values;
-    if (!Array.isArray(values)) {
-      parts = [values];
-    } else if (values[0] === values[1]) {
-      parts = [values[0]];
-    }
-
-    return parts.map(value => new Date(value).toUTCString()).join(' : ');
-  }
-
-  render() {
-    const { start, end, step, orientation, reversed, disabled, range, values } =
-      this.props;
-
-    return (
-      <StyledSlider>
-        <div className="play-slider-controls padded">
-          <i
-            className="fa fa-step-backward fa-lg slider-button "
-            onClick={this.stepBackward}
-          />
-          <i className={this.getPlayClass()} onClick={this.play} />
-          <i
-            className="fa fa-step-forward fa-lg slider-button "
-            onClick={this.stepForward}
-          />
-        </div>
-        <div className="play-slider-scrobbler padded">
-          <BootstrapSliderWrapper
-            value={range ? values : values[0]}
-            range={range}
-            formatter={this.formatter}
-            change={this.onChange}
-            min={start}
-            max={end}
-            step={step}
-            orientation={orientation}
-            reversed={reversed}
-            disabled={disabled ? 'disabled' : 'enabled'}
-          />
-        </div>
-      </StyledSlider>
-    );
-  }
-}
-
-PlaySlider.propTypes = propTypes;
-PlaySlider.defaultProps = defaultProps;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Tooltip.tsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Tooltip.tsx
index d61c4844ac..564e18a8a3 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Tooltip.tsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/components/Tooltip.tsx
@@ -18,14 +18,14 @@
  */
 
 import { styled, safeHtmlSpan } from '@superset-ui/core';
-import React from 'react';
+import React, { ReactNode } from 'react';
 
 export type TooltipProps = {
   tooltip:
     | {
         x: number;
         y: number;
-        content: string;
+        content: ReactNode;
       }
     | null
     | undefined;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/factory.tsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/factory.tsx
index 248c2826ad..4ddde91247 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/factory.tsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/factory.tsx
@@ -18,7 +18,13 @@
  */
 import React from 'react';
 import { isEqual } from 'lodash';
-import { Datasource, QueryFormData, JsonObject } from '@superset-ui/core';
+import { Layer } from 'deck.gl/typed';
+import {
+  Datasource,
+  QueryFormData,
+  JsonObject,
+  HandlerFunction,
+} from '@superset-ui/core';
 
 import {
   DeckGLContainerStyledWrapper,
@@ -27,12 +33,13 @@ import {
 import CategoricalDeckGLContainer from './CategoricalDeckGLContainer';
 import fitViewport, { Viewport } from './utils/fitViewport';
 import { Point } from './types';
+import { TooltipProps } from './components/Tooltip';
 
 type deckGLComponentProps = {
   datasource: Datasource;
   formData: QueryFormData;
   height: number;
-  onAddFilter: () => void;
+  onAddFilter: HandlerFunction;
   payload: JsonObject;
   setControlValue: () => void;
   viewport: Viewport;
@@ -42,21 +49,22 @@ export interface getLayerType<T> {
   (
     formData: QueryFormData,
     payload: JsonObject,
-    onAddFilter: () => void,
-    setTooltip: (tooltip: string) => void,
+    onAddFilter: HandlerFunction | undefined,
+    setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+    datasource?: Datasource,
   ): T;
 }
-interface getPointsType<T> {
-  (point: number[]): T;
+interface getPointsType {
+  (data: JsonObject[]): Point[];
 }
 type deckGLComponentState = {
   viewport: Viewport;
-  layer: unknown;
+  layer: Layer;
 };
 
 export function createDeckGLComponent(
   getLayer: getLayerType<unknown>,
-  getPoints: getPointsType<Point[]>,
+  getPoints: getPointsType,
 ): React.ComponentClass<deckGLComponentProps> {
   // Higher order component
   class Component extends React.PureComponent<
@@ -104,10 +112,10 @@ export function createDeckGLComponent(
     computeLayer(props: deckGLComponentProps) {
       const { formData, payload, onAddFilter } = props;
 
-      return getLayer(formData, payload, onAddFilter, this.setTooltip);
+      return getLayer(formData, payload, onAddFilter, this.setTooltip) as Layer;
     }
 
-    setTooltip = (tooltip: string) => {
+    setTooltip = (tooltip: TooltipProps['tooltip']) => {
       const { current } = this.containerRef;
       if (current) {
         current?.setTooltip(tooltip);
@@ -137,8 +145,8 @@ export function createDeckGLComponent(
 }
 
 export function createCategoricalDeckGLComponent(
-  getLayer: getLayerType<unknown>,
-  getPoints: getPointsType<Point[]>,
+  getLayer: getLayerType<Layer>,
+  getPoints: getPointsType,
 ) {
   return function Component(props: deckGLComponentProps) {
     const {
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/Arc.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/Arc.tsx
similarity index 78%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/Arc.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/Arc.tsx
index 75cf8d09a1..1bc19618b6 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/Arc.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/Arc.tsx
@@ -16,15 +16,22 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { ArcLayer } from 'deck.gl';
+import { ArcLayer } from 'deck.gl/typed';
 import React from 'react';
-import { t } from '@superset-ui/core';
+import {
+  HandlerFunction,
+  JsonObject,
+  QueryFormData,
+  t,
+} from '@superset-ui/core';
 import { commonLayerProps } from '../common';
 import { createCategoricalDeckGLComponent } from '../../factory';
 import TooltipRow from '../../TooltipRow';
+import { TooltipProps } from '../../components/Tooltip';
+import { Point } from '../../types';
 
-function getPoints(data) {
-  const points = [];
+function getPoints(data: JsonObject[]) {
+  const points: Point[] = [];
   data.forEach(d => {
     points.push(d.sourcePosition);
     points.push(d.targetPosition);
@@ -33,8 +40,8 @@ function getPoints(data) {
   return points;
 }
 
-function setTooltipContent(formData) {
-  return o => (
+function setTooltipContent(formData: QueryFormData) {
+  return (o: JsonObject) => (
     <div className="deckgl-tooltip">
       <TooltipRow
         label={t('Start (Longitude, Latitude): ')}
@@ -54,7 +61,12 @@ function setTooltipContent(formData) {
   );
 }
 
-export function getLayer(fd, payload, onAddFilter, setTooltip) {
+export function getLayer(
+  fd: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: HandlerFunction,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+) {
   const data = payload.data.features;
   const sc = fd.color_picker;
   const tc = fd.target_color_picker;
@@ -65,7 +77,7 @@ export function getLayer(fd, payload, onAddFilter, setTooltip) {
       d.sourceColor || d.color || [sc.r, sc.g, sc.b, 255 * sc.a],
     getTargetColor: d =>
       d.targetColor || d.color || [tc.r, tc.g, tc.b, 255 * tc.a],
-    id: `path-layer-${fd.slice_id}`,
+    id: `path-layer-${fd.slice_id}` as const,
     strokeWidth: fd.stroke_width ? fd.stroke_width : 3,
     ...commonLayerProps(fd, setTooltip, setTooltipContent(fd)),
   });
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Arc/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.tsx
similarity index 68%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.tsx
index 263b576ec9..4aa827e45b 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/Geojson.tsx
@@ -17,16 +17,25 @@
  * under the License.
  */
 import React from 'react';
-import PropTypes from 'prop-types';
-import { GeoJsonLayer } from 'deck.gl';
+import { GeoJsonLayer } from 'deck.gl/typed';
 import geojsonExtent from '@mapbox/geojson-extent';
-
-import { DeckGLContainerStyledWrapper } from '../../DeckGLContainer';
+import {
+  HandlerFunction,
+  JsonObject,
+  JsonValue,
+  QueryFormData,
+} from '@superset-ui/core';
+
+import {
+  DeckGLContainer,
+  DeckGLContainerStyledWrapper,
+} from '../../DeckGLContainer';
 import { hexToRGB } from '../../utils/colors';
 import sandboxedEval from '../../utils/sandbox';
 import { commonLayerProps } from '../common';
 import TooltipRow from '../../TooltipRow';
-import fitViewport from '../../utils/fitViewport';
+import fitViewport, { Viewport } from '../../utils/fitViewport';
+import { TooltipProps } from '../../components/Tooltip';
 
 const propertyMap = {
   fillColor: 'fillColor',
@@ -38,8 +47,8 @@ const propertyMap = {
   'stroke-width': 'strokeWidth',
 };
 
-const alterProps = (props, propOverrides) => {
-  const newProps = {};
+const alterProps = (props: JsonObject, propOverrides: JsonObject) => {
+  const newProps: JsonObject = {};
   Object.keys(props).forEach(k => {
     if (k in propertyMap) {
       newProps[propertyMap[k]] = props[k];
@@ -59,18 +68,22 @@ const alterProps = (props, propOverrides) => {
     ...propOverrides,
   };
 };
-let features;
-const recurseGeoJson = (node, propOverrides, extraProps) => {
-  if (node && node.features) {
-    node.features.forEach(obj => {
+let features: JsonObject[];
+const recurseGeoJson = (
+  node: JsonObject,
+  propOverrides: JsonObject,
+  extraProps?: JsonObject,
+) => {
+  if (node?.features) {
+    node.features.forEach((obj: JsonObject) => {
       recurseGeoJson(obj, propOverrides, node.extraProps || extraProps);
     });
   }
-  if (node && node.geometry) {
+  if (node?.geometry) {
     const newNode = {
       ...node,
       properties: alterProps(node.properties, propOverrides),
-    };
+    } as JsonObject;
     if (!newNode.extraProps) {
       newNode.extraProps = extraProps;
     }
@@ -78,7 +91,7 @@ const recurseGeoJson = (node, propOverrides, extraProps) => {
   }
 };
 
-function setTooltipContent(o) {
+function setTooltipContent(o: JsonObject) {
   return (
     o.object.extraProps && (
       <div className="deckgl-tooltip">
@@ -94,16 +107,21 @@ function setTooltipContent(o) {
   );
 }
 
-const getFillColor = feature => feature?.properties?.fillColor;
-const getLineColor = feature => feature?.properties?.strokeColor;
+const getFillColor = (feature: JsonObject) => feature?.properties?.fillColor;
+const getLineColor = (feature: JsonObject) => feature?.properties?.strokeColor;
 
-export function getLayer(formData, payload, onAddFilter, setTooltip) {
+export function getLayer(
+  formData: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: HandlerFunction,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+) {
   const fd = formData;
   const fc = fd.fill_color_picker;
   const sc = fd.stroke_color_picker;
   const fillColor = [fc.r, fc.g, fc.b, 255 * fc.a];
   const strokeColor = [sc.r, sc.g, sc.b, 255 * sc.a];
-  const propOverrides = {};
+  const propOverrides: JsonObject = {};
   if (fillColor[3] > 0) {
     propOverrides.fillColor = fillColor;
   }
@@ -122,7 +140,7 @@ export function getLayer(formData, payload, onAddFilter, setTooltip) {
   }
 
   return new GeoJsonLayer({
-    id: `geojson-layer-${fd.slice_id}`,
+    id: `geojson-layer-${fd.slice_id}` as const,
     data: features,
     extruded: fd.extruded,
     filled: fd.filled,
@@ -136,21 +154,20 @@ export function getLayer(formData, payload, onAddFilter, setTooltip) {
   });
 }
 
-const propTypes = {
-  formData: PropTypes.object.isRequired,
-  payload: PropTypes.object.isRequired,
-  setControlValue: PropTypes.func.isRequired,
-  viewport: PropTypes.object.isRequired,
-  onAddFilter: PropTypes.func,
-};
-const defaultProps = {
-  onAddFilter() {},
+export type DeckGLGeoJsonProps = {
+  formData: QueryFormData;
+  payload: JsonObject;
+  setControlValue: (control: string, value: JsonValue) => void;
+  viewport: Viewport;
+  onAddFilter: HandlerFunction;
+  height: number;
+  width: number;
 };
 
-class DeckGLGeoJson extends React.Component {
-  containerRef = React.createRef();
+class DeckGLGeoJson extends React.Component<DeckGLGeoJsonProps> {
+  containerRef = React.createRef<DeckGLContainer>();
 
-  setTooltip = tooltip => {
+  setTooltip = (tooltip: TooltipProps['tooltip']) => {
     const { current } = this.containerRef;
     if (current) {
       current.setTooltip(tooltip);
@@ -164,14 +181,17 @@ class DeckGLGeoJson extends React.Component {
     let { viewport } = this.props;
     if (formData.autozoom) {
       const points =
-        payload?.data?.features?.reduce?.((acc, feature) => {
-          const bounds = geojsonExtent(feature);
-          if (bounds) {
-            return [...acc, [bounds[0], bounds[1]], [bounds[2], bounds[3]]];
-          }
-
-          return acc;
-        }, []) || [];
+        payload?.data?.features?.reduce?.(
+          (acc: [number, number, number, number][], feature: any) => {
+            const bounds = geojsonExtent(feature);
+            if (bounds) {
+              return [...acc, [bounds[0], bounds[1]], [bounds[2], bounds[3]]];
+            }
+
+            return acc;
+          },
+          [],
+        ) || [];
 
       if (points.length) {
         viewport = fitViewport(viewport, {
@@ -199,7 +219,4 @@ class DeckGLGeoJson extends React.Component {
   }
 }
 
-DeckGLGeoJson.propTypes = propTypes;
-DeckGLGeoJson.defaultProps = defaultProps;
-
 export default DeckGLGeoJson;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Geojson/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/Grid.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/Grid.tsx
similarity index 77%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/Grid.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/Grid.tsx
index d19ef3edb1..887971d556 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/Grid.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/Grid.tsx
@@ -16,17 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { GridLayer } from 'deck.gl';
+import { Color, GridLayer } from 'deck.gl/typed';
 import React from 'react';
-import { t, CategoricalColorNamespace } from '@superset-ui/core';
+import {
+  t,
+  CategoricalColorNamespace,
+  JsonObject,
+  QueryFormData,
+} from '@superset-ui/core';
 
 import { commonLayerProps, getAggFunc } from '../common';
 import sandboxedEval from '../../utils/sandbox';
 import { hexToRGB } from '../../utils/colors';
 import { createDeckGLComponent } from '../../factory';
 import TooltipRow from '../../TooltipRow';
+import { TooltipProps } from '../../components/Tooltip';
 
-function setTooltipContent(o) {
+function setTooltipContent(o: JsonObject) {
   return (
     <div className="deckgl-tooltip">
       <TooltipRow
@@ -43,10 +49,17 @@ function setTooltipContent(o) {
   );
 }
 
-export function getLayer(formData, payload, onAddFilter, setTooltip) {
+export function getLayer(
+  formData: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: () => void,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+) {
   const fd = formData;
   const colorScale = CategoricalColorNamespace.getScale(fd.color_scheme);
-  const colorRange = colorScale.range().map(color => hexToRGB(color));
+  const colorRange = colorScale
+    .range()
+    .map(color => hexToRGB(color)) as Color[];
   let data = payload.data.features;
 
   if (fd.js_data_mutator) {
@@ -58,20 +71,21 @@ export function getLayer(formData, payload, onAddFilter, setTooltip) {
   const aggFunc = getAggFunc(fd.js_agg_function, p => p.weight);
 
   return new GridLayer({
-    id: `grid-layer-${fd.slice_id}`,
+    id: `grid-layer-${fd.slice_id}` as const,
     data,
-    pickable: true,
     cellSize: fd.grid_size,
     extruded: fd.extruded,
     colorRange,
     outline: false,
+    // @ts-ignore
     getElevationValue: aggFunc,
+    // @ts-ignore
     getColorValue: aggFunc,
     ...commonLayerProps(fd, setTooltip, setTooltipContent),
   });
 }
 
-function getPoints(data) {
+function getPoints(data: JsonObject[]) {
   return data.map(d => d.position);
 }
 
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Grid/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/Heatmap.tsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/Heatmap.tsx
index 2bd1f63ce7..b491d6dba1 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/Heatmap.tsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Heatmap/Heatmap.tsx
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { HeatmapLayer } from 'deck.gl';
+import { HeatmapLayer, Position, Color } from 'deck.gl/typed';
 import React from 'react';
-import { t, getSequentialSchemeRegistry } from '@superset-ui/core';
+import { t, getSequentialSchemeRegistry, JsonObject } from '@superset-ui/core';
 import { commonLayerProps } from '../common';
 import sandboxedEval from '../../utils/sandbox';
 import { hexToRGB } from '../../utils/colors';
 import { createDeckGLComponent, getLayerType } from '../../factory';
 import TooltipRow from '../../TooltipRow';
 
-function setTooltipContent(o: any) {
+function setTooltipContent(o: JsonObject) {
   return (
     <div className="deckgl-tooltip">
       <TooltipRow
@@ -63,16 +63,16 @@ export const getLayer: getLayerType<unknown> = (
   const colorRange = colorScale
     ?.range()
     ?.map(color => hexToRGB(color))
-    ?.reverse();
+    ?.reverse() as Color[];
 
   return new HeatmapLayer({
-    id: `heatmp-layer-${fd.slice_id}`,
+    id: `heatmp-layer-${fd.slice_id}` as const,
     data,
     intensity,
     radiusPixels,
     colorRange,
     aggregation: aggregation.toUpperCase(),
-    getPosition: (d: { position: number[]; weight: number }) => d.position,
+    getPosition: (d: { position: Position; weight: number }) => d.position,
     getWeight: (d: { position: number[]; weight: number }) =>
       d.weight ? d.weight : 1,
     ...commonLayerProps(fd, setTooltip, setTooltipContent),
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/Hex.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/Hex.tsx
similarity index 75%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/Hex.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/Hex.tsx
index a3c430acb1..0b8d3fd428 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/Hex.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/Hex.tsx
@@ -16,17 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { HexagonLayer } from 'deck.gl';
+import { HexagonLayer, Color } from 'deck.gl/typed';
 import React from 'react';
-import { t, CategoricalColorNamespace } from '@superset-ui/core';
+import {
+  t,
+  CategoricalColorNamespace,
+  QueryFormData,
+  JsonObject,
+} from '@superset-ui/core';
 
 import { commonLayerProps, getAggFunc } from '../common';
 import sandboxedEval from '../../utils/sandbox';
 import { hexToRGB } from '../../utils/colors';
 import { createDeckGLComponent } from '../../factory';
 import TooltipRow from '../../TooltipRow';
+import { TooltipProps } from '../../components/Tooltip';
 
-function setTooltipContent(o) {
+function setTooltipContent(o: JsonObject) {
   return (
     <div className="deckgl-tooltip">
       <TooltipRow
@@ -42,10 +48,17 @@ function setTooltipContent(o) {
   );
 }
 
-export function getLayer(formData, payload, onAddFilter, setTooltip) {
+export function getLayer(
+  formData: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: () => void,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+) {
   const fd = formData;
   const colorScale = CategoricalColorNamespace.getScale(fd.color_scheme);
-  const colorRange = colorScale.range().map(color => hexToRGB(color));
+  const colorRange = colorScale
+    .range()
+    .map(color => hexToRGB(color)) as Color[];
   let data = payload.data.features;
 
   if (fd.js_data_mutator) {
@@ -53,23 +66,24 @@ export function getLayer(formData, payload, onAddFilter, setTooltip) {
     const jsFnMutator = sandboxedEval(fd.js_data_mutator);
     data = jsFnMutator(data);
   }
-  const aggFunc = getAggFunc(fd.js_agg_function, p => p.weight);
+  const aggFunc = getAggFunc(fd.js_agg_function, p => p?.weight);
 
   return new HexagonLayer({
-    id: `hex-layer-${fd.slice_id}`,
+    id: `hex-layer-${fd.slice_id}` as const,
     data,
-    pickable: true,
     radius: fd.grid_size,
     extruded: fd.extruded,
     colorRange,
     outline: false,
+    // @ts-ignore
     getElevationValue: aggFunc,
+    // @ts-ignore
     getColorValue: aggFunc,
     ...commonLayerProps(fd, setTooltip, setTooltipContent),
   });
 }
 
-function getPoints(data) {
+function getPoints(data: JsonObject[]) {
   return data.map(d => d.position);
 }
 
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Hex/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/Path.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/Path.tsx
similarity index 78%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/Path.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/Path.tsx
index faadf4b3e1..c4f13f0e57 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/Path.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/Path.tsx
@@ -17,14 +17,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { PathLayer } from 'deck.gl';
 import React from 'react';
+import { PathLayer } from 'deck.gl/typed';
+import { JsonObject, QueryFormData } from '@superset-ui/core';
 import { commonLayerProps } from '../common';
 import sandboxedEval from '../../utils/sandbox';
 import { createDeckGLComponent } from '../../factory';
 import TooltipRow from '../../TooltipRow';
+import { TooltipProps } from '../../components/Tooltip';
+import { Point } from '../../types';
 
-function setTooltipContent(o) {
+function setTooltipContent(o: JsonObject) {
   return (
     o.object.extraProps && (
       <div className="deckgl-tooltip">
@@ -40,11 +43,16 @@ function setTooltipContent(o) {
   );
 }
 
-export function getLayer(formData, payload, onAddFilter, setTooltip) {
+export function getLayer(
+  formData: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: () => void,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+) {
   const fd = formData;
   const c = fd.color_picker;
   const fixedColor = [c.r, c.g, c.b, 255 * c.a];
-  let data = payload.data.features.map(feature => ({
+  let data = payload.data.features.map((feature: JsonObject) => ({
     ...feature,
     path: feature.path,
     width: fd.line_width,
@@ -57,7 +65,7 @@ export function getLayer(formData, payload, onAddFilter, setTooltip) {
   }
 
   return new PathLayer({
-    id: `path-layer-${fd.slice_id}`,
+    id: `path-layer-${fd.slice_id}` as const,
     getColor: d => d.color,
     getPath: d => d.path,
     getWidth: d => d.width,
@@ -69,8 +77,8 @@ export function getLayer(formData, payload, onAddFilter, setTooltip) {
   });
 }
 
-function getPoints(data) {
-  let points = [];
+function getPoints(data: JsonObject[]) {
+  let points: Point[] = [];
   data.forEach(d => {
     points = points.concat(d.path);
   });
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Path/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/Polygon.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/Polygon.tsx
similarity index 65%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/Polygon.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/Polygon.tsx
index a881cfd96d..627125c398 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/Polygon.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/Polygon.tsx
@@ -22,27 +22,36 @@
 /* eslint no-underscore-dangle: ["error", { "allow": ["", "__timestamp"] }] */
 
 import React from 'react';
-import { t } from '@superset-ui/core';
-import PropTypes from 'prop-types';
+import {
+  HandlerFunction,
+  JsonObject,
+  JsonValue,
+  QueryFormData,
+  t,
+} from '@superset-ui/core';
 
-import { PolygonLayer } from 'deck.gl';
+import { PolygonLayer } from 'deck.gl/typed';
 
-import AnimatableDeckGLContainer from '../../AnimatableDeckGLContainer';
 import Legend from '../../components/Legend';
 import TooltipRow from '../../TooltipRow';
 import { getBuckets, getBreakPointColorScaler } from '../../utils';
 
 import { commonLayerProps } from '../common';
-import { getPlaySliderParams } from '../../utils/time';
 import sandboxedEval from '../../utils/sandbox';
-// eslint-disable-next-line import/extensions
 import getPointsFromPolygon from '../../utils/getPointsFromPolygon';
-// eslint-disable-next-line import/extensions
-import fitViewport from '../../utils/fitViewport';
+import fitViewport, { Viewport } from '../../utils/fitViewport';
+import {
+  DeckGLContainer,
+  DeckGLContainerStyledWrapper,
+} from '../../DeckGLContainer';
+import { TooltipProps } from '../../components/Tooltip';
 
 const DOUBLE_CLICK_THRESHOLD = 250; // milliseconds
 
-function getElevation(d, colorScaler) {
+function getElevation(
+  d: JsonObject,
+  colorScaler: (d: JsonObject) => [number, number, number, number],
+) {
   /* in deck.gl 5.3.4 (used in Superset as of 2018-10-24), if a polygon has
    * opacity zero it will make everything behind it have opacity zero,
    * effectively showing the map layer no matter what other polygons are
@@ -51,8 +60,8 @@ function getElevation(d, colorScaler) {
   return colorScaler(d)[3] === 0 ? 0 : d.elevation;
 }
 
-function setTooltipContent(formData) {
-  return o => {
+function setTooltipContent(formData: PolygonFormData) {
+  return (o: JsonObject) => {
     const metricLabel = formData.metric.label || formData.metric;
 
     return (
@@ -82,25 +91,18 @@ function setTooltipContent(formData) {
 }
 
 export function getLayer(
-  formData,
-  payload,
-  onAddFilter,
-  setTooltip,
-  selected,
-  onSelect,
-  filters,
+  formData: PolygonFormData,
+  payload: JsonObject,
+  onAddFilter: HandlerFunction,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+  selected: JsonObject[],
+  onSelect: (value: JsonValue) => void,
 ) {
   const fd = formData;
   const fc = fd.fill_color_picker;
   const sc = fd.stroke_color_picker;
   let data = [...payload.data.features];
 
-  if (filters != null) {
-    filters.forEach(f => {
-      data = data.filter(x => f(x));
-    });
-  }
-
   if (fd.js_data_mutator) {
     // Applying user defined data mutator if defined
     const jsFnMutator = sandboxedEval(fd.js_data_mutator);
@@ -108,7 +110,7 @@ export function getLayer(
   }
 
   const metricLabel = fd.metric ? fd.metric.label || fd.metric : null;
-  const accessor = d => d[metricLabel];
+  const accessor = (d: JsonObject) => d[metricLabel];
   // base color for the polygons
   const baseColorScaler =
     fd.metric === null
@@ -116,8 +118,13 @@ export function getLayer(
       : getBreakPointColorScaler(fd, data, accessor);
 
   // when polygons are selected, reduce the opacity of non-selected polygons
-  const colorScaler = d => {
-    const baseColor = baseColorScaler(d);
+  const colorScaler = (d: JsonObject): [number, number, number, number] => {
+    const baseColor = (baseColorScaler?.(d) as [
+      number,
+      number,
+      number,
+      number,
+    ]) || [0, 0, 0, 0];
     if (selected.length > 0 && !selected.includes(d[fd.line_column])) {
       baseColor[3] /= 2;
     }
@@ -130,12 +137,11 @@ export function getLayer(
     fd.metric &&
     ['json', 'geohash', 'zipcode'].includes(fd.line_type)
       ? setTooltipContent(fd)
-      : undefined;
+      : () => null;
 
   return new PolygonLayer({
-    id: `path-layer-${fd.slice_id}`,
+    id: `path-layer-${fd.slice_id}` as const,
     data,
-    pickable: true,
     filled: fd.filled,
     stroked: fd.stroked,
     getPolygon: getPointsFromPolygon,
@@ -151,34 +157,50 @@ export function getLayer(
   });
 }
 
-const propTypes = {
-  formData: PropTypes.object.isRequired,
-  payload: PropTypes.object.isRequired,
-  setControlValue: PropTypes.func.isRequired,
-  viewport: PropTypes.object.isRequired,
-  onAddFilter: PropTypes.func,
-  width: PropTypes.number.isRequired,
-  height: PropTypes.number.isRequired,
+export type PolygonFormData = QueryFormData & {
+  break_points: string[];
+  num_buckets: string;
+  linear_color_scheme: string | string[];
+  opacity: number;
+};
+export type DeckGLPolygonProps = {
+  formData: PolygonFormData;
+  payload: JsonObject;
+  setControlValue: (control: string, value: JsonValue) => void;
+  viewport: Viewport;
+  onAddFilter: HandlerFunction;
+  width: number;
+  height: number;
 };
 
-const defaultProps = {
-  onAddFilter() {},
+export type DeckGLPolygonState = {
+  lastClick: number;
+  viewport: Viewport;
+  formData: PolygonFormData;
+  selected: JsonObject[];
 };
 
-class DeckGLPolygon extends React.Component {
-  containerRef = React.createRef();
+class DeckGLPolygon extends React.PureComponent<
+  DeckGLPolygonProps,
+  DeckGLPolygonState
+> {
+  containerRef = React.createRef<DeckGLContainer>();
 
-  constructor(props) {
+  constructor(props: DeckGLPolygonProps) {
     super(props);
 
-    this.state = DeckGLPolygon.getDerivedStateFromProps(props);
+    this.state = DeckGLPolygon.getDerivedStateFromProps(
+      props,
+    ) as DeckGLPolygonState;
 
     this.getLayers = this.getLayers.bind(this);
     this.onSelect = this.onSelect.bind(this);
-    this.onValuesChange = this.onValuesChange.bind(this);
   }
 
-  static getDerivedStateFromProps(props, state) {
+  static getDerivedStateFromProps(
+    props: DeckGLPolygonProps,
+    state?: DeckGLPolygonState,
+  ) {
     const { width, height, formData, payload } = props;
 
     // the state is computed only from the payload; if it hasn't changed, do
@@ -189,19 +211,6 @@ class DeckGLPolygon extends React.Component {
     }
 
     const features = payload.data.features || [];
-    const timestamps = features.map(f => f.__timestamp);
-
-    // the granularity has to be read from the payload form_data, not the
-    // props formData which comes from the instantaneous controls state
-    const granularity =
-      payload.form_data.time_grain_sqla ||
-      payload.form_data.granularity ||
-      'P1D';
-
-    const { start, end, getStep, values, disabled } = getPlaySliderParams(
-      timestamps,
-      granularity,
-    );
 
     let { viewport } = props;
     if (formData.autozoom) {
@@ -213,11 +222,6 @@ class DeckGLPolygon extends React.Component {
     }
 
     return {
-      start,
-      end,
-      getStep,
-      values,
-      disabled,
       viewport,
       selected: [],
       lastClick: 0,
@@ -225,10 +229,10 @@ class DeckGLPolygon extends React.Component {
     };
   }
 
-  onSelect(polygon) {
+  onSelect(polygon: JsonObject) {
     const { formData, onAddFilter } = this.props;
 
-    const now = new Date();
+    const now = new Date().getDate();
     const doubleClick = now - this.state.lastClick <= DOUBLE_CLICK_THRESHOLD;
 
     // toggle selected polygons
@@ -252,32 +256,11 @@ class DeckGLPolygon extends React.Component {
     }
   }
 
-  onValuesChange(values) {
-    this.setState({
-      values: Array.isArray(values)
-        ? values
-        : [values, values + this.state.getStep(values)],
-    });
-  }
-
-  getLayers(values) {
+  getLayers() {
     if (this.props.payload.data.features === undefined) {
       return [];
     }
 
-    const filters = [];
-
-    // time filter
-    if (values[0] === values[1] || values[1] === this.end) {
-      filters.push(
-        d => d.__timestamp >= values[0] && d.__timestamp <= values[1],
-      );
-    } else {
-      filters.push(
-        d => d.__timestamp >= values[0] && d.__timestamp < values[1],
-      );
-    }
-
     const layer = getLayer(
       this.props.formData,
       this.props.payload,
@@ -285,13 +268,12 @@ class DeckGLPolygon extends React.Component {
       this.setTooltip,
       this.state.selected,
       this.onSelect,
-      filters,
     );
 
     return [layer];
   }
 
-  setTooltip = tooltip => {
+  setTooltip = (tooltip: TooltipProps['tooltip']) => {
     const { current } = this.containerRef;
     if (current) {
       current.setTooltip(tooltip);
@@ -300,48 +282,36 @@ class DeckGLPolygon extends React.Component {
 
   render() {
     const { payload, formData, setControlValue } = this.props;
-    const { start, end, getStep, values, disabled, viewport } = this.state;
 
     const fd = formData;
     const metricLabel = fd.metric ? fd.metric.label || fd.metric : null;
-    const accessor = d => d[metricLabel];
+    const accessor = (d: JsonObject) => d[metricLabel];
 
     const buckets = getBuckets(formData, payload.data.features, accessor);
 
     return (
       <div style={{ position: 'relative' }}>
-        <AnimatableDeckGLContainer
+        <DeckGLContainerStyledWrapper
           ref={this.containerRef}
-          aggregation
-          getLayers={this.getLayers}
-          start={start}
-          end={end}
-          getStep={getStep}
-          values={values}
-          disabled={disabled}
-          viewport={viewport}
+          viewport={this.state.viewport}
+          layers={this.getLayers()}
+          setControlValue={setControlValue}
+          mapStyle={formData.mapbox_style}
+          mapboxApiAccessToken={payload.data.mapboxApiKey}
           width={this.props.width}
           height={this.props.height}
-          mapboxApiAccessToken={payload.data.mapboxApiKey}
-          mapStyle={formData.mapbox_style}
-          setControlValue={setControlValue}
-          onValuesChange={this.onValuesChange}
-          onViewportChange={this.onViewportChange}
-        >
-          {formData.metric !== null && (
-            <Legend
-              categories={buckets}
-              position={formData.legend_position}
-              format={formData.legend_format}
-            />
-          )}
-        </AnimatableDeckGLContainer>
+        />
+
+        {formData.metric !== null && (
+          <Legend
+            categories={buckets}
+            position={formData.legend_position}
+            format={formData.legend_format}
+          />
+        )}
       </div>
     );
   }
 }
 
-DeckGLPolygon.propTypes = propTypes;
-DeckGLPolygon.defaultProps = defaultProps;
-
 export default DeckGLPolygon;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Polygon/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/Scatter.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/Scatter.tsx
similarity index 76%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/Scatter.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/Scatter.tsx
index 5237523067..c529e5c1d9 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/Scatter.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/Scatter.tsx
@@ -16,20 +16,30 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { ScatterplotLayer } from 'deck.gl';
+import { ScatterplotLayer } from 'deck.gl/typed';
 import React from 'react';
-import { getMetricLabel, t } from '@superset-ui/core';
+import {
+  Datasource,
+  getMetricLabel,
+  JsonObject,
+  QueryFormData,
+  t,
+} from '@superset-ui/core';
 import { commonLayerProps } from '../common';
 import { createCategoricalDeckGLComponent } from '../../factory';
 import TooltipRow from '../../TooltipRow';
 import { unitToRadius } from '../../utils/geo';
+import { TooltipProps } from '../../components/Tooltip';
 
-function getPoints(data) {
+function getPoints(data: JsonObject[]) {
   return data.map(d => d.position);
 }
 
-function setTooltipContent(formData, verboseMap) {
-  return o => {
+function setTooltipContent(
+  formData: QueryFormData,
+  verboseMap?: Record<string, string>,
+) {
+  return (o: JsonObject) => {
     const label =
       verboseMap?.[formData.point_radius_fixed.value] ||
       getMetricLabel(formData.point_radius_fixed?.value);
@@ -56,14 +66,14 @@ function setTooltipContent(formData, verboseMap) {
 }
 
 export function getLayer(
-  formData,
-  payload,
-  onAddFilter,
-  setTooltip,
-  datasource,
+  formData: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: () => void,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+  datasource: Datasource,
 ) {
   const fd = formData;
-  const dataWithRadius = payload.data.features.map(d => {
+  const dataWithRadius = payload.data.features.map((d: JsonObject) => {
     let radius = unitToRadius(fd.point_unit, d.radius) || 10;
     if (fd.multiplier) {
       radius *= fd.multiplier;
@@ -78,13 +88,13 @@ export function getLayer(
   });
 
   return new ScatterplotLayer({
-    id: `scatter-layer-${fd.slice_id}`,
+    id: `scatter-layer-${fd.slice_id}` as const,
     data: dataWithRadius,
     fp64: true,
     getFillColor: d => d.color,
     getRadius: d => d.radius,
-    radiusMinPixels: Number(fd.min_radius) || null,
-    radiusMaxPixels: Number(fd.max_radius) || null,
+    radiusMinPixels: Number(fd.min_radius) || undefined,
+    radiusMaxPixels: Number(fd.max_radius) || undefined,
     stroked: false,
     ...commonLayerProps(
       fd,
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Scatter/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/Screengrid.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/Screengrid.tsx
similarity index 55%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/Screengrid.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/Screengrid.tsx
index 7883dda17e..173770c6c1 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/Screengrid.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/Screengrid.tsx
@@ -21,22 +21,25 @@
 /* eslint no-underscore-dangle: ["error", { "allow": ["", "__timestamp"] }] */
 
 import React from 'react';
-import PropTypes from 'prop-types';
-import { ScreenGridLayer } from 'deck.gl';
-import { t } from '@superset-ui/core';
-import AnimatableDeckGLContainer from '../../AnimatableDeckGLContainer';
-import { getPlaySliderParams } from '../../utils/time';
+import { ScreenGridLayer } from 'deck.gl/typed';
+import { JsonObject, JsonValue, QueryFormData, t } from '@superset-ui/core';
+import { noop } from 'lodash';
 import sandboxedEval from '../../utils/sandbox';
 import { commonLayerProps } from '../common';
 import TooltipRow from '../../TooltipRow';
 // eslint-disable-next-line import/extensions
-import fitViewport from '../../utils/fitViewport';
-
-function getPoints(data) {
+import fitViewport, { Viewport } from '../../utils/fitViewport';
+import {
+  DeckGLContainer,
+  DeckGLContainerStyledWrapper,
+} from '../../DeckGLContainer';
+import { TooltipProps } from '../../components/Tooltip';
+
+function getPoints(data: JsonObject[]) {
   return data.map(d => d.position);
 }
 
-function setTooltipContent(o) {
+function setTooltipContent(o: JsonObject) {
   return (
     <div className="deckgl-tooltip">
       <TooltipRow
@@ -54,17 +57,14 @@ function setTooltipContent(o) {
 }
 
 export function getLayer(
-  formData,
-  payload,
-  onAddFilter,
-  setTooltip,
-  selected,
-  onSelect,
-  filters,
+  formData: QueryFormData,
+  payload: JsonObject,
+  onAddFilter: () => void,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
 ) {
   const fd = formData;
   const c = fd.color_picker;
-  let data = payload.data.features.map(d => ({
+  let data = payload.data.features.map((d: JsonObject) => ({
     ...d,
     color: [c.r, c.g, c.b, 255 * c.a],
   }));
@@ -75,18 +75,11 @@ export function getLayer(
     data = jsFnMutator(data);
   }
 
-  if (filters != null) {
-    filters.forEach(f => {
-      data = data.filter(x => f(x));
-    });
-  }
-
   // Passing a layer creator function instead of a layer since the
   // layer needs to be regenerated at each render
   return new ScreenGridLayer({
-    id: `screengrid-layer-${fd.slice_id}`,
+    id: `screengrid-layer-${fd.slice_id}` as const,
     data,
-    pickable: true,
     cellSizePixels: fd.grid_size,
     minColor: [c.r, c.g, c.b, 0],
     maxColor: [c.r, c.g, c.b, 255 * c.a],
@@ -96,32 +89,41 @@ export function getLayer(
   });
 }
 
-const propTypes = {
-  formData: PropTypes.object.isRequired,
-  payload: PropTypes.object.isRequired,
-  setControlValue: PropTypes.func.isRequired,
-  viewport: PropTypes.object.isRequired,
-  onAddFilter: PropTypes.func,
-  width: PropTypes.number.isRequired,
-  height: PropTypes.number.isRequired,
+export type DeckGLScreenGridProps = {
+  formData: QueryFormData;
+  payload: JsonObject;
+  setControlValue: (control: string, value: JsonValue) => void;
+  viewport: Viewport;
+  width: number;
+  height: number;
+  onAddFilter: () => void;
 };
-const defaultProps = {
-  onAddFilter() {},
+
+export type DeckGLScreenGridState = {
+  viewport: Viewport;
+  formData: QueryFormData;
 };
 
-class DeckGLScreenGrid extends React.PureComponent {
-  containerRef = React.createRef();
+class DeckGLScreenGrid extends React.PureComponent<
+  DeckGLScreenGridProps,
+  DeckGLScreenGridState
+> {
+  containerRef = React.createRef<DeckGLContainer>();
 
-  constructor(props) {
+  constructor(props: DeckGLScreenGridProps) {
     super(props);
 
-    this.state = DeckGLScreenGrid.getDerivedStateFromProps(props);
+    this.state = DeckGLScreenGrid.getDerivedStateFromProps(
+      props,
+    ) as DeckGLScreenGridState;
 
     this.getLayers = this.getLayers.bind(this);
-    this.onValuesChange = this.onValuesChange.bind(this);
   }
 
-  static getDerivedStateFromProps(props, state) {
+  static getDerivedStateFromProps(
+    props: DeckGLScreenGridProps,
+    state?: DeckGLScreenGridState,
+  ) {
     // the state is computed only from the payload; if it hasn't changed, do
     // not recompute state since this would reset selections and/or the play
     // slider position due to changes in form controls
@@ -130,19 +132,7 @@ class DeckGLScreenGrid extends React.PureComponent {
     }
 
     const features = props.payload.data.features || [];
-    const timestamps = features.map(f => f.__timestamp);
-
-    // the granularity has to be read from the payload form_data, not the
-    // props formData which comes from the instantaneous controls state
-    const granularity =
-      props.payload.form_data.time_grain_sqla ||
-      props.payload.form_data.granularity ||
-      'P1D';
-
-    const { start, end, getStep, values, disabled } = getPlaySliderParams(
-      timestamps,
-      granularity,
-    );
+
     const { width, height, formData } = props;
 
     let { viewport } = props;
@@ -155,53 +145,23 @@ class DeckGLScreenGrid extends React.PureComponent {
     }
 
     return {
-      start,
-      end,
-      getStep,
-      values,
-      disabled,
       viewport,
-      selected: [],
-      lastClick: 0,
-      formData: props.payload.form_data,
+      formData: props.payload.form_data as QueryFormData,
     };
   }
 
-  onValuesChange(values) {
-    this.setState({
-      values: Array.isArray(values)
-        ? values
-        : // eslint-disable-next-line react/no-access-state-in-setstate
-          [values, values + this.state.getStep(values)],
-    });
-  }
-
-  getLayers(values) {
-    const filters = [];
-
-    // time filter
-    if (values[0] === values[1] || values[1] === this.end) {
-      filters.push(
-        d => d.__timestamp >= values[0] && d.__timestamp <= values[1],
-      );
-    } else {
-      filters.push(
-        d => d.__timestamp >= values[0] && d.__timestamp < values[1],
-      );
-    }
-
+  getLayers() {
     const layer = getLayer(
       this.props.formData,
       this.props.payload,
-      this.props.onAddFilter,
+      noop,
       this.setTooltip,
-      filters,
     );
 
     return [layer];
   }
 
-  setTooltip = tooltip => {
+  setTooltip = (tooltip: TooltipProps['tooltip']) => {
     const { current } = this.containerRef;
     if (current) {
       current.setTooltip(tooltip);
@@ -213,30 +173,19 @@ class DeckGLScreenGrid extends React.PureComponent {
 
     return (
       <div>
-        <AnimatableDeckGLContainer
+        <DeckGLContainerStyledWrapper
           ref={this.containerRef}
-          aggregation
-          getLayers={this.getLayers}
-          start={this.state.start}
-          end={this.state.end}
-          getStep={this.state.getStep}
-          values={this.state.values}
-          disabled={this.state.disabled}
           viewport={this.state.viewport}
+          layers={this.getLayers()}
+          setControlValue={setControlValue}
+          mapStyle={formData.mapbox_style}
+          mapboxApiAccessToken={payload.data.mapboxApiKey}
           width={this.props.width}
           height={this.props.height}
-          mapboxApiAccessToken={payload.data.mapboxApiKey}
-          mapStyle={formData.mapbox_style}
-          setControlValue={setControlValue}
-          onValuesChange={this.onValuesChange}
-          onViewportChange={this.onViewportChange}
         />
       </div>
     );
   }
 }
 
-DeckGLScreenGrid.propTypes = propTypes;
-DeckGLScreenGrid.defaultProps = defaultProps;
-
 export default DeckGLScreenGrid;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/Screengrid/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/common.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/common.tsx
similarity index 63%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/common.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/common.tsx
index e847ef3eec..80f0371e5c 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/common.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/common.tsx
@@ -16,14 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+import { ReactNode } from 'react';
 import * as d3array from 'd3-array';
+import { JsonObject, JsonValue, QueryFormData } from '@superset-ui/core';
 import sandboxedEval from '../utils/sandbox';
+import { TooltipProps } from '../components/Tooltip';
 
 export function commonLayerProps(
-  formData,
-  setTooltip,
-  setTooltipContent,
-  onSelect,
+  formData: QueryFormData,
+  setTooltip: (tooltip: TooltipProps['tooltip']) => void,
+  setTooltipContent: (content: JsonObject) => ReactNode,
+  onSelect?: (value: JsonValue) => void,
 ) {
   const fd = formData;
   let onHover;
@@ -32,7 +35,7 @@ export function commonLayerProps(
     tooltipContentGenerator = sandboxedEval(fd.js_tooltip);
   }
   if (tooltipContentGenerator) {
-    onHover = o => {
+    onHover = (o: JsonObject) => {
       if (o.picked) {
         setTooltip({
           content: tooltipContentGenerator(o),
@@ -42,16 +45,21 @@ export function commonLayerProps(
       } else {
         setTooltip(null);
       }
+      return true;
     };
   }
   let onClick;
   if (fd.js_onclick_href) {
-    onClick = o => {
+    onClick = (o: any) => {
       const href = sandboxedEval(fd.js_onclick_href)(o);
       window.open(href);
+      return true;
     };
   } else if (fd.table_filter && onSelect !== undefined) {
-    onClick = o => onSelect(o.object[fd.line_column]);
+    onClick = (o: any) => {
+      onSelect(o.object[fd.line_column]);
+      return true;
+    };
   }
 
   return {
@@ -68,17 +76,23 @@ const percentiles = {
   p99: 0.99,
 };
 
-/* Get an a stat function that operates on arrays, aligns with control=js_agg_function  */
-export function getAggFunc(type = 'sum', accessor = null) {
+/* Get a stat function that operates on arrays, aligns with control=js_agg_function  */
+export function getAggFunc(
+  type = 'sum',
+  accessor: ((object: any) => number | undefined) | null = null,
+) {
   if (type === 'count') {
-    return arr => arr.length;
+    return (arr: number[]) => arr.length;
   }
-  let d3func;
+  let d3func: (
+    iterable: Array<unknown>,
+    accessor?: (object: JsonObject) => number | undefined,
+  ) => number[] | number | undefined;
   if (type in percentiles) {
-    d3func = (arr, acc) => {
+    d3func = (arr, acc: (object: JsonObject) => number | undefined) => {
       let sortedArr;
       if (accessor) {
-        sortedArr = arr.sort((o1, o2) =>
+        sortedArr = arr.sort((o1: JsonObject, o2: JsonObject) =>
           d3array.ascending(accessor(o1), accessor(o2)),
         );
       } else {
@@ -91,8 +105,8 @@ export function getAggFunc(type = 'sum', accessor = null) {
     d3func = d3array[type];
   }
   if (!accessor) {
-    return arr => d3func(arr);
+    return (arr: JsonObject[]) => d3func(arr);
   }
 
-  return arr => d3func(arr.map(x => accessor(x)));
+  return (arr: JsonObject[]) => d3func(arr.map(x => accessor(x)));
 }
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/index.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/index.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/index.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/layers/index.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/preset.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/preset.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/preset.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/preset.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/transformProps.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/transformProps.ts
similarity index 91%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/transformProps.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/transformProps.ts
index ab62dbead7..3d7c43445a 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/transformProps.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/transformProps.ts
@@ -16,9 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
+import { ChartProps } from '@superset-ui/core';
+
 const NOOP = () => {};
 
-export default function transformProps(chartProps) {
+export default function transformProps(chartProps: ChartProps) {
   const { datasource, height, hooks, queriesData, rawFormData, width } =
     chartProps;
   const { onAddFilter = NOOP, setControlValue = NOOP } = hooks;
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx
index 0010d617b2..9a123e91c3 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/Shared_DeckGL.jsx
@@ -39,7 +39,7 @@ const DEFAULT_VIEWPORT = {
 
 const sandboxUrl =
   'https://github.com/apache/superset/' +
-  'blob/master/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.js';
+  'blob/master/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.ts';
 const jsFunctionInfo = (
   <div>
     {t(
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.ts
similarity index 69%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.ts
index 9e6d2b0d84..03816e96dc 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.jsx
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/controls.ts
@@ -16,10 +16,21 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-export function columnChoices(datasource) {
+
+import { QueryResponse } from '@superset-ui/core';
+import {
+  ColumnMeta,
+  ControlPanelState,
+  Dataset,
+} from '@superset-ui/chart-controls';
+
+export function columnChoices(datasource: Dataset | QueryResponse | null) {
   if (datasource?.columns) {
     return datasource.columns
-      .map(col => [col.column_name, col.verbose_name || col.column_name])
+      .map(col => [
+        col.column_name,
+        (col as ColumnMeta).verbose_name || col.column_name,
+      ])
       .sort((opt1, opt2) =>
         opt1[1].toLowerCase() > opt2[1].toLowerCase() ? 1 : -1,
       );
@@ -31,9 +42,11 @@ export const PRIMARY_COLOR = { r: 0, g: 122, b: 135, a: 1 };
 
 export default {
   default: null,
-  mapStateToProps: state => ({
+  mapStateToProps: (state: ControlPanelState) => ({
     choices: state.datasource
-      ? state.datasource.time_grain_sqla.filter(o => o[0] !== null)
+      ? (state.datasource as Dataset).time_grain_sqla?.filter(
+          o => o[0] !== null,
+        )
       : null,
   }),
 };
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/sharedDndControls.jsx b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/sharedDndControls.tsx
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/sharedDndControls.jsx
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/sharedDndControls.tsx
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/utils.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/utils.js
deleted file mode 100644
index d9b783f0e0..0000000000
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/utils.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * 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.
- */
-/* eslint camelcase: 0 */
-import $ from 'jquery';
-
-/**
- * Sets the body and title content of a modal, and shows it. Assumes HTML for modal exists and that
- * it handles closing (i.e., works with bootstrap)
- *
- * @param {object} options object of the form
- *  {
- *    title: {string},
- *    body: {string},
- *    modalSelector: {string, default: '.misc-modal' },
- *    titleSelector: {string, default: '.misc-modal .modal-title' },
- *    bodySelector:  {string, default: '.misc-modal .modal-body' },
- *   }
- */
-export function showModal(options) {
-  /* eslint no-param-reassign: 0 */
-  options.modalSelector = options.modalSelector || '.misc-modal';
-  options.titleSelector = options.titleSelector || '.misc-modal .modal-title';
-  options.bodySelector = options.bodySelector || '.misc-modal .modal-body';
-  $(options.titleSelector).html(options.title || '');
-  $(options.bodySelector).html(options.body || '');
-  $(options.modalSelector).modal('show');
-}
-
-export function formatSelectOptionsForRange(start, end) {
-  // outputs array of arrays
-  // formatSelectOptionsForRange(1, 5)
-  // returns [[1,1], [2,2], [3,3], [4,4], [5,5]]
-  const options = [];
-  // eslint-disable-next-line no-plusplus
-  for (let i = start; i <= end; i++) {
-    options.push([i, i.toString()]);
-  }
-  return options;
-}
-
-export function formatSelectOptions(options) {
-  return options.map(opt => [opt, opt.toString()]);
-}
-
-export function getDatasourceParameter(datasourceId, datasourceType) {
-  return `${datasourceId}__${datasourceType}`;
-}
-
-export function getParam(name) {
-  /* eslint no-useless-escape: 0 */
-  const formattedName = name.replace(/\[/, '\\[').replace(/]/, '\\]');
-  const regex = new RegExp(`[\\?&]${formattedName}=([^&#]*)`);
-  // eslint-disable-next-line no-restricted-globals
-  const results = regex.exec(location.search);
-  return results === null
-    ? ''
-    : decodeURIComponent(results[1].replace(/\+/g, ' '));
-}
-
-export function mainMetric(savedMetrics) {
-  // Using 'count' as default metric if it exists, otherwise using whatever one shows up first
-  let metric;
-  if (savedMetrics && savedMetrics.length > 0) {
-    savedMetrics.forEach(m => {
-      if (m.metric_name === 'count') {
-        metric = 'count';
-      }
-    });
-    if (!metric) {
-      metric = savedMetrics[0].metric_name;
-    }
-  }
-  return metric;
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/utils.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/utils.ts
similarity index 69%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/utils.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/utils.ts
index 13bc88157f..48c164eb5d 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/utils.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utilities/utils.ts
@@ -18,16 +18,6 @@
  */
 /* eslint camelcase: 0 */
 
-// eslint-disable-next-line import/prefer-default-export
-export function roundDecimal(number, precision) {
-  let roundedNumber;
-  if (precision) {
-    roundedNumber =
-      // eslint-disable-next-line no-param-reassign
-      Math.round(number * (precision = 10 ** precision)) / precision;
-  } else {
-    roundedNumber = Math.round(number);
-  }
-
-  return roundedNumber;
+export function formatSelectOptions(options: (string | number)[]) {
+  return options.map(opt => [opt, opt.toString()]);
 }
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils.ts
similarity index 62%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils.ts
index 4de17a9309..aac2a739e6 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils.ts
@@ -18,19 +18,35 @@
  * under the License.
  */
 import { extent } from 'd3-array';
-import { scaleThreshold } from 'd3-scale';
+import { ScaleLinear, ScaleThreshold, scaleThreshold } from 'd3-scale';
 import {
   getSequentialSchemeRegistry,
+  JsonObject,
+  QueryFormData,
   SequentialScheme,
 } from '@superset-ui/core';
+import { isNumber } from 'lodash';
 import { hexToRGB } from './utils/colors';
 
 const DEFAULT_NUM_BUCKETS = 10;
 
+export type Buckets = {
+  break_points: string[];
+  num_buckets: string;
+};
+
+export type BucketsWithColorScale = Buckets & {
+  linear_color_scheme: string | string[];
+  opacity: number;
+};
+
 export function getBreakPoints(
-  { break_points: formDataBreakPoints, num_buckets: formDataNumBuckets },
-  features,
-  accessor,
+  {
+    break_points: formDataBreakPoints,
+    num_buckets: formDataNumBuckets,
+  }: Buckets,
+  features: JsonObject[],
+  accessor: (value: JsonObject) => number | undefined,
 ) {
   if (!features) {
     return [];
@@ -40,23 +56,33 @@ export function getBreakPoints(
     const numBuckets = formDataNumBuckets
       ? parseInt(formDataNumBuckets, 10)
       : DEFAULT_NUM_BUCKETS;
-    const [minValue, maxValue] = extent(features, accessor);
-    if (minValue === undefined) {
+    const [minValue, maxValue] = extent<JsonObject, number>(
+      features,
+      accessor,
+    ).map((value: number | string | undefined) =>
+      typeof value === 'string' ? parseFloat(value) : value,
+    );
+    if (minValue === undefined || maxValue === undefined) {
       return [];
     }
     const delta = (maxValue - minValue) / numBuckets;
     const precision =
       delta === 0 ? 0 : Math.max(0, Math.ceil(Math.log10(1 / delta)));
-    const extraBucket = maxValue > maxValue.toFixed(precision) ? 1 : 0;
+    const extraBucket =
+      maxValue > parseFloat(maxValue.toFixed(precision)) ? 1 : 0;
     const startValue =
-      minValue < minValue.toFixed(precision) ? minValue - 1 : minValue;
+      minValue < parseFloat(minValue.toFixed(precision))
+        ? minValue - 1
+        : minValue;
 
     return new Array(numBuckets + 1 + extraBucket)
-      .fill()
+      .fill(0)
       .map((_, i) => (startValue + i * delta).toFixed(precision));
   }
 
-  return formDataBreakPoints.sort((a, b) => parseFloat(a) - parseFloat(b));
+  return formDataBreakPoints.sort(
+    (a: string, b: string) => parseFloat(a) - parseFloat(b),
+  );
 }
 
 export function getBreakPointColorScaler(
@@ -65,9 +91,9 @@ export function getBreakPointColorScaler(
     num_buckets: formDataNumBuckets,
     linear_color_scheme: linearColorScheme,
     opacity,
-  },
-  features,
-  accessor,
+  }: BucketsWithColorScale,
+  features: JsonObject[],
+  accessor: (value: JsonObject) => number | undefined,
 ) {
   const breakPoints =
     formDataBreakPoints || formDataNumBuckets
@@ -87,8 +113,11 @@ export function getBreakPointColorScaler(
       })
     : getSequentialSchemeRegistry().get(linearColorScheme);
 
-  let scaler;
-  let maskPoint;
+  if (!colorScheme) {
+    return null;
+  }
+  let scaler: ScaleLinear<string, string> | ScaleThreshold<number, string>;
+  let maskPoint: (v: number | undefined) => boolean;
   if (breakPoints !== null) {
     // bucket colors into discrete colors
     const n = breakPoints.length - 1;
@@ -103,17 +132,29 @@ export function getBreakPointColorScaler(
     bucketedColors.unshift(first);
     bucketedColors.push(last);
 
-    const points = breakPoints.map(p => parseFloat(p));
-    scaler = scaleThreshold().domain(points).range(bucketedColors);
-    maskPoint = value => value > breakPoints[n] || value < breakPoints[0];
+    const points = breakPoints.map(parseFloat);
+    scaler = scaleThreshold<number, string>()
+      .domain(points)
+      .range(bucketedColors);
+    maskPoint = value => !!value && (value > points[n] || value < points[0]);
   } else {
     // interpolate colors linearly
-    scaler = colorScheme.createLinearScale(extent(features, accessor));
+    const linearScaleDomain = extent(features, accessor);
+    if (!linearScaleDomain.some(isNumber)) {
+      scaler = colorScheme.createLinearScale();
+    } else {
+      scaler = colorScheme.createLinearScale(
+        extent(features, accessor) as number[],
+      );
+    }
     maskPoint = () => false;
   }
 
-  return d => {
+  return (d: JsonObject): [number, number, number, number] => {
     const v = accessor(d);
+    if (!v) {
+      return [0, 0, 0, 0];
+    }
     const c = hexToRGB(scaler(v));
     if (maskPoint(v)) {
       c[3] = 0;
@@ -125,7 +166,11 @@ export function getBreakPointColorScaler(
   };
 }
 
-export function getBuckets(fd, features, accessor) {
+export function getBuckets(
+  fd: QueryFormData & BucketsWithColorScale,
+  features: JsonObject[],
+  accessor: (value: JsonObject) => number | undefined,
+) {
   const breakPoints = getBreakPoints(fd, features, accessor);
   const colorScaler = getBreakPointColorScaler(fd, features, accessor);
   const buckets = {};
@@ -136,7 +181,7 @@ export function getBuckets(fd, features, accessor) {
     // fix polygon doesn't show
     const metricLabel = fd.metric ? fd.metric.label || fd.metric : null;
     buckets[range] = {
-      color: colorScaler({ [metricLabel || fd.metric]: mid }),
+      color: colorScaler?.({ [metricLabel || fd.metric]: mid }),
       enabled: true,
     };
   });
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/colors.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/colors.ts
similarity index 90%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/colors.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/colors.ts
index 8d8e2bd6fc..7f562dbca2 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/colors.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/colors.ts
@@ -19,7 +19,10 @@
 import { rgb } from 'd3-color';
 
 // eslint-disable-next-line import/prefer-default-export
-export function hexToRGB(hex, alpha = 255) {
+export function hexToRGB(
+  hex: string | undefined,
+  alpha = 255,
+): [number, number, number, number] {
   if (!hex) {
     return [0, 0, 0, alpha];
   }
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.ts
similarity index 88%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.ts
index cf1d691ff9..5d3ba876ee 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/explore.ts
@@ -17,11 +17,12 @@
  * under the License.
  */
 import URI from 'urijs';
+import { JsonObject } from '@superset-ui/core';
 import { safeStringify } from './safeStringify';
 
 const MAX_URL_LENGTH = 8000;
 
-export function getURIDirectory(formData, endpointType = 'base') {
+export function getURIDirectory(endpointType = 'base') {
   // Building the directory part of the URI
   let directory = '/explore/';
   if (['json', 'csv', 'query', 'results', 'samples'].includes(endpointType)) {
@@ -32,17 +33,17 @@ export function getURIDirectory(formData, endpointType = 'base') {
 }
 
 export function getExploreLongUrl(
-  formData,
-  endpointType,
+  formData: JsonObject,
+  endpointType: string,
   allowOverflow = true,
   extraSearch = {},
-) {
+): string | undefined {
   if (!formData.datasource) {
-    return null;
+    return undefined;
   }
 
   const uri = new URI('/');
-  const directory = getURIDirectory(formData, endpointType);
+  const directory = getURIDirectory(endpointType);
   const search = uri.search(true);
   Object.keys(extraSearch).forEach(key => {
     search[key] = extraSearch[key];
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/fitViewport.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/fitViewport.ts
index c8e2487b90..3ea9024297 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/fitViewport.ts
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/fitViewport.ts
@@ -49,7 +49,7 @@ export default function fitViewport(
     offset,
     padding = 20,
   }: FitViewportOptions,
-) {
+): Viewport {
   const { bearing, pitch } = originalViewPort;
   const bounds = computeBoundsFromPoints(points);
 
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/geo.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/geo.ts
similarity index 72%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/geo.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/geo.ts
index b09cc089dc..48b1e92661 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/geo.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/geo.ts
@@ -16,7 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { roundDecimal } from './utils';
+
+export type Unit =
+  | 'square_m'
+  | 'radius_m'
+  | 'radius_km'
+  | 'radius_miles'
+  | 'square_km'
+  | 'square_miles';
 
 export const defaultViewport = {
   bearing: 0,
@@ -28,7 +35,7 @@ export const defaultViewport = {
 
 const METER_TO_MILE = 1609.34;
 
-export function unitToRadius(unit, num) {
+export function unitToRadius(unit: Unit, num: number) {
   if (unit === 'square_m') {
     return Math.sqrt(num / Math.PI);
   }
@@ -50,16 +57,3 @@ export function unitToRadius(unit, num) {
 
   return null;
 }
-
-export const EARTH_CIRCUMFERENCE_KM = 40075.16;
-export const MILES_PER_KM = 1.60934;
-
-export function kmToPixels(kilometers, latitude, zoomLevel) {
-  // Algorithm from: https://wiki.openstreetmap.org/wiki/Zoom_levels
-  const latitudeRad = latitude * (Math.PI / 180);
-  // Seems like the zoomLevel is off by one
-  const kmPerPixel =
-    (EARTH_CIRCUMFERENCE_KM * Math.cos(latitudeRad)) / 2 ** (zoomLevel + 9);
-
-  return roundDecimal(kilometers / kmPerPixel, 2);
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/safeStringify.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/safeStringify.ts
similarity index 94%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/safeStringify.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/safeStringify.ts
index 4e4bf1e8e4..aa985f87cf 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/safeStringify.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/safeStringify.ts
@@ -18,6 +18,8 @@
  * under the License.
  */
 
+import { JsonObject } from '@superset-ui/core';
+
 /**
  * A Stringify function that will not crash when it runs into circular JSON references,
  * unlike JSON.stringify. Any circular references are simply omitted, as if there had
@@ -26,7 +28,7 @@
  */
 
 // eslint-disable-next-line import/prefer-default-export
-export function safeStringify(object) {
+export function safeStringify(object: JsonObject) {
   const cache = new Set();
 
   return JSON.stringify(object, (key, value) => {
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.ts
similarity index 91%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.ts
index 3082774a73..bf41f1f200 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.js
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/sandbox.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 // A safe alternative to JS's eval
-import vm from 'vm';
+import vm, { Context, RunningScriptOptions } from 'vm';
 import _ from 'underscore';
 import * as d3array from 'd3-array';
 import * as colors from './colors';
@@ -33,7 +33,11 @@ const GLOBAL_CONTEXT = {
 };
 
 // Copied/modified from https://github.com/hacksparrow/safe-eval/blob/master/index.js
-export default function sandboxedEval(code, context, opts) {
+export default function sandboxedEval(
+  code: string,
+  context?: Context,
+  opts?: RunningScriptOptions | string,
+) {
   const sandbox = {};
   const resultKey = `SAFE_EVAL_${Math.floor(Math.random() * 1000000)}`;
   sandbox[resultKey] = {};
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/time.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/time.js
deleted file mode 100644
index 6554adb7a1..0000000000
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/src/utils/time.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/* eslint-disable no-negated-condition */
-/**
- * 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 moment from 'moment';
-
-// array with the minimum values of each part of a timestamp -- note that
-// months are zero-indexed in JavaScript
-const truncatePartTo = [
-  1, // year
-  0, // month
-  1, // day
-  0, // hour
-  0, // minute
-  0, // second
-  0, // millisecond
-];
-
-export function truncate(timestamp, step) {
-  /*
-   * Truncate timestamp down to duration resolution.
-   */
-  const lowerBound = moment(timestamp).subtract(step);
-  const explodedTimestamp = timestamp.toArray();
-  const explodedLowerBound = lowerBound.toArray();
-
-  const firstDiffIndex = explodedTimestamp
-    .map((part, i) => explodedLowerBound[i] !== part)
-    .indexOf(true);
-  const dateParts = explodedTimestamp.map((part, i) => {
-    if (i === firstDiffIndex) {
-      // truncate down to closest `truncatePartTo[i] + n * step`
-      const difference = part - explodedLowerBound[i];
-
-      return part - ((part - truncatePartTo[i]) % difference);
-    }
-    if (i < firstDiffIndex || firstDiffIndex === -1) {
-      return part;
-    }
-
-    return truncatePartTo[i];
-  });
-
-  return moment(dateParts);
-}
-
-function getStepSeconds(step, start) {
-  /* Return number of seconds in a step.
-   *
-   * The step might be ambiguous, eg, "1 month" has a variable number of
-   * seconds, which is why we need to know the start time.
-   */
-  const startMilliseconds = parseInt(moment(start).format('x'), 10);
-  const endMilliseconds = parseInt(moment(start).add(step).format('x'), 10);
-
-  return endMilliseconds - startMilliseconds;
-}
-
-export function getPlaySliderParams(timestamps, timeGrain) {
-  const minTimestamp = moment(
-    Number(timestamps.reduce((a, b) => (a < b ? a : b))),
-  );
-  const maxTimestamp = moment(
-    Number(timestamps.reduce((a, b) => (a > b ? a : b))),
-  );
-  let step;
-  let reference;
-
-  if (timeGrain.includes('/')) {
-    // Here, time grain is a time interval instead of a simple duration, either
-    // `reference/duration` or `duration/reference`. We need to parse the
-    // duration and make sure that start and end are in the right places. For
-    // example, if `reference` is a Saturday and `duration` is 1 week (P1W)
-    // then both start and end should be Saturdays.
-    const parts = timeGrain.split('/', 2);
-    if (parts[0].endsWith('Z')) {
-      // ISO string
-      reference = moment(parts[0]);
-      step = moment.duration(parts[1]);
-    } else {
-      reference = moment(parts[1]);
-      step = moment.duration(parts[0]);
-    }
-  } else {
-    step = moment.duration(timeGrain);
-    reference = truncate(minTimestamp, step);
-  }
-
-  // find the largest `reference + n * step` smaller than the minimum timestamp
-  let start;
-  const minValue = minTimestamp.valueOf();
-  for (start = reference.clone(); start.valueOf() < minValue; ) {
-    start.add(step);
-  }
-  for (; start.valueOf() > minValue; ) {
-    start.subtract(step);
-  }
-
-  // find the smallest `reference + n * step` larger than the maximum timestamp
-  let end;
-  const maxValue = maxTimestamp.valueOf();
-  for (end = reference.clone(); end.valueOf() > maxValue; ) {
-    end.subtract(step);
-  }
-  for (; end.valueOf() < maxValue; ) {
-    end.add(step);
-  }
-
-  const values =
-    timeGrain != null ? [start, start.clone().add(step)] : [start, end];
-  const disabled = timestamps.every(timestamp => timestamp === null);
-
-  return {
-    start: parseInt(start.format('x'), 10),
-    end: parseInt(end.format('x'), 10),
-    getStep: getStepSeconds.bind(this, step),
-    values: values.map(v => parseInt(v.format('x'), 10)),
-    disabled,
-  };
-}
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/test/utils/colors.test.js b/superset-frontend/plugins/legacy-preset-chart-deckgl/test/utils/colors.test.ts
similarity index 100%
rename from superset-frontend/plugins/legacy-preset-chart-deckgl/test/utils/colors.test.js
rename to superset-frontend/plugins/legacy-preset-chart-deckgl/test/utils/colors.test.ts
diff --git a/superset-frontend/plugins/legacy-preset-chart-deckgl/types/external.d.ts b/superset-frontend/plugins/legacy-preset-chart-deckgl/types/external.d.ts
index 02c511cbc9..9543307b69 100644
--- a/superset-frontend/plugins/legacy-preset-chart-deckgl/types/external.d.ts
+++ b/superset-frontend/plugins/legacy-preset-chart-deckgl/types/external.d.ts
@@ -16,32 +16,5 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-declare module '@math.gl/web-mercator';
 
-declare module 'deck.gl' {
-  import { Layer, LayerProps } from '@deck.gl/core';
-
-  interface HeatmapLayerProps<T extends object = any> extends LayerProps<T> {
-    id?: string;
-    data?: T[];
-    getPosition?: (d: T) => number[] | null | undefined;
-    getWeight?: (d: T) => number | null | undefined;
-    radiusPixels?: number;
-    colorRange?: number[][];
-    threshold?: number;
-    intensity?: number;
-    aggregation?: string;
-  }
-
-  export class HeatmapLayer<T extends object = any> extends Layer<
-    T,
-    HeatmapLayerProps<T>
-  > {
-    constructor(props: HeatmapLayerProps<T>);
-  }
-}
-
-declare module '*.png' {
-  const value: any;
-  export default value;
-}
+declare module '*.png';