@vitessce/all 3.0.0 → 3.0.1

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.
@@ -6,7 +6,7 @@ var __publicField = (obj, key2, value2) => {
6
6
  };
7
7
  import * as React from "react";
8
8
  import React__default, { Children, isValidElement, cloneElement, useMemo, forwardRef, useRef, useImperativeHandle, useEffect, useLayoutEffect as useLayoutEffect$1, useState, PureComponent, Component as Component$1, useCallback, createElement, useReducer, Suspense } from "react";
9
- import { useLoaders, useCoordination, useDescription, useImageData, useReady, TitleInfo, useVitessceContainer, useSetWarning, useUrls, useObsSetsData, usePlotOptionsStyles, OptionsContainer, CellColorEncodingOption, OptionSelect, useComponentHover, useComponentViewInfo, useSetComponentHover, useSetComponentViewInfo, useDeckCanvasSize, useMultiObsLabels, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useFeatureLabelsData, useGetObsInfo, useUint8FeatureSelection, useExpressionValueGetter, useAuxiliaryCoordination, useHasLoader, useObsLocationsData, useObsLabelsData, useObsSegmentationsData, useNeighborhoodsData, useObsFeatureMatrixData, useUint8ObsFeatureMatrix, useGetObsMembership, PopperMenu, useComponentLayout, useClosestVitessceContainerSize, useWindowDimensions, useWarning, useGridItemSize, useGenomicProfilesData, DataSourceFetchError, AbstractLoaderError, AbstractTwoStepLoader, LoaderResult, LoaderValidationError, VitS } from "@vitessce/vit-s";
9
+ import { useLoaders, useCoordination, useDescription, useImageData, useReady, TitleInfo, useVitessceContainer, useSetWarning, useObsSetsData, useUrls, usePlotOptionsStyles, OptionsContainer, CellColorEncodingOption, OptionSelect, useComponentHover, useComponentViewInfo, useSetComponentHover, useSetComponentViewInfo, useInitialCoordination, useDeckCanvasSize, useMultiObsLabels, useObsEmbeddingData, useFeatureSelection, useObsFeatureMatrixIndices, useFeatureLabelsData, useGetObsInfo, useUint8FeatureSelection, useExpressionValueGetter, useAuxiliaryCoordination, useHasLoader, useObsLocationsData, useObsLabelsData, useObsSegmentationsData, useNeighborhoodsData, useObsFeatureMatrixData, useUint8ObsFeatureMatrix, useGetObsMembership, PopperMenu, useComponentLayout, useClosestVitessceContainerSize, useWindowDimensions, useWarning, useGridItemSize, useGenomicProfilesData, DataSourceFetchError, AbstractLoaderError, AbstractTwoStepLoader, LoaderResult, LoaderValidationError, logConfig, VitS } from "@vitessce/vit-s";
10
10
  import * as ReactDOM from "react-dom";
11
11
  import ReactDOM__default from "react-dom";
12
12
  function _mergeNamespaces(n3, m2) {
@@ -37756,14 +37756,12 @@ function Description(props2) {
37756
37756
  const classes = useStyles$d();
37757
37757
  return jsxRuntimeExports.jsxs("div", { className: classes.description, children: [jsxRuntimeExports.jsx("p", { children: description2 }), metadata2 && Array.from(metadata2.entries()).map(([layerIndex, { name: layerName, metadata: metadataRecord }]) => metadataRecord && Object.entries(metadataRecord).length > 0 ? jsxRuntimeExports.jsxs("details", { children: [jsxRuntimeExports.jsx("summary", { children: layerName }), jsxRuntimeExports.jsx("div", { className: classes.metadataContainer, children: jsxRuntimeExports.jsx("table", { children: jsxRuntimeExports.jsx("tbody", { children: Object.entries(metadataRecord).map(([key2, value2]) => jsxRuntimeExports.jsxs("tr", { children: [jsxRuntimeExports.jsx("th", { title: key2, children: key2 }), jsxRuntimeExports.jsx("td", { title: value2, children: value2 })] }, key2)) }) }) })] }, layerIndex) : null)] });
37758
37758
  }
37759
- const addUrl = () => {
37760
- };
37761
37759
  function DescriptionSubscriber(props2) {
37762
37760
  const { coordinationScopes, description: descriptionOverride, removeGridComponent, theme, title: title2 = "Description" } = props2;
37763
37761
  const loaders = useLoaders();
37764
37762
  const [{ dataset, spatialImageLayer: rasterLayers }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.DESCRIPTION], coordinationScopes);
37765
37763
  const [description2] = useDescription(loaders, dataset);
37766
- const [{ image: image2 }, imageStatus] = useImageData(loaders, dataset, addUrl, false, {}, {}, {});
37764
+ const [{ image: image2 }, imageStatus] = useImageData(loaders, dataset, false, {}, {}, {});
37767
37765
  const { loaders: imageLayerLoaders = [], meta: imageLayerMeta = [] } = image2 || {};
37768
37766
  const isReady = useReady([imageStatus]);
37769
37767
  const metadata2 = useMemo(() => {
@@ -46136,6 +46134,7 @@ const useHelpTooltipStyles = makeStyles((theme) => ({
46136
46134
  cursor: "pointer",
46137
46135
  width: "100%",
46138
46136
  backgroundColor: "transparent",
46137
+ color: theme.palette.grayDarkD15,
46139
46138
  borderRadius: "2px",
46140
46139
  "&:hover": {
46141
46140
  backgroundColor: theme.palette.grayLightL10
@@ -51109,14 +51108,12 @@ function ObsSetsManagerSubscriber(props2) {
51109
51108
  const setWarning = useSetWarning();
51110
51109
  const [{ dataset, obsType, obsSetSelection: cellSetSelection, obsSetExpansion: cellSetExpansion, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets, obsColorEncoding: cellColorEncoding }, { setObsSetSelection: setCellSetSelection, setObsColorEncoding: setCellColorEncoding, setObsSetColor: setCellSetColor, setObsSetExpansion: setCellSetExpansion, setAdditionalObsSets: setAdditionalCellSets }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.OBS_SETS], coordinationScopes);
51111
51110
  const title2 = titleOverride || `${capitalize$2(obsType)} Sets`;
51112
- const [urls2, addUrl2] = useUrls(loaders, dataset);
51113
51111
  useEffect(() => {
51114
51112
  setCellSetExpansion([]);
51115
51113
  }, [loaders, dataset]);
51116
- const [{ obsIndex, obsSets: cellSets }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, true, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
51117
- const isReady = useReady([
51118
- obsSetsStatus
51119
- ]);
51114
+ const [{ obsIndex, obsSets: cellSets }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, true, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
51115
+ const isReady = useReady([obsSetsStatus]);
51116
+ const urls2 = useUrls([obsSetsUrls]);
51120
51117
  useEffect(() => {
51121
51118
  if (additionalCellSets) {
51122
51119
  let upgradedCellSets;
@@ -155474,16 +155471,16 @@ async function getDecoder(fileDirectory) {
155474
155471
  const Decoder = await importFn();
155475
155472
  return new Decoder(fileDirectory);
155476
155473
  }
155477
- addDecoder([void 0, 1], () => import("./raw-3c693341.js").then((m2) => m2.default));
155478
- addDecoder(5, () => import("./lzw-865bd058.js").then((m2) => m2.default));
155474
+ addDecoder([void 0, 1], () => import("./raw-3c2d82ff.js").then((m2) => m2.default));
155475
+ addDecoder(5, () => import("./lzw-4d26ee71.js").then((m2) => m2.default));
155479
155476
  addDecoder(6, () => {
155480
155477
  throw new Error("old style JPEG compression is not supported.");
155481
155478
  });
155482
- addDecoder(7, () => import("./jpeg-e740c9a5.js").then((m2) => m2.default));
155483
- addDecoder([8, 32946], () => import("./deflate-f57b3163.js").then((m2) => m2.default));
155484
- addDecoder(32773, () => import("./packbits-d4191efd.js").then((m2) => m2.default));
155485
- addDecoder(34887, () => import("./lerc-01e6c4d8.js").then((m2) => m2.default));
155486
- addDecoder(50001, () => import("./webimage-83da2258.js").then((m2) => m2.default));
155479
+ addDecoder(7, () => import("./jpeg-7f0b1b2c.js").then((m2) => m2.default));
155480
+ addDecoder([8, 32946], () => import("./deflate-475a23c9.js").then((m2) => m2.default));
155481
+ addDecoder(32773, () => import("./packbits-08efb7ce.js").then((m2) => m2.default));
155482
+ addDecoder(34887, () => import("./lerc-f7557585.js").then((m2) => m2.default));
155483
+ addDecoder(50001, () => import("./webimage-a7dde8d2.js").then((m2) => m2.default));
155487
155484
  function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
155488
155485
  return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
155489
155486
  }
@@ -171929,7 +171926,7 @@ const VisibilityOffIcon = createSvgIcon(/* @__PURE__ */ React.createElement("pat
171929
171926
  d: "M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z"
171930
171927
  }), "VisibilityOff");
171931
171928
  const useStyles$b = makeStyles(() => ({
171932
- button: {
171929
+ toolButton: {
171933
171930
  display: "inline-flex",
171934
171931
  "&:active": {
171935
171932
  opacity: ".65",
@@ -171952,7 +171949,7 @@ const useStyles$b = makeStyles(() => ({
171952
171949
  transform: "scale(0.98)"
171953
171950
  // make the button slightly smaller
171954
171951
  },
171955
- icon: {
171952
+ toolIcon: {
171956
171953
  // btn btn-outline-secondary mr-2 icon
171957
171954
  padding: "0",
171958
171955
  height: "2em",
@@ -171990,12 +171987,12 @@ const useStyles$b = makeStyles(() => ({
171990
171987
  function IconTool(props2) {
171991
171988
  const { alt, onClick, isActive: isActive2, children: children2 } = props2;
171992
171989
  const classes = useStyles$b();
171993
- return jsxRuntimeExports.jsx("button", { className: clsx(classes.icon, { [classes.toolActive]: isActive2 }), onClick, type: "button", title: alt, children: children2 });
171990
+ return jsxRuntimeExports.jsx("button", { className: clsx(classes.toolIcon, { [classes.toolActive]: isActive2 }), onClick, type: "button", title: alt, children: children2 });
171994
171991
  }
171995
171992
  function IconButton2(props2) {
171996
171993
  const { alt, onClick, children: children2 } = props2;
171997
171994
  const classes = useStyles$b();
171998
- return jsxRuntimeExports.jsx("button", { className: clsx(classes.icon, classes.button), onClick, type: "button", title: alt, children: children2 });
171995
+ return jsxRuntimeExports.jsx("button", { className: clsx(classes.toolIcon, classes.toolButton), onClick, type: "button", title: alt, children: children2 });
171999
171996
  }
172000
171997
  function ToolMenu(props2) {
172001
171998
  const { setActiveTool, activeTool, visibleTools = { pan: true, selectLasso: true }, recenterOnClick = () => {
@@ -174758,17 +174755,17 @@ function EmbeddingScatterplotSubscriber(props2) {
174758
174755
  const setComponentHover = useSetComponentHover();
174759
174756
  const setComponentViewInfo = useSetComponentViewInfo(uuid);
174760
174757
  const [{ dataset, obsType, featureType, featureValueType, embeddingZoom: zoom2, embeddingTargetX: targetX2, embeddingTargetY: targetY2, embeddingTargetZ: targetZ, embeddingType: mapping, obsFilter: cellFilter, obsHighlight: cellHighlight, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, embeddingObsSetPolygonsVisible: cellSetPolygonsVisible, embeddingObsSetLabelsVisible: cellSetLabelsVisible, embeddingObsSetLabelSize: cellSetLabelSize, embeddingObsRadius: cellRadiusFixed, embeddingObsRadiusMode: cellRadiusMode, embeddingObsOpacity: cellOpacityFixed, embeddingObsOpacityMode: cellOpacityMode, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible }, { setEmbeddingZoom: setZoom, setEmbeddingTargetX: setTargetX, setEmbeddingTargetY: setTargetY, setEmbeddingTargetZ: setTargetZ, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setEmbeddingObsSetPolygonsVisible: setCellSetPolygonsVisible, setEmbeddingObsSetLabelsVisible: setCellSetLabelsVisible, setEmbeddingObsSetLabelSize: setCellSetLabelSize, setEmbeddingObsRadius: setCellRadiusFixed, setEmbeddingObsRadiusMode: setCellRadiusMode, setEmbeddingObsOpacity: setCellOpacityFixed, setEmbeddingObsOpacityMode: setCellOpacityMode, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setTooltipsVisible }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
174758
+ const { embeddingZoom: initialZoom, embeddingTargetX: initialTargetX, embeddingTargetY: initialTargetY } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
174761
174759
  const observationsLabel = observationsLabelOverride || obsType;
174762
- const [urls2, addUrl2] = useUrls(loaders, dataset);
174763
174760
  const [width2, height2, deckRef] = useDeckCanvasSize();
174764
174761
  const title2 = titleOverride || `Scatterplot (${mapping})`;
174765
- const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset, addUrl2);
174766
- const [{ obsIndex: obsEmbeddingIndex, obsEmbedding }, obsEmbeddingStatus] = useObsEmbeddingData(loaders, dataset, addUrl2, true, {}, {}, { obsType, embeddingType: mapping });
174762
+ const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset);
174763
+ const [{ obsIndex: obsEmbeddingIndex, obsEmbedding }, obsEmbeddingStatus, obsEmbeddingUrls] = useObsEmbeddingData(loaders, dataset, true, {}, {}, { obsType, embeddingType: mapping });
174767
174764
  const cellsCount = (obsEmbeddingIndex == null ? void 0 : obsEmbeddingIndex.length) || 0;
174768
- const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
174765
+ const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
174769
174766
  const [expressionData, loadedFeatureSelection, featureSelectionStatus] = useFeatureSelection(loaders, dataset, false, geneSelection, { obsType, featureType, featureValueType });
174770
- const [{ obsIndex: matrixObsIndex }, matrixIndicesStatus] = useObsFeatureMatrixIndices(loaders, dataset, addUrl2, false, { obsType, featureType, featureValueType });
174771
- const [{ featureLabelsMap }, featureLabelsStatus] = useFeatureLabelsData(loaders, dataset, addUrl2, false, {}, {}, { featureType });
174767
+ const [{ obsIndex: matrixObsIndex }, matrixIndicesStatus, matrixIndicesUrls] = useObsFeatureMatrixIndices(loaders, dataset, false, { obsType, featureType, featureValueType });
174768
+ const [{ featureLabelsMap }, featureLabelsStatus, featureLabelsUrls] = useFeatureLabelsData(loaders, dataset, false, {}, {}, { featureType });
174772
174769
  const isReady = useReady([
174773
174770
  obsEmbeddingStatus,
174774
174771
  obsSetsStatus,
@@ -174776,6 +174773,12 @@ function EmbeddingScatterplotSubscriber(props2) {
174776
174773
  featureLabelsStatus,
174777
174774
  matrixIndicesStatus
174778
174775
  ]);
174776
+ const urls2 = useUrls([
174777
+ obsEmbeddingUrls,
174778
+ obsSetsUrls,
174779
+ matrixIndicesUrls,
174780
+ featureLabelsUrls
174781
+ ]);
174779
174782
  const [dynamicCellRadius, setDynamicCellRadius] = useState(cellRadiusFixed);
174780
174783
  const [dynamicCellOpacity, setDynamicCellOpacity] = useState(cellOpacityFixed);
174781
174784
  const [originalViewState, setOriginalViewState] = useState(null);
@@ -174848,33 +174851,39 @@ function EmbeddingScatterplotSubscriber(props2) {
174848
174851
  return [null, null, null, null, null];
174849
174852
  }, [obsEmbedding]);
174850
174853
  useEffect(() => {
174851
- if (xRange && yRange && isReady) {
174854
+ if (xRange && yRange) {
174852
174855
  const pointSizeDevicePixels = getPointSizeDevicePixels(window.devicePixelRatio, zoom2, xRange, yRange, width2, height2);
174853
174856
  setDynamicCellRadius(pointSizeDevicePixels);
174854
174857
  const nextCellOpacityScale = getPointOpacity(zoom2, xRange, yRange, width2, height2, numCells, averageFillDensity);
174855
174858
  setDynamicCellOpacity(nextCellOpacityScale);
174856
- if (typeof targetX2 !== "number" || typeof targetY2 !== "number") {
174859
+ if (typeof initialTargetX !== "number" || typeof initialTargetY !== "number") {
174857
174860
  const newTargetX = xExtent[0] + xRange / 2;
174858
174861
  const newTargetY = yExtent[0] + yRange / 2;
174859
174862
  const newZoom = Math.log2(Math.min(width2 / xRange, height2 / yRange));
174860
- setTargetX(newTargetX);
174861
- setTargetY(-newTargetY);
174862
- setZoom(newZoom);
174863
+ const notYetInitialized = typeof targetX2 !== "number" || typeof targetY2 !== "number";
174864
+ const stillDefaultInitialized = targetX2 === newTargetX && targetY2 === -newTargetY;
174865
+ if (notYetInitialized || stillDefaultInitialized) {
174866
+ setTargetX(newTargetX);
174867
+ setTargetY(-newTargetY);
174868
+ setZoom(newZoom);
174869
+ }
174863
174870
  setOriginalViewState({ target: [newTargetX, -newTargetY, 0], zoom: newZoom });
174864
174871
  } else if (!originalViewState) {
174865
- setOriginalViewState({ target: [targetX2, targetY2, 0], zoom: zoom2 });
174872
+ setOriginalViewState({ target: [initialTargetX, initialTargetY, 0], zoom: initialZoom });
174866
174873
  }
174867
174874
  }
174868
174875
  }, [
174869
174876
  xRange,
174870
174877
  yRange,
174871
- isReady,
174872
174878
  xExtent,
174873
174879
  yExtent,
174874
174880
  numCells,
174875
174881
  width2,
174876
174882
  height2,
174883
+ initialZoom,
174877
174884
  zoom2,
174885
+ initialTargetX,
174886
+ initialTargetY,
174878
174887
  averageFillDensity
174879
174888
  ]);
174880
174889
  const getObsInfo = useGetObsInfo(observationsLabel, obsLabelsTypes, obsLabelsData, obsSetsMembership);
@@ -174953,7 +174962,6 @@ function GatingSubscriber(props2) {
174953
174962
  const setComponentHover = useSetComponentHover();
174954
174963
  const setComponentViewInfo = useSetComponentViewInfo(uuid);
174955
174964
  const [{ dataset, obsType, featureType, featureValueType, embeddingZoom: zoom2, embeddingTargetX: targetX2, embeddingTargetY: targetY2, embeddingTargetZ: targetZ, obsFilter: cellFilter, obsHighlight: cellHighlight, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, embeddingObsSetPolygonsVisible: cellSetPolygonsVisible, embeddingObsSetLabelsVisible: cellSetLabelsVisible, embeddingObsSetLabelSize: cellSetLabelSize, embeddingObsRadius: cellRadiusFixed, embeddingObsRadiusMode: cellRadiusMode, embeddingObsOpacity: cellOpacityFixed, embeddingObsOpacityMode: cellOpacityMode, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, featureSelection: gatingFeatureSelectionColor, featureValueTransform, featureValueTransformCoefficient, gatingFeatureSelectionX, gatingFeatureSelectionY }, { setEmbeddingZoom: setZoom, setEmbeddingTargetX: setTargetX, setEmbeddingTargetY: setTargetY, setEmbeddingTargetZ: setTargetZ, setObsFilter: setCellFilter, setObsSetSelection: setCellSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setEmbeddingObsSetPolygonsVisible: setCellSetPolygonsVisible, setEmbeddingObsSetLabelsVisible: setCellSetLabelsVisible, setEmbeddingObsSetLabelSize: setCellSetLabelSize, setEmbeddingObsRadius: setCellRadiusFixed, setEmbeddingObsRadiusMode: setCellRadiusMode, setEmbeddingObsOpacity: setCellOpacityFixed, setEmbeddingObsOpacityMode: setCellOpacityMode, setFeatureValueColormap: setGeneExpressionColormap, setFeatureValueColormapRange: setGeneExpressionColormapRange, setFeatureValueTransform, setFeatureValueTransformCoefficient, setGatingFeatureSelectionX, setGatingFeatureSelectionY }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.GATING], coordinationScopes);
174956
- const [urls2, addUrl2] = useUrls(loaders, dataset);
174957
174965
  const [width2, height2, deckRef] = useDeckCanvasSize();
174958
174966
  const title2 = useMemo(() => {
174959
174967
  if (titleOverride) {
@@ -174966,11 +174974,11 @@ function GatingSubscriber(props2) {
174966
174974
  }, [titleOverride, gatingFeatureSelectionX, gatingFeatureSelectionY]);
174967
174975
  const featureSelectionX = useMemo(() => gatingFeatureSelectionX ? [gatingFeatureSelectionX] : null, [gatingFeatureSelectionX]);
174968
174976
  const featureSelectionY = useMemo(() => gatingFeatureSelectionY ? [gatingFeatureSelectionY] : null, [gatingFeatureSelectionY]);
174969
- const [{ obsSets: cellSets }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
174977
+ const [{ obsSets: cellSets }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
174970
174978
  const [expressionDataColor, loadedColor, featureSelectionColorStatus] = useFeatureSelection(loaders, dataset, false, gatingFeatureSelectionColor, { obsType, featureType, featureValueType });
174971
174979
  const [expressionDataX, loadedX, featureSelectionXStatus] = useFeatureSelection(loaders, dataset, false, featureSelectionX, { obsType, featureType, featureValueType });
174972
174980
  const [expressionDataY, loadedY, featureSelectionYStatus] = useFeatureSelection(loaders, dataset, false, featureSelectionY, { obsType, featureType, featureValueType });
174973
- const [{ obsIndex, featureIndex }, matrixIndicesStatus] = useObsFeatureMatrixIndices(loaders, dataset, addUrl2, false, { obsType, featureType, featureValueType });
174981
+ const [{ obsIndex, featureIndex }, matrixIndicesStatus, matrixIndicesUrls] = useObsFeatureMatrixIndices(loaders, dataset, false, { obsType, featureType, featureValueType });
174974
174982
  const cellsCount = (obsIndex == null ? void 0 : obsIndex.length) || 0;
174975
174983
  const isReady = useReady([
174976
174984
  obsSetsStatus,
@@ -174979,6 +174987,10 @@ function GatingSubscriber(props2) {
174979
174987
  featureSelectionYStatus,
174980
174988
  matrixIndicesStatus
174981
174989
  ]);
174990
+ const urls2 = useUrls([
174991
+ obsSetsUrls,
174992
+ matrixIndicesUrls
174993
+ ]);
174982
174994
  const obsXY = useMemo(() => {
174983
174995
  if (!(cellsCount && (expressionDataX == null ? void 0 : expressionDataX[0]) && (expressionDataY == null ? void 0 : expressionDataY[0]) && featureSelectionX && featureSelectionY)) {
174984
174996
  return null;
@@ -191219,16 +191231,13 @@ const useToggleStyles = makeStyles(() => ({
191219
191231
  cameraLabel: {
191220
191232
  padding: "0px 0px 0px 16px"
191221
191233
  },
191222
- box: {
191234
+ toggleBox: {
191223
191235
  padding: "0px"
191224
- },
191225
- button: {
191226
- padding: "0px 0px 0px 8px"
191227
191236
  }
191228
191237
  }));
191229
191238
  const ToggleFixedAxisButton = ({ setSpatialAxisFixed, spatialAxisFixed, use3d }) => {
191230
191239
  const classes = useToggleStyles();
191231
- return jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.cameraLabel, children: "Fix Camera Axis" }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.box, children: jsxRuntimeExports.jsx(Checkbox$1, { onClick: () => setSpatialAxisFixed(!spatialAxisFixed), disabled: !use3d, checked: Boolean(spatialAxisFixed) }) })] });
191240
+ return jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.cameraLabel, children: "Fix Camera Axis" }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.toggleBox, children: jsxRuntimeExports.jsx(Checkbox$1, { onClick: () => setSpatialAxisFixed(!spatialAxisFixed), disabled: !use3d, checked: Boolean(spatialAxisFixed) }) })] });
191232
191241
  };
191233
191242
  function SpatialOptions(props2) {
191234
191243
  const { observationsLabel, cellColorEncoding, setCellColorEncoding, setSpatialAxisFixed, spatialAxisFixed, use3d, tooltipsVisible, setTooltipsVisible, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, canShowExpressionOptions, canShowColorEncodingOption, canShow3DOptions } = props2;
@@ -191274,27 +191283,27 @@ function SpatialSubscriber(props2) {
191274
191283
  const setComponentHover = useSetComponentHover();
191275
191284
  const setComponentViewInfo = useSetComponentViewInfo(uuid);
191276
191285
  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, featureSelection: geneSelection, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, spatialAxisFixed, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, tooltipsVisible }, { 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);
191286
+ const { spatialZoom: initialZoom, spatialTargetX: initialTargetX, spatialTargetY: initialTargetY, spatialTargetZ: initialTargetZ } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SPATIAL], coordinationScopes);
191277
191287
  const observationsLabel = observationsLabelOverride || obsType;
191278
191288
  const [{ imageLayerCallbacks, segmentationLayerCallbacks }] = useAuxiliaryCoordination(COMPONENT_COORDINATION_TYPES.layerController, coordinationScopes);
191279
191289
  const use3d = imageLayers == null ? void 0 : imageLayers.some((l2) => l2.use3d);
191280
- const [urls2, addUrl2] = useUrls(loaders, dataset);
191281
191290
  const [width2, height2, deckRef] = useDeckCanvasSize();
191282
- const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset, addUrl2);
191291
+ const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset);
191283
191292
  const hasExpressionData = useHasLoader(loaders, dataset, DataType$2.OBS_FEATURE_MATRIX, { obsType, featureType, featureValueType });
191284
191293
  const hasSegmentationsData = useHasLoader(loaders, dataset, DataType$2.OBS_SEGMENTATIONS, { obsType });
191285
191294
  const hasLocationsData = useHasLoader(loaders, dataset, DataType$2.OBS_LOCATIONS, { obsType });
191286
191295
  const hasImageData = useHasLoader(loaders, dataset, DataType$2.IMAGE, {});
191287
- const [{ obsIndex: obsLocationsIndex, obsLocations }, obsLocationsStatus] = useObsLocationsData(loaders, dataset, addUrl2, false, { setSpatialPointLayer: setMoleculesLayer }, { spatialPointLayer: moleculesLayer }, { obsType: "molecule" });
191288
- const [{ obsLabels: obsLocationsLabels }, obsLabelsStatus] = useObsLabelsData(loaders, dataset, addUrl2, false, {}, {}, { obsType: "molecule" });
191289
- const [{ obsIndex: obsCentroidsIndex, obsLocations: obsCentroids }, obsCentroidsStatus] = useObsLocationsData(loaders, dataset, addUrl2, false, {}, {}, { obsType });
191290
- const [{ obsIndex: obsSegmentationsIndex, obsSegmentations, obsSegmentationsType }, obsSegmentationsStatus] = useObsSegmentationsData(loaders, dataset, addUrl2, false, { setSpatialSegmentationLayer: setCellsLayer }, { spatialSegmentationLayer: cellsLayer }, { obsType });
191291
- const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
191296
+ const [{ obsIndex: obsLocationsIndex, obsLocations }, obsLocationsStatus, obsLocationsUrls] = useObsLocationsData(loaders, dataset, false, { setSpatialPointLayer: setMoleculesLayer }, { spatialPointLayer: moleculesLayer }, { obsType: "molecule" });
191297
+ const [{ obsLabels: obsLocationsLabels }, obsLabelsStatus, obsLabelsUrls] = useObsLabelsData(loaders, dataset, false, {}, {}, { obsType: "molecule" });
191298
+ const [{ obsIndex: obsCentroidsIndex, obsLocations: obsCentroids }, obsCentroidsStatus, obsCentroidsUrls] = useObsLocationsData(loaders, dataset, false, {}, {}, { obsType });
191299
+ const [{ obsIndex: obsSegmentationsIndex, obsSegmentations, obsSegmentationsType }, obsSegmentationsStatus, obsSegmentationsUrls] = useObsSegmentationsData(loaders, dataset, false, { setSpatialSegmentationLayer: setCellsLayer }, { spatialSegmentationLayer: cellsLayer }, { obsType });
191300
+ const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
191292
191301
  const [expressionData, loadedFeatureSelection, featureSelectionStatus] = useFeatureSelection(loaders, dataset, false, geneSelection, { obsType, featureType, featureValueType });
191293
- const [{ obsIndex: matrixObsIndex }, matrixIndicesStatus] = useObsFeatureMatrixIndices(loaders, dataset, addUrl2, false, { obsType, featureType, featureValueType });
191294
- const [{ image: image2 }, imageStatus] = useImageData(loaders, dataset, addUrl2, false, { setSpatialImageLayer: setRasterLayers }, { spatialImageLayer: imageLayers }, {});
191302
+ const [{ obsIndex: matrixObsIndex }, matrixIndicesStatus, matrixIndicesUrls] = useObsFeatureMatrixIndices(loaders, dataset, false, { obsType, featureType, featureValueType });
191303
+ const [{ image: image2 }, imageStatus, imageUrls] = useImageData(loaders, dataset, false, { setSpatialImageLayer: setRasterLayers }, { spatialImageLayer: imageLayers }, {});
191295
191304
  const { loaders: imageLayerLoaders = [], meta: meta2 = [] } = image2 || {};
191296
- const [neighborhoods, neighborhoodsStatus] = useNeighborhoodsData(loaders, dataset, addUrl2, false, { setSpatialNeighborhoodLayer: setNeighborhoodsLayer }, { spatialNeighborhoodLayer: neighborhoodsLayer });
191297
- const [{ featureLabelsMap }, featureLabelsStatus] = useFeatureLabelsData(loaders, dataset, addUrl2, false, {}, {}, { featureType });
191305
+ const [neighborhoods, neighborhoodsStatus, neighborhoodsUrls] = useNeighborhoodsData(loaders, dataset, false, { setSpatialNeighborhoodLayer: setNeighborhoodsLayer }, { spatialNeighborhoodLayer: neighborhoodsLayer });
191306
+ const [{ featureLabelsMap }, featureLabelsStatus, featureLabelsUrls] = useFeatureLabelsData(loaders, dataset, false, {}, {}, { featureType });
191298
191307
  const isReady = useReady([
191299
191308
  obsLocationsStatus,
191300
191309
  obsLabelsStatus,
@@ -191307,6 +191316,17 @@ function SpatialSubscriber(props2) {
191307
191316
  neighborhoodsStatus,
191308
191317
  featureLabelsStatus
191309
191318
  ]);
191319
+ const urls2 = useUrls([
191320
+ obsLocationsUrls,
191321
+ obsLabelsUrls,
191322
+ obsCentroidsUrls,
191323
+ obsSegmentationsUrls,
191324
+ obsSetsUrls,
191325
+ matrixIndicesUrls,
191326
+ imageUrls,
191327
+ neighborhoodsUrls,
191328
+ featureLabelsUrls
191329
+ ]);
191310
191330
  const obsLocationsFeatureIndex = useMemo(() => {
191311
191331
  if (obsLocationsLabels) {
191312
191332
  return Array.from(new Set(obsLocationsLabels));
@@ -191315,8 +191335,8 @@ function SpatialSubscriber(props2) {
191315
191335
  }, [obsLocationsLabels]);
191316
191336
  const moleculesCount = (obsLocationsFeatureIndex == null ? void 0 : obsLocationsFeatureIndex.length) || 0;
191317
191337
  const locationsCount = (obsLocationsIndex == null ? void 0 : obsLocationsIndex.length) || 0;
191318
- const [originalViewState, setOriginalViewState] = useState({ target: [targetX2, targetY2, targetZ], zoom: zoom2 });
191319
- const { initialTargetX, initialTargetY, initialTargetZ, initialZoom } = useMemo(
191338
+ const [originalViewState, setOriginalViewState] = useState(null);
191339
+ const { initialTargetX: defaultTargetX, initialTargetY: defaultTargetY, initialTargetZ: defaultTargetZ, initialZoom: defaultZoom } = useMemo(
191320
191340
  () => getInitialSpatialTargets({
191321
191341
  width: width2,
191322
191342
  height: height2,
@@ -191332,23 +191352,47 @@ function SpatialSubscriber(props2) {
191332
191352
  return (_a2 = metadata2 == null ? void 0 : metadata2.transform) == null ? void 0 : _a2.matrix;
191333
191353
  })
191334
191354
  }),
191335
- // Deliberate dependency omissions: width/height - technically then
191336
- // these initial values will be "wrong" after resizing, but it shouldn't be far enough
191337
- // off to be noticeable.
191338
191355
  // Deliberate dependency omissions: imageLayerLoaders and meta - using `image` as
191339
191356
  // an indirect dependency instead.
191340
191357
  // eslint-disable-next-line react-hooks/exhaustive-deps
191341
- [image2, use3d, hasImageData, obsCentroids, obsSegmentations, obsSegmentationsType]
191358
+ [
191359
+ image2,
191360
+ use3d,
191361
+ hasImageData,
191362
+ obsCentroids,
191363
+ obsSegmentations,
191364
+ obsSegmentationsType,
191365
+ width2,
191366
+ height2
191367
+ ]
191342
191368
  );
191343
191369
  useEffect(() => {
191344
- if (typeof targetX2 !== "number" || typeof targetY2 !== "number") {
191345
- setTargetX(initialTargetX);
191346
- setTargetY(initialTargetY);
191347
- setTargetZ(initialTargetZ);
191348
- setZoom(initialZoom);
191349
- setOriginalViewState({ target: [initialTargetX, initialTargetY, initialTargetZ], zoom: initialZoom });
191350
- }
191351
- }, [initialTargetX, initialTargetY, initialTargetZ, initialZoom]);
191370
+ if (typeof initialTargetX !== "number" || typeof initialTargetY !== "number") {
191371
+ const notYetInitialized = typeof targetX2 !== "number" || typeof targetY2 !== "number";
191372
+ const stillDefaultInitialized = targetX2 === defaultTargetX && targetY2 === defaultTargetY;
191373
+ if (notYetInitialized || stillDefaultInitialized) {
191374
+ setTargetX(defaultTargetX);
191375
+ setTargetY(defaultTargetY);
191376
+ setTargetZ(defaultTargetZ);
191377
+ setZoom(defaultZoom);
191378
+ }
191379
+ setOriginalViewState({ target: [defaultTargetX, defaultTargetY, defaultTargetZ], zoom: defaultZoom });
191380
+ } else if (!originalViewState) {
191381
+ setOriginalViewState({
191382
+ target: [initialTargetX, initialTargetY, initialTargetZ],
191383
+ zoom: initialZoom
191384
+ });
191385
+ }
191386
+ }, [
191387
+ defaultTargetX,
191388
+ defaultTargetY,
191389
+ defaultTargetZ,
191390
+ defaultZoom,
191391
+ initialTargetX,
191392
+ initialTargetY,
191393
+ initialTargetZ,
191394
+ initialZoom
191395
+ ]);
191352
191396
  const mergedCellSets = useMemo(() => mergeObsSets(cellSets, additionalCellSets), [cellSets, additionalCellSets]);
191353
191397
  const setCellSelectionProp = useCallback((v) => {
191354
191398
  setObsSelection(v, additionalCellSets, cellSetColor, setCellSetSelection, setAdditionalCellSets, setCellSetColor, setCellColorEncoding);
@@ -191669,8 +191713,8 @@ function shouldUsePaddedImplementation(dataLength) {
191669
191713
  return dataLength <= DATA_TEXTURE_SIZE ** 2;
191670
191714
  }
191671
191715
  const Heatmap$1 = forwardRef((props2, deckRef) => {
191672
- const { uuid, theme, viewState: rawViewState, setViewState, width: viewWidth2, height: viewHeight2, expressionMatrix: expression2, cellColors, cellColorLabels = [""], colormap, colormapRange, clearPleaseWait, setComponentHover, setCellHighlight = createDefaultUpdateCellsHover("Heatmap"), setGeneHighlight = createDefaultUpdateGenesHover("Heatmap"), setTrackHighlight = createDefaultUpdateTracksHover("Heatmap"), updateViewInfo = createDefaultUpdateViewInfo("Heatmap"), setIsRendering = () => {
191673
- }, transpose: transpose2 = false, variablesTitle = "Genes", observationsTitle = "Cells", variablesDashes = true, observationsDashes = true, useDevicePixels = 1, hideObservationLabels = false, hideVariableLabels = false, onHeatmapClick, setColorEncoding, featureIndex } = props2;
191716
+ const { uuid, theme, viewState: rawViewState, setViewState, width: viewWidth2, height: viewHeight2, uint8ObsFeatureMatrix, cellColors, cellColorLabels = [""], colormap, colormapRange, setComponentHover, setCellHighlight = createDefaultUpdateCellsHover("Heatmap"), setGeneHighlight = createDefaultUpdateGenesHover("Heatmap"), setTrackHighlight = createDefaultUpdateTracksHover("Heatmap"), updateViewInfo = createDefaultUpdateViewInfo("Heatmap"), setIsRendering = () => {
191717
+ }, transpose: transpose2 = false, variablesTitle = "Genes", observationsTitle = "Cells", variablesDashes = true, observationsDashes = true, useDevicePixels = 1, hideObservationLabels = false, hideVariableLabels = false, onHeatmapClick, setColorEncoding, obsIndex, featureIndex, featureLabelsMap } = props2;
191674
191718
  const viewState = {
191675
191719
  ...rawViewState,
191676
191720
  target: transpose2 ? [rawViewState.target[1], rawViewState.target[0]] : rawViewState.target,
@@ -191679,11 +191723,6 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191679
191723
  const axisLeftTitle = transpose2 ? variablesTitle : observationsTitle;
191680
191724
  const axisTopTitle = transpose2 ? observationsTitle : variablesTitle;
191681
191725
  const workerPool = useMemo(() => new HeatmapPool(), []);
191682
- useEffect(() => {
191683
- if (clearPleaseWait && expression2) {
191684
- clearPleaseWait("expression-matrix");
191685
- }
191686
- }, [clearPleaseWait, expression2]);
191687
191726
  const tilesRef = useRef();
191688
191727
  const dataRef = useRef();
191689
191728
  const [axisLeftLabels, setAxisLeftLabels] = useState([]);
@@ -191693,15 +191732,15 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191693
191732
  const [tileIteration, incTileIteration] = useReducer((i2) => i2 + 1, 0);
191694
191733
  const [backlog, setBacklog] = useState([]);
191695
191734
  useEffect(() => {
191696
- if (expression2 && expression2.matrix && !shouldUsePaddedImplementation(expression2.matrix.length)) {
191697
- dataRef.current = copyUint8Array(expression2.matrix);
191735
+ if (uint8ObsFeatureMatrix && !shouldUsePaddedImplementation(uint8ObsFeatureMatrix.length)) {
191736
+ dataRef.current = copyUint8Array(uint8ObsFeatureMatrix);
191698
191737
  }
191699
- }, [dataRef, expression2]);
191738
+ }, [dataRef, uint8ObsFeatureMatrix]);
191700
191739
  useEffect(() => {
191701
- if (!expression2) {
191740
+ if (!obsIndex) {
191702
191741
  return;
191703
191742
  }
191704
- const newCellOrdering = !cellColors || cellColors.size === 0 ? expression2.rows : Array.from(cellColors.keys());
191743
+ const newCellOrdering = !cellColors || cellColors.size === 0 ? obsIndex : Array.from(cellColors.keys());
191705
191744
  const oldCellOrdering = transpose2 ? axisTopLabels : axisLeftLabels;
191706
191745
  if (!isEqual$4(oldCellOrdering, newCellOrdering)) {
191707
191746
  if (transpose2) {
@@ -191710,33 +191749,33 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191710
191749
  setAxisLeftLabels(newCellOrdering);
191711
191750
  }
191712
191751
  }
191713
- }, [expression2, cellColors, axisTopLabels, axisLeftLabels, transpose2]);
191752
+ }, [obsIndex, cellColors, axisTopLabels, axisLeftLabels, transpose2]);
191714
191753
  useEffect(() => {
191715
- if (!expression2) {
191754
+ if (!featureIndex) {
191716
191755
  return;
191717
191756
  }
191718
191757
  if (transpose2) {
191719
- setAxisLeftLabels(expression2.cols);
191758
+ setAxisLeftLabels(featureIndex);
191720
191759
  } else {
191721
- setAxisTopLabels(expression2.cols);
191760
+ setAxisTopLabels(featureIndex);
191722
191761
  }
191723
- }, [expression2, transpose2]);
191762
+ }, [featureIndex, transpose2]);
191724
191763
  const [longestCellLabel, longestGeneLabel] = useMemo(() => {
191725
- if (!expression2) {
191764
+ if (!obsIndex || !featureIndex) {
191726
191765
  return ["", ""];
191727
191766
  }
191728
191767
  return [
191729
- getLongestString(expression2.rows),
191730
- getLongestString([...expression2.cols, ...cellColorLabels])
191768
+ getLongestString(obsIndex),
191769
+ getLongestString([...featureIndex, ...cellColorLabels])
191731
191770
  ];
191732
- }, [expression2, cellColorLabels]);
191771
+ }, [featureIndex, cellColorLabels, obsIndex]);
191733
191772
  const expressionRowLookUp = useMemo(() => {
191734
191773
  const lookUp = /* @__PURE__ */ new Map();
191735
- if (expression2 == null ? void 0 : expression2.rows) {
191736
- expression2.rows.forEach((cell2, j) => lookUp.set(cell2, j));
191774
+ if (obsIndex) {
191775
+ obsIndex.forEach((cell2, j) => lookUp.set(cell2, j));
191737
191776
  }
191738
191777
  return lookUp;
191739
- }, [expression2]);
191778
+ }, [obsIndex]);
191740
191779
  const width2 = axisTopLabels.length;
191741
191780
  const height2 = axisLeftLabels.length;
191742
191781
  const [axisOffsetLeft, axisOffsetTop] = getAxisSizes(transpose2, longestGeneLabel, longestCellLabel, hideObservationLabels, hideVariableLabels);
@@ -191812,29 +191851,28 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191812
191851
  });
191813
191852
  }, [matrixRight, matrixBottom, transpose2, setViewState]);
191814
191853
  useEffect(() => {
191815
- if (!expression2 || !expression2.matrix || expression2.matrix.length < DATA_TEXTURE_SIZE ** 2) {
191854
+ if (!uint8ObsFeatureMatrix || uint8ObsFeatureMatrix.length < DATA_TEXTURE_SIZE ** 2) {
191816
191855
  return;
191817
191856
  }
191818
191857
  if (axisTopLabels && axisLeftLabels && xTiles && yTiles) {
191819
191858
  setBacklog((prev) => [...prev, v4$1()]);
191820
191859
  }
191821
- }, [dataRef, expression2, axisTopLabels, axisLeftLabels, xTiles, yTiles]);
191860
+ }, [dataRef, uint8ObsFeatureMatrix, axisTopLabels, axisLeftLabels, xTiles, yTiles]);
191822
191861
  useEffect(() => {
191823
191862
  if (backlog.length < 1 || shouldUsePaddedImplementation(dataRef.current.length)) {
191824
191863
  return;
191825
191864
  }
191826
191865
  const curr = backlog[backlog.length - 1];
191827
191866
  if (dataRef.current && dataRef.current.buffer.byteLength && expressionRowLookUp.size > 0 && !shouldUsePaddedImplementation(dataRef.current.length)) {
191828
- const { cols, matrix: matrix2 } = expression2;
191829
191867
  const promises = range$a(yTiles).map((i2) => range$a(xTiles).map(async (j) => workerPool.process({
191830
191868
  curr,
191831
191869
  tileI: i2,
191832
191870
  tileJ: j,
191833
191871
  tileSize: TILE_SIZE,
191834
191872
  cellOrdering: transpose2 ? axisTopLabels : axisLeftLabels,
191835
- cols,
191873
+ cols: featureIndex,
191836
191874
  transpose: transpose2,
191837
- data: matrix2.buffer.slice(),
191875
+ data: uint8ObsFeatureMatrix.buffer.slice(),
191838
191876
  expressionRowLookUp
191839
191877
  })));
191840
191878
  const process2 = async () => {
@@ -191854,27 +191892,28 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191854
191892
  axisLeftLabels,
191855
191893
  axisTopLabels,
191856
191894
  backlog,
191857
- expression2,
191895
+ uint8ObsFeatureMatrix,
191858
191896
  transpose2,
191859
191897
  xTiles,
191860
191898
  yTiles,
191861
191899
  workerPool,
191862
- expressionRowLookUp
191900
+ expressionRowLookUp,
191901
+ featureIndex
191863
191902
  ]);
191864
191903
  useEffect(() => {
191865
191904
  setIsRendering(backlog.length > 0);
191866
191905
  }, [backlog, setIsRendering]);
191867
191906
  const paddedExpressions = useMemo(() => {
191868
191907
  const cellOrdering = transpose2 ? axisTopLabels : axisLeftLabels;
191869
- if ((expression2 == null ? void 0 : expression2.matrix) && cellOrdering.length && gl && shouldUsePaddedImplementation(expression2.matrix.length)) {
191908
+ if (uint8ObsFeatureMatrix && cellOrdering.length && gl && shouldUsePaddedImplementation(uint8ObsFeatureMatrix.length)) {
191870
191909
  let newIndex = 0;
191871
191910
  for (let cellOrderingIndex = 0; cellOrderingIndex < cellOrdering.length; cellOrderingIndex += 1) {
191872
191911
  const cell2 = cellOrdering[cellOrderingIndex];
191873
191912
  newIndex = transpose2 ? cellOrderingIndex : newIndex;
191874
191913
  const cellIndex = expressionRowLookUp.get(cell2);
191875
- for (let geneIndex = 0; geneIndex < expression2.cols.length; geneIndex += 1) {
191876
- const index2 = cellIndex * expression2.cols.length + geneIndex;
191877
- paddedExpressionContainer[newIndex % (DATA_TEXTURE_SIZE * DATA_TEXTURE_SIZE)] = expression2.matrix[index2];
191914
+ for (let geneIndex = 0; geneIndex < featureIndex.length; geneIndex += 1) {
191915
+ const index2 = cellIndex * featureIndex.length + geneIndex;
191916
+ paddedExpressionContainer[newIndex % (DATA_TEXTURE_SIZE * DATA_TEXTURE_SIZE)] = uint8ObsFeatureMatrix[index2];
191878
191917
  newIndex = transpose2 ? newIndex + cellOrdering.length : newIndex + 1;
191879
191918
  }
191880
191919
  }
@@ -191896,18 +191935,18 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191896
191935
  transpose2,
191897
191936
  axisTopLabels,
191898
191937
  axisLeftLabels,
191899
- expression2,
191938
+ uint8ObsFeatureMatrix,
191900
191939
  expressionRowLookUp,
191940
+ featureIndex,
191901
191941
  gl
191902
191942
  ]);
191903
191943
  const heatmapLayers = useMemo(() => {
191904
- const usePaddedExpressions = (expression2 == null ? void 0 : expression2.matrix) && shouldUsePaddedImplementation(expression2 == null ? void 0 : expression2.matrix.length);
191944
+ const usePaddedExpressions = uint8ObsFeatureMatrix && shouldUsePaddedImplementation(uint8ObsFeatureMatrix.length);
191905
191945
  if ((!tilesRef.current || backlog.length) && !usePaddedExpressions) {
191906
191946
  return [];
191907
191947
  }
191908
191948
  if (usePaddedExpressions) {
191909
191949
  let getLayer2 = function(i2, j) {
191910
- const { cols } = expression2;
191911
191950
  return new PaddedExpressionHeatmapBitmapLayer({
191912
191951
  id: `heatmapLayer-${i2}-${j}`,
191913
191952
  image: paddedExpressions,
@@ -191921,7 +191960,7 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191921
191960
  tileJ: j,
191922
191961
  numXTiles: xTiles,
191923
191962
  numYTiles: yTiles,
191924
- origDataSize: transpose2 ? [cols.length, cellOrdering.length] : [cellOrdering.length, cols.length],
191963
+ origDataSize: transpose2 ? [featureIndex.length, cellOrdering.length] : [cellOrdering.length, featureIndex.length],
191925
191964
  aggSizeX,
191926
191965
  aggSizeY,
191927
191966
  colormap,
@@ -191961,28 +192000,29 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
191961
192000
  const layers2 = tilesRef.current.map((tile, index2) => getLayer(Math.floor(index2 / xTiles), index2 % xTiles, tile));
191962
192001
  return layers2;
191963
192002
  }, [
191964
- expression2,
192003
+ uint8ObsFeatureMatrix,
191965
192004
  backlog.length,
191966
192005
  transpose2,
191967
192006
  axisTopLabels,
191968
192007
  axisLeftLabels,
191969
- yTiles,
191970
- xTiles,
191971
192008
  paddedExpressions,
191972
192009
  matrixLeft,
191973
192010
  tileWidth,
191974
192011
  matrixTop,
191975
192012
  tileHeight,
192013
+ yTiles,
192014
+ xTiles,
191976
192015
  aggSizeX,
191977
192016
  aggSizeY,
191978
192017
  colormap,
191979
192018
  colormapRange,
191980
- tileIteration
192019
+ tileIteration,
192020
+ featureIndex
191981
192021
  ]);
191982
192022
  const axisLeftDashes = transpose2 ? variablesDashes : observationsDashes;
191983
192023
  const axisTopDashes = transpose2 ? observationsDashes : variablesDashes;
191984
- const axisTopLabelData = useMemo(() => axisTopLabels.map((d, i2) => [i2, axisTopDashes ? `- ${d}` : d]), [axisTopLabels, axisTopDashes]);
191985
- const axisLeftLabelData = useMemo(() => axisLeftLabels.map((d, i2) => [i2, axisLeftDashes ? `${d} -` : d]), [axisLeftLabels, axisLeftDashes]);
192024
+ const axisTopLabelData = useMemo(() => (!transpose2 && featureLabelsMap ? axisTopLabels.map((d) => featureLabelsMap.get(d) || d) : axisTopLabels).map((d, i2) => [i2, axisTopDashes ? `- ${d}` : d]), [axisTopLabels, axisTopDashes, transpose2, featureLabelsMap]);
192025
+ const axisLeftLabelData = useMemo(() => (transpose2 && featureLabelsMap ? axisLeftLabels.map((d) => featureLabelsMap.get(d) || d) : axisLeftLabels).map((d, i2) => [i2, axisLeftDashes ? `${d} -` : d]), [axisLeftLabels, axisLeftDashes, transpose2, featureLabelsMap]);
191986
192026
  const cellColorLabelsData = useMemo(() => cellColorLabels.map((d, i2) => [i2, d && (transpose2 ? `${d} -` : `- ${d}`)]), [cellColorLabels, transpose2]);
191987
192027
  const hideTopLabels = transpose2 ? hideObservationLabels : hideVariableLabels;
191988
192028
  const hideLeftLabels = transpose2 ? hideVariableLabels : hideObservationLabels;
@@ -192153,7 +192193,7 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
192153
192193
  const showText = width2 > 0 && height2 > 0;
192154
192194
  const layers = heatmapLayers.concat(showText ? textLayers : []).concat(...cellColorsLayersList);
192155
192195
  function onHover(info2, event2) {
192156
- if (!expression2) {
192196
+ if (!uint8ObsFeatureMatrix) {
192157
192197
  return;
192158
192198
  }
192159
192199
  let highlightedCell = null;
@@ -192179,8 +192219,8 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
192179
192219
  setTrackHighlight(null);
192180
192220
  setColorEncoding("geneSelection");
192181
192221
  } else {
192182
- const obsI2 = expression2.rows.indexOf(transpose2 ? axisTopLabels[trackColI] : axisLeftLabels[trackColI]);
192183
- const cellIndex = expression2.rows[obsI2];
192222
+ const obsI2 = obsIndex.indexOf(transpose2 ? axisTopLabels[trackColI] : axisLeftLabels[trackColI]);
192223
+ const cellIndex = obsIndex[obsI2];
192184
192224
  setTrackHighlight([cellIndex, trackI, mouseX, mouseY]);
192185
192225
  highlightedCell = cellIndex;
192186
192226
  setColorEncoding("cellSelection");
@@ -192196,9 +192236,9 @@ const Heatmap$1 = forwardRef((props2, deckRef) => {
192196
192236
  numRows: height2,
192197
192237
  numCols: width2
192198
192238
  });
192199
- const obsI = expression2.rows.indexOf(transpose2 ? axisTopLabels[colI] : axisLeftLabels[rowI]);
192200
- const varI = expression2.cols.indexOf(transpose2 ? axisLeftLabels[rowI] : axisTopLabels[colI]);
192201
- const obsId = expression2.rows[obsI];
192239
+ const obsI = obsIndex.indexOf(transpose2 ? axisTopLabels[colI] : axisLeftLabels[rowI]);
192240
+ const varI = featureIndex.indexOf(transpose2 ? axisLeftLabels[rowI] : axisTopLabels[colI]);
192241
+ const obsId = obsIndex[obsI];
192202
192242
  const varId = featureIndex[varI];
192203
192243
  if (setComponentHover) {
192204
192244
  setComponentHover();
@@ -192348,17 +192388,21 @@ function HeatmapSubscriber(props2) {
192348
192388
  const variablesTitle = capitalize$2(variablesPluralLabel);
192349
192389
  const [isRendering, setIsRendering] = useState(false);
192350
192390
  const [hoveredColorEncoding, setHoveredColorEncoding] = useState("geneSelection");
192351
- const [urls2, addUrl2] = useUrls(loaders, dataset);
192352
192391
  const [width2, height2, deckRef] = useDeckCanvasSize();
192353
- const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset, addUrl2);
192354
- const [{ featureLabelsMap }, featureLabelsStatus] = useFeatureLabelsData(loaders, dataset, addUrl2, false, {}, {}, { featureType });
192355
- const [{ obsIndex, featureIndex, obsFeatureMatrix }, matrixStatus] = useObsFeatureMatrixData(loaders, dataset, addUrl2, true, {}, {}, { obsType, featureType, featureValueType });
192356
- const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
192392
+ const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset);
192393
+ const [{ featureLabelsMap }, featureLabelsStatus, featureLabelsUrls] = useFeatureLabelsData(loaders, dataset, false, {}, {}, { featureType });
192394
+ const [{ obsIndex, featureIndex, obsFeatureMatrix }, matrixStatus, matrixUrls] = useObsFeatureMatrixData(loaders, dataset, true, {}, {}, { obsType, featureType, featureValueType });
192395
+ const [{ obsSets: cellSets, obsSetsMembership }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, false, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
192357
192396
  const isReady = useReady([
192358
192397
  featureLabelsStatus,
192359
192398
  matrixStatus,
192360
192399
  obsSetsStatus
192361
192400
  ]);
192401
+ const urls2 = useUrls([
192402
+ featureLabelsUrls,
192403
+ matrixUrls,
192404
+ obsSetsUrls
192405
+ ]);
192362
192406
  const [uint8ObsFeatureMatrix, obsFeatureMatrixExtent] = useUint8ObsFeatureMatrix({ obsFeatureMatrix });
192363
192407
  const mergedCellSets = useMemo(() => mergeObsSets(cellSets, additionalCellSets), [cellSets, additionalCellSets]);
192364
192408
  const cellColors = useMemo(() => getCellColors({
@@ -192383,16 +192427,6 @@ function HeatmapSubscriber(props2) {
192383
192427
  }
192384
192428
  return null;
192385
192429
  }, [variablesLabel, featureLabelsMap]);
192386
- const expressionMatrix = useMemo(() => {
192387
- if (obsIndex && featureIndex && uint8ObsFeatureMatrix) {
192388
- return {
192389
- rows: obsIndex,
192390
- cols: featureLabelsMap ? featureIndex.map((key2) => featureLabelsMap.get(key2) || key2) : featureIndex,
192391
- matrix: uint8ObsFeatureMatrix.data
192392
- };
192393
- }
192394
- return null;
192395
- }, [obsIndex, featureIndex, uint8ObsFeatureMatrix, featureLabelsMap]);
192396
192430
  const cellsCount = obsIndex ? obsIndex.length : 0;
192397
192431
  const genesCount = featureIndex ? featureIndex.length : 0;
192398
192432
  const setTrackHighlight = useCallback(() => {
@@ -192422,7 +192456,7 @@ function HeatmapSubscriber(props2) {
192422
192456
  setZoomY(zoom2);
192423
192457
  setTargetX(target2[0]);
192424
192458
  setTargetY(target2[1]);
192425
- }, colormapRange: geneExpressionColormapRange, setColormapRange: setGeneExpressionColormapRange, height: height2, width: width2, theme, uuid, expressionMatrix, cellColors, colormap: geneExpressionColormap, setIsRendering, setCellHighlight, setGeneHighlight, featureIndex, setTrackHighlight, setComponentHover: () => {
192459
+ }, colormapRange: geneExpressionColormapRange, setColormapRange: setGeneExpressionColormapRange, height: height2, width: width2, theme, uuid, uint8ObsFeatureMatrix: uint8ObsFeatureMatrix == null ? void 0 : uint8ObsFeatureMatrix.data, cellColors, colormap: geneExpressionColormap, setIsRendering, setCellHighlight, setGeneHighlight, featureLabelsMap, obsIndex, featureIndex, setTrackHighlight, setComponentHover: () => {
192426
192460
  setComponentHover(uuid);
192427
192461
  }, updateViewInfo: setComponentViewInfo, observationsTitle, variablesTitle, variablesDashes: false, observationsDashes: false, cellColorLabels, useDevicePixels: true, onHeatmapClick, setColorEncoding: setHoveredColorEncoding }), tooltipsVisible && jsxRuntimeExports.jsx(HeatmapTooltipSubscriber, { parentUuid: uuid, width: width2, height: height2, transpose: transpose2, getObsInfo, getFeatureInfo, obsHighlight: cellHighlight, featureHighlight: geneHighlight }), jsxRuntimeExports.jsx(Legend, { visible: true, theme, featureType, featureValueType, obsColorEncoding: "geneExpression", considerSelections: false, featureSelection: geneSelection, featureValueColormap: geneExpressionColormap, featureValueColormapRange: geneExpressionColormapRange, extent: obsFeatureMatrixExtent })] });
192428
192462
  }
@@ -196625,10 +196659,10 @@ const useStyles$8 = makeStyles((theme) => ({
196625
196659
  backgroundClip: "unset"
196626
196660
  }
196627
196661
  },
196628
- radio: {
196662
+ tableRadio: {
196629
196663
  borderRadius: "50%"
196630
196664
  },
196631
- checkbox: {
196665
+ tableCheckbox: {
196632
196666
  borderRadius: "2px"
196633
196667
  }
196634
196668
  }));
@@ -196709,7 +196743,7 @@ function SelectableTable(props2) {
196709
196743
  const inputUuid = v4$1();
196710
196744
  const rowRenderer = ({ index: index2, style: style2 }) => (
196711
196745
  // eslint-disable-next-line jsx-a11y/interactive-supports-focus
196712
- jsxRuntimeExports.jsxs("div", { className: clsx(classes.tableItem, classes.tableRow, { "row-checked": isSelected(data2[index2][idKey]) }), style: style2, role: "button", onClick: () => onSelectRow(data2[index2][idKey], !isSelected(data2[index2][idKey]) || !hasColorEncoding), children: [jsxRuntimeExports.jsx("div", { className: clsx(classes.inputContainer, classes.tableCell, { [classes.hiddenInputColumn]: !showTableInputs }), children: jsxRuntimeExports.jsx("label", { htmlFor: `${inputUuid}_${data2[index2][idKey]}`, children: jsxRuntimeExports.jsx("input", { id: `${inputUuid}_${data2[index2][idKey]}`, type: "checkbox", className: clsx(classes.radioOrCheckbox, isCheckingMultiple ? classes.checkbox : classes.radio), name: inputUuid, value: data2[index2][idKey], onChange: handleInputChange, checked: isSelected(data2[index2][idKey]) }) }) }), columns.map((column) => jsxRuntimeExports.jsx("div", { className: classes.tableCell, children: data2[index2][column] }, column))] }, data2[index2][idKey])
196746
+ jsxRuntimeExports.jsxs("div", { className: clsx(classes.tableItem, classes.tableRow, { "row-checked": isSelected(data2[index2][idKey]) }), style: style2, role: "button", onClick: () => onSelectRow(data2[index2][idKey], !isSelected(data2[index2][idKey]) || !hasColorEncoding), children: [jsxRuntimeExports.jsx("div", { className: clsx(classes.inputContainer, classes.tableCell, { [classes.hiddenInputColumn]: !showTableInputs }), children: jsxRuntimeExports.jsx("label", { htmlFor: `${inputUuid}_${data2[index2][idKey]}`, children: jsxRuntimeExports.jsx("input", { id: `${inputUuid}_${data2[index2][idKey]}`, type: "checkbox", className: clsx(classes.radioOrCheckbox, isCheckingMultiple ? classes.tableCheckbox : classes.tableRadio), name: inputUuid, value: data2[index2][idKey], onChange: handleInputChange, checked: isSelected(data2[index2][idKey]) }) }) }), columns.map((column) => jsxRuntimeExports.jsx("div", { className: classes.tableCell, children: data2[index2][column] }, column))] }, data2[index2][idKey])
196713
196747
  );
196714
196748
  const headerRowRenderer = ({ style: style2 }) => jsxRuntimeExports.jsx("div", { className: classes.tableRow, style: style2, children: columnLabels.map((columnLabel) => jsxRuntimeExports.jsx("div", { className: classes.tableCell, style: { fontWeight: "bold" }, children: columnLabel }, columnLabel)) });
196715
196749
  return jsxRuntimeExports.jsx("div", { className: classes.selectableTable, children: jsxRuntimeExports.jsx(AutoSizer$1.AutoSizer, { children: ({ width: width2, height: height2 }) => jsxRuntimeExports.jsx(Table$1.Table, {
@@ -196725,6 +196759,11 @@ function SelectableTable(props2) {
196725
196759
  rowGetter: ({ index: index2 }) => data2[index2]
196726
196760
  }) }) });
196727
196761
  }
196762
+ const FEATURELIST_SORT_OPTIONS = [
196763
+ "alphabetical",
196764
+ "original"
196765
+ ];
196766
+ const ALT_COLNAME = "Alternate ID";
196728
196767
  const useStyles$7 = makeStyles(() => ({
196729
196768
  searchBar: {
196730
196769
  marginBottom: "4px",
@@ -196734,10 +196773,11 @@ const useStyles$7 = makeStyles(() => ({
196734
196773
  }
196735
196774
  }));
196736
196775
  function FeatureList(props2) {
196737
- const { hasColorEncoding, geneList = [], featureLabelsMap, featureType, geneSelection = [], geneFilter = null, setGeneSelection, enableMultiSelect, showTable, sort: sort2 } = props2;
196776
+ const { hasColorEncoding, geneList = [], featureLabelsMap, geneSelection = [], geneFilter = null, setGeneSelection, enableMultiSelect, showFeatureTable, featureListSort, featureListSortKey, hasFeatureLabels, primaryColumnName } = props2;
196738
196777
  const classes = useStyles$7();
196739
196778
  const [searchTerm, setSearchTerm] = useState("");
196740
196779
  const [searchResults, setSearchResults] = useState(geneList);
196780
+ const selectableTableSortKey = featureListSortKey === "featureIndex" ? "key" : "name";
196741
196781
  useEffect(() => {
196742
196782
  const results = geneList.filter((gene) => {
196743
196783
  var _a2;
@@ -196758,44 +196798,87 @@ function FeatureList(props2) {
196758
196798
  }
196759
196799
  }
196760
196800
  }
196761
- let data2 = searchResults.filter((gene) => geneFilter ? geneFilter.includes(gene) : true).map((gene) => ({
196762
- key: gene,
196763
- name: (featureLabelsMap == null ? void 0 : featureLabelsMap.get(gene)) || gene,
196764
- value: geneSelection ? geneSelection.includes(gene) : false
196765
- }));
196766
- if (sort2 === "alphabetical") {
196767
- data2 = data2.sort((a2, b2) => a2.name.localeCompare(b2.name));
196768
- }
196801
+ const data2 = useMemo(() => {
196802
+ const preSortedData = searchResults.filter((gene) => geneFilter ? geneFilter.includes(gene) : true).map((gene) => ({
196803
+ key: gene,
196804
+ name: (featureLabelsMap == null ? void 0 : featureLabelsMap.get(gene)) || gene,
196805
+ value: geneSelection ? geneSelection.includes(gene) : false
196806
+ }));
196807
+ if (preSortedData && featureListSort === "alphabetical" && preSortedData.length > 0) {
196808
+ return preSortedData.sort((a2, b2) => a2[selectableTableSortKey].localeCompare(b2[selectableTableSortKey]));
196809
+ }
196810
+ return preSortedData;
196811
+ }, [
196812
+ featureListSort,
196813
+ selectableTableSortKey,
196814
+ searchResults,
196815
+ geneFilter,
196816
+ featureLabelsMap,
196817
+ geneSelection
196818
+ ]);
196769
196819
  const handleChange = (event2) => {
196770
196820
  setSearchTerm(event2.target.value);
196771
196821
  };
196772
- const columns = ["name"];
196773
- const columnLabels = [`${capitalize$2(featureType)} ID`];
196774
- if (showTable) {
196775
- columns.push("key");
196776
- columnLabels.push("Alternate ID");
196777
- }
196822
+ const [columns, columnLabels] = useMemo(() => {
196823
+ if (showFeatureTable && hasFeatureLabels) {
196824
+ return [
196825
+ ["name", "key"],
196826
+ [primaryColumnName, ALT_COLNAME]
196827
+ ];
196828
+ }
196829
+ return [
196830
+ ["name"],
196831
+ [primaryColumnName]
196832
+ ];
196833
+ }, [showFeatureTable, primaryColumnName, hasFeatureLabels]);
196778
196834
  return jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("input", { className: classes.searchBar, type: "text", placeholder: "Search", value: searchTerm, onChange: handleChange }), jsxRuntimeExports.jsx(SelectableTable, { columns, columnLabels, data: data2, hasColorEncoding, idKey: "key", valueKey: "value", onChange, allowMultiple: enableMultiSelect, allowUncheck: enableMultiSelect, showTableHead: columnLabels.length > 1 })] });
196779
196835
  }
196836
+ function FeatureListOptions(props2) {
196837
+ const { children: children2, featureListSort, setFeatureListSort, featureListSortKey, setFeatureListSortKey, showFeatureTable, setShowFeatureTable, hasFeatureLabels, primaryColumnName } = props2;
196838
+ function handleFeatureListSortChange(event2) {
196839
+ setFeatureListSort(event2.target.value);
196840
+ }
196841
+ function handleFeatureListSortKeyChange(event2) {
196842
+ setFeatureListSortKey(event2.target.value);
196843
+ }
196844
+ function handleShowTableChange(event2) {
196845
+ setShowFeatureTable(event2.target.checked);
196846
+ }
196847
+ const classes = usePlotOptionsStyles();
196848
+ return jsxRuntimeExports.jsxs(OptionsContainer, { children: [children2, jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, htmlFor: "feature-list-sort-option-select", children: "Sort Ordering" }), jsxRuntimeExports.jsx(TableCell$1, { children: jsxRuntimeExports.jsx(OptionSelect, { className: classes.select, value: featureListSort, onChange: handleFeatureListSortChange, inputProps: {
196849
+ id: "feature-list-sort-option-select"
196850
+ }, children: FEATURELIST_SORT_OPTIONS.map((option) => jsxRuntimeExports.jsx("option", { value: option, children: option }, option)) }) })] }), hasFeatureLabels ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, htmlFor: "feature-list-sort-key-select", children: "Sort Key" }), jsxRuntimeExports.jsx(TableCell$1, { children: jsxRuntimeExports.jsx(OptionSelect, { className: classes.select, disabled: featureListSort === "original", value: featureListSortKey, onChange: handleFeatureListSortKeyChange, inputProps: {
196851
+ id: "feature-list-sort-key-select"
196852
+ }, children: hasFeatureLabels ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsx("option", { value: "featureLabels", children: primaryColumnName }), jsxRuntimeExports.jsx("option", { value: "featureIndex", children: ALT_COLNAME })] }) : jsxRuntimeExports.jsx("option", { value: "featureIndex", children: primaryColumnName }) }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, children: "Show Alternate IDs" }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, children: jsxRuntimeExports.jsx(Checkbox$1, { className: classes.tableCheckbox, checked: showFeatureTable, onChange: handleShowTableChange, name: "feature-list-show-table", color: "default" }) })] })] }) : null] });
196853
+ }
196780
196854
  function FeatureListSubscriber(props2) {
196781
- const { coordinationScopes, removeGridComponent, variablesLabelOverride, theme, title: titleOverride, enableMultiSelect = false, showTable = false, sort: sort2 = "alphabetical" } = props2;
196855
+ const { coordinationScopes, removeGridComponent, variablesLabelOverride, theme, title: titleOverride, enableMultiSelect = false, showTable = false, sort: sort2 = "alphabetical", sortKey: sortKey2 = null } = props2;
196782
196856
  const loaders = useLoaders();
196783
196857
  const [{ dataset, featureType, featureSelection: geneSelection, featureFilter: geneFilter, obsColorEncoding: cellColorEncoding }, { setFeatureSelection: setGeneSelection, setFeatureFilter: setGeneFilter, setFeatureHighlight: setGeneHighlight, setObsColorEncoding: setCellColorEncoding }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_LIST], coordinationScopes);
196784
196858
  const variablesLabel = variablesLabelOverride || featureType;
196785
196859
  const title2 = titleOverride || `${capitalize$2(variablesLabel)} List`;
196786
- const [urls2, addUrl2] = useUrls(loaders, dataset);
196787
- const [{ featureLabelsMap }, featureLabelsStatus] = useFeatureLabelsData(loaders, dataset, addUrl2, false, {}, {}, { featureType });
196788
- const [{ featureIndex }, matrixIndicesStatus] = useObsFeatureMatrixIndices(loaders, dataset, addUrl2, true, { featureType });
196860
+ const [{ featureLabelsMap }, featureLabelsStatus, featureLabelsUrls] = useFeatureLabelsData(loaders, dataset, false, {}, {}, { featureType });
196861
+ const [{ featureIndex }, matrixIndicesStatus, obsFeatureMatrixUrls] = useObsFeatureMatrixIndices(loaders, dataset, true, { featureType });
196789
196862
  const isReady = useReady([
196790
196863
  featureLabelsStatus,
196791
196864
  matrixIndicesStatus
196792
196865
  ]);
196866
+ const urls2 = useUrls([
196867
+ featureLabelsUrls,
196868
+ obsFeatureMatrixUrls
196869
+ ]);
196793
196870
  const geneList = featureIndex || [];
196794
196871
  const numGenes = geneList.length;
196872
+ const hasFeatureLabels = Boolean(featureLabelsMap);
196795
196873
  function setGeneSelectionAndColorEncoding(newSelection) {
196796
196874
  setGeneSelection(newSelection);
196797
196875
  setCellColorEncoding("geneSelection");
196798
196876
  }
196877
+ const [showFeatureTable, setShowFeatureTable] = useState(showTable);
196878
+ const [featureListSort, setFeatureListSort] = useState(sort2);
196879
+ const [featureListSortKey, setFeatureListSortKey] = useState(null);
196880
+ const initialSortKey = sortKey2 || (hasFeatureLabels ? "featureLabels" : "featureIndex");
196881
+ const primaryColumnName = `${capitalize$2(featureType)} ID`;
196799
196882
  return jsxRuntimeExports.jsx(TitleInfo, {
196800
196883
  title: title2,
196801
196884
  info: `${commaNumber(numGenes)} ${plur(variablesLabel, numGenes)}`,
@@ -196807,7 +196890,8 @@ function FeatureListSubscriber(props2) {
196807
196890
  removeGridComponent,
196808
196891
  isReady,
196809
196892
  urls: urls2,
196810
- children: jsxRuntimeExports.jsx(FeatureList, { hasColorEncoding: cellColorEncoding === "geneSelection", showTable, geneList, sort: sort2, featureLabelsMap, featureType, geneSelection, geneFilter, setGeneSelection: setGeneSelectionAndColorEncoding, setGeneFilter, setGeneHighlight, enableMultiSelect })
196893
+ options: jsxRuntimeExports.jsx(FeatureListOptions, { featureListSort, setFeatureListSort, featureListSortKey: featureListSortKey || initialSortKey, setFeatureListSortKey, showFeatureTable, setShowFeatureTable, hasFeatureLabels: Boolean(featureLabelsMap), primaryColumnName }),
196894
+ children: jsxRuntimeExports.jsx(FeatureList, { hasColorEncoding: cellColorEncoding === "geneSelection", showFeatureTable, geneList, featureListSort, featureListSortKey: featureListSortKey || initialSortKey, featureLabelsMap, featureType, geneSelection, geneFilter, setGeneSelection: setGeneSelectionAndColorEncoding, setGeneFilter, setGeneHighlight, enableMultiSelect, hasFeatureLabels: Boolean(featureLabelsMap), primaryColumnName })
196811
196895
  });
196812
196896
  }
196813
196897
  const useSpanStyles = makeStyles(() => ({
@@ -196830,45 +196914,22 @@ const useSelectStyles = makeStyles(() => ({
196830
196914
  margin: "4px 0"
196831
196915
  }
196832
196916
  }));
196833
- withStyles2((theme) => ({
196834
- paper: {
196835
- backgroundColor: theme.palette.background.paper
196836
- },
196837
- span: {
196838
- width: "70px",
196839
- textAlign: "center",
196840
- paddingLeft: "2px",
196841
- paddingRight: "2px"
196842
- },
196843
- colors: {
196844
- "&:hover": {
196845
- backgroundColor: "transparent"
196846
- },
196847
- paddingLeft: "2px",
196848
- paddingRight: "2px"
196849
- },
196850
- popper: {
196851
- zIndex: 4
196852
- }
196853
- }));
196854
196917
  const sharedControllerStyles = {
196855
196918
  width: "100%",
196856
196919
  flexDirection: "column"
196857
196920
  };
196858
196921
  const useControllerSectionStyles = makeStyles(() => ({
196859
- root: {
196922
+ layerControllerRoot: {
196860
196923
  ...sharedControllerStyles,
196861
196924
  padding: "0px 8px"
196862
196925
  }
196863
196926
  }));
196864
- const StyledAccordionDetails = withStyles2(() => ({
196865
- root: {
196927
+ const useAccordionStyles = makeStyles((theme) => ({
196928
+ accordionDetailsRoot: {
196866
196929
  ...sharedControllerStyles,
196867
196930
  padding: "8px 8px 24px 8px"
196868
- }
196869
- }))(AccordionDetails$1);
196870
- const StyledAccordionSummary = withStyles2((theme) => ({
196871
- root: {
196931
+ },
196932
+ accordionSummaryRoot: {
196872
196933
  padding: "0px 8px"
196873
196934
  },
196874
196935
  content: {
@@ -196884,30 +196945,30 @@ const StyledAccordionSummary = withStyles2((theme) => ({
196884
196945
  top: theme.spacing(-1.3)
196885
196946
  }
196886
196947
  }
196887
- }))(AccordionSummary$1);
196888
- const StyledInputLabel = withStyles2(() => ({
196889
- root: {
196948
+ }));
196949
+ const useInputLabelStyles = makeStyles(() => ({
196950
+ inputLabelRoot: {
196890
196951
  fontSize: "14px"
196891
196952
  }
196892
- }))(InputLabel$1);
196893
- const OverflowEllipsisGrid = withStyles2(() => ({
196953
+ }));
196954
+ const useOverflowEllipsisGridStyles = makeStyles(() => ({
196894
196955
  item: {
196895
196956
  width: "100%",
196896
196957
  overflow: "hidden",
196897
196958
  whiteSpace: "nowrap",
196898
196959
  textOverflow: "ellipsis"
196899
196960
  }
196900
- }))(Grid$3);
196901
- const StyledSelectionSlider = withStyles2(() => ({
196902
- root: {
196961
+ }));
196962
+ const useSelectionSliderStyles = makeStyles(() => ({
196963
+ selectionSliderRoot: {
196903
196964
  marginTop: "7px"
196904
196965
  },
196905
196966
  markActive: {
196906
196967
  backgroundColor: "rgba(128, 128, 128, 0.7)"
196907
196968
  }
196908
- }))(Slider$1);
196969
+ }));
196909
196970
  const useStyles$6 = makeStyles((theme) => ({
196910
- container: {
196971
+ paletteContainer: {
196911
196972
  width: "70px",
196912
196973
  height: "40px",
196913
196974
  display: "flex",
@@ -196928,7 +196989,7 @@ const useStyles$6 = makeStyles((theme) => ({
196928
196989
  }));
196929
196990
  const ColorPalette = ({ handleChange }) => {
196930
196991
  const classes = useStyles$6();
196931
- return jsxRuntimeExports.jsx("div", { className: classes.container, "aria-label": "color-swatch", children: VIEWER_PALETTE.map((color2) => jsxRuntimeExports.jsx(IconButton$2, { className: classes.button, onClick: () => handleChange(color2), children: jsxRuntimeExports.jsx(LensIcon, { fontSize: "small", style: { color: `rgb(${color2})` }, className: classes.icon }) }, color2)) });
196992
+ return jsxRuntimeExports.jsx("div", { className: classes.paletteContainer, "aria-label": "color-swatch", children: VIEWER_PALETTE.map((color2) => jsxRuntimeExports.jsx(IconButton$2, { className: classes.button, onClick: () => handleChange(color2), children: jsxRuntimeExports.jsx(LensIcon, { fontSize: "small", style: { color: `rgb(${color2})` }, className: classes.icon }) }, color2)) });
196932
196993
  };
196933
196994
  const useStyles$5 = makeStyles(() => ({
196934
196995
  menuButton: {
@@ -197179,7 +197240,7 @@ function VectorLayerController(props2) {
197179
197240
  handleLayerChange({ ...layer, visible: v });
197180
197241
  }
197181
197242
  const classes = useControllerSectionStyles();
197182
- return jsxRuntimeExports.jsx(Grid$3, { item: true, style: { marginTop: "10px" }, children: jsxRuntimeExports.jsxs(Paper$1, { className: classes.root, children: [jsxRuntimeExports.jsx(Typography$1, { style: {
197243
+ return jsxRuntimeExports.jsx(Grid$3, { item: true, style: { marginTop: "10px" }, children: jsxRuntimeExports.jsxs(Paper$1, { className: classes.layerControllerRoot, children: [jsxRuntimeExports.jsx(Typography$1, { style: {
197183
197244
  padding: "15px 8px 0px 8px",
197184
197245
  marginBottom: "-5px"
197185
197246
  }, children: label2 }), jsxRuntimeExports.jsxs(Grid$3, { container: true, direction: "row", justifyContent: "space-between", children: [jsxRuntimeExports.jsx(Grid$3, { item: true, xs: 2, children: jsxRuntimeExports.jsx(Checkbox$1, { color: "primary", checked: isOn, onChange: (e3, v) => handleCheckBoxChange(v) }) }), jsxRuntimeExports.jsx(Grid$3, { item: true, xs: 9, style: { paddingRight: "8px" }, children: jsxRuntimeExports.jsx(Slider$1, { value: slider, min: 0, max: 1, step: 1e-3, onChange: (e3, v) => handleSliderChange(v), style: { marginTop: "7px" }, orientation: "horizontal" }) })] })] }) });
@@ -197281,7 +197342,9 @@ function SliderDomainSelector({ value: value2, inputId, handleChange }) {
197281
197342
  return jsxRuntimeExports.jsx(Select$1, { native: true, onChange: (e3) => handleChange(e3.target.value), value: value2, inputProps: { name: "domain-selector", id: inputId }, style: { width: "100%" }, classes: { root: classes.selectRoot }, children: DOMAIN_OPTIONS.map((name2) => jsxRuntimeExports.jsx("option", { value: name2, children: name2 }, name2)) });
197282
197343
  }
197283
197344
  function GlobalSelectionSlider({ field: field2, value: value2, handleChange, possibleValues }) {
197284
- return jsxRuntimeExports.jsx(StyledSelectionSlider, {
197345
+ const classes = useSelectionSliderStyles();
197346
+ return jsxRuntimeExports.jsx(Slider$1, {
197347
+ classes: { root: classes.selectionSliderRoot, markActive: classes.markActive },
197285
197348
  value: value2,
197286
197349
  // See https://github.com/hms-dbmi/viv/issues/176 for why
197287
197350
  // we have the two handlers.
@@ -197594,6 +197657,9 @@ function LayerController(props2) {
197594
197657
  );
197595
197658
  }
197596
197659
  const controllerSectionClasses = useControllerSectionStyles();
197660
+ const accordionClasses = useAccordionStyles();
197661
+ const inputLabelClasses = useInputLabelStyles();
197662
+ const overflowEllipsisGridClasses = useOverflowEllipsisGridStyles();
197597
197663
  const { visible } = layer;
197598
197664
  const visibleSetting = typeof visible === "boolean" ? visible : true;
197599
197665
  const Visibility = visibleSetting ? VisibilityIcon : VisibilityOffIcon;
@@ -197632,10 +197698,15 @@ function LayerController(props2) {
197632
197698
  spatialWidth,
197633
197699
  modelMatrix: modelMatrix2
197634
197700
  }), isRgb(loader2, channels2) && disableChannelsIfRgbDetected ? null : channelControllers, isRgb(loader2, channels2) && disableChannelsIfRgbDetected ? null : jsxRuntimeExports.jsx(Button$1, { disabled: channels2.length === MAX_CHANNELS, onClick: handleChannelAdd, fullWidth: true, variant: "outlined", style: buttonStyles, startIcon: jsxRuntimeExports.jsx(AddIcon, {}), size: "small", children: "Add Channel" })] });
197635
- return jsxRuntimeExports.jsxs(Accordion$1, { className: controllerSectionClasses.root, onChange: (e3, expanded) => {
197701
+ return jsxRuntimeExports.jsxs(Accordion$1, { className: controllerSectionClasses.layerControllerRoot, onChange: (e3, expanded) => {
197636
197702
  var _a3, _b, _c;
197637
197703
  return !disabled && setIsExpanded(expanded && ((_c = (_b = (_a3 = e3 == null ? void 0 : e3.target) == null ? void 0 : _a3.attributes) == null ? void 0 : _b.role) == null ? void 0 : _c.value) === "presentation");
197638
- }, TransitionProps: { enter: false }, expanded: !disabled && isExpanded, children: [jsxRuntimeExports.jsx(StyledAccordionSummary, { expandIcon: jsxRuntimeExports.jsx(ExpandMoreIcon, { role: "presentation" }), "aria-controls": `layer-${name2}-controls`, children: jsxRuntimeExports.jsxs(Grid$3, { container: true, direction: "column", m: 1, justifyContent: "center", children: [jsxRuntimeExports.jsxs(OverflowEllipsisGrid, { item: true, children: [jsxRuntimeExports.jsx(Button$1, { onClick: (e3) => {
197704
+ }, TransitionProps: { enter: false }, expanded: !disabled && isExpanded, children: [jsxRuntimeExports.jsx(AccordionSummary$1, { classes: {
197705
+ root: accordionClasses.accordionSummaryRoot,
197706
+ content: accordionClasses.content,
197707
+ expanded: accordionClasses.expanded,
197708
+ expandIcon: accordionClasses.expandIcon
197709
+ }, expandIcon: jsxRuntimeExports.jsx(ExpandMoreIcon, { role: "presentation" }), "aria-controls": `layer-${name2}-controls`, children: jsxRuntimeExports.jsxs(Grid$3, { container: true, direction: "column", m: 1, justifyContent: "center", children: [jsxRuntimeExports.jsxs(Grid$3, { item: true, classes: { item: overflowEllipsisGridClasses.item }, children: [jsxRuntimeExports.jsx(Button$1, { onClick: (e3) => {
197639
197710
  if (!disabled) {
197640
197711
  e3.stopPropagation();
197641
197712
  const nextVisible = typeof visible === "boolean" ? !visible : false;
@@ -197646,7 +197717,7 @@ function LayerController(props2) {
197646
197717
  marginBottom: 2,
197647
197718
  padding: 0,
197648
197719
  minWidth: 0
197649
- }, children: jsxRuntimeExports.jsx(Visibility, {}) }), name2] }), !disabled && !isExpanded && !use3d && jsxRuntimeExports.jsxs(Grid$3, { container: true, direction: "row", alignItems: "center", justifyContent: "center", children: [jsxRuntimeExports.jsx(Grid$3, { item: true, xs: 6, children: jsxRuntimeExports.jsx(StyledInputLabel, { htmlFor: `layer-${name2}-opacity-closed`, children: "Opacity:" }) }), jsxRuntimeExports.jsx(Grid$3, { item: true, xs: 6, children: jsxRuntimeExports.jsx(Slider$1, { id: `layer-${name2}-opacity-closed`, value: opacity2, onChange: (e3, v) => setOpacity(v), valueLabelDisplay: "auto", getAriaLabel: () => "opacity slider", min: 0, max: 1, step: 0.01, orientation: "horizontal" }) })] })] }) }), jsxRuntimeExports.jsxs(StyledAccordionDetails, { children: [useVolumeTabs ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs(Tabs$1, { value: tab, onChange: handleTabChange, "aria-label": "simple tabs example", style: { height: "24px", minHeight: "24px" }, children: [jsxRuntimeExports.jsx(Tab$1, { label: "Channels", style: {
197720
+ }, children: jsxRuntimeExports.jsx(Visibility, {}) }), name2] }), !disabled && !isExpanded && !use3d && jsxRuntimeExports.jsxs(Grid$3, { container: true, direction: "row", alignItems: "center", justifyContent: "center", children: [jsxRuntimeExports.jsx(Grid$3, { item: true, xs: 6, children: jsxRuntimeExports.jsx(InputLabel$1, { htmlFor: `layer-${name2}-opacity-closed`, classes: { root: inputLabelClasses.inputLabelRoot }, children: "Opacity:" }) }), jsxRuntimeExports.jsx(Grid$3, { item: true, xs: 6, children: jsxRuntimeExports.jsx(Slider$1, { id: `layer-${name2}-opacity-closed`, value: opacity2, onChange: (e3, v) => setOpacity(v), valueLabelDisplay: "auto", getAriaLabel: () => "opacity slider", min: 0, max: 1, step: 0.01, orientation: "horizontal" }) })] })] }) }), jsxRuntimeExports.jsxs(AccordionDetails$1, { classes: { root: accordionClasses.accordionDetailsRoot }, children: [useVolumeTabs ? jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs(Tabs$1, { value: tab, onChange: handleTabChange, "aria-label": "simple tabs example", style: { height: "24px", minHeight: "24px" }, children: [jsxRuntimeExports.jsx(Tab$1, { label: "Channels", style: {
197650
197721
  fontSize: ".75rem",
197651
197722
  bottom: 12,
197652
197723
  width: "50%",
@@ -197850,12 +197921,9 @@ function LayerControllerSubscriber(props2) {
197850
197921
  const layerControllerRef = useRef();
197851
197922
  const [componentWidth, componentHeight] = useClosestVitessceContainerSize(layerControllerRef);
197852
197923
  const { height: windowHeight, width: windowWidth } = useWindowDimensions();
197853
- const [obsLocationsData, obsLocationsStatus] = useObsLocationsData(loaders, dataset, () => {
197854
- }, false, { setSpatialPointLayer: setMoleculesLayer }, { spatialPointLayer: moleculesLayer }, {});
197855
- const [{ obsSegmentations, obsSegmentationsType }, obsSegmentationsStatus] = useObsSegmentationsData(loaders, dataset, () => {
197856
- }, false, { setSpatialSegmentationLayer: setCellsLayer }, { spatialSegmentationLayer: cellsLayer }, {});
197857
- const [{ image: image2 }, imageStatus] = useImageData(loaders, dataset, () => {
197858
- }, false, { setSpatialImageLayer: setRasterLayers }, { spatialImageLayer: rasterLayers }, {});
197924
+ const [obsLocationsData, obsLocationsStatus] = useObsLocationsData(loaders, dataset, false, { setSpatialPointLayer: setMoleculesLayer }, { spatialPointLayer: moleculesLayer }, {});
197925
+ const [{ obsSegmentations, obsSegmentationsType }, obsSegmentationsStatus] = useObsSegmentationsData(loaders, dataset, false, { setSpatialSegmentationLayer: setCellsLayer }, { spatialSegmentationLayer: cellsLayer }, {});
197926
+ const [{ image: image2 }, imageStatus] = useImageData(loaders, dataset, false, { setSpatialImageLayer: setRasterLayers }, { spatialImageLayer: rasterLayers }, {});
197859
197927
  const { loaders: imageLayerLoaders, meta: imageLayerMeta } = image2 || {};
197860
197928
  const isReady = useReady([
197861
197929
  obsLocationsStatus,
@@ -198472,7 +198540,7 @@ const HIGLASS_BUNDLE_VERSION = "1.11.13";
198472
198540
  const HIGLASS_CSS_URL = `https://unpkg.com/${HIGLASS_PKG_NAME}@${HIGLASS_BUNDLE_VERSION}/dist/hglib.css`;
198473
198541
  register({ dataFetcher: ZarrMultivecDataFetcher, config: ZarrMultivecDataFetcher.config }, { pluginType: "dataFetcher" });
198474
198542
  const LazyHiGlassComponent = React__default.lazy(async () => {
198475
- const { HiGlassComponent } = await import("./hglib-1422f224.js").then((n3) => n3.h);
198543
+ const { HiGlassComponent } = await import("./hglib-76c1b0ad.js").then((n3) => n3.h);
198476
198544
  return { default: HiGlassComponent };
198477
198545
  });
198478
198546
  const HG_SIZE = 800;
@@ -198629,9 +198697,9 @@ function GenomicProfilesSubscriber(props2) {
198629
198697
  const [width2, height2, containerRef] = useGridItemSize();
198630
198698
  const loaders = useLoaders();
198631
198699
  const [{ dataset, obsSetColor: cellSetColor, obsSetSelection: cellSetSelection }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.GENOMIC_PROFILES], coordinationScopes);
198632
- const [urls2, addUrl2] = useUrls(loaders, dataset);
198633
- const [genomicProfilesAttrs, genomicProfilesStatus] = useGenomicProfilesData(loaders, dataset, addUrl2, true, {}, {}, {});
198700
+ const [genomicProfilesAttrs, genomicProfilesStatus, genomicProfilesUrls] = useGenomicProfilesData(loaders, dataset, true, {}, {}, {});
198634
198701
  const isReady = useReady([genomicProfilesStatus]);
198702
+ const urls2 = useUrls([genomicProfilesUrls]);
198635
198703
  const hgViewConfig = useMemo(() => {
198636
198704
  if (!genomicProfilesAttrs || urls2.length !== 1) {
198637
198705
  return null;
@@ -255485,18 +255553,22 @@ function CellSetExpressionPlotSubscriber(props2) {
255485
255553
  const loaders = useLoaders();
255486
255554
  const [{ dataset, obsType, featureType, featureValueType, featureSelection: geneSelection, featureValueTransform, featureValueTransformCoefficient, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets }, { setFeatureValueTransform, setFeatureValueTransformCoefficient }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.OBS_SET_FEATURE_VALUE_DISTRIBUTION], coordinationScopes);
255487
255555
  const [width2, height2, containerRef] = useGridItemSize();
255488
- const [urls2, addUrl2] = useUrls(loaders, dataset);
255489
255556
  const transformOptions = VALUE_TRANSFORM_OPTIONS;
255490
255557
  const [expressionData, loadedFeatureSelection, featureSelectionStatus] = useFeatureSelection(loaders, dataset, false, geneSelection, { obsType, featureType, featureValueType });
255491
- const [{ featureLabelsMap }, featureLabelsStatus] = useFeatureLabelsData(loaders, dataset, addUrl2, false, {}, {}, { featureType });
255492
- const [{ obsIndex }, matrixIndicesStatus] = useObsFeatureMatrixIndices(loaders, dataset, addUrl2, false, { obsType, featureType, featureValueType });
255493
- const [{ obsSets: cellSets }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, true, {}, {}, { obsType });
255558
+ const [{ featureLabelsMap }, featureLabelsStatus, featureLabelsUrls] = useFeatureLabelsData(loaders, dataset, false, {}, {}, { featureType });
255559
+ const [{ obsIndex }, matrixIndicesStatus, matrixIndicesUrls] = useObsFeatureMatrixIndices(loaders, dataset, false, { obsType, featureType, featureValueType });
255560
+ const [{ obsSets: cellSets }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, true, {}, {}, { obsType });
255494
255561
  const isReady = useReady([
255495
255562
  featureSelectionStatus,
255496
255563
  matrixIndicesStatus,
255497
255564
  obsSetsStatus,
255498
255565
  featureLabelsStatus
255499
255566
  ]);
255567
+ const urls2 = useUrls([
255568
+ featureLabelsUrls,
255569
+ matrixIndicesUrls,
255570
+ obsSetsUrls
255571
+ ]);
255500
255572
  const [expressionArr, setArr, expressionMax] = useExpressionByCellSet(expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme);
255501
255573
  const firstGeneSelected = geneSelection && geneSelection.length >= 1 ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(geneSelection[0])) || geneSelection[0] : null;
255502
255574
  const selectedTransformName = (_a2 = transformOptions.find((o2) => o2.value === featureValueTransform)) == null ? void 0 : _a2.name;
@@ -255626,13 +255698,11 @@ function CellSetSizesPlotSubscriber(props2) {
255626
255698
  const [{ dataset, obsType, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets, obsSetExpansion: cellSetExpansion }, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.OBS_SET_SIZES], coordinationScopes);
255627
255699
  const title2 = titleOverride || `${capitalize$2(obsType)} Set Sizes`;
255628
255700
  const [width2, height2, containerRef] = useGridItemSize();
255629
- const [urls2, addUrl2] = useUrls(loaders, dataset);
255630
255701
  const [currentHierarchy, setCurrentHierarchy] = useState([]);
255631
255702
  const [prevCellSetSelection, setPrevCellSetSelection] = useState([]);
255632
- const [{ obsSets: cellSets }, obsSetsStatus] = useObsSetsData(loaders, dataset, addUrl2, true, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
255633
- const isReady = useReady([
255634
- obsSetsStatus
255635
- ]);
255703
+ const [{ obsSets: cellSets }, obsSetsStatus, obsSetsUrls] = useObsSetsData(loaders, dataset, true, { setObsSetSelection: setCellSetSelection, setObsSetColor: setCellSetColor }, { obsSetSelection: cellSetSelection, obsSetColor: cellSetColor }, { obsType });
255704
+ const isReady = useReady([obsSetsStatus]);
255705
+ const urls2 = useUrls([obsSetsUrls]);
255636
255706
  const mergedCellSets = useMemo(() => mergeObsSets(cellSets, additionalCellSets), [cellSets, additionalCellSets]);
255637
255707
  const data2 = useMemo(() => {
255638
255708
  if (cellSetSelection && cellSetColor && mergedCellSets && cellSets) {
@@ -255732,13 +255802,15 @@ function ExpressionHistogramSubscriber(props2) {
255732
255802
  const loaders = useLoaders();
255733
255803
  const [{ dataset, obsType, featureType, featureValueType, featureSelection: geneSelection, additionalObsSets: additionalCellSets, obsSetColor: cellSetColor }, { setAdditionalObsSets: setAdditionalCellSets, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setObsSetSelection: setCellSetSelection }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_VALUE_HISTOGRAM], coordinationScopes);
255734
255804
  const [width2, height2, containerRef] = useGridItemSize();
255735
- const [urls2, addUrl2] = useUrls(loaders, dataset);
255736
- const [{ obsIndex, featureIndex, obsFeatureMatrix }, matrixStatus] = useObsFeatureMatrixData(loaders, dataset, addUrl2, true, {}, {}, { obsType, featureType, featureValueType });
255805
+ const [{ obsIndex, featureIndex, obsFeatureMatrix }, matrixStatus, matrixUrls] = useObsFeatureMatrixData(loaders, dataset, true, {}, {}, { obsType, featureType, featureValueType });
255737
255806
  const [expressionData, loadedFeatureSelection, featureSelectionStatus] = useFeatureSelection(loaders, dataset, false, geneSelection, { obsType, featureType, featureValueType });
255738
255807
  const isReady = useReady([
255739
255808
  matrixStatus,
255740
255809
  featureSelectionStatus
255741
255810
  ]);
255811
+ const urls2 = useUrls([
255812
+ matrixUrls
255813
+ ]);
255742
255814
  const firstGeneSelected = geneSelection && geneSelection.length >= 1 ? geneSelection[0] : null;
255743
255815
  const data2 = useMemo(() => {
255744
255816
  if (firstGeneSelected && obsFeatureMatrix && expressionData) {
@@ -256409,6 +256481,33 @@ async function initLoader(imageData) {
256409
256481
  const channels2 = Array.isArray(Channels) ? Channels.map((channel, i2) => channel.Name || `Channel ${i2}`) : [Channels.Name || `Channel ${0}`];
256410
256482
  return { ...loader2, channels: channels2 };
256411
256483
  }
256484
+ case "ome-zarr": {
256485
+ const { coordinateTransformations: coordinateTransformationsFromOptions } = metadata2 || {};
256486
+ const loader2 = await loadOmeZarr(url, { fetchOptions: requestInit2, type: "multiscales" });
256487
+ const { metadata: loaderMetadata } = loader2;
256488
+ const { omero, multiscales } = loaderMetadata;
256489
+ if (!Array.isArray(multiscales) || multiscales.length === 0) {
256490
+ console.error("Multiscales array must exist and have at least one element");
256491
+ }
256492
+ const { coordinateTransformations } = multiscales[0];
256493
+ const axes = getNgffAxes(multiscales[0].axes);
256494
+ const transformMatrixFromOptions = coordinateTransformationsToMatrix(coordinateTransformationsFromOptions, axes);
256495
+ const transformMatrixFromFile = coordinateTransformationsToMatrix(coordinateTransformations, axes);
256496
+ const transformMatrix = transformMatrixFromFile.multiplyLeft(transformMatrixFromOptions);
256497
+ const { channels: channels2, name: omeroName } = omero;
256498
+ return {
256499
+ name: omeroName || "Image",
256500
+ channels: channels2.map((c2, i2) => c2.label || `Channel ${i2}`),
256501
+ ...transformMatrix ? {
256502
+ metadata: {
256503
+ transform: {
256504
+ matrix: transformMatrix
256505
+ }
256506
+ }
256507
+ } : {},
256508
+ ...loader2
256509
+ };
256510
+ }
256412
256511
  default: {
256413
256512
  throw Error(`Image type (${type2}) is not supported`);
256414
256513
  }
@@ -256430,7 +256529,7 @@ class RasterLoader extends JsonLoader {
256430
256529
  }
256431
256530
  const { data: raster } = payload;
256432
256531
  const { images, renderLayers, usePhysicalSizeScaling = false } = raster;
256433
- const urls2 = images.filter((image2) => !image2.url.includes("zarr")).map((image2) => [image2.url, image2.name]);
256532
+ const urls2 = images.filter((image2) => !image2.url.includes("zarr")).map((image2) => ({ url: image2.url, name: image2.name }));
256434
256533
  const imagesWithLoaderCreators = images.map((image2) => ({
256435
256534
  ...image2,
256436
256535
  loaderCreator: async () => initLoader(image2)
@@ -257492,9 +257591,6 @@ class OmeTiffLoader extends AbstractTwoStepLoader {
257492
257591
  async load() {
257493
257592
  const { url, requestInit: requestInit2 } = this;
257494
257593
  const { coordinateTransformations: coordinateTransformationsFromOptions } = this.options || {};
257495
- const urls2 = [
257496
- [url, "image"]
257497
- ];
257498
257594
  const offsets2 = await this.loadOffsets();
257499
257595
  const loader2 = await loadOmeTiff(url, { offsets: offsets2, headers: requestInit2 == null ? void 0 : requestInit2.headers });
257500
257596
  const { Name: imageName, Pixels: { Channels, DimensionOrder, PhysicalSizeX, PhysicalSizeXUnit, PhysicalSizeY, PhysicalSizeYUnit } } = loader2.metadata;
@@ -257513,6 +257609,9 @@ class OmeTiffLoader extends AbstractTwoStepLoader {
257513
257609
  }
257514
257610
  } : {}
257515
257611
  };
257612
+ const urls2 = [
257613
+ { url, name: image2.name }
257614
+ ];
257516
257615
  const imagesWithLoaderCreators = [
257517
257616
  {
257518
257617
  ...image2,
@@ -257542,7 +257641,6 @@ class OmeTiffAsObsSegmentationsLoader extends OmeTiffLoader {
257542
257641
  const offsets2 = await this.loadOffsets();
257543
257642
  const loader2 = await loadOmeTiff(url, { offsets: offsets2, headers: requestInit2 == null ? void 0 : requestInit2.headers });
257544
257643
  const { Name: imageName, Pixels: { Channels, DimensionOrder, PhysicalSizeX, PhysicalSizeXUnit, PhysicalSizeY, PhysicalSizeYUnit } } = loader2.metadata;
257545
- const urls2 = [url, "OME-TIFF"];
257546
257644
  const transformMatrixFromOptions = coordinateTransformationsToMatrix(coordinateTransformationsFromOptions, getNgffAxesForTiff(DimensionOrder));
257547
257645
  const usePhysicalSizeScaling = PhysicalSizeX && PhysicalSizeXUnit && PhysicalSizeY && PhysicalSizeYUnit;
257548
257646
  const image2 = {
@@ -257559,6 +257657,7 @@ class OmeTiffAsObsSegmentationsLoader extends OmeTiffLoader {
257559
257657
  } : {}
257560
257658
  }
257561
257659
  };
257660
+ const urls2 = [{ url, name: image2.name }];
257562
257661
  const imagesWithLoaderCreators = [
257563
257662
  {
257564
257663
  ...image2,
@@ -258208,10 +258307,11 @@ function Vitessce(props2) {
258208
258307
  pluginCoordinationTypes: pluginCoordinationTypesProp,
258209
258308
  pluginJointFileTypes: pluginJointFileTypesProp
258210
258309
  } = props2;
258211
- const configUid = config3 == null ? void 0 : config3.uid;
258310
+ const configKey = (config3 == null ? void 0 : config3.uid) || config3;
258212
258311
  const configVersion = config3 == null ? void 0 : config3.version;
258213
258312
  const [configOrWarning, success] = useMemo(() => {
258214
258313
  try {
258314
+ logConfig(config3, "pre-upgrade view config");
258215
258315
  const validConfig = upgradeAndParse(config3, onConfigUpgrade);
258216
258316
  return [validConfig, true];
258217
258317
  } catch (e3) {
@@ -258224,7 +258324,7 @@ function Vitessce(props2) {
258224
258324
  false
258225
258325
  ];
258226
258326
  }
258227
- }, [configUid, configVersion]);
258327
+ }, [configKey, configVersion]);
258228
258328
  const mergedPluginViewTypes = useMemo(() => [
258229
258329
  ...baseViewTypes,
258230
258330
  ...pluginViewTypesProp || []