precision-dashwidgets 0.5.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,82 @@
1
1
  # precision-dashwidgets
2
2
 
3
+ ## Version Compatibility
4
+
5
+ | PrecisionDashWidgets | PennsieveDashboard | Notes |
6
+ |----------------------|--------------------|-------|
7
+ | >= 1.0.0 | >= 1.0.0 | `s3Url`/`apiUrl` removed — use `services` instead |
8
+ | < 1.0.0 | < 1.0.0 | Legacy `s3Url`/`apiUrl` on `GlobalVarsShape` |
9
+
10
+ ---
11
+
3
12
  Interactive genomics visualization widgets built with Vue 3. These components provide gene expression analysis, dimensionality reduction plots (UMAP/tSNE), and distribution visualizations powered by DuckDB WASM for client-side querying of Parquet data files.
4
13
 
14
+ ## Getting Started
15
+
16
+ ### Prerequisites
17
+
18
+ - **Node.js** >= 18
19
+ - **npm** >= 9
20
+
21
+ ### Clone and Run
22
+
23
+ ```bash
24
+ # Clone the repo
25
+ git clone https://github.com/nih-sparc/DashboardRepo.git
26
+ cd DashboardRepo/packages/PrecisionDashWidgets
27
+
28
+ # Install dependencies
29
+ npm install
30
+
31
+ # Start the dev server (opens at http://localhost:5173)
32
+ npm run dev
33
+ ```
34
+
35
+ The dev server loads `src/App.vue`, which renders a `MultiDashboard` with all the widgets wired up against sample data. This is the fastest way to see everything in action.
36
+
37
+ ### Build the Library
38
+
39
+ ```bash
40
+ # Build for distribution (outputs to dist/)
41
+ npm run build
42
+
43
+ # Preview the built package
44
+ npm run preview
45
+ ```
46
+
47
+ The build produces two bundles in `dist/`:
48
+ - `precision-dashwidgets.es.js` (ESM)
49
+ - `precision-dashwidgets.umd.js` (UMD)
50
+ - `style.css` (combined styles)
51
+
52
+ ---
53
+
54
+ ## Architecture
55
+
56
+ ### Libs vs Components
57
+
58
+ The codebase uses a **two-layer architecture** under `src/`:
59
+
60
+ - **`src/components/`** — Lightweight **wrapper components** that form the public API. Each wrapper handles prop injection (e.g. `dataPath`, `initialGene1`), connects to the shared Pinia store, resolves the data URL via `useDashboardGlobalVars()`, and delegates all rendering to a corresponding lib component. These are what consumers import.
61
+
62
+ - **`src/libs/`** — The **implementation layer** where the actual visualization logic lives. Lib components own DuckDB initialization, WebGL/D3 rendering, user interaction handling, and local state. For example, `components/GeneExpressionViewer/` wraps `libs/GeneExpressionViewer/GeneCoexpressionViewer.vue`.
63
+
64
+ This split keeps the public-facing component API clean and dashboard-aware, while the libs remain self-contained and reusable.
65
+
66
+ ### DuckDB and dataManager.js
67
+
68
+ All data access goes through `src/libs/dataManager.js`, which exports the `UMAPGeneViewer` class. When a component mounts, it creates a `UMAPGeneViewer` instance pointed at a base URL (S3, HTTP, etc.) containing Parquet files. The class initializes a **DuckDB WASM** worker in-browser, fetches the Parquet files as binary buffers, registers them in DuckDB, and then runs SQL queries entirely client-side — no backend needed.
69
+
70
+ Key operations include loading UMAP/tSNE coordinates, searching genes via full-text SQL queries against `gene_stats.parquet`, and loading individual gene expression data on-demand from chunked Parquet files referenced in `gene_locations.parquet`. Results are cached in memory so repeated gene lookups are instant.
71
+
72
+ Each component currently creates its own `UMAPGeneViewer` / DuckDB instance. See [Known Limitations](#known-limitations) and the [Roadmap](#roadmap-configurable-data-schema) for planned shared-instance support.
73
+
74
+ ### Shared State
75
+
76
+ Cross-widget coordination (e.g. selecting a gene in one widget updates another) is handled by a **Pinia store** (`usePrecisionStore`). Dashboard-level context like the data URL and filters flows through Vue's `provide`/`inject` via `DASHBOARD_GLOBAL_VARS_KEY`.
77
+
78
+ ---
79
+
5
80
  ## Components
6
81
 
7
82
  ### GeneExpression
@@ -10,7 +85,7 @@ Gene co-expression analysis widget. Renders a scatter plot (UMAP or tSNE) colore
10
85
 
11
86
  | Prop | Type | Description |
12
87
  |------|------|-------------|
13
- | `dataPath` | `string?` | URL to data directory containing Parquet files. Falls back to injected `s3Url`, then the default. |
88
+ | `dataPath` | `string?` | URL to data directory containing Parquet files. Falls back to injected `services.s3Url`, then the default. |
14
89
  | `initialGene1` | `string?` | Pre-selected first gene (e.g. `"CDH9"`) |
15
90
  | `initialGene2` | `string?` | Pre-selected second gene (e.g. `"TAC1"`) |
16
91
 
@@ -20,7 +95,7 @@ Dual-panel comparison widget. Left panel shows a UMAP colored by a selected meta
20
95
 
21
96
  | Prop | Type | Description |
22
97
  |------|------|-------------|
23
- | `dataPath` | `string?` | URL to data directory containing Parquet files. Falls back to injected `s3Url`, then the default. |
98
+ | `dataPath` | `string?` | URL to data directory containing Parquet files. Falls back to injected `services.s3Url`, then the default. |
24
99
  | `initialGene` | `string?` | Pre-selected gene for the expression panel |
25
100
  | `initialMetadataColumn` | `string?` | Pre-selected metadata column for the metadata panel |
26
101
 
@@ -30,7 +105,7 @@ Gene expression distribution widget. Renders violin or box plots showing the dis
30
105
 
31
106
  | Prop | Type | Description |
32
107
  |------|------|-------------|
33
- | `dataPath` | `string?` | URL to data directory containing Parquet files. Falls back to injected `s3Url`, then the default. |
108
+ | `dataPath` | `string?` | URL to data directory containing Parquet files. Falls back to injected `services.s3Url`, then the default. |
34
109
  | `initialGene` | `string?` | Pre-selected gene |
35
110
  | `initialMetadataColumn` | `string?` | Pre-selected metadata column for x-axis grouping |
36
111
 
@@ -127,7 +202,7 @@ const defaultLayout = [
127
202
 
128
203
  The dashboard provides two context mechanisms:
129
204
 
130
- 1. **Global vars injection** (`DASHBOARD_GLOBAL_VARS_KEY`) - provides `s3Url`, `apiUrl`, and shared filters via `provide`/`inject`.
205
+ 1. **Global vars injection** (`DASHBOARD_GLOBAL_VARS_KEY`) - provides `services` (configurables like data URLs, API keys) and shared `filters` via `provide`/`inject`.
131
206
  2. **Pinia store** (`usePrecisionStore`) - shared reactive state for gene and metadata selections across all widgets. When a user selects a gene in one widget, other widgets can react.
132
207
 
133
208
  These are wired automatically when used inside the dashboard framework.
@@ -218,7 +293,7 @@ import {
218
293
 
219
294
  #### Alternative: Provide Global Vars (set data path once)
220
295
 
221
- Instead of passing `dataPath` to every component, you can provide `DASHBOARD_GLOBAL_VARS_KEY` in an ancestor component. All widgets will inherit the `s3Url` from it:
296
+ Instead of passing `dataPath` to every component, you can provide `DASHBOARD_GLOBAL_VARS_KEY` in an ancestor component. All widgets will inherit `services.s3Url` from it:
222
297
 
223
298
  ```vue
224
299
  <script setup>
@@ -226,8 +301,7 @@ import { provide, ref } from 'vue'
226
301
  import { DASHBOARD_GLOBAL_VARS_KEY } from 'precision-dashwidgets'
227
302
 
228
303
  provide(DASHBOARD_GLOBAL_VARS_KEY, {
229
- s3Url: ref('https://your-bucket.s3.amazonaws.com/your-dataset'),
230
- apiUrl: ref(''),
304
+ services: ref({ s3Url: 'https://your-bucket.s3.amazonaws.com/your-dataset' }),
231
305
  filters: ref({}),
232
306
  setFilter: () => {},
233
307
  clearFilter: () => {},
@@ -235,7 +309,7 @@ provide(DASHBOARD_GLOBAL_VARS_KEY, {
235
309
  </script>
236
310
  ```
237
311
 
238
- **Resolution order:** `dataPath` prop > injected `s3Url` > built-in default URL.
312
+ **Resolution order:** `dataPath` prop > injected `services.s3Url` > built-in default URL.
239
313
 
240
314
  ### Accessing Shared State
241
315
 
@@ -391,19 +465,6 @@ provide('precision:data', dataProvider)
391
465
  </script>
392
466
  ```
393
467
 
394
- ## Development
395
-
396
- ```bash
397
- # Start dev server
398
- npm run dev
399
-
400
- # Build library
401
- npm run build
402
-
403
- # Preview build
404
- npm run preview
405
- ```
406
-
407
468
  ## Tech Stack
408
469
 
409
470
  - **Vue 3** - Component framework
@@ -1,5 +1,5 @@
1
1
  import { i as r } from "./pako.esm-D_m2s4NW.mjs";
2
- import { B as a } from "./index-BPlDjM00.mjs";
2
+ import { B as a } from "./index-CdW9BP2T.mjs";
3
3
  class s extends a {
4
4
  decodeBlock(e) {
5
5
  return r(new Uint8Array(e)).buffer;
@@ -0,0 +1,4 @@
1
+ import { a as r } from "./index-w9j4W2ma.mjs";
2
+ export {
3
+ r as TextViewer
4
+ };
@@ -2,7 +2,7 @@ var Ky = Object.defineProperty;
2
2
  var Oy = (t, A, e) => A in t ? Ky(t, A, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[A] = e;
3
3
  var f = (t, A, e) => Oy(t, typeof A != "symbol" ? A + "" : A, e);
4
4
  import { defineComponent as pC, ref as ee, watch as jI, onMounted as Hf, onUnmounted as Yf, openBlock as Ne, createElementBlock as ve, unref as Bo, createElementVNode as _A, createCommentVNode as vt, toDisplayString as Mo, Fragment as Wy, createVNode as Vy, nextTick as zy, normalizeStyle as Xy, computed as ll, createTextVNode as El, normalizeClass as jy } from "vue";
5
- import { g as Zy } from "./index-BKzfWMQL.mjs";
5
+ import { g as Zy } from "./index-w9j4W2ma.mjs";
6
6
  function sa(t, A) {
7
7
  if (!t)
8
8
  throw new Error(A || "loader assertion failed.");
@@ -28949,19 +28949,19 @@ const U0 = {
28949
28949
  function Ht(t, A) {
28950
28950
  Array.isArray(t) || (t = [t]), t.forEach((e) => Jk.set(e, A));
28951
28951
  }
28952
- Ht([void 0, 1], () => import("./raw-BOTKG_OX.mjs").then((t) => t.default));
28953
- Ht(5, () => import("./lzw-BPNO0d6S.mjs").then((t) => t.default));
28952
+ Ht([void 0, 1], () => import("./raw-DLEwRloC.mjs").then((t) => t.default));
28953
+ Ht(5, () => import("./lzw-BWgBDxct.mjs").then((t) => t.default));
28954
28954
  Ht(6, () => {
28955
28955
  throw new Error("old style JPEG compression is not supported.");
28956
28956
  });
28957
- Ht(7, () => import("./jpeg-CcPIHJJb.mjs").then((t) => t.default));
28958
- Ht([8, 32946], () => import("./deflate-BhCs3EVM.mjs").then((t) => t.default));
28959
- Ht(32773, () => import("./packbits-2KoZ88H4.mjs").then((t) => t.default));
28957
+ Ht(7, () => import("./jpeg-jsrKVbbY.mjs").then((t) => t.default));
28958
+ Ht([8, 32946], () => import("./deflate-CyCS27iF.mjs").then((t) => t.default));
28959
+ Ht(32773, () => import("./packbits-CUORHrxc.mjs").then((t) => t.default));
28960
28960
  Ht(
28961
28961
  34887,
28962
- () => import("./lerc-BgJ5uP3F.mjs").then(async (t) => (await t.zstd.init(), t)).then((t) => t.default)
28962
+ () => import("./lerc-CBpfbMul.mjs").then(async (t) => (await t.zstd.init(), t)).then((t) => t.default)
28963
28963
  );
28964
- Ht(50001, () => import("./webimage-UA6QS-y3.mjs").then((t) => t.default));
28964
+ Ht(50001, () => import("./webimage-BOc3YOov.mjs").then((t) => t.default));
28965
28965
  function Hk(t, A) {
28966
28966
  let e = t.length - A, i = 0;
28967
28967
  do {
@@ -44756,7 +44756,7 @@ Si([8, 32946], () => import("./deflate-DbhbvOaP-D8NSBt31.mjs").then((t) => t.def
44756
44756
  Si(32773, () => import("./packbits-BuzK6gM3-6Um4hupZ.mjs").then((t) => t.default));
44757
44757
  Si(
44758
44758
  34887,
44759
- () => import("./lerc-XufrP0FH-AWUOo2VT.mjs").then(async (t) => (await t.zstd.init(), t)).then((t) => t.default)
44759
+ () => import("./lerc-XufrP0FH-BsxGX2dW.mjs").then(async (t) => (await t.zstd.init(), t)).then((t) => t.default)
44760
44760
  );
44761
44761
  Si(50001, () => import("./webimage--SJddlky-F_hESl4q.mjs").then((t) => t.default));
44762
44762
  function xg(t, A, e, i = 1) {
@@ -0,0 +1,4 @@
1
+ import { C as r } from "./index-w9j4W2ma.mjs";
2
+ export {
3
+ r as Markdown
4
+ };
@@ -1,5 +1,5 @@
1
- import { M as a } from "./index-BKzfWMQL.mjs";
2
- import { j as e, q as M, K as s, r as P } from "./index-BKzfWMQL.mjs";
1
+ import { M as a } from "./index-w9j4W2ma.mjs";
2
+ import { j as e, q as M, K as s, r as P } from "./index-w9j4W2ma.mjs";
3
3
  export {
4
4
  a as UMAP,
5
5
  e as UMAPControlPanel,
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as y, ref as t, openBlock as u, createElementBlock as c, createElementVNode as l, withDirectives as p, vModelText as r, withKeys as b, createCommentVNode as k } from "vue";
2
- import { k as U } from "./index-BKzfWMQL.mjs";
2
+ import { k as U } from "./index-w9j4W2ma.mjs";
3
3
  const g = { class: "ai-plot-widget" }, h = { class: "ai-plot-field" }, x = {
4
4
  key: 0,
5
5
  class: "ai-plot-field"
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as le, inject as te, ref as g, computed as F, watch as ne, onMounted as oe, onBeforeUnmount as re, openBlock as w, createElementBlock as E, createElementVNode as r, withDirectives as D, vModelText as ie, Fragment as M, renderList as N, toDisplayString as $, vModelSelect as W, createCommentVNode as ue } from "vue";
2
- import { k as se, b as z } from "./index-BKzfWMQL.mjs";
2
+ import { k as se, b as z } from "./index-w9j4W2ma.mjs";
3
3
  const ce = { class: "pp-container" }, pe = { class: "pp-header" }, ve = { class: "pp-controls" }, de = { class: "pp-field" }, me = ["disabled"], fe = { class: "pp-field" }, ye = ["disabled"], Se = ["value"], ge = ["value"], we = ["disabled"], Ee = ["value"], $e = { class: "pp-field" }, he = ["disabled"], Ae = {
4
4
  key: 0,
5
5
  class: "pp-message"
@@ -1,5 +1,5 @@
1
- import { E as a } from "./index-BKzfWMQL.mjs";
2
- import { f as t, H as p, I as x } from "./index-BKzfWMQL.mjs";
1
+ import { E as a } from "./index-w9j4W2ma.mjs";
2
+ import { f as t, H as p, I as x } from "./index-w9j4W2ma.mjs";
3
3
  export {
4
4
  a as DataExplorer,
5
5
  t as DataExplorerCore,
@@ -5750,31 +5750,31 @@ const vI = { class: "markdown-header" }, yI = {
5750
5750
  }
5751
5751
  }), S3 = /* @__PURE__ */ Ns(NI, [["__scopeId", "data-v-4007de4f"]]);
5752
5752
  Ca(
5753
- () => import("./index-u1qleOVs-BYmcfDHg.mjs").then((e) => e.DataExplorer)
5753
+ () => import("./index-u1qleOVs-B74-wHol.mjs").then((e) => e.DataExplorer)
5754
5754
  );
5755
5755
  Ca(
5756
- () => import("./index-Oh_goZGT-ChJfpWzo.mjs").then((e) => e.UMAP)
5756
+ () => import("./index-Oh_goZGT-Drk6kHj-.mjs").then((e) => e.UMAP)
5757
5757
  );
5758
5758
  Ca(
5759
- () => import("./index-GF8k2nCC-lOm3hJ2E.mjs").then((e) => e.Markdown)
5759
+ () => import("./index-GF8k2nCC-Rypj-gGv.mjs").then((e) => e.Markdown)
5760
5760
  );
5761
5761
  Ca(
5762
- () => import("./index-CRAkqt4--DYvOyo89.mjs").then((e) => e.TextViewer)
5762
+ () => import("./index-CRAkqt4--CvnY7WxJ.mjs").then((e) => e.TextViewer)
5763
5763
  );
5764
5764
  Ca(
5765
- () => import("./index-dhOjlnSX-BYdQtWmD.mjs").then((e) => e.ProportionPlot)
5765
+ () => import("./index-dhOjlnSX-11_jYWLn.mjs").then((e) => e.ProportionPlot)
5766
5766
  );
5767
5767
  Ca(
5768
- () => import("./index-UOUUzHJY-w-g8Wwzh.mjs").then((e) => e.AiPlotly)
5768
+ () => import("./index-UOUUzHJY-DebPJ0dC.mjs").then((e) => e.AiPlotly)
5769
5769
  );
5770
5770
  Ca(
5771
5771
  () => import("./core-l0sNRNKZ.mjs").then((e) => e.TSViewer)
5772
5772
  );
5773
5773
  Ca(
5774
- () => import("./index-BPlDjM00.mjs").then((e) => e.i).then((e) => e.OmeViewer)
5774
+ () => import("./index-CdW9BP2T.mjs").then((e) => e.i).then((e) => e.OmeViewer)
5775
5775
  );
5776
5776
  Ca(
5777
- () => import("./index-BPlDjM00.mjs").then((e) => e.i).then((e) => e.TiffViewer)
5777
+ () => import("./index-CdW9BP2T.mjs").then((e) => e.i).then((e) => e.TiffViewer)
5778
5778
  );
5779
5779
  const OI = "dashboard:globalVars";
5780
5780
  function No(e = !1) {
@@ -5785,7 +5785,10 @@ const MI = { class: "data-explorer-wrap" }, LI = { class: "data-explorer-info" }
5785
5785
  inheritAttrs: !1,
5786
5786
  __name: "DataExplorer",
5787
5787
  setup(e) {
5788
- const t = No(), n = it("Data Explorer"), r = wn(() => pe(t.s3Url));
5788
+ const t = No(), n = it("Data Explorer"), r = wn(() => {
5789
+ var i;
5790
+ return (i = pe(t == null ? void 0 : t.services)) == null ? void 0 : i.s3Url;
5791
+ });
5789
5792
  return Mx(() => {
5790
5793
  }), (i, a) => {
5791
5794
  const s = Lx("el-icon");
@@ -5818,12 +5821,15 @@ const MI = { class: "data-explorer-wrap" }, LI = { class: "data-explorer-info" }
5818
5821
  for (const [r, i] of t)
5819
5822
  n[r] = i;
5820
5823
  return n;
5821
- }, E3 = /* @__PURE__ */ ha(DI, [["__scopeId", "data-v-c63ff2cc"]]), CI = { class: "umap-wrap" }, FI = /* @__PURE__ */ Object.assign({
5824
+ }, E3 = /* @__PURE__ */ ha(DI, [["__scopeId", "data-v-dcb02f80"]]), CI = { class: "umap-wrap" }, FI = /* @__PURE__ */ Object.assign({
5822
5825
  inheritAttrs: !1
5823
5826
  }, {
5824
5827
  __name: "Umap",
5825
5828
  setup(e) {
5826
- const t = No(), n = it("Data Explorer"), r = wn(() => pe(t == null ? void 0 : t.s3Url));
5829
+ const t = No(), n = it("Data Explorer"), r = wn(() => {
5830
+ var i;
5831
+ return (i = pe(t == null ? void 0 : t.services)) == null ? void 0 : i.s3Url;
5832
+ });
5827
5833
  return (i, a) => (mt(), gt(er, null, [
5828
5834
  ko(i.$slots, "default", { widgetName: n.value }, void 0, !0),
5829
5835
  L("div", CI, [
@@ -5831,7 +5837,7 @@ const MI = { class: "data-explorer-wrap" }, LI = { class: "data-explorer-info" }
5831
5837
  ])
5832
5838
  ], 64));
5833
5839
  }
5834
- }), A3 = /* @__PURE__ */ ha(FI, [["__scopeId", "data-v-78e97b02"]]), _f = Wh("precisionGlobalVars", () => {
5840
+ }), A3 = /* @__PURE__ */ ha(FI, [["__scopeId", "data-v-0bdda911"]]), _f = Wh("precisionGlobalVars", () => {
5835
5841
  const e = it(null), t = it(null), n = it(null), r = it(null), i = it(null);
5836
5842
  function a(d) {
5837
5843
  e.value = d === "" ? null : d;
@@ -17604,7 +17610,10 @@ const NC = { class: "pp-container" }, OC = {
17604
17610
  },
17605
17611
  setup(e) {
17606
17612
  const t = e, n = No(), r = _f(), i = wn(
17607
- () => t.dataPath ?? (n ? pe(n.s3Url) : null) ?? tF
17613
+ () => {
17614
+ var a;
17615
+ return t.dataPath ?? (n ? (a = pe(n.services)) == null ? void 0 : a.s3Url : null) ?? tF;
17616
+ }
17608
17617
  );
17609
17618
  return (a, s) => (mt(), gt(er, null, [
17610
17619
  ko(a.$slots, "default", {}, void 0, !0),
@@ -17616,7 +17625,7 @@ const NC = { class: "pp-container" }, OC = {
17616
17625
  ])
17617
17626
  ], 64));
17618
17627
  }
17619
- }), I3 = /* @__PURE__ */ ha(eF, [["__scopeId", "data-v-356bb78d"]]);
17628
+ }), I3 = /* @__PURE__ */ ha(eF, [["__scopeId", "data-v-fea395b3"]]);
17620
17629
  var nF = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
17621
17630
  function rF(e) {
17622
17631
  return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
@@ -24482,7 +24491,10 @@ const qh = /* @__PURE__ */ rF(iF), aF = { class: "gene-coexpression-viewer" }, s
24482
24491
  },
24483
24492
  setup(e) {
24484
24493
  const t = e, n = No(), r = _f(), i = wn(
24485
- () => t.dataPath ?? (n ? pe(n.s3Url) : null) ?? dB
24494
+ () => {
24495
+ var a;
24496
+ return t.dataPath ?? (n ? (a = pe(n.services)) == null ? void 0 : a.s3Url : null) ?? dB;
24497
+ }
24486
24498
  );
24487
24499
  return Vi(() => {
24488
24500
  t.initialGene1 && r.selectedGene1 === null && r.setSelectedGene1(t.initialGene1), t.initialGene2 && r.selectedGene2 === null && r.setSelectedGene2(t.initialGene2);
@@ -24498,7 +24510,7 @@ const qh = /* @__PURE__ */ rF(iF), aF = { class: "gene-coexpression-viewer" }, s
24498
24510
  ])
24499
24511
  ], 64));
24500
24512
  }
24501
- }), R3 = /* @__PURE__ */ ha(hB, [["__scopeId", "data-v-2eeb7a01"]]), pB = { class: "umap-comparison-dashboard" }, mB = {
24513
+ }), R3 = /* @__PURE__ */ ha(hB, [["__scopeId", "data-v-86d0f81d"]]), pB = { class: "umap-comparison-dashboard" }, mB = {
24502
24514
  key: 0,
24503
24515
  class: "loading-container"
24504
24516
  }, vB = {
@@ -25522,7 +25534,10 @@ const qh = /* @__PURE__ */ rF(iF), aF = { class: "gene-coexpression-viewer" }, s
25522
25534
  },
25523
25535
  setup(e) {
25524
25536
  const t = e, n = No(), r = _f(), i = wn(
25525
- () => t.dataPath ?? (n ? pe(n.s3Url) : null) ?? WB
25537
+ () => {
25538
+ var a;
25539
+ return t.dataPath ?? (n ? (a = pe(n.services)) == null ? void 0 : a.s3Url : null) ?? WB;
25540
+ }
25526
25541
  );
25527
25542
  return Vi(() => {
25528
25543
  t.initialGene && r.selectedGene === null && r.setSelectedGene(t.initialGene), t.initialMetadataColumn && r.selectedMetadataColumn === null && r.setSelectedMetadataColumn(t.initialMetadataColumn);
@@ -25538,7 +25553,7 @@ const qh = /* @__PURE__ */ rF(iF), aF = { class: "gene-coexpression-viewer" }, s
25538
25553
  ])
25539
25554
  ], 64));
25540
25555
  }
25541
- }), k3 = /* @__PURE__ */ ha(XB, [["__scopeId", "data-v-79a2dcfe"]]), QB = { class: "violin-plot-container" }, KB = {
25556
+ }), k3 = /* @__PURE__ */ ha(XB, [["__scopeId", "data-v-4fa6ccbe"]]), QB = { class: "violin-plot-container" }, KB = {
25542
25557
  key: 0,
25543
25558
  class: "loading-container"
25544
25559
  }, JB = {
@@ -25829,7 +25844,10 @@ const qh = /* @__PURE__ */ rF(iF), aF = { class: "gene-coexpression-viewer" }, s
25829
25844
  },
25830
25845
  setup(e) {
25831
25846
  const t = e, n = No(), r = _f(), i = wn(
25832
- () => t.dataPath ?? (n ? pe(n.s3Url) : null) ?? y3
25847
+ () => {
25848
+ var s;
25849
+ return t.dataPath ?? (n ? (s = pe(n.services)) == null ? void 0 : s.s3Url : null) ?? y3;
25850
+ }
25833
25851
  );
25834
25852
  Vi(() => {
25835
25853
  t.initialGene && r.selectedGeneX === null && r.setSelectedGeneX(t.initialGene), t.initialMetadataColumn && r.selectedMetadataColumn === null && r.setSelectedMetadataColumn(t.initialMetadataColumn);
@@ -25849,7 +25867,7 @@ const qh = /* @__PURE__ */ rF(iF), aF = { class: "gene-coexpression-viewer" }, s
25849
25867
  ])
25850
25868
  ], 64));
25851
25869
  }
25852
- }), N3 = /* @__PURE__ */ ha(g3, [["__scopeId", "data-v-3180d386"]]);
25870
+ }), N3 = /* @__PURE__ */ ha(g3, [["__scopeId", "data-v-d523c42c"]]);
25853
25871
  export {
25854
25872
  x3 as C,
25855
25873
  OI as D,
@@ -1,4 +1,4 @@
1
- import { B as re } from "./index-BPlDjM00.mjs";
1
+ import { B as re } from "./index-CdW9BP2T.mjs";
2
2
  const O = new Int32Array([
3
3
  0,
4
4
  1,
@@ -1,6 +1,6 @@
1
1
  import { i as rA } from "./pako.esm-D_m2s4NW.mjs";
2
- import { g as sA } from "./index-BKzfWMQL.mjs";
3
- import { B as DA } from "./index-BPlDjM00.mjs";
2
+ import { g as sA } from "./index-w9j4W2ma.mjs";
3
+ import { B as DA } from "./index-CdW9BP2T.mjs";
4
4
  const nA = {
5
5
  AddCompression: 1
6
6
  }, gA = {
@@ -1,5 +1,5 @@
1
1
  import { w as sA } from "./pako.esm-Bx5X36Wo-CzWah3nf.mjs";
2
- import { w as rA, x as gA, S as DA } from "./index-BPlDjM00.mjs";
2
+ import { w as rA, x as gA, S as DA } from "./index-CdW9BP2T.mjs";
3
3
  import { g as nA } from "./basedecoder-PoXbLGBV-BL0bCGZI.mjs";
4
4
  var EA = { exports: {} }, iA;
5
5
  function wA() {
@@ -1,4 +1,4 @@
1
- import { B as b } from "./index-BPlDjM00.mjs";
1
+ import { B as b } from "./index-CdW9BP2T.mjs";
2
2
  const B = 9, E = 256, p = 257, k = 12;
3
3
  function x(c, o, r) {
4
4
  const i = o % 8, n = Math.floor(o / 8), h = 8 - i, g = o + r - (n + 1) * 8;
@@ -1,4 +1,4 @@
1
- import { B as c } from "./index-BPlDjM00.mjs";
1
+ import { B as c } from "./index-CdW9BP2T.mjs";
2
2
  class l extends c {
3
3
  decodeBlock(s) {
4
4
  const n = new DataView(s), r = [];
@@ -1,4 +1,4 @@
1
- import { D as o, c as e, G as r, d as i, P as t, S as n, U as l, d as D, u as P, e as S } from "./index-BKzfWMQL.mjs";
1
+ import { D as o, c as e, G as r, d as i, P as t, S as n, U as l, d as D, u as P, e as S } from "./index-w9j4W2ma.mjs";
2
2
  export {
3
3
  o as DASHBOARD_GLOBAL_VARS_KEY,
4
4
  e as DataExplorer,