@vitessce/all 3.5.10 → 3.5.11

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.
@@ -10466,6 +10466,7 @@ const CoordinationType$1 = {
10466
10466
  FEATURE_VALUE_COLORMAP: "featureValueColormap",
10467
10467
  FEATURE_VALUE_TRANSFORM: "featureValueTransform",
10468
10468
  FEATURE_VALUE_COLORMAP_RANGE: "featureValueColormapRange",
10469
+ FEATURE_AGGREGATION_STRATEGY: "featureAggregationStrategy",
10469
10470
  OBS_COLOR_ENCODING: "obsColorEncoding",
10470
10471
  SPATIAL_IMAGE_LAYER: "spatialImageLayer",
10471
10472
  SPATIAL_SEGMENTATION_LAYER: "spatialSegmentationLayer",
@@ -10691,6 +10692,7 @@ const COMPONENT_COORDINATION_TYPES = {
10691
10692
  CoordinationType$1.FEATURE_SELECTION,
10692
10693
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
10693
10694
  CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
10695
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10694
10696
  CoordinationType$1.OBS_COLOR_ENCODING,
10695
10697
  CoordinationType$1.ADDITIONAL_OBS_SETS,
10696
10698
  CoordinationType$1.TOOLTIPS_VISIBLE,
@@ -10734,6 +10736,7 @@ const COMPONENT_COORDINATION_TYPES = {
10734
10736
  CoordinationType$1.FEATURE_SELECTION,
10735
10737
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
10736
10738
  CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
10739
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10737
10740
  CoordinationType$1.OBS_COLOR_ENCODING,
10738
10741
  CoordinationType$1.ADDITIONAL_OBS_SETS,
10739
10742
  CoordinationType$1.TOOLTIPS_VISIBLE,
@@ -10813,6 +10816,7 @@ const COMPONENT_COORDINATION_TYPES = {
10813
10816
  CoordinationType$1.FEATURE_SELECTION,
10814
10817
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
10815
10818
  CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
10819
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10816
10820
  CoordinationType$1.OBS_COLOR_ENCODING,
10817
10821
  CoordinationType$1.ADDITIONAL_OBS_SETS,
10818
10822
  CoordinationType$1.MOLECULE_HIGHLIGHT,
@@ -10850,6 +10854,7 @@ const COMPONENT_COORDINATION_TYPES = {
10850
10854
  CoordinationType$1.FEATURE_SELECTION,
10851
10855
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
10852
10856
  CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
10857
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10853
10858
  CoordinationType$1.OBS_COLOR_ENCODING,
10854
10859
  CoordinationType$1.ADDITIONAL_OBS_SETS,
10855
10860
  CoordinationType$1.MOLECULE_HIGHLIGHT,
@@ -10963,6 +10968,7 @@ const COMPONENT_COORDINATION_TYPES = {
10963
10968
  CoordinationType$1.FEATURE_SELECTION,
10964
10969
  CoordinationType$1.FEATURE_VALUE_TRANSFORM,
10965
10970
  CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
10971
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10966
10972
  CoordinationType$1.OBS_SET_SELECTION,
10967
10973
  CoordinationType$1.OBS_SET_FILTER,
10968
10974
  CoordinationType$1.OBS_SET_HIGHLIGHT,
@@ -10978,6 +10984,7 @@ const COMPONENT_COORDINATION_TYPES = {
10978
10984
  CoordinationType$1.FEATURE_TYPE,
10979
10985
  CoordinationType$1.FEATURE_VALUE_TYPE,
10980
10986
  CoordinationType$1.FEATURE_SELECTION,
10987
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
10981
10988
  CoordinationType$1.ADDITIONAL_OBS_SETS,
10982
10989
  CoordinationType$1.OBS_SET_COLOR,
10983
10990
  CoordinationType$1.OBS_COLOR_ENCODING,
@@ -11056,6 +11063,7 @@ const COMPONENT_COORDINATION_TYPES = {
11056
11063
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
11057
11064
  CoordinationType$1.FEATURE_VALUE_COLORMAP_RANGE,
11058
11065
  CoordinationType$1.FEATURE_SELECTION,
11066
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
11059
11067
  CoordinationType$1.TOOLTIPS_VISIBLE,
11060
11068
  CoordinationType$1.TOOLTIP_CROSSHAIRS_VISIBLE,
11061
11069
  CoordinationType$1.LEGEND_VISIBLE,
@@ -11096,6 +11104,7 @@ const COMPONENT_COORDINATION_TYPES = {
11096
11104
  CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
11097
11105
  CoordinationType$1.FEATURE_VALUE_POSITIVITY_THRESHOLD,
11098
11106
  CoordinationType$1.FEATURE_VALUE_COLORMAP,
11107
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
11099
11108
  CoordinationType$1.OBS_SET_SELECTION,
11100
11109
  CoordinationType$1.OBS_SET_FILTER,
11101
11110
  CoordinationType$1.OBS_SET_HIGHLIGHT,
@@ -11124,6 +11133,7 @@ const COMPONENT_COORDINATION_TYPES = {
11124
11133
  CoordinationType$1.FEATURE_SELECTION,
11125
11134
  CoordinationType$1.FEATURE_VALUE_TRANSFORM,
11126
11135
  CoordinationType$1.FEATURE_VALUE_TRANSFORM_COEFFICIENT,
11136
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
11127
11137
  CoordinationType$1.OBS_SET_SELECTION,
11128
11138
  CoordinationType$1.OBS_SET_HIGHLIGHT,
11129
11139
  CoordinationType$1.OBS_HIGHLIGHT,
@@ -11228,6 +11238,7 @@ const COMPONENT_COORDINATION_TYPES = {
11228
11238
  CoordinationType$1.OBS_TYPE,
11229
11239
  CoordinationType$1.SAMPLE_TYPE,
11230
11240
  CoordinationType$1.FEATURE_SELECTION,
11241
+ CoordinationType$1.FEATURE_AGGREGATION_STRATEGY,
11231
11242
  CoordinationType$1.SAMPLE_SET_SELECTION,
11232
11243
  CoordinationType$1.SAMPLE_SET_FILTER,
11233
11244
  CoordinationType$1.OBS_SET_SELECTION,
@@ -11601,6 +11612,7 @@ const annDataFeatureSetStats = z.object({
11601
11612
  termColumn: z.string().optional(),
11602
11613
  pValueColumn: z.string(),
11603
11614
  pValueAdjusted: z.boolean().optional(),
11615
+ featureSetLibrary: z.string().optional().describe("Optionally, provide a feature set library name. By default, Reactome_2022."),
11604
11616
  analysisType: z.string().optional().describe("Optionally, provide an analysis_type name. By default, pertpy_hypergeometric.")
11605
11617
  });
11606
11618
  const annDataObsSetStats = z.object({
@@ -11611,7 +11623,6 @@ const annDataObsSetStats = z.object({
11611
11623
  foldChangeColumn: z.string().describe("The log-fold change is then calculated between this expected sample and the expected sample with no active covariates from the intercept section."),
11612
11624
  foldChangeTransformation: z.enum(["log2"]).optional(),
11613
11625
  isCredibleEffectColumn: z.string().describe("Column which annotates effects as being credible or not (boolean)."),
11614
- covariateColumn: z.string().describe("Column which defines the covariate used in the analysis."),
11615
11626
  analysisType: z.string().optional().describe("Optionally, provide an analysis_type name. By default, sccoda_df.")
11616
11627
  });
11617
11628
  const annDataObsLabels = annDataObs;
@@ -53362,7 +53373,7 @@ function getCellColors(params2) {
53362
53373
  }
53363
53374
  return /* @__PURE__ */ new Map();
53364
53375
  }
53365
- function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, obsIndex, mergedCellSets, cellSetSelection, arraysToStratify) {
53376
+ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, obsIndex, mergedCellSets, cellSetSelection, arraysToStratify, featureAggregationStrategy) {
53366
53377
  const result = new InternMap$1([], JSON.stringify);
53367
53378
  const hasSampleSetSelection = Array.isArray(sampleSetSelection) && sampleSetSelection.length > 0;
53368
53379
  const hasCellSetSelection = Array.isArray(cellSetSelection) && cellSetSelection.length > 0;
@@ -53372,9 +53383,13 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
53372
53383
  if (arrKeys.includes("obsIndex") || arrKeys.includes("i")) {
53373
53384
  throw new Error('The keys "obsIndex" and "i" are reserved for internal use.');
53374
53385
  }
53375
- if (Object.values(arraysToStratify).some((arr) => arr.length !== obsIndex.length)) {
53376
- throw new Error("All arrays must have the same length as the obsIndex.");
53377
- }
53386
+ if (Object.entries(arraysToStratify).some(([arrKey, arr]) => {
53387
+ if (arrKey === "featureValue") {
53388
+ return arr.some((a2) => a2.length !== obsIndex.length);
53389
+ }
53390
+ return arr.length !== obsIndex.length;
53391
+ }))
53392
+ ;
53378
53393
  const sampleSetInfo = sampleSets && sampleSetSelection ? treeToObsIdsBySetNames(sampleSets, sampleSetSelection) : null;
53379
53394
  const cellSetInfo = mergedCellSets && cellSetSelection ? treeToObsIdsBySetNames(mergedCellSets, cellSetSelection) : null;
53380
53395
  cellSetKeys.forEach((cellSetKey) => {
@@ -53404,6 +53419,7 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
53404
53419
  });
53405
53420
  const sampleIdToSetMap = sampleSets && sampleSetSelection ? treeToSelectedSetMap(sampleSets, sampleSetSelection) : null;
53406
53421
  const cellIdToSetMap = mergedCellSets && cellSetSelection ? treeToSelectedSetMap(mergedCellSets, cellSetSelection) : null;
53422
+ let cellCount = 0;
53407
53423
  for (let i2 = 0; i2 < obsIndex.length; i2 += 1) {
53408
53424
  const obsId = obsIndex[i2];
53409
53425
  const cellSet = (cellIdToSetMap == null ? void 0 : cellIdToSetMap.get(obsId)) || null;
@@ -53414,10 +53430,28 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
53414
53430
  }
53415
53431
  const insertionIndex = result.get(cellSet).get(sampleSet).get("i");
53416
53432
  arrKeys.forEach((arrKey) => {
53417
- const value2 = arraysToStratify[arrKey][i2];
53433
+ let value2;
53434
+ if (arrKey === "featureValue") {
53435
+ if (featureAggregationStrategy === "first") {
53436
+ value2 = arraysToStratify[arrKey][0][i2];
53437
+ } else if (featureAggregationStrategy === "last") {
53438
+ value2 = arraysToStratify[arrKey].at(-1)[i2];
53439
+ } else if (typeof featureAggregationStrategy === "number") {
53440
+ const j = featureAggregationStrategy;
53441
+ value2 = arraysToStratify[arrKey][j][i2];
53442
+ } else if (featureAggregationStrategy === "sum" || featureAggregationStrategy === "mean") {
53443
+ value2 = arraysToStratify[arrKey].reduce((a2, h2) => a2 + h2[i2], 0);
53444
+ if (featureAggregationStrategy === "mean") {
53445
+ value2 /= arraysToStratify[arrKey].length;
53446
+ }
53447
+ }
53448
+ } else {
53449
+ value2 = arraysToStratify[arrKey][i2];
53450
+ }
53418
53451
  result.get(cellSet).get(sampleSet).get(arrKey)[insertionIndex] = value2;
53419
53452
  });
53420
53453
  result.get(cellSet).get(sampleSet).set("i", insertionIndex + 1);
53454
+ cellCount += 1;
53421
53455
  }
53422
53456
  cellSetKeys.forEach((cellSetKey) => {
53423
53457
  sampleSetKeys.forEach((sampleSetKey) => {
@@ -53428,7 +53462,7 @@ function stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetS
53428
53462
  result.get(cellSetKey).get(sampleSetKey).delete("i");
53429
53463
  });
53430
53464
  });
53431
- return result;
53465
+ return [result, cellCount];
53432
53466
  }
53433
53467
  function stratifyExpressionData(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, mergedCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient) {
53434
53468
  const result = new InternMap$1([], JSON.stringify);
@@ -53472,12 +53506,38 @@ function stratifyExpressionData(sampleEdges, sampleSets, sampleSetSelection, exp
53472
53506
  }
53473
53507
  return [null, null];
53474
53508
  }
53475
- function aggregateStratifiedExpressionData(stratifiedResult, geneSelection) {
53509
+ function aggregateStratifiedExpressionData(stratifiedResult, geneSelection, featureAggregationStrategy) {
53476
53510
  const result = new InternMap$1([], JSON.stringify);
53477
53511
  Array.from(stratifiedResult.entries()).forEach(([cellSetKey, firstLevelInternMap]) => {
53478
53512
  result.set(cellSetKey, new InternMap$1([], JSON.stringify));
53479
53513
  Array.from(firstLevelInternMap.entries()).forEach(([sampleSetKey, secondLevelInternMap]) => {
53480
- const values3 = secondLevelInternMap.get(geneSelection[0]);
53514
+ let values3;
53515
+ if (featureAggregationStrategy === "first") {
53516
+ values3 = secondLevelInternMap.get(geneSelection[0]);
53517
+ } else if (featureAggregationStrategy === "last") {
53518
+ values3 = secondLevelInternMap.get(geneSelection.at(-1));
53519
+ } else if (typeof featureAggregationStrategy === "number") {
53520
+ const i2 = featureAggregationStrategy;
53521
+ if (i2 >= 0 && i2 < geneSelection.length) {
53522
+ values3 = secondLevelInternMap.get(geneSelection[i2]);
53523
+ } else {
53524
+ throw new Error("Feature index used for featureAggregationStrategy is invalid.");
53525
+ }
53526
+ } else if (featureAggregationStrategy === "sum" || featureAggregationStrategy === "mean") {
53527
+ const subarrays = geneSelection.map((geneId) => secondLevelInternMap.get(geneId));
53528
+ values3 = subarrays.reduce((acc, curr) => acc.map((val, idx) => val + curr[idx]));
53529
+ if (featureAggregationStrategy === "mean") {
53530
+ const N2 = geneSelection.length;
53531
+ values3 = values3.map((val) => val / N2);
53532
+ }
53533
+ } else if (featureAggregationStrategy === "difference") {
53534
+ if (geneSelection.length === 2) {
53535
+ const subarrays = geneSelection.map((geneId) => secondLevelInternMap.get(geneId));
53536
+ values3 = subarrays.reduce((acc, curr) => acc.map((val, idx) => val - curr[idx]));
53537
+ } else {
53538
+ throw new Error("Expected exactly two selected features when featureAggregationStrategy is difference.");
53539
+ }
53540
+ }
53481
53541
  result.get(cellSetKey).set(sampleSetKey, values3);
53482
53542
  });
53483
53543
  });
@@ -175382,8 +175442,15 @@ class SelectionLayer extends CompositeLayer {
175382
175442
  if (!nodePolygonContainsSelectedPolygon && !nodePolygonWithinSelectedPolygon && !nodePolygonOverlapsSelectedPolgyon) {
175383
175443
  return true;
175384
175444
  }
175385
- if (node2.data && booleanPointInPolygon$1(point$a([].slice.call(getObsCoords(node2.data))), selectedPolygon)) {
175386
- pickingInfos.push(node2.data);
175445
+ if (node2.data) {
175446
+ let current2 = node2;
175447
+ while (current2) {
175448
+ const pointCoords = [].slice.call(getObsCoords(current2.data));
175449
+ if (booleanPointInPolygon$1(point$a(pointCoords), selectedPolygon)) {
175450
+ pickingInfos.push(current2.data);
175451
+ }
175452
+ current2 = current2.next;
175453
+ }
175387
175454
  }
175388
175455
  return false;
175389
175456
  });
@@ -177279,16 +177346,16 @@ async function getDecoder(fileDirectory) {
177279
177346
  const Decoder = await importFn();
177280
177347
  return new Decoder(fileDirectory);
177281
177348
  }
177282
- addDecoder([void 0, 1], () => import("./raw-27b6a685.js").then((m2) => m2.default));
177283
- addDecoder(5, () => import("./lzw-8adf7fb3.js").then((m2) => m2.default));
177349
+ addDecoder([void 0, 1], () => import("./raw-7ad8e084.js").then((m2) => m2.default));
177350
+ addDecoder(5, () => import("./lzw-ffd426d3.js").then((m2) => m2.default));
177284
177351
  addDecoder(6, () => {
177285
177352
  throw new Error("old style JPEG compression is not supported.");
177286
177353
  });
177287
- addDecoder(7, () => import("./jpeg-96ca6dfa.js").then((m2) => m2.default));
177288
- addDecoder([8, 32946], () => import("./deflate-d652c9c3.js").then((m2) => m2.default));
177289
- addDecoder(32773, () => import("./packbits-b963b38b.js").then((m2) => m2.default));
177290
- addDecoder(34887, () => import("./lerc-262d98f3.js").then((m2) => m2.default));
177291
- addDecoder(50001, () => import("./webimage-55725738.js").then((m2) => m2.default));
177354
+ addDecoder(7, () => import("./jpeg-8687eb38.js").then((m2) => m2.default));
177355
+ addDecoder([8, 32946], () => import("./deflate-916bb37d.js").then((m2) => m2.default));
177356
+ addDecoder(32773, () => import("./packbits-3388263e.js").then((m2) => m2.default));
177357
+ addDecoder(34887, () => import("./lerc-42867a4a.js").then((m2) => m2.default));
177358
+ addDecoder(50001, () => import("./webimage-60247a11.js").then((m2) => m2.default));
177292
177359
  function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
177293
177360
  return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
177294
177361
  }
@@ -191745,7 +191812,10 @@ const getPosition = (object2, { index: index2, data: data2, target: target2 }) =
191745
191812
  target2[2] = POINT_LAYER_Z_INDEX;
191746
191813
  return target2;
191747
191814
  };
191748
- const contourGetWeight = (object2, { index: index2, data: data2 }) => data2.src.featureValues[index2];
191815
+ const contourGetWeight = (object2, { index: index2, data: data2 }) => {
191816
+ var _a3;
191817
+ return (_a3 = data2.src.featureValues) == null ? void 0 : _a3[index2];
191818
+ };
191749
191819
  const contourGetPosition = (object2, { index: index2, data: data2, target: target2 }) => {
191750
191820
  target2[0] = data2.src.embeddingX[index2];
191751
191821
  target2[1] = -data2.src.embeddingY[index2];
@@ -192042,6 +192112,16 @@ class Scatterplot extends AbstractSpatialOrScatterplot {
192042
192112
  const { obsEmbeddingIndex, obsEmbedding } = this.props;
192043
192113
  super.viewInfoDidUpdate(obsEmbeddingIndex, obsEmbedding, makeFlippedGetObsCoords);
192044
192114
  }
192115
+ componentWillUnmount() {
192116
+ delete this.cellsQuadTree;
192117
+ delete this.cellsLayer;
192118
+ delete this.cellsData;
192119
+ delete this.stratifiedData;
192120
+ delete this.cellSetsForceSimulation;
192121
+ delete this.cellSetsLabelPrevZoom;
192122
+ delete this.cellSetsLayers;
192123
+ delete this.contourLayers;
192124
+ }
192045
192125
  /**
192046
192126
  * Here, asynchronously check whether props have
192047
192127
  * updated which require re-computing memoized variables,
@@ -192248,8 +192328,9 @@ if (typeof document !== "undefined") {
192248
192328
  else
192249
192329
  document.addEventListener("DOMContentLoaded", $bbed8b41f857bcc0$var$setupGlobalEvents);
192250
192330
  }
192331
+ const FEATURE_AGGREGATION_STRATEGIES$1 = ["first", "last", "sum", "mean"];
192251
192332
  function ScatterplotOptions(props) {
192252
- const { children: children2, observationsLabel, cellRadius, setCellRadius, cellRadiusMode, setCellRadiusMode, cellOpacity, setCellOpacity, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles, contourColorEncoding, setContourColorEncoding } = props;
192333
+ const { children: children2, observationsLabel, cellRadius, setCellRadius, cellRadiusMode, setCellRadiusMode, cellOpacity, setCellOpacity, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles, contourColorEncoding, setContourColorEncoding, featureAggregationStrategy, setFeatureAggregationStrategy } = props;
192253
192334
  const scatterplotOptionsId = $bdb11010cef70236$export$f680877a34711e37();
192254
192335
  const observationsLabelNice = capitalize$2(observationsLabel);
192255
192336
  const classes = usePlotOptionsStyles();
@@ -192300,6 +192381,9 @@ function ScatterplotOptions(props) {
192300
192381
  setContourPercentiles(values3);
192301
192382
  }
192302
192383
  const handlePercentilesChangeDebounced = useCallback(debounce$5(handlePercentilesChange, 5, { trailing: true }), [handlePercentilesChange]);
192384
+ function handleFeatureAggregationStrategyChange(event2) {
192385
+ setFeatureAggregationStrategy(event2.target.value);
192386
+ }
192303
192387
  return jsxRuntimeExports.jsxs(OptionsContainer, { children: [children2, jsxRuntimeExports.jsx(CellColorEncodingOption, { observationsLabel, cellColorEncoding, setCellColorEncoding }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsxs("label", { htmlFor: `scatterplot-set-labels-visible-${scatterplotOptionsId}`, children: [observationsLabelNice, " Set Labels Visible"] }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(w$3, { className: classes.checkbox, checked: cellSetLabelsVisible, onChange: handleLabelVisibilityChange, name: "scatterplot-option-cell-set-labels", color: "default", inputProps: {
192304
192388
  "aria-label": "Show or hide set labels",
192305
192389
  id: `scatterplot-set-labels-visible-${scatterplotOptionsId}`
@@ -192341,7 +192425,9 @@ function ScatterplotOptions(props) {
192341
192425
  id: `scatterplot-contours-filled-${scatterplotOptionsId}`
192342
192426
  } }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `scatterplot-contour-color-encoding-${scatterplotOptionsId}`, children: "Contour Color Encoding" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsxs(OptionSelect, { className: classes.select, value: contourColorEncoding, onChange: handleContourColorEncodingChange, inputProps: {
192343
192427
  id: `scatterplot-contour-color-encoding-${scatterplotOptionsId}`
192344
- }, children: [jsxRuntimeExports.jsx("option", { value: "sampleSetSelection", children: "Sample Sets" }), jsxRuntimeExports.jsxs("option", { value: "cellSetSelection", children: [observationsLabelNice, " Sets"] }), jsxRuntimeExports.jsx("option", { value: "staticColor", children: "Static Color" })] }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, children: "Contour Percentiles" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(Slider$1, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: contourPercentiles || defaultContourPercentiles, onChange: handlePercentilesChangeDebounced, "aria-label": "Scatterplot sliders for contour percentile thresholds", id: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 9e-3, max: 0.999 }) })] })] });
192428
+ }, children: [jsxRuntimeExports.jsx("option", { value: "sampleSetSelection", children: "Sample Sets" }), jsxRuntimeExports.jsxs("option", { value: "cellSetSelection", children: [observationsLabelNice, " Sets"] }), jsxRuntimeExports.jsx("option", { value: "staticColor", children: "Static Color" })] }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, children: "Contour Percentiles" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(Slider$1, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: contourPercentiles || defaultContourPercentiles, onChange: handlePercentilesChangeDebounced, "aria-label": "Scatterplot sliders for contour percentile thresholds", id: `scatterplot-contour-percentiles-${scatterplotOptionsId}`, valueLabelDisplay: "auto", step: 5e-3, min: 9e-3, max: 0.999 }) })] }), setFeatureAggregationStrategy ? jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `feature-aggregation-strategy-${scatterplotOptionsId}`, children: "Feature Aggregation Strategy" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(OptionSelect, { className: classes.select, value: featureAggregationStrategy ?? "first", onChange: handleFeatureAggregationStrategyChange, inputProps: {
192429
+ id: `feature-aggregation-strategy-${scatterplotOptionsId}`
192430
+ }, children: FEATURE_AGGREGATION_STRATEGIES$1.map((opt) => jsxRuntimeExports.jsx("option", { value: opt, children: capitalize$2(opt) }, opt)) }) })] }) : null] });
192345
192431
  }
192346
192432
  const styles$1 = makeStyles((theme) => ({
192347
192433
  tooltipAnchor: {
@@ -196808,8 +196894,50 @@ const titleHeight = 10;
196808
196894
  const rectHeight = 8;
196809
196895
  const rectMarginY = 2;
196810
196896
  const rectMarginX = 2;
196897
+ function combineExtents(extents, featureAggregationStrategy) {
196898
+ if (Array.isArray(extents)) {
196899
+ if (featureAggregationStrategy === "first") {
196900
+ return extents[0];
196901
+ }
196902
+ if (featureAggregationStrategy === "last") {
196903
+ return extents.at(-1);
196904
+ }
196905
+ if (typeof featureAggregationStrategy === "number") {
196906
+ const i2 = featureAggregationStrategy;
196907
+ return extents[i2];
196908
+ }
196909
+ if (featureAggregationStrategy === "sum") {
196910
+ return extents.reduce((a2, h2) => [a2[0] + h2[0], a2[1] + h2[1]]);
196911
+ }
196912
+ if (featureAggregationStrategy === "mean") {
196913
+ return extents.reduce((a2, h2) => [a2[0] + h2[0], a2[1] + h2[1]]).map((v2) => v2 / extents.length);
196914
+ }
196915
+ }
196916
+ return null;
196917
+ }
196918
+ function combineMissings(missings, featureAggregationStrategy) {
196919
+ if (Array.isArray(missings)) {
196920
+ if (featureAggregationStrategy === "first") {
196921
+ return missings[0];
196922
+ }
196923
+ if (featureAggregationStrategy === "last") {
196924
+ return missings.at(-1);
196925
+ }
196926
+ if (typeof featureAggregationStrategy === "number") {
196927
+ const i2 = featureAggregationStrategy;
196928
+ return missings[i2];
196929
+ }
196930
+ if (featureAggregationStrategy === "sum") {
196931
+ return missings.reduce((a2, h2) => a2 + h2, 0);
196932
+ }
196933
+ if (featureAggregationStrategy === "mean") {
196934
+ return missings.reduce((a2, h2) => a2 + h2 / missings.length, 0);
196935
+ }
196936
+ }
196937
+ return null;
196938
+ }
196811
196939
  function Legend(props) {
196812
- const { visible: visibleProp, positionRelative = false, highContrast = false, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, spatialChannelColor, spatialLayerColor, obsSetSelection, obsSetColor, extent: extent2, missing, width: width2 = 100, height: height2 = 36, theme, showObsLabel = false, pointsVisible = true, contoursVisible = false, contoursFilled, contourPercentiles, contourThresholds } = props;
196940
+ const { visible: visibleProp, positionRelative = false, highContrast = false, obsType, featureValueType, considerSelections = true, obsColorEncoding, featureSelection, featureLabelsMap, featureValueColormap, featureValueColormapRange, spatialChannelColor, spatialLayerColor, obsSetSelection, obsSetColor, featureAggregationStrategy, extent: extent2, missing, width: width2 = 100, height: height2 = 36, theme, showObsLabel = false, pointsVisible = true, contoursVisible = false, contoursFilled, contourPercentiles, contourThresholds } = props;
196813
196941
  const svgRef = useRef();
196814
196942
  const classes = useStyles$p();
196815
196943
  const isDarkTheme = theme === "dark";
@@ -196818,9 +196946,9 @@ function Legend(props) {
196818
196946
  const layerColor = Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3 ? spatialLayerColor : getDefaultColor(theme);
196819
196947
  const channelColor = Array.isArray(spatialChannelColor) && spatialChannelColor.length === 3 ? spatialChannelColor : getDefaultColor(theme);
196820
196948
  const staticColor = obsColorEncoding === "spatialChannelColor" ? channelColor : layerColor;
196821
- const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length === 1 || isSetColor && (obsSetSelection == null ? void 0 : obsSetSelection.length) > 0 && (obsSetColor == null ? void 0 : obsSetColor.length) > 0 || isStaticColor);
196949
+ const visible = visibleProp && (!considerSelections || obsColorEncoding === "geneSelection" && featureSelection && Array.isArray(featureSelection) && featureSelection.length >= 1 || isSetColor && (obsSetSelection == null ? void 0 : obsSetSelection.length) > 0 && (obsSetColor == null ? void 0 : obsSetColor.length) > 0 || isStaticColor);
196822
196950
  const levelZeroNames = useMemo(() => Array.from(new Set((obsSetSelection == null ? void 0 : obsSetSelection.map((setPath) => setPath[0])) || [])), [obsSetSelection]);
196823
- const dynamicHeight = isSetColor ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height2 + (!pointsVisible && contoursVisible ? 25 : 0);
196951
+ const dynamicHeight = isSetColor && obsSetSelection ? levelZeroNames.length * titleHeight + (obsSetSelection == null ? void 0 : obsSetSelection.length) * (rectHeight + rectMarginY) : height2 + (!pointsVisible && contoursVisible ? 25 : 0);
196824
196952
  useEffect(() => {
196825
196953
  const domElement = svgRef.current;
196826
196954
  const foregroundColor = highContrast ? "black" : isDarkTheme ? "white" : "black";
@@ -196829,7 +196957,7 @@ function Legend(props) {
196829
196957
  svg2.attr("width", width2).attr("height", dynamicHeight);
196830
196958
  const g2 = svg2.append("g").attr("width", width2).attr("height", dynamicHeight);
196831
196959
  if (!considerSelections || obsColorEncoding === "geneSelection") {
196832
- const [xMin, xMax] = extent2 || [0, 1];
196960
+ const [xMin, xMax] = combineExtents(extent2, featureAggregationStrategy) || [0, 1];
196833
196961
  if (featureValueColormap && pointsVisible) {
196834
196962
  const xlinkHref = getXlinkHref(featureValueColormap);
196835
196963
  g2.append("image").attr("x", 0).attr("y", titleHeight).attr("width", width2).attr("height", rectHeight).attr("preserveAspectRatio", "none").attr("href", xlinkHref);
@@ -196893,8 +197021,19 @@ function Legend(props) {
196893
197021
  });
196894
197022
  });
196895
197023
  }
196896
- const featureSelectionLabelRaw = featureSelection && featureSelection.length >= 1 && !isStaticColor ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(featureSelection[0])) || (featureLabelsMap == null ? void 0 : featureLabelsMap.get(cleanFeatureId(featureSelection[0]))) || featureSelection[0] : null;
196897
- const featureSelectionLabel = missing ? `${featureSelectionLabelRaw} (${Math.round(missing * 100)}% NaN)` : featureSelectionLabelRaw;
197024
+ const featureSelectionLabelRaw = featureSelection && featureSelection.length >= 1 && !isStaticColor ? featureSelection.map((geneName) => (featureLabelsMap == null ? void 0 : featureLabelsMap.get(geneName)) || (featureLabelsMap == null ? void 0 : featureLabelsMap.get(cleanFeatureId(geneName))) || geneName) : null;
197025
+ let featureSelectionLabelRawStr = "";
197026
+ if (featureAggregationStrategy === "first") {
197027
+ featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw[0];
197028
+ } else if (featureAggregationStrategy === "last") {
197029
+ featureSelectionLabelRawStr = featureSelectionLabelRaw == null ? void 0 : featureSelectionLabelRaw.at(-1);
197030
+ } else if (featureAggregationStrategy === "sum") {
197031
+ featureSelectionLabelRawStr = "Sum of features";
197032
+ } else if (featureAggregationStrategy === "mean") {
197033
+ featureSelectionLabelRawStr = "Mean of features";
197034
+ }
197035
+ const combinedMissing = combineMissings(missing, featureAggregationStrategy);
197036
+ const featureSelectionLabel = combinedMissing ? `${featureSelectionLabelRawStr} (${Math.round(combinedMissing * 100)}% NaN)` : featureSelectionLabelRawStr;
196898
197037
  const obsLabel = capitalize$2(obsType);
196899
197038
  const featureLabel = considerSelections ? featureSelectionLabel || capitalize$2(featureValueType) : capitalize$2(featureValueType);
196900
197039
  const mainLabel = showObsLabel ? obsLabel : featureLabel;
@@ -196928,7 +197067,8 @@ function Legend(props) {
196928
197067
  contourThresholds,
196929
197068
  contoursFilled,
196930
197069
  contoursVisible,
196931
- pointsVisible
197070
+ pointsVisible,
197071
+ featureAggregationStrategy
196932
197072
  ]);
196933
197073
  return jsxRuntimeExports.jsx("div", { className: clsx(classes.legend, {
196934
197074
  [classes.legendRelative]: positionRelative,
@@ -197089,6 +197229,7 @@ function ChannelNamesLegend(props) {
197089
197229
  }) : null });
197090
197230
  }
197091
197231
  const DEFAULT_CONTOUR_PERCENTILES = [0.09, 0.9, 0.99];
197232
+ const DEFAULT_FEATURE_AGGREGATION_STRATEGY$1 = "first";
197092
197233
  function EmbeddingScatterplotSubscriber(props) {
197093
197234
  const {
197094
197235
  uuid,
@@ -197108,10 +197249,11 @@ function EmbeddingScatterplotSubscriber(props) {
197108
197249
  const loaders = useLoaders();
197109
197250
  const setComponentHover = useSetComponentHover();
197110
197251
  const setComponentViewInfo = useSetComponentViewInfo(uuid);
197111
- const [{ dataset, obsType, featureType, featureValueType, sampleType, 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, sampleSetSelection: sampleSetSelectionFromCoordination, sampleSetColor, embeddingPointsVisible, embeddingContoursVisible, embeddingContoursFilled, embeddingContourPercentiles: contourPercentiles, contourColorEncoding, contourColor }, { 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, setEmbeddingPointsVisible, setEmbeddingContoursVisible, setEmbeddingContoursFilled, setEmbeddingContourPercentiles: setContourPercentiles, setContourColorEncoding }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
197252
+ const [{ dataset, obsType, featureType, featureValueType, sampleType, 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, sampleSetSelection: sampleSetSelectionFromCoordination, sampleSetColor, embeddingPointsVisible, embeddingContoursVisible, embeddingContoursFilled, embeddingContourPercentiles: contourPercentiles, contourColorEncoding, contourColor, featureAggregationStrategy }, { 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, setEmbeddingPointsVisible, setEmbeddingContoursVisible, setEmbeddingContoursFilled, setEmbeddingContourPercentiles: setContourPercentiles, setContourColorEncoding, setFeatureAggregationStrategy }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
197112
197253
  const { embeddingZoom: initialZoom, embeddingTargetX: initialTargetX, embeddingTargetY: initialTargetY } = useInitialCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.SCATTERPLOT], coordinationScopes);
197113
197254
  const observationsLabel = observationsLabelOverride || obsType;
197114
197255
  const sampleSetSelection = sampleSetSelectionFromProps || sampleSetSelectionFromCoordination;
197256
+ const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY$1;
197115
197257
  const [width2, height2, deckRef] = useDeckCanvasSize();
197116
197258
  const title2 = titleOverride || `Scatterplot (${mapping})`;
197117
197259
  const [obsLabelsTypes, obsLabelsData] = useMultiObsLabels(coordinationScopes, obsType, loaders, dataset);
@@ -197214,7 +197356,7 @@ function EmbeddingScatterplotSubscriber(props) {
197214
197356
  return [null, null, null, null, null];
197215
197357
  }, [obsEmbedding]);
197216
197358
  useEffect(() => {
197217
- if (xRange && yRange) {
197359
+ if (xRange && yRange && width2 && height2) {
197218
197360
  const pointSizeDevicePixels = getPointSizeDevicePixels(window.devicePixelRatio, zoom2, xRange, yRange, width2, height2);
197219
197361
  setDynamicCellRadius(pointSizeDevicePixels);
197220
197362
  const nextCellOpacityScale = getPointOpacity(zoom2, xRange, yRange, width2, height2, numCells, averageFillDensity);
@@ -197283,6 +197425,9 @@ function EmbeddingScatterplotSubscriber(props) {
197283
197425
  originalViewState.target[1]
197284
197426
  ];
197285
197427
  const scaleFactor = 2 ** originalViewState.zoom;
197428
+ if (!(typeof scaleFactor === "number" && typeof center2[0] === "number" && typeof center2[1] === "number") || Number.isNaN(scaleFactor)) {
197429
+ return null;
197430
+ }
197286
197431
  const radius2 = Math.min(width2, height2) / 2 / scaleFactor;
197287
197432
  const numPoints = 96;
197288
197433
  const options = { steps: numPoints, units: "degrees" };
@@ -197327,17 +197472,16 @@ function EmbeddingScatterplotSubscriber(props) {
197327
197472
  }
197328
197473
  return null;
197329
197474
  }, [sampleEdges]);
197330
- const stratifiedData = useMemo(() => {
197475
+ const [stratifiedData, stratifiedDataCount] = useMemo(() => {
197331
197476
  if (alignedEmbeddingData == null ? void 0 : alignedEmbeddingData.data) {
197332
- const result = stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, alignedEmbeddingIndex, mergedCellSets, cellSetSelection, {
197477
+ const [result, cellCountResult] = stratifyArrays(sampleEdges, sampleIdToObsIdsMap, sampleSets, sampleSetSelection, alignedEmbeddingIndex, mergedCellSets, cellSetSelection, {
197333
197478
  obsEmbeddingX: alignedEmbeddingData.data[0],
197334
197479
  obsEmbeddingY: alignedEmbeddingData.data[1],
197335
- // TODO: aggregate and transform expression data if needed prior to passing here
197336
- ...(uint8ExpressionData == null ? void 0 : uint8ExpressionData[0]) ? { featureValue: uint8ExpressionData == null ? void 0 : uint8ExpressionData[0] } : {}
197337
- });
197338
- return result;
197480
+ ...(uint8ExpressionData == null ? void 0 : uint8ExpressionData[0]) ? { featureValue: uint8ExpressionData } : {}
197481
+ }, featureAggregationStrategyToUse);
197482
+ return [result, cellCountResult];
197339
197483
  }
197340
- return null;
197484
+ return [null, null];
197341
197485
  }, [
197342
197486
  alignedEmbeddingIndex,
197343
197487
  alignedEmbeddingData,
@@ -197347,7 +197491,8 @@ function EmbeddingScatterplotSubscriber(props) {
197347
197491
  sampleSets,
197348
197492
  sampleSetSelection,
197349
197493
  cellSetSelection,
197350
- mergedCellSets
197494
+ mergedCellSets,
197495
+ featureAggregationStrategyToUse
197351
197496
  ]);
197352
197497
  const setViewState = ({ zoom: newZoom, target: target2 }) => {
197353
197498
  setZoom(newZoom);
@@ -197355,7 +197500,8 @@ function EmbeddingScatterplotSubscriber(props) {
197355
197500
  setTargetY(target2[1]);
197356
197501
  setTargetZ(target2[2] || 0);
197357
197502
  };
197358
- return jsxRuntimeExports.jsxs(TitleInfo, { title: title2, info: `${commaNumber(cellsCount)} ${pluralize(observationsLabel, cellsCount)}`, closeButtonVisible, downloadButtonVisible, removeGridComponent, urls: urls2, theme, isReady, helpText, options: jsxRuntimeExports.jsx(ScatterplotOptions, { observationsLabel, cellRadius: cellRadiusFixed, setCellRadius: setCellRadiusFixed, cellRadiusMode, setCellRadiusMode, cellOpacity: cellOpacityFixed, setCellOpacity: setCellOpacityFixed, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles: DEFAULT_CONTOUR_PERCENTILES, contourColorEncoding, setContourColorEncoding }), children: [jsxRuntimeExports.jsx(ScatterplotWrapper, {
197503
+ const cellCountToUse = embeddingPointsVisible ? cellsCount : stratifiedDataCount ?? cellsCount;
197504
+ return jsxRuntimeExports.jsxs(TitleInfo, { title: title2, info: `${commaNumber(cellCountToUse)} ${pluralize(observationsLabel, cellCountToUse)}`, closeButtonVisible, downloadButtonVisible, removeGridComponent, urls: urls2, theme, isReady, helpText, options: jsxRuntimeExports.jsx(ScatterplotOptions, { observationsLabel, cellRadius: cellRadiusFixed, setCellRadius: setCellRadiusFixed, cellRadiusMode, setCellRadiusMode, cellOpacity: cellOpacityFixed, setCellOpacity: setCellOpacityFixed, cellOpacityMode, setCellOpacityMode, cellSetLabelsVisible, setCellSetLabelsVisible, tooltipsVisible, setTooltipsVisible, cellSetLabelSize, setCellSetLabelSize, cellSetPolygonsVisible, setCellSetPolygonsVisible, cellColorEncoding, setCellColorEncoding, geneExpressionColormap, setGeneExpressionColormap, geneExpressionColormapRange, setGeneExpressionColormapRange, embeddingPointsVisible, setEmbeddingPointsVisible, embeddingContoursVisible, setEmbeddingContoursVisible, embeddingContoursFilled, setEmbeddingContoursFilled, contourPercentiles, setContourPercentiles, defaultContourPercentiles: DEFAULT_CONTOUR_PERCENTILES, contourColorEncoding, setContourColorEncoding, featureAggregationStrategy, setFeatureAggregationStrategy }), children: [jsxRuntimeExports.jsx(ScatterplotWrapper, {
197359
197505
  ref: deckRef,
197360
197506
  uuid,
197361
197507
  theme,
@@ -197401,7 +197547,7 @@ function EmbeddingScatterplotSubscriber(props) {
197401
197547
  embeddingContoursVisible,
197402
197548
  circleInfo,
197403
197549
  featureSelection: geneSelection
197404
- }), tooltipsVisible && jsxRuntimeExports.jsx(ScatterplotTooltipSubscriber, { parentUuid: uuid, obsHighlight: cellHighlight, width: width2, height: height2, getObsInfo: getObsInfo2, featureType, featureLabelsMap }), jsxRuntimeExports.jsx(Legend, {
197550
+ }), tooltipsVisible && width2 && height2 ? jsxRuntimeExports.jsx(ScatterplotTooltipSubscriber, { parentUuid: uuid, obsHighlight: cellHighlight, width: width2, height: height2, getObsInfo: getObsInfo2, featureType, featureLabelsMap }) : null, jsxRuntimeExports.jsx(Legend, {
197405
197551
  visible: true,
197406
197552
  theme,
197407
197553
  featureType,
@@ -197412,14 +197558,15 @@ function EmbeddingScatterplotSubscriber(props) {
197412
197558
  featureValueColormap: geneExpressionColormap,
197413
197559
  featureValueColormapRange: geneExpressionColormapRange,
197414
197560
  obsSetSelection: cellSetSelection,
197415
- extent: expressionExtents == null ? void 0 : expressionExtents[0],
197416
- missing: expressionMissing == null ? void 0 : expressionMissing[0],
197561
+ extent: expressionExtents,
197562
+ missing: expressionMissing,
197417
197563
  // Contour percentile legend
197418
197564
  pointsVisible: embeddingPointsVisible,
197419
197565
  contoursVisible: embeddingContoursVisible,
197420
197566
  contoursFilled: embeddingContoursFilled,
197421
197567
  contourPercentiles: contourPercentiles || DEFAULT_CONTOUR_PERCENTILES,
197422
- contourThresholds
197568
+ contourThresholds,
197569
+ featureAggregationStrategy: featureAggregationStrategyToUse
197423
197570
  })] });
197424
197571
  }
197425
197572
  function DualEmbeddingScatterplotSubscriber(props) {
@@ -218490,7 +218637,7 @@ class ErrorBoundary extends React__default.Component {
218490
218637
  }
218491
218638
  }
218492
218639
  const LazySpatialThree = React__default.lazy(async () => {
218493
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-7b4cc1b8.js");
218640
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-1de95a31.js");
218494
218641
  return { default: SpatialWrapper2 };
218495
218642
  });
218496
218643
  const SpatialThreeAdapter = React__default.forwardRef((props, ref2) => jsxRuntimeExports.jsx("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsxRuntimeExports.jsx(ErrorBoundary, { children: jsxRuntimeExports.jsx(Suspense, { fallback: jsxRuntimeExports.jsx("div", { children: "Loading..." }), children: jsxRuntimeExports.jsx(LazySpatialThree, { ...props }) }) }) }));
@@ -229349,7 +229496,7 @@ const useStyles$6 = makeStyles((theme) => ({
229349
229496
  }));
229350
229497
  register({ dataFetcher: ZarrMultivecDataFetcher_default, config: ZarrMultivecDataFetcher_default.config }, { pluginType: "dataFetcher" });
229351
229498
  const LazyHiGlassComponent = React__default.lazy(async () => {
229352
- const { HiGlassComponent } = await import("./higlass-0bd691db.js");
229499
+ const { HiGlassComponent } = await import("./higlass-5022c0ac.js");
229353
229500
  return { default: HiGlassComponent };
229354
229501
  });
229355
229502
  const HG_SIZE = 800;
@@ -232297,7 +232444,7 @@ const useStyles$5 = makeStyles(() => ({
232297
232444
  }
232298
232445
  }));
232299
232446
  const LazyReactNeuroglancer = React__default.lazy(async () => {
232300
- const ReactNeuroglancer = await import("./index-c358749f.js").then((n3) => n3.i);
232447
+ const ReactNeuroglancer = await import("./index-9fa0b8f0.js").then((n3) => n3.i);
232301
232448
  return ReactNeuroglancer;
232302
232449
  });
232303
232450
  function createWorker() {
@@ -232320,16 +232467,20 @@ function NeuroglancerSubscriber(props) {
232320
232467
  const { closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title: title2 = "Neuroglancer", viewerState: viewerStateInitial = null, helpText = ViewHelpMapping.NEUROGLANCER } = props;
232321
232468
  return jsxRuntimeExports.jsx(TitleInfo, { title: title2, helpText, isSpatial: true, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isReady: true, children: viewerStateInitial && jsxRuntimeExports.jsx(Neuroglancer, { viewerState: viewerStateInitial }) });
232322
232469
  }
232470
+ const FEATURE_AGGREGATION_STRATEGIES = ["first", "last", "sum", "mean"];
232323
232471
  function CellSetExpressionPlotOptions(props) {
232324
- const { featureValueTransform, setFeatureValueTransform, featureValueTransformCoefficient, setFeatureValueTransformCoefficient, transformOptions, featureValuePositivityThreshold, setFeatureValuePositivityThreshold, featureValueColormap, setFeatureValueColormap } = props;
232472
+ const { featureValueTransform, setFeatureValueTransform, featureValueTransformCoefficient, setFeatureValueTransformCoefficient, transformOptions, featureValuePositivityThreshold, setFeatureValuePositivityThreshold, featureValueColormap, setFeatureValueColormap, featureAggregationStrategy, setFeatureAggregationStrategy } = props;
232325
232473
  const cellSetExpressionPlotOptionsId = $bdb11010cef70236$export$f680877a34711e37();
232326
232474
  const classes = usePlotOptionsStyles();
232327
232475
  function handleFeatureValueColormapChange(event2) {
232328
232476
  setFeatureValueColormap(event2.target.value);
232329
232477
  }
232330
- const handleTransformChange = (event2) => {
232478
+ function handleTransformChange(event2) {
232331
232479
  setFeatureValueTransform(event2.target.value === "" ? null : event2.target.value);
232332
- };
232480
+ }
232481
+ function handleFeatureAggregationStrategyChange(event2) {
232482
+ setFeatureAggregationStrategy(event2.target.value);
232483
+ }
232333
232484
  function handlePositivityThresholdChange(event2, value2) {
232334
232485
  setFeatureValuePositivityThreshold(value2);
232335
232486
  }
@@ -232351,7 +232502,9 @@ function CellSetExpressionPlotOptions(props) {
232351
232502
  id: `cellset-expression-transform-select-${cellSetExpressionPlotOptionsId}`
232352
232503
  }, children: transformOptions.map((opt) => jsxRuntimeExports.jsx("option", { value: opt.value === null ? "" : opt.value, children: opt.name }, opt.name)) }) })] }), jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `cellset-expression-transform-coeff-${cellSetExpressionPlotOptionsId}`, children: "Transform Coefficient" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(TextField$1, { label: "Transform Coefficient", type: "number", onChange: handleTransformCoefficientChange, value: featureValueTransformCoefficient, InputLabelProps: {
232353
232504
  shrink: true
232354
- }, id: `cellset-expression-transform-coeff-${cellSetExpressionPlotOptionsId}` }) })] }), setFeatureValuePositivityThreshold ? jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, children: "Positivity Threshold" }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, children: jsxRuntimeExports.jsx(Slider$1, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: featureValuePositivityThreshold, onChange: handlePositivityThresholdChange, "aria-labelledby": "pos-threshold-slider", valueLabelDisplay: "auto", step: 1, min: 0, max: 100 }) })] }, "transform-coefficient-option-row") : null] });
232505
+ }, id: `cellset-expression-transform-coeff-${cellSetExpressionPlotOptionsId}` }) })] }), setFeatureAggregationStrategy ? jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, variant: "head", scope: "row", children: jsxRuntimeExports.jsx("label", { htmlFor: `feature-aggregation-strategy-${cellSetExpressionPlotOptionsId}`, children: "Feature Aggregation Strategy" }) }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, variant: "body", children: jsxRuntimeExports.jsx(OptionSelect, { className: classes.select, value: featureAggregationStrategy ?? "first", onChange: handleFeatureAggregationStrategyChange, inputProps: {
232506
+ id: `feature-aggregation-strategy-${cellSetExpressionPlotOptionsId}`
232507
+ }, children: FEATURE_AGGREGATION_STRATEGIES.map((opt) => jsxRuntimeExports.jsx("option", { value: opt, children: capitalize$2(opt) }, opt)) }) })] }) : null, setFeatureValuePositivityThreshold ? jsxRuntimeExports.jsxs(TableRow$1, { children: [jsxRuntimeExports.jsx(TableCell$1, { className: classes.labelCell, children: "Positivity Threshold" }), jsxRuntimeExports.jsx(TableCell$1, { className: classes.inputCell, children: jsxRuntimeExports.jsx(Slider$1, { classes: { root: classes.slider, valueLabel: classes.sliderValueLabel }, value: featureValuePositivityThreshold, onChange: handlePositivityThresholdChange, "aria-labelledby": "pos-threshold-slider", valueLabelDisplay: "auto", step: 1, min: 0, max: 100 }) })] }, "transform-coefficient-option-row") : null] });
232355
232508
  }
232356
232509
  function bandSpace$1(count2, paddingInner2, paddingOuter2) {
232357
232510
  var space2 = count2 - paddingInner2 + paddingOuter2 * 2;
@@ -237499,12 +237652,35 @@ function histogramStratifiedExpressionData(summarizedResult, binCount, yMinProp)
237499
237652
  // d3.scaleLinear without a range set
237500
237653
  };
237501
237654
  }
237502
- function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMinProp) {
237655
+ const DEFAULT_FEATURE_AGGREGATION_STRATEGY = "first";
237656
+ function featureSummary(geneSelection, featureAggregationStrategy) {
237657
+ if (featureAggregationStrategy === "first") {
237658
+ return geneSelection == null ? void 0 : geneSelection[0];
237659
+ }
237660
+ if (featureAggregationStrategy === "last") {
237661
+ return geneSelection == null ? void 0 : geneSelection.at(-1);
237662
+ }
237663
+ if (typeof featureAggregationStrategy === "number") {
237664
+ const i2 = featureAggregationStrategy;
237665
+ return geneSelection == null ? void 0 : geneSelection[i2];
237666
+ }
237667
+ if (featureAggregationStrategy === "sum") {
237668
+ return geneSelection == null ? void 0 : geneSelection.join(" + ");
237669
+ }
237670
+ if (featureAggregationStrategy === "mean") {
237671
+ return `Mean of ${geneSelection == null ? void 0 : geneSelection.join(", ")}`;
237672
+ }
237673
+ if (featureAggregationStrategy === "difference") {
237674
+ return geneSelection == null ? void 0 : geneSelection.join(" - ");
237675
+ }
237676
+ return "";
237677
+ }
237678
+ function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMinProp, featureAggregationStrategy) {
237503
237679
  const mergedCellSets = useMemo(() => mergeObsSets(cellSets, additionalCellSets), [cellSets, additionalCellSets]);
237504
237680
  const [expressionArr, expressionMax] = useMemo(() => {
237505
237681
  const [stratifiedData, exprMax] = stratifyExpressionData(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, mergedCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient);
237506
237682
  if (stratifiedData) {
237507
- const aggregateData = aggregateStratifiedExpressionData(stratifiedData, geneSelection);
237683
+ const aggregateData = aggregateStratifiedExpressionData(stratifiedData, geneSelection, featureAggregationStrategy);
237508
237684
  const summarizedData = summarizeStratifiedExpressionData(aggregateData, true);
237509
237685
  const histogramData = histogramStratifiedExpressionData(summarizedData, 16, yMinProp);
237510
237686
  return [histogramData, exprMax];
@@ -237523,7 +237699,8 @@ function useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, exp
237523
237699
  yMinProp,
237524
237700
  sampleEdges,
237525
237701
  sampleSets,
237526
- sampleSetSelection
237702
+ sampleSetSelection,
237703
+ featureAggregationStrategy
237527
237704
  ]);
237528
237705
  const setArr = useMemo(() => mergedCellSets && cellSetSelection && cellSetColor ? treeToSetSizesBySetNames(mergedCellSets, cellSetSelection, cellSetSelection, cellSetColor, theme) : [], [mergedCellSets, cellSetSelection, cellSetColor, theme]);
237529
237706
  return [expressionArr, setArr, expressionMax];
@@ -237533,7 +237710,7 @@ function CellSetExpressionPlotSubscriber(props) {
237533
237710
  const { coordinationScopes, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title: title2, xAxisTitle, jitter: jitter2 = false, yMin = null, yUnits = null, helpText = ViewHelpMapping.OBS_SET_FEATURE_VALUE_DISTRIBUTION } = props;
237534
237711
  const classes = useStyles$4();
237535
237712
  const loaders = useLoaders();
237536
- const [{ dataset, obsType, featureType, featureValueType, featureSelection: geneSelection, featureValueTransform, featureValueTransformCoefficient, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets, sampleType, sampleSetSelection, sampleSetColor }, { setFeatureValueTransform, setFeatureValueTransformCoefficient, setSampleSetColor }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.OBS_SET_FEATURE_VALUE_DISTRIBUTION], coordinationScopes);
237713
+ const [{ dataset, obsType, featureType, featureValueType, featureSelection: geneSelection, featureValueTransform, featureValueTransformCoefficient, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, additionalObsSets: additionalCellSets, sampleType, sampleSetSelection, sampleSetColor, featureAggregationStrategy }, { setFeatureValueTransform, setFeatureValueTransformCoefficient, setSampleSetColor, setFeatureAggregationStrategy }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.OBS_SET_FEATURE_VALUE_DISTRIBUTION], coordinationScopes);
237537
237714
  const [width2, height2, containerRef] = useGridItemSize();
237538
237715
  const transformOptions = VALUE_TRANSFORM_OPTIONS;
237539
237716
  const [expressionData, loadedFeatureSelection, featureSelectionStatus] = useFeatureSelection(loaders, dataset, false, geneSelection, { obsType, featureType, featureValueType });
@@ -237559,11 +237736,18 @@ function CellSetExpressionPlotSubscriber(props) {
237559
237736
  sampleSetsUrls,
237560
237737
  sampleEdgesUrls
237561
237738
  ]);
237562
- const [histogramData, setArr, exprMax] = useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMin);
237563
- const firstGeneSelected = geneSelection && geneSelection.length >= 1 ? (featureLabelsMap == null ? void 0 : featureLabelsMap.get(geneSelection[0])) || (featureLabelsMap == null ? void 0 : featureLabelsMap.get(cleanFeatureId(geneSelection[0]))) || geneSelection[0] : null;
237739
+ const featureAggregationStrategyToUse = featureAggregationStrategy ?? DEFAULT_FEATURE_AGGREGATION_STRATEGY;
237740
+ const [histogramData, setArr, exprMax] = useExpressionByCellSet(sampleEdges, sampleSets, sampleSetSelection, expressionData, obsIndex, cellSets, additionalCellSets, geneSelection, cellSetSelection, cellSetColor, featureValueTransform, featureValueTransformCoefficient, theme, yMin, featureAggregationStrategyToUse);
237741
+ const featureSuffix = useMemo(() => {
237742
+ const cleanedGeneSelection = geneSelection == null ? void 0 : geneSelection.map((geneName) => (featureLabelsMap == null ? void 0 : featureLabelsMap.get(geneName)) || (featureLabelsMap == null ? void 0 : featureLabelsMap.get(cleanFeatureId(geneName))) || geneName);
237743
+ if (Array.isArray(cleanedGeneSelection)) {
237744
+ return featureSummary(cleanedGeneSelection, featureAggregationStrategyToUse);
237745
+ }
237746
+ return null;
237747
+ }, [geneSelection, featureAggregationStrategyToUse]);
237564
237748
  const selectedTransformName = (_a3 = transformOptions.find((o2) => o2.value === featureValueTransform)) == null ? void 0 : _a3.name;
237565
- const titleSuffix = firstGeneSelected ? ` (${firstGeneSelected})` : "";
237566
- return jsxRuntimeExports.jsx(TitleInfo, { title: title2 ? `${title2}${titleSuffix}` : `Expression by ${capitalize$2(obsType)} Set${titleSuffix}`, closeButtonVisible, downloadButtonVisible, removeGridComponent, urls: urls2, theme, isReady, helpText, options: jsxRuntimeExports.jsx(CellSetExpressionPlotOptions, { featureValueTransform, setFeatureValueTransform, featureValueTransformCoefficient, setFeatureValueTransformCoefficient, transformOptions }), children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: histogramData ? jsxRuntimeExports.jsx(CellSetExpressionPlot, { yMin, yUnits, jitter: jitter2, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, sampleSetSelection, sampleSetColor, colors: setArr, data: histogramData, exprMax, theme, width: width2, height: height2, obsType, featureType, featureValueType, featureValueTransformName: selectedTransformName, xAxisTitle }) : jsxRuntimeExports.jsxs("span", { children: ["Select a ", featureType, "."] }) }) });
237749
+ const titleSuffix = featureSuffix ? ` (${featureSuffix})` : "";
237750
+ return jsxRuntimeExports.jsx(TitleInfo, { title: title2 ? `${title2}${titleSuffix}` : `Expression by ${capitalize$2(obsType)} Set${titleSuffix}`, closeButtonVisible, downloadButtonVisible, removeGridComponent, urls: urls2, theme, isReady, helpText, options: jsxRuntimeExports.jsx(CellSetExpressionPlotOptions, { featureValueTransform, setFeatureValueTransform, featureValueTransformCoefficient, setFeatureValueTransformCoefficient, transformOptions, featureAggregationStrategy, setFeatureAggregationStrategy }), children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: histogramData ? jsxRuntimeExports.jsx(CellSetExpressionPlot, { yMin, yUnits, jitter: jitter2, obsSetSelection: cellSetSelection, obsSetColor: cellSetColor, sampleSetSelection, sampleSetColor, colors: setArr, data: histogramData, exprMax, theme, width: width2, height: height2, obsType, featureType, featureValueType, featureValueTransformName: selectedTransformName, xAxisTitle }) : jsxRuntimeExports.jsxs("span", { children: ["Select a ", featureType, "."] }) }) });
237567
237751
  }
237568
237752
  /*! *****************************************************************************
237569
237753
  Copyright (c) Microsoft Corporation.
@@ -289528,7 +289712,26 @@ function ExpressionHistogramSubscriber(props) {
289528
289712
  return jsxRuntimeExports.jsx(TitleInfo, { title: `Histogram${firstGeneSelected ? ` (${firstGeneSelected})` : ""}`, closeButtonVisible, downloadButtonVisible, removeGridComponent, urls: urls2, theme, isReady, helpText, children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: jsxRuntimeExports.jsx(ExpressionHistogram, { geneSelection, obsType, featureType, featureValueType, onSelect, data: data2, theme, width: width2, height: height2 }) }) });
289529
289713
  }
289530
289714
  function DotPlot(props) {
289531
- const { isStratified, transpose: transpose2, data: rawData, theme, width: width2, height: height2, marginRight, marginBottom, obsType, sampleType, keyLength = 36, featureType, featureValueType, featureValueTransformName, featureValueColormap, obsSetSelection, obsSetColor } = props;
289715
+ const {
289716
+ isStratified,
289717
+ transpose: transpose2,
289718
+ data: rawData,
289719
+ theme,
289720
+ width: width2,
289721
+ height: height2,
289722
+ marginRight,
289723
+ marginBottom,
289724
+ obsType,
289725
+ sampleType,
289726
+ keyLength = 36,
289727
+ featureType,
289728
+ featureValueType,
289729
+ featureValueTransformName,
289730
+ // TODO: re-enable featureValueColormap coordination
289731
+ // featureValueColormap,
289732
+ obsSetSelection,
289733
+ obsSetColor
289734
+ } = props;
289532
289735
  const vegaContainerRef = useRef();
289533
289736
  const data2 = rawData.map((d) => ({
289534
289737
  ...d,
@@ -289587,7 +289790,8 @@ function DotPlot(props) {
289587
289790
  type: "quantitative",
289588
289791
  title: meanTransform,
289589
289792
  scale: {
289590
- scheme: featureValueColormap
289793
+ // scheme: featureValueColormap,
289794
+ scheme: "greys"
289591
289795
  },
289592
289796
  legend: {
289593
289797
  direction: "horizontal",
@@ -290090,8 +290294,6 @@ function TreemapSubscriber(props) {
290090
290294
  ]);
290091
290295
  const mergedObsSets = useMemo(() => mergeObsSets(obsSets, additionalObsSets), [obsSets, additionalObsSets]);
290092
290296
  const mergedSampleSets = useMemo(() => mergeObsSets(sampleSets, null), [sampleSets]);
290093
- const obsCount = (obsIndex == null ? void 0 : obsIndex.length) || 0;
290094
- const sampleCount = (sampleIndex == null ? void 0 : sampleIndex.length) || 0;
290095
290297
  const [obsCounts, sampleCounts] = useMemo(() => {
290096
290298
  var _a3, _b3;
290097
290299
  const obsResult = new InternMap$1([], JSON.stringify);
@@ -290112,7 +290314,7 @@ function TreemapSubscriber(props) {
290112
290314
  const sampleSetSize = (_a4 = sampleSetSizes == null ? void 0 : sampleSetSizes.find((d) => isEqual$5(d.setNamePath, sampleSetKey))) == null ? void 0 : _a4.size;
290113
290315
  sampleResult.set(sampleSetKey, sampleSetSize || 0);
290114
290316
  });
290115
- if (mergedObsSets && obsSetSelection) {
290317
+ if (mergedObsSets && obsSetSelection && obsIndex) {
290116
290318
  const sampleIdToSetMap = sampleSets && sampleSetSelection ? treeToSelectedSetMap(sampleSets, sampleSetSelection) : null;
290117
290319
  const cellIdToSetMap = treeToSelectedSetMap(mergedObsSets, obsSetSelection);
290118
290320
  for (let i2 = 0; i2 < obsIndex.length; i2 += 1) {
@@ -290140,13 +290342,20 @@ function TreemapSubscriber(props) {
290140
290342
  mergedObsSets,
290141
290343
  obsSetSelection,
290142
290344
  mergedSampleSets,
290143
- sampleSetSelection
290345
+ sampleSetSelection,
290346
+ obsIndex
290144
290347
  // TODO: consider filtering-related coordination values
290145
290348
  ]);
290349
+ const totalObsCount = (obsIndex == null ? void 0 : obsIndex.length) || 0;
290350
+ const totalSampleCount = (sampleIndex == null ? void 0 : sampleIndex.length) || 0;
290351
+ const selectedObsCount = obsCounts.reduce((a2, h2) => a2 + h2.value, 0);
290352
+ const selectedSampleCount = sampleCounts.reduce((a2, h2) => a2 + h2.value, 0);
290353
+ const unselectedObsCount = totalObsCount - selectedObsCount;
290354
+ const unselectedSampleCount = totalSampleCount - selectedSampleCount;
290146
290355
  const onNodeClick = useCallback((obsSetPath2) => {
290147
290356
  setObsSetSelection([obsSetPath2]);
290148
290357
  }, [setObsSetSelection]);
290149
- return jsxRuntimeExports.jsx(TitleInfo, { title: `Treemap of ${capitalize$2(pluralize(obsType, 2))}`, info: `${commaNumber(obsCount)} ${pluralize(obsType, obsCount)} from ${commaNumber(sampleCount)} ${pluralize(sampleType, sampleCount)}`, removeGridComponent, urls: urls2, theme, isReady, helpText, options: jsxRuntimeExports.jsx(TreemapOptions, { obsType, sampleType, obsColorEncoding, setObsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, setHierarchyLevels }), children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: jsxRuntimeExports.jsx(Treemap, { obsCounts, sampleCounts, obsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, theme, width: width2, height: height2, obsType, sampleType, obsSetColor, sampleSetColor, obsSetSelection, sampleSetSelection, onNodeClick }) }) });
290358
+ return jsxRuntimeExports.jsxs(TitleInfo, { title: `Treemap of ${capitalize$2(pluralize(obsType, 2))}`, info: `${commaNumber(selectedObsCount)} ${pluralize(obsType, selectedObsCount)} from ${commaNumber(selectedSampleCount)} ${pluralize(sampleType, selectedSampleCount)}`, removeGridComponent, urls: urls2, theme, isReady, helpText, withPadding: false, options: jsxRuntimeExports.jsx(TreemapOptions, { obsType, sampleType, obsColorEncoding, setObsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, setHierarchyLevels }), children: [jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: jsxRuntimeExports.jsx(Treemap, { obsCounts, sampleCounts, obsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, theme, width: width2, height: Math.max(height2 * (selectedObsCount / totalObsCount), 40), obsType, sampleType, obsSetColor, sampleSetColor, obsSetSelection, sampleSetSelection, onNodeClick }) }), jsxRuntimeExports.jsx("div", { style: { position: "absolute", right: "2px", bottom: "2px", fontSize: "10px" }, children: unselectedObsCount > 0 ? jsxRuntimeExports.jsx("span", { children: `${commaNumber(unselectedObsCount)} ${pluralize(obsType, unselectedObsCount)} from ${commaNumber(unselectedSampleCount)} ${pluralize(sampleType, unselectedSampleCount)} currently omitted` }) : null })] });
290150
290359
  }
290151
290360
  function VolcanoPlot(props) {
290152
290361
  const { theme, width: width2, height: height2, obsType, featureType, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: data2, marginTop = 5, marginRight = 5, marginLeft = 50, marginBottom = 50, onFeatureClick, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold } = props;
@@ -290303,27 +290512,28 @@ function VolcanoPlotSubscriber(props) {
290303
290512
  }, [setFeatureSelection]);
290304
290513
  return jsxRuntimeExports.jsx(TitleInfo, { title: title2, removeGridComponent, theme, isReady, helpText, options: jsxRuntimeExports.jsx(VolcanoPlotOptions, { obsType, featureType, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold, setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold, setFeatureLabelSignificanceThreshold, setFeatureLabelFoldChangeThreshold }), children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: featureStats ? jsxRuntimeExports.jsx(VolcanoPlot, { theme, width: width2, height: height2, obsType, featureType, obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: featureStats, onFeatureClick, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold }) : jsxRuntimeExports.jsxs("span", { children: ["Select at least one ", obsType, " set."] }) }) });
290305
290514
  }
290515
+ const MAX_BAR_SIZE = 40;
290306
290516
  function CellSetCompositionBarPlot(props) {
290307
- const { data: data2, theme, width: width2, height: height2, marginRight = 200, marginBottom = 120, keyLength = 36, obsType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor } = props;
290517
+ const { data: data2, theme, width: width2, height: heightProp, marginRight = 200, marginBottom = 60, keyLength = 36, obsType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor } = props;
290518
+ const height2 = Array.isArray(obsSetSelection) && (heightProp - marginBottom) / obsSetSelection.length >= MAX_BAR_SIZE ? MAX_BAR_SIZE * obsSetSelection.length + marginBottom : heightProp;
290308
290519
  const [obsSetColorScale, sampleSetColorScale] = useMemo(() => [
290309
290520
  getColorScale(obsSetSelection, obsSetColor, theme),
290310
290521
  getColorScale(sampleSetSelection, sampleSetColor, theme)
290311
290522
  ], [obsSetSelection, sampleSetSelection, sampleSetColor, obsSetColor, theme]);
290312
290523
  const computedData = useMemo(() => {
290313
- var _a3, _b3, _c3, _d3, _e3, _f3, _g3;
290524
+ var _a3, _b3, _c3, _d3, _e3, _f3;
290314
290525
  if (Array.isArray(data2) && data2.length === 1) {
290315
290526
  const { df, metadata: metadata2 } = data2[0];
290316
290527
  const referenceCellType = (_a3 = metadata2 == null ? void 0 : metadata2.analysis_params) == null ? void 0 : _a3.reference_cell_type;
290528
+ const covariateValue = (_b3 = metadata2 == null ? void 0 : metadata2.analysis_params) == null ? void 0 : _b3.covariate_value;
290317
290529
  const coordinationValues = metadata2 == null ? void 0 : metadata2.coordination_values;
290318
- const obsSetColumnName = (_c3 = (_b3 = coordinationValues == null ? void 0 : coordinationValues.obsSetSelection) == null ? void 0 : _b3[0]) == null ? void 0 : _c3[0];
290530
+ const obsSetColumnName = (_d3 = (_c3 = coordinationValues == null ? void 0 : coordinationValues.obsSetSelection) == null ? void 0 : _c3[0]) == null ? void 0 : _d3[0];
290319
290531
  const obsSetGroupName = obsSetsColumnNameMappingReversed == null ? void 0 : obsSetsColumnNameMappingReversed[obsSetColumnName];
290320
- const sampleSetColumnName = (_e3 = (_d3 = coordinationValues == null ? void 0 : coordinationValues.sampleSetFilter) == null ? void 0 : _d3[0]) == null ? void 0 : _e3[0];
290532
+ const sampleSetColumnName = (_f3 = (_e3 = coordinationValues == null ? void 0 : coordinationValues.sampleSetFilter) == null ? void 0 : _e3[0]) == null ? void 0 : _f3[0];
290321
290533
  const sampleSetGroupName = sampleSetsColumnNameMappingReversed == null ? void 0 : sampleSetsColumnNameMappingReversed[sampleSetColumnName];
290322
- const covariatePrefix = `${sampleSetColumnName}T.`;
290323
- const firstCovariateValue = (_g3 = (_f3 = df.covariate) == null ? void 0 : _f3[0]) == null ? void 0 : _g3.substring(covariatePrefix.length);
290324
- const firstCovariateSetPath = [sampleSetGroupName, firstCovariateValue];
290534
+ const covariateSetPath = [sampleSetGroupName, covariateValue];
290325
290535
  let shouldSwapFoldChangeDirection = false;
290326
- if (isEqual$5(firstCovariateSetPath, sampleSetSelection[0])) {
290536
+ if (isEqual$5(covariateSetPath, sampleSetSelection[0])) {
290327
290537
  shouldSwapFoldChangeDirection = true;
290328
290538
  }
290329
290539
  return df.obsSetId.map((obsSetId, i2) => {
@@ -290380,6 +290590,22 @@ function CellSetCompositionBarPlot(props) {
290380
290590
  domain: [true, false],
290381
290591
  range: [2, 0.5]
290382
290592
  };
290593
+ const xExtent = useMemo(() => {
290594
+ if (computedData) {
290595
+ const [min2, max2] = extent$2(computedData.map((d) => d.logFoldChange));
290596
+ const buffer2 = 1.05;
290597
+ const minAbs = Math.abs(min2) * buffer2;
290598
+ const maxAbs = Math.abs(max2) * buffer2;
290599
+ if (minAbs > maxAbs) {
290600
+ return [-minAbs, minAbs];
290601
+ }
290602
+ return [-maxAbs, maxAbs];
290603
+ }
290604
+ return void 0;
290605
+ }, [computedData]);
290606
+ const xScale = {
290607
+ domain: xExtent
290608
+ };
290383
290609
  const spec = {
290384
290610
  mark: { type: "bar", stroke: "black", cursor: "pointer" },
290385
290611
  params: [
@@ -290414,7 +290640,8 @@ function CellSetCompositionBarPlot(props) {
290414
290640
  // TODO: support using intercept+effect here based on user-selected options?
290415
290641
  field: "logFoldChange",
290416
290642
  type: "quantitative",
290417
- title: "Log fold-change"
290643
+ title: "Log fold-change",
290644
+ scale: xScale
290418
290645
  },
290419
290646
  color: {
290420
290647
  field: "key",
@@ -290430,7 +290657,8 @@ function CellSetCompositionBarPlot(props) {
290430
290657
  strokeWidth: {
290431
290658
  field: "isReferenceSet",
290432
290659
  type: "nominal",
290433
- scale: strokeWidthScale
290660
+ scale: strokeWidthScale,
290661
+ legend: null
290434
290662
  },
290435
290663
  tooltip: {
290436
290664
  field: "effectExpectedSample",
@@ -290489,7 +290717,7 @@ function CellSetCompositionBarPlotSubscriber(props) {
290489
290717
  return jsxRuntimeExports.jsx(TitleInfo, { title: `${capitalize$2(obsType)} Set Composition Analysis Plot`, removeGridComponent, theme, isReady, helpText, children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: obsSetStats ? jsxRuntimeExports.jsx(CellSetCompositionBarPlot, { theme, width: width2, height: height2, obsType, obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: obsSetStats, onBarSelect }) : jsxRuntimeExports.jsxs("span", { children: ["Select at least one ", obsType, " set and a pair of ", sampleType, " sets."] }) }) });
290490
290718
  }
290491
290719
  function FeatureSetEnrichmentBarPlot(props) {
290492
- const { data: data2, theme, width: width2, height: height2, marginRight = 200, marginBottom = 120, keyLength = 36, featureType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, pValueThreshold } = props;
290720
+ const { data: data2, theme, width: width2, height: height2, marginRight = 300, marginBottom = 120, keyLength = 36, featureType, onBarSelect, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, pValueThreshold } = props;
290493
290721
  const [obsSetColorScale, sampleSetColorScale] = useMemo(() => [
290494
290722
  getColorScale(obsSetSelection, obsSetColor, theme),
290495
290723
  getColorScale(sampleSetSelection, sampleSetColor, theme)
@@ -290534,7 +290762,7 @@ function FeatureSetEnrichmentBarPlot(props) {
290534
290762
  }
290535
290763
  return [...a2, h2];
290536
290764
  }, []);
290537
- const MAX_ROWS = 25;
290765
+ const MAX_ROWS = 50;
290538
290766
  result = result.slice(0, MAX_ROWS);
290539
290767
  return result;
290540
290768
  }
@@ -290565,7 +290793,7 @@ function FeatureSetEnrichmentBarPlot(props) {
290565
290793
  select: {
290566
290794
  type: "point",
290567
290795
  on: "click[event.shiftKey === false]",
290568
- fields: ["name"],
290796
+ fields: ["name", "term"],
290569
290797
  empty: "none"
290570
290798
  }
290571
290799
  },
@@ -290574,7 +290802,7 @@ function FeatureSetEnrichmentBarPlot(props) {
290574
290802
  select: {
290575
290803
  type: "point",
290576
290804
  on: "click[event.shiftKey]",
290577
- fields: ["name"],
290805
+ fields: ["name", "term"],
290578
290806
  empty: "none"
290579
290807
  }
290580
290808
  }
@@ -290621,10 +290849,11 @@ function FeatureSetEnrichmentBarPlot(props) {
290621
290849
  config: VEGA_THEMES[theme]
290622
290850
  };
290623
290851
  const handleSignal = (name2, value2) => {
290852
+ var _a3, _b3;
290624
290853
  if (name2 === "bar_select") {
290625
- onBarSelect(value2.obsSetPath);
290854
+ onBarSelect((_a3 = value2.name) == null ? void 0 : _a3[0], (_b3 = value2.term) == null ? void 0 : _b3[0]);
290626
290855
  } else if (name2 === "shift_bar_select") {
290627
- onBarSelect(value2.obsSetPath, true);
290856
+ onBarSelect(value2.name, value2.term, true);
290628
290857
  }
290629
290858
  };
290630
290859
  const signalListeners = { bar_select: handleSignal, shift_bar_select: handleSignal };
@@ -290642,7 +290871,7 @@ function FeatureSetEnrichmentBarPlotSubscriber(props) {
290642
290871
  const { coordinationScopes, removeGridComponent, theme, helpText = ViewHelpMapping.FEATURE_SET_ENRICHMENT_BAR_PLOT } = props;
290643
290872
  const classes = useStyles$4();
290644
290873
  const loaders = useLoaders();
290645
- useAsyncFunction(AsyncFunctionType.TRANSFORM_FEATURE);
290874
+ const transformFeature2 = useAsyncFunction(AsyncFunctionType.TRANSFORM_FEATURE);
290646
290875
  const [{ dataset, obsType, sampleType, featureType, featureValueType, obsFilter: cellFilter, obsHighlight: cellHighlight, obsSetSelection, obsSetColor, obsColorEncoding: cellColorEncoding, additionalObsSets: additionalCellSets, featurePointSignificanceThreshold, featurePointFoldChangeThreshold, featureLabelSignificanceThreshold, featureLabelFoldChangeThreshold, featureValueTransform, featureValueTransformCoefficient, gatingFeatureSelectionX, gatingFeatureSelectionY, featureSelection, sampleSetSelection, sampleSetColor }, { setObsFilter: setCellFilter, setObsSetSelection, setObsHighlight: setCellHighlight, setObsSetColor: setCellSetColor, setObsColorEncoding: setCellColorEncoding, setAdditionalObsSets: setAdditionalCellSets, setFeaturePointSignificanceThreshold, setFeaturePointFoldChangeThreshold, setFeatureLabelSignificanceThreshold, setFeatureLabelFoldChangeThreshold, setFeatureValueTransform, setFeatureValueTransformCoefficient, setGatingFeatureSelectionX, setGatingFeatureSelectionY, setFeatureSelection, setSampleSetSelection, setSampleSetColor }] = useCoordination(COMPONENT_COORDINATION_TYPES[ViewType$1.FEATURE_SET_ENRICHMENT_BAR_PLOT], coordinationScopes);
290647
290876
  const [width2, height2, containerRef] = useGridItemSize();
290648
290877
  const obsSetsLoader = useMatchingLoader(loaders, dataset, DataType$3.OBS_SETS, { obsType });
@@ -290665,6 +290894,11 @@ function FeatureSetEnrichmentBarPlotSubscriber(props) {
290665
290894
  featureSetStatsStatus
290666
290895
  ]);
290667
290896
  const onBarSelect = useCallback(async (featureSetName, featureSetTerm, isShiftDown = false) => {
290897
+ const kgNode = { nodeType: "pathway", term: featureSetTerm };
290898
+ const targetFeatureType = featureType;
290899
+ const targetsInPathway = await transformFeature2(kgNode, targetFeatureType);
290900
+ const featureIds = targetsInPathway.filter((d, i2) => i2 < 10).map((d) => d.label);
290901
+ setFeatureSelection(featureIds);
290668
290902
  }, [setFeatureSelection]);
290669
290903
  return jsxRuntimeExports.jsx(TitleInfo, { title: `${capitalize$2(featureType)} Set Enrichment Plot`, removeGridComponent, theme, isReady, helpText, children: jsxRuntimeExports.jsx("div", { ref: containerRef, className: classes.vegaContainer, children: featureSetStats ? jsxRuntimeExports.jsx(FeatureSetEnrichmentBarPlot, { theme, width: width2, height: height2, obsType, featureType, obsSetsColumnNameMapping, obsSetsColumnNameMappingReversed, sampleSetsColumnNameMapping, sampleSetsColumnNameMappingReversed, sampleSetSelection, obsSetSelection, obsSetColor, sampleSetColor, data: featureSetStats, onBarSelect, pValueThreshold: 0.01 }) : jsxRuntimeExports.jsxs("span", { children: ["Select at least one ", obsType, " set."] }) }) });
290670
290904
  }
@@ -296346,79 +296580,88 @@ class MoleculesJsonAsObsLocationsLoader extends JsonLoader {
296346
296580
  }
296347
296581
  }
296348
296582
  async function initLoader(imageData) {
296349
- const { type: type2, url, metadata: metadata2, requestInit: requestInit2 } = imageData;
296350
- switch (type2) {
296351
- case "zarr": {
296352
- const { dimensions, isPyramid, transform: transform4 } = metadata2 || {};
296353
- const labels2 = dimensions.map((d) => d.field);
296354
- let source2;
296355
- const root2 = await zarrOpenRoot(url, null, { requestInit: requestInit2 });
296356
- if (isPyramid) {
296357
- const metadataUrl = `${url}${url.slice(-1) === "/" ? "" : "/"}.zmetadata`;
296358
- const response = await fetch(metadataUrl);
296359
- const { metadata: zarrMetadata } = await response.json();
296360
- const paths = Object.keys(zarrMetadata).filter((metaKey) => metaKey.includes(".zarray")).map((arrMetaKeys) => arrMetaKeys.slice(0, -7));
296361
- const data2 = await Promise.all(paths.map((path2) => open$1(root2.resolve(path2), { kind: "array" })));
296362
- const tileSize = guessTileSize(data2[0]);
296363
- source2 = data2.map((d) => new ZarritaPixelSource(createZarrArrayAdapter(d), labels2, tileSize));
296364
- } else {
296365
- const data2 = await open$1(root2, { kind: "array" });
296366
- source2 = new ZarritaPixelSource(createZarrArrayAdapter(data2), labels2);
296367
- }
296368
- return { data: source2, metadata: { dimensions, transform: transform4 }, channels: (dimensions.find((d) => d.field === "channel") || dimensions[0]).values };
296369
- }
296370
- case "ome-tiff": {
296371
- let loader2;
296372
- if (metadata2 && "omeTiffOffsetsUrl" in metadata2) {
296373
- const { omeTiffOffsetsUrl } = metadata2;
296374
- const res = await fetch(omeTiffOffsetsUrl, requestInit2 || {});
296375
- if (res.ok) {
296376
- const offsets2 = await res.json();
296377
- loader2 = await loadOmeTiff(url, {
296378
- offsets: offsets2,
296379
- headers: requestInit2 == null ? void 0 : requestInit2.headers
296380
- });
296583
+ try {
296584
+ const { type: type2, url, metadata: metadata2, requestInit: requestInit2 } = imageData;
296585
+ switch (type2) {
296586
+ case "zarr": {
296587
+ const { dimensions, isPyramid, transform: transform4 } = metadata2 || {};
296588
+ const labels2 = dimensions.map((d) => d.field);
296589
+ let source2;
296590
+ const root2 = await zarrOpenRoot(url, null, { requestInit: requestInit2 });
296591
+ if (isPyramid) {
296592
+ const metadataUrl = `${url}${url.slice(-1) === "/" ? "" : "/"}.zmetadata`;
296593
+ const response = await fetch(metadataUrl);
296594
+ if (!response.ok)
296595
+ throw new Error(`Failed to fetch metadata: ${response.status}`);
296596
+ const { metadata: zarrMetadata } = await response.json();
296597
+ const paths = Object.keys(zarrMetadata).filter((metaKey) => metaKey.includes(".zarray")).map((arrMetaKeys) => arrMetaKeys.slice(0, -7));
296598
+ const data2 = await Promise.all(paths.map((path2) => open$1(root2.resolve(path2), { kind: "array" })));
296599
+ const tileSize = guessTileSize(data2[0]);
296600
+ source2 = data2.map((d) => new ZarritaPixelSource(createZarrArrayAdapter(d), labels2, tileSize));
296381
296601
  } else {
296382
- throw new Error(`Offsets not found but provided: ${res.status} from ${res.url}`);
296602
+ const data2 = await open$1(root2, { kind: "array" });
296603
+ source2 = new ZarritaPixelSource(createZarrArrayAdapter(data2), labels2);
296383
296604
  }
296384
- } else {
296385
- loader2 = await loadOmeTiff(url, { headers: requestInit2 == null ? void 0 : requestInit2.headers });
296386
- }
296387
- const { Pixels: { Channels } } = loader2.metadata;
296388
- const channels2 = Array.isArray(Channels) ? Channels.map((channel, i2) => channel.Name || `Channel ${i2}`) : [Channels.Name || `Channel ${0}`];
296389
- return { ...loader2, channels: channels2 };
296390
- }
296391
- case "ome-zarr": {
296392
- const { coordinateTransformations: coordinateTransformationsFromOptions } = metadata2 || {};
296393
- const root2 = await zarrOpenRoot(url, null, { requestInit: requestInit2 });
296394
- const loader2 = await loadOmeZarr(root2);
296395
- const { metadata: loaderMetadata } = loader2;
296396
- const { omero, multiscales } = loaderMetadata;
296397
- if (!Array.isArray(multiscales) || multiscales.length === 0) {
296398
- log$c.error("Multiscales array must exist and have at least one element");
296399
- }
296400
- const { coordinateTransformations } = multiscales[0];
296401
- const axes = getNgffAxes(multiscales[0].axes);
296402
- const transformMatrixFromOptions = coordinateTransformationsToMatrix(coordinateTransformationsFromOptions, axes);
296403
- const transformMatrixFromFile = coordinateTransformationsToMatrix(coordinateTransformations, axes);
296404
- const transformMatrix = transformMatrixFromFile.multiplyLeft(transformMatrixFromOptions);
296405
- const { channels: channels2, name: omeroName } = omero;
296406
- return {
296407
- name: omeroName || "Image",
296408
- channels: channels2.map((c2, i2) => c2.label || `Channel ${i2}`),
296409
- ...transformMatrix ? {
296410
- metadata: {
296411
- transform: {
296412
- matrix: transformMatrix
296413
- }
296605
+ return {
296606
+ data: source2,
296607
+ metadata: { dimensions, transform: transform4 },
296608
+ channels: (dimensions.find((d) => d.field === "channel") || dimensions[0]).values
296609
+ };
296610
+ }
296611
+ case "ome-tiff": {
296612
+ let loader2;
296613
+ if (metadata2 == null ? void 0 : metadata2.omeTiffOffsetsUrl) {
296614
+ try {
296615
+ const res = await fetch(metadata2.omeTiffOffsetsUrl, requestInit2 || {});
296616
+ if (!res.ok)
296617
+ throw new Error(`Offsets not found: ${res.status} from ${res.url}`);
296618
+ const offsets2 = await res.json();
296619
+ loader2 = await loadOmeTiff(url, {
296620
+ offsets: offsets2,
296621
+ headers: requestInit2 == null ? void 0 : requestInit2.headers
296622
+ });
296623
+ } catch (err2) {
296624
+ log$c.error("Error loading OME-TIFF offsets:", err2);
296625
+ throw err2;
296414
296626
  }
296415
- } : {},
296416
- ...loader2
296417
- };
296418
- }
296419
- default: {
296420
- throw Error(`Image type (${type2}) is not supported`);
296627
+ } else {
296628
+ loader2 = await loadOmeTiff(url, { headers: requestInit2 == null ? void 0 : requestInit2.headers });
296629
+ }
296630
+ const { Pixels: { Channels } } = loader2.metadata;
296631
+ const channels2 = Array.isArray(Channels) ? Channels.map((channel, i2) => channel.Name || `Channel ${i2}`) : [Channels.Name || `Channel ${0}`];
296632
+ return { ...loader2, channels: channels2 };
296633
+ }
296634
+ case "ome-zarr": {
296635
+ const { coordinateTransformations: coordinateTransformationsFromOptions } = metadata2 || {};
296636
+ const root2 = await zarrOpenRoot(url, null, { requestInit: requestInit2 });
296637
+ const loader2 = await loadOmeZarr(root2);
296638
+ const { metadata: loaderMetadata } = loader2;
296639
+ const { omero, multiscales } = loaderMetadata;
296640
+ if (!Array.isArray(multiscales) || multiscales.length === 0) {
296641
+ throw new Error("Multiscales array must exist and have at least one element");
296642
+ }
296643
+ const { coordinateTransformations } = multiscales[0];
296644
+ const axes = getNgffAxes(multiscales[0].axes);
296645
+ const transformMatrixFromOptions = coordinateTransformationsToMatrix(coordinateTransformationsFromOptions, axes);
296646
+ const transformMatrixFromFile = coordinateTransformationsToMatrix(coordinateTransformations, axes);
296647
+ const transformMatrix = transformMatrixFromFile.multiplyLeft(transformMatrixFromOptions);
296648
+ const { channels: channels2, name: omeroName } = omero;
296649
+ return {
296650
+ name: omeroName || "Image",
296651
+ channels: channels2.map((c2, i2) => c2.label || `Channel ${i2}`),
296652
+ ...transformMatrix ? { metadata: { transform: { matrix: transformMatrix } } } : {},
296653
+ ...loader2
296654
+ };
296655
+ }
296656
+ default: {
296657
+ const errorMessage = `Image type (${type2}) is not supported`;
296658
+ log$c.error(errorMessage);
296659
+ throw new Error(errorMessage);
296660
+ }
296421
296661
  }
296662
+ } catch (error2) {
296663
+ log$c.error("Error in initLoader:", error2);
296664
+ throw error2;
296422
296665
  }
296423
296666
  }
296424
296667
  class RasterLoader extends JsonLoader {
@@ -296573,6 +296816,15 @@ function basename(path2) {
296573
296816
  }
296574
296817
  return result;
296575
296818
  }
296819
+ function prependSlash(path2) {
296820
+ if (typeof path2 === "string" && path2.length >= 1) {
296821
+ if (path2.charAt(0) === "/") {
296822
+ return path2;
296823
+ }
296824
+ return `/${path2}`;
296825
+ }
296826
+ return path2;
296827
+ }
296576
296828
  class AnnDataSource extends ZarrDataSource {
296577
296829
  /**
296578
296830
  *
@@ -296640,29 +296892,33 @@ class AnnDataSource extends ZarrDataSource {
296640
296892
  }
296641
296893
  /**
296642
296894
  *
296643
- * @param {string} path
296895
+ * @param {string} pathOrig
296644
296896
  * @returns
296645
296897
  */
296646
- async _loadColumn(path2) {
296898
+ async _loadColumn(pathOrig) {
296647
296899
  const { storeRoot } = this;
296648
- const prefix2 = dirname(path2);
296900
+ const path2 = prependSlash(pathOrig);
296901
+ const prefixOrig = dirname(path2);
296902
+ const prefix2 = prependSlash(prefixOrig);
296649
296903
  const { categories, "encoding-type": encodingType } = await this.getJson(`${path2}/.zattrs`);
296650
296904
  let categoriesValues;
296651
296905
  let codesPath;
296652
296906
  if (categories) {
296653
- const { dtype } = await open$1(storeRoot.resolve(`/${prefix2}/${categories}`), { kind: "array" });
296654
- if (dtype === "v2:object") {
296655
- categoriesValues = await this.getFlatArrDecompressed(`/${prefix2}/${categories}`);
296907
+ const { dtype } = await open$1(storeRoot.resolve(`${prefix2}/${categories}`), { kind: "array" });
296908
+ if (dtype === "v2:object" || dtype === "|O") {
296909
+ categoriesValues = await this.getFlatArrDecompressed(`${prefix2}/${categories}`);
296656
296910
  }
296657
296911
  } else if (encodingType === "categorical") {
296658
- const { dtype } = await open$1(storeRoot.resolve(`/${path2}/categories`), { kind: "array" });
296659
- if (dtype === "v2:object") {
296660
- categoriesValues = await this.getFlatArrDecompressed(`/${path2}/categories`);
296912
+ const { dtype } = await open$1(storeRoot.resolve(`${path2}/categories`), { kind: "array" });
296913
+ if (dtype === "v2:object" || dtype === "|O") {
296914
+ categoriesValues = await this.getFlatArrDecompressed(`${path2}/categories`);
296661
296915
  }
296662
- codesPath = `/${path2}/codes`;
296916
+ codesPath = `${path2}/codes`;
296917
+ } else if (encodingType === "string-array") {
296918
+ return this.getFlatArrDecompressed(path2);
296663
296919
  } else {
296664
- const { dtype } = await open$1(storeRoot.resolve(`/${path2}`), { kind: "array" });
296665
- if (dtype === "v2:object") {
296920
+ const { dtype } = await open$1(storeRoot.resolve(path2), { kind: "array" });
296921
+ if (dtype === "v2:object" || dtype === "|O") {
296666
296922
  return this.getFlatArrDecompressed(path2);
296667
296923
  }
296668
296924
  }
@@ -296736,7 +296992,7 @@ class AnnDataSource extends ZarrDataSource {
296736
296992
  if (this.obsIndex) {
296737
296993
  return this.obsIndex;
296738
296994
  }
296739
- this.obsIndex = this.getJson("obs/.zattrs").then(({ _index }) => this.getFlatArrDecompressed(`/obs/${_index}`));
296995
+ this.obsIndex = this.getJson("obs/.zattrs").then(({ _index }) => this._loadColumn(`/obs/${_index}`));
296740
296996
  return this.obsIndex;
296741
296997
  }
296742
296998
  /**
@@ -296747,7 +297003,7 @@ class AnnDataSource extends ZarrDataSource {
296747
297003
  */
296748
297004
  loadDataFrameIndex(path2 = void 0) {
296749
297005
  const dfPath = path2 ? dirname(path2) : "";
296750
- return this.getJson(`${dfPath}/.zattrs`).then(({ _index }) => this.getFlatArrDecompressed(`${dfPath.length > 0 ? "/" : ""}${dfPath}/${_index}`));
297006
+ return this.getJson(`${dfPath}/.zattrs`).then(({ _index }) => this._loadColumn(`${dfPath.length > 0 ? "/" : ""}${dfPath}/${_index}`));
296751
297007
  }
296752
297008
  /**
296753
297009
  * Class method for loading the var index.
@@ -296758,7 +297014,7 @@ class AnnDataSource extends ZarrDataSource {
296758
297014
  if (this.varIndex) {
296759
297015
  return this.varIndex;
296760
297016
  }
296761
- this.varIndex = this.getJson("var/.zattrs").then(({ _index }) => this.getFlatArrDecompressed(`/var/${_index}`));
297017
+ this.varIndex = this.getJson("var/.zattrs").then(({ _index }) => this._loadColumn(`/var/${_index}`));
296762
297018
  return this.varIndex;
296763
297019
  }
296764
297020
  /**
@@ -297549,6 +297805,11 @@ class ObsSegmentationsAnndataLoader extends AbstractTwoStepLoader {
297549
297805
  }
297550
297806
  }
297551
297807
  class ObsSetsAnndataLoader extends AbstractTwoStepLoader {
297808
+ constructor(dataSource, params2) {
297809
+ super(dataSource, params2);
297810
+ this.region = null;
297811
+ this.tablePath = null;
297812
+ }
297552
297813
  loadObsIndices() {
297553
297814
  var _a3;
297554
297815
  const { options } = this;
@@ -297583,7 +297844,7 @@ class ObsSetsAnndataLoader extends AbstractTwoStepLoader {
297583
297844
  if (!this.cachedResult) {
297584
297845
  const { options } = this;
297585
297846
  this.cachedResult = Promise.all([
297586
- this.dataSource.loadObsIndex(),
297847
+ this.dataSource.loadObsIndex(this.tablePath),
297587
297848
  this.loadObsIndices(),
297588
297849
  this.loadCellSetIds(),
297589
297850
  this.loadCellSetScores()
@@ -297911,11 +298172,11 @@ let FeatureStatsAnndataLoader$1 = class FeatureStatsAnndataLoader extends Abstra
297911
298172
  const rawSampleSetSelection = sampleSetSelection;
297912
298173
  if (sampleSetSelection) {
297913
298174
  if (sampleSetSelection.length !== 2) {
297914
- return Promise.reject(new Error("Expected exactly two sample sets for volcano plot."));
298175
+ return null;
297915
298176
  }
297916
298177
  }
297917
298178
  if (!obsSetSelection) {
297918
- return Promise.reject(new Error("Expected obsSetSelection to be present."));
298179
+ return null;
297919
298180
  }
297920
298181
  const metadata2 = await this.loadMetadata();
297921
298182
  const matchingComparisons = [];
@@ -297988,9 +298249,21 @@ class FeatureStatsAnndataLoader2 extends AbstractTwoStepLoader {
297988
298249
  this.loadFeatureSetTerms(dfPath),
297989
298250
  this.loadSignificances(dfPath)
297990
298251
  ]);
298252
+ const cleanName = (s2) => {
298253
+ if (s2.includes("R-HSA-")) {
298254
+ return s2.substring(0, s2.indexOf("R-HSA-") - 1);
298255
+ }
298256
+ return s2;
298257
+ };
298258
+ const cleanTerm = (s2) => {
298259
+ if (s2.includes("R-HSA-")) {
298260
+ return `REACTOME:${s2.substring(s2.indexOf("R-HSA-"))}`;
298261
+ }
298262
+ return s2;
298263
+ };
297991
298264
  return {
297992
- featureSetName,
297993
- featureSetTerm,
298265
+ featureSetName: featureSetName.map((s2) => cleanName(s2)),
298266
+ featureSetTerm: featureSetTerm.map((s2) => cleanTerm(s2)),
297994
298267
  featureSetSignificance
297995
298268
  };
297996
298269
  }
@@ -298019,30 +298292,31 @@ class FeatureStatsAnndataLoader2 extends AbstractTwoStepLoader {
298019
298292
  * @returns {Promise<LoaderResult<FeatureStatsData>>}
298020
298293
  */
298021
298294
  async loadMulti(volcanoOptions) {
298022
- const { analysisType: targetAnalysisType = "pertpy_hypergeometric" } = this.options;
298295
+ const { analysisType: targetAnalysisType = "pertpy_hypergeometric", featureSetLibrary: targetFeatureSetLibrary = "Reactome_2022" } = this.options;
298023
298296
  const { sampleSetSelection, obsSetSelection } = volcanoOptions || {};
298024
298297
  const rawObsSetSelection = obsSetSelection;
298025
298298
  const rawSampleSetSelection = sampleSetSelection;
298026
298299
  if (sampleSetSelection) {
298027
298300
  if (sampleSetSelection.length !== 2) {
298028
- return Promise.reject(new Error("Expected exactly two sample sets for volcano plot."));
298301
+ return null;
298029
298302
  }
298030
298303
  }
298031
298304
  if (!obsSetSelection) {
298032
- return Promise.reject(new Error("Expected obsSetSelection to be present."));
298305
+ return null;
298033
298306
  }
298034
298307
  const metadata2 = await this.loadMetadata();
298035
298308
  const matchingComparisons = [];
298036
298309
  Object.values(metadata2.comparisons).forEach((comparisonGroupObject) => {
298037
298310
  const { results } = comparisonGroupObject;
298038
298311
  results.forEach((resultObject) => {
298312
+ var _a3;
298039
298313
  const {
298040
298314
  analysis_type,
298041
- // analysis_params,
298315
+ analysis_params,
298042
298316
  coordination_values
298043
298317
  // path,
298044
298318
  } = resultObject;
298045
- if (analysis_type === targetAnalysisType) {
298319
+ if (analysis_type === targetAnalysisType && ((_a3 = analysis_params == null ? void 0 : analysis_params.pertpy_hypergeometric) == null ? void 0 : _a3.enrichr_library_name) === targetFeatureSetLibrary) {
298046
298320
  if (sampleSetSelection) {
298047
298321
  rawObsSetSelection.forEach((obsSetPath2) => {
298048
298322
  if (isEqual$5([obsSetPath2], coordination_values.obsSetFilter)) {
@@ -298115,10 +298389,6 @@ class ObsSetStatsAnndataLoader extends AbstractTwoStepLoader {
298115
298389
  }
298116
298390
  return values3.data;
298117
298391
  }
298118
- async loadCovariate(dfPath) {
298119
- const { covariateColumn } = this.options;
298120
- return this.dataSource._loadColumn(`${dfPath}/${covariateColumn}`);
298121
- }
298122
298392
  async loadObsSetNames(dfPath) {
298123
298393
  const { indexColumn } = this.options;
298124
298394
  if (indexColumn) {
@@ -298132,28 +298402,23 @@ class ObsSetStatsAnndataLoader extends AbstractTwoStepLoader {
298132
298402
  obsSetFoldChange,
298133
298403
  interceptExpectedSample,
298134
298404
  effectExpectedSample,
298135
- isCredibleEffect,
298405
+ isCredibleEffect
298136
298406
  // TODO: rather than passing this down,
298137
298407
  // do the fold change direction swapping in the loader
298138
298408
  // (as opposed to in the view).
298139
- // TODO: also, see https://github.com/keller-mark/compasce/issues/30
298140
- // which would allow not loading this column altogether.
298141
- covariate
298142
298409
  ] = await Promise.all([
298143
298410
  this.loadObsSetNames(dfPath),
298144
298411
  this.loadFoldChanges(dfPath),
298145
298412
  this.loadInterceptValues(dfPath),
298146
298413
  this.loadEffectValues(dfPath),
298147
- this.loadIsCredible(dfPath),
298148
- this.loadCovariate(dfPath)
298414
+ this.loadIsCredible(dfPath)
298149
298415
  ]);
298150
298416
  return {
298151
298417
  obsSetId,
298152
298418
  obsSetFoldChange,
298153
298419
  interceptExpectedSample,
298154
298420
  effectExpectedSample,
298155
- isCredibleEffect,
298156
- covariate
298421
+ isCredibleEffect
298157
298422
  };
298158
298423
  }
298159
298424
  /**
@@ -298186,10 +298451,10 @@ class ObsSetStatsAnndataLoader extends AbstractTwoStepLoader {
298186
298451
  const rawObsSetSelection = obsSetSelection;
298187
298452
  const rawSampleSetSelection = sampleSetSelection;
298188
298453
  if (!sampleSetSelection || (sampleSetSelection == null ? void 0 : sampleSetSelection.length) !== 2) {
298189
- return Promise.reject(new Error("Expected exactly two sample sets for cell type composition analysis plot."));
298454
+ return null;
298190
298455
  }
298191
298456
  if (!obsSetSelection) {
298192
- return Promise.reject(new Error("Expected obsSetSelection to be present."));
298457
+ return null;
298193
298458
  }
298194
298459
  const metadata2 = await this.loadMetadata();
298195
298460
  const rawObsSetGroups = Array.from(new Set(rawObsSetSelection.map((setPath) => setPath == null ? void 0 : setPath[0])));
@@ -298897,18 +299162,19 @@ class SpatialDataObsSetsLoader extends ObsSetsAnndataLoader {
298897
299162
  constructor(dataSource, params2) {
298898
299163
  super(dataSource, params2);
298899
299164
  this.region = this.options.region;
299165
+ this.tablePath = this.options.tablePath;
298900
299166
  }
298901
299167
  }
298902
- const pluralRegex = /^tables\/([^/]*)\/(.*)$/;
298903
- const singularRegex = /^table\/([^/]*)\/(.*)$/;
299168
+ const pluralRegex = /^tables\/([^/]*)(\/?)(.*)$/;
299169
+ const singularRegex = /^table\/([^/]*)(\/?)(.*)$/;
298904
299170
  function getTablePrefix(arrPath) {
298905
299171
  if (arrPath) {
298906
299172
  const pluralMatches = arrPath.match(pluralRegex);
298907
- if (pluralMatches && pluralMatches.length === 3) {
299173
+ if (pluralMatches && pluralMatches.length >= 3) {
298908
299174
  return `tables/${pluralMatches[1]}/`;
298909
299175
  }
298910
299176
  const singularMatches = arrPath.match(singularRegex);
298911
- if (singularMatches && singularMatches.length === 3) {
299177
+ if (singularMatches && singularMatches.length >= 3) {
298912
299178
  return `table/${singularMatches[1]}/`;
298913
299179
  }
298914
299180
  }
@@ -351498,7 +351764,7 @@ function loadPathwayNodes() {
351498
351764
  kgId: d.id,
351499
351765
  label: d.pathway,
351500
351766
  // For reactome
351501
- term: `reactome:${d.acc}`,
351767
+ term: `REACTOME:${d.acc}`,
351502
351768
  // For reactome
351503
351769
  // label: d.ontology_label, // For GO_BP
351504
351770
  // term: d.acc, // For GO_BP
@@ -351565,7 +351831,11 @@ async function loadPathwayToGeneEdges() {
351565
351831
  }));
351566
351832
  });
351567
351833
  }
351568
- async function transformFeature({ queryClient }, node2, targetModality) {
351834
+ async function transformFeature({ queryClient }, nodeOrig, targetModality) {
351835
+ var _a3;
351836
+ const node2 = {
351837
+ ...nodeOrig
351838
+ };
351569
351839
  if (targetModality === node2.nodeType) {
351570
351840
  return [node2];
351571
351841
  }
@@ -351581,6 +351851,19 @@ async function transformFeature({ queryClient }, node2, targetModality) {
351581
351851
  staleTime: Infinity,
351582
351852
  queryFn: loadPathwayToGeneEdges
351583
351853
  });
351854
+ if (!node2.kgId) {
351855
+ const pathwayNodes = await queryClient.fetchQuery({
351856
+ queryKey: ["pathwayNodes"],
351857
+ staleTime: Infinity,
351858
+ queryFn: loadPathwayNodes
351859
+ });
351860
+ const foundId = (_a3 = pathwayNodes.find((n3) => n3.term === node2.term)) == null ? void 0 : _a3.kgId;
351861
+ if (foundId) {
351862
+ node2.kgId = foundId;
351863
+ } else {
351864
+ console.warn("Could not find matching pathway node based on term.");
351865
+ }
351866
+ }
351584
351867
  const matchingEdges = pathwayGeneEdges.filter((d) => d.source === node2.kgId);
351585
351868
  const matchingGeneIds = matchingEdges.map((d) => d.target);
351586
351869
  const matchingGenes = geneNodes.filter((d) => matchingGeneIds.includes(d.kgId));
@@ -352469,6 +352752,17 @@ const baseCoordinationTypes = [
352469
352752
  null,
352470
352753
  z.array(z.string()).nullable()
352471
352754
  ),
352755
+ new PluginCoordinationType(CoordinationType$1.FEATURE_AGGREGATION_STRATEGY, null, z.union([
352756
+ z.enum([
352757
+ "first",
352758
+ "last",
352759
+ "mean",
352760
+ "sum",
352761
+ "difference"
352762
+ ]),
352763
+ // An index of a featureSelection array element.
352764
+ z.number()
352765
+ ]).nullable()),
352472
352766
  new PluginCoordinationType(
352473
352767
  CoordinationType$1.FEATURE_SET_SELECTION,
352474
352768
  null,