@vitessce/launcher 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@ import { jsxs, jsx } from "react/jsx-runtime";
2
2
  import { useRef, useEffect, useState } from "react";
3
3
  import { useThree, useFrame } from "@react-three/fiber";
4
4
  import { Bvh } from "@react-three/drei";
5
- import { useXR, useXRInputSourceState } from "@react-three/xr";
6
5
  import { Matrix4, Vector3, Box3, FrontSide } from "three";
7
- import { i as isValidGeometrySize, M as MeasureLine, s as stringifyLineData } from "./index-C2U2CO2P.js";
6
+ import { g as getXRModule, i as isValidGeometrySize, M as MeasureLine, s as stringifyLineData } from "./index-BlOIc49f.js";
7
+ const { useXR, useXRInputSourceState } = getXRModule();
8
8
  function getHandJoint(hand, jointName) {
9
9
  return hand.get(jointName);
10
10
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import React__default from "react";
3
- import { a as getDefaultExportFromCjs, d as requireAssign, f as require_export, h as require_core, j as require_fails, k as require_toObject, m as require_objectKeys, n as require_cof, o as require_wks, p as require_iterators, q as requireWeb_dom_iterable, s as requireEs6_string_iterator, t as require_anObject, v as require_hide, w as require_ctx, x as require_toLength, y as require_global, z as require_objectDp, A as require_descriptors, D as require_isObject, E as require_objectCreate, F as require_iterDefine, G as require_iterStep, H as require_meta, I as require_isArray, J as require_iobject, K as require_setToStringTag, M as require_aFunction, N as requireIterator, O as require_propertyDesc, c as commonjsGlobal, P as requireEs6_symbol, Q as requireDefineProperty, R as require_toIobject, S as require_objectGopd, T as require_html, U as require_domCreate, V as require_library, W as requireSymbol, X as require_objectPie, Y as require_has, Z as require_redefine, _ as require_objectAssign, $ as diffCameraState } from "./index-DDD3apxS.js";
3
+ import { a as getDefaultExportFromCjs, d as requireAssign, f as require_export, h as require_core, j as require_fails, k as require_toObject, m as require_objectKeys, n as require_cof, o as require_wks, p as require_iterators, q as requireWeb_dom_iterable, s as requireEs6_string_iterator, t as require_anObject, v as require_hide, w as require_ctx, x as require_toLength, y as require_global, z as require_objectDp, A as require_descriptors, D as require_isObject, E as require_objectCreate, F as require_iterDefine, G as require_iterStep, H as require_meta, I as require_isArray, J as require_iobject, K as require_setToStringTag, M as require_aFunction, N as requireIterator, O as require_propertyDesc, c as commonjsGlobal, P as requireEs6_symbol, Q as requireDefineProperty, R as require_toIobject, S as require_objectGopd, T as require_html, U as require_domCreate, V as require_library, W as requireSymbol, X as require_objectPie, Y as require_has, Z as require_redefine, _ as require_objectAssign, $ as diffCameraState } from "./index-DYR0bplz.js";
4
4
  var assignExports = requireAssign();
5
5
  const _Object$assign = /* @__PURE__ */ getDefaultExportFromCjs(assignExports);
6
6
  var es6_object_keys = {};
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
- import { x as xrStore } from "./xrStore-BymedRtx.js";
3
+ import { x as xrStore } from "./xrStore-D3LG-myx.js";
4
4
  function XREnterButton() {
5
5
  const [supported, setSupported] = useState(false);
6
6
  const [entered, setEntered] = useState(false);
@@ -1,7 +1,8 @@
1
1
  import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
2
  import { useRef } from "react";
3
- import { useXRInputSourceState, useXR } from "@react-three/xr";
4
3
  import { useThree, useFrame } from "@react-three/fiber";
4
+ import { g as getXRModule } from "./index-BlOIc49f.js";
5
+ const { useXRInputSourceState } = getXRModule();
5
6
  function getHandJoint(hand, jointName) {
6
7
  return hand.get(jointName);
7
8
  }
@@ -38,6 +39,7 @@ function HandBbox() {
38
39
  });
39
40
  return jsxs(Fragment, { children: [jsxs("mesh", { name: "leftTipBbox", ref: leftTipRef, children: [jsx("boxGeometry", { args: [0.02, 0.02, 0.02] }), jsx("meshStandardMaterial", { color: "blue", transparent: true, opacity: 0 })] }), jsxs("mesh", { name: "rightTipBbox", ref: rightTipRef, children: [jsx("boxGeometry", { args: [0.02, 0.02, 0.02] }), jsx("meshStandardMaterial", { color: "orange", transparent: true, opacity: 0 })] })] });
40
41
  }
42
+ const { useXR } = getXRModule();
41
43
  function HandDecorate() {
42
44
  const session = useXR((state) => state.session);
43
45
  const { scene } = useThree();
@@ -1,6 +1,7 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { XR } from "@react-three/xr";
3
- import { x as xrStore } from "./xrStore-BymedRtx.js";
2
+ import { g as getXRModule } from "./index-BlOIc49f.js";
3
+ import { x as xrStore } from "./xrStore-D3LG-myx.js";
4
+ const { XR } = getXRModule();
4
5
  function XRWrapper({ children }) {
5
6
  return jsx(XR, { store: xrStore, children });
6
7
  }
@@ -1,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-SxljTded.js";
2
- import { B as BaseDecoder } from "./index-DDD3apxS.js";
2
+ import { B as BaseDecoder } from "./index-DYR0bplz.js";
3
3
  class DeflateDecoder extends BaseDecoder {
4
4
  decodeBlock(buffer) {
5
5
  return inflate_1(new Uint8Array(buffer)).buffer;
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import React__default, { createContext, isValidElement, PureComponent, Component, useMemo, useState, useRef, useEffect, useCallback, memo, useContext, useReducer, useLayoutEffect } from "react";
3
- import { r as requireObjectAssign, a as getDefaultExportFromCjs$1, c as commonjsGlobal, e as earcut } from "./index-DDD3apxS.js";
3
+ import { r as requireObjectAssign, a as getDefaultExportFromCjs$1, c as commonjsGlobal, e as earcut } from "./index-DYR0bplz.js";
4
4
  import ReactDOM__default, { unstable_batchedUpdates, createPortal } from "react-dom";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  function finallyConstructor(callback) {
@@ -4,7 +4,7 @@ import { useThree, useFrame, Canvas } from "@react-three/fiber";
4
4
  import { OrbitControls } from "@react-three/drei";
5
5
  import * as THREE from "three";
6
6
  import { Data3DTexture, RedFormat, UnsignedByteType, LinearFilter, RedIntegerFormat, UnsignedIntType, NearestFilter, Vector3, Vector2, Vector4, UniformsUtils } from "three";
7
- import { l as log, i as isEqual, C as CoordinationType, u as useEventCallback } from "./index-DDD3apxS.js";
7
+ import { l as log, i as isEqual, C as CoordinationType, u as useEventCallback } from "./index-DYR0bplz.js";
8
8
  const LogLevel = {
9
9
  INFO: "info",
10
10
  WARN: "warn",
@@ -3,7 +3,7 @@ import React__default, { useRef, useState, useEffect, Suspense, forwardRef } fro
3
3
  import { Canvas } from "@react-three/fiber";
4
4
  import { Center, Text, Line, Bvh, OrbitControls } from "@react-three/drei";
5
5
  import { Matrix3, Matrix4, Vector3, Vector2, UniformsUtils, Data3DTexture, RedFormat, FloatType, LinearFilter, FrontSide, Scene, Group, MeshPhysicalMaterial, MeshBasicMaterial, MeshStandardMaterial, BackSide } from "three";
6
- import { C as CoordinationType, g as getImageSize } from "./index-DDD3apxS.js";
6
+ import { C as CoordinationType, g as getImageSize } from "./index-DYR0bplz.js";
7
7
  function MeasureLine({ currentLine, scale }) {
8
8
  const textRef = useRef(null);
9
9
  return jsxs("group", { children: [jsx(Center, { bottom: true, right: true, position: [currentLine.midPoint.x, currentLine.midPoint.y, currentLine.midPoint.z], rotation: [0, 0, 0], children: jsx(Text, { color: "gray", scale: 0.05, ref: textRef, children: `${(currentLine.startPoint.distanceTo(currentLine.endPoint) * scale).toFixed(2)} µm` }) }), jsx(Line, {
@@ -944,8 +944,8 @@ function GeometryAndMesh(props) {
944
944
  setObsHighlight(e.object.name);
945
945
  }, onPointerOut: () => setObsHighlight(null) }) })] }) : null, renderingSettings.uniforms && renderingSettings.shader && renderingSettings.meshScale && renderingSettings.geometrySize ? jsx("group", { children: jsxs("mesh", { scale: renderingSettings.meshScale, ref: materialRef, children: [jsx("boxGeometry", { args: renderingSettings.geometrySize }), jsx("shaderMaterial", { customProgramCacheKey: () => "1", side: FrontSide, uniforms: renderingSettings.uniforms, needsUpdate: true, transparent: true, vertexShader: renderingSettings.shader.vertexShader, fragmentShader: renderingSettings.shader.fragmentShader })] }) }) : null] }), jsx("group", { name: "lines", children: lines.map((object) => jsx(MeasureLine, { currentLine: object, scale: 1 }, stringifyLineData(object))) })] });
946
946
  }
947
- const LazyGeometryAndMeshXR = React__default.lazy(() => import("./GeometryAndMeshXR-CeAaq3ae.js").catch(() => ({ default: GeometryAndMesh })));
948
- const LazyXRSceneComponents = React__default.lazy(() => import("./XRSceneComponents-DnZLSAJz.js").catch(() => ({ default: () => null })));
947
+ const LazyGeometryAndMeshXR = React__default.lazy(() => import("./GeometryAndMeshXR-BTEzmbOK.js").catch(() => ({ default: GeometryAndMesh })));
948
+ const LazyXRSceneComponents = React__default.lazy(() => import("./XRSceneComponents-BTW4vULD.js").catch(() => ({ default: () => null })));
949
949
  function SpatialThree(props) {
950
950
  const materialRef = useRef(null);
951
951
  const orbitRef = useRef(null);
@@ -1289,22 +1289,33 @@ function SpatialThree(props) {
1289
1289
  const { xrEnabled } = props;
1290
1290
  return jsxs("group", { children: [xrEnabled ? jsxs(Fragment, { children: [jsx(Suspense, { fallback: null, children: jsx(LazyXRSceneComponents, {}) }), jsx(Suspense, { fallback: jsx(GeometryAndMesh, { ...geometryAndMeshProps }), children: jsx(LazyGeometryAndMeshXR, { ...geometryAndMeshProps }) })] }) : jsx(GeometryAndMesh, { ...geometryAndMeshProps }), jsx(OrbitControls, { ref: orbitRef, enableDamping: false, dampingFactor: 0 })] });
1291
1291
  }
1292
+ let xrModule = null;
1293
+ async function loadXRModule() {
1294
+ xrModule = await import("@react-three/xr");
1295
+ return xrModule;
1296
+ }
1297
+ function getXRModule() {
1298
+ if (!xrModule) {
1299
+ throw new Error("@react-three/xr is not loaded; call loadXRModule() first.");
1300
+ }
1301
+ return xrModule;
1302
+ }
1292
1303
  const LazyXRWrapper = React__default.lazy(
1293
1304
  // eslint-disable-next-line implicit-arrow-linebreak, function-paren-newline
1294
- () => import("./XRWrapper-C94X82Mb.js").catch(() => ({
1305
+ () => import("./XRWrapper-BFmCjZo_.js").catch(() => ({
1295
1306
  default: ({ children }) => children
1296
1307
  }))
1297
1308
  );
1298
1309
  const LazyXREnterButton = React__default.lazy(
1299
1310
  // eslint-disable-next-line implicit-arrow-linebreak, function-paren-newline
1300
- () => import("./XREnterButton-vmEhdF4L.js").catch(() => ({
1311
+ () => import("./XREnterButton-Cy5hojS1.js").catch(() => ({
1301
1312
  default: () => null
1302
1313
  }))
1303
1314
  );
1304
1315
  const SpatialWrapper = forwardRef((props, canvasRef) => {
1305
1316
  const [xrAvailable, setXrAvailable] = useState(false);
1306
1317
  useEffect(() => {
1307
- import("@react-three/xr").then(() => setXrAvailable(true)).catch(() => {
1318
+ loadXRModule().then(() => setXrAvailable(true)).catch(() => {
1308
1319
  });
1309
1320
  }, []);
1310
1321
  return jsxs("div", { style: { width: "100%", height: "100%" }, children: [xrAvailable && jsx(Suspense, { fallback: null, children: jsx(LazyXREnterButton, {}) }), jsx(Canvas, { style: { position: "absolute", top: 0, left: 0 }, camera: {
@@ -1322,6 +1333,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
1322
1333
  export {
1323
1334
  MeasureLine as M,
1324
1335
  index as a,
1336
+ getXRModule as g,
1325
1337
  isValidGeometrySize as i,
1326
1338
  stringifyLineData as s
1327
1339
  };
@@ -10382,6 +10382,7 @@ const CoordinationType$1 = {
10382
10382
  SPATIAL_CHANNEL_LABELS_VISIBLE: "spatialChannelLabelsVisible",
10383
10383
  SPATIAL_CHANNEL_LABELS_ORIENTATION: "spatialChannelLabelsOrientation",
10384
10384
  SPATIAL_CHANNEL_LABEL_SIZE: "spatialChannelLabelSize",
10385
+ SPATIAL_CHANNELS_SORT_ORDER: "spatialChannelsSortOrder",
10385
10386
  // Multi-sample / comparative
10386
10387
  SAMPLE_TYPE: "sampleType",
10387
10388
  SAMPLE_SELECTION: "sampleSelection",
@@ -10434,7 +10435,9 @@ const ViewHelpMapping = {
10434
10435
  OBS_SET_COMPOSITION_BAR_PLOT: "The set composition bar plot displays the results of a compositional analysis conducted using the scCODA method (Büttner et al. 2021 Nature Communications).",
10435
10436
  FEATURE_SET_ENRICHMENT_BAR_PLOT: "The feature set enrichment bar plot displays the results of a hypergeometric test applied to the differential expression test results to identify enriched pathway gene sets.",
10436
10437
  SAMPLE_SET_PAIR_MANAGER: "Select pairs of sample groups.",
10437
- FEATURE_STATS_TABLE: "This table displays per-feature statistics, for example, from a differential expression test."
10438
+ FEATURE_STATS_TABLE: "This table displays per-feature statistics, for example, from a differential expression test.",
10439
+ LAYER_CONTROLLER_BETA: "The spatial layer controller provides an interface for manipulating the visualization layers displayed in the spatial view.",
10440
+ SPATIAL_BETA: "The spatial view displays (potentially layered) spatially-resolved data including RGB or multiplexed images, segmentations of observations (bitmask- or polygon-based), and/or points (e.g., representing FISH transcripts)."
10438
10441
  };
10439
10442
  ({
10440
10443
  // For new file types
@@ -10985,6 +10988,7 @@ const COMPONENT_COORDINATION_TYPES = {
10985
10988
  CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
10986
10989
  CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
10987
10990
  CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
10991
+ CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER,
10988
10992
  CoordinationType$1.PHOTOMETRIC_INTERPRETATION
10989
10993
  ],
10990
10994
  [ViewType$1.HEATMAP]: [
@@ -11166,7 +11170,8 @@ const COMPONENT_COORDINATION_TYPES = {
11166
11170
  CoordinationType$1.LEGEND_VISIBLE,
11167
11171
  CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
11168
11172
  CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
11169
- CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
11173
+ CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
11174
+ CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER
11170
11175
  ],
11171
11176
  [ViewType$1.GENOMIC_PROFILES]: [
11172
11177
  CoordinationType$1.DATASET,
@@ -210928,22 +210933,22 @@ async function getDecoder(fileDirectory) {
210928
210933
  const Decoder = await importFn();
210929
210934
  return new Decoder(fileDirectory);
210930
210935
  }
210931
- addDecoder([void 0, 1], () => import("./raw-Dcz65jWu.js").then((m2) => m2.default));
210932
- addDecoder(5, () => import("./lzw-BlNLuocx.js").then((m2) => m2.default));
210936
+ addDecoder([void 0, 1], () => import("./raw-CCLdztVu.js").then((m2) => m2.default));
210937
+ addDecoder(5, () => import("./lzw-CKCb2yMZ.js").then((m2) => m2.default));
210933
210938
  addDecoder(6, () => {
210934
210939
  throw new Error("old style JPEG compression is not supported.");
210935
210940
  });
210936
- addDecoder(7, () => import("./jpeg-4XvdCEqV.js").then((m2) => m2.default));
210937
- addDecoder([8, 32946], () => import("./deflate-nYfk3Mbe.js").then((m2) => m2.default));
210938
- addDecoder(32773, () => import("./packbits-D7jhgu7h.js").then((m2) => m2.default));
210941
+ addDecoder(7, () => import("./jpeg-Co4ZcifY.js").then((m2) => m2.default));
210942
+ addDecoder([8, 32946], () => import("./deflate-Bbx7Vqb7.js").then((m2) => m2.default));
210943
+ addDecoder(32773, () => import("./packbits-BNHyrTcI.js").then((m2) => m2.default));
210939
210944
  addDecoder(
210940
210945
  34887,
210941
- () => import("./lerc-J5N91MJw.js").then(async (m2) => {
210946
+ () => import("./lerc-_s2Wotdl.js").then(async (m2) => {
210942
210947
  await m2.zstd.init();
210943
210948
  return m2;
210944
210949
  }).then((m2) => m2.default)
210945
210950
  );
210946
- addDecoder(50001, () => import("./webimage-CMXekglL.js").then((m2) => m2.default));
210951
+ addDecoder(50001, () => import("./webimage-BozDrenu.js").then((m2) => m2.default));
210947
210952
  function copyNewSize(array2, width2, height2, samplesPerPixel = 1) {
210948
210953
  return new (Object.getPrototypeOf(array2)).constructor(width2 * height2 * samplesPerPixel);
210949
210954
  }
@@ -227799,7 +227804,7 @@ function ToolMenu(props) {
227799
227804
  return jsxs("div", { className: classes2.tool, children: [visibleTools.pan && jsx$1(IconTool, { alt: pointerIconAltText, onClick: () => setActiveTool(null), isActive: activeTool === null, children: jsx$1(SvgNearMe, {}) }), visibleTools.selectLasso ? jsx$1(IconTool, { alt: lassoIconAltText, onClick: () => setActiveTool(distEs6Exports$2.SELECTION_TYPE.POLYGON), isActive: activeTool === distEs6Exports$2.SELECTION_TYPE.POLYGON, children: jsx$1(SvgSelectionLasso, {}) }) : null, visibleTools.recenter ? jsx$1(IconButton, { alt: "click to recenter", onClick: () => onRecenterButtonCLick(), "aria-label": "Recenter scatterplot view", children: jsx$1(CenterFocusStrong, {}) }) : null] });
227800
227805
  }
227801
227806
  const getCursorWithTool = () => "crosshair";
227802
- const getCursor = (interactionState) => interactionState.isDragging ? "grabbing" : "default";
227807
+ const getCursor = (interactionState) => interactionState.isDragging ? "grabbing" : "grab";
227803
227808
  function getOnHoverCallback(obsIndex, setObsHighlight, setComponentHover) {
227804
227809
  return (info2) => {
227805
227810
  if (setComponentHover) {
@@ -255514,12 +255519,12 @@ class ErrorBoundary extends React__default.Component {
255514
255519
  }
255515
255520
  }
255516
255521
  const LazySpatialThree = React__default.lazy(async () => {
255517
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-C2U2CO2P.js").then((n3) => n3.a);
255522
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-BlOIc49f.js").then((n3) => n3.a);
255518
255523
  return { default: SpatialWrapper2 };
255519
255524
  });
255520
255525
  const SpatialThreeAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialThree, { ...props }) }) }) }));
255521
255526
  const LazySpatialAccelerated = React__default.lazy(async () => {
255522
- const { SpatialWrapper: SpatialWrapper2 } = await import("./index-DuFOjj6d.js");
255527
+ const { SpatialWrapper: SpatialWrapper2 } = await import("./index-BSOXpbtb.js");
255523
255528
  return { default: SpatialWrapper2 };
255524
255529
  });
255525
255530
  const SpatialAcceleratedAdapter = React__default.forwardRef((props, ref2) => jsx$1("div", { ref: ref2, style: { width: "100%", height: "100%" }, children: jsx$1(ErrorBoundary, { fallback: jsx$1("div", { children: "3D spatial view is not available in this environment." }), children: jsx$1(Suspense, { fallback: jsx$1("div", { children: "Loading..." }), children: jsx$1(LazySpatialAccelerated, { ...props }) }) }) }));
@@ -255696,7 +255701,8 @@ function SpatialSubscriber(props) {
255696
255701
  bitmaskValueIsIndex = false,
255697
255702
  // TODO: move to coordination type
255698
255703
  three: threeFor3d = false,
255699
- accelerated: acceleratedFor3d = false
255704
+ accelerated: acceleratedFor3d = false,
255705
+ helpText = ViewHelpMapping.SPATIAL_BETA
255700
255706
  } = props;
255701
255707
  const loaders = useLoaders();
255702
255708
  const setComponentHover = useSetComponentHover();
@@ -256140,7 +256146,7 @@ function SpatialSubscriber(props) {
256140
256146
  }
256141
256147
  }
256142
256148
  };
256143
- return jsxs(TitleInfo, { title: title2, info: subtitle, isSpatial: true, urls: urls2, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isReady, errors, children: [shouldUseThree ? acceleratedFor3d ? jsx$1(SpatialAcceleratedAdapter, { ref: threeRef, uuid: uuid2, width: width2, height: height2, theme, hideTools: !isSelectable, rotation: [rotationX, rotationY, rotationZ], setRotationX, setRotationY, setRotationZ, targetT, targetZ, viewState: isValidViewState ? {
256149
+ return jsxs(TitleInfo, { title: title2, info: subtitle, isSpatial: true, urls: urls2, theme, closeButtonVisible, downloadButtonVisible, removeGridComponent, isReady, errors, helpText, children: [shouldUseThree ? acceleratedFor3d ? jsx$1(SpatialAcceleratedAdapter, { ref: threeRef, uuid: uuid2, width: width2, height: height2, theme, hideTools: !isSelectable, rotation: [rotationX, rotationY, rotationZ], setRotationX, setRotationY, setRotationZ, targetT, targetZ, viewState: isValidViewState ? {
256144
256150
  zoom: zoom2,
256145
256151
  target: [targetX2, targetY2, targetZ],
256146
256152
  rotationX,
@@ -263843,7 +263849,7 @@ function FeatureListOptions(props) {
263843
263849
  const { classes: classes2 } = usePlotOptionsStyles();
263844
263850
  return jsxs(OptionsContainer, { children: [children3, jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-sort-option-${featureListId}`, children: "Sort Ordering" }) }), jsx$1(TableCell, { variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, value: featureListSort, onChange: handleFeatureListSortChange, inputProps: {
263845
263851
  id: `feature-list-sort-option-${featureListId}`
263846
- }, children: FEATURELIST_SORT_OPTIONS.map((option) => jsx$1("option", { value: option, children: option }, option)) }) })] }), hasFeatureLabels ? jsxs(Fragment, { children: [jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-sort-key-${featureListId}`, children: "Sort Key" }) }), jsx$1(TableCell, { variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, disabled: featureListSort === "original", value: featureListSortKey, onChange: handleFeatureListSortKeyChange, inputProps: {
263852
+ }, children: FEATURELIST_SORT_OPTIONS.map((option) => jsx$1("option", { value: option, children: capitalize$3(option) }, option)) }) })] }), hasFeatureLabels ? jsxs(Fragment, { children: [jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-sort-key-${featureListId}`, children: "Sort Key" }) }), jsx$1(TableCell, { variant: "body", children: jsx$1(OptionSelect, { className: classes2.select, disabled: featureListSort === "original", value: featureListSortKey, onChange: handleFeatureListSortKeyChange, inputProps: {
263847
263853
  "aria-label": "Select the feature list sort key",
263848
263854
  id: `feature-list-sort-key-${featureListId}`
263849
263855
  }, children: hasFeatureLabels ? jsxs(Fragment, { children: [jsx$1("option", { value: "featureLabels", children: primaryColumnName }), jsx$1("option", { value: "featureIndex", children: ALT_COLNAME })] }) : jsx$1("option", { value: "featureIndex", children: primaryColumnName }) }) })] }), jsxs(TableRow, { children: [jsx$1(TableCell, { className: classes2.labelCell, variant: "head", scope: "row", children: jsx$1("label", { htmlFor: `feature-list-show-alternative-ids-${featureListId}`, children: "Show Alternate IDs" }) }), jsx$1(TableCell, { className: classes2.inputCell, variant: "body", children: jsx$1(Checkbox$1, { className: classes2.tableCheckbox, checked: showFeatureTable, onChange: handleShowTableChange, name: "feature-list-show-table", color: "default", slotProps: { input: {
@@ -268171,17 +268177,23 @@ const useStyles$a = makeStyles()(() => ({
268171
268177
  }
268172
268178
  }));
268173
268179
  function ChannelSelectionDropdown(props) {
268174
- const { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled } = props;
268180
+ const { featureIndex, channelsSortOrder, targetC, setTargetC, setWindow: setWindow2, disabled } = props;
268175
268181
  const { classes: classes2 } = useStyles$a();
268176
268182
  const { classes: selectClasses2 } = useSelectStyles();
268177
268183
  function handleChange(event2) {
268178
268184
  setTargetC(event2.target.value === "" ? null : Number(event2.target.value));
268179
268185
  setWindow2(null);
268180
268186
  }
268181
- return Array.isArray(featureIndex) ? jsx$1(NativeSelect, { classes: { root: selectClasses2.selectRoot }, className: classes2.oneLineChannelSelect, value: targetC === null ? "" : targetC, onChange: handleChange, inputProps: { "aria-label": "Channel selector" }, children: featureIndex.map((channelName, channelIndex) => (
268182
- // eslint-disable-next-line react/no-array-index-key
268183
- jsx$1("option", { disabled, value: channelIndex, children: channelName }, `${channelName}-${channelIndex}`)
268184
- )) }) : null;
268187
+ const sortedOptions = useMemo$1(() => {
268188
+ if (!Array.isArray(featureIndex))
268189
+ return [];
268190
+ const options = featureIndex.map((channelName, channelIndex) => ({ channelName, channelIndex }));
268191
+ if (channelsSortOrder === "alphabetical") {
268192
+ return options.sort((a2, b2) => a2.channelName.localeCompare(b2.channelName, void 0, { numeric: true, sensitivity: "base" }));
268193
+ }
268194
+ return options;
268195
+ }, [featureIndex, channelsSortOrder]);
268196
+ return Array.isArray(featureIndex) ? jsx$1(NativeSelect, { classes: { root: selectClasses2.selectRoot }, className: classes2.oneLineChannelSelect, value: targetC === null ? "" : targetC, onChange: handleChange, inputProps: { "aria-label": "Channel selector" }, children: sortedOptions.map(({ channelName, channelIndex }) => jsx$1("option", { disabled, value: channelIndex, children: channelName }, `${channelName}-${channelIndex}`)) }) : null;
268185
268197
  }
268186
268198
  function ImageChannelController(props) {
268187
268199
  const {
@@ -268209,7 +268221,8 @@ function ImageChannelController(props) {
268209
268221
  spatialRenderingMode,
268210
268222
  numResolutions,
268211
268223
  spatialMaxResolution,
268212
- setSpatialMaxResolution
268224
+ setSpatialMaxResolution,
268225
+ channelsSortOrder
268213
268226
  } = props;
268214
268227
  const removeChannel = useRemoveImageChannelInMetaCoordinationScopes();
268215
268228
  const [showValueExtent, setShowValueExtent] = useState(true);
@@ -268246,7 +268259,7 @@ function ImageChannelController(props) {
268246
268259
  setWindow2(minMaxDomain);
268247
268260
  }
268248
268261
  }
268249
- return jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelVisibilityCheckbox, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, colormapOn }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, isStaticColor: !colormapOn, palette: VIEWER_PALETTE }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(ChannelSelectionDropdown, { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled: isLoading }) }), jsx$1(Grid$1, { size: 3, children: jsx$1(ChannelSlider, { image: image2, targetT, targetZ, targetC, window: window2, setWindow: setWindow2, disabled, color: color2, theme, colormapOn, showValueExtent, minMaxDomain }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelOptions, { onRemove: onRemove2, showValueExtent, setShowValueExtent, onResetWindowUsingIQR: handleResetWindowUsingIQR, numResolutions, spatialMaxResolution, setSpatialMaxResolution }) })] });
268262
+ return jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelVisibilityCheckbox, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, colormapOn }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelColorPickerMenu, { color: color2, setColor: setColor2, visible, setVisible, disabled: isLoading, theme, isStaticColor: !colormapOn, palette: VIEWER_PALETTE }) }), jsx$1(Grid$1, { size: 6, children: jsx$1(ChannelSelectionDropdown, { featureIndex, targetC, setTargetC, setWindow: setWindow2, disabled: isLoading, channelsSortOrder }) }), jsx$1(Grid$1, { size: 3, children: jsx$1(ChannelSlider, { image: image2, targetT, targetZ, targetC, window: window2, setWindow: setWindow2, disabled, color: color2, theme, colormapOn, showValueExtent, minMaxDomain }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ChannelOptions, { onRemove: onRemove2, showValueExtent, setShowValueExtent, onResetWindowUsingIQR: handleResetWindowUsingIQR, numResolutions, spatialMaxResolution, setSpatialMaxResolution }) })] });
268250
268263
  }
268251
268264
  function DimensionSlider(props) {
268252
268265
  const { boundingSlice, sliceValue, setSliceValue, label: label2 } = props;
@@ -268345,7 +268358,7 @@ const lodSliderRangeConfig = {
268345
268358
  step: 1
268346
268359
  };
268347
268360
  function ImageLayerEllipsisMenu(props) {
268348
- const { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize } = props;
268361
+ const { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize, channelsSortOrder, setChannelsSortOrder } = props;
268349
268362
  const [open2, setOpen] = useState(false);
268350
268363
  const { classes: selectClasses2 } = useSelectStyles();
268351
268364
  const { classes: menuClasses } = useEllipsisMenuStyles();
@@ -268371,6 +268384,9 @@ function ImageLayerEllipsisMenu(props) {
268371
268384
  function handleChannelLabelsOrientationChange(event2) {
268372
268385
  setChannelLabelsOrientation(event2.target.value);
268373
268386
  }
268387
+ function handleChannelsSortOrderChange(event2) {
268388
+ setChannelsSortOrder(event2.target.value);
268389
+ }
268374
268390
  function handleLodFactorChange(event2, value2) {
268375
268391
  setLocalLodSliderValue(value2);
268376
268392
  }
@@ -268392,11 +268408,12 @@ function ImageLayerEllipsisMenu(props) {
268392
268408
  const channelLabelsOrientationId = $bdb11010cef70236$export$f680877a34711e37();
268393
268409
  const channelLabelSizeId = $bdb11010cef70236$export$f680877a34711e37();
268394
268410
  const lodFactorId = $bdb11010cef70236$export$f680877a34711e37();
268411
+ const channelsSortOrderId = $bdb11010cef70236$export$f680877a34711e37();
268395
268412
  return jsxs(PopperMenu, { open: open2, setOpen, buttonIcon: jsx$1(MoreVertIcon, {}), buttonClassName: menuClasses.imageLayerMenuButton, containerClassName: menuClasses.imageLayerPopperContainer, withPaper: true, "aria-label": "Open image layer options menu", children: [is3dMode && jsxs(MenuItem, { dense: true, disableGutters: true, className: menuClasses.menuItem, children: [jsx$1("label", { id: `${lodFactorId}-label`, className: menuClasses.imageLayerMenuLabel, htmlFor: lodFactorId, children: "LOD Factor: " }), jsx$1(Slider, { disabled: !is3dMode, value: localLodSliderValue, onChange: handleLodFactorChange, onChangeCommitted: handleLodFactorChangeCommitted, className: menuClasses.menuItemSlider, orientation: "horizontal", id: lodFactorId, "aria-label": "Level of detail factor slider", valueLabelDisplay: "off", ...lodSliderRangeConfig }), jsx$1(Box, { px: 1 }), jsx$1(Input$1, { value: localLodSliderValue, onChange: handleLodFactorInputChange, onBlur: handleLodFactorInputChange, "aria-labelledby": `${lodFactorId}-label`, size: "small", sx: { width: "6ch", flexShrink: 0, fontVariantNumeric: "tabular-nums" }, endAdornment: jsx$1(InputAdornment$1, { position: "end", variant: "standard", sx: { "& > p": { marginBottom: 0 } }, children: "%" }), inputProps: {
268396
268413
  ...lodSliderRangeConfig,
268397
268414
  inputMode: "numeric",
268398
268415
  pattern: "[0-9]*"
268399
- } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapId, children: "Colormap: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleColormapChange, value: colormap === null ? "" : colormap, inputProps: { id: colormapId, "aria-label": "Colormap selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "None", value: "", children: "None" }), COLORMAP_OPTIONS.map((name2) => jsx$1("option", { value: name2, children: name2 }, name2))] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: interpretationId, children: "Photometric Interpretation: " }), jsxs(NativeSelect, { onChange: handleInterpretationChange, value: photometricInterpretation, inputProps: { id: interpretationId, "aria-label": "Photometric interpretation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "RGB", value: "RGB", children: "RGB" }), channelScopes.length > 0 ? jsx$1("option", { "aria-label": "BlackIsZero", value: "BlackIsZero", children: "BlackIsZero" }) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: transparentId, children: "Zero Transparent: " }), jsx$1(Checkbox$1, { color: "primary", checked: spatialLayerTransparentColor !== null, onChange: (e3, v) => setSpatialLayerTransparentColor(v ? [0, 0, 0] : null), slotProps: { input: { id: transparentId, "aria-label": "Render zero-value pixels as transparent" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: volumetricId, children: "Volumetric Rendering: " }), jsxs(NativeSelect, { onChange: handleVolumetricChange, value: volumetricRenderingAlgorithm, inputProps: { id: volumetricId, "aria-label": "Volumetric rendering algorithm selector" }, classes: { root: selectClasses2.selectRoot }, disabled: !is3dMode, children: [jsx$1("option", { "aria-label": "Additive", value: "additive", children: "Additive" }), jsx$1("option", { "aria-label": "Maximum Intensity Projection", value: "maximumIntensityProjection", children: "Maximum Intensity Projection" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: resolutionId, children: "Volume Resolution: " }), jsxs(NativeSelect, { disabled: !is3dMode || !isMultiResolution, onChange: handleResolutionChange, value: spatialTargetResolution === null ? "auto" : spatialTargetResolution, inputProps: { id: resolutionId, "aria-label": "Volumetric resolution selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "auto", children: "Auto" }), Array.isArray(multiResolutionStats) ? multiResolutionStats.map((stats, resolution) => stats.canLoad ? jsx$1("option", { value: resolution, children: `3D: ${resolution}x Downsampled, ~${formatBytes(stats.totalBytes)} per channel, (${stats.height}, ${stats.width}, ${stats.depthDownsampled})` }, `(${stats.height}, ${stats.width}, ${stats.depthDownsampled})`) : null) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: tooltipsVisibleId, children: "Tooltips Visible: " }), jsx$1(Checkbox$1, { color: "primary", checked: tooltipsVisible, onChange: (e3, v) => setTooltipsVisible(v), slotProps: { input: { id: tooltipsVisibleId, "aria-label": "Render pixel value tooltips" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsVisibleId, children: "Channel Labels Visible: " }), jsx$1(Checkbox$1, { disabled: photometricInterpretation === "RGB", color: "primary", checked: channelLabelsVisible, onChange: (e3, v) => setChannelLabelsVisible(v), slotProps: { input: { id: channelLabelsVisibleId, "aria-label": "Render channel labels" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsOrientationId, children: "Channel Labels Orientation: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleChannelLabelsOrientationChange, value: channelLabelsOrientation, inputProps: { id: channelLabelsOrientationId, "aria-label": "Channel labels orientation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "Vertical", value: "vertical", children: "Vertical" }), jsx$1("option", { "aria-label": "Horizontal", value: "horizontal", children: "Horizontal" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelSizeId, children: "Channel Labels Size: " }), jsx$1(Slider, { disabled: photometricInterpretation === "RGB", value: channelLabelSize, min: 8, max: 36, step: 1, onChange: (e3, v) => setChannelLabelSize(v), className: menuClasses.menuItemSlider, orientation: "horizontal", id: channelLabelSizeId, "aria-label": "Channel labels text size slider" })] })] });
268416
+ } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: colormapId, children: "Colormap: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleColormapChange, value: colormap === null ? "" : colormap, inputProps: { id: colormapId, "aria-label": "Colormap selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "None", value: "", children: "None" }), COLORMAP_OPTIONS.map((name2) => jsx$1("option", { value: name2, children: name2 }, name2))] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: interpretationId, children: "Photometric Interpretation: " }), jsxs(NativeSelect, { onChange: handleInterpretationChange, value: photometricInterpretation, inputProps: { id: interpretationId, "aria-label": "Photometric interpretation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "RGB", value: "RGB", children: "RGB" }), channelScopes.length > 0 ? jsx$1("option", { "aria-label": "BlackIsZero", value: "BlackIsZero", children: "BlackIsZero" }) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: transparentId, children: "Zero Transparent: " }), jsx$1(Checkbox$1, { color: "primary", checked: spatialLayerTransparentColor !== null, onChange: (e3, v) => setSpatialLayerTransparentColor(v ? [0, 0, 0] : null), slotProps: { input: { id: transparentId, "aria-label": "Render zero-value pixels as transparent" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: volumetricId, children: "Volumetric Rendering: " }), jsxs(NativeSelect, { onChange: handleVolumetricChange, value: volumetricRenderingAlgorithm, inputProps: { id: volumetricId, "aria-label": "Volumetric rendering algorithm selector" }, classes: { root: selectClasses2.selectRoot }, disabled: !is3dMode, children: [jsx$1("option", { "aria-label": "Additive", value: "additive", children: "Additive" }), jsx$1("option", { "aria-label": "Maximum Intensity Projection", value: "maximumIntensityProjection", children: "Maximum Intensity Projection" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: resolutionId, children: "Volume Resolution: " }), jsxs(NativeSelect, { disabled: !is3dMode || !isMultiResolution, onChange: handleResolutionChange, value: spatialTargetResolution === null ? "auto" : spatialTargetResolution, inputProps: { id: resolutionId, "aria-label": "Volumetric resolution selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { value: "auto", children: "Auto" }), Array.isArray(multiResolutionStats) ? multiResolutionStats.map((stats, resolution) => stats.canLoad ? jsx$1("option", { value: resolution, children: `3D: ${resolution}x Downsampled, ~${formatBytes(stats.totalBytes)} per channel, (${stats.height}, ${stats.width}, ${stats.depthDownsampled})` }, `(${stats.height}, ${stats.width}, ${stats.depthDownsampled})`) : null) : null] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: tooltipsVisibleId, children: "Tooltips Visible: " }), jsx$1(Checkbox$1, { color: "primary", checked: tooltipsVisible, onChange: (e3, v) => setTooltipsVisible(v), slotProps: { input: { id: tooltipsVisibleId, "aria-label": "Render pixel value tooltips" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsVisibleId, children: "Channel Labels Visible: " }), jsx$1(Checkbox$1, { disabled: photometricInterpretation === "RGB", color: "primary", checked: channelLabelsVisible, onChange: (e3, v) => setChannelLabelsVisible(v), slotProps: { input: { id: channelLabelsVisibleId, "aria-label": "Render channel labels" } } })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelsOrientationId, children: "Channel Labels Orientation: " }), jsxs(NativeSelect, { disabled: photometricInterpretation === "RGB", onChange: handleChannelLabelsOrientationChange, value: channelLabelsOrientation, inputProps: { id: channelLabelsOrientationId, "aria-label": "Channel labels orientation selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "Vertical", value: "vertical", children: "Vertical" }), jsx$1("option", { "aria-label": "Horizontal", value: "horizontal", children: "Horizontal" })] })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelLabelSizeId, children: "Channel Labels Size: " }), jsx$1(Slider, { disabled: photometricInterpretation === "RGB", value: channelLabelSize, min: 8, max: 36, step: 1, onChange: (e3, v) => setChannelLabelSize(v), className: menuClasses.menuItemSlider, orientation: "horizontal", id: channelLabelSizeId, "aria-label": "Channel labels text size slider" })] }), jsxs(MenuItem, { dense: true, disableGutters: true, classes: menuClasses.menuItem, children: [jsx$1("label", { className: menuClasses.imageLayerMenuLabel, htmlFor: channelsSortOrderId, children: "Channel Ordering: " }), jsxs(NativeSelect, { onChange: handleChannelsSortOrderChange, value: channelsSortOrder, inputProps: { id: channelsSortOrderId, "aria-label": "Channel sort order selector" }, classes: { root: selectClasses2.selectRoot }, children: [jsx$1("option", { "aria-label": "Original", value: "original", children: "Original" }), jsx$1("option", { "aria-label": "Alphabetical", value: "alphabetical", children: "Alphabetical" })] })] })] });
268400
268417
  }
268401
268418
  function ImageLayerController(props) {
268402
268419
  const {
@@ -268422,8 +268439,8 @@ function ImageLayerController(props) {
268422
268439
  volumeStillRef = null
268423
268440
  } = props;
268424
268441
  const [open2, setOpen] = useState(true);
268425
- const { spatialLayerVisible: visible, spatialLayerOpacity: opacity2, spatialLayerColormap: colormap, photometricInterpretation, spatialTargetResolution, spatialLodFactor, volumetricRenderingAlgorithm, spatialLayerTransparentColor, spatialSliceX, spatialSliceY, spatialSliceZ, tooltipsVisible, spatialChannelLabelsVisible: channelLabelsVisible, spatialChannelLabelsOrientation: channelLabelsOrientation, spatialChannelLabelSize: channelLabelSize } = layerCoordination;
268426
- const { setSpatialLayerVisible: setVisible, setSpatialLayerOpacity: setOpacity2, setSpatialLayerColormap: setColormap, setPhotometricInterpretation, setSpatialTargetResolution, setSpatialLodFactor, setVolumetricRenderingAlgorithm, setSpatialLayerTransparentColor, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ, setTooltipsVisible, setSpatialChannelLabelsVisible: setChannelLabelsVisible, setSpatialChannelLabelsOrientation: setChannelLabelsOrientation, setSpatialChannelLabelSize: setChannelLabelSize } = setLayerCoordination;
268442
+ const { spatialLayerVisible: visible, spatialLayerOpacity: opacity2, spatialLayerColormap: colormap, photometricInterpretation, spatialTargetResolution, spatialLodFactor, volumetricRenderingAlgorithm, spatialLayerTransparentColor, spatialSliceX, spatialSliceY, spatialSliceZ, tooltipsVisible, spatialChannelLabelsVisible: channelLabelsVisible, spatialChannelLabelsOrientation: channelLabelsOrientation, spatialChannelLabelSize: channelLabelSize, spatialChannelsSortOrder: channelsSortOrder } = layerCoordination;
268443
+ const { setSpatialLayerVisible: setVisible, setSpatialLayerOpacity: setOpacity2, setSpatialLayerColormap: setColormap, setPhotometricInterpretation, setSpatialTargetResolution, setSpatialLodFactor, setVolumetricRenderingAlgorithm, setSpatialLayerTransparentColor, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ, setTooltipsVisible, setSpatialChannelLabelsVisible: setChannelLabelsVisible, setSpatialChannelLabelsOrientation: setChannelLabelsOrientation, setSpatialChannelLabelSize: setChannelLabelSize, setSpatialChannelsSortOrder: setChannelsSortOrder } = setLayerCoordination;
268427
268444
  const addChannel = useAddImageChannelInMetaCoordinationScopes();
268428
268445
  const visibleSetting = typeof visible === "boolean" ? visible : true;
268429
268446
  const Visibility = useMemo$1(() => visibleSetting ? VisibilityIcon : VisibilityOffIcon, [visibleSetting]);
@@ -268443,12 +268460,12 @@ function ImageLayerController(props) {
268443
268460
  const { classes: menuClasses } = useEllipsisMenuStyles();
268444
268461
  const { classes: controllerSectionClasses } = useControllerSectionStyles();
268445
268462
  const isMultiChannel = photometricInterpretation !== "RGB";
268446
- return jsx$1(Grid$1, { className: controllerSectionClasses.layerControllerGrid, children: jsxs(Paper, { elevation: 4, className: controllerSectionClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { className: menuClasses.imageLayerVisibleButton, onClick: handleVisibleChange, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1 }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ImageLayerEllipsisMenu, { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(ImageIcon, { className: classes2.layerTypeImageIcon }), isMultiChannel ? jsx$1(Button, { onClick: handleOpenChange, className: classes2.channelExpansionButton, "aria-label": "Expand or collapse channel controls", children: open2 ? jsx$1(ExpandLess, {}) : jsx$1(ExpandMore, {}) }) : null] })] }), isMultiChannel && open2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [channelScopes.map((cScope) => {
268463
+ return jsx$1(Grid$1, { className: controllerSectionClasses.layerControllerGrid, children: jsxs(Paper, { elevation: 4, className: controllerSectionClasses.layerControllerRoot, children: [jsxs(Grid$1, { container: true, direction: "row", justifyContent: "space-between", children: [jsx$1(Grid$1, { size: 1, children: jsx$1(Button, { className: menuClasses.imageLayerVisibleButton, onClick: handleVisibleChange, "aria-label": "Toggle layer visibility", children: jsx$1(Visibility, {}) }) }), jsx$1(Grid$1, { size: 1 }), jsx$1(Grid$1, { size: 6, children: jsx$1(Typography, { className: menuClasses.imageLayerName, children: label2 }) }), jsx$1(Grid$1, { size: 2, children: jsx$1(Slider, { value: opacity2, min: 0, max: 1, step: 1e-3, onChange: handleOpacityChange, className: menuClasses.imageLayerOpacitySlider, orientation: "horizontal", "aria-label": `Adjust opacity for layer ${label2}` }) }), jsx$1(Grid$1, { size: 1, children: jsx$1(ImageLayerEllipsisMenu, { colormap, setColormap, photometricInterpretation, setPhotometricInterpretation, spatialTargetResolution, setSpatialTargetResolution, spatialLodFactor, setSpatialLodFactor, volumetricRenderingAlgorithm, setVolumetricRenderingAlgorithm, spatialLayerTransparentColor, setSpatialLayerTransparentColor, spatialRenderingMode, image: image2, channelScopes, tooltipsVisible, setTooltipsVisible, channelLabelsVisible, setChannelLabelsVisible, channelLabelsOrientation, setChannelLabelsOrientation, channelLabelSize, setChannelLabelSize, channelsSortOrder, setChannelsSortOrder }) }), jsxs(Grid$1, { size: 1, container: true, direction: "row", children: [jsx$1(ImageIcon, { className: classes2.layerTypeImageIcon }), isMultiChannel ? jsx$1(Button, { onClick: handleOpenChange, className: classes2.channelExpansionButton, "aria-label": "Expand or collapse channel controls", children: open2 ? jsx$1(ExpandLess, {}) : jsx$1(ExpandMore, {}) }) : null] })] }), isMultiChannel && open2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [channelScopes.map((cScope) => {
268447
268464
  const { spatialTargetC, spatialChannelVisible, spatialChannelOpacity, spatialChannelColor, spatialChannelWindow, spatialMaxResolution } = channelCoordination[cScope];
268448
268465
  const { setSpatialTargetC, setSpatialChannelVisible, setSpatialChannelOpacity, setSpatialChannelColor, setSpatialChannelWindow, setSpatialMaxResolution } = setChannelCoordination[cScope];
268449
268466
  const channelIndex = image2?.getChannelIndex(spatialTargetC);
268450
268467
  const numResolutions = image2?.getNumResolutions();
268451
- return jsx$1(ImageChannelController, { theme, coordinationScopesRaw, layerScope, channelScope: cScope, targetT, targetZ, targetC: channelIndex, setTargetC: setSpatialTargetC, visible: spatialChannelVisible, setVisible: setSpatialChannelVisible, opacity: spatialChannelOpacity, setOpacity: setSpatialChannelOpacity, color: spatialChannelColor, setColor: setSpatialChannelColor, window: spatialChannelWindow, setWindow: setSpatialChannelWindow, colormapOn: colormap !== null, featureIndex, image: image2, spatialRenderingMode, numResolutions, spatialMaxResolution, setSpatialMaxResolution }, cScope);
268468
+ return jsx$1(ImageChannelController, { theme, coordinationScopesRaw, layerScope, channelScope: cScope, targetT, targetZ, targetC: channelIndex, setTargetC: setSpatialTargetC, visible: spatialChannelVisible, setVisible: setSpatialChannelVisible, opacity: spatialChannelOpacity, setOpacity: setSpatialChannelOpacity, color: spatialChannelColor, setColor: setSpatialChannelColor, window: spatialChannelWindow, setWindow: setSpatialChannelWindow, colormapOn: colormap !== null, featureIndex, image: image2, channelsSortOrder, spatialRenderingMode, numResolutions, spatialMaxResolution, setSpatialMaxResolution }, cScope);
268452
268469
  }), jsx$1(Button, { disabled: channelScopes.length === MAX_CHANNELS$1 || channelScopes.length === imageNumChannels, onClick: handleChannelAdd, fullWidth: true, variant: "outlined", className: classes2.imageLayerButton, startIcon: jsx$1(AddIcon, {}), size: "small", "aria-label": "Add a channel to this layer", children: "Add Channel" })] }) : null, is3dMode && image2 ? jsxs(Grid$1, { container: true, direction: "column", justifyContent: "space-between", className: classes2.imageChannelControllerGrid, children: [jsx$1(Typography, { className: classes2.clippingPanesLabel, children: "Clipping planes:" }), jsx$1(Grid$1, { size: 12, className: classes2.clippingSliders, children: jsx$1(ClippingSliders, { image: image2, spatialSliceX, spatialSliceY, spatialSliceZ, setSpatialSliceX, setSpatialSliceY, setSpatialSliceZ }) }), jsx$1(LoadingStatusIndicator, { loadingProgress: volumeLoadingProgress, onStopLoading: onStopVolumeLoading, onRestartLoading: onRestartVolumeLoading, stillRef: volumeStillRef, spatialRenderingMode })] }) : null] }) });
268453
268470
  }
268454
268471
  const useStyles$8 = makeStyles()((theme) => ({
@@ -268499,7 +268516,7 @@ function LayerController(props) {
268499
268516
  return jsxs("div", { children: [anyLayerHasZ ? jsx$1(GlobalDimensionSlider, { label: "Z", targetValue: targetZ, setTargetValue: setTargetZ, max: maxZ, spatialRenderingMode, setSpatialRenderingMode }) : null, anyLayerHasT ? jsx$1(GlobalDimensionSlider, { label: "T", targetValue: targetT, setTargetValue: setTargetT, max: maxT }) : null, pointLayerScopes && reversedPointLayerScopes.map((layerScope) => jsx$1(PointLayerController, { theme, layerScope, layerCoordination: pointLayerCoordination[0][layerScope], setLayerCoordination: pointLayerCoordination[1][layerScope], pointMatrixIndicesData: pointMultiIndicesData?.[layerScope], tiledPointsLoadingProgress, layerPerFeatureForPoints }, layerScope)), spotLayerScopes && reversedSpotLayerScopes.map((layerScope) => jsx$1(SpotLayerController, { theme, layerScope, layerCoordination: spotLayerCoordination[0][layerScope], setLayerCoordination: spotLayerCoordination[1][layerScope] }, layerScope)), segmentationLayerScopes && reversedSegmentationLayerScopes.map((layerScope) => jsx$1(SegmentationLayerController, { theme, layerScope, layerCoordination: segmentationLayerCoordination[0][layerScope], setLayerCoordination: segmentationLayerCoordination[1][layerScope], channelScopes: segmentationChannelScopesByLayer[layerScope], channelCoordination: segmentationChannelCoordination[0][layerScope], setChannelCoordination: segmentationChannelCoordination[1][layerScope] }, layerScope)), imageLayerScopes && reversedImageLayerScopes.map((layerScope) => jsx$1(ImageLayerController, { theme, coordinationScopesRaw, layerScope, layerCoordination: imageLayerCoordination[0][layerScope], setLayerCoordination: imageLayerCoordination[1][layerScope], channelScopes: imageChannelScopesByLayer[layerScope], channelCoordination: imageChannelCoordination[0][layerScope], setChannelCoordination: imageChannelCoordination[1][layerScope], image: images[layerScope]?.image?.instance, featureIndex: images[layerScope]?.featureIndex, targetT, targetZ, spatialRenderingMode, volumeLoadingProgress: volumeLoadingStatus?.loadingProgress, onStopVolumeLoading: volumeLoadingStatus?.onStopLoading, onRestartVolumeLoading: volumeLoadingStatus?.onRestartLoading, volumeStillRef: volumeLoadingStatus?.stillRef }, layerScope))] });
268500
268517
  }
268501
268518
  function LayerControllerSubscriber(props) {
268502
- const { coordinationScopes: coordinationScopesRaw, coordinationScopesBy: coordinationScopesByRaw, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title: title2 = "Spatial Layers", uuid: uuid2, layerPerFeatureForPoints = false, cameraPresets } = props;
268519
+ const { coordinationScopes: coordinationScopesRaw, coordinationScopesBy: coordinationScopesByRaw, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, title: title2 = "Spatial Layers", uuid: uuid2, layerPerFeatureForPoints = false, cameraPresets, helpText = ViewHelpMapping.LAYER_CONTROLLER_BETA } = props;
268503
268520
  const loaders = useLoaders();
268504
268521
  const mergeCoordination = useMergeCoordination();
268505
268522
  const coordinationScopes = useCoordinationScopes(coordinationScopesRaw);
@@ -268587,7 +268604,8 @@ function LayerControllerSubscriber(props) {
268587
268604
  CoordinationType$1.TOOLTIPS_VISIBLE,
268588
268605
  CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE,
268589
268606
  CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION,
268590
- CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE
268607
+ CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE,
268608
+ CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER
268591
268609
  ], coordinationScopes, coordinationScopesBy, CoordinationType$1.IMAGE_LAYER);
268592
268610
  const imageChannelCoordination = useComplexCoordinationSecondary([
268593
268611
  CoordinationType$1.SPATIAL_TARGET_C,
@@ -268655,7 +268673,7 @@ function LayerControllerSubscriber(props) {
268655
268673
  imageDataStatus,
268656
268674
  pointMultiIndicesDataStatus
268657
268675
  ]);
268658
- return jsx$1(TitleInfo, { title: title2, isScroll: true, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, isReady, errors, children: jsx$1(LayerController, { theme, coordinationScopesRaw, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, images: imageData, imageLayerScopes, imageLayerCoordination, targetT, targetZ, setTargetT, setTargetZ, spatialRenderingMode, setSpatialRenderingMode, imageChannelScopesByLayer, imageChannelCoordination, spotLayerScopes, spotLayerCoordination, pointLayerScopes, pointLayerCoordination, pointMultiIndicesData, layerPerFeatureForPoints, volumeLoadingStatus, tiledPointsLoadingProgress }) });
268676
+ return jsx$1(TitleInfo, { title: title2, isScroll: true, closeButtonVisible, downloadButtonVisible, removeGridComponent, theme, isReady, errors, helpText, children: jsx$1(LayerController, { theme, coordinationScopesRaw, segmentationLayerScopes, segmentationLayerCoordination, segmentationChannelScopesByLayer, segmentationChannelCoordination, images: imageData, imageLayerScopes, imageLayerCoordination, targetT, targetZ, setTargetT, setTargetZ, spatialRenderingMode, setSpatialRenderingMode, imageChannelScopesByLayer, imageChannelCoordination, spotLayerScopes, spotLayerCoordination, pointLayerScopes, pointLayerCoordination, pointMultiIndicesData, layerPerFeatureForPoints, volumeLoadingStatus, tiledPointsLoadingProgress }) });
268659
268677
  }
268660
268678
  const isIterable$2 = (obj) => Symbol.iterator in obj;
268661
268679
  const hasIterableEntries = (value2) => (
@@ -270570,7 +270588,7 @@ function HiglassGlobalStyles(props) {
270570
270588
  }
270571
270589
  register({ dataFetcher: ZarrMultivecDataFetcher_default, config: ZarrMultivecDataFetcher_default.config }, { pluginType: "dataFetcher" });
270572
270590
  const LazyHiGlassComponent = React__default.lazy(async () => {
270573
- const { HiGlassComponent } = await import("./higlass-DPgS6S1h.js");
270591
+ const { HiGlassComponent } = await import("./higlass-C6IxqTVD.js");
270574
270592
  return { default: HiGlassComponent };
270575
270593
  });
270576
270594
  const HG_SIZE = 800;
@@ -272159,13 +272177,16 @@ const globalNeuroglancerStyles = {
272159
272177
  },
272160
272178
  "input.perspective-panel-show-slice-views": { pointerEvents: "all" },
272161
272179
  ".neuroglancer-rendered-data-panel": {
272162
- cursor: "crosshair",
272180
+ cursor: "grab",
272163
272181
  position: "relative",
272164
272182
  outline: "0",
272165
272183
  touchAction: "none",
272166
272184
  color: "#fff",
272167
272185
  textAlign: "left"
272168
272186
  },
272187
+ ".neuroglancer-rendered-data-panel:active": {
272188
+ cursor: "grabbing"
272189
+ },
272169
272190
  ".neuroglancer-display-dimensions-widget": {
272170
272191
  position: "absolute",
272171
272192
  cursor: "default",
@@ -273518,7 +273539,7 @@ function NeuroglancerGlobalStyles(props) {
273518
273539
  const { classes: classes2 } = props;
273519
273540
  return jsxs(Fragment, { children: [jsx$1(GlobalStyles$3, { styles: globalNeuroglancerCss }), jsx$1(ScopedGlobalStyles, { styles: globalNeuroglancerStyles, parentClassName: classes2.neuroglancerWrapper })] });
273520
273541
  }
273521
- const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-BLfUOvtO.js"));
273542
+ const LazyReactNeuroglancer = React__default.lazy(() => import("./ReactNeuroglancer-Bw5gQWL3.js"));
273522
273543
  function createWorker() {
273523
273544
  const worker = new WorkerFactory$1();
273524
273545
  worker.AsyncComputationWorker = WorkerFactory;
@@ -276552,7 +276573,7 @@ function useFilteredVolcanoData(props) {
276552
276573
  const rawSampleSetPathB = coordinationValues.sampleSetFilter[1];
276553
276574
  const sampleSetPathB = [...rawSampleSetPathB];
276554
276575
  sampleSetPathB[0] = sampleSetsColumnNameMappingReversed[rawSampleSetPathB[0]];
276555
- if (isEqual$3(sampleSetPathA, sampleSetSelection[1]) && isEqual$3(sampleSetPathB, sampleSetSelection[0])) {
276576
+ if (isEqual$3(sampleSetPathA, sampleSetSelection[0]) && isEqual$3(sampleSetPathB, sampleSetSelection[1])) {
276556
276577
  shouldSwapFoldChangeDirection = true;
276557
276578
  }
276558
276579
  }
@@ -328306,6 +328327,10 @@ function TreemapSubscriber(props) {
328306
328327
  }, [setObsSetSelection]);
328307
328328
  return jsxs(TitleInfo, { title: `Treemap of ${capitalize$3(pluralize(obsType, 2))}`, info: `${commaNumber(selectedObsCount)} ${pluralize(obsType, selectedObsCount)} from ${commaNumber(selectedSampleCount)} ${pluralize(sampleType, selectedSampleCount)}`, removeGridComponent, urls: urls2, theme, isReady, helpText, errors, withPadding: false, options: jsx$1(TreemapOptions, { obsType, sampleType, obsColorEncoding, setObsColorEncoding, hierarchyLevels: hierarchyLevels || DEFAULT_HIERARCHY_LEVELS, setHierarchyLevels }), children: [jsx$1("div", { ref: containerRef, className: classes2.vegaContainer, children: jsx$1(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 }) }), jsx$1("div", { style: { position: "absolute", right: "2px", bottom: "2px", fontSize: "10px" }, children: unselectedObsCount > 0 ? jsx$1("span", { children: `${commaNumber(unselectedObsCount)} ${pluralize(obsType, unselectedObsCount)} from ${commaNumber(unselectedSampleCount)} ${pluralize(sampleType, unselectedSampleCount)} currently omitted` }) : null })] });
328308
328329
  }
328330
+ const GOLDEN_RATIO = 0.6180339887498948;
328331
+ function topJitter(index2, rangePixels) {
328332
+ return index2 * GOLDEN_RATIO % 1 * rangePixels;
328333
+ }
328309
328334
  function VolcanoPlot(props) {
328310
328335
  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;
328311
328336
  const svgRef = useRef();
@@ -328367,10 +328392,10 @@ function VolcanoPlot(props) {
328367
328392
  const obsSetPath2 = [...rawObsSetPath];
328368
328393
  obsSetPath2[0] = obsSetsColumnNameMappingReversed[rawObsSetPath[0]];
328369
328394
  const color2 = obsSetColorScale(obsSetPath2);
328370
- obsSetG.append("g").selectAll("circle").data(filteredDf).join("circle").attr("cx", (d) => xScale(d.logFoldChange)).attr("cy", (d) => yScale(d.minusLog10p)).attr("r", 3).attr("opacity", 0.5).attr("fill", color2).on("click", (event2, d) => {
328395
+ obsSetG.append("g").selectAll("circle").data(filteredDf).join("circle").attr("cx", (d) => xScale(d.logFoldChange)).attr("cy", (d, i2) => yScale(d.minusLog10p) + (!Number.isFinite(d.minusLog10p) ? topJitter(i2, 20) : 0)).attr("r", 3).attr("opacity", 0.5).attr("fill", color2).on("click", (event2, d) => {
328371
328396
  onFeatureClick(d.featureId);
328372
328397
  });
328373
- const textElements = obsSetG.append("g").selectAll("text").data(filteredDf).join("text").text((d) => d.featureId).attr("text-anchor", (d) => d.logFoldChange < 0 ? "end" : "start").attr("x", (d) => xScale(d.logFoldChange)).attr("y", (d) => yScale(d.minusLog10p)).style("display", (d) => Math.abs(d.logFoldChange) < (featureLabelFoldChangeThreshold ?? 5) || d.featureSignificance >= (featureLabelSignificanceThreshold ?? 0.01) ? "none" : void 0).attr("fill", color2).on("click", (event2, d) => {
328398
+ const textElements = obsSetG.append("g").selectAll("text").data(filteredDf).join("text").text((d) => d.featureId).attr("text-anchor", (d) => d.logFoldChange < 0 ? "end" : "start").attr("x", (d) => xScale(d.logFoldChange)).attr("y", (d, i2) => yScale(d.minusLog10p) + (!Number.isFinite(d.minusLog10p) ? topJitter(i2, 20) : 0)).style("display", (d) => Math.abs(d.logFoldChange) < (featureLabelFoldChangeThreshold ?? 5) || d.featureSignificance >= (featureLabelSignificanceThreshold ?? 0.01) ? "none" : void 0).attr("fill", color2).on("click", (event2, d) => {
328374
328399
  onFeatureClick(d.featureId);
328375
328400
  });
328376
328401
  textElements.append("title").text((d) => `${featureType}: ${d.featureId}
@@ -353180,6 +353205,7 @@ const baseCoordinationTypes = [
353180
353205
  new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNEL_LABELS_VISIBLE, true, z.boolean()),
353181
353206
  new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNEL_LABELS_ORIENTATION, "vertical", z.enum(["vertical", "horizontal"])),
353182
353207
  new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNEL_LABEL_SIZE, 14, z.number()),
353208
+ new PluginCoordinationType(CoordinationType$1.SPATIAL_CHANNELS_SORT_ORDER, "original", z.enum(["original", "alphabetical"])),
353183
353209
  new PluginCoordinationType(CoordinationType$1.SAMPLE_TYPE, "sample", z.string().nullable()),
353184
353210
  // TODO: remove one array level and use multi-coordination for sampleSetSelection?
353185
353211
  new PluginCoordinationType(CoordinationType$1.SAMPLE_FILTER, null, z.array(z.string()).nullable()),
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a1, a0 } from "./index-DDD3apxS.js";
1
+ import { a1, a0 } from "./index-DYR0bplz.js";
2
2
  export {
3
3
  a1 as ControlledLauncher,
4
4
  a0 as UncontrolledLauncher
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-DDD3apxS.js";
1
+ import { B as BaseDecoder } from "./index-DYR0bplz.js";
2
2
  const dctZigZag = new Int32Array([
3
3
  0,
4
4
  1,
@@ -1,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-SxljTded.js";
2
- import { a as getDefaultExportFromCjs, B as BaseDecoder, L as LercParameters, b as LercAddCompression } from "./index-DDD3apxS.js";
2
+ import { a as getDefaultExportFromCjs, B as BaseDecoder, L as LercParameters, b as LercAddCompression } from "./index-DYR0bplz.js";
3
3
  var LercDecode = { exports: {} };
4
4
  var hasRequiredLercDecode;
5
5
  function requireLercDecode() {
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-DDD3apxS.js";
1
+ import { B as BaseDecoder } from "./index-DYR0bplz.js";
2
2
  const MIN_BITS = 9;
3
3
  const CLEAR_CODE = 256;
4
4
  const EOI_CODE = 257;
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-DDD3apxS.js";
1
+ import { B as BaseDecoder } from "./index-DYR0bplz.js";
2
2
  class PackbitsDecoder extends BaseDecoder {
3
3
  decodeBlock(buffer) {
4
4
  const dataView = new DataView(buffer);
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-DDD3apxS.js";
1
+ import { B as BaseDecoder } from "./index-DYR0bplz.js";
2
2
  class RawDecoder extends BaseDecoder {
3
3
  decodeBlock(buffer) {
4
4
  return buffer;
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-DDD3apxS.js";
1
+ import { B as BaseDecoder } from "./index-DYR0bplz.js";
2
2
  class WebImageDecoder extends BaseDecoder {
3
3
  constructor() {
4
4
  super();
@@ -0,0 +1,8 @@
1
+ import { g as getXRModule } from "./index-BlOIc49f.js";
2
+ const xrStore = getXRModule().createXRStore({
3
+ handTracking: true,
4
+ emulate: false
5
+ });
6
+ export {
7
+ xrStore as x
8
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/launcher",
3
- "version": "4.0.0",
3
+ "version": "4.0.1",
4
4
  "author": "HIDIVE Lab at HMS",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -20,14 +20,14 @@
20
20
  "use-query-params": "^1.1.9",
21
21
  "react-dropzone": "^14.3.8",
22
22
  "@tanstack/react-query": "^5.80.2",
23
- "@vitessce/all": "4.0.0",
24
- "@vitessce/constants-internal": "4.0.0",
25
- "@vitessce/example-configs": "4.0.0",
26
- "@vitessce/example-plugins": "4.0.0",
27
- "@vitessce/globals": "4.0.0",
28
- "@vitessce/styles": "4.0.0",
29
- "@vitessce/vit-s": "4.0.0",
30
- "@vitessce/config": "4.0.0"
23
+ "@vitessce/all": "4.0.1",
24
+ "@vitessce/example-configs": "4.0.1",
25
+ "@vitessce/example-plugins": "4.0.1",
26
+ "@vitessce/styles": "4.0.1",
27
+ "@vitessce/globals": "4.0.1",
28
+ "@vitessce/constants-internal": "4.0.1",
29
+ "@vitessce/config": "4.0.1",
30
+ "@vitessce/vit-s": "4.0.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "react": "19.2.6",
@@ -1,8 +0,0 @@
1
- import { createXRStore } from "@react-three/xr";
2
- const xrStore = createXRStore({
3
- handTracking: true,
4
- emulate: false
5
- });
6
- export {
7
- xrStore as x
8
- };