@vitessce/all 3.8.4 → 3.8.6

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.
@@ -1,4 +1,4 @@
1
- import { aF as getDefaultExportFromCjs, aG as Raycaster, W as OrthographicCamera, K as PerspectiveCamera, av as Scene, aH as PCFSoftShadowMap, aI as VSMShadowMap, aJ as PCFShadowMap, aK as BasicShadowMap, aL as NoToneMapping, aM as ACESFilmicToneMapping, e as Vector3, V as Vector2, aN as Clock, aO as WebGLRenderer, aP as Camera, x as BufferGeometry, r as Material, aQ as Layers, a1 as Texture, aC as RGBAFormat, ay as UnsignedByteType, C as Color, aj as _extends, aR as THREE, aS as EventDispatcher, aT as MOUSE, aU as TOUCH, aV as Spherical, Q as Quaternion, an as Ray, ak as Plane } from "./index-se6p8sp4.js";
1
+ import { aF as getDefaultExportFromCjs, aG as Raycaster, W as OrthographicCamera, K as PerspectiveCamera, av as Scene, aH as PCFSoftShadowMap, aI as VSMShadowMap, aJ as PCFShadowMap, aK as BasicShadowMap, aL as NoToneMapping, aM as ACESFilmicToneMapping, e as Vector3, V as Vector2, aN as Clock, aO as WebGLRenderer, aP as Camera, x as BufferGeometry, r as Material, aQ as Layers, a1 as Texture, aC as RGBAFormat, ay as UnsignedByteType, C as Color, aj as _extends, aR as THREE, aS as EventDispatcher, aT as MOUSE, aU as TOUCH, aV as Spherical, Q as Quaternion, an as Ray, ak as Plane } from "./index-Z-pD1WnL.js";
2
2
  import * as React from "react";
3
3
  import React__default, { useReducer, useRef, useEffect, useLayoutEffect, useDebugValue, useState, useMemo } from "react";
4
4
  var constants = { exports: {} };
@@ -1,4 +1,4 @@
1
- import { aF as getDefaultExportFromCjs, b0 as requireAssign, b1 as require_export, b2 as require_core, b3 as require_fails, b4 as require_toObject, b5 as require_objectKeys, b6 as require_cof, b7 as require_wks, b8 as require_iterators, b9 as requireWeb_dom_iterable, ba as requireEs6_string_iterator, bb as require_anObject, bc as require_hide, bd as require_ctx, be as require_toLength, bf as require_global, bg as require_objectDp, bh as require_descriptors, bi as require_isObject, bj as require_objectCreate, bk as require_iterDefine, bl as require_iterStep, bm as require_meta, bn as require_isArray, bo as require_iobject, bp as require_setToStringTag, bq as require_aFunction, br as requireIterator, bs as require_propertyDesc, aZ as commonjsGlobal, bt as requireEs6_symbol, bu as requireDefineProperty, bv as require_toIobject, bw as require_objectGopd, bx as require_html, by as require_domCreate, bz as require_library, bA as requireSymbol, bB as require_objectPie, bC as require_has, bD as require_redefine, bE as require_objectAssign, bF as diffCameraState, ao as jsxRuntimeExports } from "./index-se6p8sp4.js";
1
+ import { aF as getDefaultExportFromCjs, b0 as requireAssign, b1 as require_export, b2 as require_core, b3 as require_fails, b4 as require_toObject, b5 as require_objectKeys, b6 as require_cof, b7 as require_wks, b8 as require_iterators, b9 as requireWeb_dom_iterable, ba as requireEs6_string_iterator, bb as require_anObject, bc as require_hide, bd as require_ctx, be as require_toLength, bf as require_global, bg as require_objectDp, bh as require_descriptors, bi as require_isObject, bj as require_objectCreate, bk as require_iterDefine, bl as require_iterStep, bm as require_meta, bn as require_isArray, bo as require_iobject, bp as require_setToStringTag, bq as require_aFunction, br as requireIterator, bs as require_propertyDesc, aZ as commonjsGlobal, bt as requireEs6_symbol, bu as requireDefineProperty, bv as require_toIobject, bw as require_objectGopd, bx as require_html, by as require_domCreate, bz as require_library, bA as requireSymbol, bB as require_objectPie, bC as require_has, bD as require_redefine, bE as require_objectAssign, bF as diffCameraState, ao as jsxRuntimeExports } from "./index-Z-pD1WnL.js";
2
2
  import React__default from "react";
3
3
  var assignExports = requireAssign();
4
4
  const _Object$assign = /* @__PURE__ */ getDefaultExportFromCjs(assignExports);
@@ -1,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-SxljTded.js";
2
- import { aW as BaseDecoder } from "./index-se6p8sp4.js";
2
+ import { aW as BaseDecoder } from "./index-Z-pD1WnL.js";
3
3
  class DeflateDecoder extends BaseDecoder {
4
4
  decodeBlock(buffer) {
5
5
  return inflate_1(new Uint8Array(buffer)).buffer;
@@ -1,7 +1,7 @@
1
1
  import * as React$7 from "react";
2
2
  import React__default, { isValidElement, PureComponent, Component, createElement, createContext, createRef } from "react";
3
3
  import ReactDOM__default, { findDOMNode as findDOMNode$1 } from "react-dom";
4
- import { aZ as commonjsGlobal$1, a_ as requireObjectAssign, aF as getDefaultExportFromCjs$1, a$ as earcut } from "./index-se6p8sp4.js";
4
+ import { aZ as commonjsGlobal$1, a_ as requireObjectAssign, aF as getDefaultExportFromCjs$1, a$ as earcut } from "./index-Z-pD1WnL.js";
5
5
  var promise = {};
6
6
  var hasRequiredPromise;
7
7
  function requirePromise() {
@@ -1,6 +1,6 @@
1
- import { aw as log, ax as isEqual, ar as Data3DTexture, as as RedFormat, ay as UnsignedByteType, l as LinearFilter, az as RedIntegerFormat, aA as UnsignedIntType, m as NearestFilter, e as Vector3, V as Vector2, ag as Vector4, ae as UniformsUtils, aq as CoordinationType, aB as WebGLMultipleRenderTargets, aC as RGBAFormat, av as Scene, W as OrthographicCamera, ad as ShaderMaterial, z as Mesh, aD as PlaneGeometry, ao as jsxRuntimeExports, aE as GLSL3, am as BackSide } from "./index-se6p8sp4.js";
1
+ import { aw as log, ax as isEqual, ar as Data3DTexture, as as RedFormat, ay as UnsignedByteType, l as LinearFilter, az as RedIntegerFormat, aA as UnsignedIntType, m as NearestFilter, e as Vector3, V as Vector2, ag as Vector4, ae as UniformsUtils, aq as CoordinationType, aB as WebGLMultipleRenderTargets, aC as RGBAFormat, av as Scene, W as OrthographicCamera, ad as ShaderMaterial, z as Mesh, aD as PlaneGeometry, ao as jsxRuntimeExports, aE as GLSL3, am as BackSide } from "./index-Z-pD1WnL.js";
2
2
  import { useRef, useState, useMemo, useEffect, useCallback } from "react";
3
- import { u as useThree, a as useFrame, O as OrbitControls, C as Canvas } from "./OrbitControls-CYynRaKW.js";
3
+ import { u as useThree, a as useFrame, O as OrbitControls, C as Canvas } from "./OrbitControls-blC-_luf.js";
4
4
  const LogLevel = {
5
5
  INFO: "info",
6
6
  WARN: "warn",
@@ -220,6 +220,7 @@ function _requestBufferToRequestObjects(buffer, k) {
220
220
  class VolumeDataManager {
221
221
  constructor(glParam) {
222
222
  logWithColor$2("CLASS INITIALIZING");
223
+ log.debug("VolumeDataManager constructor", { glParam, glParamContext: glParam.getContext?.() });
223
224
  const gl = glParam.getContext?.() || glParam;
224
225
  const renderer = glParam;
225
226
  if (gl.domElement && gl.getContext) {
@@ -242,12 +243,20 @@ class VolumeDataManager {
242
243
  };
243
244
  return defaults[param] || 0;
244
245
  },
246
+ isContextLost: () => false,
245
247
  MAX_TEXTURE_SIZE: "MAX_TEXTURE_SIZE",
246
248
  MAX_3D_TEXTURE_SIZE: "MAX_3D_TEXTURE_SIZE",
247
249
  MAX_RENDERBUFFER_SIZE: "MAX_RENDERBUFFER_SIZE",
248
250
  MAX_UNIFORM_BUFFER_BINDINGS: "MAX_UNIFORM_BUFFER_BINDINGS"
249
251
  };
250
252
  }
253
+ this._originalGlParam = glParam;
254
+ this._isContextLost = false;
255
+ this._contextRestoredCallbacks = [];
256
+ if (this.gl && this.gl.canvas) {
257
+ this.gl.canvas.addEventListener("webglcontextlost", this._handleContextLost.bind(this));
258
+ this.gl.canvas.addEventListener("webglcontextrestored", this._handleContextRestored.bind(this));
259
+ }
251
260
  log.debug("GL CONSTANTS");
252
261
  log.debug(this.gl);
253
262
  log.debug(this.gl.TEXTURE0);
@@ -339,8 +348,78 @@ class VolumeDataManager {
339
348
  this.needsBailout = false;
340
349
  this.initStatus = INIT_STATUS.NOT_STARTED;
341
350
  this.initError = null;
351
+ this._lastChannelConfig = null;
342
352
  logWithColor$2("VolumeDataManager constructor complete");
343
353
  }
354
+ /**
355
+ * Handle WebGL context loss
356
+ */
357
+ _handleContextLost(event) {
358
+ logWithColor$2("CONTEXT LOST");
359
+ log.warn("WebGL context lost, preventing default and setting flag");
360
+ event.preventDefault();
361
+ this._isContextLost = true;
362
+ if (this.channels && this.channels.zarrMappings) {
363
+ this._lastChannelConfig = {
364
+ zarrMappings: [...this.channels.zarrMappings],
365
+ colorMappings: [...this.channels.colorMappings],
366
+ downsampleMin: [...this.channels.downsampleMin],
367
+ downsampleMax: [...this.channels.downsampleMax]
368
+ };
369
+ }
370
+ }
371
+ /**
372
+ * Handle WebGL context restoration
373
+ */
374
+ _handleContextRestored(event) {
375
+ logWithColor$2("CONTEXT RESTORED");
376
+ log.warn("WebGL context restored, reinitializing textures");
377
+ this._isContextLost = false;
378
+ if (this._originalGlParam && this._originalGlParam.getContext) {
379
+ this.gl = this._originalGlParam.getContext();
380
+ }
381
+ if (this._lastChannelConfig) {
382
+ this.channels.zarrMappings = [...this._lastChannelConfig.zarrMappings];
383
+ this.channels.colorMappings = [...this._lastChannelConfig.colorMappings];
384
+ this.channels.downsampleMin = [...this._lastChannelConfig.downsampleMin];
385
+ this.channels.downsampleMax = [...this._lastChannelConfig.downsampleMax];
386
+ log.debug("Restored channel configuration after context loss");
387
+ }
388
+ if (this.PT && this.zarrStore && this.zarrStore.brickLayout) {
389
+ try {
390
+ this.initMRMCPT();
391
+ log.debug("Successfully reinitialized MRMCPT after context restoration");
392
+ } catch (error) {
393
+ log.error("Failed to reinitialize MRMCPT after context restoration:", error);
394
+ }
395
+ }
396
+ this._contextRestoredCallbacks.forEach((callback) => {
397
+ try {
398
+ callback();
399
+ } catch (error) {
400
+ log.error("Error in context restored callback:", error);
401
+ }
402
+ });
403
+ }
404
+ /**
405
+ * Check if WebGL context is lost
406
+ */
407
+ isContextLost() {
408
+ if (this._isContextLost)
409
+ return true;
410
+ if (this.gl && typeof this.gl.isContextLost === "function") {
411
+ return this.gl.isContextLost();
412
+ }
413
+ return false;
414
+ }
415
+ /**
416
+ * Register a callback to be called when context is restored
417
+ */
418
+ onContextRestored(callback) {
419
+ if (typeof callback === "function") {
420
+ this._contextRestoredCallbacks.push(callback);
421
+ }
422
+ }
344
423
  initImages(images, imageLayerScopes) {
345
424
  logWithColor$2("INIT IMAGES");
346
425
  this.images = images;
@@ -629,6 +708,12 @@ class VolumeDataManager {
629
708
  log.debug("newColorMappings", newColorMappings);
630
709
  this.channels.colorMappings = newColorMappings;
631
710
  log.debug("updatedChannels", this.channels);
711
+ this._lastChannelConfig = {
712
+ zarrMappings: [...this.channels.zarrMappings],
713
+ colorMappings: [...this.channels.colorMappings],
714
+ downsampleMin: [...this.channels.downsampleMin],
715
+ downsampleMax: [...this.channels.downsampleMax]
716
+ };
632
717
  }
633
718
  /**
634
719
  * Try to load a resolution level
@@ -746,6 +831,10 @@ class VolumeDataManager {
746
831
  log.debug("processRequestData: already busy, skipping");
747
832
  return;
748
833
  }
834
+ if (this.isContextLost()) {
835
+ log.debug("processRequestData: WebGL context is lost, skipping");
836
+ return;
837
+ }
749
838
  this.isBusy = true;
750
839
  this.triggerRequest = false;
751
840
  const { requests, origRequestCount } = _requestBufferToRequestObjects(buffer, this.k);
@@ -763,6 +852,10 @@ class VolumeDataManager {
763
852
  this.needsBailout = true;
764
853
  return;
765
854
  }
855
+ if (this.isContextLost()) {
856
+ log.debug("processUsageData: WebGL context is lost, skipping");
857
+ return;
858
+ }
766
859
  this.isBusy = true;
767
860
  this.triggerUsage = false;
768
861
  const now = ++this.timeStamp;
@@ -804,6 +897,10 @@ class VolumeDataManager {
804
897
  log.error("pagetable texture not initialized");
805
898
  return;
806
899
  }
900
+ if (this.isContextLost()) {
901
+ log.warn("WebGL context is lost, skipping channel purge");
902
+ return;
903
+ }
807
904
  this.channels.downsampleMin[ptChannelIndex] = void 0;
808
905
  this.channels.downsampleMax[ptChannelIndex] = void 0;
809
906
  this.channels.zarrMappings[ptChannelIndex] = void 0;
@@ -833,6 +930,10 @@ class VolumeDataManager {
833
930
  _updatePTEntry(ptX, ptY, ptZ, ptVal) {
834
931
  if (!this.ptTHREE)
835
932
  return;
933
+ if (this.isContextLost()) {
934
+ log.warn("WebGL context is lost, skipping PT entry update");
935
+ return;
936
+ }
836
937
  const { gl } = this;
837
938
  const texPT = this.renderer.properties.get(this.ptTHREE).__webglTexture;
838
939
  gl.activeTexture(gl.TEXTURE0);
@@ -883,16 +984,51 @@ class VolumeDataManager {
883
984
  * 4. Upload one brick + PT entry *
884
985
  * ------------------------------------------------------------- */
885
986
  async _uploadBrick(ptCoord, bcSlot) {
987
+ log.debug("uploading brick", ptCoord, bcSlot);
988
+ if (this.isContextLost()) {
989
+ log.warn("WebGL context is lost, skipping brick upload");
990
+ return;
991
+ }
886
992
  if (ptCoord.x >= this.PT.xExtent || ptCoord.y >= this.PT.yExtent || ptCoord.z >= this.PT.zTotal || ptCoord.x < 0 || ptCoord.y < 0 || ptCoord.z < 0) {
887
993
  log.error("this.PT", this.PT);
888
994
  log.error("ptCoord out of bounds", ptCoord);
889
995
  return;
890
996
  }
891
997
  const { channel, resolution, x, y, z } = _ptToZarr(ptCoord.x, ptCoord.y, ptCoord.z, { PT_zExtent: this.PT.zExtent, PT_z0Extent: this.PT.z0Extent, PT_anchors: this.PT.anchors });
998
+ if (!this.channels || !this.channels.zarrMappings || this.channels.zarrMappings.length === 0) {
999
+ log.error("Channel mappings not initialized, skipping brick upload");
1000
+ return;
1001
+ }
1002
+ if (channel < 0 || channel >= this.channels.zarrMappings.length) {
1003
+ log.error("Channel index out of bounds", { channel, mappingsLength: this.channels.zarrMappings.length });
1004
+ return;
1005
+ }
892
1006
  const zarrChannel = this.channels.zarrMappings[channel];
893
1007
  if (zarrChannel === void 0 || zarrChannel === -1) {
894
- log.error("zarrChannel is undefined or -1", zarrChannel);
895
- return;
1008
+ log.warn("zarrChannel is undefined or -1", {
1009
+ zarrChannel,
1010
+ channel,
1011
+ ptCoord,
1012
+ channelMappings: this.channels.zarrMappings,
1013
+ contextLost: this.isContextLost()
1014
+ });
1015
+ if (this._lastChannelConfig && this._lastChannelConfig.zarrMappings[channel] !== void 0) {
1016
+ log.warn("Attempting to use last known channel config");
1017
+ this.channels.zarrMappings = [...this._lastChannelConfig.zarrMappings];
1018
+ this.channels.colorMappings = [...this._lastChannelConfig.colorMappings];
1019
+ this.channels.downsampleMin = [...this._lastChannelConfig.downsampleMin];
1020
+ this.channels.downsampleMax = [...this._lastChannelConfig.downsampleMax];
1021
+ const restoredZarrChannel = this.channels.zarrMappings[channel];
1022
+ if (restoredZarrChannel !== void 0 && restoredZarrChannel !== -1) {
1023
+ log.debug("Successfully restored channel mapping, continuing with upload");
1024
+ } else {
1025
+ log.error("Could not restore valid channel mapping, aborting brick upload");
1026
+ return;
1027
+ }
1028
+ } else {
1029
+ log.error("No fallback channel config available, aborting brick upload");
1030
+ return;
1031
+ }
896
1032
  }
897
1033
  log.debug("starting to load zarr chunk", { resolution, z, y, x, zarrChannel });
898
1034
  let chunk = await this.loadZarrChunk(0, zarrChannel, z, y, x, resolution);
@@ -962,6 +1098,7 @@ class VolumeDataManager {
962
1098
  if (ptRequests.length === 0)
963
1099
  return;
964
1100
  const slots = this._allocateBCSlots(ptRequests.length);
1101
+ log.debug("Handling brick requests:", { requestCount: ptRequests.length, slotCount: slots.length });
965
1102
  log.debug("handleBrickRequests: starting for loop");
966
1103
  for (let i = 0; i < ptRequests.length; ++i) {
967
1104
  log.debug("uploading brick", ptRequests[i], slots[i]);
@@ -3464,6 +3601,8 @@ function VolumeView(props) {
3464
3601
  useFrame((state, delta, xrFrame) => {
3465
3602
  if (!mrtRef.current || !dataManager || !renderManager)
3466
3603
  return;
3604
+ if (!renderState.shader)
3605
+ return;
3467
3606
  const { gl: frameGl, camera: frameCamera, scene: frameScene, clock } = state;
3468
3607
  if (!stillRef.current) {
3469
3608
  performGeometryPass(frameGl, frameCamera, frameScene, { mrtRef });
@@ -1,7 +1,7 @@
1
- import { G as Group, M as Matrix4, T as TrianglesDrawMode, a as TriangleFanDrawMode, b as TriangleStripDrawMode, R as REVISION, L as Loader, c as LoaderUtils, F as FileLoader, d as MeshPhysicalMaterial, V as Vector2, C as Color, S as SpotLight, P as PointLight, D as DirectionalLight, e as Vector3, I as InstancedMesh, Q as Quaternion, O as Object3D, f as TextureLoader, g as ImageBitmapLoader, B as BufferAttribute, h as InterleavedBuffer, i as LinearMipmapLinearFilter, N as NearestMipmapLinearFilter, j as LinearMipmapNearestFilter, k as NearestMipmapNearestFilter, l as LinearFilter, m as NearestFilter, n as RepeatWrapping, o as MirroredRepeatWrapping, p as ClampToEdgeWrapping, q as PointsMaterial, r as Material, s as LineBasicMaterial, t as MeshStandardMaterial, u as DoubleSide, v as MeshBasicMaterial, w as PropertyBinding, x as BufferGeometry, y as SkinnedMesh, z as Mesh, A as LineSegments, E as Line$1, H as LineLoop, J as Points, K as PerspectiveCamera, U as MathUtils, W as OrthographicCamera, X as Skeleton, Y as InterpolateDiscrete, Z as InterpolateLinear, _ as AnimationClip, $ as Bone, a0 as InterleavedBufferAttribute, a1 as Texture, a2 as VectorKeyframeTrack, a3 as QuaternionKeyframeTrack, a4 as NumberKeyframeTrack, a5 as FrontSide, a6 as Interpolant, a7 as Box3, a8 as Sphere, a9 as InstancedBufferGeometry, aa as Float32BufferAttribute, ab as InstancedInterleavedBuffer, ac as WireframeGeometry, ad as ShaderMaterial, ae as UniformsUtils, af as UniformsLib, ag as Vector4, ah as Line3, ai as SphereGeometry, aj as _extends, ak as Plane, al as Triangle, am as BackSide, an as Ray$1, ao as jsxRuntimeExports, ap as Matrix3, aq as CoordinationType, ar as Data3DTexture, as as RedFormat, at as FloatType, au as getImageSize, av as Scene } from "./index-se6p8sp4.js";
1
+ import { G as Group, M as Matrix4, T as TrianglesDrawMode, a as TriangleFanDrawMode, b as TriangleStripDrawMode, R as REVISION, L as Loader, c as LoaderUtils, F as FileLoader, d as MeshPhysicalMaterial, V as Vector2, C as Color, S as SpotLight, P as PointLight, D as DirectionalLight, e as Vector3, I as InstancedMesh, Q as Quaternion, O as Object3D, f as TextureLoader, g as ImageBitmapLoader, B as BufferAttribute, h as InterleavedBuffer, i as LinearMipmapLinearFilter, N as NearestMipmapLinearFilter, j as LinearMipmapNearestFilter, k as NearestMipmapNearestFilter, l as LinearFilter, m as NearestFilter, n as RepeatWrapping, o as MirroredRepeatWrapping, p as ClampToEdgeWrapping, q as PointsMaterial, r as Material, s as LineBasicMaterial, t as MeshStandardMaterial, u as DoubleSide, v as MeshBasicMaterial, w as PropertyBinding, x as BufferGeometry, y as SkinnedMesh, z as Mesh, A as LineSegments, E as Line$1, H as LineLoop, J as Points, K as PerspectiveCamera, U as MathUtils, W as OrthographicCamera, X as Skeleton, Y as InterpolateDiscrete, Z as InterpolateLinear, _ as AnimationClip, $ as Bone, a0 as InterleavedBufferAttribute, a1 as Texture, a2 as VectorKeyframeTrack, a3 as QuaternionKeyframeTrack, a4 as NumberKeyframeTrack, a5 as FrontSide, a6 as Interpolant, a7 as Box3, a8 as Sphere, a9 as InstancedBufferGeometry, aa as Float32BufferAttribute, ab as InstancedInterleavedBuffer, ac as WireframeGeometry, ad as ShaderMaterial, ae as UniformsUtils, af as UniformsLib, ag as Vector4, ah as Line3, ai as SphereGeometry, aj as _extends, ak as Plane, al as Triangle, am as BackSide, an as Ray$1, ao as jsxRuntimeExports, ap as Matrix3, aq as CoordinationType, ar as Data3DTexture, as as RedFormat, at as FloatType, au as getImageSize, av as Scene } from "./index-Z-pD1WnL.js";
2
2
  import * as React from "react";
3
3
  import { useRef, useEffect, useState, forwardRef } from "react";
4
- import { u as useThree, a as useFrame, c as create, e as extend, b as createPortal, O as OrbitControls, C as Canvas } from "./OrbitControls-CYynRaKW.js";
4
+ import { u as useThree, a as useFrame, c as create, e as extend, b as createPortal, O as OrbitControls, C as Canvas } from "./OrbitControls-blC-_luf.js";
5
5
  const isPromise = (promise) => typeof promise === "object" && typeof promise.then === "function";
6
6
  const globalCache = [];
7
7
  function shallowEqualArrays(arrA, arrB, equal = (a, b) => a === b) {
@@ -5027,7 +5027,7 @@ const Text = /* @__PURE__ */ React.forwardRef(({
5027
5027
  const {
5028
5028
  Text: TextMeshImpl,
5029
5029
  preloadFont
5030
- } = suspend(async () => import("./troika-three-text.esm-BtJXS2ob.js"), []);
5030
+ } = suspend(async () => import("./troika-three-text.esm-BsP89YlX.js"), []);
5031
5031
  const invalidate = useThree(({
5032
5032
  invalidate: invalidate2
5033
5033
  }) => invalidate2);
@@ -10157,6 +10157,7 @@ const COMPONENT_COORDINATION_TYPES = {
10157
10157
  CoordinationType$1.FEATURE_SELECTION,
10158
10158
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
10159
10159
  CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
10160
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10160
10161
  // TODO: CoordinationType.FEATURE_COLOR_ENCODING,
10161
10162
  // TODO: CoordinationType.ADDITIONAL_FEATURE_SETS,
10162
10163
  CoordinationType$1.TOOLTIPS_VISIBLE,
@@ -209322,22 +209323,22 @@ async function getDecoder(fileDirectory) {
209322
209323
  const Decoder = await importFn();
209323
209324
  return new Decoder(fileDirectory);
209324
209325
  }
209325
- addDecoder([void 0, 1], () => import("./raw-CGkykmix.js").then((m2) => m2.default));
209326
- addDecoder(5, () => import("./lzw-KgXyy-19.js").then((m2) => m2.default));
209326
+ addDecoder([void 0, 1], () => import("./raw-CRt4_45v.js").then((m2) => m2.default));
209327
+ addDecoder(5, () => import("./lzw-CE0HuE9L.js").then((m2) => m2.default));
209327
209328
  addDecoder(6, () => {
209328
209329
  throw new Error("old style JPEG compression is not supported.");
209329
209330
  });
209330
- addDecoder(7, () => import("./jpeg-BUtzsoPi.js").then((m2) => m2.default));
209331
- addDecoder([8, 32946], () => import("./deflate-Bi9jTZa_.js").then((m2) => m2.default));
209332
- addDecoder(32773, () => import("./packbits-Bmv1iZNF.js").then((m2) => m2.default));
209331
+ addDecoder(7, () => import("./jpeg-DdeYvQ7M.js").then((m2) => m2.default));
209332
+ addDecoder([8, 32946], () => import("./deflate-CsetZFHb.js").then((m2) => m2.default));
209333
+ addDecoder(32773, () => import("./packbits-z6O-xEjB.js").then((m2) => m2.default));
209333
209334
  addDecoder(
209334
209335
  34887,
209335
- () => import("./lerc-B9pxOoW2.js").then(async (m2) => {
209336
+ () => import("./lerc-D1O_lzXu.js").then(async (m2) => {
209336
209337
  await m2.zstd.init();
209337
209338
  return m2;
209338
209339
  }).then((m2) => m2.default)
209339
209340
  );
209340
- addDecoder(50001, () => import("./webimage-C9QSeLIa.js").then((m2) => m2.default));
209341
+ addDecoder(50001, () => import("./webimage-CLacHpNV.js").then((m2) => m2.default));
209341
209342
  function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
209342
209343
  return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
209343
209344
  }
@@ -231711,7 +231712,9 @@ function EmbeddingScatterplotSubscriber(props) {
231711
231712
  // Average fill density for dynamic opacity calculation.
231712
231713
  averageFillDensity,
231713
231714
  // For the dual scatterplot:
231714
- sampleSetSelection: sampleSetSelectionFromProps
231715
+ sampleSetSelection: sampleSetSelectionFromProps,
231716
+ // Circle scale factor:
231717
+ circleScaleFactor = 0.8
231715
231718
  } = props;
231716
231719
  const loaders = useLoaders();
231717
231720
  const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
@@ -231916,7 +231919,7 @@ function EmbeddingScatterplotSubscriber(props) {
231916
231919
  return null;
231917
231920
  }
231918
231921
  const size2 = Math.max(xRange, yRange);
231919
- const radius2 = size2 * Math.sqrt(2) / 2 * 0.8;
231922
+ const radius2 = size2 * Math.sqrt(2) / 2 * circleScaleFactor;
231920
231923
  const numPoints = 96;
231921
231924
  const options = { steps: numPoints, units: "degrees" };
231922
231925
  const circlePolygon = circle$5(center2, radius2, options);
@@ -231926,7 +231929,7 @@ function EmbeddingScatterplotSubscriber(props) {
231926
231929
  polygon: circlePolygon,
231927
231930
  steps: numPoints
231928
231931
  };
231929
- }, [originalViewState, width2, height2, xRange, yRange]);
231932
+ }, [originalViewState, width2, height2, xRange, yRange, circleScaleFactor]);
231930
231933
  const [alignedEmbeddingIndex, alignedEmbeddingData] = useMemo$1(() => {
231931
231934
  if (obsEmbedding?.data && obsEmbeddingIndex && matrixObsIndex) {
231932
231935
  const matrixIndexMap = new Map(matrixObsIndex.map((key2, i2) => [key2, i2]));
@@ -247754,7 +247757,7 @@ function uri2href(url) {
247754
247757
  }
247755
247758
  throw Error(`Protocol not supported, got: ${JSON.stringify(protocol)}`);
247756
247759
  }
247757
- function fetch_range$1(url, offset2, length2, opts2 = {}) {
247760
+ function fetch_range(url, offset2, length2, opts2 = {}) {
247758
247761
  if (offset2 !== void 0 && length2 !== void 0) {
247759
247762
  opts2 = {
247760
247763
  ...opts2,
@@ -247766,7 +247769,7 @@ function fetch_range$1(url, offset2, length2, opts2 = {}) {
247766
247769
  }
247767
247770
  return fetch(url, opts2);
247768
247771
  }
247769
- function merge_init$1(storeOverrides, requestOverrides) {
247772
+ function merge_init(storeOverrides, requestOverrides) {
247770
247773
  return {
247771
247774
  ...storeOverrides,
247772
247775
  ...requestOverrides,
@@ -247780,7 +247783,7 @@ function assert$5(expression2, msg = "") {
247780
247783
  if (!expression2)
247781
247784
  throw new Error(msg);
247782
247785
  }
247783
- function resolve$2(root2, path2) {
247786
+ function resolve$1(root2, path2) {
247784
247787
  const base2 = typeof root2 === "string" ? new URL(root2) : root2;
247785
247788
  if (!base2.pathname.endsWith("/")) {
247786
247789
  base2.pathname += "/";
@@ -247789,7 +247792,7 @@ function resolve$2(root2, path2) {
247789
247792
  resolved.search = base2.search;
247790
247793
  return resolved;
247791
247794
  }
247792
- async function handle_response$1(response) {
247795
+ async function handle_response(response) {
247793
247796
  if (response.status === 404) {
247794
247797
  return void 0;
247795
247798
  }
@@ -247798,7 +247801,7 @@ async function handle_response$1(response) {
247798
247801
  }
247799
247802
  throw new Error(`Unexpected response status ${response.status} ${response.statusText}`);
247800
247803
  }
247801
- async function fetch_suffix$1(url, suffix_length, init2, use_suffix_request) {
247804
+ async function fetch_suffix(url, suffix_length, init2, use_suffix_request) {
247802
247805
  if (use_suffix_request) {
247803
247806
  return fetch(url, {
247804
247807
  ...init2,
@@ -247811,9 +247814,9 @@ async function fetch_suffix$1(url, suffix_length, init2, use_suffix_request) {
247811
247814
  }
247812
247815
  let content_length = response.headers.get("Content-Length");
247813
247816
  let length2 = Number(content_length);
247814
- return fetch_range$1(url, length2 - suffix_length, length2, init2);
247817
+ return fetch_range(url, length2 - suffix_length, length2, init2);
247815
247818
  }
247816
- let FetchStore$1 = class FetchStore {
247819
+ class FetchStore {
247817
247820
  #overrides;
247818
247821
  #use_suffix_request;
247819
247822
  constructor(url, options = {}) {
@@ -247822,25 +247825,25 @@ let FetchStore$1 = class FetchStore {
247822
247825
  this.#use_suffix_request = options.useSuffixRequest ?? false;
247823
247826
  }
247824
247827
  #merge_init(overrides) {
247825
- return merge_init$1(this.#overrides, overrides);
247828
+ return merge_init(this.#overrides, overrides);
247826
247829
  }
247827
247830
  async get(key2, options = {}) {
247828
- let href2 = resolve$2(this.url, key2).href;
247831
+ let href2 = resolve$1(this.url, key2).href;
247829
247832
  let response = await fetch(href2, this.#merge_init(options));
247830
- return handle_response$1(response);
247833
+ return handle_response(response);
247831
247834
  }
247832
247835
  async getRange(key2, range2, options = {}) {
247833
- let url = resolve$2(this.url, key2);
247836
+ let url = resolve$1(this.url, key2);
247834
247837
  let init2 = this.#merge_init(options);
247835
247838
  let response;
247836
247839
  if ("suffixLength" in range2) {
247837
- response = await fetch_suffix$1(url, range2.suffixLength, init2, this.#use_suffix_request);
247840
+ response = await fetch_suffix(url, range2.suffixLength, init2, this.#use_suffix_request);
247838
247841
  } else {
247839
- response = await fetch_range$1(url, range2.offset, range2.length, init2);
247842
+ response = await fetch_range(url, range2.offset, range2.length, init2);
247840
247843
  }
247841
- return handle_response$1(response);
247844
+ return handle_response(response);
247842
247845
  }
247843
- };
247846
+ }
247844
247847
  let BoolArray$1 = class BoolArray {
247845
247848
  #bytes;
247846
247849
  constructor(x2, byteOffset, length2) {
@@ -250132,7 +250135,7 @@ class HTTPRangeReader {
250132
250135
  if (size2 === 0) {
250133
250136
  return new Uint8Array(0);
250134
250137
  }
250135
- const req = await fetch_range$1(this.url, offset2, size2, this.#overrides);
250138
+ const req = await fetch_range(this.url, offset2, size2, this.#overrides);
250136
250139
  assert$5(req.ok, `failed http request ${this.url}, status: ${req.status} offset: ${offset2} size: ${size2}: ${req.statusText}`);
250137
250140
  return new Uint8Array(await req.arrayBuffer());
250138
250141
  }
@@ -250400,7 +250403,7 @@ class ReferenceStore {
250400
250403
  if (!url) {
250401
250404
  throw Error(`No url for key ${key2}, and no target url provided.`);
250402
250405
  }
250403
- let res = await fetch_range$1(uri2href(url), offset2, size2, merge_init$1(this.#overrides, opts2));
250406
+ let res = await fetch_range(uri2href(url), offset2, size2, merge_init(this.#overrides, opts2));
250404
250407
  if (res.status === 200 || res.status === 206) {
250405
250408
  return new Uint8Array(await res.arrayBuffer());
250406
250409
  }
@@ -250415,7 +250418,7 @@ class ReferenceStore {
250415
250418
  return ReferenceStore.fromSpec(spec, opts2);
250416
250419
  }
250417
250420
  }
250418
- class RelaxedFetchStore extends FetchStore$1 {
250421
+ class RelaxedFetchStore extends FetchStore {
250419
250422
  // This allows returning `undefined` for 403 responses,
250420
250423
  // as opposed to completely erroring.
250421
250424
  // Needed due to https://github.com/manzt/zarrita.js/pull/212
@@ -253033,12 +253036,12 @@ class ErrorBoundary extends React__default.Component {
253033
253036
  }
253034
253037
  }
253035
253038
  const LazySpatialThree = React__default.lazy(async () => {
253036
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-SV2fA7OO.js");
253039
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-VG1RjUEu.js");
253037
253040
  return { default: SpatialWrapper2 };
253038
253041
  });
253039
253042
  const SpatialThreeAdapter = React__default.forwardRef((props, ref2) => jsxRuntimeExports.jsx("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsxRuntimeExports.jsx(ErrorBoundary, { children: jsxRuntimeExports.jsx(Suspense, { fallback: jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: jsxRuntimeExports.jsx(LazySpatialThree, { ...props }) }) }) }));
253040
253043
  const LazySpatialAccelerated = React__default.lazy(async () => {
253041
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-BiA0XI99.js");
253044
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-CHxaVZhJ.js");
253042
253045
  return { default: SpatialWrapper2 };
253043
253046
  });
253044
253047
  const SpatialAcceleratedAdapter = React__default.forwardRef((props, ref2) => jsxRuntimeExports.jsx("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsxRuntimeExports.jsx(ErrorBoundary, { children: jsxRuntimeExports.jsx(Suspense, { fallback: jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: jsxRuntimeExports.jsx(LazySpatialAccelerated, { ...props }) }) }) }));
@@ -265935,89 +265938,6 @@ function set_from_chunk_binary(dest, src, bytes_per_element2, projections2) {
265935
265938
  }, bytes_per_element2, projs);
265936
265939
  }
265937
265940
  }
265938
- function fetch_range(url, offset2, length2, opts2 = {}) {
265939
- if (offset2 !== void 0 && length2 !== void 0) {
265940
- opts2 = {
265941
- ...opts2,
265942
- headers: {
265943
- ...opts2.headers,
265944
- Range: `bytes=${offset2}-${offset2 + length2 - 1}`
265945
- }
265946
- };
265947
- }
265948
- return fetch(url, opts2);
265949
- }
265950
- function merge_init(storeOverrides, requestOverrides) {
265951
- return {
265952
- ...storeOverrides,
265953
- ...requestOverrides,
265954
- headers: {
265955
- ...storeOverrides.headers,
265956
- ...requestOverrides.headers
265957
- }
265958
- };
265959
- }
265960
- function resolve$1(root2, path2) {
265961
- const base2 = typeof root2 === "string" ? new URL(root2) : root2;
265962
- if (!base2.pathname.endsWith("/")) {
265963
- base2.pathname += "/";
265964
- }
265965
- const resolved = new URL(path2.slice(1), base2);
265966
- resolved.search = base2.search;
265967
- return resolved;
265968
- }
265969
- async function handle_response(response) {
265970
- if (response.status === 404) {
265971
- return void 0;
265972
- }
265973
- if (response.status === 200 || response.status === 206) {
265974
- return new Uint8Array(await response.arrayBuffer());
265975
- }
265976
- throw new Error(`Unexpected response status ${response.status} ${response.statusText}`);
265977
- }
265978
- async function fetch_suffix(url, suffix_length, init2, use_suffix_request) {
265979
- if (use_suffix_request) {
265980
- return fetch(url, {
265981
- ...init2,
265982
- headers: { ...init2.headers, Range: `bytes=-${suffix_length}` }
265983
- });
265984
- }
265985
- let response = await fetch(url, { ...init2, method: "HEAD" });
265986
- if (!response.ok) {
265987
- return response;
265988
- }
265989
- let content_length = response.headers.get("Content-Length");
265990
- let length2 = Number(content_length);
265991
- return fetch_range(url, length2 - suffix_length, length2, init2);
265992
- }
265993
- class FetchStore2 {
265994
- #overrides;
265995
- #use_suffix_request;
265996
- constructor(url, options = {}) {
265997
- this.url = url;
265998
- this.#overrides = options.overrides ?? {};
265999
- this.#use_suffix_request = options.useSuffixRequest ?? false;
266000
- }
266001
- #merge_init(overrides) {
266002
- return merge_init(this.#overrides, overrides);
266003
- }
266004
- async get(key2, options = {}) {
266005
- let href2 = resolve$1(this.url, key2).href;
266006
- let response = await fetch(href2, this.#merge_init(options));
266007
- return handle_response(response);
266008
- }
266009
- async getRange(key2, range2, options = {}) {
266010
- let url = resolve$1(this.url, key2);
266011
- let init2 = this.#merge_init(options);
266012
- let response;
266013
- if ("suffixLength" in range2) {
266014
- response = await fetch_suffix(url, range2.suffixLength, init2, this.#use_suffix_request);
266015
- } else {
266016
- response = await fetch_range(url, range2.offset, range2.length, init2);
266017
- }
266018
- return handle_response(response);
266019
- }
266020
- }
266021
265941
  function multivecChunksToTileDenseArray(chunks, tileShape, isRow) {
266022
265942
  const fullTileLength = isRow ? tileShape[1] : tileShape[0] * tileShape[1];
266023
265943
  const fullTileArray = new Float32Array(fullTileLength);
@@ -266063,7 +265983,7 @@ var ZarrMultivecDataFetcher = function ZarrMultivecDataFetcher2(HGC, ...args) {
266063
265983
  this.storeRoot = Promise.resolve(ZarrMultivecDataFetcher2.urlToStoreRoot[dataConfig.url]);
266064
265984
  } else if (dataConfig.url) {
266065
265985
  const { url, options = {} } = dataConfig;
266066
- this.store = new FetchStore2(url, options);
265986
+ this.store = new FetchStore(url, options);
266067
265987
  this.storeRoot = Promise.resolve(root(this.store));
266068
265988
  }
266069
265989
  if (dataConfig.row !== void 0) {
@@ -266239,7 +266159,7 @@ function HiglassGlobalStyles(props) {
266239
266159
  }
266240
266160
  register({ dataFetcher: ZarrMultivecDataFetcher_default, config: ZarrMultivecDataFetcher_default.config }, { pluginType: "dataFetcher" });
266241
266161
  const LazyHiGlassComponent = React__default.lazy(async () => {
266242
- const { HiGlassComponent } = await import("./higlass-DlJQBL8o.js");
266162
+ const { HiGlassComponent } = await import("./higlass-BYlgWL_Y.js");
266243
266163
  return { default: HiGlassComponent };
266244
266164
  });
266245
266165
  const HG_SIZE = 800;
@@ -269186,7 +269106,7 @@ function NeuroglancerGlobalStyles(props) {
269186
269106
  const { classes: classes2 } = props;
269187
269107
  return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx(GlobalStyles$3, { styles: globalNeuroglancerCss }), jsxRuntimeExports.jsx(ScopedGlobalStyles, { styles: globalNeuroglancerStyles, parentClassName: classes2.neuroglancerWrapper })] });
269188
269108
  }
269189
- const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-B784BBrr.js"));
269109
+ const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-BV_821il.js"));
269190
269110
  function createWorker() {
269191
269111
  return new WorkerFactory();
269192
269112
  }
@@ -299439,6 +299359,7 @@ accessor$1(() => 0, [], "zero");
299439
299359
  accessor$1(() => 1, [], "one");
299440
299360
  accessor$1(() => true, [], "true");
299441
299361
  accessor$1(() => false, [], "false");
299362
+ /* @__PURE__ */ new Set([...Object.getOwnPropertyNames(Object.prototype).filter((name2) => typeof Object.prototype[name2] === "function"), "__proto__"]);
299442
299363
  var isArray$2 = Array.isArray;
299443
299364
  function peek$2(array2) {
299444
299365
  return array2[array2.length - 1];
@@ -301721,8 +301642,7 @@ function splitAccessPath(p) {
301721
301642
  for (i2 = j = 0; j < n3; ++j) {
301722
301643
  c2 = p[j];
301723
301644
  if (c2 === "\\") {
301724
- s2 += p.substring(i2, j);
301725
- s2 += p.substring(++j, ++j);
301645
+ s2 += p.substring(i2, j++);
301726
301646
  i2 = j;
301727
301647
  } else if (c2 === q) {
301728
301648
  push2();
@@ -301780,7 +301700,8 @@ const Error$1 = 1;
301780
301700
  const Warn = 2;
301781
301701
  const Info2 = 3;
301782
301702
  const Debug = 4;
301783
- function logger(_, method2, handler = log$1$1) {
301703
+ function logger(_, method2) {
301704
+ let handler = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : log$1$1;
301784
301705
  let level = _ || None$2;
301785
301706
  return {
301786
301707
  level(_2) {
@@ -301814,7 +301735,10 @@ function isObject$2(_) {
301814
301735
  return _ === Object(_);
301815
301736
  }
301816
301737
  const isLegalKey = (key2) => key2 !== "__proto__";
301817
- function mergeConfig(...configs) {
301738
+ function mergeConfig() {
301739
+ for (var _len = arguments.length, configs = new Array(_len), _key = 0; _key < _len; _key++) {
301740
+ configs[_key] = arguments[_key];
301741
+ }
301818
301742
  return configs.reduce((out, source2) => {
301819
301743
  for (const key2 in source2) {
301820
301744
  if (key2 === "signals") {
@@ -302052,9 +301976,8 @@ function extentIndex(array2, f2) {
302052
301976
  }
302053
301977
  return [u2, v];
302054
301978
  }
302055
- const hop = Object.prototype.hasOwnProperty;
302056
301979
  function has$1(object2, property2) {
302057
- return hop.call(object2, property2);
301980
+ return Object.hasOwn(object2, property2);
302058
301981
  }
302059
301982
  const NULL = {};
302060
301983
  function fastmap(input) {
@@ -353838,7 +353761,7 @@ const initialState$1 = {
353838
353761
  };
353839
353762
  const pageSizeOptions$1 = [10];
353840
353763
  function FeatureStatsTable(props) {
353841
- const { obsType, featureType, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, data: data2, setFeatureSelection, featurePointSignificanceThreshold, featurePointFoldChangeThreshold } = props;
353764
+ const { obsType, featureType, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, data: data2, setFeatureSelection, setFeatureAggregationStrategy, featurePointSignificanceThreshold, featurePointFoldChangeThreshold } = props;
353842
353765
  const [
353843
353766
  // eslint-disable-next-line no-unused-vars
353844
353767
  computedData,
@@ -353898,6 +353821,7 @@ function FeatureStatsTable(props) {
353898
353821
  }, [filteredData, obsSetsColumnNameMappingReversed]);
353899
353822
  const onSelectionModelChange = useCallback((rowIds) => {
353900
353823
  const featureIds = Array.from(rowIds.ids).map((rowId) => rowId.split(ROW_ID_DELIMITER)[0]);
353824
+ setFeatureAggregationStrategy(null);
353901
353825
  setFeatureSelection(featureIds);
353902
353826
  }, []);
353903
353827
  const rowSelectionModel = useMemo$1(() => ({ ids: /* @__PURE__ */ new Set([]), type: "include" }), []);
@@ -353921,7 +353845,7 @@ function FeatureStatsTableSubscriber(props) {
353921
353845
  const { title: title2 = "Differential Expression Results", coordinationScopes: coordinationScopesRaw, removeGridComponent, theme, helpText = ViewHelpMapping.FEATURE_STATS_TABLE } = props;
353922
353846
  const loaders = useLoaders();
353923
353847
  const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
353924
- const [{ dataset, obsType, sampleType, featureType, featureValueType, obsFilter: cellFilter, obsHighlight: cellHighlight, obsSetSelection, obsSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureValueTransform, featureValueTransformCoefficient, gatingFeatureSelectionX, gatingFeatureSelectionY, featureSelection, sampleSetSelection, sampleSetColor }, { setObsFilter: setCellFilter, setObsSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold, setFeatureValueTransform, setFeatureValueTransformCoefficient, setGatingFeatureSelectionX, setGatingFeatureSelectionY, setFeatureSelection, setSampleSetSelection, setSampleSetColor }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_STATS_TABLE], coordinationScopes);
353848
+ const [{ dataset, obsType, sampleType, featureType, featureValueType, obsFilter: cellFilter, obsHighlight: cellHighlight, obsSetSelection, obsSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureValueTransform, featureValueTransformCoefficient, featureAggregationStrategy, gatingFeatureSelectionX, gatingFeatureSelectionY, featureSelection, sampleSetSelection, sampleSetColor }, { setObsFilter: setCellFilter, setObsSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold, setFeatureValueTransform, setFeatureValueTransformCoefficient, setFeatureAggregationStrategy, setGatingFeatureSelectionX, setGatingFeatureSelectionY, setFeatureSelection, setSampleSetSelection, setSampleSetColor }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_STATS_TABLE], coordinationScopes);
353925
353849
  const obsSetsLoader = useMatchingLoader(loaders, dataset, DataType$3.OBS_SETS, { obsType });
353926
353850
  const sampleSetsLoader = useMatchingLoader(loaders, dataset, DataType$3.SAMPLE_SETS, { sampleType });
353927
353851
  const obsSetsColumnNameMapping = useColumnNameMapping(obsSetsLoader);
@@ -353944,7 +353868,7 @@ function FeatureStatsTableSubscriber(props) {
353944
353868
  const isReady = useReady([
353945
353869
  featureStatsStatus
353946
353870
  ]);
353947
- return jsxRuntimeExports.jsx(TitleInfo, { title: title2, removeGridComponent, theme, isReady, helpText, errors, withPadding: false, children: featureStats ? jsxRuntimeExports.jsx(FeatureStatsTable, { theme, obsType, featureType, obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: featureStats, featureSelection, setFeatureSelection, featurePointSignificanceThreshold, featurePointFoldChangeThreshold }) : jsxRuntimeExports.jsxs("p", { style: { padding: "12px" }, children: ["Select at least one ", obsType, " set."] }) });
353871
+ return jsxRuntimeExports.jsx(TitleInfo, { title: title2, removeGridComponent, theme, isReady, helpText, errors, withPadding: false, children: featureStats ? jsxRuntimeExports.jsx(FeatureStatsTable, { theme, obsType, featureType, obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: featureStats, featureSelection, setFeatureSelection, setFeatureAggregationStrategy, featurePointSignificanceThreshold, featurePointFoldChangeThreshold }) : jsxRuntimeExports.jsxs("p", { style: { padding: "12px" }, children: ["Select at least one ", obsType, " set."] }) });
353948
353872
  }
353949
353873
  class CsvSource {
353950
353874
  constructor({ url, requestInit: requestInit2 }) {
@@ -354080,6 +354004,24 @@ class ObsLabelsCsvLoader extends CsvLoader {
354080
354004
  return this.cachedResult;
354081
354005
  }
354082
354006
  }
354007
+ class VitessceConfigViewHConcat {
354008
+ constructor(views) {
354009
+ this.views = views;
354010
+ }
354011
+ }
354012
+ class VitessceConfigViewVConcat {
354013
+ constructor(views) {
354014
+ this.views = views;
354015
+ }
354016
+ }
354017
+ function hconcat(...views) {
354018
+ const vcvhc = new VitessceConfigViewHConcat(views);
354019
+ return vcvhc;
354020
+ }
354021
+ function vconcat(...views) {
354022
+ const vcvvc = new VitessceConfigViewVConcat(views);
354023
+ return vcvvc;
354024
+ }
354083
354025
  class CoordinationLevel {
354084
354026
  constructor(value2) {
354085
354027
  this.value = value2;
@@ -354098,6 +354040,233 @@ class CoordinationLevel {
354098
354040
  function CL(value2) {
354099
354041
  return new CoordinationLevel(value2);
354100
354042
  }
354043
+ class AbstractAutoConfig {
354044
+ constructor(parsedStore) {
354045
+ const { url, fileType, zmetadata } = parsedStore;
354046
+ this.url = url;
354047
+ this.fileType = fileType;
354048
+ this.zmetadata = zmetadata;
354049
+ }
354050
+ // eslint-disable-next-line class-methods-use-this
354051
+ addFiles(vc, dataset) {
354052
+ throw new Error("The addFiles() method has not been implemented.");
354053
+ }
354054
+ // eslint-disable-next-line class-methods-use-this
354055
+ addViews(vc, dataset, layoutOption) {
354056
+ throw new Error("The addViews() method has not been implemented.");
354057
+ }
354058
+ }
354059
+ class AnnDataAutoConfig extends AbstractAutoConfig {
354060
+ getOptions() {
354061
+ const { zmetadata } = this;
354062
+ const options = {
354063
+ obsEmbedding: [],
354064
+ obsSets: []
354065
+ };
354066
+ zmetadata.forEach(({ path: path2, attrs }) => {
354067
+ const lowerPath = path2.toLowerCase();
354068
+ const relPath = path2.substring(1);
354069
+ if (["/x"].includes(lowerPath)) {
354070
+ options.obsFeatureMatrix = {
354071
+ path: relPath
354072
+ // TODO: Also check the shape of X.
354073
+ // If X is very large, try to initialize initial-filtering properties
354074
+ // (will require that /var contains a boolean column however.)
354075
+ };
354076
+ }
354077
+ if (["/obsm/x_spatial", "/obsm/spatial"].includes(lowerPath)) {
354078
+ options.obsLocations = {
354079
+ path: relPath
354080
+ };
354081
+ }
354082
+ if (["/obsm/x_umap", "/obsm/umap"].includes(lowerPath)) {
354083
+ options.obsEmbedding.push({ path: relPath, embeddingType: "UMAP" });
354084
+ }
354085
+ if (["/obsm/x_tsne", "/obsm/tsne"].includes(lowerPath)) {
354086
+ options.obsEmbedding.push({ path: relPath, embeddingType: "t-SNE" });
354087
+ }
354088
+ if (["/obsm/x_pca", "/obsm/pca"].includes(lowerPath)) {
354089
+ options.obsEmbedding.push({ path: relPath, embeddingType: "PCA" });
354090
+ }
354091
+ const supportedObsSetsPaths = [
354092
+ "cluster",
354093
+ "clusters",
354094
+ "subcluster",
354095
+ "cell_type",
354096
+ "celltype",
354097
+ "leiden",
354098
+ "louvain",
354099
+ "disease",
354100
+ "organism",
354101
+ "self_reported_ethnicity",
354102
+ "tissue",
354103
+ "sex"
354104
+ ].map((colname) => `/obs/${colname}`);
354105
+ if (supportedObsSetsPaths.includes(lowerPath)) {
354106
+ const name2 = relPath.split("/").at(-1);
354107
+ options.obsSets.push({ path: relPath, name: name2 });
354108
+ }
354109
+ });
354110
+ return options;
354111
+ }
354112
+ addFiles(vc, dataset) {
354113
+ const { url, fileType } = this;
354114
+ dataset.addFile({
354115
+ url,
354116
+ fileType,
354117
+ options: this.getOptions()
354118
+ // TODO: coordination values?
354119
+ });
354120
+ }
354121
+ // eslint-disable-next-line class-methods-use-this
354122
+ addViews(vc, dataset, layoutOption) {
354123
+ }
354124
+ }
354125
+ class SpatialDataAutoConfig extends AbstractAutoConfig {
354126
+ getOptions() {
354127
+ const { zmetadata } = this;
354128
+ const options = {};
354129
+ const availableElements = zmetadata.filter(({ path: path2 }) => {
354130
+ const relPath = path2.substring(1);
354131
+ return relPath.match(/^(tables|table|images|labels|shapes|points)\/([^/]*)$/);
354132
+ });
354133
+ availableElements.forEach(({ path: path2, attrs }) => {
354134
+ const relPath = path2.substring(1);
354135
+ const firstCoordinateSystem = attrs?.multiscales?.[0]?.coordinateTransformations?.[0]?.output?.name;
354136
+ if (relPath.match(/^(images)\/([^/]*)$/)) {
354137
+ options.image = {
354138
+ path: relPath,
354139
+ coordinateSystem: firstCoordinateSystem
354140
+ // TODO: support a fileUid property in the schema?
354141
+ };
354142
+ }
354143
+ if (relPath.match(/^(labels)\/([^/]*)$/)) {
354144
+ options.obsSegmentations = {
354145
+ path: relPath,
354146
+ coordinateSystem: firstCoordinateSystem
354147
+ // TODO: support a fileUid property in the schema?
354148
+ };
354149
+ }
354150
+ if (relPath.match(/^(shapes)\/([^/]*)$/)) {
354151
+ options.obsSpots = {
354152
+ path: relPath,
354153
+ coordinateSystem: firstCoordinateSystem
354154
+ };
354155
+ }
354156
+ if (relPath.match(/^(points)\/([^/]*)$/)) {
354157
+ options.obsPoints = {
354158
+ path: relPath,
354159
+ coordinateSystem: firstCoordinateSystem
354160
+ };
354161
+ }
354162
+ if (relPath.match(/^(tables|table)\/([^/]*)$/)) {
354163
+ const tableEls = zmetadata.filter(({ path: subpath }) => subpath.startsWith(path2));
354164
+ const hasX = tableEls.find((el) => el.path === `${path2}/X`);
354165
+ if (hasX) {
354166
+ options.obsFeatureMatrix = {
354167
+ path: hasX.path.substring(1)
354168
+ // region: null,
354169
+ };
354170
+ }
354171
+ const hasObs = tableEls.find((el) => el.path === `${path2}/obs`);
354172
+ if (hasObs) {
354173
+ const columnOrder = hasObs.attrs?.["column-order"];
354174
+ options.obsSets = {
354175
+ // region: null,
354176
+ tablePath: relPath,
354177
+ obsSets: columnOrder.map((c2) => ({
354178
+ // TODO: determine whether this column is string/categorical.
354179
+ // TODO: determine whether this column contains too many
354180
+ // categories to make sense to consider a cell set.
354181
+ path: `${hasObs.path.substring(1)}/${c2}`,
354182
+ name: c2
354183
+ }))
354184
+ };
354185
+ }
354186
+ }
354187
+ });
354188
+ return options;
354189
+ }
354190
+ addFiles(vc, dataset) {
354191
+ const { url, fileType } = this;
354192
+ dataset.addFile({
354193
+ url,
354194
+ fileType,
354195
+ options: this.getOptions()
354196
+ // TODO: coordination values?
354197
+ });
354198
+ }
354199
+ // eslint-disable-next-line class-methods-use-this
354200
+ addViews(vc, dataset, layoutOption) {
354201
+ const options = this.getOptions();
354202
+ const spatialView = vc.addView(dataset, "spatialBeta");
354203
+ const lcView = vc.addView(dataset, "layerControllerBeta");
354204
+ const controlViews = [lcView];
354205
+ if (options.obsSets) {
354206
+ const obsSets = vc.addView(dataset, "obsSets");
354207
+ controlViews.push(obsSets);
354208
+ }
354209
+ if (options.obsFeatureMatrix) {
354210
+ const featureList = vc.addView(dataset, "featureList");
354211
+ controlViews.push(featureList);
354212
+ }
354213
+ vc.layout(hconcat(spatialView, vconcat(...controlViews)));
354214
+ }
354215
+ }
354216
+ class OmeAutoConfig extends AbstractAutoConfig {
354217
+ addFiles(vc, dataset) {
354218
+ const { url, fileType } = this;
354219
+ dataset.addFile({
354220
+ url,
354221
+ fileType
354222
+ // TODO: options?
354223
+ // TODO: coordination values?
354224
+ });
354225
+ }
354226
+ // eslint-disable-next-line class-methods-use-this
354227
+ addViews(vc, dataset, layoutOption) {
354228
+ const spatialView = vc.addView(dataset, "spatialBeta");
354229
+ const lcView = vc.addView(dataset, "layerControllerBeta");
354230
+ vc.layout(hconcat(spatialView, lcView));
354231
+ }
354232
+ }
354233
+ ({
354234
+ [FileType$1.IMAGE_OME_TIFF]: [".ome.tif", ".ome.tiff", ".ome.tf2", ".ome.tf8"],
354235
+ [FileType$1.IMAGE_OME_ZARR]: [".ome.zarr"],
354236
+ [FileType$1.IMAGE_OME_ZARR_ZIP]: [".ome.zarr.zip"],
354237
+ [FileType$1.ANNDATA_ZARR]: [".ad.zarr", ".h5ad.zarr", ".adata.zarr", ".anndata.zarr"],
354238
+ [FileType$1.ANNDATA_ZARR_ZIP]: [".ad.zarr.zip", ".h5ad.zarr.zip", ".adata.zarr.zip", ".anndata.zarr.zip"],
354239
+ // TODO: how to handle h5ad-based AnnData (since needs reference JSON file).
354240
+ // Perhaps just assume one H5AD+one JSON (or .ref.json) file correspond to each other?
354241
+ [FileType$1.SPATIALDATA_ZARR]: [".sd.zarr", ".sdata.zarr", ".spatialdata.zarr"],
354242
+ [FileType$1.SPATIALDATA_ZARR_ZIP]: [".sd.zarr.zip", ".sdata.zarr.zip", ".spatialdata.zarr.zip"]
354243
+ });
354244
+ ({
354245
+ // OME-TIFF
354246
+ [FileType$1.IMAGE_OME_TIFF]: OmeAutoConfig,
354247
+ [FileType$1.OBS_SEGMENTATIONS_OME_TIFF]: OmeAutoConfig,
354248
+ // OME-Zarr
354249
+ [FileType$1.IMAGE_OME_ZARR]: OmeAutoConfig,
354250
+ [FileType$1.IMAGE_OME_ZARR_ZIP]: OmeAutoConfig,
354251
+ [FileType$1.OBS_SEGMENTATIONS_OME_ZARR]: OmeAutoConfig,
354252
+ [FileType$1.OBS_SEGMENTATIONS_OME_ZARR_ZIP]: OmeAutoConfig,
354253
+ // AnnData
354254
+ [FileType$1.ANNDATA_ZARR]: AnnDataAutoConfig,
354255
+ [FileType$1.ANNDATA_ZARR_ZIP]: AnnDataAutoConfig,
354256
+ // SpatialData
354257
+ [FileType$1.SPATIALDATA_ZARR]: SpatialDataAutoConfig,
354258
+ [FileType$1.SPATIALDATA_ZARR_ZIP]: SpatialDataAutoConfig
354259
+ });
354260
+ [
354261
+ FileType$1.ANNDATA_ZARR,
354262
+ FileType$1.ANNDATA_ZARR_ZIP,
354263
+ FileType$1.SPATIALDATA_ZARR,
354264
+ FileType$1.SPATIALDATA_ZARR_ZIP,
354265
+ FileType$1.IMAGE_OME_ZARR,
354266
+ FileType$1.IMAGE_OME_ZARR_ZIP,
354267
+ FileType$1.OBS_SEGMENTATIONS_OME_ZARR,
354268
+ FileType$1.OBS_SEGMENTATIONS_OME_ZARR_ZIP
354269
+ ];
354101
354270
  class ObsSpotsCsvLoader extends CsvLoader {
354102
354271
  loadFromCache(data2) {
354103
354272
  if (this.cachedResult) {
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { bQ, bO, bM, bP, bN, bL, bR } from "./index-se6p8sp4.js";
1
+ import { bQ, bO, bM, bP, bN, bL, bR } from "./index-Z-pD1WnL.js";
2
2
  import { useComplexCoordination, useComplexCoordinationSecondary, useCoordination, useCoordinationScopes, useCoordinationScopesBy, useGridItemSize, useMultiCoordinationScopesNonNull, useMultiCoordinationScopesSecondaryNonNull, usePageModeView } from "@vitessce/vit-s";
3
3
  export {
4
4
  bQ as PluginAsyncFunction,
@@ -1,4 +1,4 @@
1
- import { aW as BaseDecoder } from "./index-se6p8sp4.js";
1
+ import { aW as BaseDecoder } from "./index-Z-pD1WnL.js";
2
2
  const dctZigZag = new Int32Array([
3
3
  0,
4
4
  1,
@@ -1,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-SxljTded.js";
2
- import { aF as getDefaultExportFromCjs, aW as BaseDecoder, aX as LercParameters, aY as LercAddCompression } from "./index-se6p8sp4.js";
2
+ import { aF as getDefaultExportFromCjs, aW as BaseDecoder, aX as LercParameters, aY as LercAddCompression } from "./index-Z-pD1WnL.js";
3
3
  var LercDecode = { exports: {} };
4
4
  var hasRequiredLercDecode;
5
5
  function requireLercDecode() {
@@ -1,4 +1,4 @@
1
- import { aW as BaseDecoder } from "./index-se6p8sp4.js";
1
+ import { aW as BaseDecoder } from "./index-Z-pD1WnL.js";
2
2
  const MIN_BITS = 9;
3
3
  const CLEAR_CODE = 256;
4
4
  const EOI_CODE = 257;
@@ -1,4 +1,4 @@
1
- import { aW as BaseDecoder } from "./index-se6p8sp4.js";
1
+ import { aW as BaseDecoder } from "./index-Z-pD1WnL.js";
2
2
  class PackbitsDecoder extends BaseDecoder {
3
3
  decodeBlock(buffer) {
4
4
  const dataView = new DataView(buffer);
@@ -1,4 +1,4 @@
1
- import { aW as BaseDecoder } from "./index-se6p8sp4.js";
1
+ import { aW as BaseDecoder } from "./index-Z-pD1WnL.js";
2
2
  class RawDecoder extends BaseDecoder {
3
3
  decodeBlock(buffer) {
4
4
  return buffer;
@@ -1,4 +1,4 @@
1
- import { bG as MeshDistanceMaterial, bH as MeshDepthMaterial, bI as RGBADepthPacking, ae as UniformsUtils, bJ as ShaderChunk, a9 as InstancedBufferGeometry, a8 as Sphere, a7 as Box3, am as BackSide, u as DoubleSide, z as Mesh, a5 as FrontSide, v as MeshBasicMaterial, C as Color, e as Vector3, M as Matrix4, V as Vector2, ap as Matrix3, ag as Vector4, a1 as Texture, l as LinearFilter, aD as PlaneGeometry, x as BufferGeometry, aa as Float32BufferAttribute, bK as InstancedBufferAttribute } from "./index-se6p8sp4.js";
1
+ import { bG as MeshDistanceMaterial, bH as MeshDepthMaterial, bI as RGBADepthPacking, ae as UniformsUtils, bJ as ShaderChunk, a9 as InstancedBufferGeometry, a8 as Sphere, a7 as Box3, am as BackSide, u as DoubleSide, z as Mesh, a5 as FrontSide, v as MeshBasicMaterial, C as Color, e as Vector3, M as Matrix4, V as Vector2, ap as Matrix3, ag as Vector4, a1 as Texture, l as LinearFilter, aD as PlaneGeometry, x as BufferGeometry, aa as Float32BufferAttribute, bK as InstancedBufferAttribute } from "./index-Z-pD1WnL.js";
2
2
  function workerBootstrap() {
3
3
  var modules = /* @__PURE__ */ Object.create(null);
4
4
  function registerModule(ref, callback) {
@@ -1,4 +1,4 @@
1
- import { aW as BaseDecoder } from "./index-se6p8sp4.js";
1
+ import { aW as BaseDecoder } from "./index-Z-pD1WnL.js";
2
2
  class WebImageDecoder extends BaseDecoder {
3
3
  constructor() {
4
4
  super();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/all",
3
- "version": "3.8.4",
3
+ "version": "3.8.6",
4
4
  "author": "HIDIVE Lab at HMS",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -17,38 +17,38 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "zod": "^3.21.4",
20
- "@vitessce/styles": "3.8.4",
21
- "@vitessce/constants-internal": "3.8.4",
22
- "@vitessce/abstract": "3.8.4",
23
- "@vitessce/error": "3.8.4",
24
- "@vitessce/csv": "3.8.4",
25
- "@vitessce/description": "3.8.4",
26
- "@vitessce/feature-list": "3.8.4",
27
- "@vitessce/genomic-profiles": "3.8.4",
28
- "@vitessce/heatmap": "3.8.4",
29
- "@vitessce/glb": "3.8.4",
30
- "@vitessce/json": "3.8.4",
31
- "@vitessce/layer-controller": "3.8.4",
32
- "@vitessce/layer-controller-beta": "3.8.4",
33
- "@vitessce/link-controller": "3.8.4",
34
- "@vitessce/obs-sets-manager": "3.8.4",
35
- "@vitessce/ome-tiff": "3.8.4",
36
- "@vitessce/plugins": "3.8.4",
37
- "@vitessce/scatterplot-embedding": "3.8.4",
38
- "@vitessce/scatterplot-gating": "3.8.4",
39
- "@vitessce/schemas": "3.8.4",
40
- "@vitessce/spatial": "3.8.4",
41
- "@vitessce/spatial-beta": "3.8.4",
42
- "@vitessce/statistical-plots": "3.8.4",
43
- "@vitessce/status": "3.8.4",
44
- "@vitessce/vit-s": "3.8.4",
45
- "@vitessce/zarr": "3.8.4",
46
- "@vitessce/globals": "3.8.4",
47
- "@vitessce/spatial-zarr": "3.8.4",
48
- "@vitessce/spatial-three": "3.8.4",
49
- "@vitessce/spatial-accelerated": "3.8.4",
50
- "@vitessce/biomarker-select": "3.8.4",
51
- "@vitessce/neuroglancer": "3.8.4"
20
+ "@vitessce/styles": "3.8.6",
21
+ "@vitessce/constants-internal": "3.8.6",
22
+ "@vitessce/abstract": "3.8.6",
23
+ "@vitessce/error": "3.8.6",
24
+ "@vitessce/csv": "3.8.6",
25
+ "@vitessce/description": "3.8.6",
26
+ "@vitessce/feature-list": "3.8.6",
27
+ "@vitessce/genomic-profiles": "3.8.6",
28
+ "@vitessce/heatmap": "3.8.6",
29
+ "@vitessce/glb": "3.8.6",
30
+ "@vitessce/json": "3.8.6",
31
+ "@vitessce/layer-controller": "3.8.6",
32
+ "@vitessce/layer-controller-beta": "3.8.6",
33
+ "@vitessce/link-controller": "3.8.6",
34
+ "@vitessce/obs-sets-manager": "3.8.6",
35
+ "@vitessce/ome-tiff": "3.8.6",
36
+ "@vitessce/plugins": "3.8.6",
37
+ "@vitessce/scatterplot-embedding": "3.8.6",
38
+ "@vitessce/scatterplot-gating": "3.8.6",
39
+ "@vitessce/schemas": "3.8.6",
40
+ "@vitessce/spatial": "3.8.6",
41
+ "@vitessce/spatial-beta": "3.8.6",
42
+ "@vitessce/statistical-plots": "3.8.6",
43
+ "@vitessce/status": "3.8.6",
44
+ "@vitessce/vit-s": "3.8.6",
45
+ "@vitessce/zarr": "3.8.6",
46
+ "@vitessce/globals": "3.8.6",
47
+ "@vitessce/spatial-zarr": "3.8.6",
48
+ "@vitessce/spatial-three": "3.8.6",
49
+ "@vitessce/spatial-accelerated": "3.8.6",
50
+ "@vitessce/biomarker-select": "3.8.6",
51
+ "@vitessce/neuroglancer": "3.8.6"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/react": "^18.0.28",