vitessce
Version:
Vitessce app and React component library
1,544 lines (1,519 loc) • 1.91 MB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __pow = Math.pow;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
var __require = typeof require !== "undefined" ? require : (x) => {
throw new Error('Dynamic require of "' + x + '" is not supported');
};
var __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/components/heatmap/HeatmapSubscriber.js
import React14, {
useEffect as useEffect5,
useState as useState6,
useCallback as useCallback5,
useMemo as useMemo5
} from "react";
// src/components/TitleInfo.js
import React3, { useState as useState2 } from "react";
import { makeStyles as makeStyles2 } from "@material-ui/core/styles";
import CloudDownloadIcon from "@material-ui/icons/CloudDownload";
import MenuItem from "@material-ui/core/MenuItem";
import IconButton2 from "@material-ui/core/IconButton";
import Link from "@material-ui/core/Link";
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
import ArrowDropUpIcon from "@material-ui/icons/ArrowDropUp";
import SettingsIcon from "@material-ui/icons/Settings";
import CloseIcon from "@material-ui/icons/Close";
// src/components/classNames.js
var TOOLTIP_ANCESTOR = "tooltip-ancestor";
var CARD = `card card-body my-2 ${TOOLTIP_ANCESTOR}`;
var PRIMARY_CARD = `${CARD} bg-primary`;
var SECONDARY_CARD = `${CARD} bg-secondary`;
var BLACK_CARD = `${CARD} bg-black`;
var SCROLL_CARD = `${PRIMARY_CARD} scroll`;
var VITESSCE_CONTAINER = "vitessce-container";
// src/components/LoadingIndicator.js
import React from "react";
import CircularProgress from "@material-ui/core/CircularProgress";
function LoadingIndicator() {
return /* @__PURE__ */ React.createElement("div", {
className: "loading-indicator-backdrop"
}, /* @__PURE__ */ React.createElement("div", {
className: "loading-indicator-container"
}, /* @__PURE__ */ React.createElement(CircularProgress, null)));
}
// src/components/shared-mui/components.js
import React2, { useRef as useRef3 } from "react";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import IconButton from "@material-ui/core/IconButton";
import MenuList from "@material-ui/core/MenuList";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Fade from "@material-ui/core/Fade";
// src/components/hooks.js
import {
useRef as useRef2,
useState,
useEffect,
useCallback as useCallback2,
useMemo as useMemo2
} from "react";
import debounce from "lodash/debounce";
// src/app/state/hooks.js
import { useRef, useCallback, useMemo } from "react";
import create from "zustand";
import createContext from "zustand/context";
import shallow from "zustand/shallow";
// src/app/constants.js
var Component = {
DESCRIPTION: "description",
STATUS: "status",
GENES: "genes",
CELL_SETS: "cellSets",
SCATTERPLOT: "scatterplot",
SPATIAL: "spatial",
HEATMAP: "heatmap",
LAYER_CONTROLLER: "layerController",
CELL_SET_SIZES: "cellSetSizes",
GENOMIC_PROFILES: "genomicProfiles",
CELL_SET_EXPRESSION: "cellSetExpression",
EXPRESSION_HISTOGRAM: "expressionHistogram",
GATING: "gating"
};
var DataType = {
CELLS: "cells",
CELL_SETS: "cell-sets",
EXPRESSION_MATRIX: "expression-matrix",
GENOMIC_PROFILES: "genomic-profiles",
MOLECULES: "molecules",
NEIGHBORHOODS: "neighborhoods",
RASTER: "raster"
};
var FileType = {
CELLS_JSON: "cells.json",
CELL_SETS_JSON: "cell-sets.json",
EXPRESSION_MATRIX_ZARR: "expression-matrix.zarr",
GENOMIC_PROFILES_ZARR: "genomic-profiles.zarr",
MOLECULES_JSON: "molecules.json",
NEIGHBORHOODS_JSON: "neighborhoods.json",
RASTER_JSON: "raster.json",
RASTER_OME_ZARR: "raster.ome-zarr",
CLUSTERS_JSON: "clusters.json",
GENES_JSON: "genes.json",
ANNDATA_CELL_SETS_ZARR: "anndata-cell-sets.zarr",
ANNDATA_CELLS_ZARR: "anndata-cells.zarr",
ANNDATA_EXPRESSION_MATRIX_ZARR: "anndata-expression-matrix.zarr"
};
var CoordinationType = {
DATASET: "dataset",
OBS_TYPE: "obsType",
FEATURE_TYPE: "featureType",
FEATURE_VALUE_TYPE: "featureValueType",
EMBEDDING_TYPE: "embeddingType",
EMBEDDING_ZOOM: "embeddingZoom",
EMBEDDING_ROTATION: "embeddingRotation",
EMBEDDING_TARGET_X: "embeddingTargetX",
EMBEDDING_TARGET_Y: "embeddingTargetY",
EMBEDDING_TARGET_Z: "embeddingTargetZ",
EMBEDDING_OBS_SET_POLYGONS_VISIBLE: "embeddingObsSetPolygonsVisible",
EMBEDDING_OBS_SET_LABELS_VISIBLE: "embeddingObsSetLabelsVisible",
EMBEDDING_OBS_SET_LABEL_SIZE: "embeddingObsSetLabelSize",
EMBEDDING_OBS_RADIUS: "embeddingObsRadius",
EMBEDDING_OBS_RADIUS_MODE: "embeddingObsRadiusMode",
EMBEDDING_OBS_OPACITY: "embeddingObsOpacity",
EMBEDDING_OBS_OPACITY_MODE: "embeddingObsOpacityMode",
SPATIAL_ZOOM: "spatialZoom",
SPATIAL_ROTATION: "spatialRotation",
SPATIAL_TARGET_X: "spatialTargetX",
SPATIAL_TARGET_Y: "spatialTargetY",
SPATIAL_TARGET_Z: "spatialTargetZ",
SPATIAL_ROTATION_X: "spatialRotationX",
SPATIAL_ROTATION_Y: "spatialRotationY",
SPATIAL_ROTATION_Z: "spatialRotationZ",
SPATIAL_ROTATION_ORBIT: "spatialRotationOrbit",
SPATIAL_ORBIT_AXIS: "spatialOrbitAxis",
SPATIAL_AXIS_FIXED: "spatialAxisFixed",
HEATMAP_ZOOM_X: "heatmapZoomX",
HEATMAP_ZOOM_Y: "heatmapZoomY",
HEATMAP_TARGET_X: "heatmapTargetX",
HEATMAP_TARGET_Y: "heatmapTargetY",
OBS_FILTER: "obsFilter",
OBS_HIGHLIGHT: "obsHighlight",
OBS_SET_SELECTION: "obsSetSelection",
OBS_SET_HIGHLIGHT: "obsSetHighlight",
OBS_SET_COLOR: "obsSetColor",
FEATURE_FILTER: "featureFilter",
FEATURE_HIGHLIGHT: "featureHighlight",
FEATURE_SELECTION: "featureSelection",
FEATURE_VALUE_COLORMAP: "featureValueColormap",
FEATURE_VALUE_TRANSFORM: "featureValueTransform",
FEATURE_VALUE_COLORMAP_RANGE: "featureValueColormapRange",
OBS_COLOR_ENCODING: "obsColorEncoding",
SPATIAL_IMAGE_LAYER: "spatialImageLayer",
SPATIAL_SEGMENTATION_LAYER: "spatialSegmentationLayer",
SPATIAL_POINT_LAYER: "spatialPointLayer",
SPATIAL_NEIGHBORHOOD_LAYER: "spatialNeighborhoodLayer",
GENOMIC_ZOOM_X: "genomicZoomX",
GENOMIC_ZOOM_Y: "genomicZoomY",
GENOMIC_TARGET_X: "genomicTargetX",
GENOMIC_TARGET_Y: "genomicTargetY",
ADDITIONAL_OBS_SETS: "additionalObsSets",
MOLECULE_HIGHLIGHT: "moleculeHighlight",
GATING_FEATURE_SELECTION_X: "gatingFeatureSelectionX",
GATING_FEATURE_SELECTION_Y: "gatingFeatureSelectionY",
FEATURE_VALUE_TRANSFORM_COEFFICIENT: "featureValueTransformCoefficient"
};
// src/utils.js
function fromEntries(iterable) {
return [...iterable].reduce((obj, { 0: key, 1: val }) => Object.assign(obj, { [key]: val }), {});
}
function pluralize(singular, plural, count) {
return count === 1 ? singular : plural;
}
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
}
function getLongestString(strings) {
return strings.reduce((prevLongest, currentValue) => prevLongest.length > currentValue.length ? prevLongest : currentValue);
}
function getNextScope(prevScopes) {
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const nextCharIndices = [0];
function next() {
const r = [];
nextCharIndices.forEach((charIndex) => {
r.unshift(chars[charIndex]);
});
let increment = true;
for (let i = 0; i < nextCharIndices.length; i++) {
const val = ++nextCharIndices[i];
if (val >= chars.length) {
nextCharIndices[i] = 0;
} else {
increment = false;
break;
}
}
if (increment) {
nextCharIndices.push(0);
}
return r.join("");
}
let nextScope;
do {
nextScope = next();
} while (prevScopes.includes(nextScope));
return nextScope;
}
function getSourceFromLoader(loader, level) {
const { data } = loader;
const source = Array.isArray(data) ? data[level || data.length - 1] : data;
return source;
}
function isRgb(loader) {
const source = getSourceFromLoader(loader);
const { shape, dtype, labels } = source;
const channelSize = shape[labels.indexOf("c")];
return channelSize === 3 && dtype === "Uint8";
}
// src/app/state/hooks.js
var {
Provider: ViewConfigProviderLocal,
useStore: useViewConfigStoreLocal,
useStoreApi: useViewConfigStoreApiLocal
} = createContext();
var ViewConfigProvider = ViewConfigProviderLocal;
var useViewConfigStore = useViewConfigStoreLocal;
var useViewConfigStoreApi = useViewConfigStoreApiLocal;
var {
Provider: AuxiliaryProviderLocal,
useStore: useAuxiliaryStoreLocal
} = createContext();
var AuxiliaryProvider = AuxiliaryProviderLocal;
var useAuxiliaryStore = useAuxiliaryStoreLocal;
var createViewConfigStore = () => create((set) => ({
viewConfig: null,
loaders: null,
setViewConfig: (viewConfig) => set({ viewConfig }),
setLoaders: (loaders) => set({ loaders }),
setCoordinationValue: ({ parameter, scope, value }) => set((state) => ({
viewConfig: __spreadProps(__spreadValues({}, state.viewConfig), {
coordinationSpace: __spreadProps(__spreadValues({}, state.viewConfig.coordinationSpace), {
[parameter]: __spreadProps(__spreadValues({}, state.viewConfig.coordinationSpace[parameter]), {
[scope]: value
})
})
})
})),
removeComponent: (uid) => set((state) => {
const newLayout = state.viewConfig.layout.filter((c) => c.uid !== uid);
return {
viewConfig: __spreadProps(__spreadValues({}, state.viewConfig), {
layout: newLayout
})
};
}),
changeLayout: (newComponentProps) => set((state) => {
const newLayout = state.viewConfig.layout.slice();
newComponentProps.forEach(([i, newProps]) => {
newLayout[i] = __spreadValues(__spreadValues({}, newLayout[i]), newProps);
});
return {
viewConfig: __spreadProps(__spreadValues({}, state.viewConfig), {
layout: newLayout
})
};
})
}));
var useComponentLayout = (component, scopes, coordinationScopes) => useViewConfigStore((state) => state.viewConfig.layout.filter((l) => l.component === component).filter((l) => scopes.every((scope) => l.coordinationScopes[scope] === coordinationScopes[scope])));
var createAuxiliaryStore = () => create((set) => ({
auxiliaryStore: null,
setCoordinationValue: ({ parameter, scope, value }) => set((state) => ({
auxiliaryStore: __spreadProps(__spreadValues({}, state.auxiliaryStore), {
[parameter]: {
[scope]: value
}
})
}))
}));
var useHoverStore = create((set) => ({
componentHover: null,
setComponentHover: (componentHover) => set({ componentHover })
}));
var useWarnStore = create((set) => ({
warning: null,
setWarning: (warning) => set({ warning })
}));
var useViewInfoStore = create((set) => ({
viewInfo: {},
setComponentViewInfo: (uuid, viewInfo) => set((state) => ({
viewInfo: __spreadProps(__spreadValues({}, state.viewInfo), {
[uuid]: viewInfo
})
}))
}));
var useGridSizeStore = create((set) => ({
resizeCount: {},
incrementResizeCount: () => set((state) => ({
resizeCount: state.resizeCount + 1
}))
}));
function useCoordination(parameters, coordinationScopes) {
const setCoordinationValue = useViewConfigStore((state) => state.setCoordinationValue);
const values = useViewConfigStore((state) => {
const { coordinationSpace } = state.viewConfig;
return fromEntries(parameters.map((parameter) => {
if (coordinationSpace && coordinationSpace[parameter]) {
const value = coordinationSpace[parameter][coordinationScopes[parameter]];
return [parameter, value];
}
return [parameter, void 0];
}));
}, shallow);
const setters = useMemo(() => fromEntries(parameters.map((parameter) => {
const setterName = `set${capitalize(parameter)}`;
const setterFunc = (value) => setCoordinationValue({
parameter,
scope: coordinationScopes[parameter],
value
});
return [setterName, setterFunc];
})), [parameters, coordinationScopes]);
return [values, setters];
}
function useDatasetUids(coordinationScopes) {
const parameter = CoordinationType.DATASET;
const datasetScopes = coordinationScopes[parameter];
const datasetUids = useViewConfigStore((state) => {
const { coordinationSpace } = state.viewConfig;
const datasetScopesArr = Array.isArray(datasetScopes) ? datasetScopes : [datasetScopes];
return fromEntries(datasetScopesArr.map((datasetScope) => {
if (coordinationSpace && coordinationSpace[parameter]) {
const value = coordinationSpace[parameter][datasetScope];
return [datasetScope, value];
}
return [datasetScope, void 0];
}));
}, shallow);
return datasetUids;
}
function useMultiDatasetCoordination(parameters, coordinationScopes) {
const setCoordinationValue = useViewConfigStore((state) => state.setCoordinationValue);
const datasetScopes = coordinationScopes[CoordinationType.DATASET];
const datasetScopesArr = Array.isArray(datasetScopes) ? datasetScopes : [datasetScopes];
const values = useViewConfigStore((state) => {
const { coordinationSpace } = state.viewConfig;
return fromEntries(datasetScopesArr.map((datasetScope) => {
const datasetValues = fromEntries(parameters.map((parameter) => {
if (coordinationSpace && coordinationSpace[parameter]) {
let value;
const parameterSpace = coordinationSpace[parameter];
const parameterScope = coordinationScopes[parameter];
if (typeof parameterScope === "object") {
value = parameterSpace[parameterScope[datasetScope]];
} else if (typeof parameterScope === "string") {
value = parameterSpace[parameterScope];
} else {
console.error(`coordination scope for ${parameter} must be of type string or object.`);
}
return [parameter, value];
}
return [parameter, void 0];
}));
return [datasetScope, datasetValues];
}));
}, shallow);
const setters = useMemo(() => fromEntries(datasetScopesArr.map((datasetScope) => {
const datasetSetters = fromEntries(parameters.map((parameter) => {
const setterName = `set${capitalize(parameter)}`;
let setterFunc;
const parameterScope = coordinationScopes[parameter];
if (typeof parameterScope === "object") {
setterFunc = (value) => setCoordinationValue({
parameter,
scope: parameterScope[datasetScope],
value
});
} else if (typeof parameterScope === "string") {
setterFunc = (value) => setCoordinationValue({
parameter,
scope: parameterScope,
value
});
} else {
console.error(`coordination scope for ${parameter} must be of type string or object.`);
}
return [setterName, setterFunc];
}));
return [datasetScope, datasetSetters];
})), [parameters, coordinationScopes]);
return [values, setters];
}
var AUXILIARY_COORDINATION_TYPES_MAP = {
spatialImageLayer: ["rasterLayersCallbacks", "areLoadingRasterChannnels"]
};
var mapCoordinationScopes = (coordinationScopes) => {
const newCoordinationScopes = {};
Object.keys(coordinationScopes).forEach((key) => {
const newCoordinationTypes = AUXILIARY_COORDINATION_TYPES_MAP[key] || [];
newCoordinationTypes.forEach((coordinationType) => {
newCoordinationScopes[coordinationType || key] = coordinationScopes[key];
});
});
return newCoordinationScopes;
};
var mapParameters = (parameters) => parameters.map((parameter) => AUXILIARY_COORDINATION_TYPES_MAP[parameter]).filter(Boolean).flat();
function useAuxiliaryCoordination(parameters, coordinationScopes) {
const setCoordinationValue = useAuxiliaryStore((state) => state.setCoordinationValue);
const mappedCoordinationScopes = mapCoordinationScopes(coordinationScopes);
const mappedParameters = mapParameters(parameters);
const values = useAuxiliaryStore((state) => {
const { auxiliaryStore } = state;
return fromEntries(mappedParameters.map((parameter) => {
if (auxiliaryStore && auxiliaryStore[parameter]) {
const value = auxiliaryStore[parameter][mappedCoordinationScopes[parameter]];
return [parameter, value];
}
return [parameter, void 0];
}));
}, shallow);
const setters = useMemo(() => fromEntries(mappedParameters.map((parameter) => {
const setterName = `set${capitalize(parameter)}`;
const setterFunc = (value) => setCoordinationValue({
parameter,
scope: mappedCoordinationScopes[parameter],
value
});
return [setterName, setterFunc];
})), [parameters, coordinationScopes]);
return [values, setters];
}
function useLoaders() {
return useViewConfigStore((state) => state.loaders);
}
function useLayout() {
return useViewConfigStore((state) => {
var _a2;
return (_a2 = state.viewConfig) == null ? void 0 : _a2.layout;
});
}
function useRemoveComponent() {
return useViewConfigStore((state) => state.removeComponent);
}
function useChangeLayout() {
return useViewConfigStore((state) => state.changeLayout);
}
function useSetLoaders() {
return useViewConfigStore((state) => state.setLoaders);
}
function useSetViewConfig(viewConfigStoreApi) {
const setViewConfigRef = useRef(viewConfigStoreApi.getState().setViewConfig);
const setViewConfig = setViewConfigRef.current;
return setViewConfig;
}
function useComponentHover() {
return useHoverStore((state) => state.componentHover);
}
function useSetComponentHover() {
return useHoverStore((state) => state.setComponentHover);
}
function useWarning() {
return useWarnStore((state) => state.warning);
}
function useSetWarning() {
return useWarnStore((state) => state.setWarning);
}
function useComponentViewInfo(uuid) {
return useViewInfoStore(useCallback((state) => state.viewInfo[uuid], [uuid]));
}
function useSetComponentViewInfo(uuid) {
const setViewInfoRef = useRef(useViewInfoStore.getState().setComponentViewInfo);
const setComponentViewInfo = (viewInfo) => setViewInfoRef.current(uuid, viewInfo);
return setComponentViewInfo;
}
function useGridResize() {
return useGridSizeStore((state) => state.resizeCount);
}
function useEmitGridResize() {
return useGridSizeStore((state) => state.incrementResizeCount);
}
// src/components/hooks.js
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
function useVitessceContainer(ref) {
return useCallback2(() => {
if (ref.current) {
return ref.current.closest(`.${VITESSCE_CONTAINER}`);
}
return null;
}, [ref]);
}
function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
const onResizeDebounced = debounce(handleResize, 100, { trailing: true });
window.addEventListener("resize", onResizeDebounced);
return () => window.removeEventListener("resize", onResizeDebounced);
}, []);
return windowDimensions;
}
function useGridItemSize() {
const containerRef = useRef2();
const [height, setHeight] = useState();
const [width, setWidth] = useState();
const resizeCount = useGridResize();
const incrementResizeCount = useEmitGridResize();
useEffect(() => {
function onWindowResize() {
incrementResizeCount();
}
const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });
window.addEventListener("resize", onResizeDebounced);
onWindowResize();
return () => {
window.removeEventListener("resize", onResizeDebounced);
};
}, [incrementResizeCount]);
useEffect(() => {
if (!containerRef.current)
return;
const container = containerRef.current;
const containerRect = container.getBoundingClientRect();
setHeight(containerRect.height);
setWidth(containerRect.width);
}, [resizeCount]);
return [width, height, containerRef];
}
function useDeckCanvasSize() {
const deckRef = useRef2();
const [height, setHeight] = useState();
const [width, setWidth] = useState();
const resizeCount = useGridResize();
const incrementResizeCount = useEmitGridResize();
useEffect(() => {
function onWindowResize() {
incrementResizeCount();
}
const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });
window.addEventListener("resize", onResizeDebounced);
onWindowResize();
return () => {
window.removeEventListener("resize", onResizeDebounced);
};
}, [incrementResizeCount]);
useEffect(() => {
if (!deckRef.current)
return;
const { canvas } = deckRef.current.deck;
const canvasRect = canvas.getBoundingClientRect();
setHeight(canvasRect.height);
setWidth(canvasRect.width);
}, [resizeCount]);
return [width, height, deckRef];
}
function useReady(supportedItems) {
const items2 = supportedItems;
const [waiting, setWaiting] = useState(items2);
const setItemIsReady = useCallback2((readyItem) => {
setWaiting((waitingItems) => {
const nextWaitingItems = waitingItems.filter((item) => item !== readyItem);
console.log(`cleared ${readyItem}; waiting on ${nextWaitingItems.length}: ${JSON.stringify(nextWaitingItems)}`);
return nextWaitingItems;
});
}, [setWaiting]);
const setItemIsNotReady = useCallback2((notReadyItem) => {
setWaiting((waitingItems) => {
const nextWaitingItems = [...waitingItems, notReadyItem];
console.log(`waiting on ${nextWaitingItems.length}: ${JSON.stringify(nextWaitingItems)}`);
return nextWaitingItems;
});
}, [setWaiting]);
const resetReadyItems = useCallback2(() => {
setWaiting(items2);
console.log(`waiting on ${items2.length}: ${JSON.stringify(items2)}`);
}, [setWaiting, items2]);
const isReady = waiting.length === 0;
return [isReady, setItemIsReady, setItemIsNotReady, resetReadyItems];
}
function useUrls() {
const [urls, setUrls] = useState([]);
const addUrl = useCallback2((url, name2) => {
if (url) {
setUrls((prev) => [...prev, { url, name: name2 }]);
}
}, [setUrls]);
const resetUrls = useCallback2(() => {
setUrls([]);
}, [setUrls]);
return [urls, addUrl, resetUrls];
}
function useClosestVitessceContainerSize(ref) {
const [height, setHeight] = useState();
const [width, setWidth] = useState();
useEffect(() => {
function onWindowResize() {
if (ref.current) {
const {
clientHeight: componentHeight,
clientWidth: componentWidth
} = ref.current.closest(".vitessce-container");
setWidth(componentWidth);
setHeight(componentHeight);
}
}
const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });
window.addEventListener("resize", onResizeDebounced);
onWindowResize();
return () => {
window.removeEventListener("resize", onResizeDebounced);
};
}, [ref]);
return [width, height];
}
function useExpressionValueGetter({ attrs, expressionData }) {
const cellIdMap = useMemo2(() => {
const result = {};
if (attrs && attrs.rows) {
for (let i = 0; i < attrs.rows.length; i++) {
result[attrs.rows[i]] = i;
}
}
return result;
}, [attrs]);
const getExpressionValue = useCallback2((entry) => {
const cellId = entry[0];
if (cellIdMap && expressionData && expressionData[0]) {
const cellIndex = cellIdMap[cellId];
const val = expressionData[0][cellIndex];
return val;
}
return 0;
}, [cellIdMap, expressionData]);
return getExpressionValue;
}
// src/components/shared-mui/styles.js
import { makeStyles, createTheme } from "@material-ui/core/styles";
import { grey } from "@material-ui/core/colors";
var styles = makeStyles(() => ({
paper: {
maxHeight: 200,
overflow: "auto"
},
container: {
position: "relative",
left: 0,
top: 0
},
span: {
width: "70px",
textAlign: "center",
paddingLeft: "2px",
paddingRight: "2px"
}
}));
var muiTheme = {
dark: createTheme({
palette: {
type: "dark",
primary: grey,
secondary: grey,
primaryBackground: "#222222",
primaryBackgroundHighlight: "#000000",
primaryBackgroundInput: "#D3D3D3",
primaryBackgroundDim: "#333333",
primaryBackgroundLight: "#757575",
primaryForeground: "#D3D3D3",
primaryForegroundDim: "#000000",
primaryForegroundActive: "#9bb7d6",
secondaryBackground: "#000000",
secondaryBackgroundDim: "#444444",
secondaryForeground: "#D3D3D3"
},
props: {
MuiButtonBase: {
disableRipple: true
}
}
}),
light: createTheme({
palette: {
type: "light",
primary: grey,
secondary: grey,
primaryBackground: "#F1F1F1",
primaryBackgroundHighlight: "#FFFFFF",
primaryBackgroundInput: "#FFFFFF",
primaryBackgroundDim: "#8A8A8A",
primaryBackgroundLight: "#e0e0e0",
primaryForeground: "#333333",
primaryForegroundDim: "#808080",
primaryForegroundActive: "#0074D9",
secondaryBackground: "#F1F1F1",
secondaryBackgroundDim: "#C0C0C0",
secondaryForeground: "#222222"
},
props: {
MuiButtonBase: {
disableRipple: true
}
}
})
};
// src/components/shared-mui/components.js
function MuiSpan(props) {
const { children } = props;
const classes = styles();
return /* @__PURE__ */ React2.createElement("span", {
className: classes.span
}, children);
}
function PopperMenu(props) {
const {
buttonIcon,
open,
setOpen,
children,
buttonClassName,
placement = "bottom-end"
} = props;
const classes = styles();
const anchorRef = useRef3();
const handleClick = () => {
setOpen((prev) => !prev);
};
const handleClose = () => {
setOpen(false);
};
const id = open ? "v-popover-menu" : void 0;
const getTooltipContainer = useVitessceContainer(anchorRef);
return /* @__PURE__ */ React2.createElement("div", {
ref: anchorRef,
className: classes.container
}, /* @__PURE__ */ React2.createElement(IconButton, {
"aria-describedby": id,
onClick: handleClick,
size: "small",
className: buttonClassName
}, buttonIcon), /* @__PURE__ */ React2.createElement(Popper, {
id,
open,
anchorEl: anchorRef && anchorRef.current,
container: getTooltipContainer,
onClose: handleClose,
placement,
transition: true
}, ({ TransitionProps }) => /* @__PURE__ */ React2.createElement(ClickAwayListener, {
onClickAway: handleClose
}, /* @__PURE__ */ React2.createElement(Fade, __spreadProps(__spreadValues({}, TransitionProps), {
timeout: 100
}), /* @__PURE__ */ React2.createElement(Paper, {
elevation: 4,
className: classes.paper
}, /* @__PURE__ */ React2.createElement(MenuList, null, children))))));
}
// src/components/TitleInfo.js
var useStyles = makeStyles2((theme) => ({
iconButton: {
border: "none",
marginLeft: 0,
background: "none",
color: theme.palette.primaryForeground,
paddingLeft: "0.25em",
paddingRight: "0.25em",
borderRadius: "2px",
"&:hover": {
backgroundColor: theme.palette.primaryBackgroundLight
},
"&:first-child": {
marginLeft: "0.25em"
},
"&:last-child": {
marginRight: "0.25em"
},
"& svg": {
width: "0.7em",
height: "0.7em",
verticalAlign: "middle",
overflow: "visible"
}
},
downloadLink: {
color: theme.palette.primaryForeground
}
}));
function SettingsIconWithArrow({ open }) {
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(SettingsIcon, null), open ? /* @__PURE__ */ React3.createElement(ArrowDropUpIcon, null) : /* @__PURE__ */ React3.createElement(ArrowDropDownIcon, null));
}
function PlotOptions(props) {
const { options } = props;
const [open, setOpen] = useState2(false);
const classes = useStyles();
return /* @__PURE__ */ React3.createElement(PopperMenu, {
open,
setOpen,
buttonIcon: /* @__PURE__ */ React3.createElement(SettingsIconWithArrow, {
open
}),
buttonClassName: classes.iconButton,
placement: "bottom-end"
}, options);
}
function CloudDownloadIconWithArrow({ open }) {
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(CloudDownloadIcon, null), open ? /* @__PURE__ */ React3.createElement(ArrowDropUpIcon, null) : /* @__PURE__ */ React3.createElement(ArrowDropDownIcon, null));
}
function DownloadOptions(props) {
const { urls } = props;
const [open, setOpen] = useState2(false);
const classes = useStyles();
return /* @__PURE__ */ React3.createElement(PopperMenu, {
open,
setOpen,
buttonIcon: /* @__PURE__ */ React3.createElement(CloudDownloadIconWithArrow, {
open
}),
buttonClassName: classes.iconButton,
placement: "bottom-end"
}, urls.map(({ url, name: name2 }) => /* @__PURE__ */ React3.createElement(MenuItem, {
dense: true,
key: url
}, /* @__PURE__ */ React3.createElement(Link, {
underline: "none",
href: url,
target: "_blank",
rel: "noopener",
className: classes.downloadLink
}, "Download ", name2))));
}
function ClosePaneButton(props) {
const { removeGridComponent } = props;
const classes = useStyles();
return /* @__PURE__ */ React3.createElement(IconButton2, {
onClick: removeGridComponent,
size: "small",
className: classes.iconButton,
title: "close"
}, /* @__PURE__ */ React3.createElement(CloseIcon, null));
}
function TitleInfo(props) {
const {
title: title25,
info,
children,
isScroll,
isSpatial,
removeGridComponent,
urls,
isReady,
options
} = props;
const childClassName = isScroll ? SCROLL_CARD : isSpatial ? BLACK_CARD : SECONDARY_CARD;
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", {
className: "title"
}, /* @__PURE__ */ React3.createElement("div", {
className: "title-left"
}, title25), /* @__PURE__ */ React3.createElement("div", {
className: "title-info",
title: info
}, info), /* @__PURE__ */ React3.createElement("div", {
className: "title-buttons"
}, options && /* @__PURE__ */ React3.createElement(PlotOptions, {
options
}), urls && urls.length > 0 && /* @__PURE__ */ React3.createElement(DownloadOptions, {
urls
}), /* @__PURE__ */ React3.createElement(ClosePaneButton, {
removeGridComponent
}))), /* @__PURE__ */ React3.createElement("div", {
className: childClassName
}, !isReady && /* @__PURE__ */ React3.createElement(LoadingIndicator, null), children));
}
// src/components/utils.js
import React4 from "react";
import { COORDINATE_SYSTEM } from "@deck.gl/core";
// src/schemas/cell-sets.schema.json
var $schema = "http://json-schema.org/draft-07/schema#";
var $id = "https://github.com/vitessce/vitessce/#cell-sets";
var title = "Vitessce cell sets data";
var type = "object";
var definitions = {
stringArray: {
type: "array",
items: {
type: "string"
}
},
stringProbabilityTupleArray: {
type: "array",
items: {
type: "array",
additionalItems: false,
items: [
{
type: "string"
},
{
oneOf: [
{
type: "number",
minimum: 0,
maximum: 1
},
{
type: "null"
}
]
}
]
}
},
colorArray: {
type: "array",
items: {
type: "integer",
minimum: 0,
maximum: 255
},
minItems: 3,
maxItems: 3
},
treeNodeLeaf: {
type: "object",
additionalProperties: false,
required: ["name"],
properties: {
name: {
type: "string"
},
color: {
$ref: "#/definitions/colorArray"
},
set: {
$ref: "#/definitions/stringArray"
}
}
},
treeNodeNonLeaf: {
type: "object",
additionalProperties: false,
required: ["name"],
properties: {
name: {
type: "string"
},
color: {
$ref: "#/definitions/colorArray"
},
children: {
type: "array",
items: {
$ref: "#/definitions/treeNode"
}
}
}
},
treeNode: {
oneOf: [
{
$ref: "#/definitions/treeNodeNonLeaf"
},
{
$ref: "#/definitions/treeNodeLeaf"
}
]
},
"version0.1.2": {
type: "object",
additionalProperties: false,
required: ["version", "datatype", "tree"],
properties: {
dataset: {
type: "string"
},
version: {
type: "string",
enum: ["0.1.2"]
},
datatype: {
type: "string",
enum: ["cell"]
},
tree: {
type: "array",
items: {
$ref: "#/definitions/treeNodeNonLeaf"
}
}
}
},
treeNodeLeafProbabilistic: {
type: "object",
additionalProperties: false,
required: ["name"],
properties: {
name: {
type: "string"
},
color: {
$ref: "#/definitions/colorArray"
},
set: {
$ref: "#/definitions/stringProbabilityTupleArray"
}
}
},
treeNodeNonLeafProbabilistic: {
type: "object",
additionalProperties: false,
required: ["name"],
properties: {
name: {
type: "string"
},
color: {
$ref: "#/definitions/colorArray"
},
children: {
type: "array",
items: {
$ref: "#/definitions/treeNodeProbabilistic"
}
}
}
},
treeNodeProbabilistic: {
oneOf: [
{
$ref: "#/definitions/treeNodeNonLeafProbabilistic"
},
{
$ref: "#/definitions/treeNodeLeafProbabilistic"
}
]
},
"version0.1.3": {
type: "object",
additionalProperties: false,
required: ["version", "datatype", "tree"],
properties: {
dataset: {
type: "string"
},
version: {
type: "string",
enum: ["0.1.3"]
},
datatype: {
type: "string",
enum: ["cell"]
},
tree: {
type: "array",
items: {
$ref: "#/definitions/treeNodeNonLeafProbabilistic"
}
}
}
}
};
var oneOf = [
{
$ref: "#/definitions/version0.1.2"
},
{
$ref: "#/definitions/version0.1.3"
}
];
var cell_sets_schema_default = {
$schema,
$id,
title,
type,
definitions,
oneOf
};
// src/schemas/cell-sets-tabular.schema.json
var $schema2 = "http://json-schema.org/draft-07/schema#";
var $id2 = "https://github.com/vitessce/vitessce/#cell-sets-tabular";
var title2 = "Vitessce cell sets data, tabular format";
var definitions2 = {
colorArray: {
type: "array",
items: { type: "integer", minimum: 0, maximum: 255 },
minItems: 3,
maxItems: 3
}
};
var type2 = "array";
var items = {
type: "object",
additionalProperties: false,
required: ["groupName", "setName", "obsId"],
properties: {
groupName: { type: "string" },
setName: { type: "string" },
setColor: { $ref: "#/definitions/colorArray" },
obsId: { type: "string" },
predictionScore: {
oneOf: [
{
type: "number",
minimum: 0,
maximum: 1
},
{
type: "null"
}
]
}
}
};
var cell_sets_tabular_schema_default = {
$schema: $schema2,
$id: $id2,
title: title2,
definitions: definitions2,
type: type2,
items
};
// src/components/sets/constants.js
var FILE_EXTENSION_JSON = "json";
var MIME_TYPE_JSON = "application/json";
var FILE_EXTENSION_TABULAR = "csv";
var MIME_TYPE_TABULAR = "text/csv";
var SEPARATOR_TABULAR = ",";
var NA_VALUE_TABULAR = "NA";
var SETS_DATATYPE_CELL = "cell";
var HIERARCHICAL_SCHEMAS = {
cell: {
latestVersion: "0.1.3",
schema: cell_sets_schema_default
}
};
var TABULAR_SCHEMAS = {
cell: {
schema: cell_sets_tabular_schema_default
}
};
// src/components/utils.js
function makeCellStatusMessage(cellInfoFactors) {
return Object.entries(cellInfoFactors).map(([factor, value]) => `${factor}: ${value}`).join("; ");
}
function cellLayerDefaultProps(cells, updateStatus, setCellHighlight, setComponentHover) {
return {
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
data: cells,
pickable: true,
autoHighlight: true,
stroked: true,
filled: true,
getElevation: 0,
onHover: (info) => {
if (setComponentHover) {
setComponentHover();
}
if (info.object) {
const [cellId, cellInfo] = info.object;
const { factors = {} } = cellInfo;
if (updateStatus) {
updateStatus(makeCellStatusMessage(factors));
}
if (setCellHighlight) {
setCellHighlight(cellId);
}
} else if (setCellHighlight) {
setCellHighlight("");
}
}
};
}
var DEFAULT_DARK_COLOR = [50, 50, 50];
var DEFAULT_LIGHT_COLOR = [200, 200, 200];
function getDefaultColor(theme) {
return theme === "dark" ? DEFAULT_DARK_COLOR : DEFAULT_LIGHT_COLOR;
}
var PALETTE = [
[68, 119, 170],
[136, 204, 238],
[68, 170, 153],
[17, 119, 51],
[153, 153, 51],
[221, 204, 119],
[204, 102, 119],
[136, 34, 85],
[170, 68, 153]
];
var VIEWER_PALETTE = [
[0, 0, 255],
[0, 255, 0],
[255, 0, 255],
[255, 255, 0],
[0, 255, 255],
[255, 255, 255],
[255, 128, 0],
[255, 0, 0]
];
var COLORMAP_OPTIONS = [
"viridis",
"greys",
"magma",
"jet",
"hot",
"bone",
"copper",
"summer",
"density",
"inferno"
];
var DEFAULT_GL_OPTIONS = { webgl2: true };
function createDefaultUpdateCellsHover(componentName) {
return (hoverInfo) => console.warn(`${componentName} updateCellsHover: ${hoverInfo.cellId}`);
}
function createDefaultUpdateGenesHover(componentName) {
return (hoverInfo) => console.warn(`${componentName} updateGenesHover: ${hoverInfo.geneId}`);
}
function createDefaultUpdateTracksHover(componentName) {
return (hoverInfo) => console.warn(`${componentName} updateTracksHover: ${hoverInfo}`);
}
function createDefaultUpdateViewInfo(componentName) {
return (viewInfo) => console.warn(`${componentName} updateViewInfo: ${viewInfo}`);
}
function copyUint8Array(arr) {
const newBuffer = new ArrayBuffer(arr.buffer.byteLength);
const newArr = new Uint8Array(newBuffer);
newArr.set(arr);
return newArr;
}
function getNextNumberedNodeName(nodes, prefix) {
let i = 1;
if (nodes) {
while (nodes.find((n) => n.name === `${prefix}${i}`)) {
i++;
}
}
return `${prefix}${i}`;
}
function setCellSelection(cellSelection, additionalCellSets, cellSetColor, setCellSetSelection, setAdditionalCellSets, setCellSetColor, setCellColorEncoding, prefix = "Selection ") {
const CELL_SELECTIONS_LEVEL_ZERO_NAME = "My Selections";
const selectionsLevelZeroNode = additionalCellSets == null ? void 0 : additionalCellSets.tree.find((n) => n.name === CELL_SELECTIONS_LEVEL_ZERO_NAME);
const nextAdditionalCellSets = {
version: HIERARCHICAL_SCHEMAS[SETS_DATATYPE_CELL].latestVersion,
datatype: SETS_DATATYPE_CELL,
tree: [...additionalCellSets ? additionalCellSets.tree : []]
};
const nextName = getNextNumberedNodeName(selectionsLevelZeroNode == null ? void 0 : selectionsLevelZeroNode.children, prefix);
let colorIndex = 0;
if (selectionsLevelZeroNode) {
colorIndex = selectionsLevelZeroNode.children.length;
selectionsLevelZeroNode.children.push({
name: nextName,
set: cellSelection.map((d) => [d, null])
});
} else {
nextAdditionalCellSets.tree.push({
name: CELL_SELECTIONS_LEVEL_ZERO_NAME,
children: [
{
name: nextName,
set: cellSelection.map((d) => [d, null])
}
]
});
}
setAdditionalCellSets(nextAdditionalCellSets);
const nextPath = ["My Selections", nextName];
setCellSetColor([
...cellSetColor || [],
{
path: nextPath,
color: PALETTE[colorIndex % PALETTE.length]
}
]);
setCellSetSelection([nextPath]);
setCellColorEncoding("cellSetSelection");
}
function mergeCellSets(cellSets, additionalCellSets) {
return {
version: HIERARCHICAL_SCHEMAS[SETS_DATATYPE_CELL].latestVersion,
datatype: SETS_DATATYPE_CELL,
tree: [
...cellSets ? cellSets.tree : [],
...additionalCellSets ? additionalCellSets.tree : []
]
};
}
function createWarningComponent(props) {
return () => {
const {
title: title25,
message
} = props;
return /* @__PURE__ */ React4.createElement("div", {
className: PRIMARY_CARD
}, /* @__PURE__ */ React4.createElement("h1", null, title25), /* @__PURE__ */ React4.createElement("div", null, message));
};
}
function asEsModule(component) {
return {
__esModule: true,
default: component
};
}
function formatBytes(bytes, decimals = 2) {
if (bytes === 0)
return "0 Bytes";
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ["Bytes", "KB", "MB", "GB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
}
var getStatsForResolution = (loader, resolution) => {
const { shape, labels } = loader[resolution];
const height = shape[labels.indexOf("y")];
const width = shape[labels.indexOf("x")];
const depth = shape[labels.indexOf("z")];
const depthDownsampled = Math.max(1, depth >> resolution);
const totalBytes = 4 * height * width * depthDownsampled;
return {
height,
width,
depthDownsampled,
totalBytes
};
};
var canLoadResolution = (loader, resolution) => {
var _a2, _b2, _c;
const {
totalBytes,
height,
width,
depthDownsampled
} = getStatsForResolution(loader, resolution);
const maxHeapSize = ((_a2 = window.performance) == null ? void 0 : _a2.memory) && ((_c = (_b2 = window.performance) == null ? void 0 : _b2.memory) == null ? void 0 : _c.jsHeapSizeLimit) / 2;
const maxSize = maxHeapSize || __pow(2, 31) - 1;
return totalBytes < maxSize && height <= 2048 && depthDownsampled <= 2048 && width <= 2048 && depthDownsampled > 1;
};
// src/components/data-hooks.js
import { useState as useState3, useEffect as useEffect2 } from "react";
import equal2 from "fast-deep-equal";
// src/loaders/errors/AbstractLoaderError.js
var AbstractLoaderError = class {
constructor(message) {
this.message = message;
}
warnInConsole() {
throw new Error("The warnInConsole() method has not been implemented.");
}
};
// src/loaders/errors/LoaderValidationError.js
var LoaderValidationError = class extends AbstractLoaderError {
constructor(datasetType, datasetFileType, datasetUrl, reason) {
super(`Error while validating ${datasetType}.`);
this.name = "LoaderValidationError";
this.datasetType = datasetType;
this.datasetFileType = datasetFileType;
this.datasetUrl = datasetUrl;
this.reason = reason;
}
warnInConsole() {
const {
datasetType,
datasetUrl,
reason
} = this;
console.warn(`${datasetType} from ${datasetUrl}: validation failed`, JSON.stringify(reason, null, 2));
}
};
// src/loaders/errors/LoaderNotFoundError.js
var LoaderNotFoundError = class extends AbstractLoaderError {
constructor(datasetType, datasetFileType, datasetUrl) {
super(`Error finding loader for ${datasetType}.`);
this.name = "LoaderNotFoundError";
this.datasetType = datasetType;
this.datasetFileType = datasetFileType;
this.datasetUrl = datasetUrl;
}
warnInConsole() {
const {
datasetType,
datasetFileType,
datasetUrl
} = this;
if (datasetFileType && datasetUrl) {
console.warn(`${datasetType} from ${datasetUrl}: unable to find loader for fileType ${datasetFileType}`);
} else {
console.warn(`${datasetType}: unable to find loader`);
}
}
};
// src/loaders/errors/DatasetNotFoundError.js
var DatasetNotFoundError = class extends AbstractLoaderError {
constructor(datasetUid) {
super(`Error finding dataset for ${datasetUid}. Please check that at least one dataset exists in the view config.`);
this.name = "DatasetNotFoundError";
this.datasetUid = datasetUid;
}
warnInConsole() {
const {
datasetUid
} = this;
if (datasetUid) {
console.warn(`Unable to find dataset for ${datasetUid}`);
} else {
console.warn("No dataset uid specified.");
}
}
};
// node_modules/@hms-dbmi/viv/dist/viv.es.js
import { COORDINATE_SYSTEM as COORDINATE_SYSTEM2, Layer, project32, picking, CompositeLayer, LayerExtension, OrthographicView, Controller, OrbitView } from "@deck.gl/core";
import { Matrix4 } from "math.gl";
import GL from "@luma.gl/constants";
import { TileLayer } from "@deck.gl/geo-layers";
import { Model, Geometry, Texture2D, isWebGL2, Texture3D } from "@luma.gl/core";
import { ProgramManager } from "@luma.gl/engine";
import { hasFeature, FEATURES } from "@luma.gl/webgl";
import { BitmapLayer as BitmapLayer$1, PolygonLayer, LineLayer, TextLayer } from "@deck.gl/layers";
import quickselect from "quickselect";
import { Plane } from "@math.gl/culling";
import React5, { PureComponent, useMemo as useMemo3 } from "react";
import DeckGL from "@deck.gl/react";
import equal from "fast-deep-equal";
import { fromUrl, fromBlob } from "geotiff";
import parser from "fast-xml-parser";
import { KeyError, openGroup, BoundsCheckError, slice, HTTPStore } from "zarr";
var fs$6 = "#define SHADER_NAME xr-layer-fragment-shader\nprecision highp float;precision highp int;precision highp SAMPLER_TYPE;\n#define GLSLIFY 1\nuniform SAMPLER_TYPE channel0;uniform SAMPLER_TYPE channel1;uniform SAMPLER_TYPE channel2;uniform SAMPLER_TYPE channel3;uniform SAMPLER_TYPE channel4;uniform SAMPLER_TYPE channel5;in vec2 vTexCoord;uniform vec2 contrastLimits[6];void main(){float intensity0=float(texture(channel0,vTexCoord).r);DECKGL_PROCESS_INTENSITY(intensity0,contrastLimits[0],0);float intensity1=float(texture(channel1,vTexCoord).r);DECKGL_PROCESS_INTENSITY(intensity1,contrastLimits[1],1);float intensity2=float(texture(channel2,vTexCoord).r);DECKGL_PROCESS_INTENSITY(intensity2,contrastLimits[2],2);float intensity3=float(texture(channel3,vTexCoord).r);DECKGL_PROCESS_INTENSITY(intensity3,contrastLimits[3],3);float intensity4=float(texture(channel4,vTexCoord).r);DECKGL_PROCESS_INTENSITY(intensity4,contrastLimits[4],4);float intensity5=float(texture(channel5,vTexCoord).r);DECKGL_PROCESS_INTENSITY(intensity5,contrastLimits[5],5);DECKGL_MUTATE_COLOR(gl_FragColor,intensity0,intensity1,intensity2,intensity3,intensity4,intensity5,vTexCoord);geometry.uv=vTexCoord;DECKGL_FILTER_COLOR(gl_FragColor,geometry);}";
var vs$1 = "#define GLSLIFY 1\n#define SHADER_NAME xr-layer-vertex-shader\nattribute vec2 texCoords;attribute vec3 positions;attribute vec3 positions64Low;attribute vec3 instancePickingColors;varying vec2 vTexCoord;void main(void){geometry.worldPosition=positions;geometry.uv=texCoords;geometry.pickingColor=instancePickingColors;gl_Position=project_position_to_clipspace(positions,positions64Low,vec3(0.),geometry.position);DECKGL_FILTER_GL_POSITION(gl_Position,geometry);vTexCoord=texCoords;vec4 color=vec4(0.);DECKGL_FILTER_COLOR(color,geometry);}";
var fs$5 = "#define GLSLIFY 1\nfloat apply_contrast_limits(float intensity,vec2 contrastLimits){return max(0.,(intensity-contrastLimits[0])/max(0.0005,(contrastLimits[1]-contrastLimits[0])));}";
var channels$1 = {
name: "channel-intensity-module",
defines: {
SAMPLER_TYPE: "usampler2D",
COLORMAP_FUNCTION: ""
},
fs: fs$5
};
var MAX_COLOR_INTENSITY = 255;
var DEFAULT_COLOR_OFF = [0, 0, 0];
var MAX_CHANNELS = 6;
var DEFAULT_FONT_FAMILY = "-apple-system, 'Helvetica Neue', Arial, sans-serif";
var DTYPE_VALUES = {
Uint8: {
format: GL.R8UI,
dataFormat: GL.RED_INTEGER,
type: GL.UNSIGNED_BYTE,
max: __pow(2, 8) - 1,
sampler: "usampler2D"
},
Uint16: {
format: GL.R16UI,
dataFormat: GL.RED_INTEGER,
type: GL.UNSIGNED_SHORT,
max: __pow(2, 16) - 1,
sampler: "usampler2D"
},
Uint32: {
format: GL.R32UI,
dataFormat: GL.RED_INTEGER,
type: GL.UNSIGNED_INT,
max: __pow(2, 32) - 1,
sampler: "usampler2D"
},
Float32: