Repository: deephaven/deephaven-plugins (language: python)

Issue:
Deephaven express should respect the disable webGL flag
We're adding a flag to disable WebGL: https://github.com/deephaven/web-client-ui/pull/2134
Deephaven express should respect that flag.


Discussion / hints:
We'll need the client to communicate with the server plugin whenever the WebGL setting changes (and likely theme as well for colors to work correctly). That gets a little complicated because we only have message streams to specific instances of widgets, whereas this would be a "global" setting. Probably easiest to just communicate with each instance, but in theory we could "optimize" it to only notify once per session and have that somehow propagate to each instance (just for that user/session). Otherwise you may have a bunch of plots open, and send the same message "webGL=off" to each instance.
I don't think the client necessarily needs to communicate to the server here. We could just replace any series ending in gl with their non-gl variant in JS even if the server says to render with gl
This is a little more complicated than I initially thought 
From https://plotly.com/python/webgl-vs-svg/

>The following trace types use WebGL for part or all of the rendering:
>Accelerated versions of SVG trace types: scattergl, scatterpolargl, heatmapgl
>High-performance multidimensional trace types: splom, or parcoords
>3-d trace types scatter3d, surface, mesh3d, cone, streamtube
>Mapbox Gl JS-powered trace types: scattermapbox, choroplethmapbox, densitymapbox

So we definitely would swap out the gl versions to the svg versions, but what do we do in the other cases? Do we disable those too by just removing them and showing a message that they are not supported when WebGL is disabled?
That's a good question. This is probably something that we could handle client-side if that's easier. There's already some checks for 3D/geo at least based on trace names (so ticking data doesn't reset you when rotating the scene).

It should be easy to replace traces client side with their non-gl variant since we just need to strip the `gl` suffix. Then for those other types we can determine what to do. Maybe disable with a button to enable just that plot if webgl is the only option
We'll definitely do this client side. My inclination would be to disable with a button to enable unless `web.webgl.editable` is false, then it's just disabled with no option to enable. That's perhaps the strictest version of what is reasonable, but without finer grained settings it seems like the only option that obeys the setting whilst allowing as much flexibility as possible.

Fix patch:
diff --git a/package-lock.json b/package-lock.json
index 322705379..af91cf429 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -181,6 +181,11 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/@astral-sh/ruff-wasm-web": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/@astral-sh/ruff-wasm-web/-/ruff-wasm-web-0.6.4.tgz",
+      "integrity": "sha512-IzXhcOU8McbU0cPDuU8iBaYa0SLEzFmIN5G0QnnXWu9vdWUcsnWcPpjJRFItmTk0kEibagCoCHc+39aAyD6XIw=="
+    },
     "node_modules/@babel/code-frame": {
       "version": "7.23.5",
       "dev": true,
@@ -2203,17 +2208,17 @@
       }
     },
     "node_modules/@deephaven/chart": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.88.0.tgz",
-      "integrity": "sha512-t0m2GE+o46pnyPLiF3gNbqxsrasoKKB37E5eFgyncmfye3JjYAoDEjdKZfp/ck4zHE68tO7N+e7fbyqju5Edpw==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.97.0.tgz",
+      "integrity": "sha512-6N8+K0LmNGfB/YhIa670qSmgDnxYeMO3B5q3FYSs6iF51VkrG431YLhAoQGTcgNglSpvxGNH+qldLadIDn4baA==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "buffer": "^6.0.3",
         "fast-deep-equal": "^3.1.3",
         "lodash.debounce": "^4.0.8",
@@ -2232,15 +2237,15 @@
       }
     },
     "node_modules/@deephaven/chart/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -2274,19 +2279,19 @@
       }
     },
     "node_modules/@deephaven/chart/node_modules/@deephaven/jsapi-types": {
-      "version": "1.0.0-dev0.35.2",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-      "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+      "version": "1.0.0-dev0.36.1",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+      "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
     },
     "node_modules/@deephaven/chart/node_modules/@deephaven/jsapi-utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-      "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+      "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
       "dependencies": {
-        "@deephaven/filters": "^0.88.0",
+        "@deephaven/filters": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "lodash.clamp": "^4.0.3",
         "nanoid": "^5.0.7"
       },
@@ -2295,9 +2300,9 @@
       }
     },
     "node_modules/@deephaven/chart/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -2306,9 +2311,9 @@
       }
     },
     "node_modules/@deephaven/chart/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -2418,19 +2423,21 @@
       }
     },
     "node_modules/@deephaven/console": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.88.0.tgz",
-      "integrity": "sha512-RKyGJSXTxiFapPej5BnoHakgil9ATU9Xjt2nwZ5x630ATu9f6k3xfeHpOxeuvcr6IjdUsvPcMk74y5IRAOatJA==",
-      "dependencies": {
-        "@deephaven/chart": "^0.88.0",
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/jsapi-bootstrap": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.97.0.tgz",
+      "integrity": "sha512-3/y/uV0OME2XOgR62drVdFwF7fIvuUZrDl6G66PDekBEyUjWuJSPgZeeQbb5wjvvKyF7rLvFU6Ar92gz3QNOLQ==",
+      "dependencies": {
+        "@astral-sh/ruff-wasm-web": "0.6.4",
+        "@deephaven/chart": "^0.97.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/jsapi-bootstrap": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "classnames": "^2.3.1",
         "linkifyjs": "^4.1.0",
@@ -2438,7 +2445,7 @@
         "lodash.throttle": "^4.1.1",
         "memoize-one": "^5.1.1",
         "memoizee": "^0.4.15",
-        "monaco-editor": "^0.41.0",
+        "monaco-editor": "^0.43.0",
         "nanoid": "^5.0.7",
         "papaparse": "5.3.2",
         "popper.js": "^1.16.1",
@@ -2454,15 +2461,15 @@
       }
     },
     "node_modules/@deephaven/console/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -2496,15 +2503,15 @@
       }
     },
     "node_modules/@deephaven/console/node_modules/@deephaven/jsapi-bootstrap": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-      "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+      "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0"
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0"
       },
       "engines": {
         "node": ">=16"
@@ -2514,14 +2521,30 @@
       }
     },
     "node_modules/@deephaven/console/node_modules/@deephaven/jsapi-types": {
-      "version": "1.0.0-dev0.35.2",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-      "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+      "version": "1.0.0-dev0.36.1",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+      "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
+    },
+    "node_modules/@deephaven/console/node_modules/@deephaven/jsapi-utils": {
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+      "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
+      "dependencies": {
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
+        "lodash.clamp": "^4.0.3",
+        "nanoid": "^5.0.7"
+      },
+      "engines": {
+        "node": ">=16"
+      }
     },
     "node_modules/@deephaven/console/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -2530,9 +2553,9 @@
       }
     },
     "node_modules/@deephaven/console/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -2548,6 +2571,11 @@
         "url": "https://github.com/sponsors/mysticatea"
       }
     },
+    "node_modules/@deephaven/console/node_modules/monaco-editor": {
+      "version": "0.43.0",
+      "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.43.0.tgz",
+      "integrity": "sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q=="
+    },
     "node_modules/@deephaven/dashboard": {
       "version": "0.40.4",
       "license": "Apache-2.0",
@@ -2575,30 +2603,30 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.88.0.tgz",
-      "integrity": "sha512-bdS6fLYruSpOLUJoE3fv3ohUvW96I81bL7in+kw1u7GweZiFBqvNA69FU+7J0mP5uAeZp8KBXo1AoGKpHk5rFQ==",
-      "dependencies": {
-        "@deephaven/chart": "^0.88.0",
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/console": "^0.88.0",
-        "@deephaven/dashboard": "^0.88.0",
-        "@deephaven/file-explorer": "^0.88.0",
-        "@deephaven/filters": "^0.88.0",
-        "@deephaven/golden-layout": "^0.88.0",
-        "@deephaven/grid": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/iris-grid": "^0.88.0",
-        "@deephaven/jsapi-bootstrap": "^0.88.0",
-        "@deephaven/jsapi-components": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.97.0.tgz",
+      "integrity": "sha512-rUPL9FnHLRisLJJp4G52ys1/Sw2HjSz1mnQVMVfKwew29gCT3QNLK01kcuuIWqe4Yu122YVFLSU6Px8kFjyT/Q==",
+      "dependencies": {
+        "@deephaven/chart": "^0.97.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/console": "^0.97.0",
+        "@deephaven/dashboard": "^0.97.0",
+        "@deephaven/file-explorer": "^0.97.0",
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/golden-layout": "^0.97.0",
+        "@deephaven/grid": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/iris-grid": "^0.97.0",
+        "@deephaven/jsapi-bootstrap": "^0.97.0",
+        "@deephaven/jsapi-components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/plugin": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/redux": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/plugin": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/redux": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "classnames": "^2.3.1",
         "fast-deep-equal": "^3.1.3",
@@ -2626,15 +2654,15 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -2668,16 +2696,16 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/dashboard": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.88.0.tgz",
-      "integrity": "sha512-TFQK3jhJB1L85Pg2rvsfwgHKmZfjanNfQvNconfKTMDMRaeADRL+KnDvHedRHesJNcjRs1lO3Tlt/qrMTv0aEQ==",
-      "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/golden-layout": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/redux": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.97.0.tgz",
+      "integrity": "sha512-eLbNEJryrdwaZ9fYNtj/I4IqAxTSSX9OIVWf1wLZTCGtw7CLahA5DG68aCEoZkZlakHTyJTt7j9XyR5HjyxrYA==",
+      "dependencies": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/golden-layout": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/redux": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "fast-deep-equal": "^3.1.3",
         "lodash.ismatch": "^4.1.1",
         "lodash.throttle": "^4.1.1",
@@ -2694,11 +2722,11 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/golden-layout": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.88.0.tgz",
-      "integrity": "sha512-30SuCWmbRUxaJVR66D3sHwiEq2XHrEjzyT7Tg0pNutH/iD+2XIY5rAZyTqepX4cmSjBuBEOPVva7bf2R8+ZHTA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.97.0.tgz",
+      "integrity": "sha512-i5vvqHMmnmXwOPExTWDR2D58Ej3ZBS67F+wWP4sDRNYNUvwVqsAEAcr+kz6Ggoe141WZGeBvzeIOe9G1aAYxmg==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "jquery": "^3.6.0",
         "nanoid": "^5.0.7"
       },
@@ -2708,15 +2736,15 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/jsapi-bootstrap": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-      "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+      "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0"
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0"
       },
       "engines": {
         "node": ">=16"
@@ -2726,17 +2754,17 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/jsapi-components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.88.0.tgz",
-      "integrity": "sha512-As2Gj6zH7qJabM5C6Qo/r0uBacf4u97o++7OHxI4mUn/PohUJV2tF8T8C9z0BCSype5sqw3k0U4/Dq2zoU9WgQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.97.0.tgz",
+      "integrity": "sha512-vLJWQAYV8UM7Yni0qwZ8PDVhY+Z7DD9mQVcoEBVMl9onePSEO9lmtWvo874VTcsklQ1eMTEvildFaarFqvSN+g==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/jsapi-bootstrap": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/jsapi-bootstrap": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@types/js-cookie": "^3.0.3",
         "classnames": "^2.3.2",
         "js-cookie": "^3.0.5",
@@ -2751,19 +2779,19 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/jsapi-types": {
-      "version": "1.0.0-dev0.35.2",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-      "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+      "version": "1.0.0-dev0.36.1",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+      "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/jsapi-utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-      "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+      "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
       "dependencies": {
-        "@deephaven/filters": "^0.88.0",
+        "@deephaven/filters": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "lodash.clamp": "^4.0.3",
         "nanoid": "^5.0.7"
       },
@@ -2772,9 +2800,9 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -2783,14 +2811,14 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/redux": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.88.0.tgz",
-      "integrity": "sha512-Non+QSAxaZZjYZtwfaUXqnEQ9wNJkFwH9GPyuD3oJljYQxzO/LvcLznzMR6eKrCRCQWasv1X4BY6cbRWbI32HQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.97.0.tgz",
+      "integrity": "sha512-RhC5QJs2D/3wHQutctPkf+BFcTUwx7Q6fiwmUe5jE5GbhagZoPgv/0HYOkEJ4zOvl4hXY43GitysnXnJUD2d8A==",
       "dependencies": {
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/plugin": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/plugin": "^0.97.0",
         "fast-deep-equal": "^3.1.3",
         "proxy-memoize": "^3.0.0",
         "redux-thunk": "2.4.1"
@@ -2803,9 +2831,9 @@
       }
     },
     "node_modules/@deephaven/dashboard-core-plugins/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -2856,15 +2884,15 @@
       }
     },
     "node_modules/@deephaven/file-explorer": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.88.0.tgz",
-      "integrity": "sha512-VswIr1yIlwOzmEl2PQlQ72a8p+0xFlQGX5hld++ewKwhWlYNaVeyOHXkVigDKRuDGfLeD5Sn1d2IBEjWJ7Mc1w==",
-      "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.97.0.tgz",
+      "integrity": "sha512-Co9i1Ic/AYMPei/R7avJ4dU4IjQWLtKfJmHf66o03QhhuOL/arJSkrcJvHhqlCqhwAXMhZ4dJYhzeUtwIwErrg==",
+      "dependencies": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "classnames": "^2.3.1",
@@ -2879,15 +2907,15 @@
       }
     },
     "node_modules/@deephaven/file-explorer/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -2921,9 +2949,9 @@
       }
     },
     "node_modules/@deephaven/file-explorer/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -2932,9 +2960,9 @@
       }
     },
     "node_modules/@deephaven/file-explorer/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -2951,9 +2979,9 @@
       }
     },
     "node_modules/@deephaven/filters": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.88.0.tgz",
-      "integrity": "sha512-aOJ4pxx7+mhHj/nULwAgnhN78oxAjta0LI1LiLuqGxH6f6WV8fG6tN1tpuL4UbMx/TwT5Al5l/a9p51CaOZnBg==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.97.0.tgz",
+      "integrity": "sha512-kkMmGIqiIIr8RZC9dE7n95pIgp+WhUV1xQvqJQn9w4HZ46M6IV8BEbOAF7C8fBzlMWofkGDMcWU4BOnhyaz3PQ==",
       "engines": {
         "node": ">=16"
       }
@@ -2971,11 +2999,11 @@
       }
     },
     "node_modules/@deephaven/grid": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.88.0.tgz",
-      "integrity": "sha512-VR7Ts+uEjWhP809gElld2zSpherIxQz74ddTPPtHEdWSGtW51RXsws/5BlS8TIKStTxUrvMjmzGbAJij3SQ2aA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.97.0.tgz",
+      "integrity": "sha512-TP2zBiD8Tfj5CbmIbxxeh4764r7cLPHIjif0XfJhWm9WQR74QcKmU9h4Kc057WxXFGl1WCIJ/2hn5Eg6X2Dyew==",
       "dependencies": {
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/utils": "^0.97.0",
         "classnames": "^2.3.1",
         "color-convert": "^2.0.1",
         "event-target-shim": "^6.0.2",
@@ -2993,9 +3021,9 @@
       }
     },
     "node_modules/@deephaven/grid/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -3028,9 +3056,9 @@
       }
     },
     "node_modules/@deephaven/icons": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.88.0.tgz",
-      "integrity": "sha512-3B+CQJmpRbCGqf0B65ek77M59/kQLGr4TmSglYzTTGFrW6TbptO3Q9uTQ0LMIAhkHSDw6gjLUBR3DtVPzm3dUA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.97.0.tgz",
+      "integrity": "sha512-0WUPiuiXh//LGOd/L3PBT3xYiujScEEmJv4hpXJ4LbfJZezWrmqncDVaTsRwJ/lAzzJc6rmt4D16VaV406OgIA==",
       "dependencies": {
         "@fortawesome/fontawesome-common-types": "^6.1.1"
       },
@@ -3040,22 +3068,22 @@
       }
     },
     "node_modules/@deephaven/iris-grid": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.88.0.tgz",
-      "integrity": "sha512-LJIGuP8PiwK8L1yok/IJtMIWpcU5+/T1FHPtfzwsXydRhAKnhUX+/KLaomD8IFFt5wGCQjimlwRGfeQ+fEPdMg==",
-      "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/console": "^0.88.0",
-        "@deephaven/filters": "^0.88.0",
-        "@deephaven/grid": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/jsapi-components": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.97.0.tgz",
+      "integrity": "sha512-8PPKCydfXRvsB3oZkq5cl2P2rV5oQH9RIPcpwRP65SYkpTbxnNWoEvVtD4IGOiaudn6nE3bAeJhj69u/oJGlrw==",
+      "dependencies": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/console": "^0.97.0",
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/grid": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/jsapi-components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@dnd-kit/core": "^6.1.0",
         "@dnd-kit/sortable": "^7.0.2",
         "@dnd-kit/utilities": "^3.2.2",
@@ -3067,7 +3095,7 @@
         "lodash.throttle": "^4.1.1",
         "memoize-one": "^5.1.1",
         "memoizee": "^0.4.15",
-        "monaco-editor": "^0.41.0",
+        "monaco-editor": "^0.43.0",
         "nanoid": "^5.0.7",
         "prop-types": "^15.7.2",
         "react-beautiful-dnd": "^13.1.0",
@@ -3082,15 +3110,15 @@
       }
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -3124,15 +3152,15 @@
       }
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/jsapi-bootstrap": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-      "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+      "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0"
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0"
       },
       "engines": {
         "node": ">=16"
@@ -3142,17 +3170,17 @@
       }
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/jsapi-components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.88.0.tgz",
-      "integrity": "sha512-As2Gj6zH7qJabM5C6Qo/r0uBacf4u97o++7OHxI4mUn/PohUJV2tF8T8C9z0BCSype5sqw3k0U4/Dq2zoU9WgQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.97.0.tgz",
+      "integrity": "sha512-vLJWQAYV8UM7Yni0qwZ8PDVhY+Z7DD9mQVcoEBVMl9onePSEO9lmtWvo874VTcsklQ1eMTEvildFaarFqvSN+g==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/jsapi-bootstrap": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/jsapi-bootstrap": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@types/js-cookie": "^3.0.3",
         "classnames": "^2.3.2",
         "js-cookie": "^3.0.5",
@@ -3167,19 +3195,19 @@
       }
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/jsapi-types": {
-      "version": "1.0.0-dev0.35.2",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-      "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+      "version": "1.0.0-dev0.36.1",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+      "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/jsapi-utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-      "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+      "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
       "dependencies": {
-        "@deephaven/filters": "^0.88.0",
+        "@deephaven/filters": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "lodash.clamp": "^4.0.3",
         "nanoid": "^5.0.7"
       },
@@ -3188,9 +3216,9 @@
       }
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -3199,9 +3227,9 @@
       }
     },
     "node_modules/@deephaven/iris-grid/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -3217,6 +3245,11 @@
         "url": "https://github.com/sponsors/mysticatea"
       }
     },
+    "node_modules/@deephaven/iris-grid/node_modules/monaco-editor": {
+      "version": "0.43.0",
+      "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.43.0.tgz",
+      "integrity": "sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q=="
+    },
     "node_modules/@deephaven/js-plugin-auth-keycloak": {
       "resolved": "plugins/auth-keycloak/src/js",
       "link": true
@@ -3367,17 +3400,18 @@
       }
     },
     "node_modules/@deephaven/plugin": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.88.0.tgz",
-      "integrity": "sha512-yV5dIsfFyIfxOARligKeC64TskpuKKvtDm242RUvPO7UWuYHJt9RgN+Y9VC5MCY7dbOgZmX7xlz2TtMamYmUYQ==",
-      "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/golden-layout": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/iris-grid": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.97.0.tgz",
+      "integrity": "sha512-p+9OvdUC8z1VSCPoaFfEtwTcymPBPGsPscGmSd8qiy8+CYj4OmSd+aubhKlwolyT2CfL9w8e1O3MB8zZxWBxvA==",
+      "dependencies": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/golden-layout": "^0.97.0",
+        "@deephaven/grid": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/iris-grid": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
         "@fortawesome/fontawesome-common-types": "^6.1.1",
         "@fortawesome/react-fontawesome": "^0.2.0"
       },
@@ -3389,15 +3423,15 @@
       }
     },
     "node_modules/@deephaven/plugin/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -3431,11 +3465,11 @@
       }
     },
     "node_modules/@deephaven/plugin/node_modules/@deephaven/golden-layout": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.88.0.tgz",
-      "integrity": "sha512-30SuCWmbRUxaJVR66D3sHwiEq2XHrEjzyT7Tg0pNutH/iD+2XIY5rAZyTqepX4cmSjBuBEOPVva7bf2R8+ZHTA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.97.0.tgz",
+      "integrity": "sha512-i5vvqHMmnmXwOPExTWDR2D58Ej3ZBS67F+wWP4sDRNYNUvwVqsAEAcr+kz6Ggoe141WZGeBvzeIOe9G1aAYxmg==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "jquery": "^3.6.0",
         "nanoid": "^5.0.7"
       },
@@ -3445,13 +3479,14 @@
       }
     },
     "node_modules/@deephaven/plugin/node_modules/@deephaven/jsapi-types": {
-      "version": "1.0.0-dev0.34.0",
-      "license": "Apache-2.0"
+      "version": "1.0.0-dev0.36.1",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+      "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
     },
     "node_modules/@deephaven/plugin/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -3460,9 +3495,9 @@
       }
     },
     "node_modules/@deephaven/plugin/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -3487,13 +3522,13 @@
       }
     },
     "node_modules/@deephaven/react-hooks": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.88.0.tgz",
-      "integrity": "sha512-2nfDWZ2mU3uNMxBu5WOD+bie9svrEXYEdDWglkZqcb77ZrI9pcLiuybz4ybGnN/NNnweyqvHD0q3Mi+VqXDdyw==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.97.0.tgz",
+      "integrity": "sha512-h248fMsmaFohDEDjQDEusRA8+JHEqpYFevKqRmtvU4R4W+0k6w14cLabf36J8E1uaBsoSOMSb8wy+S8oLeJE1w==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "lodash.debounce": "^4.0.8",
         "lodash.throttle": "^4.1.1",
         "nanoid": "^5.0.7"
@@ -3506,9 +3541,9 @@
       }
     },
     "node_modules/@deephaven/react-hooks/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -3517,9 +3552,9 @@
       }
     },
     "node_modules/@deephaven/react-hooks/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -3553,12 +3588,12 @@
       }
     },
     "node_modules/@deephaven/storage": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.88.0.tgz",
-      "integrity": "sha512-SL1nNK6Qnap9il8L4URz5dklhzgdpqaJ1KqXyWZCSJe4GpOCfRQLbsaBIWR426AELXR38ZJ2nf3tWy0hiig/7w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.97.0.tgz",
+      "integrity": "sha512-SZTKfkd8CJkNoECXhWN+vfakVoblYbMcnRBwwXKHDXRjC4yw+D/BFS3XCDikyh6vfX8uANYfktCLS8kZ/4hiNg==",
       "dependencies": {
-        "@deephaven/filters": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
         "lodash.throttle": "^4.1.1"
       },
       "engines": {
@@ -3569,9 +3604,9 @@
       }
     },
     "node_modules/@deephaven/storage/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -31908,15 +31943,15 @@
       "version": "0.11.2",
       "license": "Apache-2.0",
       "dependencies": {
-        "@deephaven/chart": "0.88.0",
-        "@deephaven/components": "0.88.0",
-        "@deephaven/dashboard": "0.88.0",
-        "@deephaven/dashboard-core-plugins": "0.88.0",
-        "@deephaven/icons": "0.88.0",
-        "@deephaven/jsapi-bootstrap": "0.88.0",
-        "@deephaven/log": "0.88.0",
-        "@deephaven/plugin": "0.88.0",
-        "@deephaven/utils": "0.88.0",
+        "@deephaven/chart": "0.97.0",
+        "@deephaven/components": "0.97.0",
+        "@deephaven/dashboard": "0.97.0",
+        "@deephaven/dashboard-core-plugins": "0.97.0",
+        "@deephaven/icons": "0.97.0",
+        "@deephaven/jsapi-bootstrap": "0.97.0",
+        "@deephaven/log": "0.97.0",
+        "@deephaven/plugin": "0.97.0",
+        "@deephaven/utils": "0.97.0",
         "deep-equal": "^2.2.1",
         "nanoid": "^5.0.7",
         "plotly.js": "^2.29.1",
@@ -31925,7 +31960,8 @@
         "react-redux": "^7.2.9"
       },
       "devDependencies": {
-        "@deephaven/jsapi-types": "1.0.0-dev0.35.2",
+        "@deephaven/jsapi-types": "1.0.0-dev0.36.1",
+        "@deephaven/test-utils": "0.97.0",
         "@types/deep-equal": "^1.0.1",
         "@types/plotly.js": "^2.12.18",
         "@types/plotly.js-dist-min": "^2.3.1",
@@ -31941,15 +31977,15 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/components": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-      "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+      "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
       "dependencies": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "@internationalized/date": "^3.5.5",
@@ -31983,16 +32019,16 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/dashboard": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.88.0.tgz",
-      "integrity": "sha512-TFQK3jhJB1L85Pg2rvsfwgHKmZfjanNfQvNconfKTMDMRaeADRL+KnDvHedRHesJNcjRs1lO3Tlt/qrMTv0aEQ==",
-      "dependencies": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/golden-layout": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/redux": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.97.0.tgz",
+      "integrity": "sha512-eLbNEJryrdwaZ9fYNtj/I4IqAxTSSX9OIVWf1wLZTCGtw7CLahA5DG68aCEoZkZlakHTyJTt7j9XyR5HjyxrYA==",
+      "dependencies": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/golden-layout": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/redux": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "fast-deep-equal": "^3.1.3",
         "lodash.ismatch": "^4.1.1",
         "lodash.throttle": "^4.1.1",
@@ -32009,11 +32045,11 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/dashboard/node_modules/@deephaven/golden-layout": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.88.0.tgz",
-      "integrity": "sha512-30SuCWmbRUxaJVR66D3sHwiEq2XHrEjzyT7Tg0pNutH/iD+2XIY5rAZyTqepX4cmSjBuBEOPVva7bf2R8+ZHTA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.97.0.tgz",
+      "integrity": "sha512-i5vvqHMmnmXwOPExTWDR2D58Ej3ZBS67F+wWP4sDRNYNUvwVqsAEAcr+kz6Ggoe141WZGeBvzeIOe9G1aAYxmg==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "jquery": "^3.6.0",
         "nanoid": "^5.0.7"
       },
@@ -32023,15 +32059,15 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/jsapi-bootstrap": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-      "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+      "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
       "dependencies": {
-        "@deephaven/components": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0"
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0"
       },
       "engines": {
         "node": ">=16"
@@ -32041,19 +32077,19 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/jsapi-types": {
-      "version": "1.0.0-dev0.35.2",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-      "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+      "version": "1.0.0-dev0.36.1",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+      "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/jsapi-utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-      "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+      "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
       "dependencies": {
-        "@deephaven/filters": "^0.88.0",
+        "@deephaven/filters": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "lodash.clamp": "^4.0.3",
         "nanoid": "^5.0.7"
       },
@@ -32062,9 +32098,9 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/log": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-      "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+      "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
       "dependencies": {
         "event-target-shim": "^6.0.2"
       },
@@ -32073,14 +32109,14 @@
       }
     },
     "plugins/plotly-express/src/js/node_modules/@deephaven/redux": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.88.0.tgz",
-      "integrity": "sha512-Non+QSAxaZZjYZtwfaUXqnEQ9wNJkFwH9GPyuD3oJljYQxzO/LvcLznzMR6eKrCRCQWasv1X4BY6cbRWbI32HQ==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.97.0.tgz",
+      "integrity": "sha512-RhC5QJs2D/3wHQutctPkf+BFcTUwx7Q6fiwmUe5jE5GbhagZoPgv/0HYOkEJ4zOvl4hXY43GitysnXnJUD2d8A==",
       "dependencies": {
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/plugin": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/plugin": "^0.97.0",
         "fast-deep-equal": "^3.1.3",
         "proxy-memoize": "^3.0.0",
         "redux-thunk": "2.4.1"
@@ -32092,10 +32128,19 @@
         "redux": "^4.2.0"
       }
     },
+    "plugins/plotly-express/src/js/node_modules/@deephaven/test-utils": {
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/test-utils/-/test-utils-0.97.0.tgz",
+      "integrity": "sha512-OYRe7gArImzV/bz2ROHWRHiStokFZqRaFuP7PfzZM5yYg23igWKOMJ425sgGMxPzJxMru03qdbsnQLM3BJGOiA==",
+      "dev": true,
+      "engines": {
+        "node": ">=16"
+      }
+    },
     "plugins/plotly-express/src/js/node_modules/@deephaven/utils": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-      "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+      "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw==",
       "engines": {
         "node": ">=16"
       }
@@ -32879,6 +32924,11 @@
         "@jridgewell/trace-mapping": "^0.3.9"
       }
     },
+    "@astral-sh/ruff-wasm-web": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/@astral-sh/ruff-wasm-web/-/ruff-wasm-web-0.6.4.tgz",
+      "integrity": "sha512-IzXhcOU8McbU0cPDuU8iBaYa0SLEzFmIN5G0QnnXWu9vdWUcsnWcPpjJRFItmTk0kEibagCoCHc+39aAyD6XIw=="
+    },
     "@babel/code-frame": {
       "version": "7.23.5",
       "dev": true,
@@ -34054,17 +34104,17 @@
       }
     },
     "@deephaven/chart": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.88.0.tgz",
-      "integrity": "sha512-t0m2GE+o46pnyPLiF3gNbqxsrasoKKB37E5eFgyncmfye3JjYAoDEjdKZfp/ck4zHE68tO7N+e7fbyqju5Edpw==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/chart/-/chart-0.97.0.tgz",
+      "integrity": "sha512-6N8+K0LmNGfB/YhIa670qSmgDnxYeMO3B5q3FYSs6iF51VkrG431YLhAoQGTcgNglSpvxGNH+qldLadIDn4baA==",
       "requires": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "buffer": "^6.0.3",
         "fast-deep-equal": "^3.1.3",
         "lodash.debounce": "^4.0.8",
@@ -34077,15 +34127,15 @@
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -34111,35 +34161,35 @@
           }
         },
         "@deephaven/jsapi-types": {
-          "version": "1.0.0-dev0.35.2",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-          "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+          "version": "1.0.0-dev0.36.1",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+          "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
         },
         "@deephaven/jsapi-utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-          "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+          "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
           "requires": {
-            "@deephaven/filters": "^0.88.0",
+            "@deephaven/filters": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "lodash.clamp": "^4.0.3",
             "nanoid": "^5.0.7"
           }
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "buffer": {
           "version": "6.0.3",
@@ -34203,19 +34253,21 @@
       }
     },
     "@deephaven/console": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.88.0.tgz",
-      "integrity": "sha512-RKyGJSXTxiFapPej5BnoHakgil9ATU9Xjt2nwZ5x630ATu9f6k3xfeHpOxeuvcr6IjdUsvPcMk74y5IRAOatJA==",
-      "requires": {
-        "@deephaven/chart": "^0.88.0",
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/jsapi-bootstrap": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/console/-/console-0.97.0.tgz",
+      "integrity": "sha512-3/y/uV0OME2XOgR62drVdFwF7fIvuUZrDl6G66PDekBEyUjWuJSPgZeeQbb5wjvvKyF7rLvFU6Ar92gz3QNOLQ==",
+      "requires": {
+        "@astral-sh/ruff-wasm-web": "0.6.4",
+        "@deephaven/chart": "^0.97.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/jsapi-bootstrap": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "classnames": "^2.3.1",
         "linkifyjs": "^4.1.0",
@@ -34223,7 +34275,7 @@
         "lodash.throttle": "^4.1.1",
         "memoize-one": "^5.1.1",
         "memoizee": "^0.4.15",
-        "monaco-editor": "^0.41.0",
+        "monaco-editor": "^0.43.0",
         "nanoid": "^5.0.7",
         "papaparse": "5.3.2",
         "popper.js": "^1.16.1",
@@ -34232,15 +34284,15 @@
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -34266,39 +34318,57 @@
           }
         },
         "@deephaven/jsapi-bootstrap": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-          "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+          "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0"
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0"
           }
         },
         "@deephaven/jsapi-types": {
-          "version": "1.0.0-dev0.35.2",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-          "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+          "version": "1.0.0-dev0.36.1",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+          "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
+        },
+        "@deephaven/jsapi-utils": {
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+          "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
+          "requires": {
+            "@deephaven/filters": "^0.97.0",
+            "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
+            "lodash.clamp": "^4.0.3",
+            "nanoid": "^5.0.7"
+          }
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2",
           "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-6.0.2.tgz",
           "integrity": "sha512-8q3LsZjRezbFZ2PN+uP+Q7pnHUMmAOziU2vA2OwoFaKIXxlxl38IylhSSgUorWu/rf4er67w0ikBqjBFk/pomA=="
+        },
+        "monaco-editor": {
+          "version": "0.43.0",
+          "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.43.0.tgz",
+          "integrity": "sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q=="
         }
       }
     },
@@ -34330,30 +34400,30 @@
       }
     },
     "@deephaven/dashboard-core-plugins": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.88.0.tgz",
-      "integrity": "sha512-bdS6fLYruSpOLUJoE3fv3ohUvW96I81bL7in+kw1u7GweZiFBqvNA69FU+7J0mP5uAeZp8KBXo1AoGKpHk5rFQ==",
-      "requires": {
-        "@deephaven/chart": "^0.88.0",
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/console": "^0.88.0",
-        "@deephaven/dashboard": "^0.88.0",
-        "@deephaven/file-explorer": "^0.88.0",
-        "@deephaven/filters": "^0.88.0",
-        "@deephaven/golden-layout": "^0.88.0",
-        "@deephaven/grid": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/iris-grid": "^0.88.0",
-        "@deephaven/jsapi-bootstrap": "^0.88.0",
-        "@deephaven/jsapi-components": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/dashboard-core-plugins/-/dashboard-core-plugins-0.97.0.tgz",
+      "integrity": "sha512-rUPL9FnHLRisLJJp4G52ys1/Sw2HjSz1mnQVMVfKwew29gCT3QNLK01kcuuIWqe4Yu122YVFLSU6Px8kFjyT/Q==",
+      "requires": {
+        "@deephaven/chart": "^0.97.0",
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/console": "^0.97.0",
+        "@deephaven/dashboard": "^0.97.0",
+        "@deephaven/file-explorer": "^0.97.0",
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/golden-layout": "^0.97.0",
+        "@deephaven/grid": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/iris-grid": "^0.97.0",
+        "@deephaven/jsapi-bootstrap": "^0.97.0",
+        "@deephaven/jsapi-components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/plugin": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/redux": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/plugin": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/redux": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "classnames": "^2.3.1",
         "fast-deep-equal": "^3.1.3",
@@ -34373,15 +34443,15 @@
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -34407,16 +34477,16 @@
           }
         },
         "@deephaven/dashboard": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.88.0.tgz",
-          "integrity": "sha512-TFQK3jhJB1L85Pg2rvsfwgHKmZfjanNfQvNconfKTMDMRaeADRL+KnDvHedRHesJNcjRs1lO3Tlt/qrMTv0aEQ==",
-          "requires": {
-            "@deephaven/components": "^0.88.0",
-            "@deephaven/golden-layout": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/redux": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.97.0.tgz",
+          "integrity": "sha512-eLbNEJryrdwaZ9fYNtj/I4IqAxTSSX9OIVWf1wLZTCGtw7CLahA5DG68aCEoZkZlakHTyJTt7j9XyR5HjyxrYA==",
+          "requires": {
+            "@deephaven/components": "^0.97.0",
+            "@deephaven/golden-layout": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/redux": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "fast-deep-equal": "^3.1.3",
             "lodash.ismatch": "^4.1.1",
             "lodash.throttle": "^4.1.1",
@@ -34425,39 +34495,39 @@
           }
         },
         "@deephaven/golden-layout": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.88.0.tgz",
-          "integrity": "sha512-30SuCWmbRUxaJVR66D3sHwiEq2XHrEjzyT7Tg0pNutH/iD+2XIY5rAZyTqepX4cmSjBuBEOPVva7bf2R8+ZHTA==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.97.0.tgz",
+          "integrity": "sha512-i5vvqHMmnmXwOPExTWDR2D58Ej3ZBS67F+wWP4sDRNYNUvwVqsAEAcr+kz6Ggoe141WZGeBvzeIOe9G1aAYxmg==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
             "jquery": "^3.6.0",
             "nanoid": "^5.0.7"
           }
         },
         "@deephaven/jsapi-bootstrap": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-          "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+          "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0"
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0"
           }
         },
         "@deephaven/jsapi-components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.88.0.tgz",
-          "integrity": "sha512-As2Gj6zH7qJabM5C6Qo/r0uBacf4u97o++7OHxI4mUn/PohUJV2tF8T8C9z0BCSype5sqw3k0U4/Dq2zoU9WgQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.97.0.tgz",
+          "integrity": "sha512-vLJWQAYV8UM7Yni0qwZ8PDVhY+Z7DD9mQVcoEBVMl9onePSEO9lmtWvo874VTcsklQ1eMTEvildFaarFqvSN+g==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
-            "@deephaven/jsapi-bootstrap": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
+            "@deephaven/jsapi-bootstrap": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/jsapi-utils": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/jsapi-utils": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@types/js-cookie": "^3.0.3",
             "classnames": "^2.3.2",
             "js-cookie": "^3.0.5",
@@ -34466,49 +34536,49 @@
           }
         },
         "@deephaven/jsapi-types": {
-          "version": "1.0.0-dev0.35.2",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-          "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+          "version": "1.0.0-dev0.36.1",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+          "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
         },
         "@deephaven/jsapi-utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-          "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+          "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
           "requires": {
-            "@deephaven/filters": "^0.88.0",
+            "@deephaven/filters": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "lodash.clamp": "^4.0.3",
             "nanoid": "^5.0.7"
           }
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/redux": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.88.0.tgz",
-          "integrity": "sha512-Non+QSAxaZZjYZtwfaUXqnEQ9wNJkFwH9GPyuD3oJljYQxzO/LvcLznzMR6eKrCRCQWasv1X4BY6cbRWbI32HQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.97.0.tgz",
+          "integrity": "sha512-RhC5QJs2D/3wHQutctPkf+BFcTUwx7Q6fiwmUe5jE5GbhagZoPgv/0HYOkEJ4zOvl4hXY43GitysnXnJUD2d8A==",
           "requires": {
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/jsapi-utils": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/plugin": "^0.88.0",
+            "@deephaven/jsapi-utils": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/plugin": "^0.97.0",
             "fast-deep-equal": "^3.1.3",
             "proxy-memoize": "^3.0.0",
             "redux-thunk": "2.4.1"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2",
@@ -34527,15 +34597,15 @@
       }
     },
     "@deephaven/file-explorer": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.88.0.tgz",
-      "integrity": "sha512-VswIr1yIlwOzmEl2PQlQ72a8p+0xFlQGX5hld++ewKwhWlYNaVeyOHXkVigDKRuDGfLeD5Sn1d2IBEjWJ7Mc1w==",
-      "requires": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/file-explorer/-/file-explorer-0.97.0.tgz",
+      "integrity": "sha512-Co9i1Ic/AYMPei/R7avJ4dU4IjQWLtKfJmHf66o03QhhuOL/arJSkrcJvHhqlCqhwAXMhZ4dJYhzeUtwIwErrg==",
+      "requires": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@fortawesome/fontawesome-svg-core": "^6.2.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
         "classnames": "^2.3.1",
@@ -34544,15 +34614,15 @@
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -34578,17 +34648,17 @@
           }
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2",
@@ -34598,9 +34668,9 @@
       }
     },
     "@deephaven/filters": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.88.0.tgz",
-      "integrity": "sha512-aOJ4pxx7+mhHj/nULwAgnhN78oxAjta0LI1LiLuqGxH6f6WV8fG6tN1tpuL4UbMx/TwT5Al5l/a9p51CaOZnBg=="
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/filters/-/filters-0.97.0.tgz",
+      "integrity": "sha512-kkMmGIqiIIr8RZC9dE7n95pIgp+WhUV1xQvqJQn9w4HZ46M6IV8BEbOAF7C8fBzlMWofkGDMcWU4BOnhyaz3PQ=="
     },
     "@deephaven/golden-layout": {
       "version": "0.40.4",
@@ -34610,11 +34680,11 @@
       }
     },
     "@deephaven/grid": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.88.0.tgz",
-      "integrity": "sha512-VR7Ts+uEjWhP809gElld2zSpherIxQz74ddTPPtHEdWSGtW51RXsws/5BlS8TIKStTxUrvMjmzGbAJij3SQ2aA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/grid/-/grid-0.97.0.tgz",
+      "integrity": "sha512-TP2zBiD8Tfj5CbmIbxxeh4764r7cLPHIjif0XfJhWm9WQR74QcKmU9h4Kc057WxXFGl1WCIJ/2hn5Eg6X2Dyew==",
       "requires": {
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/utils": "^0.97.0",
         "classnames": "^2.3.1",
         "color-convert": "^2.0.1",
         "event-target-shim": "^6.0.2",
@@ -34626,9 +34696,9 @@
       },
       "dependencies": {
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "color-convert": {
           "version": "2.0.1",
@@ -34651,30 +34721,30 @@
       }
     },
     "@deephaven/icons": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.88.0.tgz",
-      "integrity": "sha512-3B+CQJmpRbCGqf0B65ek77M59/kQLGr4TmSglYzTTGFrW6TbptO3Q9uTQ0LMIAhkHSDw6gjLUBR3DtVPzm3dUA==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/icons/-/icons-0.97.0.tgz",
+      "integrity": "sha512-0WUPiuiXh//LGOd/L3PBT3xYiujScEEmJv4hpXJ4LbfJZezWrmqncDVaTsRwJ/lAzzJc6rmt4D16VaV406OgIA==",
       "requires": {
         "@fortawesome/fontawesome-common-types": "^6.1.1"
       }
     },
     "@deephaven/iris-grid": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.88.0.tgz",
-      "integrity": "sha512-LJIGuP8PiwK8L1yok/IJtMIWpcU5+/T1FHPtfzwsXydRhAKnhUX+/KLaomD8IFFt5wGCQjimlwRGfeQ+fEPdMg==",
-      "requires": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/console": "^0.88.0",
-        "@deephaven/filters": "^0.88.0",
-        "@deephaven/grid": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/jsapi-components": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/iris-grid/-/iris-grid-0.97.0.tgz",
+      "integrity": "sha512-8PPKCydfXRvsB3oZkq5cl2P2rV5oQH9RIPcpwRP65SYkpTbxnNWoEvVtD4IGOiaudn6nE3bAeJhj69u/oJGlrw==",
+      "requires": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/console": "^0.97.0",
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/grid": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/jsapi-components": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/jsapi-utils": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
-        "@deephaven/storage": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/jsapi-utils": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
+        "@deephaven/storage": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "@dnd-kit/core": "^6.1.0",
         "@dnd-kit/sortable": "^7.0.2",
         "@dnd-kit/utilities": "^3.2.2",
@@ -34686,7 +34756,7 @@
         "lodash.throttle": "^4.1.1",
         "memoize-one": "^5.1.1",
         "memoizee": "^0.4.15",
-        "monaco-editor": "^0.41.0",
+        "monaco-editor": "^0.43.0",
         "nanoid": "^5.0.7",
         "prop-types": "^15.7.2",
         "react-beautiful-dnd": "^13.1.0",
@@ -34694,15 +34764,15 @@
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -34728,29 +34798,29 @@
           }
         },
         "@deephaven/jsapi-bootstrap": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-          "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+          "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0"
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0"
           }
         },
         "@deephaven/jsapi-components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.88.0.tgz",
-          "integrity": "sha512-As2Gj6zH7qJabM5C6Qo/r0uBacf4u97o++7OHxI4mUn/PohUJV2tF8T8C9z0BCSype5sqw3k0U4/Dq2zoU9WgQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-components/-/jsapi-components-0.97.0.tgz",
+          "integrity": "sha512-vLJWQAYV8UM7Yni0qwZ8PDVhY+Z7DD9mQVcoEBVMl9onePSEO9lmtWvo874VTcsklQ1eMTEvildFaarFqvSN+g==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
-            "@deephaven/jsapi-bootstrap": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
+            "@deephaven/jsapi-bootstrap": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/jsapi-utils": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/jsapi-utils": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@types/js-cookie": "^3.0.3",
             "classnames": "^2.3.2",
             "js-cookie": "^3.0.5",
@@ -34759,40 +34829,45 @@
           }
         },
         "@deephaven/jsapi-types": {
-          "version": "1.0.0-dev0.35.2",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-          "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+          "version": "1.0.0-dev0.36.1",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+          "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
         },
         "@deephaven/jsapi-utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-          "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+          "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
           "requires": {
-            "@deephaven/filters": "^0.88.0",
+            "@deephaven/filters": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "lodash.clamp": "^4.0.3",
             "nanoid": "^5.0.7"
           }
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2",
           "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-6.0.2.tgz",
           "integrity": "sha512-8q3LsZjRezbFZ2PN+uP+Q7pnHUMmAOziU2vA2OwoFaKIXxlxl38IylhSSgUorWu/rf4er67w0ikBqjBFk/pomA=="
+        },
+        "monaco-editor": {
+          "version": "0.43.0",
+          "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.43.0.tgz",
+          "integrity": "sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q=="
         }
       }
     },
@@ -35648,16 +35723,17 @@
     "@deephaven/js-plugin-plotly-express": {
       "version": "file:plugins/plotly-express/src/js",
       "requires": {
-        "@deephaven/chart": "0.88.0",
-        "@deephaven/components": "0.88.0",
-        "@deephaven/dashboard": "0.88.0",
-        "@deephaven/dashboard-core-plugins": "0.88.0",
-        "@deephaven/icons": "0.88.0",
-        "@deephaven/jsapi-bootstrap": "0.88.0",
-        "@deephaven/jsapi-types": "1.0.0-dev0.35.2",
-        "@deephaven/log": "0.88.0",
-        "@deephaven/plugin": "0.88.0",
-        "@deephaven/utils": "0.88.0",
+        "@deephaven/chart": "0.97.0",
+        "@deephaven/components": "0.97.0",
+        "@deephaven/dashboard": "0.97.0",
+        "@deephaven/dashboard-core-plugins": "0.97.0",
+        "@deephaven/icons": "0.97.0",
+        "@deephaven/jsapi-bootstrap": "0.97.0",
+        "@deephaven/jsapi-types": "1.0.0-dev0.36.1",
+        "@deephaven/log": "0.97.0",
+        "@deephaven/plugin": "0.97.0",
+        "@deephaven/test-utils": "0.97.0",
+        "@deephaven/utils": "0.97.0",
         "@types/deep-equal": "^1.0.1",
         "@types/plotly.js": "^2.12.18",
         "@types/plotly.js-dist-min": "^2.3.1",
@@ -35675,15 +35751,15 @@
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -35709,16 +35785,16 @@
           }
         },
         "@deephaven/dashboard": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.88.0.tgz",
-          "integrity": "sha512-TFQK3jhJB1L85Pg2rvsfwgHKmZfjanNfQvNconfKTMDMRaeADRL+KnDvHedRHesJNcjRs1lO3Tlt/qrMTv0aEQ==",
-          "requires": {
-            "@deephaven/components": "^0.88.0",
-            "@deephaven/golden-layout": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/redux": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/dashboard/-/dashboard-0.97.0.tgz",
+          "integrity": "sha512-eLbNEJryrdwaZ9fYNtj/I4IqAxTSSX9OIVWf1wLZTCGtw7CLahA5DG68aCEoZkZlakHTyJTt7j9XyR5HjyxrYA==",
+          "requires": {
+            "@deephaven/components": "^0.97.0",
+            "@deephaven/golden-layout": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/redux": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "fast-deep-equal": "^3.1.3",
             "lodash.ismatch": "^4.1.1",
             "lodash.throttle": "^4.1.1",
@@ -35727,11 +35803,11 @@
           },
           "dependencies": {
             "@deephaven/golden-layout": {
-              "version": "0.88.0",
-              "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.88.0.tgz",
-              "integrity": "sha512-30SuCWmbRUxaJVR66D3sHwiEq2XHrEjzyT7Tg0pNutH/iD+2XIY5rAZyTqepX4cmSjBuBEOPVva7bf2R8+ZHTA==",
+              "version": "0.97.0",
+              "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.97.0.tgz",
+              "integrity": "sha512-i5vvqHMmnmXwOPExTWDR2D58Ej3ZBS67F+wWP4sDRNYNUvwVqsAEAcr+kz6Ggoe141WZGeBvzeIOe9G1aAYxmg==",
               "requires": {
-                "@deephaven/components": "^0.88.0",
+                "@deephaven/components": "^0.97.0",
                 "jquery": "^3.6.0",
                 "nanoid": "^5.0.7"
               }
@@ -35739,61 +35815,67 @@
           }
         },
         "@deephaven/jsapi-bootstrap": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.88.0.tgz",
-          "integrity": "sha512-M2/nIQ69MfAruEQnT5ZG1bN/bZWAlNZD81AjlZ319kOZsYqwOhOoeGsFRFfOpjWeB8PZsUTmN2ukg4NOXVgH8A==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-bootstrap/-/jsapi-bootstrap-0.97.0.tgz",
+          "integrity": "sha512-4q0boBFTD1XIjsbO6Wg53a4fZnoByo5VebusKX7+Kj++Q4uAt3aZ9xHMii3OxEXMhreR+3tsXnpfXbwmC2mNnA==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0"
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0"
           }
         },
         "@deephaven/jsapi-types": {
-          "version": "1.0.0-dev0.35.2",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.35.2.tgz",
-          "integrity": "sha512-VM1WAps/+KEXdxIiaEGutcjgaf5p1LNf6AA+Hv7sTIaENYYJpndZqD6bGFcuuiUVTYDlnFF0hohN4l6lOsjcQw=="
+          "version": "1.0.0-dev0.36.1",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+          "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
         },
         "@deephaven/jsapi-utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.88.0.tgz",
-          "integrity": "sha512-12vAmMzltyJZ3vJJlV6CbnII29XEBoCqCdI8xZcMaHJiqjgoL9A7YV7GIWClzGZrFZMY7voeHJDkLReH0rpszQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-utils/-/jsapi-utils-0.97.0.tgz",
+          "integrity": "sha512-jMOMUPjpstuKKTpUVJj0t9ymi4MErXTkJqTZzWPehKlC71TVvFYqvw8KzmOFkMPOQZ/GALH0EUZYu5rLg7AtXQ==",
           "requires": {
-            "@deephaven/filters": "^0.88.0",
+            "@deephaven/filters": "^0.97.0",
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "lodash.clamp": "^4.0.3",
             "nanoid": "^5.0.7"
           }
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/redux": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.88.0.tgz",
-          "integrity": "sha512-Non+QSAxaZZjYZtwfaUXqnEQ9wNJkFwH9GPyuD3oJljYQxzO/LvcLznzMR6eKrCRCQWasv1X4BY6cbRWbI32HQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/redux/-/redux-0.97.0.tgz",
+          "integrity": "sha512-RhC5QJs2D/3wHQutctPkf+BFcTUwx7Q6fiwmUe5jE5GbhagZoPgv/0HYOkEJ4zOvl4hXY43GitysnXnJUD2d8A==",
           "requires": {
             "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-            "@deephaven/jsapi-utils": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/plugin": "^0.88.0",
+            "@deephaven/jsapi-utils": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/plugin": "^0.97.0",
             "fast-deep-equal": "^3.1.3",
             "proxy-memoize": "^3.0.0",
             "redux-thunk": "2.4.1"
           }
         },
+        "@deephaven/test-utils": {
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/test-utils/-/test-utils-0.97.0.tgz",
+          "integrity": "sha512-OYRe7gArImzV/bz2ROHWRHiStokFZqRaFuP7PfzZM5yYg23igWKOMJ425sgGMxPzJxMru03qdbsnQLM3BJGOiA==",
+          "dev": true
+        },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2"
@@ -36358,31 +36440,32 @@
       }
     },
     "@deephaven/plugin": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.88.0.tgz",
-      "integrity": "sha512-yV5dIsfFyIfxOARligKeC64TskpuKKvtDm242RUvPO7UWuYHJt9RgN+Y9VC5MCY7dbOgZmX7xlz2TtMamYmUYQ==",
-      "requires": {
-        "@deephaven/components": "^0.88.0",
-        "@deephaven/golden-layout": "^0.88.0",
-        "@deephaven/icons": "^0.88.0",
-        "@deephaven/iris-grid": "^0.88.0",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/plugin/-/plugin-0.97.0.tgz",
+      "integrity": "sha512-p+9OvdUC8z1VSCPoaFfEtwTcymPBPGsPscGmSd8qiy8+CYj4OmSd+aubhKlwolyT2CfL9w8e1O3MB8zZxWBxvA==",
+      "requires": {
+        "@deephaven/components": "^0.97.0",
+        "@deephaven/golden-layout": "^0.97.0",
+        "@deephaven/grid": "^0.97.0",
+        "@deephaven/icons": "^0.97.0",
+        "@deephaven/iris-grid": "^0.97.0",
         "@deephaven/jsapi-types": "^1.0.0-dev0.34.0",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/react-hooks": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/react-hooks": "^0.97.0",
         "@fortawesome/fontawesome-common-types": "^6.1.1",
         "@fortawesome/react-fontawesome": "^0.2.0"
       },
       "dependencies": {
         "@deephaven/components": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.88.0.tgz",
-          "integrity": "sha512-2GrvHOZmRrkuuisVxV1QD0U23OgIhuRXjvUTSNksOlXHd5pElZBIXQCzRfC/dnPMDnfHoV6sHC9aJHTvaSRk2w==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/components/-/components-0.97.0.tgz",
+          "integrity": "sha512-jR7/cvyOQViBdT/VwsmU02wb3ekwC0dQTbFOoWtMifiB8YvZV/TeTN6sla6RUAwSw2ntmYoT95ZFJ8MoEijxOQ==",
           "requires": {
             "@adobe/react-spectrum": "3.35.1",
-            "@deephaven/icons": "^0.88.0",
-            "@deephaven/log": "^0.88.0",
-            "@deephaven/react-hooks": "^0.88.0",
-            "@deephaven/utils": "^0.88.0",
+            "@deephaven/icons": "^0.97.0",
+            "@deephaven/log": "^0.97.0",
+            "@deephaven/react-hooks": "^0.97.0",
+            "@deephaven/utils": "^0.97.0",
             "@fortawesome/fontawesome-svg-core": "^6.2.1",
             "@fortawesome/react-fontawesome": "^0.2.0",
             "@internationalized/date": "^3.5.5",
@@ -36408,30 +36491,32 @@
           }
         },
         "@deephaven/golden-layout": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.88.0.tgz",
-          "integrity": "sha512-30SuCWmbRUxaJVR66D3sHwiEq2XHrEjzyT7Tg0pNutH/iD+2XIY5rAZyTqepX4cmSjBuBEOPVva7bf2R8+ZHTA==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/golden-layout/-/golden-layout-0.97.0.tgz",
+          "integrity": "sha512-i5vvqHMmnmXwOPExTWDR2D58Ej3ZBS67F+wWP4sDRNYNUvwVqsAEAcr+kz6Ggoe141WZGeBvzeIOe9G1aAYxmg==",
           "requires": {
-            "@deephaven/components": "^0.88.0",
+            "@deephaven/components": "^0.97.0",
             "jquery": "^3.6.0",
             "nanoid": "^5.0.7"
           }
         },
         "@deephaven/jsapi-types": {
-          "version": "1.0.0-dev0.34.0"
+          "version": "1.0.0-dev0.36.1",
+          "resolved": "https://registry.npmjs.org/@deephaven/jsapi-types/-/jsapi-types-1.0.0-dev0.36.1.tgz",
+          "integrity": "sha512-Q7we+JYMqQrHp3hQfbKF3YmjjCLTjy+D3an8x6IsfVMv7Uv7LqvuA0c/tKCIT19JDa2b9giFWf3TV8apzXry/A=="
         },
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2",
@@ -36446,30 +36531,30 @@
       "requires": {}
     },
     "@deephaven/react-hooks": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.88.0.tgz",
-      "integrity": "sha512-2nfDWZ2mU3uNMxBu5WOD+bie9svrEXYEdDWglkZqcb77ZrI9pcLiuybz4ybGnN/NNnweyqvHD0q3Mi+VqXDdyw==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/react-hooks/-/react-hooks-0.97.0.tgz",
+      "integrity": "sha512-h248fMsmaFohDEDjQDEusRA8+JHEqpYFevKqRmtvU4R4W+0k6w14cLabf36J8E1uaBsoSOMSb8wy+S8oLeJE1w==",
       "requires": {
         "@adobe/react-spectrum": "3.35.1",
-        "@deephaven/log": "^0.88.0",
-        "@deephaven/utils": "^0.88.0",
+        "@deephaven/log": "^0.97.0",
+        "@deephaven/utils": "^0.97.0",
         "lodash.debounce": "^4.0.8",
         "lodash.throttle": "^4.1.1",
         "nanoid": "^5.0.7"
       },
       "dependencies": {
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
         },
         "@deephaven/utils": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.88.0.tgz",
-          "integrity": "sha512-IEyymRaTypTnCEvdoVvHYgm0mZYkyW8TVKWrBKL71dBGfmOx2jzxG4/tamTP2AcllBo9gAxdscmaBF7SKtKQ/A=="
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/utils/-/utils-0.97.0.tgz",
+          "integrity": "sha512-Qp7abGbcwXLXpsVubbiZJIuSa1VO6ePWlfon92/Ni3X92Bp/gsyB4gbogsrNa/3g1rt40d2EAiAVVa5wiy/jCw=="
         },
         "event-target-shim": {
           "version": "6.0.2",
@@ -36489,19 +36574,19 @@
       }
     },
     "@deephaven/storage": {
-      "version": "0.88.0",
-      "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.88.0.tgz",
-      "integrity": "sha512-SL1nNK6Qnap9il8L4URz5dklhzgdpqaJ1KqXyWZCSJe4GpOCfRQLbsaBIWR426AELXR38ZJ2nf3tWy0hiig/7w==",
+      "version": "0.97.0",
+      "resolved": "https://registry.npmjs.org/@deephaven/storage/-/storage-0.97.0.tgz",
+      "integrity": "sha512-SZTKfkd8CJkNoECXhWN+vfakVoblYbMcnRBwwXKHDXRjC4yw+D/BFS3XCDikyh6vfX8uANYfktCLS8kZ/4hiNg==",
       "requires": {
-        "@deephaven/filters": "^0.88.0",
-        "@deephaven/log": "^0.88.0",
+        "@deephaven/filters": "^0.97.0",
+        "@deephaven/log": "^0.97.0",
         "lodash.throttle": "^4.1.1"
       },
       "dependencies": {
         "@deephaven/log": {
-          "version": "0.88.0",
-          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.88.0.tgz",
-          "integrity": "sha512-50DiVOWAob0J00BZMELJ1RTwkGg407Gj2b8ls8PFV3HmmKJ2+IDvH6J7prt70w3D/dsXxE04gtkh+4/SU2TiyQ==",
+          "version": "0.97.0",
+          "resolved": "https://registry.npmjs.org/@deephaven/log/-/log-0.97.0.tgz",
+          "integrity": "sha512-JZ9mlQT1xXxRFQDJ3OgodoW1ZZ3AP1Iz9ySokS43bOc5/4Itdv0l8iNoEHgsTrN1HfLmAeQSXUvLXw+2xO9J9w==",
           "requires": {
             "event-target-shim": "^6.0.2"
           }
diff --git a/plugins/plotly-express/setup.cfg b/plugins/plotly-express/setup.cfg
index 6a6334208..f5c3a61c9 100644
--- a/plugins/plotly-express/setup.cfg
+++ b/plugins/plotly-express/setup.cfg
@@ -25,7 +25,7 @@ package_dir=
     =src
 packages=find_namespace:
 install_requires =
-    deephaven-core>=0.36.0
+    deephaven-core>=0.37.0
     deephaven-plugin>=0.6.0
     plotly
     deephaven-plugin-utilities>=0.0.2
diff --git a/plugins/plotly-express/src/js/package.json b/plugins/plotly-express/src/js/package.json
index df2dd9b16..59be14b7b 100644
--- a/plugins/plotly-express/src/js/package.json
+++ b/plugins/plotly-express/src/js/package.json
@@ -36,7 +36,8 @@
     "update-dh-packages": "node ../../../../tools/update-dh-packages.mjs"
   },
   "devDependencies": {
-    "@deephaven/jsapi-types": "1.0.0-dev0.35.2",
+    "@deephaven/jsapi-types": "1.0.0-dev0.36.1",
+    "@deephaven/test-utils": "0.97.0",
     "@types/deep-equal": "^1.0.1",
     "@types/plotly.js": "^2.12.18",
     "@types/plotly.js-dist-min": "^2.3.1",
@@ -51,15 +52,15 @@
     "react-dom": "^17.0.2"
   },
   "dependencies": {
-    "@deephaven/chart": "0.88.0",
-    "@deephaven/components": "0.88.0",
-    "@deephaven/dashboard": "0.88.0",
-    "@deephaven/dashboard-core-plugins": "0.88.0",
-    "@deephaven/icons": "0.88.0",
-    "@deephaven/jsapi-bootstrap": "0.88.0",
-    "@deephaven/log": "0.88.0",
-    "@deephaven/plugin": "0.88.0",
-    "@deephaven/utils": "0.88.0",
+    "@deephaven/chart": "0.97.0",
+    "@deephaven/components": "0.97.0",
+    "@deephaven/dashboard": "0.97.0",
+    "@deephaven/dashboard-core-plugins": "0.97.0",
+    "@deephaven/icons": "0.97.0",
+    "@deephaven/jsapi-bootstrap": "0.97.0",
+    "@deephaven/log": "0.97.0",
+    "@deephaven/plugin": "0.97.0",
+    "@deephaven/utils": "0.97.0",
     "deep-equal": "^2.2.1",
     "nanoid": "^5.0.7",
     "plotly.js": "^2.29.1",
diff --git a/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.ts b/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.ts
index 152b7d096..f122daa1a 100644
--- a/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.ts
+++ b/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.ts
@@ -2,6 +2,7 @@ import type { Layout, Data, PlotData, LayoutAxis } from 'plotly.js';
 import type { dh as DhType } from '@deephaven/jsapi-types';
 import { ChartModel, ChartUtils } from '@deephaven/chart';
 import Log from '@deephaven/log';
+import { RenderOptions } from '@deephaven/chart/dist/ChartModel';
 import {
   DownsampleInfo,
   PlotlyChartWidgetData,
@@ -9,11 +10,14 @@ import {
   downsample,
   getDataMappings,
   getPathParts,
+  getReplaceableWebGlTraceIndices,
   getWidgetData,
   isAutoAxis,
   isLineSeries,
   isLinearAxis,
   removeColorsFromData,
+  setWebGlTraceType,
+  hasUnreplaceableWebGlTraces,
 } from './PlotlyExpressChartUtils';
 
 const log = Log.module('@deephaven/js-plugin-plotly-express.ChartModel');
@@ -116,6 +120,17 @@ export class PlotlyExpressChartModel extends ChartModel {
 
   isDownsamplingDisabled = false;
 
+  /**
+   * Set of traces that are originally WebGL and can be replaced with non-WebGL traces.
+   * These need to be replaced if WebGL is disabled and re-enabled if WebGL is enabled again.
+   */
+  webGlTraceIndices: Set<number> = new Set();
+
+  /**
+   * The WebGl warning is only shown once per chart. When the user acknowledges the warning, it will not be shown again.
+   */
+  hasAcknowledgedWebGlWarning = false;
+
   override getData(): Partial<Data>[] {
     const hydratedData = [...this.plotlyData];
 
@@ -207,6 +222,41 @@ export class PlotlyExpressChartModel extends ChartModel {
     this.widget = undefined;
   }
 
+  override setRenderOptions(renderOptions: RenderOptions): void {
+    this.handleWebGlAllowed(renderOptions.webgl, this.renderOptions?.webgl);
+    super.setRenderOptions(renderOptions);
+  }
+
+  /**
+   * Handle the WebGL option being set in the render options.
+   * If WebGL is enabled, traces have their original types as given.
+   * If WebGL is disabled, replace traces that require WebGL with non-WebGL traces if possible.
+   * Also, show a dismissible warning per-chart if there are WebGL traces that cannot be replaced.
+   * @param webgl The new WebGL value. True if WebGL is enabled.
+   * @param prevWebgl The previous WebGL value
+   */
+  handleWebGlAllowed(webgl = true, prevWebgl = true): void {
+    setWebGlTraceType(this.plotlyData, webgl, this.webGlTraceIndices);
+
+    const needsBlocker = hasUnreplaceableWebGlTraces(this.plotlyData);
+
+    // If WebGL is disabled and there are traces that require WebGL, show a warning that is dismissible on a per-chart basis
+    if (needsBlocker && !webgl && !this.hasAcknowledgedWebGlWarning) {
+      this.fireBlocker([
+        'WebGL is disabled but this chart cannot render without it. Check the Advanced section in the settings to enable WebGL or click below to render with WebGL for this chart.',
+      ]);
+    } else if (webgl && !prevWebgl && needsBlocker) {
+      // clear the blocker but not the acknowledged flag in case WebGL is disabled again
+      this.fireBlockerClear(false);
+    }
+  }
+
+  override fireBlockerClear(isAcknowledged = true): void {
+    super.fireBlockerClear();
+    this.hasAcknowledgedWebGlWarning =
+      isAcknowledged || this.hasAcknowledgedWebGlWarning;
+  }
+
   updateLayout(data: PlotlyChartWidgetData): void {
     const { figure } = data;
     const { plotly } = figure;
@@ -246,6 +296,11 @@ export class PlotlyExpressChartModel extends ChartModel {
       );
     }
 
+    // Retrieve the indexes of traces that require WebGL so they can be replaced if WebGL is disabled
+    this.webGlTraceIndices = getReplaceableWebGlTraceIndices(this.plotlyData);
+
+    this.handleWebGlAllowed(this.renderOptions?.webgl);
+
     newReferences.forEach(async (id, i) => {
       this.tableDataMap.set(id, {}); // Plot may render while tables are being fetched. Set this to avoid a render error
       const table = (await references[i].fetch()) as DhType.Table;
diff --git a/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts b/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts
index f6ba59a97..009f46e8c 100644
--- a/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts
+++ b/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.ts
@@ -1,6 +1,28 @@
-import type { Data, LayoutAxis, PlotlyDataLayoutConfig } from 'plotly.js';
+import type {
+  Data,
+  LayoutAxis,
+  PlotlyDataLayoutConfig,
+  PlotType,
+} from 'plotly.js';
 import type { dh as DhType } from '@deephaven/jsapi-types';
 
+/**
+ * Traces that are at least partially powered by WebGL and have no SVG equivalent.
+ * https://plotly.com/python/webgl-vs-svg/
+ */
+const UNREPLACEABLE_WEBGL_TRACE_TYPES = new Set([
+  'splom',
+  'parcoords',
+  'scatter3d',
+  'surface',
+  'mesh3d',
+  'cone',
+  'streamtube',
+  'scattermapbox',
+  'choroplethmapbox',
+  'densitymapbox',
+]);
+
 export interface PlotlyChartWidget {
   getDataAsBase64: () => string;
   exportedObjects: { fetch: () => Promise<DhType.Table> }[];
@@ -215,3 +237,54 @@ export function downsample(
     )
   );
 }
+
+/**
+ * Get the indexes of the replaceable WebGL traces in the data
+ * A replaceable WebGL has a type that ends with 'gl' which indicates it has a SVG equivalent
+ * @param data The data to check
+ * @returns The indexes of the WebGL traces
+ */
+export function getReplaceableWebGlTraceIndices(data: Data[]): Set<number> {
+  const webGlTraceIndexes = new Set<number>();
+  data.forEach((trace, index) => {
+    if (trace.type && trace.type.endsWith('gl')) {
+      webGlTraceIndexes.add(index);
+    }
+  });
+  return webGlTraceIndexes;
+}
+
+/**
+ * Check if the data contains any traces that are at least partially powered by WebGL and have no SVG equivalent.
+ * @param data The data to check for WebGL traces
+ * @returns True if the data contains any unreplaceable WebGL traces
+ */
+export function hasUnreplaceableWebGlTraces(data: Data[]): boolean {
+  return data.some(
+    trace => trace.type && UNREPLACEABLE_WEBGL_TRACE_TYPES.has(trace.type)
+  );
+}
+
+/**
+ * Set traces to use WebGL if WebGL is enabled and the trace was originally WebGL
+ * or swap out WebGL for SVG if WebGL is disabled and the trace was originally WebGL
+ * @param data The plotly figure data to update
+ * @param webgl True if WebGL is enabled
+ * @param webGlTraceIndices The indexes of the traces that are originally WebGL traces
+ */
+export function setWebGlTraceType(
+  data: Data[],
+  webgl: boolean,
+  webGlTraceIndices: Set<number>
+): void {
+  webGlTraceIndices.forEach(index => {
+    const trace = data[index];
+    if (webgl && trace.type && !trace.type.endsWith('gl')) {
+      // If WebGL is enabled and the trace is not already a WebGL trace, make it one
+      trace.type = `${trace.type}gl` as PlotType;
+    } else if (!webgl && trace.type && trace.type.endsWith('gl')) {
+      // If WebGL is disabled and the trace is a WebGL trace, remove the 'gl'
+      trace.type = trace.type.substring(0, trace.type.length - 2) as PlotType;
+    }
+  });
+}
diff --git a/plugins/plotly-express/src/js/tsconfig.json b/plugins/plotly-express/src/js/tsconfig.json
index baed111e0..ece69655d 100644
--- a/plugins/plotly-express/src/js/tsconfig.json
+++ b/plugins/plotly-express/src/js/tsconfig.json
@@ -9,5 +9,5 @@
     "noEmit": false
   },
   "include": ["src/**/*.ts", "src/**/*.tsx"],
-  "exclude": ["**/node_modules/**/*", "dist/**/*"]
+  "exclude": ["**/node_modules/**/*", "src/**/*.test.*", "dist/**/*"]
 }


Test patch:
diff --git a/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.test.ts b/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.test.ts
index a4f3bf536..54cfbf4fd 100644
--- a/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.test.ts
+++ b/plugins/plotly-express/src/js/src/PlotlyExpressChartModel.test.ts
@@ -1,6 +1,6 @@
 import type { Layout } from 'plotly.js';
 import { dh as DhType } from '@deephaven/jsapi-types';
-import { TestUtils } from '@deephaven/utils';
+import { TestUtils } from '@deephaven/test-utils';
 import { ChartModel } from '@deephaven/chart';
 import { PlotlyExpressChartModel } from './PlotlyExpressChartModel';
 import { PlotlyChartWidgetData } from './PlotlyExpressChartUtils';
@@ -262,4 +262,62 @@ describe('PlotlyExpressChartModel', () => {
       new CustomEvent(ChartModel.EVENT_DOWNSAMPLEFAILED)
     );
   });
+
+  it('should swap replaceable WebGL traces without blocker events if WebGL is disabled or reenabled', async () => {
+    const mockWidget = createMockWidget([SMALL_TABLE], 'scattergl');
+    const chartModel = new PlotlyExpressChartModel(
+      mockDh,
+      mockWidget,
+      jest.fn()
+    );
+
+    const mockSubscribe = jest.fn();
+    await chartModel.subscribe(mockSubscribe);
+    await new Promise(process.nextTick); // Subscribe is async
+    chartModel.setRenderOptions({ webgl: true });
+    expect(chartModel.plotlyData[0].type).toBe('scattergl');
+    chartModel.setRenderOptions({ webgl: false });
+    expect(chartModel.plotlyData[0].type).toBe('scatter');
+    chartModel.setRenderOptions({ webgl: true });
+    expect(chartModel.plotlyData[0].type).toBe('scattergl');
+
+    // No events should be emitted since the trace is replaceable
+    expect(mockSubscribe).toHaveBeenCalledTimes(0);
+  });
+
+  it('should emit blocker events only if unreplaceable WebGL traces are present and WebGL is disabled, then blocker clear events when reenabled', async () => {
+    const mockWidget = createMockWidget([SMALL_TABLE], 'scatter3d');
+    const chartModel = new PlotlyExpressChartModel(
+      mockDh,
+      mockWidget,
+      jest.fn()
+    );
+
+    const mockSubscribe = jest.fn();
+    await chartModel.subscribe(mockSubscribe);
+    await new Promise(process.nextTick); // Subscribe is async
+    chartModel.setRenderOptions({ webgl: true });
+    // no calls because the chart has webgl enabled
+    expect(mockSubscribe).toHaveBeenCalledTimes(0);
+    chartModel.setRenderOptions({ webgl: false });
+    // blocking event should be emitted
+    expect(mockSubscribe).toHaveBeenCalledTimes(1);
+    expect(mockSubscribe).toHaveBeenLastCalledWith(
+      new CustomEvent(ChartModel.EVENT_BLOCKER)
+    );
+    chartModel.setRenderOptions({ webgl: true });
+    // blocking clear event should be emitted, but this doesn't count as an acknowledge
+    expect(mockSubscribe).toHaveBeenCalledTimes(2);
+    expect(mockSubscribe).toHaveBeenLastCalledWith(
+      new CustomEvent(ChartModel.EVENT_BLOCKER_CLEAR)
+    );
+    expect(chartModel.hasAcknowledgedWebGlWarning).toBe(false);
+    // if user had accepted the rendering (simulated by fireBlockerClear), no EVENT_BLOCKER event should be emitted again
+    chartModel.fireBlockerClear();
+    chartModel.setRenderOptions({ webgl: false });
+    expect(mockSubscribe).toHaveBeenCalledTimes(3);
+    expect(mockSubscribe).toHaveBeenLastCalledWith(
+      new CustomEvent(ChartModel.EVENT_BLOCKER_CLEAR)
+    );
+  });
 });
diff --git a/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.test.ts b/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.test.ts
index 428e93793..9ff30906d 100644
--- a/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.test.ts
+++ b/plugins/plotly-express/src/js/src/PlotlyExpressChartUtils.test.ts
@@ -7,6 +7,9 @@ import {
   removeColorsFromData,
   getDataMappings,
   PlotlyChartWidgetData,
+  getReplaceableWebGlTraceIndices,
+  hasUnreplaceableWebGlTraces,
+  setWebGlTraceType,
 } from './PlotlyExpressChartUtils';
 
 describe('getDataMappings', () => {
@@ -202,3 +205,116 @@ describe('areSameAxisRange', () => {
     expect(areSameAxisRange(null, [0, 10])).toBe(false);
   });
 });
+
+describe('getReplaceableWebGlTraceIndexes', () => {
+  it('should return the indexes of any trace with gl', () => {
+    expect(
+      getReplaceableWebGlTraceIndices([
+        {
+          type: 'scattergl',
+        },
+        {
+          type: 'scatter',
+        },
+        {
+          type: 'scatter3d',
+        },
+        {
+          type: 'scattergl',
+        },
+      ])
+    ).toEqual(new Set([0, 3]));
+  });
+
+  it('should return an empty set if there are no traces with gl', () => {
+    expect(
+      getReplaceableWebGlTraceIndices([
+        {
+          type: 'scatter',
+        },
+        {
+          type: 'scatter3d',
+        },
+      ])
+    ).toEqual(new Set());
+  });
+});
+
+describe('hasUnreplaceableWebGlTraces', () => {
+  it('should return true if there is a single unreplaceable trace', () => {
+    expect(
+      hasUnreplaceableWebGlTraces([
+        {
+          type: 'scattermapbox',
+        },
+      ])
+    ).toBe(true);
+  });
+
+  it('should return true if there are unreplaceable traces', () => {
+    expect(
+      hasUnreplaceableWebGlTraces([
+        {
+          type: 'scattergl',
+        },
+        {
+          type: 'scatter',
+        },
+        {
+          type: 'scatter3d',
+        },
+        {
+          type: 'scattergl',
+        },
+        {
+          type: 'scatter3d',
+        },
+      ])
+    ).toBe(true);
+  });
+
+  it('should return false if there are no unreplaceable traces', () => {
+    expect(
+      hasUnreplaceableWebGlTraces([
+        {
+          type: 'scatter',
+        },
+        {
+          type: 'scattergl',
+        },
+      ])
+    ).toBe(false);
+  });
+});
+
+describe('setWebGlTraceType', () => {
+  it('should set the trace type to gl if webgl is enabled', () => {
+    const data: Plotly.Data[] = [
+      {
+        type: 'scatter',
+      },
+      {
+        type: 'scatter',
+      },
+    ];
+    const webGlTraceIndices = new Set([1]);
+    setWebGlTraceType(data, true, webGlTraceIndices);
+    expect(data[0].type).toBe('scatter');
+    expect(data[1].type).toBe('scattergl');
+  });
+
+  it('should remove the gl from the trace type if webgl is disabled', () => {
+    const data: Plotly.Data[] = [
+      {
+        type: 'scatter',
+      },
+      {
+        type: 'scattergl',
+      },
+    ];
+    const webGlTraceIndices = new Set([1]);
+    setWebGlTraceType(data, false, webGlTraceIndices);
+    expect(data[0].type).toBe('scatter');
+    expect(data[1].type).toBe('scatter');
+  });
+});