@vitessce/all 4.0.0-test.3 → 4.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.
Files changed (33) hide show
  1. package/dist/{GeometryAndMeshXR-BRP24ura.js → GeometryAndMeshXR-DGeJ5ZBr.js} +1 -1
  2. package/dist/{ReactNeuroglancer-VYcAJw_c.js → ReactNeuroglancer-Do72MK3I.js} +1 -1
  3. package/dist/{deflate-B35gUGrI.js → deflate-VdN3pn_b.js} +1 -1
  4. package/dist/{higlass-DIGh19X3.js → higlass-DL7cd1YR.js} +1 -1
  5. package/dist/{index-BRdVNpUK.js → index-Dau2mo3I.js} +7 -6
  6. package/dist/{index-DLzCt39t.js → index-GwbVVPa9.js} +395 -194
  7. package/dist/{index-CIJWVuYa.js → index-tp3-aWWe.js} +2 -2
  8. package/dist/index.js +1 -1
  9. package/dist/{jpeg-pIveo5qm.js → jpeg-CYgQz5aG.js} +1 -1
  10. package/dist/{lerc-DEzmYyQ_.js → lerc-C-Llf71G.js} +1 -1
  11. package/dist/{lzw-lK2xDQPh.js → lzw-DJhX6Tr-.js} +1 -1
  12. package/dist/{packbits-Ds8BMewq.js → packbits-BOwAxrqR.js} +1 -1
  13. package/dist/{raw-BKulPvK3.js → raw-BX1y7Iy_.js} +1 -1
  14. package/dist/{webimage-BnK9oxcF.js → webimage-DCU5-f3Q.js} +1 -1
  15. package/dist-tsc/Vitessce.js +1 -0
  16. package/dist-tsc/Vitessce.js.map +1 -0
  17. package/dist-tsc/base-plugins.d.ts.map +1 -1
  18. package/dist-tsc/base-plugins.js +2 -0
  19. package/dist-tsc/base-plugins.js.map +1 -0
  20. package/dist-tsc/index.js +1 -0
  21. package/dist-tsc/index.js.map +1 -0
  22. package/dist-tsc/joint-file-types-legacy.js +1 -0
  23. package/dist-tsc/joint-file-types-legacy.js.map +1 -0
  24. package/dist-tsc/joint-file-types-legacy.test.js +1 -0
  25. package/dist-tsc/joint-file-types-legacy.test.js.map +1 -0
  26. package/dist-tsc/joint-file-types.js +1 -0
  27. package/dist-tsc/joint-file-types.js.map +1 -0
  28. package/dist-tsc/joint-file-types.test.js +1 -0
  29. package/dist-tsc/joint-file-types.test.js.map +1 -0
  30. package/dist-tsc/latest-config-schema.test.js +1 -0
  31. package/dist-tsc/latest-config-schema.test.js.map +1 -0
  32. package/package.json +33 -33
  33. package/src/base-plugins.ts +1 -0
@@ -4,9 +4,6 @@ import { useLoaders, useCoordinationScopes, useCoordination, useDescription, use
4
4
  import { jsx as jsx$1, jsxs, Fragment } from "react/jsx-runtime";
5
5
  import * as ReactDOM from "react-dom";
6
6
  import ReactDOM__default, { createPortal } from "react-dom";
7
- import { Quaternion as Quaternion$1, Euler as Euler$1 } from "three";
8
- import { GLTFLoader as GLTFLoader$1 } from "three/addons/loaders/GLTFLoader.js";
9
- import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";
10
7
  function _mergeNamespaces(n3, m2) {
11
8
  for (var i2 = 0; i2 < m2.length; i2++) {
12
9
  const e3 = m2[i2];
@@ -4946,7 +4943,7 @@ function baseClamp(number2, lower2, upper) {
4946
4943
  }
4947
4944
  return number2;
4948
4945
  }
4949
- function clamp$7(number2, lower2, upper) {
4946
+ function clamp$8(number2, lower2, upper) {
4950
4947
  if (upper === void 0) {
4951
4948
  upper = lower2;
4952
4949
  lower2 = void 0;
@@ -9267,6 +9264,7 @@ const FileType$1 = {
9267
9264
  OBS_LABELS_MUDATA_ZARR: "obsLabels.mudata.zarr",
9268
9265
  FEATURE_LABELS_MUDATA_ZARR: "featureLabels.mudata.zarr",
9269
9266
  GENOMIC_PROFILES_ZARR: "genomic-profiles.zarr",
9267
+ GENOMIC_PROFILES_ZARR_ZIP: "genomic-profiles.zarr.zip",
9270
9268
  NEIGHBORHOODS_JSON: "neighborhoods.json",
9271
9269
  // OME-TIFF
9272
9270
  IMAGE_OME_TIFF: "image.ome-tiff",
@@ -9561,6 +9559,7 @@ const ViewHelpMapping = {
9561
9559
  [FileType$1.OBS_LABELS_MOLECULES_JSON]: DataType$3.OBS_LABELS,
9562
9560
  // For old file types
9563
9561
  [FileType$1.GENOMIC_PROFILES_ZARR]: DataType$3.GENOMIC_PROFILES,
9562
+ [FileType$1.GENOMIC_PROFILES_ZARR_ZIP]: DataType$3.GENOMIC_PROFILES,
9564
9563
  [FileType$1.NEIGHBORHOODS_JSON]: DataType$3.NEIGHBORHOODS
9565
9564
  });
9566
9565
  ({
@@ -9725,6 +9724,10 @@ const ALT_ZARR_STORE_TYPES = {
9725
9724
  },
9726
9725
  [FileType$1.OBS_EMBEDDING_SPATIALDATA_ZARR]: {
9727
9726
  zip: FileType$1.OBS_EMBEDDING_SPATIALDATA_ZARR_ZIP
9727
+ },
9728
+ // For genomic profiles:
9729
+ [FileType$1.GENOMIC_PROFILES_ZARR]: {
9730
+ zip: FileType$1.GENOMIC_PROFILES_ZARR_ZIP
9728
9731
  }
9729
9732
  };
9730
9733
  [
@@ -16101,7 +16104,7 @@ function useThemeProps$1({
16101
16104
  });
16102
16105
  }
16103
16106
  const useEnhancedEffect$1 = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
16104
- function clamp$6(val, min2 = Number.MIN_SAFE_INTEGER, max2 = Number.MAX_SAFE_INTEGER) {
16107
+ function clamp$7(val, min2 = Number.MIN_SAFE_INTEGER, max2 = Number.MAX_SAFE_INTEGER) {
16105
16108
  return Math.max(min2, Math.min(val, max2));
16106
16109
  }
16107
16110
  function clampWrapper(value2, min2 = 0, max2 = 1) {
@@ -16110,7 +16113,7 @@ function clampWrapper(value2, min2 = 0, max2 = 1) {
16110
16113
  console.error(`MUI: The value provided ${value2} is out of range [${min2}, ${max2}].`);
16111
16114
  }
16112
16115
  }
16113
- return clamp$6(value2, min2, max2);
16116
+ return clamp$7(value2, min2, max2);
16114
16117
  }
16115
16118
  function hexToRgb$1(color2) {
16116
16119
  color2 = color2.slice(1);
@@ -39601,7 +39604,7 @@ function useSlider(parameters2) {
39601
39604
  });
39602
39605
  const range2 = Array.isArray(valueDerived);
39603
39606
  let values3 = range2 ? valueDerived.slice().sort(asc) : [valueDerived];
39604
- values3 = values3.map((value2) => value2 == null ? min2 : clamp$6(value2, min2, max2));
39607
+ values3 = values3.map((value2) => value2 == null ? min2 : clamp$7(value2, min2, max2));
39605
39608
  const marks = marksProp === true && step !== null ? [...Array(Math.floor((max2 - min2) / step) + 1)].map((_, index2) => ({
39606
39609
  value: min2 + step * index2
39607
39610
  })) : marksProp || [];
@@ -39639,10 +39642,10 @@ function useSlider(parameters2) {
39639
39642
  newValue = newValue < value2 ? marksValues[marksIndex - 1] : marksValues[marksIndex + 1];
39640
39643
  }
39641
39644
  }
39642
- newValue = clamp$6(newValue, min2, max2);
39645
+ newValue = clamp$7(newValue, min2, max2);
39643
39646
  if (range2) {
39644
39647
  if (disableSwap) {
39645
- newValue = clamp$6(newValue, values3[index2 - 1] || -Infinity, values3[index2 + 1] || Infinity);
39648
+ newValue = clamp$7(newValue, values3[index2 - 1] || -Infinity, values3[index2 + 1] || Infinity);
39646
39649
  }
39647
39650
  const previousValue = newValue;
39648
39651
  newValue = setValueIndex({
@@ -39777,7 +39780,7 @@ function useSlider(parameters2) {
39777
39780
  const closestIndex = findClosest(marksValues, newValue);
39778
39781
  newValue = marksValues[closestIndex];
39779
39782
  }
39780
- newValue = clamp$6(newValue, min2, max2);
39783
+ newValue = clamp$7(newValue, min2, max2);
39781
39784
  let activeIndex = 0;
39782
39785
  if (range2) {
39783
39786
  if (!move2) {
@@ -39786,7 +39789,7 @@ function useSlider(parameters2) {
39786
39789
  activeIndex = previousIndex.current;
39787
39790
  }
39788
39791
  if (disableSwap) {
39789
- newValue = clamp$6(newValue, values3[activeIndex - 1] || -Infinity, values3[activeIndex + 1] || Infinity);
39792
+ newValue = clamp$7(newValue, values3[activeIndex - 1] || -Infinity, values3[activeIndex + 1] || Infinity);
39790
39793
  }
39791
39794
  const previousValue = newValue;
39792
39795
  newValue = setValueIndex({
@@ -47547,7 +47550,7 @@ function localStorageAvailable() {
47547
47550
  function escapeRegExp(value2) {
47548
47551
  return value2.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
47549
47552
  }
47550
- const clamp$5 = (value2, min2, max2) => Math.max(min2, Math.min(max2, value2));
47553
+ const clamp$6 = (value2, min2, max2) => Math.max(min2, Math.min(max2, value2));
47551
47554
  function range$c(from2, to) {
47552
47555
  return Array.from({
47553
47556
  length: to - from2
@@ -51253,7 +51256,7 @@ const hydrateColumnsWidth = (rawState, dimensions) => {
51253
51256
  totalFlexUnits += column2.flex;
51254
51257
  isFlex = true;
51255
51258
  } else {
51256
- computedWidth = clamp$5(column2.width || GRID_STRING_COL_DEF.width, column2.minWidth || GRID_STRING_COL_DEF.minWidth, column2.maxWidth || GRID_STRING_COL_DEF.maxWidth);
51259
+ computedWidth = clamp$6(column2.width || GRID_STRING_COL_DEF.width, column2.minWidth || GRID_STRING_COL_DEF.minWidth, column2.maxWidth || GRID_STRING_COL_DEF.maxWidth);
51257
51260
  }
51258
51261
  widthAllocatedBeforeFlex += computedWidth;
51259
51262
  }
@@ -51853,8 +51856,8 @@ const useGridVirtualScroller = () => {
51853
51856
  const maxScrollTop = Math.ceil(dimensions.minimumSize.height - dimensions.viewportOuterSize.height);
51854
51857
  const maxScrollLeft = Math.ceil(dimensions.minimumSize.width - dimensions.viewportInnerSize.width);
51855
51858
  const newScroll = {
51856
- top: clamp$5(scroller.scrollTop, 0, maxScrollTop),
51857
- left: isRtl ? clamp$5(scroller.scrollLeft, -maxScrollLeft, 0) : clamp$5(scroller.scrollLeft, 0, maxScrollLeft)
51859
+ top: clamp$6(scroller.scrollTop, 0, maxScrollTop),
51860
+ left: isRtl ? clamp$6(scroller.scrollLeft, -maxScrollLeft, 0) : clamp$6(scroller.scrollLeft, 0, maxScrollLeft)
51858
51861
  };
51859
51862
  const dx = newScroll.left - scrollPosition.current.left;
51860
51863
  const dy = newScroll.top - scrollPosition.current.top;
@@ -52292,7 +52295,7 @@ function getNearestIndexToRender(inputs, offset2, options) {
52292
52295
  if (inputs.range?.lastRowIndex && !allRowsMeasured) {
52293
52296
  allRowsMeasured = lastMeasuredIndexRelativeToAllRows >= inputs.range.lastRowIndex;
52294
52297
  }
52295
- const lastMeasuredIndexRelativeToCurrentPage = clamp$5(lastMeasuredIndexRelativeToAllRows - (inputs.range?.firstRowIndex || 0), 0, inputs.rowsMeta.positions.length);
52298
+ const lastMeasuredIndexRelativeToCurrentPage = clamp$6(lastMeasuredIndexRelativeToAllRows - (inputs.range?.firstRowIndex || 0), 0, inputs.rowsMeta.positions.length);
52296
52299
  if (allRowsMeasured || inputs.rowsMeta.positions[lastMeasuredIndexRelativeToCurrentPage] >= offset2) {
52297
52300
  return binarySearch$2(offset2, inputs.rowsMeta.positions, options);
52298
52301
  }
@@ -52376,7 +52379,7 @@ function getIndexesToRender({
52376
52379
  lastPosition: positions[positions.length - 1] + lastSize
52377
52380
  });
52378
52381
  const lastIndexPadded = binarySearch$2(lastPosition, positions);
52379
- return [clamp$5(firstIndexPadded, minFirstIndex, maxLastIndex), clamp$5(lastIndexPadded, minFirstIndex, maxLastIndex)];
52382
+ return [clamp$6(firstIndexPadded, minFirstIndex, maxLastIndex), clamp$6(lastIndexPadded, minFirstIndex, maxLastIndex)];
52380
52383
  }
52381
52384
  function areRenderContextsEqual(context1, context2) {
52382
52385
  if (context1 === context2) {
@@ -61955,7 +61958,7 @@ const useGridFocus = (apiRef, props) => {
61955
61958
  columnIndexToFocus = visibleColumns.length - 1;
61956
61959
  }
61957
61960
  }
61958
- rowIndexToFocus = clamp$5(rowIndexToFocus, 0, currentPageRows.length - 1);
61961
+ rowIndexToFocus = clamp$6(rowIndexToFocus, 0, currentPageRows.length - 1);
61959
61962
  const rowToFocus = currentPageRows[rowIndexToFocus];
61960
61963
  if (!rowToFocus) {
61961
61964
  return;
@@ -61968,7 +61971,7 @@ const useGridFocus = (apiRef, props) => {
61968
61971
  columnIndexToFocus = colSpanInfo.rightVisibleCellIndex;
61969
61972
  }
61970
61973
  }
61971
- columnIndexToFocus = clamp$5(columnIndexToFocus, 0, visibleColumns.length - 1);
61974
+ columnIndexToFocus = clamp$6(columnIndexToFocus, 0, visibleColumns.length - 1);
61972
61975
  const columnToFocus = visibleColumns[columnIndexToFocus];
61973
61976
  apiRef.current.setCellFocus(rowToFocus.id, columnToFocus.field);
61974
61977
  }, [apiRef, props.pagination, props.paginationMode]);
@@ -62081,7 +62084,7 @@ const useGridFocus = (apiRef, props) => {
62081
62084
  pagination: props.pagination,
62082
62085
  paginationMode: props.paginationMode
62083
62086
  });
62084
- const nextRow = currentPage.rows[clamp$5(lastFocusedRowIndex, 0, currentPage.rows.length - 1)];
62087
+ const nextRow = currentPage.rows[clamp$6(lastFocusedRowIndex, 0, currentPage.rows.length - 1)];
62085
62088
  nextRowId = nextRow?.id ?? null;
62086
62089
  }
62087
62090
  apiRef.current.setState((state) => _extends$c({}, state, {
@@ -66434,7 +66437,7 @@ function extractColumnWidths(apiRef, options, columns2) {
66434
66437
  const min2 = hasColumnMin ? column2.minWidth : 0;
66435
66438
  const max2 = hasColumnMax ? column2.maxWidth : Infinity;
66436
66439
  const maxContent = filteredWidths.length === 0 ? 0 : Math.max(...filteredWidths);
66437
- widthByField[column2.field] = clamp$5(maxContent, min2, max2);
66440
+ widthByField[column2.field] = clamp$6(maxContent, min2, max2);
66438
66441
  });
66439
66442
  root2.classList.remove(gridClasses.autosizing);
66440
66443
  return widthByField;
@@ -66590,7 +66593,7 @@ const useGridColumnResize = (apiRef, props) => {
66590
66593
  return;
66591
66594
  }
66592
66595
  let newWidth = computeNewWidth(initialOffsetToSeparator.current, nativeEvent.clientX, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
66593
- newWidth = clamp$5(newWidth, refs.colDef.minWidth, refs.colDef.maxWidth);
66596
+ newWidth = clamp$6(newWidth, refs.colDef.minWidth, refs.colDef.maxWidth);
66594
66597
  updateWidth(newWidth);
66595
66598
  const params2 = {
66596
66599
  element: refs.columnHeaderElement,
@@ -66616,7 +66619,7 @@ const useGridColumnResize = (apiRef, props) => {
66616
66619
  return;
66617
66620
  }
66618
66621
  let newWidth = computeNewWidth(initialOffsetToSeparator.current, finger.x, refs.columnHeaderElement.getBoundingClientRect(), resizeDirection.current);
66619
- newWidth = clamp$5(newWidth, refs.colDef.minWidth, refs.colDef.maxWidth);
66622
+ newWidth = clamp$6(newWidth, refs.colDef.minWidth, refs.colDef.maxWidth);
66620
66623
  updateWidth(newWidth);
66621
66624
  const params2 = {
66622
66625
  element: refs.columnHeaderElement,
@@ -115185,7 +115188,7 @@ function acos$4(radians2, result) {
115185
115188
  function atan$3(radians2, result) {
115186
115189
  return map$3(radians2, (angle2) => Math.atan(angle2), result);
115187
115190
  }
115188
- function clamp$4(value2, min2, max2) {
115191
+ function clamp$5(value2, min2, max2) {
115189
115192
  return map$3(value2, (value3) => Math.max(min2, Math.min(max2, value3)));
115190
115193
  }
115191
115194
  function lerp$8(a2, b2, t4) {
@@ -118155,7 +118158,7 @@ class SphericalCoordinates {
118155
118158
  this.radius = length$5(v);
118156
118159
  if (this.radius > 0) {
118157
118160
  this.theta = Math.atan2(v[0], v[1]);
118158
- this.phi = Math.acos(clamp$4(v[2] / this.radius, -1, 1));
118161
+ this.phi = Math.acos(clamp$5(v[2] / this.radius, -1, 1));
118159
118162
  }
118160
118163
  return this.check();
118161
118164
  }
@@ -118410,7 +118413,7 @@ class Euler extends MathArray {
118410
118413
  order2 = order2 || this[3];
118411
118414
  switch (order2) {
118412
118415
  case Euler.XYZ:
118413
- this[1] = Math.asin(clamp$4(m13, -1, 1));
118416
+ this[1] = Math.asin(clamp$5(m13, -1, 1));
118414
118417
  if (Math.abs(m13) < ALMOST_ONE) {
118415
118418
  this[0] = Math.atan2(-m23, m33);
118416
118419
  this[2] = Math.atan2(-m12, m11);
@@ -118420,7 +118423,7 @@ class Euler extends MathArray {
118420
118423
  }
118421
118424
  break;
118422
118425
  case Euler.YXZ:
118423
- this[0] = Math.asin(-clamp$4(m23, -1, 1));
118426
+ this[0] = Math.asin(-clamp$5(m23, -1, 1));
118424
118427
  if (Math.abs(m23) < ALMOST_ONE) {
118425
118428
  this[1] = Math.atan2(m13, m33);
118426
118429
  this[2] = Math.atan2(m21, m22);
@@ -118430,7 +118433,7 @@ class Euler extends MathArray {
118430
118433
  }
118431
118434
  break;
118432
118435
  case Euler.ZXY:
118433
- this[0] = Math.asin(clamp$4(m32, -1, 1));
118436
+ this[0] = Math.asin(clamp$5(m32, -1, 1));
118434
118437
  if (Math.abs(m32) < ALMOST_ONE) {
118435
118438
  this[1] = Math.atan2(-m31, m33);
118436
118439
  this[2] = Math.atan2(-m12, m22);
@@ -118440,7 +118443,7 @@ class Euler extends MathArray {
118440
118443
  }
118441
118444
  break;
118442
118445
  case Euler.ZYX:
118443
- this[1] = Math.asin(-clamp$4(m31, -1, 1));
118446
+ this[1] = Math.asin(-clamp$5(m31, -1, 1));
118444
118447
  if (Math.abs(m31) < ALMOST_ONE) {
118445
118448
  this[0] = Math.atan2(m32, m33);
118446
118449
  this[2] = Math.atan2(m21, m11);
@@ -118450,7 +118453,7 @@ class Euler extends MathArray {
118450
118453
  }
118451
118454
  break;
118452
118455
  case Euler.YZX:
118453
- this[2] = Math.asin(clamp$4(m21, -1, 1));
118456
+ this[2] = Math.asin(clamp$5(m21, -1, 1));
118454
118457
  if (Math.abs(m21) < ALMOST_ONE) {
118455
118458
  this[0] = Math.atan2(-m23, m22);
118456
118459
  this[1] = Math.atan2(-m31, m11);
@@ -118460,7 +118463,7 @@ class Euler extends MathArray {
118460
118463
  }
118461
118464
  break;
118462
118465
  case Euler.XZY:
118463
- this[2] = Math.asin(-clamp$4(m12, -1, 1));
118466
+ this[2] = Math.asin(-clamp$5(m12, -1, 1));
118464
118467
  if (Math.abs(m12) < ALMOST_ONE) {
118465
118468
  this[0] = Math.atan2(m32, m22);
118466
118469
  this[1] = Math.atan2(m13, m11);
@@ -121604,7 +121607,7 @@ function mod$2(value2, divisor) {
121604
121607
  function lerp$3(start2, end2, step) {
121605
121608
  return step * end2 + (1 - step) * start2;
121606
121609
  }
121607
- function clamp$3(x2, min2, max2) {
121610
+ function clamp$4(x2, min2, max2) {
121608
121611
  return x2 < min2 ? min2 : x2 > max2 ? max2 : x2;
121609
121612
  }
121610
121613
  function ieLog2(x2) {
@@ -121750,7 +121753,7 @@ function getProjectionParameters(options) {
121750
121753
  cameraToSeaLevelDistance += center2[2] * scale2 / Math.cos(pitchRadians) / height2;
121751
121754
  }
121752
121755
  const fovAboveCenter = fovRadians * (0.5 + (offset2 ? offset2[1] : 0) / height2);
121753
- const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToSeaLevelDistance / Math.sin(clamp$3(Math.PI / 2 - pitchRadians - fovAboveCenter, 0.01, Math.PI - 0.01));
121756
+ const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToSeaLevelDistance / Math.sin(clamp$4(Math.PI / 2 - pitchRadians - fovAboveCenter, 0.01, Math.PI - 0.01));
121754
121757
  const furthestDistance = Math.sin(pitchRadians) * topHalfSurfaceDistance + cameraToSeaLevelDistance;
121755
121758
  const horizonDistance = cameraToSeaLevelDistance * 10;
121756
121759
  const farZ = Math.min(furthestDistance * farZMultiplier, horizonDistance);
@@ -121808,8 +121811,8 @@ function fitBounds(options) {
121808
121811
  } = options;
121809
121812
  const [[west, south], [east, north]] = bounds2;
121810
121813
  const padding2 = getPaddingObject(options.padding);
121811
- const nw = lngLatToWorld([west, clamp$3(north, -MAX_LATITUDE, MAX_LATITUDE)]);
121812
- const se = lngLatToWorld([east, clamp$3(south, -MAX_LATITUDE, MAX_LATITUDE)]);
121814
+ const nw = lngLatToWorld([west, clamp$4(north, -MAX_LATITUDE, MAX_LATITUDE)]);
121815
+ const se = lngLatToWorld([east, clamp$4(south, -MAX_LATITUDE, MAX_LATITUDE)]);
121813
121816
  const size2 = [Math.max(Math.abs(se[0] - nw[0]), minExtent), Math.max(Math.abs(se[1] - nw[1]), minExtent)];
121814
121817
  const targetSize = [width2 - padding2.left - padding2.right - Math.abs(offset2[0]) * 2, height2 - padding2.top - padding2.bottom - Math.abs(offset2[1]) * 2];
121815
121818
  assert$b(targetSize[0] > 0 && targetSize[1] > 0);
@@ -123099,8 +123102,8 @@ function createProjectionMatrix({
123099
123102
  top: top2 = 0,
123100
123103
  bottom: bottom2 = 0
123101
123104
  } = padding2;
123102
- const offsetX = clamp$4((left2 + width2 - right2) / 2, 0, width2) - width2 / 2;
123103
- const offsetY = clamp$4((top2 + height2 - bottom2) / 2, 0, height2) - height2 / 2;
123105
+ const offsetX = clamp$5((left2 + width2 - right2) / 2, 0, width2) - width2 / 2;
123106
+ const offsetY = clamp$5((top2 + height2 - bottom2) / 2, 0, height2) - height2 / 2;
123104
123107
  matrix2[8] -= offsetX * 2 / width2;
123105
123108
  matrix2[9] += offsetY * 2 / height2;
123106
123109
  }
@@ -123215,7 +123218,7 @@ class Viewport {
123215
123218
  projectFlat(xyz) {
123216
123219
  if (this.isGeospatial) {
123217
123220
  const result = lngLatToWorld(xyz);
123218
- result[1] = clamp$4(result[1], -318, 830);
123221
+ result[1] = clamp$5(result[1], -318, 830);
123219
123222
  return result;
123220
123223
  }
123221
123224
  return xyz;
@@ -125932,7 +125935,7 @@ class MapState extends ViewState {
125932
125935
  minZoom
125933
125936
  } = this.getViewportProps();
125934
125937
  let zoom2 = startZoom + Math.log2(scale2);
125935
- zoom2 = clamp$4(zoom2, minZoom, maxZoom);
125938
+ zoom2 = clamp$5(zoom2, minZoom, maxZoom);
125936
125939
  const zoomedViewport = this.makeViewport({
125937
125940
  ...this.getViewportProps(),
125938
125941
  zoom: zoom2
@@ -126009,13 +126012,13 @@ class MapState extends ViewState {
126009
126012
  minZoom,
126010
126013
  zoom: zoom2
126011
126014
  } = props;
126012
- props.zoom = clamp$4(zoom2, minZoom, maxZoom);
126015
+ props.zoom = clamp$5(zoom2, minZoom, maxZoom);
126013
126016
  const {
126014
126017
  maxPitch,
126015
126018
  minPitch,
126016
126019
  pitch
126017
126020
  } = props;
126018
- props.pitch = clamp$4(pitch, minPitch, maxPitch);
126021
+ props.pitch = clamp$5(pitch, minPitch, maxPitch);
126019
126022
  const {
126020
126023
  normalize: normalize2 = true
126021
126024
  } = props;
@@ -126076,7 +126079,7 @@ class MapState extends ViewState {
126076
126079
  deltaScaleY = 1 - centerY / startY;
126077
126080
  }
126078
126081
  }
126079
- deltaScaleY = clamp$4(deltaScaleY, -1, 1);
126082
+ deltaScaleY = clamp$5(deltaScaleY, -1, 1);
126080
126083
  const {
126081
126084
  minPitch,
126082
126085
  maxPitch
@@ -126205,8 +126208,8 @@ function getProjectionMatrix({
126205
126208
  top: t4 = 0,
126206
126209
  bottom: b2 = 0
126207
126210
  } = padding2;
126208
- const offsetX = clamp$4((l2 + width2 - r3) / 2, 0, width2) - width2 / 2;
126209
- const offsetY = clamp$4((t4 + height2 - b2) / 2, 0, height2) - height2 / 2;
126211
+ const offsetX = clamp$5((l2 + width2 - r3) / 2, 0, width2) - width2 / 2;
126212
+ const offsetY = clamp$5((t4 + height2 - b2) / 2, 0, height2) - height2 / 2;
126210
126213
  left2 -= offsetX;
126211
126214
  right2 -= offsetX;
126212
126215
  bottom2 += offsetY;
@@ -126519,7 +126522,7 @@ class OrbitState extends ViewState {
126519
126522
  startZoom = this.getViewportProps().zoom;
126520
126523
  }
126521
126524
  const zoom2 = startZoom + Math.log2(scale2);
126522
- return clamp$4(zoom2, minZoom, maxZoom);
126525
+ return clamp$5(zoom2, minZoom, maxZoom);
126523
126526
  }
126524
126527
  _panFromCenter(offset2) {
126525
126528
  const {
@@ -126549,8 +126552,8 @@ class OrbitState extends ViewState {
126549
126552
  minRotationX,
126550
126553
  rotationOrbit
126551
126554
  } = props;
126552
- props.zoom = Array.isArray(zoom2) ? [clamp$4(zoom2[0], minZoom, maxZoom), clamp$4(zoom2[1], minZoom, maxZoom)] : clamp$4(zoom2, minZoom, maxZoom);
126553
- props.rotationX = clamp$4(props.rotationX, minRotationX, maxRotationX);
126555
+ props.zoom = Array.isArray(zoom2) ? [clamp$5(zoom2[0], minZoom, maxZoom), clamp$5(zoom2[1], minZoom, maxZoom)] : clamp$5(zoom2, minZoom, maxZoom);
126556
+ props.rotationX = clamp$5(props.rotationX, minRotationX, maxRotationX);
126554
126557
  if (rotationOrbit < -180 || rotationOrbit > 180) {
126555
126558
  props.rotationOrbit = mod$1(rotationOrbit + 180, 360) - 180;
126556
126559
  }
@@ -126594,10 +126597,10 @@ class OrthographicState extends OrbitState {
126594
126597
  let [newZoomX, newZoomY] = startZoom;
126595
126598
  switch (this.zoomAxis) {
126596
126599
  case "X":
126597
- newZoomX = clamp$4(newZoomX + deltaZoom, minZoom, maxZoom);
126600
+ newZoomX = clamp$5(newZoomX + deltaZoom, minZoom, maxZoom);
126598
126601
  break;
126599
126602
  case "Y":
126600
- newZoomY = clamp$4(newZoomY + deltaZoom, minZoom, maxZoom);
126603
+ newZoomY = clamp$5(newZoomY + deltaZoom, minZoom, maxZoom);
126601
126604
  break;
126602
126605
  default:
126603
126606
  let z2 = Math.min(newZoomX + deltaZoom, newZoomY + deltaZoom);
@@ -126613,7 +126616,7 @@ class OrthographicState extends OrbitState {
126613
126616
  }
126614
126617
  return [newZoomX, newZoomY];
126615
126618
  }
126616
- return clamp$4(startZoom + deltaZoom, minZoom, maxZoom);
126619
+ return clamp$5(startZoom + deltaZoom, minZoom, maxZoom);
126617
126620
  }
126618
126621
  }
126619
126622
  class OrthographicController extends Controller {
@@ -135352,7 +135355,7 @@ class FirstPersonState extends ViewState {
135352
135355
  longitude: longitude2,
135353
135356
  bearing
135354
135357
  } = props;
135355
- props.pitch = clamp$4(pitch, minPitch, maxPitch);
135358
+ props.pitch = clamp$5(pitch, minPitch, maxPitch);
135356
135359
  if (longitude2 !== null && (longitude2 < -180 || longitude2 > 180)) {
135357
135360
  props.longitude = mod$1(longitude2 + 180, 360) - 180;
135358
135361
  }
@@ -135401,7 +135404,7 @@ class GlobeState extends MapState {
135401
135404
  minZoom,
135402
135405
  zoom: zoom2
135403
135406
  } = props;
135404
- props.zoom = clamp$4(zoom2, minZoom, maxZoom);
135407
+ props.zoom = clamp$5(zoom2, minZoom, maxZoom);
135405
135408
  const {
135406
135409
  longitude: longitude2,
135407
135410
  latitude
@@ -135409,7 +135412,7 @@ class GlobeState extends MapState {
135409
135412
  if (longitude2 < -180 || longitude2 > 180) {
135410
135413
  props.longitude = mod$1(longitude2 + 180, 360) - 180;
135411
135414
  }
135412
- props.latitude = clamp$4(latitude, -89, 89);
135415
+ props.latitude = clamp$5(latitude, -89, 89);
135413
135416
  return props;
135414
135417
  }
135415
135418
  }
@@ -143056,7 +143059,7 @@ function getQuantileDomain(data2, valueAccessor) {
143056
143059
  function getOrdinalDomain(data2, valueAccessor) {
143057
143060
  return unique$1(getTruthyValues(data2, valueAccessor));
143058
143061
  }
143059
- function clamp$2(value2, min2, max2) {
143062
+ function clamp$3(value2, min2, max2) {
143060
143063
  return Math.max(min2, Math.min(max2, value2));
143061
143064
  }
143062
143065
  const defaultGetValue = (points2) => points2.length;
@@ -143117,7 +143120,7 @@ class BinSorter {
143117
143120
  if (len2 < 2) {
143118
143121
  return [0, 0];
143119
143122
  }
143120
- const [lower2, upper] = percentileRange.map((n3) => clamp$2(n3, 0, 100));
143123
+ const [lower2, upper] = percentileRange.map((n3) => clamp$3(n3, 0, 100));
143121
143124
  const lowerIdx = Math.ceil(lower2 / 100 * (len2 - 1));
143122
143125
  const upperIdx = Math.floor(upper / 100 * (len2 - 1));
143123
143126
  return [lowerIdx, upperIdx];
@@ -165911,7 +165914,7 @@ new Vector3();
165911
165914
  new Vector2();
165912
165915
  new Vector2();
165913
165916
  function fromSNorm(value2, rangeMaximum = 255) {
165914
- return clamp$4(value2, 0, rangeMaximum) / rangeMaximum * 2 - 1;
165917
+ return clamp$5(value2, 0, rangeMaximum) / rangeMaximum * 2 - 1;
165915
165918
  }
165916
165919
  function signNotZero(value2) {
165917
165920
  return value2 < 0 ? -1 : 1;
@@ -205028,7 +205031,7 @@ const esm = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty(
205028
205031
  asin: asin$5,
205029
205032
  assert: assert$c,
205030
205033
  atan: atan$3,
205031
- clamp: clamp$4,
205034
+ clamp: clamp$5,
205032
205035
  clone: clone$5,
205033
205036
  config: config$3,
205034
205037
  configure,
@@ -209457,22 +209460,22 @@ async function getDecoder(fileDirectory) {
209457
209460
  const Decoder = await importFn();
209458
209461
  return new Decoder(fileDirectory);
209459
209462
  }
209460
- addDecoder([void 0, 1], () => import("./raw-BKulPvK3.js").then((m2) => m2.default));
209461
- addDecoder(5, () => import("./lzw-lK2xDQPh.js").then((m2) => m2.default));
209463
+ addDecoder([void 0, 1], () => import("./raw-BX1y7Iy_.js").then((m2) => m2.default));
209464
+ addDecoder(5, () => import("./lzw-DJhX6Tr-.js").then((m2) => m2.default));
209462
209465
  addDecoder(6, () => {
209463
209466
  throw new Error("old style JPEG compression is not supported.");
209464
209467
  });
209465
- addDecoder(7, () => import("./jpeg-pIveo5qm.js").then((m2) => m2.default));
209466
- addDecoder([8, 32946], () => import("./deflate-B35gUGrI.js").then((m2) => m2.default));
209467
- addDecoder(32773, () => import("./packbits-Ds8BMewq.js").then((m2) => m2.default));
209468
+ addDecoder(7, () => import("./jpeg-CYgQz5aG.js").then((m2) => m2.default));
209469
+ addDecoder([8, 32946], () => import("./deflate-VdN3pn_b.js").then((m2) => m2.default));
209470
+ addDecoder(32773, () => import("./packbits-BOwAxrqR.js").then((m2) => m2.default));
209468
209471
  addDecoder(
209469
209472
  34887,
209470
- () => import("./lerc-DEzmYyQ_.js").then(async (m2) => {
209473
+ () => import("./lerc-C-Llf71G.js").then(async (m2) => {
209471
209474
  await m2.zstd.init();
209472
209475
  return m2;
209473
209476
  }).then((m2) => m2.default)
209474
209477
  );
209475
- addDecoder(50001, () => import("./webimage-BnK9oxcF.js").then((m2) => m2.default));
209478
+ addDecoder(50001, () => import("./webimage-DCU5-f3Q.js").then((m2) => m2.default));
209476
209479
  function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
209477
209480
  return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
209478
209481
  }
@@ -226693,7 +226696,7 @@ const BASE_POINT_SIZE = 5;
226693
226696
  const LARGE_DATASET_CELL_COUNT = 1e4;
226694
226697
  const SMALL_DATASET_CELL_COUNT = 100;
226695
226698
  function getInitialPointSize(numCells = LARGE_DATASET_CELL_COUNT) {
226696
- return BASE_POINT_SIZE / clamp$7(numCells, SMALL_DATASET_CELL_COUNT, LARGE_DATASET_CELL_COUNT);
226699
+ return BASE_POINT_SIZE / clamp$8(numCells, SMALL_DATASET_CELL_COUNT, LARGE_DATASET_CELL_COUNT);
226697
226700
  }
226698
226701
  function getPointSizeDevicePixels(devicePixelRatio2, zoom2, xRange, yRange, width2, height2, numCells) {
226699
226702
  const pointSize = getInitialPointSize(numCells);
@@ -226706,7 +226709,7 @@ function getPointSizeDevicePixels(devicePixelRatio2, zoom2, xRange, yRange, widt
226706
226709
  const diagonalAxisRange = Math.sqrt(xAxisRange ** 2 + yAxisRange ** 2);
226707
226710
  const diagonalFraction = pointSize / diagonalAxisRange;
226708
226711
  const deviceSize = diagonalFraction * diagonalScreenSize;
226709
- const pointSizeDevicePixels = clamp$7(deviceSize, pointScreenSizeMin, pointScreenSizeMax);
226712
+ const pointSizeDevicePixels = clamp$8(deviceSize, pointScreenSizeMin, pointScreenSizeMax);
226710
226713
  return pointSizeDevicePixels;
226711
226714
  }
226712
226715
  function getPointOpacity(zoom2, xRange, yRange, width2, height2, numCells, avgFillDensity) {
@@ -226735,7 +226738,7 @@ function getPointOpacity(zoom2, xRange, yRange, width2, height2, numCells, avgFi
226735
226738
  rho = Math.min(1, 1 / 10 ** (Math.log10(N2) - 3));
226736
226739
  }
226737
226740
  const alpha2 = rho * W * H / N2 * (Y02 / Y3) * (X02 / X3);
226738
- const pointOpacity = clamp$7(alpha2, 1.01 / 255, 1);
226741
+ const pointOpacity = clamp$8(alpha2, 1.01 / 255, 1);
226739
226742
  return pointOpacity;
226740
226743
  }
226741
226744
  const CELLS_LAYER_ID$1 = "scatterplot";
@@ -227351,7 +227354,7 @@ typeof SuppressedError === "function" ? SuppressedError : function(error2, suppr
227351
227354
  var e3 = new Error(message);
227352
227355
  return e3.name = "SuppressedError", e3.error = error2, e3.suppressed = suppressed, e3;
227353
227356
  };
227354
- const FEATURE_AGGREGATION_STRATEGIES$1 = ["first", "last", "sum", "mean"];
227357
+ const FEATURE_AGGREGATION_STRATEGIES$2 = ["first", "last", "sum", "mean"];
227355
227358
  function ScatterplotOptions(props) {
227356
227359
  const { children: children3, observationsLabel, cellRadius, setCellRadius, cellRadiusMode, setCellRadiusMode, cellOpacity, setCellOpacity, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles, contourColorEncoding, setContourColorEncoding, featureAggregationStrategy, setFeatureAggregationStrategy } = props;
227357
227360
  const scatterplotOptionsId = $bdb11010cef70236$export$f680877a34711e37();
@@ -227476,7 +227479,7 @@ function ScatterplotOptions(props) {
227476
227479
  return "Scatterplot sliders for contour percentile thresholds";
227477
227480
  }, id: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 9e-3, max: 0.999 }) })] }), setFeatureAggregationStrategy ? jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-aggregation-strategy-${scatterplotOptionsId}`, children: "Feature Aggregation Strategy" }) }), jsx$1(TableCell, { className: classes2.inputCell, variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, value: featureAggregationStrategy ?? "first", onChange: handleFeatureAggregationStrategyChange, inputProps: {
227478
227481
  id: `feature-aggregation-strategy-${scatterplotOptionsId}`
227479
- }, children: FEATURE_AGGREGATION_STRATEGIES$1.map((opt) => jsx$1("option", { value: opt, children: capitalize$3(opt) }, opt)) }) })] }) : null] });
227482
+ }, children: FEATURE_AGGREGATION_STRATEGIES$2.map((opt) => jsx$1("option", { value: opt, children: capitalize$3(opt) }, opt)) }) })] }) : null] });
227480
227483
  }
227481
227484
  const useStyles$s = makeStyles()((theme) => ({
227482
227485
  tooltipAnchor: {
@@ -232148,7 +232151,7 @@ function ChannelNamesLegend(props) {
232148
232151
  }) : null });
232149
232152
  }
232150
232153
  const DEFAULT_CONTOUR_PERCENTILES = [0.09, 0.9, 0.99];
232151
- const DEFAULT_FEATURE_AGGREGATION_STRATEGY$2 = "first";
232154
+ const DEFAULT_FEATURE_AGGREGATION_STRATEGY$3 = "first";
232152
232155
  function EmbeddingScatterplotSubscriber(props) {
232153
232156
  const {
232154
232157
  uuid: uuid2,
@@ -232175,7 +232178,7 @@ function EmbeddingScatterplotSubscriber(props) {
232175
232178
  const { embeddingZoom: initialZoom, embeddingTargetX: initialTargetX, embeddingTargetY: initialTargetY } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
232176
232179
  const observationsLabel = observationsLabelOverride || obsType;
232177
232180
  const sampleSetSelection = sampleSetSelectionFromProps || sampleSetSelectionFromCoordination;
232178
- const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY$2;
232181
+ const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY$3;
232179
232182
  const [width2, height2, deckRef] = useDeckCanvasSize();
232180
232183
  const title2 = titleOverride || `Scatterplot (${mapping})`;
232181
232184
  const [
@@ -236847,7 +236850,7 @@ function cbrt(x2) {
236847
236850
  function ceil$2(x2) {
236848
236851
  return finalise(x2 = new this(x2), x2.e + 1, 2);
236849
236852
  }
236850
- function clamp$1(x2, min2, max2) {
236853
+ function clamp$2(x2, min2, max2) {
236851
236854
  return new this(x2).clamp(min2, max2);
236852
236855
  }
236853
236856
  function config$1(obj) {
@@ -237018,7 +237021,7 @@ function clone$1(obj) {
237018
237021
  Decimal3.atan2 = atan2$2;
237019
237022
  Decimal3.cbrt = cbrt;
237020
237023
  Decimal3.ceil = ceil$2;
237021
- Decimal3.clamp = clamp$1;
237024
+ Decimal3.clamp = clamp$2;
237022
237025
  Decimal3.cos = cos$3;
237023
237026
  Decimal3.cosh = cosh;
237024
237027
  Decimal3.div = div;
@@ -250939,6 +250942,16 @@ class RelaxedFetchStore extends FetchStore {
250939
250942
  throw e3;
250940
250943
  }
250941
250944
  }
250945
+ async getRange(key2, range2, options = {}) {
250946
+ try {
250947
+ return await super.getRange(key2, range2, options);
250948
+ } catch (e3) {
250949
+ if (e3?.message?.startsWith("Unexpected response status 403") && true) {
250950
+ return void 0;
250951
+ }
250952
+ throw e3;
250953
+ }
250954
+ }
250942
250955
  }
250943
250956
  function transformEntriesForZipFileStore(entries2) {
250944
250957
  const topLevelZarrDirectories = new Set(Object.keys(entries2).map((k) => k.split("/")[0]).filter((firstPathItem) => firstPathItem?.endsWith(".zarr")));
@@ -251848,7 +251861,8 @@ let Spatial$1 = class Spatial extends AbstractSpatialOrScatterplot {
251848
251861
  "expressionData",
251849
251862
  "cellColorEncoding",
251850
251863
  "geneExpressionColormap",
251851
- "segmentationLayerCallbacks"
251864
+ "segmentationLayerCallbacks",
251865
+ "getExpressionValue"
251852
251866
  ].some(shallowDiff2)) {
251853
251867
  this.onUpdateCellsLayer();
251854
251868
  forceUpdate = true;
@@ -251908,6 +251922,7 @@ const useToggleStyles = makeStyles()(() => ({
251908
251922
  padding: "0px"
251909
251923
  }
251910
251924
  }));
251925
+ const FEATURE_AGGREGATION_STRATEGIES$1 = ["first", "last", "sum", "mean"];
251911
251926
  const ToggleFixedAxisButton = ({ setSpatialAxisFixed, spatialAxisFixed, use3d }) => {
251912
251927
  const toggleAxisId = $bdb11010cef70236$export$f680877a34711e37();
251913
251928
  const { classes: classes2 } = useToggleStyles();
@@ -251917,7 +251932,7 @@ const ToggleFixedAxisButton = ({ setSpatialAxisFixed, spatialAxisFixed, use3d })
251917
251932
  } } }) })] });
251918
251933
  };
251919
251934
  function SpatialOptions(props) {
251920
- const { observationsLabel, cellColorEncoding, setCellColorEncoding, setSpatialAxisFixed, spatialAxisFixed, use3d, tooltipsVisible, setTooltipsVisible, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, canShowExpressionOptions, canShowColorEncodingOption, canShow3DOptions } = props;
251935
+ const { observationsLabel, cellColorEncoding, setCellColorEncoding, setSpatialAxisFixed, spatialAxisFixed, use3d, tooltipsVisible, setTooltipsVisible, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, canShowExpressionOptions, canShowColorEncodingOption, canShow3DOptions, featureAggregationStrategy, setFeatureAggregationStrategy } = props;
251921
251936
  const spatialOptionsId = $bdb11010cef70236$export$f680877a34711e37();
251922
251937
  function handleGeneExpressionColormapChange(event2) {
251923
251938
  setGeneExpressionColormap(event2.target.value);
@@ -251953,7 +251968,7 @@ function SpatialOptions(props) {
251953
251968
  }, value: geneExpressionColormapRange, onChange: handleColormapRangeChangeDebounced, getAriaLabel: (index2) => {
251954
251969
  const labelPrefix = index2 === 0 ? "Low value slider" : "High value slider";
251955
251970
  return `${labelPrefix} for spatial gene expression colormap range`;
251956
- }, id: `gene-expression-colormap-range-${spatialOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 0, max: 1 }) })] })] }) : null] });
251971
+ }, id: `gene-expression-colormap-range-${spatialOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 0, max: 1 }) })] }), setFeatureAggregationStrategy ? jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-aggregation-strategy-${spatialOptionsId}`, children: "Feature Aggregation Strategy" }) }), jsx$1(TableCell, { className: classes2.inputCell, variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, value: featureAggregationStrategy ?? "first", onChange: (e3) => setFeatureAggregationStrategy(e3.target.value), inputProps: { id: `feature-aggregation-strategy-${spatialOptionsId}` }, children: FEATURE_AGGREGATION_STRATEGIES$1.map((opt) => jsx$1("option", { value: opt, children: capitalize$3(opt) }, opt)) }) })] }) : null] }) : null] });
251957
251972
  }
251958
251973
  function SpatialTooltipSubscriber$1(props) {
251959
251974
  const { parentUuid, obsHighlight, width: width2, height: height2, getObsInfo: getObsInfo2, hoverData, hoverCoord, hoverMode, useHoverInfoForTooltip, getObsIdFromHoverData, featureType, featureLabelsMap } = props;
@@ -251985,12 +252000,13 @@ function SpatialTooltipSubscriber$1(props) {
251985
252000
  }
251986
252001
  return cellInfo ? jsx$1(Tooltip2D, { x: x2, y: y2, parentUuid, sourceUuid, parentWidth: width2, parentHeight: height2, children: jsx$1(TooltipContent, { info: cellInfo, featureType, featureLabelsMap }) }) : null;
251987
252002
  }
252003
+ const DEFAULT_FEATURE_AGGREGATION_STRATEGY$2 = "first";
251988
252004
  function SpatialSubscriber$1(props) {
251989
252005
  const { uuid: uuid2, coordinationScopes, closeButtonVisible, downloadButtonVisible, removeGridComponent, observationsLabelOverride, subobservationsLabelOverride: subobservationsLabel = "molecule", theme, title: title2 = "Spatial", disable3d, globalDisable3d, useFullResolutionImage = {}, channelNamesVisible = false, helpText = ViewHelpMapping.SPATIAL } = props;
251990
252006
  const loaders = useLoaders();
251991
252007
  const setComponentHover = useSetComponentHover();
251992
252008
  const setComponentViewInfo = useSetComponentViewInfo(uuid2);
251993
- const [{ dataset, obsType, featureType, featureValueType, spatialZoom: zoom2, spatialTargetX: targetX2, spatialTargetY: targetY2, spatialTargetZ: targetZ, spatialRotationX: rotationX, spatialRotationY: rotationY, spatialRotationZ: rotationZ, spatialRotationOrbit: rotationOrbit, spatialOrbitAxis: orbitAxis, spatialImageLayer: imageLayers, spatialSegmentationLayer: cellsLayer, spatialPointLayer: moleculesLayer, spatialNeighborhoodLayer: neighborhoodsLayer, obsFilter: cellFilter, obsHighlight: cellHighlight, moleculeHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, spatialAxisFixed, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible, photometricInterpretation: photometricInterpretationFromCoordination }, { setSpatialZoom: setZoom, setSpatialTargetX: setTargetX, setSpatialTargetY: setTargetY, setSpatialTargetZ: setTargetZ, setSpatialRotationX: setRotationX, setSpatialRotationOrbit: setRotationOrbit, setSpatialOrbitAxis: setOrbitAxis, setSpatialImageLayer: setRasterLayers, setSpatialSegmentationLayer: setCellsLayer, setSpatialPointLayer: setMoleculesLayer, setSpatialNeighborhoodLayer: setNeighborhoodsLayer, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setMoleculeHighlight, setSpatialAxisFixed, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL], coordinationScopes);
252009
+ const [{ dataset, obsType, featureType, featureValueType, spatialZoom: zoom2, spatialTargetX: targetX2, spatialTargetY: targetY2, spatialTargetZ: targetZ, spatialRotationX: rotationX, spatialRotationY: rotationY, spatialRotationZ: rotationZ, spatialRotationOrbit: rotationOrbit, spatialOrbitAxis: orbitAxis, spatialImageLayer: imageLayers, spatialSegmentationLayer: cellsLayer, spatialPointLayer: moleculesLayer, spatialNeighborhoodLayer: neighborhoodsLayer, obsFilter: cellFilter, obsHighlight: cellHighlight, moleculeHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, spatialAxisFixed, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible, photometricInterpretation: photometricInterpretationFromCoordination, featureAggregationStrategy }, { setSpatialZoom: setZoom, setSpatialTargetX: setTargetX, setSpatialTargetY: setTargetY, setSpatialTargetZ: setTargetZ, setSpatialRotationX: setRotationX, setSpatialRotationOrbit: setRotationOrbit, setSpatialOrbitAxis: setOrbitAxis, setSpatialImageLayer: setRasterLayers, setSpatialSegmentationLayer: setCellsLayer, setSpatialPointLayer: setMoleculesLayer, setSpatialNeighborhoodLayer: setNeighborhoodsLayer, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setMoleculeHighlight, setSpatialAxisFixed, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible, setFeatureAggregationStrategy }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL], coordinationScopes);
251994
252010
  const { spatialZoom: initialZoom, spatialTargetX: initialTargetX, spatialTargetY: initialTargetY, spatialTargetZ: initialTargetZ } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL], coordinationScopes);
251995
252011
  const observationsLabel = observationsLabelOverride || obsType;
251996
252012
  const [{ imageLayerCallbacks, segmentationLayerCallbacks }] = useAuxiliaryCoordination(COMPONENT_COORDINATION_TYPES.layerController, coordinationScopes);
@@ -252196,7 +252212,15 @@ function SpatialSubscriber$1(props) {
252196
252212
  subobservationsLabel,
252197
252213
  locationsCount
252198
252214
  });
252199
- const { normData: uint8ExpressionData, extents: expressionExtents } = useUint8FeatureSelection(expressionData);
252215
+ const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY$2;
252216
+ const aggregatedExpressionData = useMemo$1(() => {
252217
+ if (featureAggregationStrategyToUse != null && expressionData && expressionData.length > 1) {
252218
+ const aggregated = aggregateFeatureArrays(expressionData, featureAggregationStrategyToUse);
252219
+ return [aggregated];
252220
+ }
252221
+ return expressionData;
252222
+ }, [expressionData, featureAggregationStrategyToUse]);
252223
+ const { normData: uint8ExpressionData, extents: expressionExtents } = useUint8FeatureSelection(aggregatedExpressionData);
252200
252224
  const shiftedExpressionDataForBitmask = useMemo$1(() => {
252201
252225
  if (matrixObsIndex && uint8ExpressionData && obsSegmentationsType === "bitmask") {
252202
252226
  const maxId = matrixObsIndex.reduce((max2, curr) => Math.max(max2, Number(curr)));
@@ -252221,7 +252245,7 @@ function SpatialSubscriber$1(props) {
252221
252245
  const canShow3DOptions = canLoad3DLayers && !(disable3d?.length === imageLayerLoaders.length) && !globalDisable3d;
252222
252246
  const options = useMemo$1(() => {
252223
252247
  if (canShow3DOptions || hasExpressionData) {
252224
- return jsx$1(SpatialOptions, { observationsLabel, cellColorEncoding, setCellColorEncoding, setSpatialAxisFixed, spatialAxisFixed, use3d, tooltipsVisible, setTooltipsVisible, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, canShowExpressionOptions: hasExpressionData, canShowColorEncodingOption: (hasLocationsData || hasSegmentationsData) && hasExpressionData, canShow3DOptions });
252248
+ return jsx$1(SpatialOptions, { observationsLabel, cellColorEncoding, setCellColorEncoding, setSpatialAxisFixed, spatialAxisFixed, use3d, tooltipsVisible, setTooltipsVisible, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, canShowExpressionOptions: hasExpressionData, canShowColorEncodingOption: (hasLocationsData || hasSegmentationsData) && hasExpressionData, canShow3DOptions, featureSelection: geneSelection, featureAggregationStrategy, setFeatureAggregationStrategy });
252225
252249
  }
252226
252250
  return null;
252227
252251
  }, [
@@ -252240,7 +252264,10 @@ function SpatialSubscriber$1(props) {
252240
252264
  spatialAxisFixed,
252241
252265
  use3d,
252242
252266
  tooltipsVisible,
252243
- setTooltipsVisible
252267
+ setTooltipsVisible,
252268
+ geneSelection,
252269
+ featureAggregationStrategy,
252270
+ setFeatureAggregationStrategy
252244
252271
  ]);
252245
252272
  useEffect(() => {
252246
252273
  if (!hasSegmentationsData && cellsLayer && !obsSegmentations && !obsSegmentationsIndex && obsCentroids && obsCentroidsIndex) {
@@ -252303,7 +252330,8 @@ function SpatialSubscriber$1(props) {
252303
252330
  featureValueColormap: geneExpressionColormap,
252304
252331
  featureValueColormapRange: geneExpressionColormapRange,
252305
252332
  setFeatureValueColormapRange: setGeneExpressionColormapRange,
252306
- extent: expressionExtents?.[0]
252333
+ extent: expressionExtents?.[0],
252334
+ featureAggregationStrategy: featureAggregationStrategyToUse
252307
252335
  })] });
252308
252336
  }
252309
252337
  function getInitialSpatialTargets({ width: width2, height: height2, obsPoints, obsSpots, obsSegmentations, obsSegmentationsLocations, segmentationChannelScopesByLayer, images, is3dMode: use3d, isReady }) {
@@ -253955,12 +253983,12 @@ class ErrorBoundary extends React__default.Component {
253955
253983
  }
253956
253984
  }
253957
253985
  const LazySpatialThree = React__default.lazy(async () => {
253958
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-CIJWVuYa.js").then((n3) => n3.a);
253986
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-tp3-aWWe.js").then((n3) => n3.a);
253959
253987
  return { default: SpatialWrapper2 };
253960
253988
  });
253961
253989
  const SpatialThreeAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialThree, { ...props }) }) }) }));
253962
253990
  const LazySpatialAccelerated = React__default.lazy(async () => {
253963
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-BRdVNpUK.js");
253991
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-Dau2mo3I.js");
253964
253992
  return { default: SpatialWrapper2 };
253965
253993
  });
253966
253994
  const SpatialAcceleratedAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialAccelerated, { ...props }) }) }) }));
@@ -254688,8 +254716,8 @@ function getAxisSizes(transpose2, longestGeneLabel, longestCellLabel, hideObserv
254688
254716
  const font2 = `${AXIS_LABEL_TEXT_SIZE}pt ${AXIS_FONT_FAMILY}`;
254689
254717
  const geneLabelMaxWidth = hideVariableLabels ? 0 : getTextWidth(longestGeneLabel, font2) + AXIS_PADDING;
254690
254718
  const cellLabelMaxWidth = hideObservationLabels ? 0 : getTextWidth(longestCellLabel, font2) + AXIS_PADDING;
254691
- const axisOffsetLeft = clamp$7(transpose2 ? geneLabelMaxWidth : cellLabelMaxWidth, AXIS_MIN_SIZE, AXIS_MAX_SIZE);
254692
- const axisOffsetTop = clamp$7(transpose2 ? cellLabelMaxWidth : geneLabelMaxWidth, AXIS_MIN_SIZE, AXIS_MAX_SIZE);
254719
+ const axisOffsetLeft = clamp$8(transpose2 ? geneLabelMaxWidth : cellLabelMaxWidth, AXIS_MIN_SIZE, AXIS_MAX_SIZE);
254720
+ const axisOffsetTop = clamp$8(transpose2 ? cellLabelMaxWidth : geneLabelMaxWidth, AXIS_MIN_SIZE, AXIS_MAX_SIZE);
254693
254721
  return [axisOffsetLeft, axisOffsetTop];
254694
254722
  }
254695
254723
  function mouseToHeatmapPosition(mouseX, mouseY, { offsetLeft, offsetTop, targetX: targetX2, targetY: targetY2, scaleFactor, matrixWidth, matrixHeight, numRows, numCols }) {
@@ -254919,8 +254947,8 @@ const Heatmap$1 = forwardRef$1((props, deckRef) => {
254919
254947
  const scaleFactor = 2 ** viewState.zoom;
254920
254948
  const cellHeight = matrixHeight * scaleFactor / height2;
254921
254949
  const cellWidth = matrixWidth * scaleFactor / width2;
254922
- const aggSizeX = clamp$7(2 ** Math.ceil(Math.log2(1 / cellWidth)), MIN_ROW_AGG, MAX_ROW_AGG);
254923
- const aggSizeY = clamp$7(2 ** Math.ceil(Math.log2(1 / cellHeight)), MIN_ROW_AGG, MAX_ROW_AGG);
254950
+ const aggSizeX = clamp$8(2 ** Math.ceil(Math.log2(1 / cellWidth)), MIN_ROW_AGG, MAX_ROW_AGG);
254951
+ const aggSizeY = clamp$8(2 ** Math.ceil(Math.log2(1 / cellHeight)), MIN_ROW_AGG, MAX_ROW_AGG);
254924
254952
  const [targetX2, targetY2] = viewState.target;
254925
254953
  useEffect(() => {
254926
254954
  updateViewInfo({
@@ -254964,8 +254992,8 @@ const Heatmap$1 = forwardRef$1((props, deckRef) => {
254964
254992
  const minTargetY = nextZoom === 0 ? 0 : -(matrixBottom - matrixBottom / nextScaleFactor);
254965
254993
  const maxTargetY = -1 * minTargetY;
254966
254994
  const nextTarget = [
254967
- clamp$7(nextViewState.target[0], minTargetX, maxTargetX),
254968
- clamp$7(nextViewState.target[1], minTargetY, maxTargetY)
254995
+ clamp$8(nextViewState.target[0], minTargetX, maxTargetX),
254996
+ clamp$8(nextViewState.target[1], minTargetY, maxTargetY)
254969
254997
  ];
254970
254998
  setViewState({
254971
254999
  zoom: nextZoom,
@@ -262110,7 +262138,7 @@ const useStyles$n = makeStyles()((theme) => ({
262110
262138
  }));
262111
262139
  const SHIFT_KEYCODE = 16;
262112
262140
  function SelectableTable(props) {
262113
- const { hasColorEncoding, columns: columns2, columnLabels, data: data2, onChange, idKey = "id", valueKey = "value", allowMultiple = false, allowUncheck = false, showTableHead = true, showTableInputs = false, testHeight = void 0, testWidth = void 0, width: width2, height: height2 } = props;
262141
+ const { hasColorEncoding, columns: columns2, columnLabels, data: data2, onChange, idKey = "id", selectedIds, allowMultiple = false, allowUncheck = false, showTableHead = true, showTableInputs = false, testHeight = void 0, testWidth = void 0, width: width2, height: height2 } = props;
262114
262142
  const [selectedRows, setSelectedRows] = useState(null);
262115
262143
  const [isCheckingMultiple, setIsCheckingMultiple] = useState(false);
262116
262144
  useEffect(() => {
@@ -262154,20 +262182,20 @@ function SelectableTable(props) {
262154
262182
  })), [data2, idKey]);
262155
262183
  const isSelected = useCallback((id2) => Array.isArray(selectedRows) && selectedRows.includes(id2), [selectedRows]);
262156
262184
  useEffect(() => {
262157
- const initialSelectedRows = data2.map((d) => {
262158
- if (d[valueKey]) {
262159
- return d[idKey];
262160
- }
262161
- return null;
262162
- }).filter(Boolean);
262163
- if (!isEqual$3(initialSelectedRows, selectedRows)) {
262164
- if (initialSelectedRows.length > 0) {
262165
- setSelectedRows(initialSelectedRows);
262166
- } else {
262167
- setSelectedRows(null);
262185
+ if (selectedIds === void 0)
262186
+ return;
262187
+ setSelectedRows((prev2) => {
262188
+ const prevList = prev2 || [];
262189
+ const nextList = selectedIds || [];
262190
+ const sharedList = prevList.filter((id2) => nextList.includes(id2));
262191
+ const nextUnique = nextList.filter((id2) => !prevList.includes(id2));
262192
+ const merged = [...sharedList, ...nextUnique];
262193
+ if (isEqual$3(merged, prevList)) {
262194
+ return prev2;
262168
262195
  }
262169
- }
262170
- }, [data2, idKey, valueKey]);
262196
+ return merged.length > 0 ? merged : null;
262197
+ });
262198
+ }, [selectedIds]);
262171
262199
  useEffect(() => {
262172
262200
  if (!onChange || !selectedRows) {
262173
262201
  return;
@@ -262239,8 +262267,7 @@ function FeatureList(props) {
262239
262267
  const data2 = useMemo$1(() => {
262240
262268
  const preSortedData = searchResults.filter((gene) => geneFilter ? geneFilter.includes(gene) : true).map((gene) => ({
262241
262269
  key: gene,
262242
- name: featureLabelsMap?.get(gene) || featureLabelsMap?.get(cleanFeatureId(gene)) || gene,
262243
- value: geneSelection ? geneSelection.includes(gene) : false
262270
+ name: featureLabelsMap?.get(gene) || featureLabelsMap?.get(cleanFeatureId(gene)) || gene
262244
262271
  }));
262245
262272
  if (preSortedData && featureListSort === "alphabetical" && preSortedData.length > 0) {
262246
262273
  return preSortedData.sort((a2, b2) => a2[selectableTableSortKey].localeCompare(b2[selectableTableSortKey]));
@@ -262251,8 +262278,7 @@ function FeatureList(props) {
262251
262278
  selectableTableSortKey,
262252
262279
  searchResults,
262253
262280
  geneFilter,
262254
- featureLabelsMap,
262255
- geneSelection
262281
+ featureLabelsMap
262256
262282
  ]);
262257
262283
  const handleChange = (event2) => {
262258
262284
  setSearchTerm(event2.target.value);
@@ -262269,7 +262295,7 @@ function FeatureList(props) {
262269
262295
  [primaryColumnName]
262270
262296
  ];
262271
262297
  }, [showFeatureTable, primaryColumnName, hasFeatureLabels]);
262272
- return width2 > 0 && height2 > 0 ? jsxs(Fragment, { children: [jsx$1("input", { className: classes2.searchBar, type: "text", placeholder: "Search", value: searchTerm, onChange: handleChange }), jsx$1(SelectableTable, { columns: columns2, columnLabels, data: data2, hasColorEncoding, idKey: "key", valueKey: "value", onChange, allowMultiple: enableMultiSelect, allowUncheck: enableMultiSelect, showTableHead: columnLabels.length > 1, width: width2, height: height2 - 34 })] }) : null;
262298
+ return width2 > 0 && height2 > 0 ? jsxs(Fragment, { children: [jsx$1("input", { className: classes2.searchBar, type: "text", placeholder: "Search", value: searchTerm, onChange: handleChange }), jsx$1(SelectableTable, { columns: columns2, columnLabels, data: data2, hasColorEncoding, idKey: "key", selectedIds: geneSelection, onChange, allowMultiple: enableMultiSelect, allowUncheck: enableMultiSelect, showTableHead: columnLabels.length > 1, width: width2, height: height2 - 34 })] }) : null;
262273
262299
  }
262274
262300
  function FeatureListOptions(props) {
262275
262301
  const { children: children3, featureListSort, setFeatureListSort, featureListSortKey, setFeatureListSortKey, showFeatureTable, setShowFeatureTable, hasFeatureLabels, primaryColumnName } = props;
@@ -263785,7 +263811,7 @@ function PointLayerController(props) {
263785
263811
  const [coloringTabIndex, setColoringTabIndex] = useState(0);
263786
263812
  const { featureIndex } = pointMatrixIndicesData || {};
263787
263813
  const hasSelectedFeatures = Array.isArray(featureSelection) && featureSelection.length > 0;
263788
- return jsxs(Grid$1, { className: lcClasses.layerControllerGrid, children: [jsxs(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleVisibleChange, className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: color2, setColor: setColor2, palette, isStaticColor, isColormap, featureValueColormap, visible }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(PointLayerEllipsisMenu, { featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible, featureFilterMode, setFeatureFilterMode }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }), null] })] }), loadingDoneFraction < 1 ? jsx$1(Grid$1, { size: 12, container: true, direction: "column", justifyContent: "space-between", className: classes2.pointFeatureControllerGrid, children: jsx$1(LinearProgress, { variant: loadingDoneFraction === 0 ? "indeterminate" : "determinate", value: loadingDoneFraction * 100 }) }) : null, null] }), hasSelectedFeatures ? jsxs(Fragment, { children: [featureSelection.map((featureName) => jsx$1(LayerPerFeatureController, { theme, featureName, featureColor, setFeatureColor, spatialLayerColor, featureIndex, featureValueColormap, featureSelection, setFeatureSelection, obsColorEncoding, loadingDoneFraction, opacity: opacity2, handleOpacityChange }, featureName)), jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 2, className: lcClasses.layerControllerSubRow, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: () => setFeatureFilterMode(featureFilterMode === "featureSelection" ? null : "featureSelection"), className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle visibility of unselected points", children: featureFilterMode === "featureSelection" ? jsx$1(VisibilityOffIcon, {}) : jsx$1(VisibilityIcon, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: getDefaultColor("dark"), setColor: null, isStaticColor: true, isColormap: false, visible: true }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: "Unselected" }) }), jsx$1(Grid$1, { size: 2, sx: { paddingRight: "12px", overflow: "visible" }, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": "Adjust opacity for unselected layer" }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }) })] }) }) })] }) : null] });
263814
+ return jsxs(Grid$1, { className: lcClasses.layerControllerGrid, children: [jsxs(Paper, { elevation: 4, className: lcClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: handleVisibleChange, className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: color2, setColor: setColor2, palette, isStaticColor, isColormap, featureValueColormap, visible }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(PointLayerEllipsisMenu, { featureSelection, obsColorEncoding, setObsColorEncoding, featureValueColormapRange, setFeatureValueColormapRange, tooltipsVisible, setTooltipsVisible, tooltipCrosshairsVisible, setTooltipCrosshairsVisible, legendVisible, setLegendVisible, featureFilterMode, setFeatureFilterMode }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }), null] })] }), loadingDoneFraction < 1 ? jsx$1(Grid$1, { size: 12, container: true, direction: "column", justifyContent: "space-between", className: classes2.pointFeatureControllerGrid, children: jsx$1(LinearProgress, { variant: loadingDoneFraction === 0 ? "indeterminate" : "determinate", value: loadingDoneFraction * 100 }) }) : null, null] }), layerPerFeatureForPoints && hasSelectedFeatures ? jsxs(Fragment, { children: [featureSelection.map((featureName) => jsx$1(LayerPerFeatureController, { theme, featureName, featureColor, setFeatureColor, spatialLayerColor, featureIndex, featureValueColormap, featureSelection, setFeatureSelection, obsColorEncoding, loadingDoneFraction, opacity: opacity2, handleOpacityChange }, featureName)), jsx$1(Grid$1, { className: lcClasses.layerControllerGrid, children: jsx$1(Paper, { elevation: 2, className: lcClasses.layerControllerSubRow, children: jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { onClick: () => setFeatureFilterMode(featureFilterMode === "featureSelection" ? null : "featureSelection"), className: menuClasses.imageLayerVisibleButton, "aria-label": "Toggle visibility of unselected points", children: featureFilterMode === "featureSelection" ? jsx$1(VisibilityOffIcon, {}) : jsx$1(VisibilityIcon, {}) }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { theme, color: getDefaultColor("dark"), setColor: null, isStaticColor: true, isColormap: false, visible: true }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: "Unselected" }) }), jsx$1(Grid$1, { size: 2, sx: { paddingRight: "12px", overflow: "visible" }, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": "Adjust opacity for unselected layer" }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(SvgPoints, { className: classes2.layerTypePointIcon }) })] }) }) })] }) : null] });
263789
263815
  }
263790
263816
  const useStyles$d = makeStyles()(() => ({
263791
263817
  layerTypeSegmentationIcon: {
@@ -267536,7 +267562,7 @@ function HiglassGlobalStyles(props) {
267536
267562
  }
267537
267563
  register({ dataFetcher: ZarrMultivecDataFetcher_default, config: ZarrMultivecDataFetcher_default.config }, { pluginType: "dataFetcher" });
267538
267564
  const LazyHiGlassComponent = React__default.lazy(async () => {
267539
- const { HiGlassComponent } = await import("./higlass-DIGh19X3.js");
267565
+ const { HiGlassComponent } = await import("./higlass-DL7cd1YR.js");
267540
267566
  return { default: HiGlassComponent };
267541
267567
  });
267542
267568
  const HG_SIZE = 800;
@@ -270484,7 +270510,7 @@ function NeuroglancerGlobalStyles(props) {
270484
270510
  const { classes: classes2 } = props;
270485
270511
  return jsxs(Fragment, { children: [jsx$1(GlobalStyles$3, { styles: globalNeuroglancerCss }), jsx$1(ScopedGlobalStyles, { styles: globalNeuroglancerStyles, parentClassName: classes2.neuroglancerWrapper })] });
270486
270512
  }
270487
- const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-VYcAJw_c.js"));
270513
+ const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-Do72MK3I.js"));
270488
270514
  function createWorker() {
270489
270515
  const worker = new WorkerFactory$1();
270490
270516
  worker.AsyncComputationWorker = WorkerFactory;
@@ -271174,17 +271200,40 @@ function diffCameraState(prev2, next4) {
271174
271200
  const pos = posHard || posSoft;
271175
271201
  return { changed: scale2 || pos || rot2, scale: scale2, pos, rot: rot2 };
271176
271202
  }
271203
+ const clamp$1 = (value2, min2, max2) => Math.max(min2, Math.min(max2, value2));
271177
271204
  function quaternionToEuler([x2, y2, z2, w2]) {
271178
- const quaternion2 = new Quaternion$1(x2, y2, z2, w2);
271179
- const euler = new Euler$1().setFromQuaternion(quaternion2, "YXZ");
271180
- const pitch = euler.x;
271181
- const yaw = euler.y;
271205
+ const x22 = x2 + x2;
271206
+ const y22 = y2 + y2;
271207
+ const z22 = z2 + z2;
271208
+ const xx = x2 * x22;
271209
+ const yy = y2 * y22;
271210
+ const zz = z2 * z22;
271211
+ const xz = x2 * z22;
271212
+ const yz = y2 * z22;
271213
+ const wx = w2 * x22;
271214
+ const wy = w2 * y22;
271215
+ const m11 = 1 - (yy + zz);
271216
+ const m13 = xz + wy;
271217
+ const m23 = yz - wx;
271218
+ const m31 = xz - wy;
271219
+ const m33 = 1 - (xx + yy);
271220
+ const pitch = Math.asin(-clamp$1(m23, -1, 1));
271221
+ const yaw = Math.abs(m23) < 0.9999999 ? Math.atan2(m13, m33) : Math.atan2(-m31, m11);
271182
271222
  return [pitch, yaw];
271183
271223
  }
271184
271224
  function eulerToQuaternion(pitch, yaw, roll = 0) {
271185
- const euler = new Euler$1(pitch, yaw, roll, "YXZ");
271186
- const quaternion2 = new Quaternion$1().setFromEuler(euler);
271187
- return [quaternion2.x, quaternion2.y, quaternion2.z, quaternion2.w];
271225
+ const c1 = Math.cos(pitch / 2);
271226
+ const c2 = Math.cos(yaw / 2);
271227
+ const c3 = Math.cos(roll / 2);
271228
+ const s1 = Math.sin(pitch / 2);
271229
+ const s2 = Math.sin(yaw / 2);
271230
+ const s3 = Math.sin(roll / 2);
271231
+ return [
271232
+ s1 * c2 * c3 + c1 * s2 * s3,
271233
+ c1 * s2 * c3 - s1 * c2 * s3,
271234
+ c1 * c2 * s3 - s1 * s2 * c3,
271235
+ c1 * c2 * c3 + s1 * s2 * s3
271236
+ ];
271188
271237
  }
271189
271238
  function makeVitNgZoomCalibrator(initialNgProjectionScale, initialDeckZoom = 0) {
271190
271239
  const base2 = initialNgProjectionScale / 2 ** -initialDeckZoom;
@@ -324325,8 +324374,8 @@ function CellSetSizesPlot(props) {
324325
324374
  value: 0
324326
324375
  }
324327
324376
  },
324328
- width: clamp$7(width2 - marginRight, 10, Infinity),
324329
- height: clamp$7(height2 - marginBottom, 10, Infinity),
324377
+ width: clamp$8(width2 - marginRight, 10, Infinity),
324378
+ height: clamp$8(height2 - marginBottom, 10, Infinity),
324330
324379
  config: VEGA_THEMES[theme]
324331
324380
  };
324332
324381
  const handleSignal = (name2, value2) => {
@@ -324439,8 +324488,8 @@ function ExpressionHistogram(props) {
324439
324488
  select: { type: "interval", encodings: ["x"] }
324440
324489
  }
324441
324490
  ],
324442
- width: clamp$7(width2 - marginRight, 10, Infinity),
324443
- height: clamp$7(height2 - marginBottom, 10, Infinity),
324491
+ width: clamp$8(width2 - marginRight, 10, Infinity),
324492
+ height: clamp$8(height2 - marginBottom, 10, Infinity),
324444
324493
  config: VEGA_THEMES[theme]
324445
324494
  };
324446
324495
  const handleSignal = (name2, value2) => {
@@ -324575,8 +324624,8 @@ function DotPlot(props) {
324575
324624
  const autoMarginForFeature = marginBottom || 30 + Math.sqrt(maxCharactersForFeature / 2) * 30;
324576
324625
  const autoMarginForGroup = marginRight || 30 + Math.sqrt(maxCharactersForGroup / 2) * 30;
324577
324626
  const autoMarginForSampleSet = marginRight || 30 + Math.sqrt(maxCharactersForSampleSet / 2) * 30;
324578
- const plotWidth = transpose2 ? clamp$7(width2 - autoMarginForFeature - 180, 10, Infinity) / (obsSetSelection?.length || 1) : clamp$7(width2 - autoMarginForGroup - autoMarginForSampleSet - 200, 10, Infinity);
324579
- const plotHeight = transpose2 ? clamp$7(height2 - autoMarginForGroup - autoMarginForSampleSet - 50, 10, Infinity) : clamp$7(height2 - autoMarginForFeature - 80, 10, Infinity) / (obsSetSelection?.length || 1);
324627
+ const plotWidth = transpose2 ? clamp$8(width2 - autoMarginForFeature - 180, 10, Infinity) / (obsSetSelection?.length || 1) : clamp$8(width2 - autoMarginForGroup - autoMarginForSampleSet - 200, 10, Infinity);
324628
+ const plotHeight = transpose2 ? clamp$8(height2 - autoMarginForGroup - autoMarginForSampleSet - 50, 10, Infinity) : clamp$8(height2 - autoMarginForFeature - 80, 10, Infinity) / (obsSetSelection?.length || 1);
324580
324629
  const groupKeys = data2.map((d) => d.keyGroup);
324581
324630
  const featureKeys = data2.map((d) => d.keyFeature);
324582
324631
  const groupSecondaryKeys = data2.map((d) => d.keyGroupSecondary);
@@ -325572,8 +325621,8 @@ function CellSetCompositionBarPlot(props) {
325572
325621
  }
325573
325622
  },
325574
325623
  // TODO: for width, also subtract length of longest y-axis set name label.
325575
- width: clamp$7(width2 - marginRight, 10, Infinity),
325576
- height: clamp$7(height2 - marginBottom, 10, Infinity),
325624
+ width: clamp$8(width2 - marginRight, 10, Infinity),
325625
+ height: clamp$8(height2 - marginBottom, 10, Infinity),
325577
325626
  config: VEGA_THEMES[theme]
325578
325627
  };
325579
325628
  const handleSignal = (name2, value2) => {
@@ -325754,8 +325803,8 @@ function FeatureSetEnrichmentBarPlot(props) {
325754
325803
  }
325755
325804
  },
325756
325805
  // TODO: for width, also subtract length of longest y-axis set name label.
325757
- width: clamp$7(width2 - marginRight, 10, Infinity),
325758
- height: clamp$7(height2 - marginBottom, 10, Infinity),
325806
+ width: clamp$8(width2 - marginRight, 10, Infinity),
325807
+ height: clamp$8(height2 - marginBottom, 10, Infinity),
325759
325808
  config: VEGA_THEMES[theme]
325760
325809
  };
325761
325810
  const handleSignal = (name2, value2) => {
@@ -326287,7 +326336,9 @@ class OmeAutoConfig extends AbstractAutoConfig {
326287
326336
  // TODO: how to handle h5ad-based AnnData (since needs reference JSON file).
326288
326337
  // Perhaps just assume one H5AD+one JSON (or .ref.json) file correspond to each other?
326289
326338
  [FileType$1.SPATIALDATA_ZARR]: [".sd.zarr", ".sdata.zarr", ".spatialdata.zarr"],
326290
- [FileType$1.SPATIALDATA_ZARR_ZIP]: [".sd.zarr.zip", ".sdata.zarr.zip", ".spatialdata.zarr.zip"]
326339
+ [FileType$1.SPATIALDATA_ZARR_ZIP]: [".sd.zarr.zip", ".sdata.zarr.zip", ".spatialdata.zarr.zip"],
326340
+ [FileType$1.GENOMIC_PROFILES_ZARR]: [".multivec.zarr"],
326341
+ [FileType$1.GENOMIC_PROFILES_ZARR_ZIP]: [".multivec.zarr.zip"]
326291
326342
  });
326292
326343
  ({
326293
326344
  // OME-TIFF
@@ -326313,8 +326364,106 @@ class OmeAutoConfig extends AbstractAutoConfig {
326313
326364
  FileType$1.IMAGE_OME_ZARR,
326314
326365
  FileType$1.IMAGE_OME_ZARR_ZIP,
326315
326366
  FileType$1.OBS_SEGMENTATIONS_OME_ZARR,
326316
- FileType$1.OBS_SEGMENTATIONS_OME_ZARR_ZIP
326367
+ FileType$1.OBS_SEGMENTATIONS_OME_ZARR_ZIP,
326368
+ FileType$1.GENOMIC_PROFILES_ZARR,
326369
+ FileType$1.GENOMIC_PROFILES_ZARR_ZIP
326317
326370
  ];
326371
+ var fetchJsonp$1 = { exports: {} };
326372
+ var fetchJsonp = fetchJsonp$1.exports;
326373
+ var hasRequiredFetchJsonp;
326374
+ function requireFetchJsonp() {
326375
+ if (hasRequiredFetchJsonp) return fetchJsonp$1.exports;
326376
+ hasRequiredFetchJsonp = 1;
326377
+ (function(module2, exports2) {
326378
+ (function(global2, factory2) {
326379
+ {
326380
+ factory2(exports2, module2);
326381
+ }
326382
+ })(fetchJsonp, function(exports3, module3) {
326383
+ var defaultOptions = {
326384
+ timeout: 5e3,
326385
+ jsonpCallback: "callback"
326386
+ };
326387
+ function generateCallbackFunction() {
326388
+ return "jsonp_" + Date.now() + "_" + Math.ceil(Math.random() * 1e5);
326389
+ }
326390
+ function clearFunction(functionName) {
326391
+ try {
326392
+ delete window[functionName];
326393
+ } catch (e3) {
326394
+ window[functionName] = void 0;
326395
+ }
326396
+ }
326397
+ function removeScript(scriptId) {
326398
+ var script = document.getElementById(scriptId);
326399
+ if (script) {
326400
+ document.getElementsByTagName("head")[0].removeChild(script);
326401
+ }
326402
+ }
326403
+ function fetchJsonp2(_url) {
326404
+ var options = arguments.length <= 1 || arguments[1] === void 0 ? {} : arguments[1];
326405
+ var url = _url;
326406
+ var timeout3 = options.timeout || defaultOptions.timeout;
326407
+ var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
326408
+ var timeoutId = void 0;
326409
+ return new Promise(function(resolve2, reject) {
326410
+ var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
326411
+ var scriptId = jsonpCallback + "_" + callbackFunction;
326412
+ window[callbackFunction] = function(response) {
326413
+ resolve2({
326414
+ ok: true,
326415
+ // keep consistent with fetch API
326416
+ json: function json2() {
326417
+ return Promise.resolve(response);
326418
+ }
326419
+ });
326420
+ if (timeoutId) clearTimeout(timeoutId);
326421
+ removeScript(scriptId);
326422
+ clearFunction(callbackFunction);
326423
+ };
326424
+ url += url.indexOf("?") === -1 ? "?" : "&";
326425
+ var jsonpScript = document.createElement("script");
326426
+ jsonpScript.setAttribute("src", "" + url + jsonpCallback + "=" + callbackFunction);
326427
+ if (options.charset) {
326428
+ jsonpScript.setAttribute("charset", options.charset);
326429
+ }
326430
+ if (options.nonce) {
326431
+ jsonpScript.setAttribute("nonce", options.nonce);
326432
+ }
326433
+ if (options.referrerPolicy) {
326434
+ jsonpScript.setAttribute("referrerPolicy", options.referrerPolicy);
326435
+ }
326436
+ if (options.crossorigin) {
326437
+ jsonpScript.setAttribute("crossorigin", typeof options.crossorigin === "string" ? options.crossorigin : "anonymous");
326438
+ }
326439
+ var fp = options.fetchPriority;
326440
+ if (fp === "high" || fp === "low" || fp === "auto") {
326441
+ jsonpScript.setAttribute("fetchPriority", fp);
326442
+ }
326443
+ jsonpScript.id = scriptId;
326444
+ document.getElementsByTagName("head")[0].appendChild(jsonpScript);
326445
+ timeoutId = setTimeout(function() {
326446
+ reject(new Error("JSONP request to " + _url + " timed out"));
326447
+ clearFunction(callbackFunction);
326448
+ removeScript(scriptId);
326449
+ window[callbackFunction] = function() {
326450
+ clearFunction(callbackFunction);
326451
+ };
326452
+ }, timeout3);
326453
+ jsonpScript.onerror = function() {
326454
+ reject(new Error("JSONP request to " + _url + " failed"));
326455
+ clearFunction(callbackFunction);
326456
+ removeScript(scriptId);
326457
+ if (timeoutId) clearTimeout(timeoutId);
326458
+ };
326459
+ });
326460
+ }
326461
+ module3.exports = fetchJsonp2;
326462
+ });
326463
+ })(fetchJsonp$1, fetchJsonp$1.exports);
326464
+ return fetchJsonp$1.exports;
326465
+ }
326466
+ requireFetchJsonp();
326318
326467
  class ObsSpotsCsvLoader extends CsvLoader {
326319
326468
  loadFromCache(data2) {
326320
326469
  if (this.cachedResult) {
@@ -327229,11 +327378,21 @@ class AnnDataSource extends ZarrDataSource {
327229
327378
  categoriesValues = await this.getFlatArrDecompressed(`${prefix2}/${categories}`);
327230
327379
  }
327231
327380
  } else if (encodingType === "categorical") {
327232
- const { dtype } = await open$1(storeRoot.resolve(`${path2}/categories`), { kind: "array" });
327233
- if (dtype === "v2:object" || dtype === "|O") {
327381
+ const categoriesZattrs = await this.getJson(`${path2}/categories/.zattrs`);
327382
+ const categoriesEncodingType = categoriesZattrs?.["encoding-type"];
327383
+ if (categoriesEncodingType === "nullable-string-array") {
327384
+ categoriesValues = await this.getFlatArrDecompressed(`${path2}/categories/values`);
327385
+ } else if (categoriesEncodingType === "string-array") {
327234
327386
  categoriesValues = await this.getFlatArrDecompressed(`${path2}/categories`);
327387
+ } else {
327388
+ const { dtype } = await open$1(storeRoot.resolve(`${path2}/categories`), { kind: "array" });
327389
+ if (dtype === "v2:object" || dtype === "|O") {
327390
+ categoriesValues = await this.getFlatArrDecompressed(`${path2}/categories`);
327391
+ }
327235
327392
  }
327236
327393
  codesPath = `${path2}/codes`;
327394
+ } else if (encodingType === "nullable-string-array") {
327395
+ return this.getFlatArrDecompressed(`${path2}/values`);
327237
327396
  } else if (encodingType === "string-array") {
327238
327397
  return this.getFlatArrDecompressed(path2);
327239
327398
  } else {
@@ -328397,16 +328556,25 @@ let FeatureStatsAnndataLoader$1 = class FeatureStatsAnndataLoader extends Abstra
328397
328556
  return this.dataSource.loadDataFrameIndex(dfPath);
328398
328557
  }
328399
328558
  async loadDataFrame(dfPath) {
328400
- const [featureId2, featureFoldChange, featureSignificance] = await Promise.all([
328401
- this.loadFeatureNames(dfPath),
328402
- this.loadFoldChanges(dfPath),
328403
- this.loadSignificances(dfPath)
328404
- ]);
328405
- return {
328406
- featureId: featureId2,
328407
- featureFoldChange,
328408
- featureSignificance
328409
- };
328559
+ try {
328560
+ const [featureId2, featureFoldChange, featureSignificance] = await Promise.all([
328561
+ this.loadFeatureNames(dfPath),
328562
+ this.loadFoldChanges(dfPath),
328563
+ this.loadSignificances(dfPath)
328564
+ ]);
328565
+ return {
328566
+ featureId: featureId2,
328567
+ featureFoldChange,
328568
+ featureSignificance
328569
+ };
328570
+ } catch (e3) {
328571
+ log$b.warn("Dataframe not found at", dfPath);
328572
+ return {
328573
+ featureId: [],
328574
+ featureFoldChange: [],
328575
+ featureSignificance: []
328576
+ };
328577
+ }
328410
328578
  }
328411
328579
  /**
328412
328580
  *
@@ -328433,7 +328601,7 @@ let FeatureStatsAnndataLoader$1 = class FeatureStatsAnndataLoader extends Abstra
328433
328601
  * @returns {Promise<LoaderResult<FeatureStatsData>>}
328434
328602
  */
328435
328603
  async loadMulti(volcanoOptions) {
328436
- const { analysisType: targetAnalysisType = "rank_genes_groups" } = this.options;
328604
+ const { analysisType: targetAnalysisType = "pydeseq2" } = this.options;
328437
328605
  const { sampleSetSelection, obsSetSelection } = volcanoOptions || {};
328438
328606
  const rawObsSetSelection = obsSetSelection;
328439
328607
  const rawSampleSetSelection = sampleSetSelection;
@@ -329411,7 +329579,7 @@ class SpatialDataObsSpotsLoader extends AbstractTwoStepLoader {
329411
329579
  const formatVersion = await this.dataSource.getShapesFormatVersion(path2);
329412
329580
  if (formatVersion === "0.1") {
329413
329581
  locations = await this.dataSource.loadNumericForDims(getCoordsPath(path2), [0, 1]);
329414
- } else if (formatVersion === "0.2") {
329582
+ } else if (formatVersion === "0.2" || formatVersion === "0.3") {
329415
329583
  locations = await this.dataSource.loadCircleShapes(getGeometryPath$1(path2));
329416
329584
  }
329417
329585
  this.locations = locations;
@@ -329610,7 +329778,7 @@ class SpatialDataObsPointsLoader extends AbstractTwoStepLoader {
329610
329778
  }
329611
329779
  let locations;
329612
329780
  const formatVersion = await this.dataSource.getPointsFormatVersion(path2);
329613
- if (formatVersion === "0.1") {
329781
+ if (formatVersion === "0.1" || formatVersion === "0.2") {
329614
329782
  locations = await this.dataSource.loadPoints(path2);
329615
329783
  } else {
329616
329784
  throw new UnknownSpatialDataFormatError("Only points format version 0.1 is supported.");
@@ -329629,7 +329797,7 @@ class SpatialDataObsPointsLoader extends AbstractTwoStepLoader {
329629
329797
  }
329630
329798
  let locationsFeatureIndex;
329631
329799
  const formatVersion = await this.dataSource.getPointsFormatVersion(path2);
329632
- if (formatVersion === "0.1") {
329800
+ if (formatVersion === "0.1" || formatVersion === "0.2") {
329633
329801
  locationsFeatureIndex = await this.dataSource.loadPointsFeatureIds(path2);
329634
329802
  } else {
329635
329803
  throw new UnknownSpatialDataFormatError("Only points format version 0.1 is supported.");
@@ -329641,7 +329809,7 @@ class SpatialDataObsPointsLoader extends AbstractTwoStepLoader {
329641
329809
  const { path: path2, featureIndexColumn, mortonCodeColumn } = this.options;
329642
329810
  let locations;
329643
329811
  const formatVersion = await this.dataSource.getPointsFormatVersion(path2);
329644
- if (formatVersion === "0.1") {
329812
+ if (formatVersion === "0.1" || formatVersion === "0.2") {
329645
329813
  locations = await this.dataSource.loadPointsInRect(path2, bounds2, signal, featureIndexColumn, mortonCodeColumn);
329646
329814
  } else {
329647
329815
  throw new UnknownSpatialDataFormatError("Only points format version 0.1 is supported.");
@@ -329673,10 +329841,8 @@ class SpatialDataObsPointsLoader extends AbstractTwoStepLoader {
329673
329841
  // and for the presence of morton_code_2d and feature_index columns.
329674
329842
  this.dataSource.supportsLoadPointsInRect(path2, featureIndexColumnName, mortonCodeColumn)
329675
329843
  ]);
329676
- const isSupportedVersion = formatVersion === "0.1";
329677
- const boundingBox = zattrs?.bounding_box;
329678
- const hasBoundingBox2D = typeof boundingBox?.x_max === "number" && typeof boundingBox?.x_min === "number" && typeof boundingBox?.y_max === "number" && typeof boundingBox?.y_min === "number";
329679
- return isSupportedVersion && hasBoundingBox2D && hasRequiredColumnsAndRowGroupSize;
329844
+ const isSupportedVersion = formatVersion === "0.1" || formatVersion === "0.2";
329845
+ return isSupportedVersion && hasRequiredColumnsAndRowGroupSize;
329680
329846
  }
329681
329847
  async load() {
329682
329848
  const [modelMatrix2, supportsTiling] = await Promise.all([
@@ -329714,7 +329880,7 @@ class SpatialDataObsPointsLoader extends AbstractTwoStepLoader {
329714
329880
  featureIds,
329715
329881
  obsPointsModelMatrix: modelMatrix2,
329716
329882
  // Return 'tiled' if the morton_code_2d column
329717
- // and bounding_box metadata are present,
329883
+ // is present,
329718
329884
  // and the row group size is small enough.
329719
329885
  // Otherwise, return 'full'.
329720
329886
  obsPointsTilingType: supportsTiling ? "tiled" : "full",
@@ -339223,6 +339389,7 @@ function sdataMortonQueryRectAux(boundingBox, origRect) {
339223
339389
  const mortonIntervals = zcoverRectangle(normRect[0][0], normRect[0][1], normRect[1][0], normRect[1][1], 16, null, true);
339224
339390
  return mortonIntervals;
339225
339391
  }
339392
+ const MORTON_CODE_EXTREME_VALUE_INDICATOR = 0;
339226
339393
  async function getParquetModule() {
339227
339394
  const module2 = await import(
339228
339395
  /* webpackIgnore: true */
@@ -339301,7 +339468,7 @@ async function _loadParquetSchemaBytes({ queryClient, store }, parquetPath, part
339301
339468
  if (!tailBytes || tailBytes.length < TAIL_LENGTH) {
339302
339469
  throw new Error(`Failed to load parquet footerLength for ${partZeroPath}`);
339303
339470
  }
339304
- const footerLength = new DataView(tailBytes.buffer).getInt32(0, true);
339471
+ const footerLength = new DataView(tailBytes.buffer, tailBytes.byteOffset, tailBytes.byteLength).getInt32(0, true);
339305
339472
  const magic = new TextDecoder().decode(tailBytes.slice(4, 8));
339306
339473
  if (magic !== "PAR1") {
339307
339474
  throw new Error("Invalid Parquet file: missing PAR1 magic number");
@@ -339348,22 +339515,22 @@ async function _loadParquetMetadataByPart({ queryClient, store }, parquetPath) {
339348
339515
  } catch (error2) {
339349
339516
  if (error2.message.includes("Failed to load parquet footerLength")) {
339350
339517
  numParts = partIndex;
339518
+ log$b.info(`Found ${numParts} parts for parquet path ${parquetPath}; An above "Failed to load parquet footerLength" error is expected for the subsequent part.`);
339351
339519
  }
339352
339520
  }
339353
339521
  } while (numParts === void 0);
339522
+ const numRows = allMetadata.map((part) => part.metadata.fileMetadata().numRows());
339523
+ const numRowGroups = allMetadata.map((part) => part.metadata.numRowGroups());
339524
+ const numRowsPerGroup = allMetadata.map((part) => part.metadata.rowGroup(0).numRows());
339354
339525
  const metadata2 = {
339355
- numRows: 0,
339356
- numRowGroups: 0,
339357
- numRowsPerGroup: 0,
339358
- schema: null
339359
- };
339360
- if (allMetadata.length > 0) {
339361
- const firstPart = allMetadata[0];
339362
- metadata2.numRows = allMetadata.reduce((sum2, part) => sum2 + part.metadata.fileMetadata().numRows(), 0);
339363
- metadata2.numRowGroups = allMetadata.reduce((sum2, part) => sum2 + part.metadata.numRowGroups(), 0);
339364
- metadata2.numRowsPerGroup = firstPart.metadata.rowGroup(0).numRows();
339365
- metadata2.schema = firstPart.schema.schema;
339366
- }
339526
+ totalNumRows: numRows.reduce((a2, b2) => a2 + b2, 0),
339527
+ totalNumRowGroups: numRowGroups.reduce((a2, b2) => a2 + b2, 0),
339528
+ // Array of count per part (length equal to numParts).
339529
+ numRowsByPart: numRows,
339530
+ numRowGroupsByPart: numRowGroups,
339531
+ numRowsPerGroupByPart: numRowsPerGroup,
339532
+ schema: allMetadata?.[0]?.schema?.schema
339533
+ };
339367
339534
  const result = {
339368
339535
  ...metadata2,
339369
339536
  // TODO: extract metadata per part and rowGroup into plain objects that match the hyparquet parquetMetadata() return value?
@@ -339387,8 +339554,8 @@ async function _loadParquetRowGroupByGroupIndex({ queryClient, store }, parquetP
339387
339554
  const store2 = ctx.meta?.store;
339388
339555
  const { readParquetRowGroup } = await _getParquetModule({ queryClient: queryClient2 });
339389
339556
  const allMetadata = await _loadParquetMetadataByPart({ queryClient: queryClient2, store: store2 }, parquetPath);
339390
- if (rowGroupIndex < 0 || rowGroupIndex >= allMetadata.numRowGroups) {
339391
- throw new Error(`Row group index ${rowGroupIndex} is out of bounds for parquet table with ${allMetadata.numRowGroups} row groups.`);
339557
+ if (rowGroupIndex < 0 || rowGroupIndex >= allMetadata.totalNumRowGroups) {
339558
+ throw new Error(`Row group index ${rowGroupIndex} is out of bounds for parquet table with ${allMetadata.totalNumRowGroups} row groups.`);
339392
339559
  }
339393
339560
  let partIndex;
339394
339561
  let cumulativeRowGroups = 0;
@@ -339498,9 +339665,9 @@ async function _bisectRowGroupsRight({ queryClient, store }, parquetPath, column
339498
339665
  );
339499
339666
  const store2 = ctx.meta?.store;
339500
339667
  const allMetadata = await _loadParquetMetadataByPart({ queryClient: queryClient2, store: store2 }, parquetPath);
339501
- const { numRowGroups } = allMetadata;
339668
+ const { totalNumRowGroups } = allMetadata;
339502
339669
  let lo = 0;
339503
- let hi = numRowGroups;
339670
+ let hi = totalNumRowGroups;
339504
339671
  while (lo < hi) {
339505
339672
  const cachedInRange = await getCachedInRange(queryClient2, parquetPath, columnName, lo, hi);
339506
339673
  const betterLo = cachedInRange.slice().reverse().find((c2) => c2.index > lo && targetValue >= c2.max);
@@ -339903,11 +340070,12 @@ class SpatialDataTableSource extends AnnDataSource {
339903
340070
  const { queryClient } = this;
339904
340071
  const { store } = this.storeRoot;
339905
340072
  const allMetadata = await _loadParquetMetadataByPart({ queryClient, store }, parquetPath);
339906
- const { numRowsPerGroup } = allMetadata;
339907
- const numRowsTotal = allMetadata.numRows;
339908
- if (numRowsPerGroup >= 1e5) {
340073
+ const { numRowsPerGroupByPart } = allMetadata;
340074
+ const numRowsTotal = allMetadata.totalNumRows;
340075
+ const maxNumRowsPerGroup = Math.max(...numRowsPerGroupByPart);
340076
+ if (maxNumRowsPerGroup >= 1e5) {
339909
340077
  if (numRowsTotal > 5e6) {
339910
- throw new Error(`The Parquet table at ${parquetPath} has ${numRowsTotal} total rows, which necessitates tiled loading, but it was not possible because the row group size is too large (${numRowsPerGroup}). See the Vitessce documentation at Data Troubleshooting -> Points for more details.`);
340078
+ throw new Error(`The Parquet table at ${parquetPath} has ${numRowsTotal} total rows, which necessitates tiled loading, but it was not possible because the row group size is too large (${maxNumRowsPerGroup}). See the Vitessce documentation at Data Troubleshooting -> Points for more details.`);
339911
340079
  }
339912
340080
  return false;
339913
340081
  }
@@ -339931,7 +340099,7 @@ class SpatialDataTableSource extends AnnDataSource {
339931
340099
  * @param {string[]|undefined} columns An optional list of column names to load.
339932
340100
  * @returns
339933
340101
  */
339934
- async loadParquetTableInRect(parquetPath, tileBbox, allPointsBbox, signal, featureIndexColumnName, mortonCodeColumn) {
340102
+ async loadParquetTableInRect(parquetPath, tileBbox, signal, featureIndexColumnName, mortonCodeColumn) {
339935
340103
  const { queryClient } = this;
339936
340104
  const { store } = this.storeRoot;
339937
340105
  const mortonCodeColumnName = mortonCodeColumn ?? "morton_code_2d";
@@ -339956,15 +340124,46 @@ class SpatialDataTableSource extends AnnDataSource {
339956
340124
  } else {
339957
340125
  tileBboxes = [tileBbox];
339958
340126
  }
340127
+ const firstRowGroupTable = await _loadParquetRowGroupByGroupIndex({ queryClient, store }, parquetPath, 0);
340128
+ const xColumnForBoundingBox = firstRowGroupTable.getChild("x");
340129
+ const yColumnForBoundingBox = firstRowGroupTable.getChild("y");
340130
+ const mortonCodeColumnForBoundingBox = firstRowGroupTable.getChild(mortonCodeColumnName);
340131
+ const boundingBoxMaxNumRows = Math.min(4, firstRowGroupTable.numRows);
340132
+ const firstMortonCodes = range$e(boundingBoxMaxNumRows).map((i2) => mortonCodeColumnForBoundingBox.get(i2));
340133
+ const boundingBoxNumRows = firstMortonCodes.filter((code2) => code2 === MORTON_CODE_EXTREME_VALUE_INDICATOR).length;
340134
+ const boundingBoxXValues = range$e(boundingBoxNumRows).map((i2) => xColumnForBoundingBox.get(i2));
340135
+ const boundingBoxYValues = range$e(boundingBoxNumRows).map((i2) => yColumnForBoundingBox.get(i2));
340136
+ const xMin = Math.min(...boundingBoxXValues);
340137
+ const xMax = Math.max(...boundingBoxXValues);
340138
+ const yMin = Math.min(...boundingBoxYValues);
340139
+ const yMax = Math.max(...boundingBoxYValues);
340140
+ const allPointsBbox = {
340141
+ x_min: xMin,
340142
+ x_max: xMax,
340143
+ y_min: yMin,
340144
+ y_max: yMax
340145
+ };
339959
340146
  const rowGroupIndicesPerTile = await Promise.all(tileBboxes.map(async (subTileBbox) => _rectToRowGroupIndices({ queryClient, store }, parquetPath, subTileBbox, allPointsBbox, mortonCodeColumnName)));
339960
340147
  const uniqueCoveredRowGroupIndices = Array.from(new Set(rowGroupIndicesPerTile.flat())).toSorted((a2, b2) => a2 - b2);
339961
340148
  const allMetadata = await _loadParquetMetadataByPart({ queryClient, store }, parquetPath);
339962
- const { numRowsPerGroup } = allMetadata;
339963
- const numRowGroups = uniqueCoveredRowGroupIndices.length;
339964
- const totalNumRows = numRowsPerGroup * numRowGroups;
339965
- const xArr = new Float32Array(totalNumRows);
339966
- const yArr = new Float32Array(totalNumRows);
339967
- const featureIndexArr = new Uint32Array(totalNumRows);
340149
+ const { numRowsPerGroupByPart, numRowGroupsByPart } = allMetadata;
340150
+ const rowGroupIToNumRows = (rowGroupI) => {
340151
+ let currPartIndex = 0;
340152
+ let prevTotalRowGroupCount = 0;
340153
+ for (let partIndex = 0; partIndex < numRowGroupsByPart.length; partIndex++) {
340154
+ const numRowGroupsInPart = numRowGroupsByPart[partIndex];
340155
+ if (prevTotalRowGroupCount <= rowGroupI && rowGroupI < prevTotalRowGroupCount + numRowGroupsInPart) {
340156
+ currPartIndex = partIndex;
340157
+ break;
340158
+ }
340159
+ prevTotalRowGroupCount += numRowGroupsInPart;
340160
+ }
340161
+ return numRowsPerGroupByPart[currPartIndex];
340162
+ };
340163
+ const totalNumRowsToLoad = uniqueCoveredRowGroupIndices.reduce((acc, rowGroupI) => acc + rowGroupIToNumRows(rowGroupI), 0);
340164
+ const xArr = new Float32Array(totalNumRowsToLoad);
340165
+ const yArr = new Float32Array(totalNumRowsToLoad);
340166
+ const featureIndexArr = new Uint32Array(totalNumRowsToLoad);
339968
340167
  const rowGroupTables = await Promise.all(uniqueCoveredRowGroupIndices.map(async (rowGroupIndex) => _loadParquetRowGroupByGroupIndex({ queryClient, store }, parquetPath, rowGroupIndex)));
339969
340168
  let rowOffset = 0;
339970
340169
  rowGroupTables.forEach((table2) => {
@@ -339977,7 +340176,7 @@ class SpatialDataTableSource extends AnnDataSource {
339977
340176
  xArr.set(xColumn.toArray(), rowOffset);
339978
340177
  yArr.set(yColumn.toArray(), rowOffset);
339979
340178
  featureIndexArr.set(featureIndexColumn.toArray(), rowOffset);
339980
- rowOffset += numRowsPerGroup;
340179
+ rowOffset += table2.numRows;
339981
340180
  });
339982
340181
  return {
339983
340182
  data: {
@@ -339985,7 +340184,7 @@ class SpatialDataTableSource extends AnnDataSource {
339985
340184
  y: yArr,
339986
340185
  featureIndices: featureIndexArr
339987
340186
  },
339988
- shape: [3, totalNumRows]
340187
+ shape: [3, totalNumRowsToLoad]
339989
340188
  };
339990
340189
  }
339991
340190
  }
@@ -345861,14 +346060,14 @@ class SpatialDataShapesSource extends SpatialDataTableSource {
345861
346060
  /**
345862
346061
  *
345863
346062
  * @param {string} path A path to within shapes.
345864
- * @returns {Promise<"0.1"|"0.2">} The format version.
346063
+ * @returns {Promise<"0.1"|"0.2"|"0.3">} The format version.
345865
346064
  */
345866
346065
  async getShapesFormatVersion(path2) {
345867
346066
  const zattrs = await this.loadSpatialDataElementAttrs(path2);
345868
346067
  const formatVersion = zattrs.spatialdata_attrs.version;
345869
346068
  const geos = zattrs.spatialdata_attrs.geos || {};
345870
346069
  const encodingType = zattrs["encoding-type"];
345871
- if (encodingType !== "ngff:shapes" || !(formatVersion === "0.1" && (geos.name === "POINT" && geos.type === 0) || formatVersion === "0.2")) {
346070
+ if (encodingType !== "ngff:shapes" || !(formatVersion === "0.1" && (geos.name === "POINT" && geos.type === 0) || formatVersion === "0.2" || formatVersion === "0.3")) {
345872
346071
  throw new Error(`Unexpected encoding type or version for shapes spatialdata_attrs: ${encodingType} ${formatVersion}`);
345873
346072
  }
345874
346073
  return formatVersion;
@@ -346077,7 +346276,7 @@ class SpatialDataPointsSource extends SpatialDataTableSource {
346077
346276
  const zattrs = await this.loadSpatialDataElementAttrs(path2);
346078
346277
  const formatVersion = zattrs.spatialdata_attrs.version;
346079
346278
  const encodingType = zattrs["encoding-type"];
346080
- if (encodingType === "ngff:points" && !(formatVersion === "0.1")) {
346279
+ if (encodingType === "ngff:points" && !(formatVersion === "0.1" || formatVersion === "0.2")) {
346081
346280
  throw new Error(`Unexpected version for points spatialdata_attrs: ${formatVersion}`);
346082
346281
  }
346083
346282
  return formatVersion;
@@ -346180,16 +346379,11 @@ class SpatialDataPointsSource extends SpatialDataTableSource {
346180
346379
  const zattrs = await this.loadSpatialDataElementAttrs(elementPath);
346181
346380
  const {
346182
346381
  // axes,
346183
- spatialdata_attrs: spatialDataAttrs,
346184
- // The bounding box (extent) of all points.
346185
- // Required for un-normalization from uints back to floats.
346186
- // TODO: decide whether these will be stored here or somewhere else.
346187
- // Reference: https://github.com/vitessce/vitessce-python/pull/476#issuecomment-3362656956
346188
- bounding_box: allPointsBbox
346382
+ spatialdata_attrs: spatialDataAttrs
346189
346383
  } = zattrs;
346190
346384
  const { feature_key: featureKey } = spatialDataAttrs;
346191
346385
  const featureIndexColumnName = featureIndexColumnNameFromOptions ?? `${featureKey}_codes`;
346192
- return this.loadParquetTableInRect(parquetPath, tileBbox, allPointsBbox, signal, featureIndexColumnName, mortonCodeColumn);
346386
+ return this.loadParquetTableInRect(parquetPath, tileBbox, signal, featureIndexColumnName, mortonCodeColumn);
346193
346387
  }
346194
346388
  async supportsLoadPointsInRect(elementPath, featureIndexColumnName, mortonCodeColumn) {
346195
346389
  const parquetPath = getParquetPath(elementPath);
@@ -346397,7 +346591,13 @@ class GlbSource {
346397
346591
  class GlbDataLoader extends AbstractTwoStepLoader {
346398
346592
  async load() {
346399
346593
  const { url, options } = this;
346400
- const loader2 = new GLTFLoader$1();
346594
+ const [{ GLTFLoader: GLTFLoader2 }, { DRACOLoader }] = await Promise.all([
346595
+ // eslint-disable-next-line import/no-unresolved
346596
+ import("three/addons/loaders/GLTFLoader.js"),
346597
+ // eslint-disable-next-line import/no-unresolved
346598
+ import("three/addons/loaders/DRACOLoader.js")
346599
+ ]);
346600
+ const loader2 = new GLTFLoader2();
346401
346601
  const dracoLoader = new DRACOLoader();
346402
346602
  dracoLoader.setDecoderPath("https://www.gstatic.com/draco/versioned/decoders/1.5.6/");
346403
346603
  loader2.setDRACOLoader(dracoLoader);
@@ -348963,7 +349163,8 @@ const baseFileTypes = [
348963
349163
  makeFileType(FileType$1.OBS_LOCATIONS_MOLECULES_JSON, DataType$3.OBS_LOCATIONS, MoleculesJsonAsObsLocationsLoader, JsonSource, z.null()),
348964
349164
  makeFileType(FileType$1.OBS_LABELS_MOLECULES_JSON, DataType$3.OBS_LABELS, MoleculesJsonAsObsLabelsLoader, JsonSource, z.null()),
348965
349165
  makeFileType(FileType$1.NEIGHBORHOODS_JSON, DataType$3.NEIGHBORHOODS, JsonLoader, JsonSource, z.null()),
348966
- makeFileType(FileType$1.GENOMIC_PROFILES_ZARR, DataType$3.GENOMIC_PROFILES, GenomicProfilesZarrLoader, ZarrDataSource, z.null())
349166
+ makeFileType(FileType$1.GENOMIC_PROFILES_ZARR, DataType$3.GENOMIC_PROFILES, GenomicProfilesZarrLoader, ZarrDataSource, z.null()),
349167
+ makeFileType(FileType$1.GENOMIC_PROFILES_ZARR_ZIP, DataType$3.GENOMIC_PROFILES, GenomicProfilesZarrLoader, ZarrDataSource, z.null())
348967
349168
  ];
348968
349169
  const baseJointFileTypes = [
348969
349170
  new PluginJointFileType(FileType$1.ANNDATA_ZARR, expandAnndataZarr, anndataZarrSchema),