view static/js/main.303f671d.chunk.js.map @ 0:6df8d6e42152 draft

planemo upload for repository https://github.com/goeckslab/tools-mti/tree/main/tools/vitessce commit 9b2dc921e692af8045773013d9f87d4d790e2ea1
author goeckslab
date Thu, 08 Sep 2022 17:22:53 +0000
parents
children
line wrap: on
line source

{"version":3,"sources":["utils.js","app/constants.js","api/VitessceConfig.js","demo/utils.js","demo/view-configs/codeluppi.js","demo/view-configs/eng.js","demo/view-configs/wang.js","demo/view-configs/spraggins.js","demo/view-configs/satija.js","demo/view-configs/blin.js","demo/view-configs/ome-ngff-legacy.js","demo/view-configs/hubmap.js","demo/view-configs/coordination-types/embeddingZoom.js","demo/view-configs/coordination-types/embeddingTargetX.js","demo/view-configs/coordination-types/embeddingTargetY.js","demo/view-configs/coordination-types/embeddingCellSetPolygonsVisible.js","demo/configs.js","demo/view-configs/rao.js","demo/view-configs/tenx.js","components/classNames.js","app/Warning.js","components/shared-mui/styles.js","app/state/hooks.js","app/vitessce-grid-layout/layout-utils.js","app/vitessce-grid-layout/VitessceGridLayout.js","loaders/AbstractTwoStepLoader.js","loaders/AbstractLoader.js","loaders/errors/AbstractLoaderError.js","loaders/errors/LoaderValidationError.js","loaders/errors/LoaderNotFoundError.js","loaders/LoaderResult.js","loaders/JsonLoader.js","loaders/MatrixZarrLoader.js","loaders/GenesJsonAsMatrixZarrLoader.js","loaders/ClustersJsonAsMatrixZarrLoader.js","components/sets/constants.js","components/utils.js","components/spatial/constants.js","layers/constants.js","layers/BitmaskLayer.js","layers/bitmask-layer-shaders.js","components/layer-controller/utils.js","components/spatial/utils.js","loaders/RasterJsonLoader.js","loaders/OmeZarrLoader.js","components/sets/utils.js","components/sets/cell-set-utils.js","components/sets/io.js","loaders/CellSetsJsonLoader.js","loaders/anndata-loaders/CellSetsZarrLoader.js","loaders/anndata-loaders/MatrixZarrLoader.js","loaders/anndata-loaders/index.js","loaders/anndata-loaders/CellsZarrLoader.js","loaders/GenomicProfilesZarrLoader.js","loaders/data-sources/ZarrDataSource.js","loaders/data-sources/AnnDataSource.js","loaders/errors/DataSourceFetchError.js","loaders/data-sources/JsonSource.js","loaders/types.js","app/vitessce-grid-utils.js","components/hooks.js","app/VitessceGrid.js","app/state/coordination.js","app/view-config-upgraders.js","app/view-config-versions.js","app/CallbackPublisher.js","components/data-hooks.js","components/LoadingIndicator.js","components/shared-mui/components.js","components/TitleInfo.js","components/description/Description.js","components/description/DescriptionSubscriber.js","components/status/Status.js","components/selectable-table/SelectableTable.js","components/genes/Genes.js","components/genes/GenesSubscriber.js","components/sets/Tree.js","components/sets/HelpTooltip.js","components/sets/Popover.js","components/sets/PopoverMenu.js","assets/menu.svg","components/sets/TreeNode.js","assets/sets/union.svg","assets/sets/intersection.svg","assets/sets/complement.svg","components/sets/SetsManagerButtons.js","components/sets/SetsManager.js","components/sets/CellSetsManagerSubscriber.js","components/interpolate-colors.js","layers/SelectionLayer.js","layers/selection-utils.js","layers/heatmap-constants.js","layers/heatmap-bitmap-layer-shaders.js","layers/HeatmapBitmapLayer.js","layers/PixelatedBitmapLayer.js","layers/HeatmapCompositeTextLayer.js","components/shared-spatial-scatterplot/quadtree.js","assets/tools/near_me.svg","assets/tools/selection_rectangle.svg","assets/tools/selection_lasso.svg","components/shared-spatial-scatterplot/ToolMenu.js","components/shared-spatial-scatterplot/cursor.js","components/shared-spatial-scatterplot/AbstractSpatialOrScatterplot.js","components/shared-spatial-scatterplot/force-collide-rects.js","layer-extensions/ScaledExpressionExtension/shader-module.js","layer-extensions/ScaledExpressionExtension/ScaledExpressionExtension.js","layer-extensions/ScaledExpressionExtension/index.js","layer-extensions/SelectionExtension/shader-module.js","layer-extensions/SelectionExtension/SelectionExtension.js","layer-extensions/SelectionExtension/index.js","components/scatterplot/Scatterplot.js","components/tooltip/styles.js","components/tooltip/Tooltip.js","components/tooltip/Tooltip2D.js","components/tooltip/TooltipContent.js","components/scatterplot/ScatterplotTooltipSubscriber.js","components/shared-plot-options/styles.js","components/shared-plot-options/OptionsContainer.js","components/shared-plot-options/OptionSelect.js","components/shared-plot-options/CellColorEncodingOption.js","components/scatterplot/ScatterplotOptions.js","components/scatterplot/ScatterplotSubscriber.js","components/spatial/Spatial.js","components/spatial/SpatialOptions.js","components/spatial/SpatialTooltipSubscriber.js","components/spatial/SpatialSubscriber.js","components/heatmap/utils.js","Pool.js","components/heatmap/HeatmapWorkerPool.js","components/heatmap/Heatmap.js","components/heatmap/HeatmapTooltipSubscriber.js","components/heatmap/HeatmapOptions.js","components/heatmap/HeatmapSubscriber.js","components/layer-controller/ColorPalette.js","components/layer-controller/ChannelOptions.js","components/layer-controller/constants.js","components/layer-controller/styles.js","components/layer-controller/shared-channel-controls.js","components/layer-controller/RasterChannelController.js","components/layer-controller/BitmaskChannelController.js","components/layer-controller/VectorLayerController.js","components/layer-controller/LayerOptions.js","components/layer-controller/VolumeOptions.js","components/layer-controller/LayerController.js","components/layer-controller/ImageAddButton.js","components/layer-controller/LayerControllerSubscriber.js","components/higlass/HiGlassLazy.js","components/higlass/HiGlassSubscriber.js","components/vega/VegaPlot.js","components/vega/utils.js","components/sets/CellSetSizesPlot.js","components/sets/CellSetSizesPlotSubscriber.js","components/higlass/GenomicProfilesSubscriber.js","components/genes/ExpressionHistogram.js","components/genes/ExpressionHistogramSubscriber.js","components/sets/hooks.js","components/sets/CellSetExpressionPlotOptions.js","components/sets/CellSetExpressionPlot.js","components/sets/CellSetExpressionPlotSubscriber.js","app/component-registry.js","components/status/StatusSubscriber.js","components/shared-spatial-scatterplot/dynamic-opacity.js","app/view-config-utils.js","app/Vitessce.js","app/app.js","demo/index.js","app/api.js","components/heatmap/heatmap.worker.js"],"names":["fromEntries","iterable","reduce","obj","key","val","Object","assign","pluralize","singular","plural","count","capitalize","word","charAt","toUpperCase","slice","getNextScope","prevScopes","nextScope","chars","nextCharIndices","next","r","forEach","charIndex","unshift","increment","i","length","push","join","includes","getSourceFromLoader","loader","level","data","Array","isArray","isRgb","source","shape","dtype","labels","indexOf","Component","DESCRIPTION","STATUS","GENES","CELL_SETS","SCATTERPLOT","SPATIAL","HEATMAP","LAYER_CONTROLLER","CELL_SET_SIZES","GENOMIC_PROFILES","CELL_SET_EXPRESSION","EXPRESSION_HISTOGRAM","FileType","CELLS_JSON","CELL_SETS_JSON","EXPRESSION_MATRIX_ZARR","GENOMIC_PROFILES_ZARR","MOLECULES_JSON","NEIGHBORHOODS_JSON","RASTER_JSON","RASTER_OME_ZARR","CLUSTERS_JSON","GENES_JSON","ANNDATA_CELL_SETS_ZARR","ANNDATA_CELLS_ZARR","ANNDATA_EXPRESSION_MATRIX_ZARR","CoordinationType","DATASET","EMBEDDING_TYPE","EMBEDDING_ZOOM","EMBEDDING_ROTATION","EMBEDDING_TARGET_X","EMBEDDING_TARGET_Y","EMBEDDING_TARGET_Z","EMBEDDING_CELL_SET_POLYGONS_VISIBLE","EMBEDDING_CELL_SET_LABELS_VISIBLE","EMBEDDING_CELL_SET_LABEL_SIZE","EMBEDDING_CELL_RADIUS","EMBEDDING_CELL_RADIUS_MODE","EMBEDDING_CELL_OPACITY","EMBEDDING_CELL_OPACITY_MODE","SPATIAL_ZOOM","SPATIAL_ROTATION","SPATIAL_TARGET_X","SPATIAL_TARGET_Y","SPATIAL_TARGET_Z","SPATIAL_ROTATION_X","SPATIAL_ROTATION_Y","SPATIAL_ROTATION_Z","SPATIAL_ROTATION_ORBIT","SPATIAL_ORBIT_AXIS","SPATIAL_AXIS_FIXED","HEATMAP_ZOOM_X","HEATMAP_ZOOM_Y","HEATMAP_TARGET_X","HEATMAP_TARGET_Y","CELL_FILTER","CELL_HIGHLIGHT","CELL_SET_SELECTION","CELL_SET_HIGHLIGHT","CELL_SET_COLOR","GENE_FILTER","GENE_HIGHLIGHT","GENE_SELECTION","GENE_EXPRESSION_COLORMAP","GENE_EXPRESSION_TRANSFORM","GENE_EXPRESSION_COLORMAP_RANGE","CELL_COLOR_ENCODING","SPATIAL_RASTER_LAYERS","SPATIAL_CELLS_LAYER","SPATIAL_MOLECULES_LAYER","SPATIAL_NEIGHBORHOODS_LAYER","GENOMIC_ZOOM_X","GENOMIC_ZOOM_Y","GENOMIC_TARGET_X","GENOMIC_TARGET_Y","ADDITIONAL_CELL_SETS","MOLECULE_HIGHLIGHT","VitessceConfigDatasetFile","url","dataType","fileType","options","this","file","type","VitessceConfigDataset","uid","name","description","dataset","files","map","f","toJSON","VitessceConfigView","component","coordinationScopes","x","y","w","h","view","args","cScopes","cScope","cType","props","VitessceConfigViewHConcat","views","VitessceConfigViewVConcat","VitessceConfigCoordinationScope","cValue","urlPrefix","makeDatasetNameToJsonFiles","datasetPrefix","getS3Url","notPublic","config","public","undefined","vapi","VitessceConfig","version","datasets","coordinationSpace","layout","initStrategy","prevDatasetUids","d","nextUid","newDataset","addCoordination","newScope","setValue","datasetScope","mapping","datasetMatches","entries","filter","Error","newView","etScope","useCoordination","cTypes","result","keys","scope","cValues","viewConcat","layoutAux","xMin","xMax","yMin","yMax","setXYWH","numViews","c","vc","addDataset","addFile","cObj","cScopeName","cScopeValue","hconcat","vcvhc","vconcat","vcvvc","cm","dt","CELLS","EXPRESSION_MATRIX","MOLECULES","NEIGHBORHOODS","RASTER","ft","ct","linnarssonDataTypes","linnarssonName","linnarssonDescription","linnarssonBase","linnarssonBaseNoMolecules","justScatter","requestInit","method","headers","mode","credentials","cache","redirect","referrer","integrity","embeddingType","A","embeddingZoom","justScatterExpression","justSpatial","spatialZoom","spatialTargetX","spatialTargetY","codeluppi2018","PCA","TSNE","transpose","geneSelection","geneExpressionColormapRange","getCodeluppiViewConfig","driesName","driesDescription","eng2019","UMAP","embeddingCellSetPolygonsVisible","embeddingCellSetLabelsVisible","embeddingCellSetLabelSize","embeddingCellRadius","cellRadius","wang2018","spatialLayers","radius","opacity","visible","stroked","vanderbiltBase","layers","spraggins2020","staticLayout","zoom","target","satijaDescription","satija2020","embeddingTargetX","embeddingTargetY","blin2019","omeNgffLegacy","hubmapIntestineSnAtacSeq","baseUrl","umap","addView","cellSetsManager","genomicProfiles","getConfig","embeddingZoomConfig","v1","v2","linkViews","embeddingTargetXConfig","embeddingTargetYConfig","embeddingCellSetPolygonsVisibleConfig","getEngViewConfig","v4","coordinationTypeConfigs","configs","genomicZoomX","genomicZoomY","genomicTargetX","genomicTargetY","hgViewConfig","autocompleteSource","genomePositionSearchBox","autocompleteServer","autocompleteId","chromInfoServer","chromInfoId","chromInfoPath","tracks","top","height","tilesetUid","server","fontSize","labelPosition","labelLeftMargin","labelRightMargin","labelTopMargin","labelBottomMargin","minHeight","geneAnnotationHeight","geneLabelPosition","geneStrandSpacing","showMousePosition","mousePositionColor","plusStrandColor","minusStrandColor","labelColor","trackBorderWidth","trackBorderColor","color","stroke","fontIsLeftAligned","left","width","minWidth","center","contents","maxZoom","backgroundColor","labelShowResolution","labelShowAssembly","labelTextOpacity","labelBackgroundColor","labelBackgroundOpacity","colorRange","colorbarBackgroundColor","colorbarBackgroundOpacity","colorbarPosition","heatmapValueScaling","showTooltip","extent","zeroValueColor","scaleStartPercent","scaleEndPercent","transforms","value","right","bottom","whole","gallery","moved","static","schemaVersion","images","usePhysicalSizeScaling","renderLayers","profileTrackUidKey","vanderbilt","CARD","PRIMARY_CARD","SECONDARY_CARD","BLACK_CARD","SCROLL_CARD","Warning","title","preformatted","unformatted","theme","className","styles","makeStyles","paper","maxHeight","overflow","container","position","span","textAlign","paddingLeft","paddingRight","muiTheme","dark","createTheme","palette","primary","grey","secondary","primaryBackground","primaryBackgroundHighlight","primaryBackgroundInput","primaryBackgroundDim","primaryBackgroundLight","primaryForeground","primaryForegroundDim","primaryForegroundActive","secondaryBackground","secondaryBackgroundDim","secondaryForeground","MuiButtonBase","disableRipple","light","createContext","ViewConfigProviderLocal","Provider","useViewConfigStoreLocal","useStore","useViewConfigStoreApiLocal","useStoreApi","ViewConfigProvider","useViewConfigStore","useViewConfigStoreApi","AuxiliaryProviderLocal","useAuxiliaryStoreLocal","AuxiliaryProvider","useAuxiliaryStore","createViewConfigStore","create","set","viewConfig","loaders","setViewConfig","setLoaders","setCoordinationValue","parameter","state","removeComponent","newLayout","splice","changeLayout","newComponentProps","newProps","createAuxiliaryStore","auxiliaryStore","useHoverStore","componentHover","setComponentHover","useWarnStore","warning","setWarning","useViewInfoStore","viewInfo","setComponentViewInfo","uuid","useGridSizeStore","resizeCount","incrementResizeCount","parameters","shallow","useMemo","AUXILIARY_COORDINATION_TYPES_MAP","spatialRasterLayers","useAuxiliaryCoordination","mappedCoordinationScopes","newCoordinationScopes","coordinationType","mapCoordinationScopes","mappedParameters","Boolean","flat","mapParameters","useLoaders","useComponentHover","useSetComponentHover","useWarning","useSetWarning","useComponentViewInfo","useCallback","useSetComponentViewInfo","setViewInfoRef","useRef","getState","current","useGridResize","useEmitGridResize","makeGridLayout","colXs","colLayout","colWs","a","id","spec","ResponsiveHeightGridLayout","prevProps","onWindowResize","WidthProvider","Responsive","VitessceGridLayout","layouts","getComponent","padding","margin","draggableHandle","reactGridLayoutProps","rowHeight","onRemoveComponent","onLayoutChangeProp","onLayoutChange","cols","breakpoints","components","positions","def","columns","columnXs","range","columnCount","resolveLayout","gridCols","gridLayouts","gridBreakpoints","gridComponents","maxRows","Math","max","values","xywh","style","layoutChildren","k","v","removeGridComponent","window","innerHeight","containerPadding","nextC","prevC","parseInt","substring","nextProps","isEqual","defaultProps","AbstractTwoStepLoader","dataSource","params","subscriptions","subscriber","token","uuidv4","AbstractLoaderError","message","LoaderValidationError","datasetType","datasetFileType","datasetUrl","reason","console","warn","JSON","stringify","LoaderNotFoundError","LoaderResult","coordinationValues","typeToSchema","cells","cellsSchema","molecules","moleculesSchema","neighborhoods","neighborhoodsSchema","raster","rasterSchema","cellSetsSchema","JsonLoader","schema","then","Promise","reject","validate","valid","resolve","failureReason","Ajv","compile","errors","MatrixZarrLoader","attrs","getJson","store","arr","openArray","path","z","getRaw","all","loadAttrs","loadArr","GenesJsonAsMatrixZarrLoader","genesSchema","catch","payload","rows","normalizedFlatMatrix","flatMap","cellId","geneId","Uint8Array","from","ClustersJsonAsMatrixZarrLoader","clustersSchema","matrix","normalizedMatrix","col","min","floor","tNormalizedMatrix","j","HIERARCHICAL_SCHEMAS","cell","latestVersion","TABULAR_SCHEMAS","cellSetsTabularSchema","cellLayerDefaultProps","updateStatus","setCellHighlight","coordinateSystem","COORDINATE_SYSTEM","CARTESIAN","pickable","autoHighlight","filled","getElevation","onHover","info","object","factors","cellInfoFactors","factor","DEFAULT_DARK_COLOR","DEFAULT_LIGHT_COLOR","getDefaultColor","PALETTE","VIEWER_PALETTE","COLORMAP_OPTIONS","DEFAULT_GL_OPTIONS","webgl2","getNextNumberedNodeName","nodes","prefix","find","n","setCellSelection","cellSelection","additionalCellSets","cellSetColor","setCellSetSelection","setAdditionalCellSets","setCellSetColor","setCellColorEncoding","CELL_SELECTIONS_LEVEL_ZERO_NAME","selectionsLevelZeroNode","tree","nextAdditionalCellSets","datatype","nextName","children","colorIndex","nextPath","mergeCellSets","cellSets","asEsModule","__esModule","default","getStatsForResolution","resolution","depth","depthDownsampled","totalBytes","canLoadResolution","performance","memory","jsHeapSizeLimit","GLOBAL_LABELS","DEFAULT_RASTER_LAYER_PROPS","colormap","domainType","transparentColor","renderingMode","RENDERING_MODES","ADDITIVE","use3d","DEFAULT_MOLECULES_LAYER","DEFAULT_CELLS_LAYER","DEFAULT_NEIGHBORHOODS_LAYER","GLSL_COLORMAPS","padWithDefault","defaultValue","padWidth","newArr","hoveredCell","compare","cellColorData","expressionData","BitmaskLayer","fs","vs","modules","project32","picking","defines","oldProps","changeFlags","setColorTexture","cellTexHeight","cellTexWidth","expressionTex","dataToTexture","setState","gl","context","model","delete","_getModel","getAttributeManager","invalidateAll","colorTex","Texture2D","mipmaps","GL","TEXTURE_MIN_FILTER","NEAREST","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","format","RGB","dataFormat","UNSIGNED_BYTE","opts","uniforms","channelsVisible","colorScaleLo","colorScaleHi","isExpressionMode","textures","setUniforms","hovered","colorTexHeight","colorTexWidth","uColorScaleRange","uIsExpressionMode","draw","isWebGL2On","isWebGL2","Float32Array","R32F","LUMINANCE","RED","FLOAT","XRLayer","getSingleSelectionStats2D","selection","getRaster","selectionStats","getChannelStats","domain","slider","contrastLimits","getSingleSelectionStats3D","lowResSource","sizeZ","raster0","rasterMid","rasterTop","stats0","statsMid","statsTop","layerName","getSingleSelectionStats","getStats","getMultiSelectionStats","selections","stats","domains","stat","sliders","getBoundingCube","physicalSizeScalingMatrix","meta","physicalSizes","size","ratio","Matrix4","scale","identity","getPhysicalSizeScalingMatrix","buildDefaultSelection","globalSelection","globalIndices","dim","getDefaultGlobalSelection","firstNonGlobalDimension","isInterleaved","lastDimSize","initializeLayerChannels","defaultSelection","colors","channel","getMetaWithTransformMatrices","imageMeta","imageLoaders","sources","metadata","transform","translate","some","every","minPhysicalSize","acc","hasZPhyscialSize","sizes","unit","replace","divide","newMeta","toArray","initializeRasterLayersAndChannels","rasterLayers","rasterRenderLayers","nextImageLoaders","nextImageMetaAndLayers","autoImageLayerDefPromises","layer","loaderCreator","globalIndicesOfRenderLayers","imageName","findIndex","image","layerIndex","autoImageLayerDefPromise","channels","isBitmask","index","modelMatrix","autoImageLayerDefs","renderSubBitmaskLayers","tile","bbox","base","bounds","tileSize","channelData","tileId","initLoader","imageData","dimensions","isPyramid","field","metadataUrl","fetch","response","json","zarrMetadata","paths","metaKey","arrMetaKeys","chunks","yChunk","xChunk","log2","ZarrPixelSource","omeTiffOffsetsUrl","res","ok","offsets","loadOmeTiff","Channels","Pixels","Name","RasterLoader","URL","createObjectURL","Blob","urls","imagesWithLoaderCreators","autoImageCache","autoImages","autoImageLayers","imageLayerLoaders","imageLayerMeta","hexToRgb","hex","exec","toLowerCase","OmeZarrLoader","loadOmeZarr","fetchOptions","omero","error","rdefs","t","defaultT","defaultZ","filterSelection","sel","nextSel","start","end","label","callbackOnKeyPress","event","callback","preventDefault","colorArrayToString","rgbArray","tinycolor","g","b","toHexString","colorStringToArray","colorString","colorObj","toRgb","getLevelTooltipText","repeat","isEqualOrPrefix","targetPath","testPath","tryRenamePath","nextTargetPath","pathToKey","nodeToSet","currNode","nodeToHeight","newLevel","childrenHeights","getNodeLength","curr","treeFindNodeByNamePath","currTree","targetNamePath","foundNodes","levelZeroNode","nodeFindNodeByNamePath","node","currLevelIndex","currNodeName","child","nodeTransform","predicate","transformedPaths","currPath","newPath","concat","nodeAppendChild","newChild","treeToUnion","checkedPaths","nodeSets","hEl","nodeToLevelDescendantNamePaths","prevPath","stopEarly","treeExport","treeExportLevelZeroNode","nodePath","cellSetColors","nodeWithColors","nodeTransformAll","newNode","nPath","nodeColor","treeToExport","nodeName","treeInitialize","colorMixWithUncertainty","originalColor","p","mixingColor","treeToSetSizesBySetNames","selectedNamePaths","setColor","setNamePath","nodeSet","filterNode","filterPath","treesConflict","testCellSets","testPaths","hasConflict","getPaths","lzn","initializeCellSetColor","nextCellSetColor","nodeCountPerTreePerLevel","fill","treeIndex","processNode","hierarchyLevel","nodeColorArray","getCellSetPolygons","cellSetSelection","cellSetPolygons","cellPositions","mappings","points","turfFeatureCollection","turfPoint","hullCoords","concaveman","Infinity","centroidCoords","centroid","geometry","coordinates","hull","treeToCellPolygonsBySetNames","tryUpgradeTreeToLatestSchema","itemId","handleImportJSON","importData","parse","handleImportTabular","dsvFormat","row","groupName","setName","obsId","predictionScore","isNil","treeToImport","Set","groupRows","setRows","levelOneNode","handleExportJSON","jsonString","encodeURIComponent","downloadForUser","dataString","fileName","downloadAnchorNode","document","createElement","setAttribute","body","appendChild","click","remove","CellSetsJsonLoader","rawData","upgradedData","newAutoSetSelectionParentName","newAutoSetSelections","newAutoSetColors","dataToCellSetsTree","cellNames","cellSetScores","cellSetsTree","cellSetIds","levelSets","InternMap","classes","has","get","levels","getNextLevelNames","levelSuffixes","l","sort","localeCompare","levelOneNodes","levelOneName","getNode","parentLevelPrefixes","currLevelName","childLevelSuffixes","isLeaf","resultNode","nextLevelNames","nextLevelName","uniqueCellSetIds","clusters","cluster","normalize","concatenateColumnVectors","numCols","numRows","BYTES_PER_ELEMENT","DataView","ArrayBuffer","TypedArray","constructor","buffer","CellSetsZarrLoader","cellSetZarrLocation","loadObsVariables","cellSetScoreZarrLocation","option","scoreName","loadObsIndex","loadCellSetIds","loadCellSetScores","CellsZarrLoader","xy","loadNumeric","poly","coordinationName","loadMappings","loadXy","loadPoly","loadFactors","dims","factorsObj","split","filteredGeneNames","geneFilterZarr","geneFilter","getFilterFn","getFlatArrDecompressed","_","loadVarIndex","filterZarr","loadFilteredGeneNames","geneNames","genes","gene","sparseArrays","_getGeneIndices","indices","_openSparseArrays","indptrArr","indexArr","cellXGeneArr","_getNumCells","numCells","startRowIndex","endRowIndex","isColumnAllZeros","geneData","rowIndices","cellXGeneData","rowIndex","_getNumGenes","numGenes","_loadCSRSparseCellXGene","cellXGene","_sparseMatrix","cellXGeneMatrix","rowStart","rowEnd","colStart","colEnd","matrixGeneFilter","_matrixZattrs","encodingType","_loadCSCSparseCellXGene","_getFilteredGenes","filteredGenes","numGenesFiltered","cellXGeneMatrixFiltered","loadGeneSelection","shouldNormalize","_loadCSCGeneSelection","_loadCSRGeneSelection","loadCellXGene","matrixGeneFilterZarr","GenomicProfilesZarrLoader","ZarrDataSource","HTTPStore","supportedMethods","getItem","buf","text","TextDecoder","decode","KeyError","readFloat32FromUint8","bytes","Int32Array","parseVlenUtf8","decoder","dataEnd","output","AnnDataSource","obsPromises","Map","obsPaths","obsPath","getObsCol","obsCol","obsPromise","_loadObsVariable","err","obs","categories","categoriesValues","obsArr","obsValues","mappedObsValues","String","parseAndMergeTextBytes","dbytes","mergeBytes","tmp","byteLength","numRequests","ceil","requests","item","keyPrefix","compressor","filters","obsIndex","_index","varIndex","DataSourceFetchError","JsonSource","_data","fileTypeToLoaderAndSource","RasterJsonLoader","AnnDataLoaders","createLoaders","configDescription","dataSources","datasetLoaders","DataSourceClass","LoaderClass","fileId","getWindowDimensions","innerWidth","useVitessceContainer","ref","closest","useGridItemSize","containerRef","useState","setHeight","setWidth","useEffect","onResizeDebounced","debounce","trailing","addEventListener","removeEventListener","containerRect","getBoundingClientRect","useDeckCanvasSize","deckRef","canvasRect","deck","canvas","useReady","supportedItems","items","waiting","setWaiting","setItemIsReady","readyItem","waitingItems","nextWaitingItems","log","setItemIsNotReady","notReadyItem","resetReadyItems","useUrls","setUrls","prev","useClosestVitessceContainerSize","componentHeight","clientHeight","componentWidth","clientWidth","useExpressionValueGetter","cellIdMap","entry","cellIndex","VitessceGrid","initialRowHeight","containerHeight","setContainerHeight","setRowHeight","bottomY","len","getNumRows","newRowHeight","getRowHeight","useRowHeight","onResize","viewConfigStoreApi","useSetViewConfig","changeLayoutPostMount","onResizeStop","DEFAULT_COORDINATION_VALUES","AUTO_INDEPENDENT_COORDINATION_TYPES","COMPONENT_COORDINATION_TYPES","upgradeReplaceViewProp","prevZScopes","prevTXScopes","prevTYScopes","nextZScope","nextTXScope","nextTYScope","targetX","targetY","SCHEMA_HANDLERS","configSchema0_1_0","datasetUid","componentDef","newComponentDef","newScopeValues","newDatasetUid","addSchema","configSchema1_0_0","replaceLayerType","layerType","isRaster","typedLayers","newLayer","newComponent","replaceCoordinationScope","configSchema1_0_1","globalDisable3d","newConfig","cloneDeep","configSchema1_0_2","disableChannelsIfRgbDetected","configSchema1_0_3","configSchema1_0_4","configSchema1_0_5","configSchema1_0_6","CallbackPublisher","onWarn","onConfigChange","onLoaderChange","validateOnConfigChange","subscribe","e","validateViewConfig","warnInConsole","initCoordinationSpace","setters","initialValues","setterName","setterFunc","initialValue","equal","useCellsData","addUrl","isRequired","coordinationSetters","initialCoordinationValues","setCells","cellsCount","setCellsCount","load","spatialCellsLayer","useCellSetsData","setCellSets","useExpressionMatrixData","expressionMatrix","setExpressionMatrix","useGeneSelection","setGeneData","expressionDataForSelection","geneIndex","useExpressionAttrs","setAttrs","useMoleculesData","setMolecules","moleculesCount","setMoleculesCount","locationsCount","setLocationsCount","spatialMoleculesLayer","useRasterData","setRaster","setImageLayerLoaders","setImageLayerMeta","nextImageMeta","LoadingIndicator","CircularProgress","MuiSpan","PopperMenu","buttonIcon","open","setOpen","buttonClassName","placement","anchorRef","handleClose","getTooltipContainer","IconButton","aria-describedby","onClick","Popper","anchorEl","onClose","transition","TransitionProps","ClickAwayListener","onClickAway","Fade","timeout","Paper","elevation","MenuList","useStyles","iconButton","border","marginLeft","background","borderRadius","marginRight","verticalAlign","downloadLink","SettingsIconWithArrow","PlotOptions","CloudDownloadIconWithArrow","DownloadOptions","MenuItem","dense","Link","underline","href","rel","ClosePaneButton","TitleInfo","isScroll","isSpatial","isReady","childClassName","Description","metadataRecord","DESCRIPTION_DATA_TYPES","Status","messages","SelectableTable","hasColorEncoding","onChange","idKey","valueKey","allowMultiple","allowUncheck","showTableHead","showTableInputs","testHeight","testWidth","selectedRows","setSelectedRows","onSelectRow","checked","union","difference","handleInputChange","getDataFromIds","ids","isSelected","initialSelectedRows","selectedRowData","inputUuid","hiddenInputsClass","rowRenderer","role","htmlFor","column","headerRowRenderer","gridStyle","outline","rowCount","headerHeight","rowGetter","Genes","geneList","setGeneSelection","searchTerm","setSearchTerm","searchResults","setSearchResults","results","placeholder","GENES_DATA_TYPES","Tree","React","forwardRef","prefixCls","showIcon","blockNode","checkable","itemHeight","classNames","virtual","HelpTooltip","content","overlayClassName","spanRef","overlay","Popover","PopoverMenuListButton","subtitle","handler","handlerKey","confirm","isConfirming","setIsConfirming","handleOrRequireConfirm","titleWithConfirm","onKeyPress","PopoverMenuList","menuConfig","defaultPalette","disableAlpha","triangle","onChangeComplete","rgb","PopoverMenu","setVisible","onVisibleChange","_extends","arguments","prototype","hasOwnProperty","call","apply","_objectWithoutProperties","excluded","sourceKeys","_objectWithoutPropertiesLoose","getOwnPropertySymbols","sourceSymbolKeys","propertyIsEnumerable","trigger","mouseEnterDelay","mouseLeaveDelay","SvgMenu","_ref","svgRef","titleId","viewBox","ForwardRef","makeNodeViewMenuConfig","onCheckNode","onNodeRemove","onNodeSetIsEditing","onExportLevelZeroNodeJSON","onExportLevelZeroNodeTabular","onExportSetJSON","editable","exportable","NamedSetNodeStatic","tooltipText","nodeKey","checkbox","isChecking","onNodeSetColor","onNodeView","expanded","onCheckLevel","checkedLevelPath","checkedLevelIndex","disableTooltip","shouldCheckNextLevel","nextLevelToCheck","niceSize","Intl","NumberFormat","tooltipProps","popoverMenuConfig","NamedSetNodeEditing","onNodeSetName","onNodeCheckNewName","currentTitle","setCurrentTitle","hasConflicts","trySetName","autoFocus","onFocus","select","NamedSetNode","isEditing","isCurrentSet","LevelsButtons","onCheck","isChecked","clsx","SwitcherIcon","isOpen","hexColor","focusable","data-icon","aria-hidden","TreeNode","renderSelector","onDragStartProp","onDragStart","rcTree","prefixClass","draggable","wrapClass","isDraggable","setSelectHandle","getNodeState","aria-grabbed","renderCheckbox","renderLevels","renderSwitcher","onNodeExpand","onNodeExpandWrapper","switcherClass","tabIndex","loading","dragOver","dragOverGapTop","dragOverGapBottom","selected","halfChecked","onDragEndProp","onDragEnd","expandable","otherProps","filterTreeNode","disabled","isDisabled","dataAndAriaAttributeProps","getDataAndAria","onDragEnter","onDragOver","onDragLeave","onDrop","bind","renderChildren","RcTreeNode","SvgUnion","strokeWidth","strokeMiterlimit","strokeDasharray","strokeOpacity","SvgIntersection","mask","SvgComplement","PlusButton","onError","onImportTree","onCreateLevelZeroNode","importable","onImport","importHandler","mimeType","uploadInputNode","File","FileReader","FileList","reader","readAsText","SetOperationButtons","onUnion","onIntersection","onComplement","operatable","hasCheckedSetsToUnion","hasCheckedSetsToIntersect","hasCheckedSetsToComplement","processSets","sets","SetsManager","additionalSets","checkedLevel","levelSelection","setSelection","setExpansion","onExpandNode","onDropNode","isDragging","setIsDragging","isEditingNodeName","setIsEditingNodeName","processedSets","processedAdditionalSets","additionalSetKeys","getAllKeys","allSetSelectionKeys","allSetExpansionKeys","setSelectionKeys","setExpansionKeys","additionalSetSelectionKeys","additionalSetExpansionKeys","renderTreeNodes","readOnly","nodeToRenderProps","levelZeroPath","levelIndex","checkedKeys","expandedKeys","autoExpandParent","onExpand","dropKey","eventKey","dragKey","dragNode","dropToGap","dropPosition","CELL_SETS_DATA_TYPES","spline","v0","v3","t1","t2","t3","innerBasis","interpolatePlasma","interpolateSequentialMulti","getCellColors","cellColorEncoding","expressionDataAttrs","geneExpColormap","cellColor","cellColorsArray","prob","treeToCellColorsBySetNames","ClickableDrawRectangleMode","onEdit","editType","DrawRectangleMode","ClickableDrawPolygonByDraggingMode","DrawPolygonByDraggingMode","MODE_MAP","SELECTION_TYPE","RECTANGLE","POLYGON","selectionType","layerIds","onSelect","EMPTY_DATA","features","PASS_THROUGH_PROPS","SelectionLayer","getCellCoords","cellsQuadTree","flippedCoordinates","flipY","selectedPolygon","turfPolygon","pickingInfos","visit","x0","y0","x1","y1","nodePoints","nodePolygon","nodePolygonContainsSelectedPolygon","booleanContains","nodePolygonWithinSelectedPolygon","booleanWithin","nodePolygonOverlapsSelectedPolgyon","booleanOverlap","booleanPointInPolygon","ViewMode","inheritedProps","EditableGeoJsonLayer","getSubLayerProps","modeConfig","dragToDraw","selectedFeatureIndexes","updatedData","_selectPolygonObjects","_subLayerProps","guides","pointType","ScatterplotLayer","radiusScale","getLineWidth","radiusMinPixels","radiusMaxPixels","getRadius","CompositeLayer","getBaseLayerId","layerId","getSelectionLayers","tool","updateCellsSelection","cellBaseLayerId","editHandlePointRadius","cellIds","cellObj","getTentativeFillColor","getTentativeLineColor","getTentativeLineDashArray","lineWidthMinPixels","lineWidthMaxPixels","getEditHandlePointColor","getEditHandlePointRadius","editHandlePointRadiusScale","editHandlePointRadiusMinPixels","editHandlePointRadiusMaxPixels","THEME_TO_TEXT_COLOR","AXIS_FONT_FAMILY","PIXELATED_TEXTURE_PARAMETERS","fragmentShader","async","aggSizeX","aggSizeY","HeatmapBitmapLayer","shaders","extensions","extension","_mergeShaders","getShaders","fragmentShaderWithColormap","_getShaders","loadTexture","bitmapTexture","uBitmapTexture","uTextureSize","uAggSize","BitmapLayer","desaturate","tintColor","PixelatedBitmapLayer","textureParameters","HeatmapCompositeTextLayer","axisTopLabelData","matrixLeft","matrixWidth","viewWidth","axisTopTitle","showAxisTopLabels","cellWidth","axisLabelTop","axisOffsetTop","scaleFactor","TextLayer","getText","getPosition","getTextAnchor","getColor","getSize","getAngle","fontFamily","updateTriggers","axisLeftLabelData","matrixTop","matrixHeight","viewHeight","axisLeftTitle","showAxisLeftLabels","cellHeight","axisLabelLeft","axisOffsetLeft","_renderAxisTopLayers","_renderAxisLeftLayers","createCellsQuadTree","cellsEntries","quadtree","addAll","SvgNearMe","SvgSelectionRectangle","SvgSelectionLasso","alt","isActive","inactive","active","ToolMenu","setActiveTool","activeTool","visibleTools","pan","selectRectangle","selectLasso","getCursorWithTool","getCursor","interactionState","AbstractSpatialOrScatterplot","viewport","onViewStateChange","onInitializeViewInfo","onWebGLInitialized","onToolChange","nextViewState","viewState","setViewState","spatialAxisFixed","onToolChangeProp","coordinate","sourceLayer","cellHighlight","hasBitmask","layerZoomScale","round","dataCoords","coords","Number","updateViewInfo","project","positionX","positionY","layerProps","getLayers","showCellSelectionTools","cellsLayer","showPanTool","useDevicePixels","OrbitView","controller","orbitAxis","OrthographicView","glOptions","dragPan","PureComponent","constant","jiggle","random","inject","getExpressionValue","getSelectionState","ScaledExpressionExtension","module","models","topModel","sideModel","_getModels","getCurrentLayer","isComposite","attributeManager","add","expressionValue","accessor","divisor","attributes","settings","m","LayerExtension","extensionName","SelectionExtension","instanced","makeDefaultGetCellPosition","cellEntry","available","s","mappedCell","makeDefaultGetCellCoords","Scatterplot","cellSetsForceSimulation","masses","strength","iterations","xCenter","vx","yCenter","vy","prepare","quad","force","nodeSize","nodeMass","xi","yi","visitAfter","xSize","ySize","xd","abs","yd","sqrt","iterate","initialize","forceCollideRects","cellSetsLabelPrevZoom","cellSetsLayers","onUpdateCellsData","onUpdateCellsLayer","onUpdateCellSetsLayers","getCellPosition","cellOpacity","cellFilter","getCellIsSelected","cellColors","getCellColor","makeDefaultGetCellColors","onCellClick","geneExpressionColormap","filteredCellsEntries","radiusUnits","lineWidthUnits","getFillColor","getLineColor","cellSetPolygonsVisible","cellSetLabelsVisible","cellSetLabelSize","PolygonLayer","wireframe","getPolygon","collisionForce","forceSimulation","tick","getAlignmentBaseline","fontWeight","createSelectionLayers","createCellsLayer","onlyViewStateChange","createCellSetsLayers","viewInfoDidUpdate","shallowDiff","propName","forceUpdate","ScatterplotWrapper","tooltipAnchor","pointerEvents","userSelect","tooltipContent","borderCollapse","Tooltip","parentWidth","parentHeight","placementX","setPlacementX","placementY","setPlacementY","flipX","Tooltip2D","parentUuid","sourceUuid","isTooltipVisible","crosshairWidth","TooltipContent","ScatterplotTooltipSubscriber","getCellInfo","cellInfo","box","boxSizing","sliderValueLabel","tableContainer","overflowX","labelCell","inputCell","selectRoot","OptionsContainer","Box","TableContainer","Table","table","TableBody","OptionSelect","classesProp","Select","native","disableUnderline","root","CellColorEncodingOption","observationsLabel","observationsLabelNice","TableRow","TableCell","inputProps","ScatterplotOptions","setCellRadius","cellRadiusMode","setCellRadiusMode","setCellOpacity","cellOpacityMode","setCellOpacityMode","setCellSetLabelsVisible","setCellSetLabelSize","setCellSetPolygonsVisible","setGeneExpressionColormap","setGeneExpressionColormapRange","handleColormapRangeChange","handleColormapRangeChangeDebounced","Checkbox","Slider","valueLabel","aria-labelledby","valueLabelDisplay","step","cmap","SCATTERPLOT_DATA_TYPES","defaultGetCellCoords","Spatial","moleculesEntries","moleculesLayer","neighborhoodsLayer","imageLayers","layerLoaderSelections","randomColorData","expression","onUpdateMoleculesData","onUpdateMoleculesLayer","onUpdateNeighborhoodsData","onUpdateNeighborhoodsLayer","onUpdateImages","layerDef","cellSelectionSet","makeDefaultGetCellIsSelected","getCellPolygon","makeDefaultGetCellPolygon","lineWidthScale","setMoleculeHighlight","getMoleculeColor","getMoleculePosition","getNeighborhoodPolygon","neighborhoodsEntry","neighborhoodsEntries","ScaleBarLayer","rawLayerDef","nextLoaderSelection","prevLoaderSelection","useTransparentColor","xSlice","ySlice","zSlice","visibilities","MultiscaleImageLayer","renderSubLayers","excludeBackground","onViewportLoad","VolumeLayer","ImageLayer","getLayerLoaderTuple","Layer","layerLoader","AdditiveColormapExtension","ColorPaletteExtension","rasterLayersCallbacks","use3dIndex","createImageLayer","createScaleBarLayer","molecule","createMoleculesLayer","createNeighborhoodsLayer","createImageLayers","onUpdateCellColors","onUpdateExpressionData","SpatialWrapper","useToggleStyles","createStyles","cameraLabel","button","ToggleFixedAxisButton","setSpatialAxisFixed","SpatialOptions","canShowExpressionOptions","canShowColorEncodingOption","canShow3DOptions","SpatialTooltipSubscriber","SPATIAL_DATA_TYPES","layerFilter","startsWith","defaultPoolSize","navigator","hardwareConcurrency","HeatmapPool","Worker","waitForWorker","currentWorker","onmessage","finishTask","onerror","postMessage","workers","idleWorkers","waitQueue","idleWorker","pop","waiter","promise","terminate","Heatmap","componentName","rawViewState","colormapRange","clearPleaseWait","hoverInfo","setGeneHighlight","createDefaultUpdateGenesHover","createDefaultUpdateViewInfo","setIsRendering","variablesTitle","observationsTitle","minZoom","workerPool","HeatmapWorkerPool","tilesRef","dataRef","axisLeftLabels","setAxisLeftLabels","axisTopLabels","setAxisTopLabels","useReducer","tileIteration","incTileIteration","backlog","setBacklog","newBuffer","copyUint8Array","newCellOrdering","oldCellOrdering","cellLabelMaxLength","geneLabelMaxLength","clamp","getAxisSizes","offsetTop","offsetLeft","matrixRight","matrixBottom","xTiles","yTiles","tileWidth","tileHeight","colI","rowI","zoomedMouseY","zoomedMouseX","minY","minInViewY","maxInViewY","globalRowY","minX","minInViewX","maxInViewX","globalRowX","heatmapToMousePosition","nextZoom","nextScaleFactor","minTargetX","maxTargetX","minTargetY","maxTargetY","nextTarget","promises","process","tileI","tileJ","cellOrdering","tiles","currWork","currIndex","heatmapLayers","getLayer","textLayers","cellColorsTiles","offset","colorBarTileWidthPx","colorBarTileHeightPx","tileData","Uint8ClampedArray","TILE_SIZE","tileY","rValue","gValue","bValue","ImageData","cellColorsLayers","COLOR_BAR_SIZE","offsetCenter","mouseX","mouseY","viewMouseX","viewMouseY","mouseToHeatmapPosition","obsI","varI","varId","HeatmapTooltipSubscriber","getGeneInfo","geneHighlight","cellCoord","geneInfo","geneCoord","HeatmapOptions","HEATMAP_DATA_TYPES","display","justifyContent","alignItems","flexWrap","icon","action","ColorPalette","handleChange","aria-label","menuButton","ChannelOptions","handlePropertyChange","handleChannelRemove","handleIQRUpdate","disableGutters","DOMAINS","needMin","DTYPE_VALUES","getDomains","useSelectStyles","sharedControllerStyles","withStyles","popper","zIndex","flexDirection","useControllerSectionStyles","StyledAccordionDetails","AccordionDetails","StyledAccordionSummary","marginBottom","spacing","expandIcon","AccordionSummary","StyledInputLabel","InputLabel","OverflowEllipsisGrid","whiteSpace","textOverflow","Grid","StyledSelectionSlider","marginTop","markActive","ChannelSelectionDropdown","channelOptions","selectionIndex","opt","ChannelVisibilityCheckbox","toggle","abbreviateNumber","maxNaiveDigits","isInteger","naive","maximumSignificantDigits","useGrouping","toExponential","ChannelSlider","handleChangeDebounced","valueLabelFormat","getAriaLabel","orientation","RasterChannelController","visibility","channelId","newDomainType","dimName","colormapOn","isLoading","newUse3d","setDomain","setDomainType","setUse3d","rgbColor","on","toRgbUIString","mounted","hasDomainChanged","has3dChanged","hasSelectionChanged","newDomain","direction","xs","BitmaskChannelController","disableOptions","justify","VectorLayerController","handleLayerChange","isOn","Typography","handleCheckBoxChange","handleSliderChange","DOMAIN_OPTIONS","VolumeDropdown","loaderWithMeta","handleMultiPropertyChange","currResolution","disable3d","setRasterLayerCallback","setAreAllChannelsLoading","spatialHeight","spatialWidth","shouldUse3D","propertiesChanged","ch","defaultViewState","getDefaultInitialViewState","rotationX","rotationOrbit","newChannels","hasZStack","decimals","dm","parseFloat","pow","toFixed","formatBytes","ColormapSelect","inputId","TransparentColorCheckbox","float","OpacitySlider","SliderDomainSelector","GlobalSelectionSlider","possibleValues","newValue","onChangeCommitted","marks","LayerOption","LayerOptions","handleColormapChange","handleOpacityChange","handleTransparentColorChange","globalControlLabels","globalLabelValues","handleGlobalChannelsSelectionChange","handleDomainChange","shouldShowTransparentColor","shouldShowDomain","shouldShowColormap","hasDimensionsAndChannels","hasViewableResolutions","useSlicerStyles","enabled","Slicer","handleSlicerSetting","sliceValuesAndSetSliceFunctions","xSliceNew","ySliceNew","zSliceNew","Slicers","setVal","renderingOptions","RenderingModeSelect","handleRenderingModeChange","FormControl","fullWidth","ReCenterButton","Button","VolumeOptions","TabPanel","other","hidden","getDomainsAndSliders","buttonStyles","borderStyle","LayerController","handleLayerRemove","ChannelController","setAreLayerChannelsLoading","areLayerChannelsLoading","shouldShowRemoveLayerButton","channelRef","firstSelection","tab","setTab","isExpanded","setIsExpanded","o","setGlobalLabelValues","setOpacity","setChannels","setChannelsAndDomainType","setChannel","addChannel","newAreLayerChannelsLoading","handleChannelAdd","newChannelId","areLayerChannelsLoadingCallback","newChannelsWithSelection","channelControllers","channelLabel","setIsLoading","loaderData","q1","q3","property","update","removeChannel","controllerSectionClasses","Visibility","VisibilityIcon","VisibilityOffIcon","useVolumeTabs","FullController","MAX_CHANNELS","variant","startIcon","Accordion","enter","aria-controls","stopPropagation","Tabs","newTab","Tab","addButton","ImageAddIcon","ImageAddButton","imageOptions","handleImageAdd","imgData","handleAdd","LAYER_CONTROLLER_DATA_TYPES","LayerControllerMemoized","memo","setMoleculesLayer","canShowCellVecmask","setCellsLayer","setRasterLayersCallbacks","areLoadingRasterChannnels","setAreLoadingRasterChannnels","handleRasterLayerChange","handleRasterLayerRemove","layerIs3DIndex","setZoom","setTargetX","setTargetY","setTargetZ","setRotationX","setRotationOrbit","spatialLayout","enableLayerButtonsWithOneLayer","shouldShowImageLayerButton","layerMeta","cb","newRasterLayersCallbacks","newZoom","newRotationX","newRotationOrbit","newAreLoadingRasterChannnels","LayerControllerSubscriber","layerController","setRasterLayers","setSpatialRasterLayers","setSpatialCellsLayer","setSpatialMoleculesLayer","setSpatialTargetX","setSpatialTargetY","setSpatialTargetZ","setSpatialRotationX","setSpatialRotationOrbit","setSpatialZoom","scopes","useComponentLayout","layerControllerRef","windowDimensions","setWindowDimensions","useWindowDimensions","windowHeight","windowWidth","newLayers","PIXI_BUNDLE_VERSION","packageJson","dependencies","HIGLASS_BUNDLE_VERSION","higlass","PIXI_BUNDLE_URL","HIGLASS_BUNDLE_URL","dynamicImportPolyfill","register","dataFetcher","ZarrMultivecDataFetcher","pluginType","HiGlassComponent","lazy","ReactDOM","handleImportError","__import__","hglib","HiGlassLazy","hgViewConfigProp","hgOptionsProp","hgOptions","genomeSize","setGenomicZoomX","setGenomicZoomY","setGenomicTargetX","setGenomicTargetY","hgInstance","setHgInstance","isActiveRef","centerX","genomesPerUnitX","unitX","initialXDomain","centerY","genomesPerUnitY","unitY","initialYDomain","zoomFixed","trackSourceServers","exportViewUrl","zoomLocks","locksByViewUid","locksDict","locationLocks","valueScaleLocks","handleMouseEnter","handleMouseLeave","api","viewConfigString","xDomain","yDomain","nextGenomicZoomX","nextGenomicZoomY","nextGenomicTargetX","nextGenomicTargetY","off","fallback","bounded","pixelPreciseMarginPadding","containerPaddingX","containerPaddingY","sizeMode","HIGLASS_DATA_TYPES","DATASET_NAME","isVega","$schema","VegaPlot","partialSpec","signalListeners","vegaComponent","tooltip","Handler","renderer","VEGA_THEMES","axis","domainColor","gridColor","tickColor","CellSetSizesPlot","keyLength","keyName","mark","encoding","labelExpr","legend","CELL_SET_SIZES_DATA_TYPES","GENOMIC_PROFILES_DATA_TYPES","REFERENCE_TILESETS","hg38","chromosomes","hg19","mm9","mm10","ExpressionHistogram","bin","maxbins","aggregate","EXPRESSION_HISTOGRAM_DATA_TYPES","useExpressionByCellSet","useGeneExpressionTransform","mergedCellSets","cellObjects","cellsArray","treeToObjectsBySetNames","firstGeneSelected","exprMax","cellIndices","normValue","transformedValue","expressionArr","expressionMax","CellSetExpressionPlotOptions","toggleGeneExpressionTransform","CellSetExpressionPlot","domainMax","maxCharactersForLabel","autoMarginBottom","colorScale","plotWidth","plotHeight","bandWidth","rectColor","axisBand","bandPosition","tickExtra","tickOffset","signals","groupby","bandwidth","fields","ops","as","scales","signal","reverse","axes","orient","zindex","tickCount","labelAngle","labelAlign","facet","encode","xc","band","expr","parent","y2","CELL_SET_EXPRESSION_DATA_TYPES","registry","descriptionOverride","setDescription","useDescription","status","moleculeHighlight","variablesLabelOverride","variablesLabel","variablesPluralLabelOverride","variablesPluralLabel","setGeneFilter","resetUrls","newSelection","cellSetExpansion","setCellSetExpansion","upgradedCellSets","allCellIds","setCellSetColorEncoding","levelNodePaths","treeToExpectedCheckedLevel","targetKey","dropPath","dropNode","dropNodeIsLevelZero","dragPath","dropParentNode","dropParentPath","dropNodeCurrIndex","dragNodeName","newDragPath","insertIndex","newLevelZero","addChildFunction","checkPathFunction","newChildren","nodeInsertChild","newColors","newCellSetColor","levelZeroName","newCellSetSelection","prevNodeColor","nextNamePath","renameNode","nextCellSetSelection","nextCellSetExpansion","setsToView","viewNode","expandedPath","importAutoSetColors","exportData","csvString","json2csv","delimiter","handleExportTabular","setToExport","treeExportSet","treeToIntersection","primaryUnion","el","treeToComplement","observationsLabelOverride","observationsPluralLabelOverride","observationsPluralLabel","titleOverride","averageFillDensity","scatterplot","targetZ","embeddingTargetZ","cellRadiusFixed","embeddingCellRadiusMode","cellOpacityFixed","embeddingCellOpacity","embeddingCellOpacityMode","setEmbeddingZoom","setEmbeddingTargetX","setEmbeddingTargetY","setEmbeddingTargetZ","setCellFilter","setEmbeddingCellSetPolygonsVisible","setEmbeddingCellSetLabelsVisible","setEmbeddingCellSetLabelSize","setCellRadiusFixed","setEmbeddingCellRadius","setEmbeddingCellRadiusMode","setCellOpacityFixed","setEmbeddingCellOpacity","setEmbeddingCellOpacityMode","dynamicCellRadius","setDynamicCellRadius","dynamicCellOpacity","setDynamicCellOpacity","setCellSelectionProp","cellSetPolygonCache","setCellSetPolygonCache","newCellSetPolygons","cacheGet","cellValues","cellCoordinates","xE","yE","xRange","yRange","xExtent","yExtent","pointSizeDevicePixels","devicePixelRatio","pointScreenSizeMin","xAxisRange","yAxisRange","diagonalScreenSize","deviceSize","getPointSizeDevicePixels","nextCellOpacityScale","avgFillDensity","N","makeViewport","getBounds","maxX","X","Y","X0","Y0","W","H","rho","log10","alpha","getPointOpacity","newTargetX","newTargetY","subobservationsLabelOverride","subobservationsLabel","subobservationsPluralLabelOverride","subobservationsPluralLabel","spatial","spatialTargetZ","spatialRotationX","rotationY","spatialRotationY","rotationZ","spatialRotationZ","spatialRotationOrbit","spatialOrbitAxis","spatialNeighborhoodsLayer","setOrbitAxis","setSpatialOrbitAxis","setNeighborhoodsLayer","setSpatialNeighborhoodsLayer","setNeighborhoods","useNeighborhoodsData","canPassInCellsLayer","useRaster","initialTargetX","initialTargetY","initialTargetZ","initialZoom","zoomBackoff","viewSize","newViewStateZoom","getViewExtentFromPolygonExtents","extents","getInitialSpatialTargets","shiftedExpressionDataForBitmask","maxId","observationsCount","subobservationsCount","parts","part","shortNumber","makeSpatialSubtitle","hasExpressionData","hasCellsData","newOrbitAxis","heatmap","zoomX","heatmapZoomX","heatmapTargetX","heatmapTargetY","setZoomX","setHeatmapZoomX","setZoomY","setHeatmapZoomY","setHeatmapTargetX","setHeatmapTargetY","isRendering","genesCount","selectedCount","setColormapRange","cellSetSizes","profileTrackNameKey","higlassServer","assembly","genomicProfilesAttrs","setGenomicProfilesAttrs","useGenomicProfilesData","foregroundColor","dimColor","referenceTracks","referenceTracksHeightSum","sum","profileTrackHeight","row_infos","profileTracks","rowInfo","trackUid","isPath","trackName","setInSelection","trackUidString","track","barFillColor","expressionHistogram","subarray","cellSetExpression","geneExpressionTransform","setGeneExpressionTransform","setArr","getExistingScopesForCoordinationType","spaceScopes","componentScopes","initializeAuto","scopeValue","newScopes","scopeName","coordinateComponentsIndependent","coordinateComponentsTogether","generateClassName","createGenerateClassName","disableGlobal","Vitessce","oldConfig","fromVersion","upgradeFunction","validateFunction","nextConfig","groupCollapsed","groupEnd","upgradeAndValidate","upgradedConfig","configOrWarning","success","StylesProvider","ThemeProvider","createStore","AwaitResponse","responseRef","preformattedDetails","statusText","redirected","react","render","getElementById","renderComponent","datasetId","URLSearchParams","location","search","responsePromise","replaceAll","checkResponse","createApp","exports","require"],"mappings":"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AAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,GAAI,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,EAAG,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,KAAM,CAAC,IAAK,GAAI,IAAK,CAAC,IAAK,GAAI,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,CAAC,IAAK,IAAK,IAAK,C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","file":"static/js/main.303f671d.chunk.js","sourcesContent":["/* eslint-disable no-plusplus */\n\n// Adapted from https://github.com/feross/fromentries/blob/29b52a850bb3a47c390937631c2638edf3443942/index.js\nexport function fromEntries(iterable) {\n  return [...iterable]\n    .reduce((obj, { 0: key, 1: val }) => Object.assign(obj, { [key]: val }), {});\n}\n\n/**\n * Select between a singular and plural version of a word,\n * based on an item count.\n * @param {string} singular The singular version of the word.\n * @param {string} plural The plural version of the word.\n * @param {number} count The number of items.\n * @returns {string} Singular if count is one, else plural.\n */\nexport function pluralize(singular, plural, count) {\n  return (count === 1 ? singular : plural);\n}\n\n/**\n * Capitalize a the first letter of a string.\n * @param {string} word A string to capitalize.\n * @returns {string} The word parameter with the first letter capitalized.\n */\nexport function capitalize(word) {\n  return word.charAt(0).toUpperCase() + word.slice(1);\n}\n\n/**\n * Generate a new scope name which does not\n * conflict / overlap with a previous scope name.\n * Really these just need to be unique within the coordination object.\n * So in theory they could be String(Math.random()) or uuidv4() or something.\n * However it may be good to make them more human-readable and memorable\n * since eventually we will want to expose a UI to update the coordination.\n * @param {string[]} prevScopes Previous scope names.\n * @returns {string} The new scope name.\n */\nexport function getNextScope(prevScopes) {\n  // Keep an ordered list of valid characters.\n  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  // Store the value of the next character for each position\n  // in the new string.\n  // For example, [0] -> \"A\", [1] -> \"B\", [0, 1] -> \"AB\"\n  const nextCharIndices = [0];\n\n  // Generate a new scope name,\n  // potentially conflicting with an existing name.\n  // Reference: https://stackoverflow.com/a/12504061\n  function next() {\n    const r = [];\n    nextCharIndices.forEach((charIndex) => {\n      r.unshift(chars[charIndex]);\n    });\n    let increment = true;\n    for (let i = 0; i < nextCharIndices.length; i++) {\n      const val = ++nextCharIndices[i];\n      if (val >= chars.length) {\n        nextCharIndices[i] = 0;\n      } else {\n        increment = false;\n        break;\n      }\n    }\n    if (increment) {\n      nextCharIndices.push(0);\n    }\n    return r.join('');\n  }\n\n  let nextScope;\n  do {\n    nextScope = next();\n  } while (prevScopes.includes(nextScope));\n  return nextScope;\n}\n\n/**\n * Get a representative PixelSource from a loader object returned from\n * the Vitessce imaging loaders\n * @param {object} loader { data: (PixelSource[]|PixelSource), metadata, channels } object\n * @param {number=} level Level of the multiscale loader from which to get a PixelSource\n * @returns {object} PixelSource object\n */\nexport function getSourceFromLoader(loader, level) {\n  const { data } = loader;\n  const source = Array.isArray(data) ? data[(level || data.length - 1)] : data;\n  return source;\n}\n\n/*\n * Helper method to determine whether pixel data is interleaved and rgb or not.\n * @param {object} loader\n */\nexport function isRgb(loader) {\n  const source = getSourceFromLoader(loader);\n  const { shape, dtype, labels } = source;\n  const channelSize = shape[labels.indexOf('c')];\n  return (channelSize === 3) && dtype === 'Uint8';\n}\n","export const Component = {\n  DESCRIPTION: 'description',\n  STATUS: 'status',\n  GENES: 'genes',\n  CELL_SETS: 'cellSets',\n  SCATTERPLOT: 'scatterplot',\n  SPATIAL: 'spatial',\n  HEATMAP: 'heatmap',\n  LAYER_CONTROLLER: 'layerController',\n  CELL_SET_SIZES: 'cellSetSizes',\n  GENOMIC_PROFILES: 'genomicProfiles',\n  CELL_SET_EXPRESSION: 'cellSetExpression',\n  EXPRESSION_HISTOGRAM: 'expressionHistogram',\n};\n\nexport const DataType = {\n  CELLS: 'cells',\n  CELL_SETS: 'cell-sets',\n  EXPRESSION_MATRIX: 'expression-matrix',\n  GENOMIC_PROFILES: 'genomic-profiles',\n  MOLECULES: 'molecules',\n  NEIGHBORHOODS: 'neighborhoods',\n  RASTER: 'raster',\n};\n\nexport const FileType = {\n  CELLS_JSON: 'cells.json',\n  CELL_SETS_JSON: 'cell-sets.json',\n  EXPRESSION_MATRIX_ZARR: 'expression-matrix.zarr',\n  GENOMIC_PROFILES_ZARR: 'genomic-profiles.zarr',\n  MOLECULES_JSON: 'molecules.json',\n  NEIGHBORHOODS_JSON: 'neighborhoods.json',\n  RASTER_JSON: 'raster.json',\n  RASTER_OME_ZARR: 'raster.ome-zarr',\n  CLUSTERS_JSON: 'clusters.json',\n  GENES_JSON: 'genes.json',\n  ANNDATA_CELL_SETS_ZARR: 'anndata-cell-sets.zarr',\n  ANNDATA_CELLS_ZARR: 'anndata-cells.zarr',\n  ANNDATA_EXPRESSION_MATRIX_ZARR: 'anndata-expression-matrix.zarr',\n};\n\n/**\n * Constants representing names of coordination types,\n * to help prevent typos.\n */\nexport const CoordinationType = {\n  DATASET: 'dataset',\n  EMBEDDING_TYPE: 'embeddingType',\n  EMBEDDING_ZOOM: 'embeddingZoom',\n  EMBEDDING_ROTATION: 'embeddingRotation',\n  EMBEDDING_TARGET_X: 'embeddingTargetX',\n  EMBEDDING_TARGET_Y: 'embeddingTargetY',\n  EMBEDDING_TARGET_Z: 'embeddingTargetZ',\n  EMBEDDING_CELL_SET_POLYGONS_VISIBLE: 'embeddingCellSetPolygonsVisible',\n  EMBEDDING_CELL_SET_LABELS_VISIBLE: 'embeddingCellSetLabelsVisible',\n  EMBEDDING_CELL_SET_LABEL_SIZE: 'embeddingCellSetLabelSize',\n  EMBEDDING_CELL_RADIUS: 'embeddingCellRadius',\n  EMBEDDING_CELL_RADIUS_MODE: 'embeddingCellRadiusMode',\n  EMBEDDING_CELL_OPACITY: 'embeddingCellOpacity',\n  EMBEDDING_CELL_OPACITY_MODE: 'embeddingCellOpacityMode',\n  SPATIAL_ZOOM: 'spatialZoom',\n  SPATIAL_ROTATION: 'spatialRotation',\n  SPATIAL_TARGET_X: 'spatialTargetX',\n  SPATIAL_TARGET_Y: 'spatialTargetY',\n  SPATIAL_TARGET_Z: 'spatialTargetZ',\n  SPATIAL_ROTATION_X: 'spatialRotationX',\n  SPATIAL_ROTATION_Y: 'spatialRotationY',\n  SPATIAL_ROTATION_Z: 'spatialRotationZ',\n  SPATIAL_ROTATION_ORBIT: 'spatialRotationOrbit',\n  SPATIAL_ORBIT_AXIS: 'spatialOrbitAxis',\n  SPATIAL_AXIS_FIXED: 'spatialAxisFixed',\n  HEATMAP_ZOOM_X: 'heatmapZoomX',\n  HEATMAP_ZOOM_Y: 'heatmapZoomY',\n  HEATMAP_TARGET_X: 'heatmapTargetX',\n  HEATMAP_TARGET_Y: 'heatmapTargetY',\n  CELL_FILTER: 'cellFilter',\n  CELL_HIGHLIGHT: 'cellHighlight',\n  CELL_SET_SELECTION: 'cellSetSelection',\n  CELL_SET_HIGHLIGHT: 'cellSetHighlight',\n  CELL_SET_COLOR: 'cellSetColor',\n  GENE_FILTER: 'geneFilter',\n  GENE_HIGHLIGHT: 'geneHighlight',\n  GENE_SELECTION: 'geneSelection',\n  GENE_EXPRESSION_COLORMAP: 'geneExpressionColormap',\n  GENE_EXPRESSION_TRANSFORM: 'geneExpressionTransform',\n  GENE_EXPRESSION_COLORMAP_RANGE: 'geneExpressionColormapRange',\n  CELL_COLOR_ENCODING: 'cellColorEncoding',\n  SPATIAL_RASTER_LAYERS: 'spatialRasterLayers',\n  SPATIAL_CELLS_LAYER: 'spatialCellsLayer',\n  SPATIAL_MOLECULES_LAYER: 'spatialMoleculesLayer',\n  SPATIAL_NEIGHBORHOODS_LAYER: 'spatialNeighborhoodsLayer',\n  GENOMIC_ZOOM_X: 'genomicZoomX',\n  GENOMIC_ZOOM_Y: 'genomicZoomY',\n  GENOMIC_TARGET_X: 'genomicTargetX',\n  GENOMIC_TARGET_Y: 'genomicTargetY',\n  ADDITIONAL_CELL_SETS: 'additionalCellSets',\n  MOLECULE_HIGHLIGHT: 'moleculeHighlight',\n};\n","import { getNextScope, fromEntries } from '../utils';\nimport { CoordinationType } from '../app/constants';\n\n\n/**\n * Class representing a file within a Vitessce config dataset.\n */\nexport class VitessceConfigDatasetFile {\n  /**\n   * Construct a new file definition instance.\n   * @param {string} url The URL to the file.\n   * @param {string} dataType The type of data contained in the file.\n   * @param {string} fileType The file type.\n   * @param {object|array|null} options An optional object or array\n   * which may provide additional parameters to the loader class\n   * corresponding to the specified fileType.\n   */\n  constructor(url, dataType, fileType, options) {\n    this.file = {\n      url,\n      type: dataType,\n      fileType,\n      ...(options !== null ? { options } : {}),\n    };\n  }\n\n  /**\n   * @returns {object} This dataset file as a JSON object.\n   */\n  toJSON() {\n    return this.file;\n  }\n}\n\n/**\n * Class representing a dataset within a Vitessce config.\n */\nexport class VitessceConfigDataset {\n  /**\n   * Construct a new dataset definition instance.\n   * @param {string} uid The unique ID for the dataset.\n   * @param {string} name The name of the dataset.\n   * @param {string} description A description for the dataset.\n   */\n  constructor(uid, name, description) {\n    this.dataset = {\n      uid,\n      name,\n      description,\n      files: [],\n    };\n  }\n\n  /**\n   * Add a file definition to the dataset.\n   * @param {string|undefined} url The URL to the file.\n   * @param {string} dataType The type of data contained in the file.\n   * @param {string} fileType The file type.\n   * @param {object|array} options An optional object or array\n   * which may provide additional parameters to the loader class\n   * corresponding to the specified fileType.\n   * @returns {VitessceConfigDataset} This, to allow chaining.\n   */\n  addFile(url, dataType, fileType, options = null) {\n    this.dataset.files.push(\n      new VitessceConfigDatasetFile(url, dataType, fileType, options),\n    );\n    return this;\n  }\n\n  /**\n   * @returns {object} This dataset as a JSON object.\n   */\n  toJSON() {\n    return {\n      ...this.dataset,\n      files: this.dataset.files.map(f => f.toJSON()),\n    };\n  }\n}\n\n/**\n * Class representing a view within a Vitessce layout.\n */\nexport class VitessceConfigView {\n  /**\n   * Construct a new view instance.\n   * @param {string} component The name of the Vitessce component type.\n   * @param {object} coordinationScopes A mapping from coordination type\n   * names to coordination scope names.\n   * @param {number} x The x-coordinate of the view in the layout.\n   * @param {number} y The y-coordinate of the view in the layout.\n   * @param {number} w The width of the view in the layout.\n   * @param {number} h The height of the view in the layout.\n   */\n  constructor(component, coordinationScopes, x, y, w, h) {\n    this.view = {\n      component,\n      coordinationScopes,\n      x,\n      y,\n      w,\n      h,\n    };\n  }\n\n  /**\n   * Attach coordination scopes to this view.\n   * @param  {...VitessceConfigCoordinationScope} args A variable number of\n   * coordination scope instances.\n   * @returns {VitessceConfigView} This, to allow chaining.\n   */\n  useCoordination(...args) {\n    const cScopes = args;\n    cScopes.forEach((cScope) => {\n      this.view.coordinationScopes[cScope.cType] = cScope.cScope;\n    });\n    return this;\n  }\n\n  /**\n    * Set the x, y, w, h values for this view.\n    * @param {number} x The x-coordinate of the view in the layout.\n    * @param {number} y The y-coordinate of the view in the layout.\n    * @param {number} w The width of the view in the layout.\n    * @param {number} h The height of the view in the layout.\n    * @returns {VitessceConfigView} This, to allow chaining.\n    */\n  setXYWH(x, y, w, h) {\n    this.view.x = x;\n    this.view.y = y;\n    this.view.w = w;\n    this.view.h = h;\n\n    return this;\n  }\n\n  /**\n   * Set props for this view.\n   * @returns {VitessceConfigView} This, to allow chaining.\n   */\n  setProps(props) {\n    this.view.props = {\n      ...(this.view.props || {}),\n      ...props,\n    };\n    return this;\n  }\n\n  /**\n   * @returns {object} This view as a JSON object.\n   */\n  toJSON() {\n    return this.view;\n  }\n}\n\n/**\n * Class representing a horizontal concatenation of views.\n */\nexport class VitessceConfigViewHConcat {\n  constructor(views) {\n    this.views = views;\n  }\n}\n\n/**\n * Class representing a vertical concatenation of views.\n */\nexport class VitessceConfigViewVConcat {\n  constructor(views) {\n    this.views = views;\n  }\n}\n\n/**\n * A helper function to create a horizontal concatenation of views.\n * @param  {...(VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat)} views A\n * variable number of views or view concatenations.\n * @returns {VitessceConfigViewHConcat} A new horizontal view concatenation instance.\n */\nexport function hconcat(...views) {\n  const vcvhc = new VitessceConfigViewHConcat(views);\n  return vcvhc;\n}\n\n/**\n * A helper function to create a vertical concatenation of views.\n * @param  {...(VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat)} views A\n * variable number of views or view concatenations.\n * @returns {VitessceConfigViewVConcat} A new vertical view concatenation instance.\n */\nexport function vconcat(...views) {\n  const vcvvc = new VitessceConfigViewVConcat(views);\n  return vcvvc;\n}\n\n/**\n * Class representing a coordination scope in the coordination space.\n */\nexport class VitessceConfigCoordinationScope {\n  /**\n   * Construct a new coordination scope instance.\n   * @param {string} cType The coordination type for this coordination scope.\n   * @param {string} cScope The name of the coordination scope.\n   */\n  constructor(cType, cScope) {\n    this.cType = cType;\n    this.cScope = cScope;\n    this.cValue = null;\n  }\n\n  /**\n   * Set the coordination value of the coordination scope.\n   * @param {any} cValue The value to set.\n   * @returns {VitessceConfigCoordinationScope} This, to allow chaining.\n   */\n  setValue(cValue) {\n    this.cValue = cValue;\n    return this;\n  }\n}\n\n/**\n * Class representing a Vitessce view config.\n */\nexport class VitessceConfig {\n  /**\n   * Construct a new view config instance.\n   * @param {string} name A name for the config. Optional.\n   * @param {string} description A description for the config. Optional.\n   */\n  constructor(name = undefined, description = undefined) {\n    this.config = {\n      version: '1.0.4',\n      name,\n      description,\n      datasets: [],\n      coordinationSpace: {},\n      layout: [],\n      initStrategy: 'auto',\n    };\n  }\n\n  /**\n   * Add a new dataset to the config.\n   * @param {string} name A name for the dataset. Optional.\n   * @param {string} description A description for the dataset. Optional.\n   * @param {object} options Extra parameters to be used internally. Optional.\n   * @param {string} options.uid Override the automatically-generated dataset ID.\n   * Intended for internal usage by the VitessceConfig.fromJSON code.\n   * @returns {VitessceConfigDataset} A new dataset instance.\n   */\n  addDataset(name = undefined, description = undefined, options = undefined) {\n    const { uid } = options || {};\n    const prevDatasetUids = this.config.datasets.map(d => d.dataset.uid);\n    const nextUid = (uid || getNextScope(prevDatasetUids));\n    const newDataset = new VitessceConfigDataset(nextUid, name, description);\n    this.config.datasets.push(newDataset);\n    const [newScope] = this.addCoordination(CoordinationType.DATASET);\n    newScope.setValue(nextUid);\n    return newDataset;\n  }\n\n  /**\n   * Add a new view to the config.\n   * @param {VitessceConfigDataset} dataset The dataset instance which defines the data\n   * that will be displayed in the view.\n   * @param {string} component A component name, such as \"scatterplot\" or \"spatial\".\n   * @param {object} options Extra options for the component.\n   * @param {number} options.x The x-coordinate for the view in the grid layout.\n   * @param {number} options.y The y-coordinate for the view in the grid layout.\n   * @param {number} options.w The width for the view in the grid layout.\n   * @param {number} options.h The height for the view in the grid layout.\n   * @param {number} options.mapping A convenience parameter for setting the EMBEDDING_TYPE\n   * coordination value. Only applicable if the component is \"scatterplot\".\n   * @returns {VitessceConfigView} A new view instance.\n   */\n  addView(dataset, component, options) {\n    const {\n      x = 0,\n      y = 0,\n      w = 1,\n      h = 1,\n      mapping = null,\n    } = options || {};\n    const datasetMatches = (\n      this.config.coordinationSpace[CoordinationType.DATASET]\n        ? Object.entries(this.config.coordinationSpace[CoordinationType.DATASET])\n        // eslint-disable-next-line no-unused-vars\n          .filter(([scopeName, datasetScope]) => datasetScope.cValue === dataset.dataset.uid)\n          .map(([scopeName]) => scopeName)\n        : []\n    );\n    let datasetScope;\n    if (datasetMatches.length === 1) {\n      [datasetScope] = datasetMatches;\n    } else {\n      throw new Error('No coordination scope matching the dataset parameter could be found in the coordination space.');\n    }\n    const coordinationScopes = {\n      [CoordinationType.DATASET]: datasetScope,\n    };\n    const newView = new VitessceConfigView(component, coordinationScopes, x, y, w, h);\n    if (mapping) {\n      const [etScope] = this.addCoordination(CoordinationType.EMBEDDING_TYPE);\n      etScope.setValue(mapping);\n      newView.useCoordination(etScope);\n    }\n    this.config.layout.push(newView);\n    return newView;\n  }\n\n  /**\n   * Get an array of new coordination scope instances corresponding to coordination types\n   * of interest.\n   * @param {...string} args A variable number of coordination type names.\n   * @returns {VitessceConfigCoordinationScope[]} An array of coordination scope instances.\n   */\n  addCoordination(...args) {\n    const cTypes = args;\n    const result = [];\n    cTypes.forEach((cType) => {\n      const prevScopes = (\n        this.config.coordinationSpace[cType]\n          ? Object.keys(this.config.coordinationSpace[cType])\n          : []\n      );\n      const scope = new VitessceConfigCoordinationScope(cType, getNextScope(prevScopes));\n      if (!this.config.coordinationSpace[scope.cType]) {\n        this.config.coordinationSpace[scope.cType] = {};\n      }\n      this.config.coordinationSpace[scope.cType][scope.cScope] = scope;\n      result.push(scope);\n    });\n    return result;\n  }\n\n  /**\n   * A convenience function for setting up new coordination scopes across a set of views.\n   * @param {VitessceConfigView[]} views An array of view objects to link together.\n   * @param {string[]} cTypes The coordination types on which to coordinate the views.\n   * @param {any[]} cValues Initial values corresponding to each coordination type.\n   * Should have the same length as the cTypes array. Optional.\n   * @returns {VitessceConfig} This, to allow chaining.\n   */\n  linkViews(views, cTypes, cValues = null) {\n    const cScopes = this.addCoordination(...cTypes);\n    views.forEach((view) => {\n      cScopes.forEach((cScope) => {\n        view.useCoordination(cScope);\n      });\n    });\n    if (Array.isArray(cValues) && cValues.length === cTypes.length) {\n      cScopes.forEach((cScope, i) => {\n        cScope.setValue(cValues[i]);\n      });\n    }\n    return this;\n  }\n\n  /**\n   * Set the layout of views.\n   * @param {VitessceConfigView|VitessceConfigViewHConcat|VitessceConfigViewVConcat} viewConcat A\n   * view or a concatenation of views.\n   * @returns {VitessceConfig} This, to allow chaining.\n   */\n  layout(viewConcat) {\n    function layoutAux(obj, xMin, xMax, yMin, yMax) {\n      const w = xMax - xMin;\n      const h = yMax - yMin;\n      if (obj instanceof VitessceConfigView) {\n        obj.setXYWH(xMin, yMin, w, h);\n      } else if (obj instanceof VitessceConfigViewHConcat) {\n        const { views } = obj;\n        const numViews = views.length;\n        views.forEach((view, i) => {\n          layoutAux(view, xMin + (w / numViews) * i, xMin + (w / numViews) * (i + 1), yMin, yMax);\n        });\n      } else if (obj instanceof VitessceConfigViewVConcat) {\n        const { views } = obj;\n        const numViews = views.length;\n        views.forEach((view, i) => {\n          layoutAux(view, xMin, xMax, yMin + (h / numViews) * i, yMin + (h / numViews) * (i + 1));\n        });\n      }\n    }\n\n    layoutAux(viewConcat, 0, 12, 0, 12);\n\n    return this;\n  }\n\n  /**\n   * Convert this instance to a JSON object that can be passed to the Vitessce component.\n   * @returns {object} The view config as a JSON object.\n   */\n  toJSON() {\n    return {\n      ...this.config,\n      datasets: this.config.datasets.map(d => d.toJSON()),\n      coordinationSpace: fromEntries(\n        Object.entries(this.config.coordinationSpace).map(([cType, cScopes]) => ([\n          cType,\n          fromEntries(\n            Object.entries(cScopes).map(([cScopeName, cScope]) => ([\n              cScopeName,\n              cScope.cValue,\n            ])),\n          ),\n        ])),\n      ),\n      layout: this.config.layout.map(c => c.toJSON()),\n    };\n  }\n\n  /**\n   * Create a VitessceConfig instance from an existing view config, to enable\n   * manipulation with the JavaScript API.\n   * @param {object} config An existing Vitessce view config as a JSON object.\n   * @returns {VitessceConfig} A new config instance, with values set to match\n   * the config parameter.\n   */\n  static fromJSON(config) {\n    const { name, description } = config;\n    const vc = new VitessceConfig(name, description);\n    config.datasets.forEach((d) => {\n      const newDataset = vc.addDataset(d.name, d.description, { uid: d.uid });\n      d.files.forEach((f) => {\n        newDataset.addFile(\n          f.url,\n          f.type,\n          f.fileType,\n        );\n      });\n    });\n    Object.keys(config.coordinationSpace).forEach((cType) => {\n      if (cType !== CoordinationType.DATASET) {\n        const cObj = config.coordinationSpace[cType];\n        vc.config.coordinationSpace[cType] = {};\n        Object.entries(cObj).forEach(([cScopeName, cScopeValue]) => {\n          const scope = new VitessceConfigCoordinationScope(cType, cScopeName);\n          scope.setValue(cScopeValue);\n          vc.config.coordinationSpace[cType][cScopeName] = scope;\n        });\n      }\n    });\n    config.layout.forEach((c) => {\n      const newView = new VitessceConfigView(c.component, c.coordinationScopes, c.x, c.y, c.w, c.h);\n      vc.config.layout.push(newView);\n    });\n    return vc;\n  }\n}\n","import {\n  VitessceConfig, hconcat, vconcat,\n} from '../api/index';\nimport {\n  Component as cm,\n  DataType as dt,\n  FileType as ft,\n  CoordinationType as ct,\n} from '../app/constants';\n\n// Exported because used by the cypress tests: They route API requests to the fixtures instead.\nexport const urlPrefix = 'https://s3.amazonaws.com/vitessce-data/0.0.31/master_release';\n\nexport function makeDatasetNameToJsonFiles(datasetPrefix) {\n  return name => ({\n    type: name,\n    fileType: `${name}.json`,\n    url: `${urlPrefix}/${datasetPrefix}/${datasetPrefix}.${name}.json`,\n  });\n}\n\nexport function getS3Url(datasetPrefix, name) {\n  return `${urlPrefix}/${datasetPrefix}/${datasetPrefix}.${name}.json`;\n}\n\nexport function notPublic(config) {\n  return {\n    ...config,\n    public: undefined,\n  };\n}\n\nexport const vapi = {\n  VitessceConfig,\n  hconcat,\n  vconcat,\n  cm,\n  dt,\n  ft,\n  ct,\n};\n","import {\n  makeDatasetNameToJsonFiles,\n  getS3Url, vapi,\n} from '../utils';\n\n\nconst linnarssonDataTypes = [\n  'cells',\n  'cell-sets',\n  'raster',\n  'molecules',\n  'neighborhoods',\n];\nconst linnarssonName = 'Codeluppi et al., Nature Methods 2018';\nconst linnarssonDescription = 'Spatial organization of the somatosensory cortex revealed by osmFISH';\nconst linnarssonBase = {\n  name: linnarssonName,\n  description: linnarssonDescription,\n  version: '1.0.0',\n  initStrategy: 'auto',\n  datasets: [\n    {\n      uid: 'codeluppi',\n      name: 'Codeluppi',\n      files: [\n        ...linnarssonDataTypes.map(makeDatasetNameToJsonFiles('linnarsson')),\n        {\n          ...makeDatasetNameToJsonFiles('linnarsson')('clusters'),\n          type: 'expression-matrix',\n        },\n      ],\n    },\n  ],\n};\n\nconst linnarssonBaseNoMolecules = {\n  name: linnarssonName,\n  description: linnarssonDescription,\n  version: '1.0.0',\n  initStrategy: 'auto',\n  datasets: [\n    {\n      uid: 'codeluppi',\n      name: 'Codeluppi',\n      files: [\n        ...linnarssonDataTypes.filter(dtype => dtype !== 'molecules').map(makeDatasetNameToJsonFiles('linnarsson')),\n        {\n          ...makeDatasetNameToJsonFiles('linnarsson')('clusters'),\n          type: 'expression-matrix',\n        },\n      ],\n    },\n  ],\n};\n\nexport const justScatter = {\n  version: '1.0.0',\n  name: 'Codeluppi, just scatterplot',\n  public: false,\n  initStrategy: 'auto',\n  datasets: [\n    {\n      uid: 'codeluppi',\n      name: 'Codeluppi',\n      files: [\n        {\n          ...makeDatasetNameToJsonFiles('linnarsson')('cells'),\n          requestInit: {\n            // Where the client checks that the value is from an enumeration,\n            // I've chosen one of the allowed values,\n            // but nothing on our S3 actually needs any of these.\n            method: 'GET',\n            headers: { 'x-foo': 'FAKE' },\n            mode: 'cors',\n            credentials: 'omit',\n            cache: 'no-store',\n            redirect: 'error',\n            referrer: 'FAKE',\n            integrity: 'FAKE',\n          },\n        },\n      ],\n    },\n  ],\n  coordinationSpace: {\n    embeddingType: {\n      A: 't-SNE',\n    },\n    embeddingZoom: {\n      A: 0.75,\n    },\n  },\n  layout: [\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'A',\n        embeddingZoom: 'A',\n      },\n      x: 0,\n      y: 0,\n      w: 12,\n      h: 2,\n    },\n  ],\n};\n\nexport const justScatterExpression = {\n  version: '1.0.0',\n  name: 'Codeluppi, just scatterplot and expression',\n  public: false,\n  initStrategy: 'auto',\n  datasets: [\n    {\n      uid: 'codeluppi',\n      name: 'Codeluppi',\n      files: [\n        makeDatasetNameToJsonFiles('linnarsson')('cells'),\n        makeDatasetNameToJsonFiles('linnarsson')('genes'),\n      ],\n    },\n  ],\n  coordinationSpace: {\n    embeddingType: {\n      A: 't-SNE',\n    },\n    embeddingZoom: {\n      A: 0.75,\n    },\n  },\n  layout: [\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'A',\n        embeddingZoom: 'A',\n      },\n      x: 0,\n      y: 0,\n      w: 12,\n      h: 2,\n    },\n    {\n      component: 'genes',\n      x: 8,\n      y: 2,\n      w: 4,\n      h: 2,\n    },\n  ],\n};\n\nexport const justSpatial = {\n  ...linnarssonBase,\n  coordinationSpace: {\n    spatialZoom: {\n      A: -6.5,\n    },\n    spatialTargetX: {\n      A: 18000,\n    },\n    spatialTargetY: {\n      A: 18000,\n    },\n  },\n  layout: [\n    {\n      component: 'spatial',\n      coordinationScopes: {\n        spatialZoom: 'A',\n        spatialTargetX: 'A',\n        spatialTargetY: 'A',\n      },\n      x: 0,\n      y: 0,\n      w: 10,\n      h: 2,\n    },\n    {\n      component: 'genes',\n      x: 10,\n      y: 1,\n      w: 2,\n      h: 1,\n    },\n  ],\n};\n\nexport const codeluppi2018 = {\n  ...linnarssonBase,\n  public: true,\n  coordinationSpace: {\n    embeddingZoom: {\n      PCA: 0,\n      TSNE: 0.75,\n    },\n    embeddingType: {\n      PCA: 'PCA',\n      TSNE: 't-SNE',\n    },\n    spatialZoom: {\n      A: -5.5,\n    },\n    spatialTargetX: {\n      A: 16000,\n    },\n    spatialTargetY: {\n      A: 20000,\n    },\n  },\n  layout: [\n    {\n      component: 'description',\n      props: {\n        description: `${linnarssonName}: ${linnarssonDescription}`,\n      },\n      x: 0,\n      y: 0,\n      w: 2,\n      h: 1,\n    },\n    {\n      component: 'layerController',\n      x: 0,\n      y: 1,\n      w: 2,\n      h: 4,\n    },\n    {\n      component: 'status',\n      x: 0,\n      y: 5,\n      w: 2,\n      h: 1,\n    },\n    {\n      component: 'spatial',\n      coordinationScopes: {\n        spatialZoom: 'A',\n        spatialTargetX: 'A',\n        spatialTargetY: 'A',\n      },\n      x: 2,\n      y: 0,\n      w: 4,\n      h: 4,\n    },\n    {\n      component: 'genes',\n      x: 9,\n      y: 0,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'cellSets',\n      x: 9,\n      y: 3,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'heatmap',\n      props: {\n        transpose: true,\n      },\n      x: 2,\n      y: 4,\n      w: 5,\n      h: 2,\n    },\n    {\n      component: 'cellSetExpression',\n      x: 7,\n      y: 4,\n      w: 5,\n      h: 2,\n    },\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'PCA',\n        embeddingZoom: 'PCA',\n      },\n      x: 6,\n      y: 0,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'TSNE',\n        embeddingZoom: 'TSNE',\n      },\n      x: 6,\n      y: 2,\n      w: 3,\n      h: 2,\n    },\n  ],\n};\n\nexport const linnarssonWithRorb = {\n  ...linnarssonBaseNoMolecules,\n  coordinationSpace: {\n    embeddingZoom: {\n      PCA: 0,\n      TSNE: 0.75,\n    },\n    embeddingType: {\n      PCA: 'PCA',\n      TSNE: 't-SNE',\n    },\n    spatialZoom: {\n      A: -5.5,\n    },\n    spatialTargetX: {\n      A: 16000,\n    },\n    spatialTargetY: {\n      A: 20000,\n    },\n    geneSelection: {\n      A: ['Rorb'],\n    },\n    geneExpressionColormapRange: {\n      A: [0, 0.75],\n    },\n  },\n  layout: [\n    {\n      component: 'description',\n      props: {\n        description: `${linnarssonName}: ${linnarssonDescription}`,\n      },\n      x: 0,\n      y: 0,\n      w: 2,\n      h: 2,\n    },\n    {\n      component: 'layerController',\n      x: 0,\n      y: 2,\n      w: 2,\n      h: 4,\n    },\n    {\n      component: 'spatial',\n      coordinationScopes: {\n        spatialZoom: 'A',\n        spatialTargetX: 'A',\n        spatialTargetY: 'A',\n        geneSelection: 'A',\n      },\n      x: 2,\n      y: 0,\n      w: 4,\n      h: 4,\n    },\n    {\n      component: 'genes',\n      coordinationScopes: {\n        geneSelection: 'A',\n      },\n      x: 9,\n      y: 0,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'cellSets',\n      x: 9,\n      y: 3,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'heatmap',\n      coordinationScopes: {\n        geneSelection: 'A',\n        geneExpressionColormapRange: 'A',\n      },\n      props: {\n        transpose: true,\n      },\n      x: 2,\n      y: 4,\n      w: 10,\n      h: 2,\n    },\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'TSNE',\n        embeddingZoom: 'TSNE',\n        geneSelection: 'A',\n      },\n      x: 6,\n      y: 0,\n      w: 3,\n      h: 4,\n    },\n  ],\n};\n\nexport function getCodeluppiViewConfig(name, description) {\n  const vc = new vapi.VitessceConfig(name, description);\n  const dataset = vc.addDataset(linnarssonName, linnarssonDescription)\n    .addFile(getS3Url('linnarsson', 'cells'), vapi.dt.CELLS, vapi.ft.CELLS_JSON)\n    .addFile(getS3Url('linnarsson', 'cell-sets'), vapi.dt.CELL_SETS, vapi.ft.CELL_SETS_JSON)\n    .addFile(getS3Url('linnarsson', 'raster'), vapi.dt.RASTER, vapi.ft.RASTER_JSON)\n    .addFile(getS3Url('linnarsson', 'molecules'), vapi.dt.MOLECULES, vapi.ft.MOLECULES_JSON);\n  return [vc, dataset];\n}\n","import {\n  makeDatasetNameToJsonFiles,\n  getS3Url, vapi,\n} from '../utils';\n\nconst driesName = 'Eng et al., Nature 2019';\nconst driesDescription = 'Transcriptome-scale super-resolved imaging in tissues by RNA seqFISH';\n\nexport const eng2019 = {\n  name: driesName,\n  version: '1.0.0',\n  description: driesDescription,\n  public: true,\n  datasets: [\n    {\n      uid: 'dries-2019',\n      name: 'Dries 2019',\n      files: [\n        'cells',\n        'cell-sets',\n      ].map(makeDatasetNameToJsonFiles('dries')),\n    },\n  ],\n  initStrategy: 'auto',\n  coordinationSpace: {\n    embeddingType: {\n      TSNE: 't-SNE',\n      UMAP: 'UMAP',\n    },\n    embeddingCellSetPolygonsVisible: {\n      A: false,\n    },\n    embeddingCellSetLabelsVisible: {\n      A: true,\n    },\n    embeddingCellSetLabelSize: {\n      A: 16,\n    },\n    embeddingCellRadius: {\n      A: 1,\n    },\n    embeddingZoom: {\n      TSNE: 3,\n      UMAP: 3,\n    },\n    spatialZoom: {\n      A: -4.4,\n    },\n    spatialTargetX: {\n      A: 3800,\n    },\n    spatialTargetY: {\n      A: -900,\n    },\n  },\n  layout: [\n    {\n      component: 'description',\n      props: {\n        description: `${driesName}: ${driesDescription}`,\n      },\n      x: 9,\n      y: 0,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'status',\n      x: 9,\n      y: 2,\n      w: 3,\n      h: 2,\n    },\n    {\n      component: 'cellSets',\n      x: 9,\n      y: 4,\n      w: 3,\n      h: 4,\n    },\n    {\n      component: 'cellSetSizes',\n      x: 5,\n      y: 4,\n      w: 4,\n      h: 4,\n    },\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'TSNE',\n        embeddingZoom: 'TSNE',\n        embeddingCellSetLabelsVisible: 'A',\n        embeddingCellSetLabelSize: 'A',\n        embeddingCellSetPolygonsVisible: 'A',\n        embeddingCellRadius: 'A',\n      },\n      x: 0,\n      y: 2,\n      w: 5,\n      h: 4,\n    },\n    {\n      component: 'spatial',\n      props: {\n        cellRadius: 50,\n      },\n      coordinationScopes: {\n        spatialZoom: 'A',\n        spatialTargetX: 'A',\n        spatialTargetY: 'A',\n      },\n      x: 5,\n      y: 0,\n      w: 4,\n      h: 4,\n    },\n    {\n      component: 'scatterplot',\n      coordinationScopes: {\n        embeddingType: 'UMAP',\n        embeddingZoom: 'UMAP',\n        embeddingCellSetLabelsVisible: 'A',\n        embeddingCellSetLabelSize: 'A',\n        embeddingCellSetPolygonsVisible: 'A',\n        embeddingCellRadius: 'A',\n      },\n      x: 0,\n      y: 0,\n      w: 5,\n      h: 4,\n    },\n  ],\n};\n\nexport function getEngViewConfig(name, description) {\n  const vc = new vapi.VitessceConfig(name, description);\n  const dataset = vc.addDataset(driesName, driesDescription)\n    .addFile(getS3Url('dries', 'cells'), vapi.dt.CELLS, vapi.ft.CELLS_JSON)\n    .addFile(getS3Url('dries', 'cell-sets'), vapi.dt.CELL_SETS, vapi.ft.CELL_SETS_JSON);\n  return [vc, dataset];\n}\n","import { makeDatasetNameToJsonFiles } from '../utils';\n\nconst wangName = 'Wang et al., Scientific Reports 2018';\nconst wangDescription = 'Multiplexed imaging of high-density libraries of RNAs with MERFISH and expansion microscopy';\n\nexport const wang2018 = {\n  name: wangName,\n  version: '1.0.0',\n  description: wangDescription,\n  public: true,\n  datasets: [\n    {\n      uid: 'wang-2018',\n      name: 'Wang 2018',\n      files: [\n        ...[\n          'cells', 'molecules',\n        ].map(makeDatasetNameToJsonFiles('wang')),\n        {\n          ...makeDatasetNameToJsonFiles('wang')('genes'),\n          type: 'expression-matrix',\n        },\n      ],\n    },\n  ],\n  initStrategy: 'auto',\n  coordinationSpace: {\n    spatialZoom: {\n      A: -1,\n    },\n    spatialLayers: {\n      A: [\n        {\n          type: 'molecules', radius: 2, opacity: 1, visible: true,\n        },\n        {\n          type: 'cells', opacity: 1, radius: 50, visible: true, stroked: false,\n        },\n      ],\n    },\n  },\n  layout: [\n    {\n      component: 'spatial',\n      coordinationScopes: {\n        spatialZoom: 'A',\n        spatialLayers: 'A',\n      },\n      x: 0,\n      y: 0,\n      w: 10,\n      h: 2,\n    },\n    {\n      component: 'genes',\n      x: 10,\n      y: 0,\n      w: 2,\n      h: 2,\n    },\n  ],\n};\n","import { urlPrefix } from '../utils';\n\nconst vanderbiltDescription = 'High bit depth (uint16) multiplex immunofluorescence images of the kidney by the BIOmolecular Multimodal Imaging Center (BIOMIC) at Vanderbilt University';\nconst vanderbiltBase = {\n  description: vanderbiltDescription,\n  layers: [\n    {\n      name: 'raster',\n      type: 'RASTER',\n      fileType: 'raster.json',\n      url: `${urlPrefix}/spraggins/spraggins.raster.json`,\n    },\n  ],\n};\n\nexport const spraggins2020 = {\n  ...vanderbiltBase,\n  version: '0.1.0',\n  name: 'Spraggins',\n  public: true,\n  staticLayout: [\n    {\n      component: 'spatial',\n      props: {\n        view: {\n          zoom: -6.5,\n          target: [20000, 20000, 0],\n        },\n      },\n      x: 0,\n      y: 0,\n      w: 9,\n      h: 2,\n    },\n    {\n      component: 'layerController',\n      x: 9,\n      y: 0,\n      w: 3,\n      h: 2,\n    },\n  ],\n};\n\nexport const neumann2020 = {\n  version: '1.0.1',\n  name: 'Neumann et al., 2020',\n  description: 'Four registered imaging modalities (PAS, IMS, AF) from HuBMAP collection HBM876.XNRH.336',\n  datasets: [\n    {\n      uid: 'A',\n      name: 'Spraggins',\n      files: [\n        {\n          type: 'raster',\n          fileType: 'raster.json',\n          options: {\n            schemaVersion: '0.0.2',\n            images: [\n              {\n                name: 'PAS',\n                type: 'ome-tiff',\n                url: 'https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=',\n              },\n              {\n                name: 'AF',\n                type: 'ome-tiff',\n                url: 'https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=',\n              },\n              {\n                name: 'IMS PosMode',\n                type: 'ome-tiff',\n                url: 'https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=',\n              },\n              {\n                name: 'IMS NegMode',\n                type: 'ome-tiff',\n                url: 'https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=',\n              },\n            ],\n            usePhysicalSizeScaling: true,\n            renderLayers: [\n              'PAS',\n              'AF',\n              'IMS PosMode',\n              'IMS NegMode',\n            ],\n          },\n        },\n      ],\n    },\n  ],\n  coordinationSpace: {},\n  layout: [\n    {\n      component: 'spatial',\n      coordinationScopes: {},\n      x: 0,\n      y: 0,\n      w: 9,\n      h: 12,\n    },\n    {\n      component: 'layerController',\n      coordinationScopes: {},\n      x: 9,\n      y: 0,\n      w: 3,\n      h: 12,\n    },\n  ],\n  initStrategy: 'auto',\n};\n","\n\nconst satijaName = 'HBM336.FWTN.636';\nconst satijaDescription = 'Spleen scRNA-seq HuBMAP dataset with cell type annotations generated by the Satija lab and the Seurat v3.1 Label Transfer workflow';\nexport const satija2020 = {\n  version: '1.0.0',\n  name: satijaName,\n  description: satijaDescription,\n  public: true,\n  datasets: [\n    {\n      uid: '339952f4-a47f-46dc-9228-18ba2ca256f2',\n      name: '339952f4-a47f-46dc-9228-18ba2ca256f2',\n      files: [\n        {\n          type: 'cells',\n          fileType: 'cells.json',\n          url: 'https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/satija/2dca1bf5832a4102ba780e9e54f6c350.cells.json',\n        },\n        {\n          type: 'cell-sets',\n          fileType: 'cell-sets.json',\n          url: 'https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/satija/2dca1bf5832a4102ba780e9e54f6c350.cell-sets.json',\n        },\n        {\n          type: 'expression-matrix',\n          fileType: 'expression-matrix.zarr',\n          url: 'https://vitessce-data.storage.googleapis.com/0.0.31/master_release/satija/2dca1bf5832a4102ba780e9e54f6c350.expression-matrix.zarr',\n        },\n      ],\n    },\n  ],\n  initStrategy: 'auto',\n  coordinationSpace: {\n    embeddingType: {\n      UMAP: 'UMAP',\n    },\n    embeddingZoom: {\n      A: 3,\n    },\n    embeddingTargetX: {\n      A: 0,\n    },\n    embeddingTargetY: {\n      A: 0,\n    },\n    spatialZoom: {},\n    spatialTargetX: {},\n    spatialTargetY: {},\n    geneExpressionColormapRange: {\n      A: [0, 0.25],\n    },\n  },\n  layout: [\n    {\n      component: 'cellSets',\n      h: 4,\n      w: 4,\n      x: 4,\n      y: 0,\n      coordinationScopes: {},\n    },\n    {\n      component: 'cellSetSizes',\n      h: 4,\n      w: 4,\n      x: 8,\n      y: 0,\n      coordinationScopes: {},\n    },\n    {\n      component: 'scatterplot',\n      h: 4,\n      props: {\n        mapping: 'UMAP',\n        view: {\n          target: [\n            0,\n            0,\n            0,\n          ],\n          zoom: 3,\n        },\n      },\n      w: 4,\n      x: 0,\n      y: 0,\n      coordinationScopes: {\n        embeddingType: 'UMAP',\n        embeddingZoom: 'A',\n        embeddingTargetX: 'A',\n        embeddingTargetY: 'A',\n      },\n    },\n    {\n      component: 'heatmap',\n      h: 4,\n      w: 10,\n      x: 0,\n      y: 4,\n      coordinationScopes: {\n        geneExpressionColormapRange: 'A',\n      },\n    },\n    {\n      component: 'description',\n      h: 4,\n      w: 2,\n      x: 10,\n      y: 4,\n      props: {\n        description: `${satijaName}: ${satijaDescription}`,\n      },\n    },\n  ],\n};\n","\n\nconst blinName = 'Blin et al., PLoS Biol 2019';\nconst blinDescription = 'Mouse blastocysts imaged by confocal microscopy';\nexport const blin2019 = {\n  version: '1.0.6',\n  name: blinName,\n  description: blinDescription,\n  public: true,\n  datasets: [\n    {\n      uid: 'idr0062-blin-nuclearsegmentation/6001240',\n      name: 'idr0062-blin-nuclearsegmentation/6001240',\n      files: [\n        {\n          type: 'raster',\n          fileType: 'raster.ome-zarr',\n          url: 'https://minio-dev.openmicroscopy.org/idr/v0.3/idr0062-blin-nuclearsegmentation/6001240.zarr',\n        },\n      ],\n    },\n  ],\n  initStrategy: 'auto',\n  layout: [\n    {\n      component: 'spatial',\n      x: 0,\n      y: 0,\n      w: 8,\n      h: 12,\n    },\n    {\n      component: 'layerController',\n      x: 8,\n      y: 0,\n      w: 4,\n      h: 6,\n    },\n    {\n      component: 'description',\n      x: 8,\n      y: 6,\n      w: 4,\n      h: 3,\n    },\n    {\n      component: 'status',\n      x: 8,\n      y: 9,\n      w: 4,\n      h: 3,\n    },\n  ],\n};\n","\n\nconst blinName = '179706';\nconst blinDescription = 'Example of OME-NGFF v0.1';\nexport const omeNgffLegacy = {\n  version: '1.0.6',\n  name: blinName,\n  description: blinDescription,\n  public: false,\n  datasets: [\n    {\n      uid: '179706',\n      name: '179706',\n      files: [\n        {\n          type: 'raster',\n          fileType: 'raster.ome-zarr',\n          url: 'https://s3.embassy.ebi.ac.uk/idr/zarr/v0.1/179706.zarr',\n        },\n      ],\n    },\n  ],\n  coordinationSpace: {\n    spatialZoom: {\n      A: -0.38015,\n    },\n    spatialTargetX: {\n      A: 807.843,\n    },\n    spatialTargetY: {\n      A: 537.031,\n    },\n  },\n  initStrategy: 'auto',\n  layout: [\n    {\n      component: 'spatial',\n      coordinationScopes: {\n        spatialZoom: 'A',\n        spatialTargetX: 'A',\n        spatialTargetY: 'A',\n      },\n      x: 0,\n      y: 0,\n      w: 8,\n      h: 12,\n    },\n    {\n      component: 'layerController',\n      x: 8,\n      y: 0,\n      w: 4,\n      h: 6,\n    },\n    {\n      component: 'description',\n      x: 8,\n      y: 6,\n      w: 4,\n      h: 3,\n    },\n    {\n      component: 'status',\n      x: 8,\n      y: 9,\n      w: 4,\n      h: 3,\n    },\n  ],\n};\n","import { vapi } from '../utils';\n\nfunction getConfig() {\n  // Instantiate a view config object.\n  const vc = new vapi.VitessceConfig('HBM485.TBWH.322', 'Large intestine snATAC-seq HuBMAP dataset with genomic data visualization powered by HiGlass');\n  // Add a dataset and its files.\n  const baseUrl = 'https://vitessce-data.s3.amazonaws.com/0.0.32/master_release/human_intestine_2020_hubmap';\n  const dataset = vc\n    .addDataset('HBM485.TBWH.322', 'Human large intestine, snATAC-seq')\n    .addFile(`${baseUrl}/human_intestine_2020_hubmap.cells.json`, vapi.dt.CELLS, vapi.ft.CELLS_JSON)\n    .addFile(`${baseUrl}/human_intestine_2020_hubmap.cell-sets.json`, vapi.dt.CELL_SETS, vapi.ft.CELL_SETS_JSON)\n    .addFile(`${baseUrl}/human_intestine_2020_hubmap.genomic-profiles.zarr`, vapi.dt.GENOMIC_PROFILES, vapi.ft.GENOMIC_PROFILES_ZARR);\n    // Add components.\n    // Use mapping: \"UMAP\" so that cells are mapped to the UMAP positions from the JSON file.\n  const umap = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 'UMAP' });\n  const cellSetsManager = vc.addView(dataset, vapi.cm.CELL_SETS);\n  const genomicProfiles = vc.addView(dataset, vapi.cm.GENOMIC_PROFILES);\n\n  // Try un-commenting the line below to link center points of the two scatterplots!\n  // vc.linkViews([umap, tsne], [ct.EMBEDDING_TARGET_X, ct.EMBEDDING_TARGET_Y], [0, 0]);\n  vc.layout(\n    vapi.vconcat(\n      genomicProfiles,\n      vapi.hconcat(umap, cellSetsManager),\n    ),\n  );\n\n  // Return the view config as JSON.\n  return vc.toJSON();\n}\n\nexport const hubmapIntestineSnAtacSeq = getConfig();\n","import { vapi } from '../../utils';\nimport { getCodeluppiViewConfig } from '../codeluppi';\n\nfunction getConfig() {\n  const [vc, dataset] = getCodeluppiViewConfig(`Coordination Type: ${vapi.ct.EMBEDDING_ZOOM}`, 'Zoom levels in the scatterplots are coordinated.');\n  const v1 = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 't-SNE' });\n  const v2 = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 't-SNE' });\n  vc.linkViews([v1, v2], [vapi.ct.EMBEDDING_ZOOM], [-1]);\n\n  vc.layout(vapi.hconcat(v1, v2));\n  return vc.toJSON();\n}\n\nexport const embeddingZoomConfig = getConfig();\n","import { vapi } from '../../utils';\nimport { getCodeluppiViewConfig } from '../codeluppi';\n\nfunction getConfig() {\n  const [vc, dataset] = getCodeluppiViewConfig(`Coordination Type: ${vapi.ct.EMBEDDING_TARGET_X}`, 'Panning along the x-axis of the scatterplots is coordinated.');\n  const v1 = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 't-SNE' });\n  const v2 = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 't-SNE' });\n  vc.linkViews([v1, v2], [vapi.ct.EMBEDDING_TARGET_X], [0]);\n\n  vc.layout(vapi.hconcat(v1, v2));\n  return vc.toJSON();\n}\n\nexport const embeddingTargetXConfig = getConfig();\n","import { vapi } from '../../utils';\nimport { getCodeluppiViewConfig } from '../codeluppi';\n\nfunction getConfig() {\n  const [vc, dataset] = getCodeluppiViewConfig(`Coordination Type: ${vapi.ct.EMBEDDING_TARGET_Y}`, 'Panning along the y-axis of the scatterplots is coordinated.');\n  const v1 = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 't-SNE' });\n  const v2 = vc.addView(dataset, vapi.cm.SCATTERPLOT, { mapping: 't-SNE' });\n  vc.linkViews([v1, v2], [vapi.ct.EMBEDDING_TARGET_Y], [0]);\n\n  vc.layout(vapi.hconcat(v1, v2));\n  return vc.toJSON();\n}\n\nexport const embeddingTargetYConfig = getConfig();\n","import { vapi } from '../../utils';\nimport { getEngViewConfig } from '../eng';\n\nfunction getConfig() {\n  const [vc, dataset] = getEngViewConfig(`Coordination Type: ${vapi.ct.EMBEDDING_CELL_SET_POLYGONS_VISIBLE}`, 'Visibility of polygon overlays is coordinated in the top two scatterplots, and independent in the bottom two. Try clicking the gear above each plot and toggling the \"Cell Set Polygons Visible\" checkboxes.');\n  const v1 = vc.addView(dataset, vapi.cm.SCATTERPLOT, {\n    mapping: 't-SNE', x: 0, y: 0, w: 5, h: 6,\n  });\n  const v2 = vc.addView(dataset, vapi.cm.SCATTERPLOT, {\n    mapping: 't-SNE', x: 5, y: 0, w: 5, h: 6,\n  });\n  vc.addView(dataset, vapi.cm.SCATTERPLOT, {\n    mapping: 't-SNE', x: 0, y: 6, w: 5, h: 6,\n  });\n  const v4 = vc.addView(dataset, vapi.cm.SCATTERPLOT, {\n    mapping: 't-SNE', x: 5, y: 6, w: 5, h: 6,\n  });\n  vc.addView(dataset, vapi.cm.CELL_SETS, {\n    x: 10, y: 0, w: 2, h: 12,\n  });\n  vc.linkViews([v1, v2], [vapi.ct.EMBEDDING_CELL_SET_POLYGONS_VISIBLE], [true]);\n  vc.linkViews([v4], [vapi.ct.EMBEDDING_CELL_SET_POLYGONS_VISIBLE], [true]);\n\n  return vc.toJSON();\n}\n\nexport const embeddingCellSetPolygonsVisibleConfig = getConfig();\n","import { notPublic, vapi } from './utils';\nimport {\n  justScatter, justScatterExpression, justSpatial, codeluppi2018,\n} from './view-configs/codeluppi';\nimport { eng2019 } from './view-configs/eng';\nimport { wang2018 } from './view-configs/wang';\nimport { spraggins2020, neumann2020 } from './view-configs/spraggins';\nimport { satija2020 } from './view-configs/satija';\nimport { justHiglass } from './view-configs/rao';\nimport { scAtacSeq10xPbmc } from './view-configs/tenx';\nimport { blin2019 } from './view-configs/blin';\nimport { omeNgffLegacy } from './view-configs/ome-ngff-legacy';\nimport { hubmapIntestineSnAtacSeq } from './view-configs/hubmap';\nimport {\n  embeddingZoomConfig,\n  embeddingTargetXConfig,\n  embeddingTargetYConfig,\n  embeddingCellSetPolygonsVisibleConfig,\n} from './view-configs/coordination-types/index';\n\n\nexport const coordinationTypeConfigs = {\n  [vapi.ct.EMBEDDING_ZOOM]: embeddingZoomConfig,\n  [vapi.ct.EMBEDDING_TARGET_X]: embeddingTargetXConfig,\n  [vapi.ct.EMBEDDING_TARGET_Y]: embeddingTargetYConfig,\n  [vapi.ct.EMBEDDING_CELL_SET_POLYGONS_VISIBLE]: embeddingCellSetPolygonsVisibleConfig,\n};\n\n// Note that the ordering of the components in the layout\n// can affect the z-index of plot tooltips due to the\n// resulting ordering of elements in the DOM.\n\nexport const configs = {\n  'just-scatter': justScatter,\n  'just-scatter-expression': justScatterExpression,\n  'just-spatial': justSpatial,\n  'just-higlass': justHiglass,\n  'codeluppi-2018': codeluppi2018,\n  'eng-2019': eng2019,\n  'wang-2018': wang2018,\n  'spraggins-2020': spraggins2020,\n  'neumann-2020': neumann2020,\n  'satija-2020': satija2020,\n  'sn-atac-seq-hubmap-2020': hubmapIntestineSnAtacSeq,\n  'sc-atac-seq-10x-genomics-pbmc': scAtacSeq10xPbmc,\n  'blin-2019': blin2019,\n  'ome-ngff-v0.1': omeNgffLegacy,\n  // Keys which enable backwards compatibility with old links.\n  'linnarsson-2018': notPublic(codeluppi2018),\n  vanderbilt: notPublic(spraggins2020),\n  'dries-2019': notPublic(eng2019),\n  ...coordinationTypeConfigs,\n};\n","\nexport const justHiglass = {\n  public: false,\n  initStrategy: 'auto',\n  version: '1.0.0',\n  datasets: [\n    {\n      uid: 'higlass-dataset',\n      name: 'HiGlass Dataset',\n      files: [],\n    },\n  ],\n  name: 'HiGlass demo',\n  coordinationSpace: {\n    genomicZoomX: {\n      A: 0,\n    },\n    genomicZoomY: {\n      A: 0,\n    },\n    genomicTargetX: {\n      A: 1549999999.5,\n    },\n    genomicTargetY: {\n      A: 1549999999.5,\n    },\n  },\n  layout: [\n    {\n      component: 'higlass',\n      coordinationScopes: {\n        genomicZoomX: 'A',\n        genomicZoomY: 'A',\n        genomicTargetX: 'A',\n        genomicTargetY: 'A',\n      },\n      props: {\n        hgViewConfig: {\n          uid: 'aa',\n          autocompleteSource: '/api/v1/suggest/?d=OHJakQICQD6gTD7skx4EWA&',\n          genomePositionSearchBox: {\n            autocompleteServer: '//higlass.io/api/v1',\n            autocompleteId: 'OHJakQICQD6gTD7skx4EWA',\n            chromInfoServer: '//higlass.io/api/v1',\n            chromInfoId: 'hg19',\n            visible: true,\n          },\n          chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',\n          tracks: {\n            top: [\n              {\n                type: 'horizontal-gene-annotations',\n                height: 60,\n                tilesetUid: 'OHJakQICQD6gTD7skx4EWA',\n                server: '//higlass.io/api/v1',\n                uid: 'OHJakQICQD6gTD7skx4EWA',\n                options: {\n                  name: 'Gene Annotations (hg19)',\n                  fontSize: 10,\n                  labelPosition: 'hidden',\n                  labelLeftMargin: 0,\n                  labelRightMargin: 0,\n                  labelTopMargin: 0,\n                  labelBottomMargin: 0,\n                  minHeight: 24,\n                  geneAnnotationHeight: 16,\n                  geneLabelPosition: 'outside',\n                  geneStrandSpacing: 4,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                  plusStrandColor: '#fdff54',\n                  minusStrandColor: '#68bf30',\n                  labelColor: 'black',\n                  trackBorderWidth: 0,\n                  trackBorderColor: 'black',\n                },\n              },\n              {\n                chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',\n                type: 'horizontal-chromosome-labels',\n                height: 30,\n                uid: 'X4e_1DKiQHmyghDa6lLMVA',\n                options: {\n                  color: '#808080',\n                  stroke: 'black',\n                  fontSize: 12,\n                  fontIsLeftAligned: false,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                },\n              },\n            ],\n            left: [\n              {\n                type: 'vertical-gene-annotations',\n                width: 60,\n                tilesetUid: 'OHJakQICQD6gTD7skx4EWA',\n                server: '//higlass.io/api/v1',\n                options: {\n                  labelPosition: 'bottomRight',\n                  name: 'Gene Annotations (hg19)',\n                  fontSize: 10,\n                  labelLeftMargin: 0,\n                  labelRightMargin: 0,\n                  labelTopMargin: 0,\n                  labelBottomMargin: 0,\n                  minWidth: 24,\n                  geneAnnotationHeight: 16,\n                  geneLabelPosition: 'outside',\n                  geneStrandSpacing: 4,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                  plusStrandColor: '#fdff54',\n                  minusStrandColor: '#68bf30',\n                  labelColor: 'black',\n                  trackBorderWidth: 0,\n                  trackBorderColor: 'black',\n                },\n                uid: 'dqBTMH78Rn6DeSyDBoAEXw',\n              },\n              {\n                chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',\n                type: 'vertical-chromosome-labels',\n                width: 30,\n                uid: 'RHdQK4IRQ7yJeDmKWb7Pcg',\n                options: {\n                  color: '#777777',\n                  stroke: 'black',\n                  fontSize: 12,\n                  fontIsLeftAligned: false,\n                  minWidth: 35,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                },\n              },\n            ],\n            center: [\n              {\n                uid: 'c1',\n                type: 'combined',\n                height: 600,\n                contents: [\n                  {\n                    server: '//higlass.io/api/v1',\n                    tilesetUid: 'CQMd6V_cRw6iCI_-Unl3PQ',\n                    type: 'heatmap',\n                    options: {\n                      maxZoom: null,\n                      labelPosition: 'bottomRight',\n                      name: 'Rao et al. (2014) GM12878 MboI (allreps) 1kb',\n                      backgroundColor: 'black',\n                      labelLeftMargin: 0,\n                      labelRightMargin: 0,\n                      labelTopMargin: 0,\n                      labelBottomMargin: 0,\n                      labelShowResolution: true,\n                      labelShowAssembly: true,\n                      labelColor: '#ffffff',\n                      labelTextOpacity: 0.5,\n                      labelBackgroundColor: 'black',\n                      labelBackgroundOpacity: 0.01,\n                      colorRange: [\n                        '#000000',\n                        '#222e54',\n                        '#448db2',\n                        '#68bf30',\n                        '#fdff54',\n                        '#FFFFFF',\n                      ],\n                      colorbarBackgroundColor: 'black',\n                      colorbarBackgroundOpacity: 0.01,\n                      colorbarPosition: 'topRight',\n                      trackBorderWidth: 0,\n                      trackBorderColor: 'black',\n                      heatmapValueScaling: 'log',\n                      showMousePosition: true,\n                      mousePositionColor: '#ff00ff',\n                      showTooltip: false,\n                      extent: 'full',\n                      zeroValueColor: null,\n                      scaleStartPercent: '0.00000',\n                      scaleEndPercent: '1.00000',\n                    },\n                    height: 500,\n                    uid: 'GjuZed1ySGW1IzZZqFB9BA',\n                    transforms: [\n                      {\n                        name: 'ICE',\n                        value: 'weight',\n                      },\n                    ],\n                  },\n                ],\n                options: {},\n              },\n            ],\n            right: [],\n            bottom: [],\n            whole: [],\n            gallery: [],\n          },\n          layout: {\n            w: 12,\n            h: 12,\n            x: 0,\n            y: 0,\n            moved: false,\n            static: false,\n          },\n        },\n      },\n      x: 0,\n      y: 0,\n      w: 8,\n      h: 2,\n    },\n    {\n      component: 'higlass',\n      coordinationScopes: {\n        genomicZoomX: 'A',\n        genomicZoomY: 'A',\n        genomicTargetX: 'A',\n        genomicTargetY: 'A',\n      },\n      props: {\n        hgViewConfig: {\n          uid: 'aa',\n          autocompleteSource: '/api/v1/suggest/?d=OHJakQICQD6gTD7skx4EWA&',\n          genomePositionSearchBox: {\n            autocompleteServer: '//higlass.io/api/v1',\n            autocompleteId: 'OHJakQICQD6gTD7skx4EWA',\n            chromInfoServer: '//higlass.io/api/v1',\n            chromInfoId: 'hg19',\n            visible: true,\n          },\n          chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',\n          tracks: {\n            top: [\n              {\n                type: 'horizontal-gene-annotations',\n                height: 60,\n                tilesetUid: 'OHJakQICQD6gTD7skx4EWA',\n                server: '//higlass.io/api/v1',\n                uid: 'OHJakQICQD6gTD7skx4EWA',\n                options: {\n                  name: 'Gene Annotations (hg19)',\n                  fontSize: 10,\n                  labelPosition: 'hidden',\n                  labelLeftMargin: 0,\n                  labelRightMargin: 0,\n                  labelTopMargin: 0,\n                  labelBottomMargin: 0,\n                  minHeight: 24,\n                  geneAnnotationHeight: 16,\n                  geneLabelPosition: 'outside',\n                  geneStrandSpacing: 4,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                  plusStrandColor: '#fdff54',\n                  minusStrandColor: '#68bf30',\n                  labelColor: 'black',\n                  trackBorderWidth: 0,\n                  trackBorderColor: 'black',\n                },\n              },\n              {\n                chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',\n                type: 'horizontal-chromosome-labels',\n                height: 30,\n                uid: 'X4e_1DKiQHmyghDa6lLMVA',\n                options: {\n                  color: '#808080',\n                  stroke: 'black',\n                  fontSize: 12,\n                  fontIsLeftAligned: false,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                },\n              },\n            ],\n            left: [\n              {\n                type: 'vertical-gene-annotations',\n                width: 60,\n                tilesetUid: 'OHJakQICQD6gTD7skx4EWA',\n                server: '//higlass.io/api/v1',\n                options: {\n                  labelPosition: 'bottomRight',\n                  name: 'Gene Annotations (hg19)',\n                  fontSize: 10,\n                  labelLeftMargin: 0,\n                  labelRightMargin: 0,\n                  labelTopMargin: 0,\n                  labelBottomMargin: 0,\n                  minWidth: 24,\n                  geneAnnotationHeight: 16,\n                  geneLabelPosition: 'outside',\n                  geneStrandSpacing: 4,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                  plusStrandColor: '#fdff54',\n                  minusStrandColor: '#68bf30',\n                  labelColor: 'black',\n                  trackBorderWidth: 0,\n                  trackBorderColor: 'black',\n                },\n                uid: 'dqBTMH78Rn6DeSyDBoAEXw',\n              },\n              {\n                chromInfoPath: '//s3.amazonaws.com/pkerp/data/hg19/chromSizes.tsv',\n                type: 'vertical-chromosome-labels',\n                width: 30,\n                uid: 'RHdQK4IRQ7yJeDmKWb7Pcg',\n                options: {\n                  color: '#777777',\n                  stroke: 'black',\n                  fontSize: 12,\n                  fontIsLeftAligned: false,\n                  minWidth: 35,\n                  showMousePosition: true,\n                  mousePositionColor: '#ff00ff',\n                },\n              },\n            ],\n            center: [\n              {\n                uid: 'c1',\n                type: 'combined',\n                height: 600,\n                contents: [\n                  {\n                    server: '//higlass.io/api/v1',\n                    tilesetUid: 'CQMd6V_cRw6iCI_-Unl3PQ',\n                    type: 'heatmap',\n                    options: {\n                      maxZoom: null,\n                      labelPosition: 'bottomRight',\n                      name: 'Rao et al. (2014) GM12878 MboI (allreps) 1kb',\n                      backgroundColor: 'black',\n                      labelLeftMargin: 0,\n                      labelRightMargin: 0,\n                      labelTopMargin: 0,\n                      labelBottomMargin: 0,\n                      labelShowResolution: true,\n                      labelShowAssembly: true,\n                      labelColor: '#ffffff',\n                      labelTextOpacity: 0.5,\n                      labelBackgroundColor: 'black',\n                      labelBackgroundOpacity: 0.01,\n                      colorRange: [\n                        '#000000',\n                        '#222e54',\n                        '#448db2',\n                        '#68bf30',\n                        '#fdff54',\n                        '#FFFFFF',\n                      ],\n                      colorbarBackgroundColor: 'black',\n                      colorbarBackgroundOpacity: 0.01,\n                      colorbarPosition: 'topRight',\n                      trackBorderWidth: 0,\n                      trackBorderColor: 'black',\n                      heatmapValueScaling: 'log',\n                      showMousePosition: true,\n                      mousePositionColor: '#ff00ff',\n                      showTooltip: false,\n                      extent: 'full',\n                      zeroValueColor: null,\n                      scaleStartPercent: '0.00000',\n                      scaleEndPercent: '1.00000',\n                    },\n                    height: 500,\n                    uid: 'GjuZed1ySGW1IzZZqFB9BA',\n                    transforms: [\n                      {\n                        name: 'ICE',\n                        value: 'weight',\n                      },\n                    ],\n                  },\n                ],\n                options: {},\n              },\n            ],\n            right: [],\n            bottom: [],\n            whole: [],\n            gallery: [],\n          },\n          layout: {\n            w: 12,\n            h: 12,\n            x: 0,\n            y: 0,\n            moved: false,\n            static: false,\n          },\n        },\n      },\n      x: 8,\n      y: 0,\n      w: 4,\n      h: 2,\n    },\n  ],\n};\n","\n\nexport const scAtacSeq10xPbmc = {\n  version: '1.0.0',\n  name: 'HiGlass serverless demo with 10x Genomics scATAC-seq 5k PBMC dataset',\n  datasets: [\n    {\n      uid: '10x-genomics-pbmc',\n      name: '10x Genomics PBMC',\n      files: [\n        {\n          type: 'genomic-profiles',\n          fileType: 'genomic-profiles.zarr',\n          url: 'http://higlass-serverless.s3.amazonaws.com/multivec/pbmc_10x_peaks_by_cluster.zarr',\n        },\n      ],\n    },\n  ],\n  layout: [\n    {\n      component: 'genomicProfiles',\n      props: {\n        profileTrackUidKey: 'file',\n      },\n      x: 0,\n      y: 0,\n      w: 8,\n      h: 2,\n    },\n    {\n      component: 'description',\n      props: {\n        description: '10x Genomics scATAC-seq of 5k PBMCs. Note: the Zarr HiGlass Plugin Datafetcher is not yet optimized. Please be patient while the HiGlass tracks load.',\n      },\n      x: 8,\n      y: 0,\n      w: 4,\n      h: 2,\n    },\n  ],\n  initStrategy: 'auto',\n};\n","export const TOOLTIP_ANCESTOR = 'tooltip-ancestor';\nconst CARD = `card card-body my-2 ${TOOLTIP_ANCESTOR}`;\nexport const PRIMARY_CARD = `${CARD} bg-primary`;\nexport const SECONDARY_CARD = `${CARD} bg-secondary`;\nexport const BLACK_CARD = `${CARD} bg-black`;\nexport const TITLE_CARD = 'title';\nexport const SCROLL_CARD = `${PRIMARY_CARD} scroll`;\nexport const VITESSCE_CONTAINER = 'vitessce-container';\n","import React from 'react';\nimport { PRIMARY_CARD } from '../components/classNames';\n\nexport default function Warning(props) {\n  const {\n    title,\n    preformatted,\n    unformatted,\n    theme,\n  } = props;\n  return (\n    <div className={`vitessce-container vitessce-theme-${theme}`}>\n      <div className=\"warning-layout container-fluid\">\n        <div className=\"row\">\n          <div className=\"col-12\">\n            <div className={PRIMARY_CARD}>\n              <h1>{title}</h1>\n              <pre>{preformatted}</pre>\n              <div>{unformatted}</div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}\n","import { makeStyles, createTheme } from '@material-ui/core/styles';\nimport { grey } from '@material-ui/core/colors';\n\nexport const styles = makeStyles(() => ({\n  paper: {\n    maxHeight: 200,\n    overflow: 'auto',\n  },\n  container: {\n    position: 'relative',\n    left: 0,\n    top: 0,\n  },\n  span: {\n    width: '70px',\n    textAlign: 'center',\n    paddingLeft: '2px',\n    paddingRight: '2px',\n  },\n}));\n\nexport const muiTheme = {\n  dark: createTheme({\n    palette: {\n      type: 'dark',\n      primary: grey,\n      secondary: grey,\n      primaryBackground: '#222222',\n      primaryBackgroundHighlight: '#000000',\n      primaryBackgroundInput: '#D3D3D3',\n      primaryBackgroundDim: '#333333',\n      primaryBackgroundLight: '#757575',\n      primaryForeground: '#D3D3D3',\n      primaryForegroundDim: '#000000',\n      primaryForegroundActive: '#9bb7d6',\n      secondaryBackground: '#000000',\n      secondaryBackgroundDim: '#444444',\n      secondaryForeground: '#D3D3D3',\n    },\n    props: {\n      MuiButtonBase: {\n        disableRipple: true,\n      },\n    },\n  }),\n  light: createTheme({\n    palette: {\n      type: 'light',\n      primary: grey,\n      secondary: grey,\n      primaryBackground: '#F1F1F1',\n      primaryBackgroundHighlight: '#FFFFFF',\n      primaryBackgroundInput: '#FFFFFF',\n      primaryBackgroundDim: '#8A8A8A',\n      primaryBackgroundLight: '#e0e0e0',\n      primaryForeground: '#333333',\n      primaryForegroundDim: '#808080',\n      primaryForegroundActive: '#0074D9',\n      secondaryBackground: '#F1F1F1',\n      secondaryBackgroundDim: '#C0C0C0',\n      secondaryForeground: '#222222',\n    },\n    props: {\n      MuiButtonBase: {\n        disableRipple: true,\n      },\n    },\n  }),\n};\n","import { useRef, useCallback, useMemo } from 'react';\nimport create from 'zustand';\nimport createContext from 'zustand/context';\nimport shallow from 'zustand/shallow';\nimport { fromEntries, capitalize } from '../../utils';\n\n// Reference: https://github.com/pmndrs/zustand#react-context\n// Reference: https://github.com/pmndrs/zustand/blob/e47ea03/tests/context.test.tsx#L60\nconst {\n  Provider: ViewConfigProviderLocal,\n  useStore: useViewConfigStoreLocal,\n  useStoreApi: useViewConfigStoreApiLocal,\n} = createContext();\n\nexport const ViewConfigProvider = ViewConfigProviderLocal;\nexport const useViewConfigStore = useViewConfigStoreLocal;\nexport const useViewConfigStoreApi = useViewConfigStoreApiLocal;\n\nconst {\n  Provider: AuxiliaryProviderLocal,\n  useStore: useAuxiliaryStoreLocal,\n} = createContext();\n\nexport const AuxiliaryProvider = AuxiliaryProviderLocal;\nexport const useAuxiliaryStore = useAuxiliaryStoreLocal;\n\n\n/**\n * The useViewConfigStore hook is initialized via the zustand\n * create() function, which sets up both the state variables\n * and the reducer-type functions.\n * Reference: https://github.com/react-spring/zustand\n * @returns {function} The useStore hook.\n */\nexport const createViewConfigStore = () => create(set => ({\n  // State:\n  // The viewConfig is an object which must conform to the schema\n  // found in src/schemas/config.schema.json.\n  viewConfig: null,\n  // The loaders object is a mapping from dataset ID to\n  // data type to loader object instance.\n  loaders: null,\n  // Reducer functions which update the state\n  // (although technically also part of state):\n  setViewConfig: viewConfig => set({ viewConfig }),\n  setLoaders: loaders => set({ loaders }),\n  setCoordinationValue: ({ parameter, scope, value }) => set(state => ({\n    viewConfig: {\n      ...state.viewConfig,\n      coordinationSpace: {\n        ...state.viewConfig.coordinationSpace,\n        [parameter]: {\n          ...state.viewConfig.coordinationSpace[parameter],\n          [scope]: value,\n        },\n      },\n    },\n  })),\n  removeComponent: i => set((state) => {\n    const newLayout = state.viewConfig.layout.slice();\n    newLayout.splice(i, 1);\n    return {\n      viewConfig: {\n        ...state.viewConfig,\n        layout: newLayout,\n      },\n    };\n  }),\n  changeLayout: newComponentProps => set((state) => {\n    const newLayout = state.viewConfig.layout.slice();\n    newComponentProps.forEach(([i, newProps]) => {\n      newLayout[i] = {\n        ...newLayout[i],\n        ...newProps,\n      };\n    });\n    return {\n      viewConfig: {\n        ...state.viewConfig,\n        layout: newLayout,\n      },\n    };\n  }),\n}));\n\n/**\n * Hook for getting components' layout from the view config based on\n * matching all coordination scopes.\n * @returns {Object} The components' layout.\n */\nexport const useComponentLayout = (component, scopes, coordinationScopes) => useViewConfigStore(\n  state => state.viewConfig.layout.filter(l => l.component === component).filter(\n    l => scopes.every(scope => l.coordinationScopes[scope]\n          === coordinationScopes[scope]),\n  ),\n);\n\n/**\n * The useAuxiliaryStore hook is initialized via the zustand\n * create() function, which sets up both the state variables\n * and the reducer-type functions.\n * Reference: https://github.com/react-spring/zustand\n * It is meant to be used for non-viewconfig-based coordination between components.\n * For example, as currently happens, the layer controller can coordinate\n * on-load callbacks with spatial view based on whether or not they are\n * coordinated via `spatialRasterLayers` - the callbacks are not part of the view config\n * though so they live here.\n * @returns {function} The useStore hook.\n */\nexport const createAuxiliaryStore = () => create(set => ({\n  auxiliaryStore: null,\n  setCoordinationValue: ({ parameter, scope, value }) => set(state => ({\n    auxiliaryStore: {\n      ...state.auxiliaryStore,\n      [parameter]: {\n        [scope]: value,\n      },\n    },\n  })),\n}));\n\n/**\n * The hover store can be used to store global state\n * related to which component is currently hovered,\n * which is required for tooltip / crossover elements.\n * @returns {function} The useStore hook.\n */\nconst useHoverStore = create(set => ({\n  // Components may need to know if they are the \"hover source\"\n  // for tooltip interactions. This value should be a unique\n  // component ID, such as its index in the view config layout.\n  componentHover: null,\n  setComponentHover: componentHover => set({ componentHover }),\n}));\n\n/**\n * The warning store can be used to store global state\n * related to app warning messages.\n * @returns {function} The useStore hook.\n */\nconst useWarnStore = create(set => ({\n  // Want a global state to collect warning messages\n  // that occur anywhere in the app.\n  warning: null,\n  setWarning: warning => set({ warning }),\n}));\n\n/**\n * The view info store can be used to store component-level\n * viewInfo objects,\n * which are required for tooltip / crossover elements.\n * @returns {function} The useStore hook.\n */\nconst useViewInfoStore = create(set => ({\n  // The viewInfo object is a mapping from\n  // component IDs to component view info objects.\n  // Each view info object must have a project() function.\n  viewInfo: {},\n  setComponentViewInfo: (uuid, viewInfo) => set(state => ({\n    viewInfo: {\n      ...state.viewInfo,\n      [uuid]: viewInfo,\n    },\n  })),\n}));\n\n/**\n * The grid size store can be used to store a\n * counter which updates on each window or react-grid-layout\n * resize event.\n * @returns {function} The useStore hook.\n */\nconst useGridSizeStore = create(set => ({\n  resizeCount: {},\n  incrementResizeCount: () => set(state => ({\n    resizeCount: state.resizeCount + 1,\n  })),\n}));\n\n/**\n * The useCoordination hook returns both the\n * values and setter functions for the coordination objects\n * in a particular coordination scope mapping.\n * This hook is intended to be used within the ___Subscriber\n * components to allow them to \"hook into\" only those coordination\n * objects and setter functions of relevance.\n * @param {string[]} parameters Array of coordination types.\n * @param {object} coordinationScopes Mapping of coordination types\n * to scope names.\n * @returns {array} Returns a tuple [values, setters]\n * where values is an object containing all coordination values,\n * and setters is an object containing all coordination setter\n * functions for the values in `values`, named with a \"set\"\n * prefix.\n */\nexport function useCoordination(parameters, coordinationScopes) {\n  const setCoordinationValue = useViewConfigStore(state => state.setCoordinationValue);\n\n  const values = useViewConfigStore((state) => {\n    const { coordinationSpace } = state.viewConfig;\n    return fromEntries(parameters.map((parameter) => {\n      if (coordinationSpace && coordinationSpace[parameter]) {\n        const value = coordinationSpace[parameter][coordinationScopes[parameter]];\n        return [parameter, value];\n      }\n      return [parameter, undefined];\n    }));\n  }, shallow);\n\n  const setters = useMemo(() => fromEntries(parameters.map((parameter) => {\n    const setterName = `set${capitalize(parameter)}`;\n    const setterFunc = value => setCoordinationValue({\n      parameter,\n      scope: coordinationScopes[parameter],\n      value,\n    });\n    return [setterName, setterFunc];\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  })), [parameters, coordinationScopes]);\n\n  return [values, setters];\n}\n\nconst AUXILIARY_COORDINATION_TYPES_MAP = {\n  spatialRasterLayers: ['rasterLayersCallbacks', 'areLoadingRasterChannnels'],\n};\n\n/**\n * The maps the coordination types of incoming scopes to new types\n * for the auxiliary store.\n * @param {object} coordinationScopes Mapping of coordination types\n * to scope names.\n * @returns {object} Mapping of coordination types\n * to new scope names for the auxiliary store.\n */\nconst mapCoordinationScopes = (coordinationScopes) => {\n  const newCoordinationScopes = {};\n  Object.keys(coordinationScopes).forEach((key) => {\n    const newCoordinationTypes = AUXILIARY_COORDINATION_TYPES_MAP[key] || [];\n    newCoordinationTypes.forEach((coordinationType) => {\n      newCoordinationScopes[coordinationType || key] = coordinationScopes[key];\n    });\n  });\n  return newCoordinationScopes;\n};\n\nconst mapParameters = parameters => parameters\n  .map(parameter => AUXILIARY_COORDINATION_TYPES_MAP[parameter]).filter(Boolean).flat();\n\n/**\n * The useAuxiliaryCoordination hook returns both the\n * values and setter functions for the auxiliary coordination objects\n * in a particular coordination scope mapping.\n * This hook is intended to be used within the ___Subscriber\n * components to allow them to \"hook into\" only those auxiliary coordination\n * objects and setter functions of relevance, for example \"on load\" callbacks.\n * @param {string[]} parameters Array of coordination types.\n * @param {object} coordinationScopes Mapping of coordination types\n * to scope names.\n * @returns {array} Returns a tuple [values, setters]\n * where values is an object containing all coordination values,\n * and setters is an object containing all coordination setter\n * functions for the values in `values`, named with a \"set\"\n * prefix.\n */\nexport function useAuxiliaryCoordination(parameters, coordinationScopes) {\n  const setCoordinationValue = useAuxiliaryStore(state => state.setCoordinationValue);\n  const mappedCoordinationScopes = mapCoordinationScopes(coordinationScopes);\n  const mappedParameters = mapParameters(parameters);\n  const values = useAuxiliaryStore((state) => {\n    const { auxiliaryStore } = state;\n    return fromEntries(mappedParameters.map((parameter) => {\n      if (auxiliaryStore && auxiliaryStore[parameter]) {\n        const value = auxiliaryStore[parameter][mappedCoordinationScopes[parameter]];\n        return [parameter, value];\n      }\n      return [parameter, undefined];\n    }));\n  }, shallow);\n  const setters = useMemo(() => fromEntries(mappedParameters.map((parameter) => {\n    const setterName = `set${capitalize(parameter)}`;\n    const setterFunc = value => setCoordinationValue({\n      parameter,\n      scope: mappedCoordinationScopes[parameter],\n      value,\n    });\n    return [setterName, setterFunc];\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  })), [parameters, coordinationScopes]);\n\n  return [values, setters];\n}\n\n/**\n * Obtain the loaders object from\n * the global app state.\n * @returns {object} The loaders object\n * in the `useViewConfigStore` store.\n */\nexport function useLoaders() {\n  return useViewConfigStore(state => state.loaders);\n}\n\n/**\n * Obtain the view config layout array from\n * the global app state.\n * @returns {object[]} The layout array\n * in the `useViewConfigStore` store.\n */\nexport function useLayout() {\n  return useViewConfigStore(state => state.viewConfig?.layout);\n}\n\n/**\n * Obtain the component removal function from\n * the global app state.\n * @returns {function} The remove component function\n * in the `useViewInfoStore` store.\n */\nexport function useRemoveComponent() {\n  return useViewConfigStore(state => state.removeComponent);\n}\n\n/**\n * Obtain the component prop setter function from\n * the global app state.\n * @returns {function} The set component props function\n * in the `useViewInfoStore` store.\n */\nexport function useChangeLayout() {\n  return useViewConfigStore(state => state.changeLayout);\n}\n\n/**\n * Obtain the loaders setter function from\n * the global app state.\n * @returns {function} The loaders setter function\n * in the `useViewConfigStore` store.\n */\nexport function useSetLoaders() {\n  return useViewConfigStore(state => state.setLoaders);\n}\n\n/**\n * Obtain the view config setter function from\n * the global app state.\n * @returns {function} The view config setter function\n * in the `useViewConfigStore` store.\n */\nexport function useSetViewConfig(viewConfigStoreApi) {\n  const setViewConfigRef = useRef(viewConfigStoreApi.getState().setViewConfig);\n  const setViewConfig = setViewConfigRef.current;\n  return setViewConfig;\n}\n\n/**\n * Obtain the component hover value from\n * the global app state.\n * @returns {number} The hovered component ID\n * in the `useHoverStore` store.\n */\nexport function useComponentHover() {\n  return useHoverStore(state => state.componentHover);\n}\n\n/**\n * Obtain the component hover setter function from\n * the global app state.\n * @returns {function} The component hover setter function\n * in the `useHoverStore` store.\n */\nexport function useSetComponentHover() {\n  return useHoverStore(state => state.setComponentHover);\n}\n\n/**\n * Obtain the warning message from\n * the global app state.\n * @returns {string} The warning message\n * in the `useWarnStore` store.\n */\nexport function useWarning() {\n  return useWarnStore(state => state.warning);\n}\n\n/**\n * Obtain the warning setter function from\n * the global app state.\n * @returns {function} The warning setter function\n * in the `useWarnStore` store.\n */\nexport function useSetWarning() {\n  return useWarnStore(state => state.setWarning);\n}\n\n/**\n * Obtain the component view info value from\n * the global app state.\n * @returns {object} The view info object for the component\n * in the `useViewInfoStore` store.\n */\nexport function useComponentViewInfo(uuid) {\n  return useViewInfoStore(useCallback(state => state.viewInfo[uuid], [uuid]));\n}\n\n/**\n * Obtain the component view info setter function from\n * the global app state.\n * @returns {function} The component view info setter function\n * in the `useViewInfoStore` store.\n */\nexport function useSetComponentViewInfo(uuid) {\n  const setViewInfoRef = useRef(useViewInfoStore.getState().setComponentViewInfo);\n  const setComponentViewInfo = viewInfo => setViewInfoRef.current(uuid, viewInfo);\n  return setComponentViewInfo;\n}\n\n/**\n * Obtain the grid resize count value\n * from the global app state.\n * @returns {number} The grid resize increment value.\n */\nexport function useGridResize() {\n  return useGridSizeStore(state => state.resizeCount);\n}\n\n/**\n * Obtain the grid resize count increment function\n * from the global app state.\n * @returns {function} The grid resize count increment\n * function.\n */\nexport function useEmitGridResize() {\n  return useGridSizeStore(state => state.incrementResizeCount);\n}\n","import range from 'lodash/range';\n\nexport const COMPONENT_ID_PREFIX = 'i';\n\nfunction sum(a) {\n  return a.reduce((x, y) => x + y, 0);\n}\n\nexport function makeGridLayout(colXs, colLayout) {\n  const colWs = [];\n  for (let i = 0; i < colXs.length; i++) { // eslint-disable-line no-plusplus\n    colWs.push(colXs[i + 1] - colXs[i]);\n  }\n  return Object.entries(colLayout).map(([id, spec]) => ({\n    i: id,\n    y: spec.y,\n    h: spec.h || 1,\n    x: colXs[spec.x],\n    w: sum(colWs.slice(spec.x, spec.x + (spec.w || 1))),\n  }));\n}\n\nexport function getMaxRows(layouts) {\n  return Math.max(\n    ...Object.values(layouts).map(\n      layout => Math.max(\n        ...layout.map(xywh => xywh.y + xywh.h),\n      ),\n    ),\n  );\n}\n\nexport function resolveLayout(layout) {\n  const cols = {};\n  const layouts = {};\n  const breakpoints = {};\n  const components = {};\n  const positions = {};\n\n  (('components' in layout) ? layout.components : layout).forEach(\n    (def, i) => {\n      const id = `${COMPONENT_ID_PREFIX}${i}`;\n      components[id] = {\n        component: def.component,\n        props: def.props || {},\n        coordinationScopes: def.coordinationScopes || {},\n      };\n      positions[id] = {\n        id, x: def.x, y: def.y, w: def.w, h: def.h,\n      };\n    },\n  );\n\n  if ('components' in layout) {\n    Object.entries(layout.columns).forEach(\n      ([width, columnXs]) => {\n        cols[width] = columnXs[columnXs.length - 1];\n        layouts[width] = makeGridLayout(columnXs, positions);\n        breakpoints[width] = width;\n      },\n    );\n  } else {\n    // static layout\n    const id = 'ID';\n    const columnCount = 12;\n    cols[id] = columnCount;\n    layouts[id] = makeGridLayout(range(columnCount + 1), positions);\n    breakpoints[id] = 1000;\n    // Default has different numbers of columns at different widths,\n    // so we do need to override that to ensure the same number of columns,\n    // regardless of window width.\n  }\n  return {\n    cols, layouts, breakpoints, components,\n  };\n}\n","import React from 'react';\nimport { Responsive, WidthProvider } from 'react-grid-layout';\nimport isEqual from 'lodash/isEqual';\nimport { getMaxRows, resolveLayout, COMPONENT_ID_PREFIX } from './layout-utils';\n\nconst ResponsiveGridLayout = WidthProvider(Responsive);\n\nclass ResponsiveHeightGridLayout extends ResponsiveGridLayout {\n  componentDidUpdate(prevProps) {\n    if (this.props.height !== prevProps.height) {\n      this.onWindowResize();\n    }\n  }\n}\n\nexport default function VitessceGridLayout(props) {\n  const {\n    layout,\n    getComponent, padding, margin, draggableHandle,\n    reactGridLayoutProps, rowHeight, theme, height,\n    onRemoveComponent, onLayoutChange: onLayoutChangeProp,\n  } = props;\n\n  // If layout changes, update grid components.\n  const {\n    cols: gridCols, layouts: gridLayouts, breakpoints: gridBreakpoints, components: gridComponents,\n  } = resolveLayout(layout);\n\n  const maxRows = getMaxRows(gridLayouts);\n\n  // Inline CSS is generally avoided, but this saves the end-user a little work,\n  // and prevents class names from getting out of sync.\n  const style = (\n    <style>\n      {`\n        ${draggableHandle} {\n          cursor: grab;\n        }\n        ${draggableHandle}:active {\n          cursor: grabbing;\n        }\n     `}\n    </style>\n  );\n\n  const onLayoutChange = (newLayout) => {\n    if (newLayout.length === Object.entries(gridComponents).length) {\n      const newComponentProps = [];\n      newLayout.forEach((nextC) => {\n        const id = nextC.i;\n        const prevC = gridComponents[id];\n        if (prevC) {\n          const i = parseInt(id.substring(id.indexOf(COMPONENT_ID_PREFIX) + 1), 10);\n          const nextProps = {\n            x: nextC.x, y: nextC.y, w: nextC.w, h: nextC.h,\n          };\n          const prevProps = {\n            x: prevC.x, y: prevC.y, w: prevC.w, h: prevC.h,\n          };\n          if (!isEqual(nextProps, prevProps)) {\n            newComponentProps.push([i, nextProps]);\n          }\n        }\n      });\n      if (newComponentProps.length > 0) {\n        onLayoutChangeProp(newComponentProps);\n      }\n    }\n  };\n\n  const layoutChildren = Object.entries(gridComponents).map(([k, v], i) => {\n    const Component = getComponent(v.component);\n\n    const removeGridComponent = () => {\n      onRemoveComponent(i);\n    };\n\n    return (\n      <div key={k}>\n        <Component\n          {... v.props}\n          uuid={i}\n          coordinationScopes={v.coordinationScopes}\n          theme={theme}\n          removeGridComponent={removeGridComponent}\n        />\n      </div>\n    );\n  });\n  return (gridLayouts && gridComponents && gridBreakpoints && gridCols) && (\n    <>\n      {style}\n      <ResponsiveHeightGridLayout\n        className=\"layout\"\n        cols={gridCols}\n        layouts={gridLayouts}\n        breakpoints={gridBreakpoints}\n        height={height}\n        rowHeight={\n          rowHeight\n          || (\n            (window.innerHeight - 2 * padding - (maxRows - 1) * margin)\n            / maxRows\n          )}\n        containerPadding={[padding, padding]}\n        margin={[margin, margin]}\n        draggableHandle={draggableHandle}\n        onLayoutChange={onLayoutChange}\n        {... reactGridLayoutProps}\n      >\n        {layoutChildren}\n      </ResponsiveHeightGridLayout>\n    </>\n  );\n}\n\nVitessceGridLayout.defaultProps = {\n  padding: 10,\n  margin: 10,\n};\n","import AbstractLoader from './AbstractLoader';\n\nexport default class AbstractTwoStepLoader extends AbstractLoader {\n  constructor(dataSource, params) {\n    super(params);\n    this.dataSource = dataSource;\n  }\n}\n","import uuidv4 from 'uuid/v4';\n\n/**\n * A loader ancestor class containing a default constructor\n * and a stub for the required load() method.\n */\nexport default class AbstractLoader {\n  constructor({\n    type, url, requestInit, options,\n  }) {\n    this.type = type;\n    this.url = url;\n    this.requestInit = requestInit;\n    this.options = options;\n\n    this.subscriptions = {};\n  }\n\n  // eslint-disable-next-line class-methods-use-this\n  load() {\n    throw new Error('The load() method has not been implemented.');\n  }\n\n  subscribe(subscriber) {\n    const token = uuidv4();\n    this.subscriptions[token] = subscriber;\n    return token;\n  }\n\n  unsubscribe(token) {\n    delete this.subscriptions[token];\n  }\n\n  publish(data) {\n    Object.values(this.subscriptions).forEach((subscriber) => {\n      subscriber(data);\n    });\n  }\n}\n","/**\n * A loader error ancestor class containing a default constructor\n * and a stub for the required warnInConsole() method.\n */\nexport default class AbstractLoaderError {\n  constructor(message) {\n    this.message = message;\n  }\n\n  // eslint-disable-next-line class-methods-use-this\n  warnInConsole() {\n    throw new Error('The warnInConsole() method has not been implemented.');\n  }\n}\n","import AbstractLoaderError from './AbstractLoaderError';\n\nexport default class LoaderValidationError extends AbstractLoaderError {\n  constructor(datasetType, datasetFileType, datasetUrl, reason) {\n    super(`Error while validating ${datasetType}.`);\n    this.name = 'LoaderValidationError';\n\n    this.datasetType = datasetType;\n    this.datasetFileType = datasetFileType;\n    this.datasetUrl = datasetUrl;\n    this.reason = reason;\n  }\n\n  warnInConsole() {\n    const {\n      datasetType, datasetUrl, reason,\n    } = this;\n    console.warn(\n      `${datasetType} from ${datasetUrl}: validation failed`,\n      JSON.stringify(reason, null, 2),\n    );\n  }\n}\n","import AbstractLoaderError from './AbstractLoaderError';\n\nexport default class LoaderNotFoundError extends AbstractLoaderError {\n  constructor(datasetType, datasetFileType, datasetUrl) {\n    super(`Error finding loader for ${datasetType}.`);\n    this.name = 'LoaderNotFoundError';\n\n    this.datasetType = datasetType;\n    this.datasetFileType = datasetFileType;\n    this.datasetUrl = datasetUrl;\n  }\n\n  warnInConsole() {\n    const {\n      datasetType, datasetFileType, datasetUrl,\n    } = this;\n    if (datasetFileType && datasetUrl) {\n      console.warn(\n        `${datasetType} from ${datasetUrl}: unable to find loader for fileType ${datasetFileType}`,\n      );\n    } else {\n      console.warn(\n        `${datasetType}: unable to find loader`,\n      );\n    }\n  }\n}\n","\n\nexport default class LoaderResult {\n  constructor(data, url, coordinationValues = null) {\n    this.data = data;\n    this.url = url;\n    this.coordinationValues = coordinationValues;\n  }\n}\n","import Ajv from 'ajv';\nimport AbstractTwoStepLoader from './AbstractTwoStepLoader';\nimport { LoaderValidationError, AbstractLoaderError } from './errors/index';\nimport LoaderResult from './LoaderResult';\n\nimport cellsSchema from '../schemas/cells.schema.json';\nimport moleculesSchema from '../schemas/molecules.schema.json';\nimport neighborhoodsSchema from '../schemas/neighborhoods.schema.json';\nimport rasterSchema from '../schemas/raster.schema.json';\nimport cellSetsSchema from '../schemas/cell-sets.schema.json';\n\nconst typeToSchema = {\n  cells: cellsSchema,\n  molecules: moleculesSchema,\n  neighborhoods: neighborhoodsSchema,\n  raster: rasterSchema,\n  'cell-sets': cellSetsSchema,\n};\n\nexport default class JsonLoader extends AbstractTwoStepLoader {\n  constructor(dataSource, params) {\n    super(dataSource, params);\n\n    const { type } = params;\n    this.schema = typeToSchema[type];\n  }\n\n  load() {\n    const {\n      url, type, fileType,\n    } = this;\n    if (this.data) {\n      return this.data;\n    }\n    this.data = this.dataSource.data\n      .then((data) => {\n        if (data instanceof AbstractLoaderError) {\n          return Promise.reject(data);\n        }\n        const [valid, reason] = this.validate(data);\n        if (valid) {\n          return Promise.resolve(new LoaderResult(data, url));\n        }\n        return Promise.reject(new LoaderValidationError(type, fileType, url, reason));\n      });\n    return this.data;\n  }\n\n  validate(data) {\n    const { schema, type } = this;\n    if (!schema) {\n      throw Error(`No schema for ${type}`);\n    }\n    const validate = new Ajv().compile(schema);\n    const valid = validate(data);\n    let failureReason;\n    if (!valid) {\n      failureReason = validate.errors;\n    }\n    return [valid, failureReason];\n  }\n}\n","import { openArray } from 'zarr';\nimport AbstractTwoStepLoader from './AbstractTwoStepLoader';\nimport LoaderResult from './LoaderResult';\n\nexport default class MatrixZarrLoader extends AbstractTwoStepLoader {\n  loadAttrs() {\n    if (this.attrs) {\n      return this.attrs;\n    }\n    this.attrs = this.dataSource.getJson('.zattrs');\n    return this.attrs;\n  }\n\n  loadArr() {\n    const { store } = this.dataSource;\n    if (this.arr) {\n      return this.arr;\n    }\n    this.arr = openArray({ store, path: '/', mode: 'r' }).then(z => new Promise((resolve) => {\n      z.getRaw([null, null])\n        .then(resolve);\n    }));\n    return this.arr;\n  }\n\n  load() {\n    return Promise\n      .all([this.loadAttrs(), this.loadArr()])\n      .then(data => Promise.resolve(new LoaderResult(data, null)));\n  }\n}\n","import genesSchema from '../schemas/genes.schema.json';\nimport JsonLoader from './JsonLoader';\nimport { AbstractLoaderError } from './errors';\nimport LoaderResult from './LoaderResult';\n\nexport default class GenesJsonAsMatrixZarrLoader extends JsonLoader {\n  constructor(dataSource, params) {\n    super(dataSource, params);\n\n    this.schema = genesSchema;\n  }\n\n  async load() {\n    const payload = await super.load().catch(reason => Promise.resolve(reason));\n    if (payload instanceof AbstractLoaderError) {\n      return Promise.reject(payload);\n    }\n    const { data, url } = payload;\n    const cols = Object.keys(data);\n    const rows = (cols.length > 0 ? Object.keys(data[cols[0]].cells) : []);\n    const attrs = { rows, cols };\n\n    const normalizedFlatMatrix = rows\n      .flatMap(cellId => cols.map(\n        geneId => (data[geneId].cells[cellId] / data[geneId].max) * 255,\n      ));\n    // Need to wrap the NestedArray to mock the HTTPStore-based array\n    // which returns promises.\n    const arr = { data: Uint8Array.from(normalizedFlatMatrix) };\n    return Promise.resolve(new LoaderResult([attrs, arr], url));\n  }\n}\n","import { extent } from 'd3-array';\nimport range from 'lodash/range';\nimport clustersSchema from '../schemas/clusters.schema.json';\nimport JsonLoader from './JsonLoader';\nimport { AbstractLoaderError } from './errors';\nimport LoaderResult from './LoaderResult';\n\nexport default class ClustersJsonAsMatrixZarrLoader extends JsonLoader {\n  constructor(dataSource, params) {\n    super(dataSource, params);\n\n    this.schema = clustersSchema;\n  }\n\n  async load() {\n    const payload = await super.load().catch(reason => Promise.resolve(reason));\n    if (payload instanceof AbstractLoaderError) {\n      return Promise.reject(payload);\n    }\n    const { data, url } = payload;\n    const { rows, cols, matrix } = data;\n    const attrs = {\n      rows: cols,\n      cols: rows,\n    };\n    const shape = [attrs.rows.length, attrs.cols.length];\n    // Normalize values by converting to one-byte integers.\n    // Normalize for each gene (column) independently.\n    const normalizedMatrix = matrix.map((col) => {\n      const [min, max] = extent(col);\n      const normalize = d => Math.floor(((d - min) / (max - min)) * 255);\n      return col.map(normalize);\n    });\n    // Transpose the normalized matrix.\n    const tNormalizedMatrix = range(shape[0])\n      .map(i => range(shape[1]).map(j => normalizedMatrix[j][i]));\n    // Flatten the transposed matrix.\n    const normalizedFlatMatrix = tNormalizedMatrix.flat();\n    // Need to wrap the NestedArray to mock the HTTPStore-based array\n    // which returns promises.\n    const arr = { data: Uint8Array.from(normalizedFlatMatrix) };\n    return Promise.resolve(new LoaderResult([attrs, arr], url));\n  }\n}\n","import cellSetsSchema from '../../schemas/cell-sets.schema.json';\nimport cellSetsTabularSchema from '../../schemas/cell-sets-tabular.schema.json';\n\nexport const FILE_EXTENSION_JSON = 'json';\nexport const MIME_TYPE_JSON = 'application/json';\n\nexport const FILE_EXTENSION_TABULAR = 'csv';\nexport const MIME_TYPE_TABULAR = 'text/csv';\nexport const SEPARATOR_TABULAR = ',';\n// The NA value below corresponds to the allowed string enum\n// value \"NA\" in the cell-sets-tabular JSON schema.\nexport const NA_VALUE_TABULAR = 'NA';\n\nexport const SETS_DATATYPE_CELL = 'cell';\nexport const HIERARCHICAL_SCHEMAS = {\n  cell: {\n    latestVersion: '0.1.3',\n    schema: cellSetsSchema,\n  },\n};\n\nexport const TABULAR_SCHEMAS = {\n  cell: {\n    schema: cellSetsTabularSchema,\n  },\n};\n","import React from 'react';\nimport { COORDINATE_SYSTEM } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport {\n  SETS_DATATYPE_CELL,\n  HIERARCHICAL_SCHEMAS,\n} from './sets/constants';\nimport { PRIMARY_CARD } from './classNames';\n\nexport function makeCellStatusMessage(cellInfoFactors) {\n  return Object.entries(cellInfoFactors).map(\n    ([factor, value]) => `${factor}: ${value}`,\n  ).join('; ');\n}\n\nexport function cellLayerDefaultProps(cells, updateStatus, setCellHighlight, setComponentHover) {\n  return {\n    coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n    data: cells,\n    pickable: true,\n    autoHighlight: true,\n    stroked: true,\n    filled: true,\n    getElevation: 0,\n    onHover: (info) => {\n      // Notify the parent component that its child component is\n      // the \"hover source\".\n      if (setComponentHover) {\n        setComponentHover();\n      }\n      if (info.object) {\n        const [cellId, cellInfo] = info.object;\n        const { factors = {} } = cellInfo;\n        if (updateStatus) {\n          updateStatus(makeCellStatusMessage(factors));\n        }\n        if (setCellHighlight) {\n          setCellHighlight(cellId);\n        }\n      } else if (setCellHighlight) {\n        // Clear the currently-hovered cell info by passing null.\n        setCellHighlight('');\n      }\n    },\n  };\n}\n\nexport const DEFAULT_DARK_COLOR = [50, 50, 50];\nexport const DEFAULT_LIGHT_COLOR = [200, 200, 200];\n\nexport function getDefaultColor(theme) {\n  return theme === 'dark' ? DEFAULT_DARK_COLOR : DEFAULT_LIGHT_COLOR;\n}\n\n// From https://personal.sron.nl/~pault/#sec:qualitative\nexport const PALETTE = [\n  [68, 119, 170],\n  [136, 204, 238],\n  [68, 170, 153],\n  [17, 119, 51],\n  [153, 153, 51],\n  [221, 204, 119],\n  [204, 102, 119],\n  [136, 34, 85],\n  [170, 68, 153],\n];\n\nexport const VIEWER_PALETTE = [\n  [0, 0, 255],\n  [0, 255, 0],\n  [255, 0, 255],\n  [255, 255, 0],\n  [0, 255, 255],\n  [255, 255, 255],\n  [255, 128, 0],\n  [255, 0, 0],\n];\n\nexport const COLORMAP_OPTIONS = [\n  'viridis',\n  'greys',\n  'magma',\n  'jet',\n  'hot',\n  'bone',\n  'copper',\n  'summer',\n  'density',\n  'inferno',\n];\n\nexport const DEFAULT_GL_OPTIONS = { webgl2: true };\n\nexport function createDefaultUpdateStatus(componentName) {\n  return message => console.warn(`${componentName} updateStatus: ${message}`);\n}\n\nexport function createDefaultUpdateCellsSelection(componentName) {\n  return cellsSelection => console.warn(`${componentName} updateCellsSelection: ${cellsSelection}`);\n}\n\nexport function createDefaultUpdateCellsHover(componentName) {\n  return hoverInfo => console.warn(`${componentName} updateCellsHover: ${hoverInfo.cellId}`);\n}\n\nexport function createDefaultUpdateGenesHover(componentName) {\n  return hoverInfo => console.warn(`${componentName} updateGenesHover: ${hoverInfo.geneId}`);\n}\n\nexport function createDefaultUpdateViewInfo(componentName) {\n  return viewInfo => console.warn(`${componentName} updateViewInfo: ${viewInfo}`);\n}\n\nexport function createDefaultClearPleaseWait() {\n  return () => {};\n}\n\n\n/**\n * Copy a typed array into a new array buffer.\n * @param {Uint8Array} arr The typed array to be copied.\n * @returns {Uint8Array} The copied array.\n */\nexport function copyUint8Array(arr) {\n  const newBuffer = new ArrayBuffer(arr.buffer.byteLength);\n  const newArr = new Uint8Array(newBuffer);\n  newArr.set(arr);\n  return newArr;\n}\n\nexport function getNextNumberedNodeName(nodes, prefix) {\n  let i = 1;\n  if (nodes) {\n    // eslint-disable-next-line no-loop-func\n    while (nodes.find(n => n.name === `${prefix}${i}`)) {\n      // eslint-disable-next-line no-plusplus\n      i++;\n    }\n  }\n  return `${prefix}${i}`;\n}\n\n/**\n * Create a new selected cell set based on a cell selection.\n * @param {string[]} cellSelection An array of cell IDs.\n * @param {object[]} additionalCellSets The previous array of user-defined cell sets.\n * @param {function} setCellSetSelection The setter function for cell set selections.\n * @param {function} setAdditionalCellSets The setter function for user-defined cell sets.\n */\nexport function setCellSelection(cellSelection, additionalCellSets, cellSetColor, setCellSetSelection, setAdditionalCellSets, setCellSetColor, setCellColorEncoding, prefix = 'Selection ') {\n  const CELL_SELECTIONS_LEVEL_ZERO_NAME = 'My Selections';\n\n  const selectionsLevelZeroNode = additionalCellSets?.tree.find(\n    n => n.name === CELL_SELECTIONS_LEVEL_ZERO_NAME,\n  );\n  const nextAdditionalCellSets = {\n    version: HIERARCHICAL_SCHEMAS[SETS_DATATYPE_CELL].latestVersion,\n    datatype: SETS_DATATYPE_CELL,\n    tree: [...(additionalCellSets ? additionalCellSets.tree : [])],\n  };\n\n  const nextName = getNextNumberedNodeName(selectionsLevelZeroNode?.children, prefix);\n  let colorIndex = 0;\n  if (selectionsLevelZeroNode) {\n    colorIndex = selectionsLevelZeroNode.children.length;\n    selectionsLevelZeroNode.children.push({\n      name: nextName,\n      set: cellSelection.map(d => [d, null]),\n    });\n  } else {\n    nextAdditionalCellSets.tree.push({\n      name: CELL_SELECTIONS_LEVEL_ZERO_NAME,\n      children: [\n        {\n          name: nextName,\n          set: cellSelection.map(d => [d, null]),\n        },\n      ],\n    });\n  }\n  setAdditionalCellSets(nextAdditionalCellSets);\n  const nextPath = ['My Selections', nextName];\n  setCellSetColor([\n    ...(cellSetColor || []),\n    {\n      path: nextPath,\n      color: PALETTE[colorIndex % PALETTE.length],\n    },\n  ]);\n  setCellSetSelection([nextPath]);\n  setCellColorEncoding('cellSetSelection');\n}\n\nexport function mergeCellSets(cellSets, additionalCellSets) {\n  return {\n    version: HIERARCHICAL_SCHEMAS[SETS_DATATYPE_CELL].latestVersion,\n    datatype: SETS_DATATYPE_CELL,\n    tree: [\n      ...(cellSets ? cellSets.tree : []),\n      ...(additionalCellSets ? additionalCellSets.tree : []),\n    ],\n  };\n}\n\nexport function createWarningComponent(props) {\n  return () => {\n    const {\n      title,\n      message,\n    } = props;\n    return (\n      <div className={PRIMARY_CARD}>\n        <h1>{title}</h1>\n        <div>{message}</div>\n      </div>\n    );\n  };\n}\n\nexport function asEsModule(component) {\n  return {\n    __esModule: true,\n    default: component,\n  };\n}\n\n\nexport function formatBytes(bytes, decimals = 2) {\n  if (bytes === 0) return '0 Bytes';\n\n  const k = 1024;\n  const dm = decimals < 0 ? 0 : decimals;\n  const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n\n  const i = Math.floor(Math.log(bytes) / Math.log(k));\n\n  // eslint-disable-next-line no-restricted-properties\n  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}\n\nexport const getStatsForResolution = (loader, resolution) => {\n  const { shape, labels } = loader[resolution];\n  const height = shape[labels.indexOf('y')];\n  const width = shape[labels.indexOf('x')];\n  const depth = shape[labels.indexOf('z')];\n  // eslint-disable-next-line no-bitwise\n  const depthDownsampled = Math.max(1, depth >> resolution);\n  // Check memory allocation limits for Float32Array (used in XR3DLayer for rendering)\n  const totalBytes = 4 * height * width * depthDownsampled;\n  return {\n    height, width, depthDownsampled, totalBytes,\n  };\n};\n\nexport const canLoadResolution = (loader, resolution) => {\n  const {\n    totalBytes, height, width, depthDownsampled,\n  } = getStatsForResolution(\n    loader,\n    resolution,\n  );\n  const maxHeapSize = window.performance?.memory\n    && window.performance?.memory?.jsHeapSizeLimit / 2;\n  const maxSize = maxHeapSize || (2 ** 31) - 1;\n  // 2048 is a normal texture size limit although some browsers go larger.\n  return (\n    totalBytes < maxSize\n    && height <= 2048\n    && depthDownsampled <= 2048\n    && width <= 2048\n    && depthDownsampled > 1\n  );\n};\n","import { RENDERING_MODES } from '@hms-dbmi/viv';\n\nexport const GLOBAL_LABELS = ['z', 't'];\n\nexport const DEFAULT_RASTER_DOMAIN_TYPE = 'Min/Max';\n\nexport const DEFAULT_RASTER_LAYER_PROPS = {\n  visible: true,\n  colormap: null,\n  opacity: 1,\n  domainType: DEFAULT_RASTER_DOMAIN_TYPE,\n  transparentColor: [0, 0, 0],\n  renderingMode: RENDERING_MODES.ADDITIVE,\n  use3d: false,\n};\n\nexport const DEFAULT_MOLECULES_LAYER = {\n  opacity: 1, radius: 20, visible: true,\n};\nexport const DEFAULT_CELLS_LAYER = {\n  opacity: 1, radius: 50, visible: true, stroked: false,\n};\nexport const DEFAULT_NEIGHBORHOODS_LAYER = {\n  visible: false,\n};\n\nexport const DEFAULT_LAYER_TYPE_ORDERING = [\n  'molecules',\n  'cells',\n  'neighborhoods',\n  'raster',\n];\n","// List of the GLSL colormaps available,\n// to validate against before string replacing.\nexport const GLSL_COLORMAPS = [\n  'plasma',\n  'viridis',\n  'jet',\n];\nexport const GLSL_COLORMAP_DEFAULT = 'plasma';\nexport const COLORMAP_SHADER_PLACEHOLDER = 'COLORMAP_FUNC';\n","import GL from '@luma.gl/constants'; // eslint-disable-line import/no-extraneous-dependencies\nimport { project32, picking } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport { Texture2D, isWebGL2 } from '@luma.gl/core';\nimport { XRLayer } from '@hms-dbmi/viv';\nimport { fs, vs } from './bitmask-layer-shaders';\nimport {\n  GLSL_COLORMAPS,\n  GLSL_COLORMAP_DEFAULT,\n  COLORMAP_SHADER_PLACEHOLDER,\n} from './constants';\n\nfunction padWithDefault(arr, defaultValue, padWidth) {\n  const newArr = [...arr];\n  for (let i = 0; i < padWidth; i += 1) {\n    newArr.push(defaultValue);\n  }\n  return newArr;\n}\n\nconst defaultProps = {\n  hoveredCell: { type: 'number', value: null, compare: true },\n  cellColorData: { type: 'object', value: null, compare: true },\n  colormap: { type: 'string', value: GLSL_COLORMAP_DEFAULT, compare: true },\n  expressionData: { type: 'object', value: null, compare: true },\n};\n\n/**\n * A BitmapLayer that performs aggregation in the fragment shader,\n * and renders its texture from a Uint8Array rather than an ImageData.\n */\nexport default class BitmaskLayer extends XRLayer {\n  // eslint-disable-next-line class-methods-use-this\n  getShaders() {\n    const { colormap } = this.props;\n    return {\n      fs,\n      vs,\n      modules: [project32, picking],\n      defines: {\n        [COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap)\n          ? colormap\n          : GLSL_COLORMAP_DEFAULT,\n      },\n    };\n  }\n\n  updateState({ props, oldProps, changeFlags }) {\n    super.updateState({ props, oldProps, changeFlags });\n    if (props.cellColorData !== oldProps.cellColorData) {\n      this.setColorTexture();\n    }\n    if (props.expressionData !== oldProps.expressionData) {\n      const { expressionData, cellTexHeight, cellTexWidth } = this.props;\n      const expressionTex = this.dataToTexture(\n        expressionData,\n        cellTexWidth,\n        cellTexHeight,\n      );\n      this.setState({ expressionTex });\n    }\n    if (props.colormap !== oldProps.colormap) {\n      const { gl } = this.context;\n      if (this.state.model) {\n        this.state.model.delete();\n      }\n      // eslint-disable-next-line no-underscore-dangle\n      this.setState({ model: this._getModel(gl) });\n\n      this.getAttributeManager().invalidateAll();\n    }\n  }\n\n  setColorTexture() {\n    const {\n      cellColorData: data,\n      cellTexHeight: height,\n      cellTexWidth: width,\n    } = this.props;\n    const colorTex = new Texture2D(this.context.gl, {\n      width,\n      height,\n      // Only use Float32 so we don't have to write two shaders\n      data,\n      // we don't want or need mimaps\n      mipmaps: false,\n      parameters: {\n        // NEAREST for integer data\n        [GL.TEXTURE_MIN_FILTER]: GL.NEAREST,\n        [GL.TEXTURE_MAG_FILTER]: GL.NEAREST,\n        // CLAMP_TO_EDGE to remove tile artifacts\n        [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,\n        [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE,\n      },\n      format: GL.RGB,\n      dataFormat: GL.RGB,\n      type: GL.UNSIGNED_BYTE,\n    });\n    this.setState({ colorTex });\n  }\n\n  draw(opts) {\n    const { uniforms } = opts;\n    const {\n      channelsVisible,\n      hoveredCell,\n      colorScaleLo,\n      colorScaleHi,\n      isExpressionMode,\n    } = this.props;\n    const {\n      textures, model, colorTex, expressionTex,\n    } = this.state;\n    // Render the image\n    if (textures && model && colorTex) {\n      model\n        .setUniforms(\n          Object.assign({}, uniforms, {\n            hovered: hoveredCell || 0,\n            colorTex,\n            expressionTex,\n            colorTexHeight: colorTex.height,\n            colorTexWidth: colorTex.width,\n            channelsVisible: padWithDefault(\n              channelsVisible,\n              false,\n              // There are six texture entries on the shaders\n              6 - channelsVisible.length,\n            ),\n            uColorScaleRange: [colorScaleLo, colorScaleHi],\n            uIsExpressionMode: isExpressionMode,\n            ...textures,\n          }),\n        )\n        .draw();\n    }\n  }\n\n  /**\n   * This function creates textures from the data\n   */\n  dataToTexture(data, width, height) {\n    const isWebGL2On = isWebGL2(this.context.gl);\n    return new Texture2D(this.context.gl, {\n      width,\n      height,\n      // Only use Float32 so we don't have to write two shaders\n      data: new Float32Array(data),\n      // we don't want or need mimaps\n      mipmaps: false,\n      parameters: {\n        // NEAREST for integer data\n        [GL.TEXTURE_MIN_FILTER]: GL.NEAREST,\n        [GL.TEXTURE_MAG_FILTER]: GL.NEAREST,\n        // CLAMP_TO_EDGE to remove tile artifacts\n        [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,\n        [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE,\n      },\n      format: isWebGL2On ? GL.R32F : GL.LUMINANCE,\n      dataFormat: isWebGL2On ? GL.RED : GL.LUMINANCE,\n      type: GL.FLOAT,\n    });\n  }\n}\nBitmaskLayer.layerName = 'BitmaskLayer';\nBitmaskLayer.defaultProps = defaultProps;\n","import glsl from 'glslify';\n\nexport const vs = glsl`\n#define SHADER_NAME bitmask-layer-vertex-shader\n\nattribute vec2 texCoords;\nattribute vec3 positions;\nattribute vec3 positions64Low;\nattribute vec3 instancePickingColors;\n\nvarying vec2 vTexCoord;\n\nvoid main(void) {\n  geometry.worldPosition = positions;\n  geometry.uv = texCoords;\n  geometry.pickingColor = instancePickingColors;\n  gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);\n  DECKGL_FILTER_GL_POSITION(gl_Position, geometry);\n  vTexCoord = texCoords;\n  vec4 color = vec4(0.0);\n  DECKGL_FILTER_COLOR(color, geometry);\n}\n`;\n\nexport const fs = glsl`\n#define SHADER_NAME bitmask-layer-fragment-shader\nprecision highp float;\n\n#pragma glslify: plasma = require(\"glsl-colormap/plasma\")\n#pragma glslify: viridis = require(\"glsl-colormap/viridis\")\n#pragma glslify: greys = require(\"glsl-colormap/greys\")\n#pragma glslify: magma = require(\"glsl-colormap/magma\")\n#pragma glslify: jet = require(\"glsl-colormap/jet\")\n#pragma glslify: bone = require(\"glsl-colormap/bone\")\n#pragma glslify: copper = require(\"glsl-colormap/copper\")\n#pragma glslify: density = require(\"glsl-colormap/density\")\n#pragma glslify: inferno = require(\"glsl-colormap/inferno\")\n#pragma glslify: cool = require(\"glsl-colormap/cool\")\n#pragma glslify: hot = require(\"glsl-colormap/hot\")\n#pragma glslify: spring = require(\"glsl-colormap/spring\")\n#pragma glslify: summer = require(\"glsl-colormap/summer\")\n#pragma glslify: autumn = require(\"glsl-colormap/autumn\")\n#pragma glslify: winter = require(\"glsl-colormap/winter\")\n\n// Data (mask) texture\nuniform sampler2D channel0;\nuniform sampler2D channel1;\nuniform sampler2D channel2;\nuniform sampler2D channel3;\nuniform sampler2D channel4;\nuniform sampler2D channel5;\n\n// Color texture\nuniform sampler2D colorTex;\nuniform float colorTexHeight;\nuniform float colorTexWidth;\nuniform float hovered;\n// range\nuniform bool channelsVisible[6];\n\n// Expression mapping\nuniform vec2 uColorScaleRange;\nuniform bool uIsExpressionMode;\nuniform sampler2D expressionTex;\n\n// opacity\nuniform float opacity;\n\nvarying vec2 vTexCoord;\n\nvec4 sampleAndGetColor(sampler2D dataTex, vec2 coord, bool isOn){\n  float sampledData = texture(dataTex, coord).r;\n  vec4 hoveredColor = float(sampledData == hovered && sampledData > 0. && hovered > 0.) * vec4(0., 0., 1., 1.);\n  // Colors are laid out corresponding to ids in row-major order in the texture.  So if width of the texture is 10, and you want ID 25,\n  // you need coordinate (1, 4) (i.e 2 rows down, and 5 columns over indexed from 0 for a total of 25 units covered in row major order).\n  vec2 colorTexCoord = vec2(mod(sampledData, colorTexWidth) / colorTexWidth, floor(sampledData / colorTexWidth) / (colorTexHeight - 1.));\n  float expressionValue = texture(expressionTex, colorTexCoord).r / 255.;\n  float scaledExpressionValue = (expressionValue - uColorScaleRange[0]) / max(0.005, (uColorScaleRange[1] - uColorScaleRange[0]));\n  vec4 sampledColor = float(uIsExpressionMode) * COLORMAP_FUNC(clamp(scaledExpressionValue, 0.0, 1.0)) +  (1. - float(uIsExpressionMode)) * vec4(texture(colorTex, colorTexCoord).rgb, 1.);\n  // Only return a color if the data is non-zero.\n  return max(0., min(sampledData, 1.)) * float(isOn) * (sampledColor + hoveredColor);\n}\n\nvoid main() {\n\n  gl_FragColor = sampleAndGetColor(channel0, vTexCoord, channelsVisible[0]);\n\n  // If the sampled color and the currently stored color (gl_FragColor) are identical, don't blend and use the sampled color,\n  // otherwise just use the currently stored color.  Repeat this for all channels.\n  vec4 sampledColor = sampleAndGetColor(channel1, vTexCoord, channelsVisible[1]);\n  gl_FragColor = (sampledColor == gl_FragColor || sampledColor == vec4(0.)) ? gl_FragColor : sampledColor;\n  sampledColor = sampleAndGetColor(channel2, vTexCoord, channelsVisible[2]);\n  gl_FragColor = (sampledColor == gl_FragColor || sampledColor == vec4(0.)) ? gl_FragColor : sampledColor;\n  sampledColor = sampleAndGetColor(channel3, vTexCoord, channelsVisible[3]);\n  gl_FragColor = (sampledColor == gl_FragColor || sampledColor == vec4(0.)) ? gl_FragColor : sampledColor;\n  sampledColor = sampleAndGetColor(channel4, vTexCoord, channelsVisible[4]);\n  gl_FragColor = (sampledColor == gl_FragColor || sampledColor == vec4(0.)) ? gl_FragColor : sampledColor;\n  sampledColor = sampleAndGetColor(channel5, vTexCoord, channelsVisible[5]);\n  gl_FragColor = (sampledColor == gl_FragColor || sampledColor == vec4(0.)) ? gl_FragColor : sampledColor;\n  // Apply the opacity if there is pixel data, and if the pixel data is empty i.e no segmentation, use 0 opacity.\n  gl_FragColor = vec4(gl_FragColor.rgb, (gl_FragColor.rgb == vec3(0., 0., 0.)) ? 0.0 : opacity);\n\n  geometry.uv = vTexCoord;\n  DECKGL_FILTER_COLOR(gl_FragColor, geometry);\n}\n`;\n","import { getChannelStats } from '@hms-dbmi/viv';\nimport { Matrix4 } from 'math.gl';\n\nasync function getSingleSelectionStats2D({ loader, selection }) {\n  const data = Array.isArray(loader) ? loader[loader.length - 1] : loader;\n  const raster = await data.getRaster({ selection });\n  const selectionStats = getChannelStats(raster.data);\n  const { domain, contrastLimits: slider } = selectionStats;\n  return { domain, slider };\n}\n\nasync function getSingleSelectionStats3D({ loader, selection }) {\n  const lowResSource = loader[loader.length - 1];\n  const { shape, labels } = lowResSource;\n  // eslint-disable-next-line no-bitwise\n  const sizeZ = shape[labels.indexOf('z')] >> (loader.length - 1);\n  const raster0 = await lowResSource.getRaster({\n    selection: { ...selection, z: 0 },\n  });\n  const rasterMid = await lowResSource.getRaster({\n    selection: { ...selection, z: Math.floor(sizeZ / 2) },\n  });\n  const rasterTop = await lowResSource.getRaster({\n    selection: { ...selection, z: Math.max(0, sizeZ - 1) },\n  });\n  const stats0 = getChannelStats(raster0.data);\n  const statsMid = getChannelStats(rasterMid.data);\n  const statsTop = getChannelStats(rasterTop.data);\n  return {\n    domain: [\n      Math.min(stats0.domain[0], statsMid.domain[0], statsTop.domain[0]),\n      Math.max(stats0.domain[1], statsMid.domain[1], statsTop.domain[1]),\n    ],\n    slider: [\n      Math.min(\n        stats0.contrastLimits[0],\n        statsMid.contrastLimits[0],\n        statsTop.contrastLimits[0],\n      ),\n      Math.max(\n        stats0.contrastLimits[1],\n        statsMid.contrastLimits[1],\n        statsTop.contrastLimits[1],\n      ),\n    ],\n  };\n}\n\n/**\n * Get bounding cube for a given loader i.e [[0, width], [0, height], [0, depth]]\n * @param {Object} loader PixelSource|PixelSource[]\n * @param {[]} selection Selection for stats.\n * @param {boolean} use3d Whether or not to get 3d stats.\n * @returns {Object} { domains, sliders }\n */\nexport const getSingleSelectionStats = async ({ loader, selection, use3d }) => {\n  const getStats = use3d\n    ? getSingleSelectionStats3D\n    : getSingleSelectionStats2D;\n  return getStats({ loader, selection });\n};\n\nexport const getMultiSelectionStats = async ({ loader, selections, use3d }) => {\n  const stats = await Promise.all(\n    selections.map(selection => getSingleSelectionStats({ loader, selection, use3d })),\n  );\n  const domains = stats.map(stat => stat.domain);\n  const sliders = stats.map(stat => stat.slider);\n  return { domains, sliders };\n};\n\n/**\n * Get physical size scaling Matrix4\n * @param {Object} loader PixelSource\n * @returns {Object} matrix\n */\nexport function getPhysicalSizeScalingMatrix(loader) {\n  const { x, y, z } = loader?.meta?.physicalSizes ?? {};\n  if (x?.size && y?.size && z?.size) {\n    const min = Math.min(z.size, x.size, y.size);\n    const ratio = [x.size / min, y.size / min, z.size / min];\n    return new Matrix4().scale(ratio);\n  }\n  return new Matrix4().identity();\n}\n\n/**\n * Get bounding cube for a given loader\n * @param {Object} loader PixelSource|PixelSource[]\n * @returns {Array} [0, width], [0, height], [0, depth]]\n */\nexport function getBoundingCube(loader) {\n  const source = Array.isArray(loader) ? loader[0] : loader;\n  const { shape, labels } = source;\n  const physicalSizeScalingMatrix = getPhysicalSizeScalingMatrix(source);\n  const xSlice = [0, physicalSizeScalingMatrix[0] * shape[labels.indexOf('x')]];\n  const ySlice = [0, physicalSizeScalingMatrix[5] * shape[labels.indexOf('y')]];\n  const zSlice = [\n    0,\n    physicalSizeScalingMatrix[10] * shape[labels.indexOf('z')],\n  ];\n  return [xSlice, ySlice, zSlice];\n}\n\nexport function abbreviateNumber(value) {\n  // Return an abbreviated representation of value, in 5 characters or less.\n\n  const maxLength = 5;\n  let maxNaiveDigits = maxLength;\n\n  /* eslint-disable no-plusplus */\n  if (!Number.isInteger(value)) {\n    --maxNaiveDigits;\n  } // Wasted on \".\"\n  if (value < 1) {\n    --maxNaiveDigits;\n  } // Wasted on \"0.\"\n  /* eslint-disable no-plusplus */\n\n  const naive = Intl.NumberFormat('en-US', {\n    maximumSignificantDigits: maxNaiveDigits,\n    useGrouping: false,\n  }).format(value);\n  if (naive.length <= maxLength) return naive;\n\n  // \"e+9\" consumes 3 characters, so if we even had two significant digits,\n  // it would take take us to six characters, including the decimal point.\n  return value.toExponential(0);\n}\n","/* eslint-disable no-plusplus */\nimport shortNumber from 'short-number';\nimport isEqual from 'lodash/isEqual';\nimport {\n  getDefaultInitialViewState,\n  MultiscaleImageLayer,\n  ImageLayer,\n  VolumeLayer,\n} from '@hms-dbmi/viv';\nimport { extent } from 'd3-array';\nimport { Matrix4 } from 'math.gl';\nimport { divide, compare, unit } from 'mathjs';\nimport { pluralize, getSourceFromLoader, isRgb } from '../../utils';\nimport { VIEWER_PALETTE } from '../utils';\nimport {\n  GLOBAL_LABELS,\n  DEFAULT_RASTER_LAYER_PROPS,\n  DEFAULT_LAYER_TYPE_ORDERING,\n} from './constants';\nimport BitmaskLayer from '../../layers/BitmaskLayer';\nimport { getMultiSelectionStats } from '../layer-controller/utils';\n\nexport function square(x, y, r) {\n  return [[x, y + r], [x + r, y], [x, y - r], [x - r, y]];\n}\n\n/**\n * Sort spatial layer definition array,\n * to keep the ordering in the layer controller\n * consistent.\n * Intended to be used with auto-initialized layer\n * definition arrays only, as a pre-defined layer array\n * should not be re-ordered.\n * @param {object[]} layers Array of layer definition objects.\n * Object must have a .type property.\n */\nexport function sortLayers(layers) {\n  return layers.sort((a, b) => (\n    DEFAULT_LAYER_TYPE_ORDERING.indexOf(a.type) - DEFAULT_LAYER_TYPE_ORDERING.indexOf(b.type)\n  ));\n}\n\n/**\n * Return the midpoint of the global dimensions.\n * @param {object} source PixelSource object from Viv\n * @returns {object} The selection.\n */\nfunction getDefaultGlobalSelection(source) {\n  const globalIndices = source.labels\n    .filter(dim => GLOBAL_LABELS.includes(dim));\n  const selection = {};\n  globalIndices.forEach((dim) => {\n    selection[dim] = Math.floor(\n      (source.shape[source.labels.indexOf(dim)] || 0) / 2,\n    );\n  });\n  return selection;\n}\n\n/**\n * Create a default selection using the midpoint of the available global dimensions,\n * and then the first four available selections from the first selectable channel.\n * @param {object} source PixelSource object from Viv\n * @returns {object} The selection.\n */\nfunction buildDefaultSelection(source) {\n  const selection = [];\n  const globalSelection = getDefaultGlobalSelection(source);\n  // First non-global dimension with some sort of selectable values\n  const firstNonGlobalDimension = source.labels.filter(\n    dim => !GLOBAL_LABELS.includes(dim)\n      && source.shape[source.labels.indexOf(dim)],\n  )[0];\n  for (let i = 0; i < Math.min(4, source.shape[\n    source.labels.indexOf(firstNonGlobalDimension)\n  ]); i += 1) {\n    selection.push(\n      {\n        [firstNonGlobalDimension]: i,\n        ...globalSelection,\n      },\n    );\n  }\n  return selection;\n}\n\n/**\n * @param {Array.<number>} shape loader shape\n */\nexport function isInterleaved(shape) {\n  const lastDimSize = shape[shape.length - 1];\n  return lastDimSize === 3 || lastDimSize === 4;\n}\n\n/**\n * Initialize the channel selections for an individual layer.\n * @param {object} loader A viv loader instance with channel names appended by Vitessce loaders\n * of the form { data: (PixelSource[]|PixelSource), metadata: Object, channels }\n * @returns {object[]} An array of selected channels with default\n * domain/slider settings.\n */\nexport async function initializeLayerChannels(loader, use3d) {\n  const result = [];\n  const source = getSourceFromLoader(loader);\n  // Add channel automatically as the first avaialable value for each dimension.\n  let defaultSelection = buildDefaultSelection(source);\n  defaultSelection = isInterleaved(source.shape)\n    ? [{ ...defaultSelection[0], c: 0 }] : defaultSelection;\n  const stats = await getMultiSelectionStats({\n    loader: loader.data, selections: defaultSelection, use3d,\n  });\n\n  const domains = isRgb(loader)\n    ? [[0, 255], [0, 255], [0, 255]]\n    : stats.domains;\n  const colors = isRgb(loader)\n    ? [[255, 0, 0], [0, 255, 0], [0, 0, 255]]\n    : null;\n  const sliders = isRgb(loader)\n    ? [[0, 255], [0, 255], [0, 255]]\n    : stats.sliders;\n\n  defaultSelection.forEach((selection, i) => {\n    const domain = domains[i];\n    const slider = sliders[i];\n    const channel = {\n      selection,\n      // eslint-disable-next-line no-nested-ternary\n      color: colors ? colors[i]\n        : defaultSelection.length !== 1\n          ? VIEWER_PALETTE[i] : [255, 255, 255],\n      visible: true,\n      slider: slider || domain,\n    };\n    result.push(channel);\n  });\n  return result;\n}\n\nfunction getMetaWithTransformMatrices(imageMeta, imageLoaders) {\n  // Do not fill in transformation matrices if any of the layers specify one.\n  const sources = imageLoaders.map(loader => getSourceFromLoader(loader));\n  if (\n    imageMeta.map(meta => meta?.metadata?.transform?.matrix\n      || meta?.metadata?.transform?.scale\n      || meta?.metadata?.transform?.translate).some(Boolean)\n    || sources.every(\n      source => !source.meta?.physicalSizes?.x || !source.meta?.physicalSizes?.y,\n    )\n  ) {\n    return imageMeta;\n  }\n  // Get the minimum physical among all the current images.\n  const minPhysicalSize = sources.reduce((acc, source) => {\n    const hasZPhyscialSize = source.meta?.physicalSizes?.z?.size;\n    const sizes = [\n      unit(`${source.meta?.physicalSizes.x.size} ${source.meta?.physicalSizes.x.unit}`.replace('µ', 'u')),\n      unit(`${source.meta?.physicalSizes.y.size} ${source.meta?.physicalSizes.y.unit}`.replace('µ', 'u')),\n    ];\n    if (hasZPhyscialSize) {\n      sizes.push(unit(`${source.meta?.physicalSizes.z.size} ${source.meta?.physicalSizes.z.unit}`.replace('µ', 'u')));\n    }\n    acc[0] = (acc[0] === undefined || compare(sizes[0], acc[0]) === -1) ? sizes[0] : acc[0];\n    acc[1] = (acc[1] === undefined || compare(sizes[1], acc[1]) === -1) ? sizes[1] : acc[1];\n    acc[2] = (acc[2] === undefined || compare(sizes[2], acc[2]) === -1) ? sizes[2] : acc[2];\n    return acc;\n  }, []);\n  const imageMetaWithTransform = imageMeta.map((meta, j) => {\n    const source = sources[j];\n    const hasZPhyscialSize = source.meta?.physicalSizes?.z?.size;\n    const sizes = [\n      unit(`${source.meta?.physicalSizes.x.size} ${source.meta?.physicalSizes.x.unit}`.replace('µ', 'u')),\n      unit(`${source.meta?.physicalSizes.y.size} ${source.meta?.physicalSizes.y.unit}`.replace('µ', 'u')),\n    ];\n    if (hasZPhyscialSize) {\n      sizes.push(unit(`${source.meta?.physicalSizes.z.size} ${source.meta?.physicalSizes.z.unit}`.replace('µ', 'u')));\n    }\n    // Find the ratio of the sizes to get the scaling factor.\n    const scale = sizes.map((i, k) => divide(i, minPhysicalSize[k]));\n    // Add in z dimension needed for Matrix4 scale API.\n    if (!scale[2]) {\n      scale[2] = 1;\n    }\n    // no need to store/use identity scaling\n    if (isEqual(scale, [1, 1, 1])) {\n      return meta;\n    }\n    // Make sure to scale the z direction by one.\n    const matrix = new Matrix4().scale([...scale]);\n    const newMeta = { ...meta };\n    newMeta.metadata = {\n      ...newMeta.metadata,\n      // We don't want to store matrix objects in the view config.\n      transform: { matrix: matrix.toArray() },\n    };\n    return newMeta;\n  });\n  return imageMetaWithTransform;\n}\n\n/**\n * Given a set of image layer loader creator functions,\n * create loader objects for an initial layer or set of layers,\n * which will be selected based on default values predefined in\n * the image data file or otherwise by a heuristic\n * (the midpoint of the layers array).\n * @param {object[]} rasterLayers A list of layer metadata objects with\n * shape { name, type, url, createLoader }.\n * @param {(string[]|null)} rasterRenderLayers A list of default raster layers. Optional.\n */\nexport async function initializeRasterLayersAndChannels(\n  rasterLayers,\n  rasterRenderLayers,\n  usePhysicalSizeScaling,\n) {\n  const nextImageLoaders = [];\n  let nextImageMetaAndLayers = [];\n  const autoImageLayerDefPromises = [];\n\n  // Start all loader creators immediately.\n  // Reference: https://eslint.org/docs/rules/no-await-in-loop\n  const loaders = await Promise.all(rasterLayers.map(layer => layer.loaderCreator()));\n\n  for (let i = 0; i < rasterLayers.length; i++) {\n    const layer = rasterLayers[i];\n    const loader = loaders[i];\n    nextImageLoaders[i] = loader;\n    nextImageMetaAndLayers[i] = layer;\n  }\n  if (usePhysicalSizeScaling) {\n    nextImageMetaAndLayers = getMetaWithTransformMatrices(nextImageMetaAndLayers, nextImageLoaders);\n  }\n  // No layers were pre-defined so set up the default image layers.\n  if (!rasterRenderLayers) {\n    // Midpoint of images list as default image to show.\n    const layerIndex = Math.floor(rasterLayers.length / 2);\n    const loader = nextImageLoaders[layerIndex];\n    const autoImageLayerDefPromise = initializeLayerChannels(loader)\n      .then(channels => Promise.resolve({\n        type: nextImageMetaAndLayers[layerIndex]?.metadata?.isBitmask ? 'bitmask' : 'raster',\n        index: layerIndex,\n        ...DEFAULT_RASTER_LAYER_PROPS,\n        channels: channels.map((channel, j) => ({\n          ...channel,\n          ...(nextImageMetaAndLayers[layerIndex].channels\n            ? nextImageMetaAndLayers[layerIndex].channels[j] : []),\n        })),\n        modelMatrix: nextImageMetaAndLayers[layerIndex]?.metadata?.transform?.matrix,\n        transparentColor: layerIndex > 0 ? [0, 0, 0] : null,\n      }));\n    autoImageLayerDefPromises.push(autoImageLayerDefPromise);\n  } else {\n    // The renderLayers parameter is a list of layer names to show by default.\n    const globalIndicesOfRenderLayers = rasterRenderLayers\n      .map(imageName => rasterLayers.findIndex(image => image.name === imageName));\n    for (let i = 0; i < globalIndicesOfRenderLayers.length; i++) {\n      const layerIndex = globalIndicesOfRenderLayers[i];\n      const loader = nextImageLoaders[layerIndex];\n      const autoImageLayerDefPromise = initializeLayerChannels(loader)\n        // eslint-disable-next-line no-loop-func\n        .then(channels => Promise.resolve({\n          type: nextImageMetaAndLayers[layerIndex]?.metadata?.isBitmask ? 'bitmask' : 'raster',\n          index: layerIndex,\n          ...DEFAULT_RASTER_LAYER_PROPS,\n          channels: channels.map((channel, j) => ({\n            ...channel,\n            ...(nextImageMetaAndLayers[layerIndex].channels\n              ? nextImageMetaAndLayers[layerIndex].channels[j] : []),\n          })),\n          domainType: 'Min/Max',\n          modelMatrix: nextImageMetaAndLayers[layerIndex]?.metadata?.transform?.matrix,\n          transparentColor: i > 0 ? [0, 0, 0] : null,\n        }));\n      autoImageLayerDefPromises.push(autoImageLayerDefPromise);\n    }\n  }\n\n  const autoImageLayerDefs = await Promise.all(autoImageLayerDefPromises);\n  return [autoImageLayerDefs, nextImageLoaders, nextImageMetaAndLayers];\n}\n\n/**\n * Make a subtitle for the spatial component.\n * @param {object} params\n * @param {number} params.observationsCount\n * @param {string} params.observationsLabel\n * @param {string} params.observationsPluralLabel\n * @param {number} params.subobservationsCount\n * @param {string} params.subobservationsLabel\n * @param {string} params.subobservationsPluralLabel\n * @param {number} params.locationsCount\n * @returns {string} The subtitle string,\n * with info about items with zero counts omitted.\n */\nexport function makeSpatialSubtitle({\n  observationsCount, observationsLabel, observationsPluralLabel,\n  subobservationsCount, subobservationsLabel, subobservationsPluralLabel,\n  locationsCount,\n}) {\n  const parts = [];\n  if (subobservationsCount > 0) {\n    let part = `${subobservationsCount} ${pluralize(subobservationsLabel, subobservationsPluralLabel, subobservationsCount)}`;\n    if (locationsCount > 0) {\n      part += ` at ${shortNumber(locationsCount)} locations`;\n    }\n    parts.push(part);\n  }\n  if (observationsCount > 0) {\n    parts.push(`${observationsCount} ${pluralize(observationsLabel, observationsPluralLabel, observationsCount)}`);\n  }\n  return parts.join(', ');\n}\n\nexport function getInitialSpatialTargets({\n  width,\n  height,\n  cells,\n  imageLayerLoaders,\n  useRaster,\n  use3d,\n}) {\n  let initialTargetX = -Infinity;\n  let initialTargetY = -Infinity;\n  let initialTargetZ = -Infinity;\n  let initialZoom = -Infinity;\n  // Some backoff from completely filling the screen.\n  const zoomBackoff = use3d ? 1.5 : 0.1;\n  const cellValues = Object.values(cells);\n  if (imageLayerLoaders.length > 0 && useRaster) {\n    for (let i = 0; i < imageLayerLoaders.length; i += 1) {\n      const viewSize = { height, width };\n      const { target, zoom: newViewStateZoom } = getDefaultInitialViewState(\n        imageLayerLoaders[i].data,\n        viewSize,\n        zoomBackoff,\n        use3d,\n      );\n      if (target[0] > initialTargetX) {\n        // eslint-disable-next-line prefer-destructuring\n        initialTargetX = target[0];\n        initialZoom = newViewStateZoom;\n      }\n      if (target[1] > initialTargetY) {\n        // eslint-disable-next-line prefer-destructuring\n        initialTargetY = target[1];\n        initialZoom = newViewStateZoom;\n      }\n      if (target[2] > initialTargetZ) {\n        // eslint-disable-next-line prefer-destructuring\n        initialTargetZ = target[2];\n        initialZoom = newViewStateZoom;\n      } else {\n        initialTargetZ = null;\n      }\n    }\n  } else if (cellValues.length > 0\n    // Only use cellValues in quadtree calculation if there is\n    // centroid data in the cells (i.e not just ids).\n    && cellValues[0].xy\n    && !useRaster) {\n    const cellCoordinates = cellValues.map(c => c.xy);\n    let xExtent = extent(cellCoordinates, c => c[0]);\n    let yExtent = extent(cellCoordinates, c => c[1]);\n    let xRange = xExtent[1] - xExtent[0];\n    let yRange = yExtent[1] - yExtent[0];\n    const getViewExtentFromPolygonExtents = extents => [\n      Math.min(...extents.map(i => i[0])),\n      Math.max(...extents.map(i => i[1])),\n    ];\n    if (xRange === 0) {\n      // The fall back is the cells' polygon coordinates, if the original range\n      // is 0 i.e the centroids are all on the same axis.\n      const polygonExtentsX = cellValues.map(cell => extent(cell.poly, i => i[0]));\n      xExtent = getViewExtentFromPolygonExtents(polygonExtentsX);\n      xRange = xExtent[1] - xExtent[0];\n    }\n    if (yRange === 0) {\n      // The fall back is the first cells' polygon coordinates, if the original range\n      // is 0 i.e the centroids are all on the same axis.\n      const polygonExtentsY = cellValues.map(cell => extent(cell.poly, i => i[1]));\n      yExtent = getViewExtentFromPolygonExtents(polygonExtentsY);\n      yRange = yExtent[1] - yExtent[0];\n    }\n    initialTargetX = xExtent[0] + xRange / 2;\n    initialTargetY = yExtent[0] + yRange / 2;\n    initialTargetZ = null;\n    initialZoom = Math.log2(Math.min(width / xRange, height / yRange)) - zoomBackoff;\n  } else {\n    return {\n      initialTargetX: null, initialTargetY: null, initialTargetZ: null, initialZoom: null,\n    };\n  }\n  return {\n    initialTargetX, initialTargetY, initialZoom, initialTargetZ,\n  };\n}\n\n/**\n * Make a subtitle for the spatial component.\n * @param {object} data PixelSource | PixelSource[]\n * @returns {Array} [Layer, PixelSource | PixelSource[]] tuple.\n */\nexport function getLayerLoaderTuple(data, use3d) {\n  const loader = ((Array.isArray(data) && data.length > 1) || !Array.isArray(data))\n    ? data : data[0];\n  if (use3d) {\n    return [VolumeLayer, Array.isArray(loader) ? loader : [loader]];\n  }\n  const Layer = (Array.isArray(data) && data.length > 1) ? MultiscaleImageLayer : ImageLayer;\n  return [Layer, loader];\n}\n\n\nexport function renderSubBitmaskLayers(props) {\n  const {\n    bbox: {\n      left, top, right, bottom,\n    },\n    x,\n    y,\n    z,\n  } = props.tile;\n  const {\n    data, id, loader,\n  } = props;\n  // Only render in positive coorinate system\n  if ([left, bottom, right, top].some(v => v < 0) || !data) {\n    return null;\n  }\n  const base = loader[0];\n  const [height, width] = loader[0].shape.slice(-2);\n  // Tiles are exactly fitted to have height and width such that their bounds\n  // match that of the actual image (not some padded version).\n  // Thus the right/bottom given by deck.gl are incorrect since\n  // they assume tiles are of uniform sizes, which is not the case for us.\n  const bounds = [\n    left,\n    data.height < base.tileSize ? height : bottom,\n    data.width < base.tileSize ? width : right,\n    top,\n  ];\n  return new BitmaskLayer(props, {\n    channelData: data,\n    // Uncomment to help debugging - shades the tile being hovered over.\n    // autoHighlight: true,\n    // highlightColor: [80, 80, 80, 50],\n    // Shared props with BitmapLayer:\n    bounds,\n    id: `sub-layer-${bounds}-${id}`,\n    tileId: { x, y, z },\n  });\n}\n","import { ZarrPixelSource, loadOmeTiff } from '@hms-dbmi/viv';\nimport { openArray } from 'zarr';\nimport rasterSchema from '../schemas/raster.schema.json';\nimport JsonLoader from './JsonLoader';\nimport { AbstractLoaderError } from './errors';\nimport LoaderResult from './LoaderResult';\n\nimport { initializeRasterLayersAndChannels } from '../components/spatial/utils';\n\nasync function initLoader(imageData) {\n  const {\n    type, url, metadata, requestInit,\n  } = imageData;\n  switch (type) {\n    case ('zarr'): {\n      const {\n        dimensions, isPyramid, transform,\n      } = metadata || {};\n      const labels = dimensions.map(d => d.field);\n      let source;\n      if (isPyramid) {\n        const metadataUrl = `${url}${\n          url.slice(-1) === '/' ? '' : '/'\n        }.zmetadata`;\n        const response = await fetch(metadataUrl);\n        const { metadata: zarrMetadata } = await response.json();\n        const paths = Object.keys(zarrMetadata)\n          .filter(metaKey => metaKey.includes('.zarray'))\n          .map(arrMetaKeys => arrMetaKeys.slice(0, -7));\n        const data = await Promise.all(\n          paths.map(path => openArray({ store: url, path })),\n        );\n        const [yChunk, xChunk] = data[0].chunks.slice(-2);\n        const size = Math.min(yChunk, xChunk);\n        // deck.gl requirement for power-of-two tile size.\n        const tileSize = 2 ** Math.floor(Math.log2(size));\n        source = data.map(d => new ZarrPixelSource(d, labels, tileSize));\n      } else {\n        const data = await openArray({ store: url });\n        source = new ZarrPixelSource(data, labels);\n      }\n      return { data: source, metadata: { dimensions, transform }, channels: (dimensions.find(d => d.field === 'channel') || dimensions[0]).values };\n    }\n    case ('ome-tiff'): {\n      let loader;\n      // Fetch offsets for ome-tiff if needed.\n      if (metadata && 'omeTiffOffsetsUrl' in metadata) {\n        const { omeTiffOffsetsUrl } = metadata;\n        const res = await fetch(omeTiffOffsetsUrl, (requestInit || {}));\n        if (res.ok) {\n          const offsets = await res.json();\n          loader = await loadOmeTiff(\n            url,\n            {\n              offsets,\n              headers: requestInit?.headers,\n            },\n          );\n        } else {\n          throw new Error('Offsets not found but provided.');\n        }\n      } else {\n        loader = await loadOmeTiff(url, { headers: requestInit?.headers });\n      }\n      const { Pixels: { Channels } } = loader.metadata;\n      const channels = Array.isArray(Channels)\n        ? Channels.map((channel, i) => channel.Name || `Channel ${i}`)\n        : [Channels.Name || `Channel ${0}`];\n      return { ...loader, channels };\n    }\n    default: {\n      throw Error(`Image type (${type}) is not supported`);\n    }\n  }\n}\n\nexport default class RasterLoader extends JsonLoader {\n  constructor(dataSource, params) {\n    const { url, options } = params;\n    if (!url && options) {\n      // eslint-disable-next-line no-param-reassign\n      dataSource.url = URL.createObjectURL(new Blob([JSON.stringify(options)]));\n    }\n    super(dataSource, params);\n    this.schema = rasterSchema;\n  }\n\n  async load() {\n    const payload = await super.load().catch(reason => Promise.resolve(reason));\n    if (payload instanceof AbstractLoaderError) {\n      return Promise.reject(payload);\n    }\n    const { data: raster } = payload;\n    const { images, renderLayers, usePhysicalSizeScaling = false } = raster;\n\n    // Get image name and URL tuples.\n    const urls = images\n      .filter(image => !image.url.includes('zarr'))\n      .map(image => ([image.url, image.name]));\n\n    // Add a loaderCreator function for each image layer.\n    const imagesWithLoaderCreators = images.map(image => ({\n      ...image,\n      loaderCreator: async () => initLoader(image),\n    }));\n\n    // TODO: use options for initial selection of channels\n    // which omit domain/slider ranges.\n    if (!this.autoImageCache) {\n      this.autoImageCache = initializeRasterLayersAndChannels(\n        imagesWithLoaderCreators,\n        renderLayers,\n        usePhysicalSizeScaling,\n      );\n    }\n\n    return this.autoImageCache.then((autoImages) => {\n      const [autoImageLayers, imageLayerLoaders, imageLayerMeta] = autoImages;\n\n      const coordinationValues = {\n        spatialRasterLayers: autoImageLayers,\n      };\n      return new LoaderResult(\n        { loaders: imageLayerLoaders, meta: imageLayerMeta },\n        urls,\n        coordinationValues,\n      );\n    });\n  }\n}\n","import { loadOmeZarr } from '@hms-dbmi/viv';\nimport { AbstractLoaderError } from './errors';\nimport LoaderResult from './LoaderResult';\n\nimport { initializeRasterLayersAndChannels } from '../components/spatial/utils';\nimport AbstractTwoStepLoader from './AbstractTwoStepLoader';\n\nfunction hexToRgb(hex) {\n  const result = /^#?([A-F\\d]{2})([A-F\\d]{2})([A-F\\d]{2})$/i.exec(hex);\n  return [\n    parseInt(result[1].toLowerCase(), 16),\n    parseInt(result[2].toLowerCase(), 16),\n    parseInt(result[3].toLowerCase(), 16),\n  ];\n}\n\nexport default class OmeZarrLoader extends AbstractTwoStepLoader {\n  async load() {\n    const payload = await this.dataSource.getJson('.zattrs').catch(reason => Promise.resolve(reason));\n    if (payload instanceof AbstractLoaderError) {\n      return Promise.reject(payload);\n    }\n\n    const loader = await loadOmeZarr(this.url, { fetchOptions: this.requestInit, type: 'multiscales' });\n    const { metadata, data } = loader;\n\n    const { omero } = metadata;\n\n    if (!omero) {\n      console.error('Path for image not valid');\n      return Promise.reject(payload);\n    }\n\n    const { rdefs, channels } = omero;\n\n    const t = rdefs.defaultT ?? 0;\n    const z = rdefs.defaultZ ?? 0;\n\n    const filterSelection = (sel) => {\n      // Remove selection keys for which there is no dimension.\n      if (data.length > 0) {\n        const nextSel = {};\n        // eslint-disable-next-line prefer-destructuring\n        const labels = data[0].labels;\n        Object.keys(sel).forEach((key) => {\n          if (labels.includes(key)) {\n            nextSel[key] = sel[key];\n          }\n        });\n        return nextSel;\n      }\n      return sel;\n    };\n\n    const imagesWithLoaderCreators = [\n      {\n        name: omero.name || 'Image',\n        channels: channels.map((channel, i) => ({\n          selection: filterSelection({ z, t, c: i }),\n          slider: [channel.window.start, channel.window.end],\n          color: hexToRgb(channel.color),\n        })),\n        loaderCreator: async () => ({ ...loader, channels: channels.map(c => c.label) }),\n      },\n    ];\n\n    // TODO: use options for initial selection of channels\n    // which omit domain/slider ranges.\n    const [\n      autoImageLayers, imageLayerLoaders, imageLayerMeta,\n    ] = await initializeRasterLayersAndChannels(\n      imagesWithLoaderCreators, undefined,\n    );\n\n    const coordinationValues = {\n      spatialRasterLayers: autoImageLayers,\n    };\n    return Promise.resolve(new LoaderResult(\n      { loaders: imageLayerLoaders, meta: imageLayerMeta },\n      [],\n      coordinationValues,\n    ));\n  }\n}\n","import tinycolor from 'tinycolor2';\nimport isEqual from 'lodash/isEqual';\n\n/**\n * Execute a callback function based on a keypress event.\n * @param {object} event The event from onKeyPress\n * @param {string} key The key identifier to match.\n * @param {Function} callback The function to execute.\n */\nexport function callbackOnKeyPress(event, key, callback) {\n  if (event.key === key) {\n    event.preventDefault();\n    callback();\n  }\n}\n\n/**\n * Convert an array of [r, g, b] numbers to a hex color.\n * @param {number[]} rgbArray The color [r, g, b] array.\n * @returns {string} The hex color as a string.\n */\nexport function colorArrayToString(rgbArray) {\n  return tinycolor({ r: rgbArray[0], g: rgbArray[1], b: rgbArray[2] }).toHexString();\n}\n\n/**\n * Convert a string color representation to an array of [r,g,b].\n * @param {string} colorString The color as a string.\n * @returns {number[]} The color as an array.\n */\nexport function colorStringToArray(colorString) {\n  const colorObj = tinycolor(colorString).toRgb();\n  return [colorObj.r, colorObj.g, colorObj.b];\n}\n\n/**\n * Get a string of help text for coloring a particular hierarchy level.\n * @param {integer} i The level. 1 for cluster, 2 for subcluster, etc.\n * @returns {string} The tooltip text for coloring the level.\n */\nexport function getLevelTooltipText(i) {\n  if (i === 0) return 'Color by hierarchy';\n  if (i <= 2) {\n    const subs = j => ('sub'.repeat(j));\n    return `Color by ${subs(i - 1)}cluster`;\n  }\n  return `Color by cluster level ${i}`;\n}\n\nexport function isEqualOrPrefix(targetPath, testPath) {\n  if (targetPath.length <= testPath.length) {\n    return isEqual(targetPath, testPath.slice(0, targetPath.length));\n  }\n  return false;\n}\n\nexport function tryRenamePath(targetPath, testPath, nextTargetPath) {\n  if (isEqualOrPrefix(targetPath, testPath)) {\n    return [...nextTargetPath, ...testPath.slice(nextTargetPath.length)];\n  }\n  return testPath;\n}\n\nexport const PATH_SEP = '___';\n\nexport function pathToKey(path) {\n  return path.join(PATH_SEP);\n}\n","/* eslint-disable no-underscore-dangle */\nimport uuidv4 from 'uuid/v4';\nimport isNil from 'lodash/isNil';\nimport isEqual from 'lodash/isEqual';\nimport range from 'lodash/range';\nimport { featureCollection as turfFeatureCollection, point as turfPoint } from '@turf/helpers';\nimport centroid from '@turf/centroid';\nimport concaveman from 'concaveman';\nimport {\n  HIERARCHICAL_SCHEMAS,\n} from './constants';\nimport { getDefaultColor, PALETTE } from '../utils';\nimport { pathToKey } from './utils';\n\n/**\n * Alias for the uuidv4 function to make code more readable.\n * @returns {string} UUID.\n */\nfunction generateKey() {\n  return uuidv4();\n}\n\n/**\n * Get the set associated with a particular node.\n * Recursive.\n * @param {object} currNode A node object.\n * @returns {array} The array representing the set associated with the node.\n */\nexport function nodeToSet(currNode) {\n  if (!currNode) {\n    return [];\n  }\n  if (!currNode.children) {\n    return (currNode.set || []);\n  }\n  return currNode.children.flatMap(c => nodeToSet(c));\n}\n\n/**\n * Get the height of a node (the number of levels to reach a leaf).\n * @param {object} currNode A node object.\n * @param {number} level The level that the height will be computed relative to. By default, 0.\n * @returns {number} The height. If the node has a .children property,\n * then the minimum value returned is 1.\n */\nexport function nodeToHeight(currNode, level = 0) {\n  if (!currNode.children) {\n    return level;\n  }\n  const newLevel = level + 1;\n  const childrenHeights = currNode.children.map(c => nodeToHeight(c, newLevel));\n  return Math.max(...childrenHeights, newLevel);\n}\n\n/**\n * Get the size associated with a particular node.\n * Recursive.\n * @param {object} currNode A node object.\n * @returns {number} The length of all the node's children\n */\nexport function getNodeLength(currNode) {\n  if (!currNode) {\n    return 0;\n  }\n  if (!currNode.children) {\n    return (currNode.set?.length || 0);\n  }\n  return currNode.children.reduce((acc, curr) => acc + getNodeLength(curr), 0);\n}\n\n/**\n * Find a node with a matching name path, relative to a particular node.\n * @param {object} node A node object.\n * @param {string[]} path The name path for the node of interest.\n * @param {number} currLevelIndex The index of the current hierarchy level.\n * @returns {object|null} A matching node object, or null if none is found.\n */\nfunction nodeFindNodeByNamePath(node, path, currLevelIndex) {\n  const currNodeName = path[currLevelIndex];\n  if (node.name === currNodeName) {\n    if (currLevelIndex === path.length - 1) {\n      return node;\n    }\n    if (node.children) {\n      const foundNodes = node.children\n        .map(child => nodeFindNodeByNamePath(child, path, currLevelIndex + 1))\n        .filter(Boolean);\n      if (foundNodes.length === 1) {\n        return foundNodes[0];\n      }\n    }\n  }\n  return null;\n}\n\n/**\n * Find a node with a matching name path, relative to the whole tree.\n * @param {object} currTree A tree object.\n * @param {string[]} targetNamePath The name path for the node of interest.\n * @returns {object|null} A matching node object, or null if none is found.\n */\nexport function treeFindNodeByNamePath(currTree, targetNamePath) {\n  const foundNodes = currTree.tree\n    .map(levelZeroNode => nodeFindNodeByNamePath(levelZeroNode, targetNamePath, 0))\n    .filter(Boolean);\n  if (foundNodes.length === 1) {\n    return foundNodes[0];\n  }\n  return null;\n}\n\n/**\n * Transform a node object using a transform function.\n * @param {object} node A node object.\n * @param {function} predicate Returns true if a node matches a condition of interest.\n * @param {function} transform Takes the node matching the predicate as input, returns\n * a transformed version of the node.\n * @param {array} transformedPaths This array parameter is mutated. The path of\n * each transformed node is appended to this array.\n * @param {string[]} The current path of the node being updated, used internally\n * during recursion.\n * @returns {object} The updated node.\n */\nexport function nodeTransform(node, predicate, transform, transformedPaths, currPath) {\n  let newPath;\n  if (!currPath) {\n    newPath = [node.name];\n  } else {\n    newPath = [...currPath];\n  }\n  if (predicate(node, newPath)) {\n    transformedPaths.push(newPath);\n    return transform(node, newPath);\n  }\n  if (node.children) {\n    return {\n      ...node,\n      children: node.children.map(\n        child => nodeTransform(\n          child, predicate, transform, transformedPaths, newPath.concat([child.name]),\n        ),\n      ),\n    };\n  }\n  return node;\n}\n\n/**\n * Transform many node objects using a transform function.\n * @param {object} node A node object.\n * @param {function} predicate Returns true if a node matches a condition of interest.\n * @param {function} transform Takes the node matching the predicate as input, returns\n * a transformed version of the node.\n * @param {array} transformedPaths This array parameter is mutated. The path of\n * each transformed node is appended to this array.\n * @param {string[]} The current path of the node being updated, used internally\n * during recursion.\n * @returns {object} The updated node.\n */\nexport function nodeTransformAll(node, predicate, transform, transformedPaths, currPath) {\n  let newPath;\n  if (!currPath) {\n    newPath = [node.name];\n  } else {\n    newPath = [...currPath];\n  }\n  let newNode = node;\n  if (predicate(node, newPath)) {\n    transformedPaths.push(newPath);\n    newNode = transform(node, newPath);\n  }\n  if (node.children) {\n    return {\n      ...newNode,\n      children: newNode.children.map(\n        child => nodeTransformAll(\n          child, predicate, transform, transformedPaths, newPath.concat([child.name]),\n        ),\n      ),\n    };\n  }\n  return newNode;\n}\n\n/**\n * Append a child to a parent node.\n * @param {object} currNode A node object.\n * @param {object} newChild The child node object.\n * @returns {object} The updated node.\n */\nexport function nodeAppendChild(currNode, newChild) {\n  return {\n    ...currNode,\n    children: [...currNode.children, newChild],\n  };\n}\n\n/**\n * Prepend a child to a parent node.\n * @param {object} currNode A node object.\n * @param {object} newChild The child node object.\n * @returns {object} The updated node.\n */\nexport function nodePrependChild(currNode, newChild) {\n  return {\n    ...currNode,\n    children: [newChild, ...currNode.children],\n  };\n}\n\n/**\n * Insert a child to a parent node.\n * @param {object} currNode A node object.\n * @param {*} newChild The child node object.\n * @param {*} insertIndex The index at which to insert the child.\n * @returns {object} The updated node.\n */\nexport function nodeInsertChild(currNode, newChild, insertIndex) {\n  const newChildren = Array.from(currNode.children);\n  newChildren.splice(insertIndex, 0, newChild);\n  return {\n    ...currNode,\n    children: newChildren,\n  };\n}\n\n/**\n * Get an array representing the union of the sets of checked nodes.\n * @param {object} currTree A tree object.\n * @returns {array} An array representing the union of the sets of checked nodes.\n */\nexport function treeToUnion(currTree, checkedPaths) {\n  const nodes = checkedPaths.map(path => treeFindNodeByNamePath(currTree, path));\n  const nodeSets = nodes.map(node => nodeToSet(node).map(([cellId]) => cellId));\n  return nodeSets\n    .reduce((a, h) => a.concat(h.filter(hEl => !a.includes(hEl))), nodeSets[0] || []);\n}\n\n/**\n * Get an array representing the intersection of the sets of checked nodes.\n * @param {object} currTree A tree object.\n * @returns {array} An array representing the intersection of the sets of checked nodes.\n */\nexport function treeToIntersection(currTree, checkedPaths) {\n  const nodes = checkedPaths.map(path => treeFindNodeByNamePath(currTree, path));\n  const nodeSets = nodes.map(node => nodeToSet(node).map(([cellId]) => cellId));\n  return nodeSets\n    .reduce((a, h) => h.filter(hEl => a.includes(hEl)), nodeSets[0] || []);\n}\n\n/**\n * Get an array representing the complement of the union of the sets of checked nodes.\n * @param {object} currTree\n * @returns {array} An array representing the complement of the\n * union of the sets of checked nodes.\n */\nexport function treeToComplement(currTree, checkedPaths, items) {\n  const primaryUnion = treeToUnion(currTree, checkedPaths);\n  return items.filter(el => !primaryUnion.includes(el));\n}\n\n/**\n * Get an flattened array of descendants at a particular relative\n * level of interest.\n * @param {object} node A node object.\n * @param {number} level The relative level of interest.\n * 0 for this node's children, 1 for grandchildren, etc.\n * @param {boolean} stopEarly Should a node be returned early if no children exist?\n * @returns {object[]} An array of descendants at the specified level,\n * where the level is relative to the node.\n */\nexport function nodeToLevelDescendantNamePaths(node, level, prevPath, stopEarly = false) {\n  if (!node.children) {\n    if (!stopEarly) {\n      return null;\n    }\n    return [[...prevPath, node.name]];\n  }\n  if (level === 0) {\n    return [[...prevPath, node.name]];\n  }\n  return node.children\n    .flatMap(c => nodeToLevelDescendantNamePaths(c, level - 1, [...prevPath, node.name], stopEarly))\n    .filter(Boolean);\n}\n\n/**\n * Export the tree by clearing tree state and all node states.\n * @param {object} currTree A tree object.\n * @returns {object} Tree object with tree and node state removed.\n */\nexport function treeExport(currTree, datatype) {\n  return {\n    version: HIERARCHICAL_SCHEMAS[datatype].latestVersion,\n    datatype,\n    tree: currTree.tree,\n  };\n}\n\n/**\n * Export the tree by clearing tree state and all node states,\n * and filter so that only the level zero node of interest is included.\n * @param {object} currTree A tree object.\n * @param {string} nodePath The path of the node of interest.\n * @param {string} dataType Datatype (i.e cell sets)\n * @param {Array} cellSetColors Array of objects of cell set colors and paths\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme\n * @returns {object} { treeToExport, nodeName }\n * Tree with one level zero node, and with state removed.\n */\nexport function treeExportLevelZeroNode(currTree, nodePath, datatype, cellSetColors, theme) {\n  const node = treeFindNodeByNamePath(currTree, nodePath);\n  const nodeWithColors = nodeTransformAll(node, () => true, (n, nPath) => {\n    const nodeColor = cellSetColors?.find(c => isEqual(c.path, nPath))?.color\n      ?? getDefaultColor(theme);\n    return {\n      ...n,\n      color: nodeColor.slice(0, 3),\n    };\n  }, []);\n  const treeWithOneLevelZeroNode = {\n    ...currTree,\n    tree: [nodeWithColors],\n  };\n  return {\n    treeToExport: treeExport(treeWithOneLevelZeroNode, datatype),\n    nodeName: node.name,\n  };\n}\n\n/**\n * Prepare the set of a node of interest for export.\n * @param {object} currTree A tree object.\n * @param {string} nodeKey The key of the node of interest.\n * @returns {object} { setToExport, nodeName } The set as an array.\n */\nexport function treeExportSet(currTree, nodePath) {\n  const node = treeFindNodeByNamePath(currTree, nodePath);\n  return { setToExport: nodeToSet(node), nodeName: node.name };\n}\n\n/**\n * Get an empty tree, with a default tree state.\n * @param {string} datatype The type of sets that this tree contains.\n * @returns {object} Empty tree.\n */\nexport function treeInitialize(datatype) {\n  return {\n    version: HIERARCHICAL_SCHEMAS[datatype].latestVersion,\n    datatype,\n    tree: [],\n  };\n}\n\n/**\n * For convenience, get an object with information required\n * to render a node as a component.\n * @param {object} node A node to be rendered.\n * @returns {object} An object containing properties required\n * by the TreeNode render functions.\n */\nexport function nodeToRenderProps(node, path, cellSetColor) {\n  const level = path.length - 1;\n  return {\n    title: node.name,\n    nodeKey: pathToKey(path),\n    path,\n    size: getNodeLength(node),\n    color: cellSetColor?.find(d => isEqual(d.path, path))?.color,\n    level,\n    isLeaf: (!node.children || node.children.length === 0) && Boolean(node.set),\n    height: nodeToHeight(node),\n  };\n}\n\n/**\n * Using a color and a probability, mix the color with an \"uncertainty\" color,\n * for example, gray.\n * Reference: https://github.com/bgrins/TinyColor/blob/80f7225029c428c0de0757f7d98ac15f497bee57/tinycolor.js#L701\n * @param {number[]} originalColor The color assignment for the class.\n * @param {number} p The mixing amount, or level certainty in the originalColor classification,\n * between 0 and 1.\n * @param {number[]} mixingColor The color with which to mix. By default, [128, 128, 128] gray.\n * @returns {number[]} Returns the color after mixing.\n */\nfunction colorMixWithUncertainty(originalColor, p, mixingColor = [128, 128, 128]) {\n  return [\n    ((originalColor[0] - mixingColor[0]) * p) + mixingColor[0],\n    ((originalColor[1] - mixingColor[1]) * p) + mixingColor[1],\n    ((originalColor[2] - mixingColor[2]) * p) + mixingColor[2],\n  ];\n}\n\n/**\n * Given a tree with state, get the cellIds and cellColors,\n * based on the nodes currently marked as \"visible\".\n * @param {object} currTree A tree object.\n *  @param {array} selectedNamePaths Array of arrays of strings,\n * representing set \"paths\".\n * @param {object[]} cellSetColor Array of objects with the\n * properties `path` and `color`.\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme\n * @returns {array} Tuple of [cellIds, cellColors]\n * where cellIds is an array of strings,\n * and cellColors is an object mapping cellIds to color [r,g,b] arrays.\n */\nexport function treeToCellColorsBySetNames(currTree, selectedNamePaths, cellSetColor, theme) {\n  let cellColorsArray = [];\n  selectedNamePaths.forEach((setNamePath) => {\n    const node = treeFindNodeByNamePath(currTree, setNamePath);\n    if (node) {\n      const nodeSet = nodeToSet(node);\n      const nodeColor = (\n        cellSetColor?.find(d => isEqual(d.path, setNamePath))?.color\n        || getDefaultColor(theme)\n      );\n      cellColorsArray = [\n        ...cellColorsArray,\n        ...nodeSet.map(([cellId, prob]) => [\n          cellId,\n          (isNil(prob) ? nodeColor : colorMixWithUncertainty(nodeColor, prob)),\n        ]),\n      ];\n    }\n  });\n  return new Map(cellColorsArray);\n}\n\n/**\n * Given a tree with state, get an array of\n * objects with cellIds and cellColors,\n * based on the nodes currently marked as \"visible\".\n * @param {object} currTree A tree object.\n * @param {array} selectedNamePaths Array of arrays of strings,\n * representing set \"paths\".\n * @param {object[]} setColor Array of objects with the\n * properties `path` and `color`\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme.\n * @returns {object[]} Array of objects with properties\n * `obsId`, `name`, and `color`.\n */\nexport function treeToObjectsBySetNames(currTree, selectedNamePaths, setColor, theme) {\n  let cellsArray = [];\n  for (let i = 0; i < selectedNamePaths.length; i += 1) {\n    const setNamePath = selectedNamePaths[i];\n    const node = treeFindNodeByNamePath(currTree, setNamePath);\n    if (node) {\n      const nodeSet = nodeToSet(node);\n      const nodeColor = (\n        setColor?.find(d => isEqual(d.path, setNamePath))?.color\n        || getDefaultColor(theme)\n      );\n      cellsArray = cellsArray.concat(nodeSet.map(([cellId]) => ({\n        obsId: cellId,\n        name: node.name,\n        color: nodeColor,\n      })));\n    }\n  }\n  return cellsArray;\n}\n\nexport function treeToCellPolygonsBySetNames(\n  currTree, cells, mapping, selectedNamePaths, cellSetColor, theme,\n) {\n  const cellSetPolygons = [];\n  selectedNamePaths.forEach((setNamePath) => {\n    const node = treeFindNodeByNamePath(currTree, setNamePath);\n    if (node) {\n      const nodeSet = nodeToSet(node);\n      const nodeColor = (\n        cellSetColor?.find(d => isEqual(d.path, setNamePath))?.color\n        || getDefaultColor(theme)\n      );\n      const cellPositions = nodeSet\n        .map(([cellId]) => ([\n          cells[cellId]?.mappings[mapping][0],\n          -cells[cellId]?.mappings[mapping][1],\n        ]))\n        .filter(cell => cell.every(i => typeof i === 'number'));\n\n      if (cellPositions.length > 2) {\n        const points = turfFeatureCollection(\n          cellPositions.map(turfPoint),\n        );\n        const concavity = Infinity;\n        const hullCoords = concaveman(cellPositions, concavity);\n        if (hullCoords) {\n          const centroidCoords = centroid(points).geometry.coordinates;\n          cellSetPolygons.push({\n            path: setNamePath,\n            name: setNamePath[setNamePath.length - 1],\n            hull: hullCoords,\n            color: nodeColor,\n            centroid: centroidCoords,\n          });\n        }\n      }\n    }\n  });\n  return cellSetPolygons;\n}\n\n/**\n * Given a tree with state, get the sizes of the\n * sets currently marked as \"visible\".\n * @param {object} currTree A tree object.\n * @param {array} selectedNamePaths Array of arrays of strings,\n * representing set \"paths\".\n * @param {object[]} setColor Array of objects with the\n * properties `path` and `color`.\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme\n * @returns {object[]} Array of objects\n * with the properties `name`, `size`, `key`,\n * and `color`.\n */\nexport function treeToSetSizesBySetNames(currTree, selectedNamePaths, setColor, theme) {\n  const sizes = [];\n  selectedNamePaths.forEach((setNamePath) => {\n    const node = treeFindNodeByNamePath(currTree, setNamePath);\n    if (node) {\n      const nodeSet = nodeToSet(node);\n      const nodeColor = setColor?.find(d => isEqual(d.path, setNamePath))?.color\n        || getDefaultColor(theme);\n      sizes.push({\n        key: generateKey(),\n        name: node.name,\n        size: nodeSet.length,\n        color: nodeColor,\n      });\n    }\n  });\n  return sizes;\n}\n\n/**\n * Find and remove a node from the descendants of the current node.\n * @param {object} node A node to search on.\n * @param {array} prevPath Path of the current node to be searched.\n * @param {array} filterPath The path sought.\n * @returns {object} A new node without a node at filterPath.\n */\nexport function filterNode(node, prevPath, filterPath) {\n  if (isEqual([...prevPath, node.name], filterPath)) {\n    return null;\n  }\n  if (!node.children) {\n    return node;\n  }\n  return {\n    ...node,\n    children: node.children.map(\n      c => filterNode(c, [...prevPath, node.name], filterPath),\n    ).filter(Boolean),\n  };\n}\n\nexport function treeToExpectedCheckedLevel(currTree, checkedPaths) {\n  let result = null;\n  if (currTree) {\n    currTree.tree.forEach((lzn) => {\n      const levelZeroPath = [lzn.name];\n      const height = nodeToHeight(lzn);\n      range(height).forEach((i) => {\n        const levelIndex = i + 1;\n        const levelNodePaths = nodeToLevelDescendantNamePaths(lzn, levelIndex, [], true);\n        if (isEqual(levelNodePaths, checkedPaths)) {\n          result = { levelZeroPath, levelIndex };\n        }\n      });\n    });\n  }\n  return result;\n}\n\nexport function treesConflict(cellSets, testCellSets) {\n  const paths = [];\n  const testPaths = [];\n  let hasConflict = false;\n\n  function getPaths(node, prevPath) {\n    paths.push([...prevPath, node.name]);\n    if (node.children) {\n      node.children.forEach(c => getPaths(c, [...prevPath, node.name]));\n    }\n  }\n  cellSets.tree.forEach(lzn => getPaths(lzn, []));\n\n  function getTestPaths(node, prevPath) {\n    testPaths.push([...prevPath, node.name]);\n    if (node.children) {\n      node.children.forEach(c => getPaths(c, [...prevPath, node.name]));\n    }\n  }\n  testCellSets.tree.forEach(lzn => getTestPaths(lzn, []));\n\n  testPaths.forEach((testPath) => {\n    if (paths.find(p => isEqual(p, testPath))) {\n      hasConflict = true;\n    }\n  });\n  return hasConflict;\n}\n\nexport function initializeCellSetColor(cellSets, cellSetColor) {\n  const nextCellSetColor = [...(cellSetColor || [])];\n  const nodeCountPerTreePerLevel = cellSets.tree.map(tree => Array\n    .from({\n      length: nodeToHeight(tree) + 1, // Need to add one because its an array.\n    }).fill(0));\n\n  function processNode(node, prevPath, hierarchyLevel, treeIndex) {\n    const index = nodeCountPerTreePerLevel[treeIndex][hierarchyLevel];\n    const nodePath = [...prevPath, node.name];\n\n    const nodeColor = nextCellSetColor.find(d => isEqual(d.path, nodePath));\n    if (!nodeColor) {\n      // If there is a color for the node specified via the cell set tree,\n      // then use it. Otherwise, use a color from the default color palette.\n      const nodeColorArray = (node.color ? node.color : PALETTE[index % PALETTE.length]);\n      nextCellSetColor.push({\n        path: nodePath,\n        color: nodeColorArray,\n      });\n    }\n    nodeCountPerTreePerLevel[treeIndex][hierarchyLevel] += 1;\n    if (node.children) {\n      node.children.forEach(c => processNode(c, nodePath, hierarchyLevel + 1, treeIndex));\n    }\n  }\n\n  cellSets.tree.forEach((lzn, treeIndex) => processNode(lzn, [], 0, treeIndex));\n  return nextCellSetColor;\n}\n\nexport function getCellSetPolygons(params) {\n  const {\n    cells,\n    mapping,\n    cellSets,\n    cellSetSelection,\n    cellSetColor,\n    theme,\n  } = params;\n  if (cellSetSelection && cellSetSelection.length > 0 && cellSets && cells) {\n    return treeToCellPolygonsBySetNames(\n      cellSets, cells, mapping, cellSetSelection, cellSetColor, theme,\n    );\n  }\n  return [];\n}\n","import Ajv from 'ajv';\nimport isNil from 'lodash/isNil';\nimport { dsvFormat } from 'd3-dsv';\nimport { parse as json2csv } from 'json2csv';\nimport { colorArrayToString, colorStringToArray } from './utils';\nimport { nodeTransform } from './cell-set-utils';\nimport { getDefaultColor } from '../utils';\nimport {\n  HIERARCHICAL_SCHEMAS, TABULAR_SCHEMAS,\n  MIME_TYPE_JSON, MIME_TYPE_TABULAR,\n  SEPARATOR_TABULAR, NA_VALUE_TABULAR,\n} from './constants';\n\n/**\n * Check if an imported tree has an old schema version that we know how to\n * \"upgrade\" to the latest schema version.  Validate against the schema.\n * @param {object} currTree A hierarchical tree object with a .version property,\n * which has already passed schema validation, but may not have the latest schema version.\n * @param {string} datatype The data type of the items in the schema.\n */\nexport function tryUpgradeTreeToLatestSchema(currTree, datatype) {\n  const validate = new Ajv().compile(HIERARCHICAL_SCHEMAS[datatype].schema);\n  const valid = validate(currTree);\n  if (!valid) {\n    const failureReason = JSON.stringify(validate.errors, null, 2);\n    throw new Error(`Tree validation failed: ${failureReason}`);\n  } else if (currTree.datatype !== datatype) {\n    throw new Error(\n      `The data type does not match the expected data type of '${datatype}'.`,\n    );\n  }\n  if (currTree.version === '0.1.2') {\n    // To upgrade from cell-sets schema 0.1.2 to 0.1.3,\n    // add a confidence value of null for each cell ID.\n    return {\n      ...currTree,\n      version: HIERARCHICAL_SCHEMAS[datatype].latestVersion,\n      tree: currTree.tree.map(levelZeroNode => nodeTransform(\n        levelZeroNode,\n        n => !n.children && Array.isArray(n.set),\n        n => ({ ...n, set: n.set.map(itemId => ([itemId, null])) }), [],\n      )),\n    };\n  }\n  return currTree;\n}\n\n/**\n * Handler for JSON imports. Validates and upgrades against the hierarchical sets schema.\n * @param {string} result The data passed from the FileReader as a string.\n * @param {string} datatype The data type to validate against.\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme\n * @returns {object} The imported tree object.\n * @throws {Error} Throws error if validation fails or if the datatype does not match.\n */\n// eslint-disable-next-line no-unused-vars\nexport function handleImportJSON(result, datatype, theme) {\n  let importData = JSON.parse(result);\n  // Validate the imported file.\n  importData = tryUpgradeTreeToLatestSchema(importData, datatype);\n  return importData;\n}\n\n/**\n * Handler for tabular imports. Validates against the tabular sets schema.\n * @param {string} result The data passed from the FileReader as a string.\n * @param {string} datatype The data type to validate against.\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme\n * @returns {object} The imported tree object.\n * @throws {Error} Throws error if validation fails or if the datatype does not match.\n */\nexport function handleImportTabular(result, datatype, theme) {\n  const dsvParser = dsvFormat(SEPARATOR_TABULAR);\n  const importData = dsvParser.parse(result, row => ({\n    groupName: row.groupName,\n    setName: row.setName,\n    setColor: (row.setColor ? colorStringToArray(row.setColor) : getDefaultColor(theme)),\n    obsId: row.obsId,\n    predictionScore: (\n      (\n        isNil(row.predictionScore)\n        || row.predictionScore === NA_VALUE_TABULAR\n      )\n        ? null\n        : +row.predictionScore\n    ),\n  }));\n  // Validate the imported file.\n  const validate = new Ajv().compile(TABULAR_SCHEMAS[datatype].schema);\n  const valid = validate(importData);\n  if (!valid) {\n    const failureReason = JSON.stringify(validate.errors, null, 2);\n    throw new Error(`Import validation failed: ${failureReason}`);\n  } else {\n    // Convert the validated array to a tree representation.\n    const treeToImport = {\n      version: HIERARCHICAL_SCHEMAS[datatype].latestVersion,\n      datatype,\n      tree: [],\n    };\n    const uniqueGroupNames = Array.from(new Set(importData.map(d => d.groupName)));\n    uniqueGroupNames.forEach((groupName) => {\n      const levelZeroNode = {\n        name: groupName,\n        children: [],\n      };\n      const groupRows = importData.filter(d => d.groupName === groupName);\n      const uniqueSetNames = Array.from(new Set(groupRows.map(d => d.setName)));\n      uniqueSetNames.forEach((setName) => {\n        const setRows = groupRows.filter(d => d.setName === setName);\n        const { setColor } = setRows[0];\n        const levelOneNode = {\n          name: setName,\n          color: setColor,\n          set: setRows.map(d => ([d.obsId, d.predictionScore])),\n        };\n        levelZeroNode.children.push(levelOneNode);\n      });\n      treeToImport.tree.push(levelZeroNode);\n    });\n    return treeToImport;\n  }\n}\n\n/**\n * Convert a tree object to a JSON representation.\n * @param {object} result The object to export.\n * @returns {string} The data in a string representation.\n */\nexport function handleExportJSON(result) {\n  const jsonString = JSON.stringify(result);\n  const dataString = `data:${MIME_TYPE_JSON};charset=utf-8,${encodeURIComponent(jsonString)}`;\n  return dataString;\n}\n\n/**\n * Convert a tree object with one level (height === 1) to a tabular representation.\n * @param {object} result The object to export.\n * @returns {string} The data in a string representation.\n */\nexport function handleExportTabular(result) {\n  // Convert a tree object to an array of JSON objects.\n  const exportData = [];\n  result.tree.forEach((levelZeroNode) => {\n    levelZeroNode.children.forEach((levelOneNode) => {\n      if (levelOneNode.set) {\n        levelOneNode.set.forEach(([obsId, prob]) => {\n          exportData.push({\n            groupName: levelZeroNode.name,\n            setName: levelOneNode.name,\n            setColor: colorArrayToString(levelOneNode.color),\n            obsId,\n            predictionScore: isNil(prob) ? NA_VALUE_TABULAR : prob,\n          });\n        });\n      }\n    });\n  });\n  const csvString = json2csv(exportData, {\n    fields: ['groupName', 'setName', 'setColor', 'obsId', 'predictionScore'],\n    delimiter: SEPARATOR_TABULAR,\n  });\n  const dataString = `data:${MIME_TYPE_TABULAR};charset=utf-8,${encodeURIComponent(csvString)}`;\n  return dataString;\n}\n\n/**\n * Download a file. Appends and removes an anchor node in the DOM.\n * @param {string} dataString The function that converts the data to a string.\n * @param {string} fileName The name of the file to be downloaded.\n */\nexport function downloadForUser(dataString, fileName) {\n  const downloadAnchorNode = document.createElement('a');\n  downloadAnchorNode.setAttribute('href', dataString);\n  downloadAnchorNode.setAttribute('download', fileName);\n  document.body.appendChild(downloadAnchorNode); // required for firefox\n  downloadAnchorNode.click();\n  downloadAnchorNode.remove();\n}\n","import cellSetsSchema from '../schemas/cell-sets.schema.json';\nimport JsonLoader from './JsonLoader';\nimport { tryUpgradeTreeToLatestSchema } from '../components/sets/io';\nimport { AbstractLoaderError } from './errors';\nimport LoaderResult from './LoaderResult';\n\nimport { initializeCellSetColor } from '../components/sets/cell-set-utils';\n\nexport default class CellSetsJsonLoader extends JsonLoader {\n  constructor(dataSource, params) {\n    super(dataSource, params);\n\n    this.schema = cellSetsSchema;\n  }\n\n  async load() {\n    const payload = await super.load().catch(reason => Promise.resolve(reason));\n    if (payload instanceof AbstractLoaderError) {\n      return Promise.reject(payload);\n    }\n    const { data: rawData, url } = payload;\n    const upgradedData = tryUpgradeTreeToLatestSchema(rawData, 'cell');\n\n    const coordinationValues = {\n      cellSetSelection: [],\n      cellSetColor: [],\n    };\n\n    // Set up the initial coordination values.\n    if (upgradedData && upgradedData.tree.length >= 1) {\n      const { tree } = upgradedData;\n      const newAutoSetSelectionParentName = tree[0].name;\n      // Create a list of set paths to initally select.\n      const newAutoSetSelections = tree[0].children\n        .map(node => ([newAutoSetSelectionParentName, node.name]));\n      // Create a list of cell set objects with color mappings.\n      const newAutoSetColors = initializeCellSetColor(upgradedData, []);\n      coordinationValues.cellSetSelection = newAutoSetSelections;\n      coordinationValues.cellSetColor = newAutoSetColors;\n    }\n    return Promise.resolve(new LoaderResult(upgradedData, url, coordinationValues));\n  }\n}\n","/* eslint-disable no-control-regex */\nimport { InternMap } from 'internmap';\nimport {\n  treeInitialize,\n  nodeAppendChild,\n  initializeCellSetColor,\n} from '../../components/sets/cell-set-utils';\nimport {\n  SETS_DATATYPE_CELL,\n} from '../../components/sets/constants';\nimport AbstractTwoStepLoader from '../AbstractTwoStepLoader';\nimport LoaderResult from '../LoaderResult';\n\nexport function dataToCellSetsTree(data, options) {\n  const [cellNames, cellSets, cellSetScores] = data;\n  const cellSetsTree = treeInitialize(SETS_DATATYPE_CELL);\n  cellSets.forEach((cellSetIds, j) => {\n    const name = options[j].groupName;\n    let levelZeroNode = {\n      name,\n      children: [],\n    };\n    if (cellSetIds.length > 0 && Array.isArray(cellSetIds[0])) {\n      // Multi-level case.\n      const levelSets = new InternMap([], JSON.stringify);\n\n      cellNames.forEach((id, i) => {\n        const classes = cellSetIds.map(col => col[i]);\n        if (levelSets.has(classes)) {\n          levelSets.get(classes).push([id, null]);\n        } else {\n          levelSets.set(classes, [[id, null]]);\n        }\n      });\n\n      const levels = Array.from(levelSets.keys());\n\n      const getNextLevelNames = (levelSuffixes) => {\n        const nextLevelNames = Array.from(new Set(levelSuffixes.map(l => l[0])));\n        return nextLevelNames.sort((a, b) => a.localeCompare(b));\n      };\n\n      // Recursive function to create nodes.\n      const getNode = (parentLevelPrefixes, currLevelName, childLevelSuffixes) => {\n        const isLeaf = childLevelSuffixes.length === 0;\n        const resultNode = {\n          name: currLevelName,\n        };\n        if (isLeaf) {\n          // Base case: this is a leaf node.\n          resultNode.set = levelSets.get([...parentLevelPrefixes, currLevelName]);\n        } else {\n          // Are the remaining suffices redundant?\n          // Consider [\"Parent\", \"Child\", \"Child\"]\n          // where parentLevelPrefixes is [\"Parent\"] and currLevelName is \"Child\".\n          const shouldBeLeaf = (\n            childLevelSuffixes.length === 1\n            && currLevelName === childLevelSuffixes[0][childLevelSuffixes[0].length - 1]\n          );\n          if (shouldBeLeaf) {\n            resultNode.set = levelSets.get(\n              [...parentLevelPrefixes, currLevelName, ...childLevelSuffixes[0]],\n            );\n          } else {\n            // Recursion, run getNode() on each of the unique names at the next level.\n            const nextLevelNames = getNextLevelNames(childLevelSuffixes);\n\n            resultNode.children = nextLevelNames\n              .map(nextLevelName => getNode(\n                [...parentLevelPrefixes, currLevelName],\n                nextLevelName,\n                childLevelSuffixes\n                  .filter(l => l[0] === nextLevelName)\n                  .map(l => l.slice(1))\n                  .filter(v => v.length > 0),\n              ));\n          }\n        }\n        return resultNode;\n      };\n      // Start the recursion.\n      const levelOneNodes = getNextLevelNames(levels)\n        .map(levelOneName => getNode(\n          [],\n          levelOneName,\n          levels.filter(l => l[0] === levelOneName).map(l => l.slice(1)),\n        ));\n\n      levelZeroNode.children = levelOneNodes;\n    } else {\n      // Single-level case.\n      // Check for the optional corresponding confidence score column name.\n      const uniqueCellSetIds = Array.from(new Set(cellSetIds)).sort();\n      const clusters = {};\n      // eslint-disable-next-line no-return-assign\n      uniqueCellSetIds.forEach(id => (clusters[id] = { name: id, set: [] }));\n      if (cellSetScores[j]) {\n        cellSetIds.forEach((id, i) => clusters[id].set.push([cellNames[i], cellSetScores[j][i]]));\n      } else {\n        cellSetIds.forEach((id, i) => clusters[id].set.push([cellNames[i], null]));\n      }\n      Object.values(clusters).forEach(\n        // eslint-disable-next-line no-return-assign\n        cluster => (levelZeroNode = nodeAppendChild(levelZeroNode, cluster)),\n      );\n    }\n    cellSetsTree.tree.push(levelZeroNode);\n  });\n  return cellSetsTree;\n}\n\n/**\n * Loader for converting zarr into the cell sets json schema.\n */\nexport default class CellSetsZarrLoader extends AbstractTwoStepLoader {\n  loadCellSetIds() {\n    const { options } = this;\n    const cellSetZarrLocation = options.map(({ setName }) => setName);\n    return this.dataSource.loadObsVariables(cellSetZarrLocation);\n  }\n\n  loadCellSetScores() {\n    const { options } = this;\n    const cellSetScoreZarrLocation = options.map(option => option.scoreName || undefined);\n    return this.dataSource.loadObsVariables(cellSetScoreZarrLocation);\n  }\n\n  async load() {\n    if (!this.cellSetsTree) {\n      const { options } = this;\n      this.cellSetsTree = Promise.all([\n        this.dataSource.loadObsIndex(),\n        this.loadCellSetIds(),\n        this.loadCellSetScores(),\n      ]).then(data => dataToCellSetsTree(data, options));\n    }\n    const cellSetsTree = await this.cellSetsTree;\n    const coordinationValues = {};\n    const { tree } = cellSetsTree;\n    const newAutoSetSelectionParentName = tree[0].name;\n    // Create a list of set paths to initally select.\n    const newAutoSetSelections = tree[0].children.map(node => [\n      newAutoSetSelectionParentName,\n      node.name,\n    ]);\n    // Create a list of cell set objects with color mappings.\n    const newAutoSetColors = initializeCellSetColor(cellSetsTree, []);\n    coordinationValues.cellSetSelection = newAutoSetSelections;\n    coordinationValues.cellSetColor = newAutoSetColors;\n    return Promise.resolve(\n      new LoaderResult(cellSetsTree, null, coordinationValues),\n    );\n  }\n}\n","/* eslint-disable no-underscore-dangle */\nimport { openArray, slice } from 'zarr';\nimport { extent } from 'd3-array';\nimport LoaderResult from '../LoaderResult';\nimport AbstractTwoStepLoader from '../AbstractTwoStepLoader';\n\nconst normalize = (arr) => {\n  const [min, max] = extent(arr);\n  const ratio = 255 / (max - min);\n  const data = new Uint8Array(\n    arr.map(i => Math.floor((i - min) * ratio)),\n  );\n  return { data };\n};\n\nconst concatenateColumnVectors = (arr) => {\n  const numCols = arr.length;\n  const numRows = arr[0].length;\n  const { BYTES_PER_ELEMENT } = arr[0];\n  const view = new DataView(new ArrayBuffer(numCols * numRows * BYTES_PER_ELEMENT));\n  const TypedArray = arr[0].constructor;\n  const dtype = TypedArray.name.replace('Array', '');\n  for (let i = 0; i < numCols; i += 1) {\n    for (let j = 0; j < numRows; j += 1) {\n      view[`set${dtype}`](BYTES_PER_ELEMENT * (j * numCols + i), arr[i][j], true);\n    }\n  }\n  return new TypedArray(view.buffer);\n};\n\n/**\n * Loader for converting zarr into the a cell x gene matrix for use in Genes/Heatmap components.\n */\nexport default class MatrixZarrLoader extends AbstractTwoStepLoader {\n  /**\n   * Class method for loading the genes list from AnnData.var,\n   * filtered if a there is a `geneFilterZarr` present in the view config.\n   * @returns {Promise} A promise for the zarr array contianing the gene names.\n   */\n  async loadFilteredGeneNames() {\n    if (this.filteredGeneNames) {\n      return this.filteredGeneNames;\n    }\n    const { geneFilter: geneFilterZarr } = this.options;\n    const getFilterFn = async () => {\n      if (!geneFilterZarr) return data => data;\n      const geneFilter = await this.dataSource.getFlatArrDecompressed(geneFilterZarr);\n      return data => data.filter((_, j) => geneFilter[j]);\n    };\n\n    this.filteredGeneNames = Promise\n      .all([this.dataSource.loadVarIndex(), getFilterFn()])\n      .then(([data, filter]) => filter(data));\n    return this.filteredGeneNames;\n  }\n\n  /**\n   * Class method for loading a filtered subset of the genes list\n   * @param {String} filterZarr A location in the zarr store to fetch a boolean array from.\n   * @returns {Array} A list of filtered genes.\n   */\n  async _getFilteredGenes(filterZarr) {\n    const filter = await this.dataSource.getFlatArrDecompressed(filterZarr);\n    const geneNames = await this.loadFilteredGeneNames();\n    const genes = geneNames.filter((_, i) => filter[i]);\n    return genes;\n  }\n\n  /**\n   * Class method for getting the integer indices of a selection of genes within a list.\n   * @param {Array} selection A list of gene names.\n   * @returns {Array} A list of integer indices.\n   */\n  async _getGeneIndices(selection) {\n    const geneNames = await this.loadFilteredGeneNames();\n    return selection.map(gene => geneNames.indexOf(gene));\n  }\n\n  /**\n   * Class method for getting the number of cells i.e entries in `obs`.\n   * @returns {Number} The number of cells.\n   */\n  async _getNumCells() {\n    const cells = await this.dataSource.loadObsIndex();\n    return cells.length;\n  }\n\n  /**\n   * Class method for getting the number of genes i.e entries in `var`,\n   * potentially filtered by `genesFilter`.\n   * @returns {Number} The number of genes.\n   */\n  async _getNumGenes() {\n    const genes = await this.loadFilteredGeneNames();\n    return genes.length;\n  }\n\n  /**\n   * Class method for opening the sparse matrix arrays in zarr.\n   * @returns {Array} A list of promises pointing to the indptr, indices, and data of the matrix.\n   */\n  async _openSparseArrays() {\n    const { options: { matrix } } = this;\n    const { store } = this.dataSource;\n    if (this.sparseArrays) {\n      return this.sparseArrays;\n    }\n    this.sparseArrays = Promise.all(\n      ['indptr', 'indices', 'data'].map(name => openArray({ store, path: `${matrix}/${name}`, mode: 'r' })),\n    );\n    return this.sparseArrays;\n  }\n\n  /**\n   * Class method for loading a gene selection from a CSC matrix.\n   * @param {Array} selection A list of gene names whose data should be fetched.\n   * @returns {Promise} A Promise.all array of promises containing Uint8Arrays, one per selection.\n   */\n  async _loadCSCGeneSelection(selection) {\n    const indices = await this._getGeneIndices(selection);\n    const [indptrArr, indexArr, cellXGeneArr] = await this._openSparseArrays();\n    const numCells = await this._getNumCells();\n    const { data: cols } = await indptrArr.getRaw(null);\n    // If there is not change in the column indexer, then the data is all zeros\n    return Promise.all(\n      indices.map(async (index) => {\n        const startRowIndex = cols[index];\n        const endRowIndex = cols[index + 1];\n        const isColumnAllZeros = startRowIndex === endRowIndex;\n        const geneData = new Float32Array(numCells).fill(0);\n        if (isColumnAllZeros) {\n          return geneData;\n        }\n        const { data: rowIndices } = await indexArr.get([\n          slice(startRowIndex, endRowIndex),\n        ]);\n        const { data: cellXGeneData } = await cellXGeneArr.get([\n          slice(startRowIndex, endRowIndex),\n        ]);\n        for (let rowIndex = 0; rowIndex < rowIndices.length; rowIndex += 1) {\n          geneData[rowIndices[rowIndex]] = cellXGeneData[rowIndex];\n        }\n        return geneData;\n      }),\n    );\n  }\n\n  /**\n   * Class method for loading a gene selection from a CSR matrix.\n   * @param {Array} selection A list of gene names whose data should be fetched.\n   * @returns {Promise} A Promise.all array of promises containing Uint8Arrays, one per selection.\n   */\n  async _loadCSRGeneSelection(selection) {\n    const indices = await this._getGeneIndices(selection);\n    const numGenes = await this._getNumGenes();\n    const numCells = await this._getNumCells();\n    const cellXGene = await this._loadCSRSparseCellXGene();\n    return indices.map((index) => {\n      const geneData = new Float32Array(numCells).fill(0);\n      for (let i = 0; i < numCells; i += 1) {\n        geneData[i] = cellXGene[i * numGenes + index];\n      }\n      return geneData;\n    });\n  }\n\n  /**\n   * Class method for loading row oriented (CSR) sparse data from zarr.\n   *\n   * @returns {Object} A { data: Float32Array } contianing the CellXGene matrix.\n   */\n  async _loadCSRSparseCellXGene() {\n    if (this._sparseMatrix) {\n      return this._sparseMatrix;\n    }\n    this._sparseMatrix = this._openSparseArrays().then(async (sparseArrays) => {\n      const { options: { matrix } } = this;\n      const { shape } = await this.dataSource.getJson(`${matrix}/.zattrs`);\n      const [rows, cols, cellXGene] = await Promise.all(\n        sparseArrays.map(async (arr) => {\n          const { data } = await arr.getRaw(null);\n          return data;\n        }),\n      );\n      const cellXGeneMatrix = new Float32Array(shape[0] * shape[1]).fill(0);\n      let row = 0;\n      rows.forEach((_, index) => {\n        const rowStart = rows[index];\n        const rowEnd = rows[index + 1];\n        for (let i = rowStart; i < rowEnd; i += 1) {\n          const val = cellXGene[i];\n          const col = cols[i];\n          cellXGeneMatrix[row * shape[1] + col] = val;\n        }\n        row += 1;\n      });\n      return cellXGeneMatrix;\n    });\n    return this._sparseMatrix;\n  }\n\n  /**\n   * Class method for loading column oriented (CSC) sparse data from zarr.\n   * @returns {Object} A { data: Float32Array } contianing the CellXGene matrix.\n   */\n  async _loadCSCSparseCellXGene() {\n    if (this._sparseMatrix) {\n      return this._sparseMatrix;\n    }\n    this._sparseMatrix = this._openSparseArrays().then(async (sparseArrays) => {\n      const { options: { matrix } } = this;\n      const { shape } = await this.dataSource.getJson(`${matrix}/.zattrs`);\n      const [cols, rows, cellXGene] = await Promise.all(\n        sparseArrays.map(async (arr) => {\n          const { data } = await arr.getRaw(null);\n          return data;\n        }),\n      );\n      const cellXGeneMatrix = new Float32Array(shape[0] * shape[1]).fill(0);\n      let col = 0;\n      cols.forEach((_, index) => {\n        const colStart = cols[index];\n        const colEnd = cols[index + 1];\n        for (let i = colStart; i < colEnd; i += 1) {\n          const val = cellXGene[i];\n          const row = rows[i];\n          cellXGeneMatrix[row * shape[1] + col] = val;\n        }\n        col += 1;\n      });\n      return cellXGeneMatrix;\n    });\n    return this._sparseMatrix;\n  }\n\n  /**\n   * Class method for loading the cell x gene matrix.\n   * @returns {Promise} A promise for the zarr array contianing the cell x gene data.\n   */\n  async loadCellXGene() {\n    const { store } = this.dataSource;\n    if (this.cellXGene) {\n      return this.cellXGene;\n    }\n    const { options: { matrix, matrixGeneFilter } } = this;\n    if (!this._matrixZattrs) {\n      this._matrixZattrs = await this.dataSource.getJson(`${matrix}/.zattrs`);\n    }\n    const encodingType = this._matrixZattrs['encoding-type'];\n    if (!matrixGeneFilter) {\n      if (encodingType === 'csr_matrix') {\n        this.cellXGene = this._loadCSRSparseCellXGene().then(data => normalize(data));\n      } else if (encodingType === 'csc_matrix') {\n        this.cellXGene = this._loadCSCSparseCellXGene().then(data => normalize(data));\n      } else {\n        if (!this.arr) {\n          this.arr = openArray({ store, path: matrix, mode: 'r' });\n        }\n        this.cellXGene = this.arr.then(z => z.getRaw(null).then(({ data }) => normalize(data)));\n      }\n    } else if (encodingType === 'csr_matrix') {\n      this.cellXGene = this._loadCSRSparseCellXGene().then(\n        async (cellXGene) => {\n          const filteredGenes = await this._getFilteredGenes(matrixGeneFilter);\n          const numGenesFiltered = filteredGenes.length;\n          const geneNames = await this.loadFilteredGeneNames();\n          const numGenes = geneNames.length;\n          const numCells = await this._getNumCells();\n          const cellXGeneMatrixFiltered = new Float32Array(\n            numCells * numGenesFiltered,\n          ).fill(0);\n          for (let i = 0; i < numGenesFiltered; i += 1) {\n            const index = geneNames.indexOf(filteredGenes[i]);\n            for (let j = 0; j < numCells; j += 1) {\n              cellXGeneMatrixFiltered[j * numGenesFiltered + i] = cellXGene[j * numGenes + index];\n            }\n          }\n          return normalize(cellXGeneMatrixFiltered);\n        },\n      );\n    } else {\n      const genes = await this._getFilteredGenes(matrixGeneFilter);\n      this.cellXGene = this.loadGeneSelection({ selection: genes, shouldNormalize: false })\n        .then(({ data }) => (normalize(concatenateColumnVectors(data))));\n    }\n    return this.cellXGene;\n  }\n\n  /**\n   * Class method for loading a gene selection.\n   * @param {Object} args\n   * @param {Array} args.selection A list of gene names whose data should be fetched.\n   * @param {Boolean} args.shouldNormalize A list of gene names whose data should be fetched.\n   * @returns {Object} { data } containing an array of gene expression data.\n   */\n  async loadGeneSelection({ selection, shouldNormalize = true }) {\n    const { options: { matrix } } = this;\n    const { store } = this.dataSource;\n    if (!this._matrixZattrs) {\n      this._matrixZattrs = await this.dataSource.getJson(`${matrix}/.zattrs`);\n    }\n    const encodingType = this._matrixZattrs['encoding-type'];\n    let genes;\n    if (encodingType === 'csc_matrix') {\n      genes = await this._loadCSCGeneSelection(selection);\n    } else if (encodingType === 'csr_matrix') {\n      genes = await this._loadCSRGeneSelection(selection);\n    } else {\n      if (!this.arr) {\n        this.arr = openArray({ store, path: matrix, mode: 'r' });\n      }\n      const indices = await this._getGeneIndices(selection);\n      // We can index directly into a normal dense array zarr store via `get`.\n      genes = await Promise.all(\n        indices.map(index => this.arr.then(z => z.get([null, index])).then(({ data }) => data)),\n      );\n    }\n    return { data: genes.map(i => (shouldNormalize ? normalize(i).data : i)), url: null };\n  }\n\n  /**\n   * Class method for loading only attributes i.e rows and columns\n   * @param {Array} selection A list of gene names whose data should be fetched.\n   * @returns {Object} { data: { rows, cols }, url } containing row and col labels for the matrix.\n   */\n  loadAttrs() {\n    return Promise.all([this.dataSource.loadObsIndex(), this.loadFilteredGeneNames()])\n      .then((d) => {\n        const [cellNames, geneNames] = d;\n        const attrs = { rows: cellNames, cols: geneNames };\n        return {\n          data: attrs,\n          url: null,\n        };\n      });\n  }\n\n  load() {\n    return Promise.all([this.loadAttrs(), this.loadCellXGene()]).then(\n      async (d) => {\n        const [{ data: attrs }, cellXGene] = d;\n        const {\n          options: { matrixGeneFilter: matrixGeneFilterZarr },\n        } = this;\n        // In order to return the correct gene list with the heatmap data,\n        // we need to filter the columns of attrs so it matches the cellXGene data.\n        if (matrixGeneFilterZarr) {\n          const matrixGeneFilter = await this.dataSource.getFlatArrDecompressed(\n            matrixGeneFilterZarr,\n          );\n          attrs.cols = attrs.cols.filter((_, i) => matrixGeneFilter[i]);\n        }\n        return Promise.resolve(new LoaderResult([attrs, cellXGene], null));\n      },\n    );\n  }\n}\n","import CellSetsZarrLoader from './CellSetsZarrLoader';\nimport CellsZarrLoader from './CellsZarrLoader';\nimport MatrixZarrLoader from './MatrixZarrLoader';\n\nexport default { CellSetsZarrLoader, CellsZarrLoader, MatrixZarrLoader };\n","import LoaderResult from '../LoaderResult';\nimport AbstractTwoStepLoader from '../AbstractTwoStepLoader';\n\n/**\n * Loader for converting zarr into the cell json schema.\n */\nexport default class CellsZarrLoader extends AbstractTwoStepLoader {\n  /**\n   * Class method for loading spatial cell centroids.\n   * @returns {Promise} A promise for an array of tuples/triples for cell centroids.\n   */\n  loadXy() {\n    const { xy } = (this.options || {});\n    if (this.xy) {\n      return this.xy;\n    }\n    if (!this.xy && xy) {\n      this.xy = this.dataSource.loadNumeric(xy);\n      return this.xy;\n    }\n    this.xy = Promise.resolve(null);\n    return this.xy;\n  }\n\n  /**\n   * Class method for loading spatial cell polygons.\n   * @returns {Promise} A promise for an array of arrays for cell polygons.\n   */\n  loadPoly() {\n    const { poly } = (this.options || {});\n    if (this.poly) {\n      return this.poly;\n    }\n    if (!this.poly && poly) {\n      this.poly = this.dataSource.loadNumeric(poly);\n      return this.poly;\n    }\n    this.poly = Promise.resolve(null);\n    return this.poly;\n  }\n\n  /**\n   * Class method for loading various mappings, like UMAP or tSNE cooridnates.\n   * @returns {Promise} A promise for an array of tuples of coordinates.\n   */\n  loadMappings() {\n    const { mappings } = (this.options || {});\n    if (this.mappings) {\n      return this.mappings;\n    }\n    if (!this.mappings && mappings) {\n      this.mappings = Promise.all(\n        Object.keys(mappings).map(async (coordinationName) => {\n          const { key } = mappings[coordinationName];\n          return { coordinationName, arr: await this.dataSource.loadNumeric(key) };\n        }),\n      );\n      return this.mappings;\n    }\n    this.mappings = Promise.resolve(null);\n    return this.mappings;\n  }\n\n  /**\n   * Class method for loading factors, which are cell set ids.\n   * @returns {Promise} A promise for an array of an array of strings of ids,\n   * where subarray is a clustering/factor.\n   */\n  loadFactors() {\n    const { factors } = (this.options || {});\n    if (factors) {\n      return this.dataSource.loadObsVariables(factors);\n    }\n    return Promise.resolve(null);\n  }\n\n  async load() {\n    if (!this.cells) {\n      this.cells = Promise.all([\n        this.loadMappings(),\n        this.loadXy(),\n        this.loadPoly(),\n        this.dataSource.loadObsIndex(),\n        this.loadFactors(),\n      ]).then(([mappings, xy, poly, cellNames, factors]) => {\n        const cells = {};\n        cellNames.forEach((name, i) => {\n          cells[name] = {};\n          if (mappings) {\n            mappings.forEach(({ coordinationName, arr }) => {\n              if (!cells[name].mappings) {\n                cells[name].mappings = {};\n              }\n              const { dims } = this.options.mappings[coordinationName];\n              cells[name].mappings[coordinationName] = dims.map(\n                dim => arr.data[i][dim],\n              );\n            });\n          }\n          if (xy) {\n            cells[name].xy = xy.data[i];\n          }\n          if (poly) {\n            cells[name].poly = poly.data[i];\n          }\n          if (factors) {\n            const factorsObj = {};\n            factors.forEach(\n              // eslint-disable-next-line no-return-assign\n              (factor, j) => (factorsObj[this.options.factors[j].split('/').slice(-1)] = factor[i]),\n            );\n            cells[name].factors = factorsObj;\n          }\n        });\n        return cells;\n      });\n    }\n    return Promise.resolve(new LoaderResult(await this.cells, null));\n  }\n}\n","import AbstractTwoStepLoader from './AbstractTwoStepLoader';\nimport LoaderResult from './LoaderResult';\n\nexport default class GenomicProfilesZarrLoader extends AbstractTwoStepLoader {\n  loadAttrs() {\n    if (this.attrs) {\n      return this.attrs;\n    }\n    this.attrs = this.dataSource.getJson('.zattrs');\n    return this.attrs;\n  }\n\n  load() {\n    const { url } = this;\n    return this.loadAttrs()\n      .then(attrs => Promise.resolve(new LoaderResult(attrs, url)));\n  }\n}\n","import { HTTPStore, KeyError } from 'zarr';\n\n/**\n * A loader ancestor class containing a default constructor\n * and a stub for the required load() method.\n */\nexport default class ZarrDataSource {\n  constructor({ url, requestInit }) {\n    // TODO: We should probably add a way of allowing HEAD requests as well:\n    // https://github.com/gzuidhof/zarr.js/blob/375ce0c299469a970da6bb5653513564e25806bb/docs/getting-started/remote-data.md#stores\n    const supportedMethods = ['GET'];\n    this.store = new HTTPStore(url, {\n      supportedMethods, fetchOptions: requestInit,\n    });\n  }\n\n  /**\n   * Class method for decoding json from the store.\n   * @param {string} key A path to the item.\n   * @returns {Promise} This async function returns a promise\n   * that resolves to the parsed JSON if successful.\n   * @throws This may throw an error.\n   */\n  async getJson(key) {\n    try {\n      const buf = await this.store.getItem(key);\n      const text = new TextDecoder('utf-8').decode(buf);\n      return JSON.parse(text);\n    } catch (err) {\n      if (err instanceof KeyError) {\n        return {};\n      }\n      throw err;\n    }\n  }\n}\n","/* eslint-disable no-underscore-dangle */\nimport { openArray } from 'zarr';\nimport range from 'lodash/range';\nimport ZarrDataSource from './ZarrDataSource';\n\nconst readFloat32FromUint8 = (bytes) => {\n  if (bytes.length !== 4) {\n    throw new Error('readFloat32 only takes in length 4 byte buffers');\n  }\n  return new Int32Array(bytes.buffer)[0];\n};\n\nconst HEADER_LENGTH = 4;\n\n/**\n   * Method for decoding text arrays from zarr.\n   * Largerly a port of https://github.com/zarr-developers/numcodecs/blob/2c1aff98e965c3c4747d9881d8b8d4aad91adb3a/numcodecs/vlen.pyx#L135-L178\n   * @returns {string[]} An array of strings.\n   */\nfunction parseVlenUtf8(buffer) {\n  const decoder = new TextDecoder();\n  let data = 0;\n  const dataEnd = data + buffer.length;\n  const length = readFloat32FromUint8(buffer.slice(data, HEADER_LENGTH));\n  if (buffer.length < HEADER_LENGTH) {\n    throw new Error('corrupt buffer, missing or truncated header');\n  }\n  data += HEADER_LENGTH;\n  const output = new Array(length);\n  for (let i = 0; i < length; i += 1) {\n    if (data + 4 > dataEnd) {\n      throw new Error('corrupt buffer, data seem truncated');\n    }\n    const l = readFloat32FromUint8(buffer.slice(data, data + 4));\n    data += 4;\n    if (data + l > dataEnd) {\n      throw new Error('corrupt buffer, data seem truncated');\n    }\n    output[i] = decoder.decode(buffer.slice(data, data + l));\n    data += l;\n  }\n  return output;\n}\n\n/**\n * A base AnnData loader which has all shared methods for more comlpex laoders,\n * like loading cell names and ids. It inherits from AbstractLoader.\n */\nexport default class AnnDataSource extends ZarrDataSource {\n  constructor(...args) {\n    super(...args);\n    /** @type {Map<string, Promise<string[]>} */\n    this.obsPromises = new Map();\n  }\n\n  /**\n   * Class method for loading obs variables.\n   * Takes the location as an argument because this is shared across objects,\n   * which have different ways of specifying location.\n   * @param {string[]} obsPaths An array of strings like \"obs/leiden\" or \"obs/bulk_labels.\"\n   * @returns {Promise} A promise for an array of ids with one per cell.\n   */\n  loadObsVariables(obsPaths) {\n    const obsPromises = obsPaths.map((obsPath) => {\n      const getObsCol = (obsCol) => {\n        if (!this.obsPromises.has(obsCol)) {\n          const obsPromise = this._loadObsVariable(obsCol).catch((err) => {\n            // clear from cache if promise rejects\n            this.obsPromises.delete(obsCol);\n            // propagate error\n            throw err;\n          });\n          this.obsPromises.set(obsCol, obsPromise);\n        }\n        return this.obsPromises.get(obsCol);\n      };\n      if (!obsPath) {\n        return Promise.resolve(undefined);\n      }\n      if (Array.isArray(obsPath)) {\n        return Promise.resolve(Promise.all(obsPath.map(getObsCol)));\n      }\n      return getObsCol(obsPath);\n    });\n    return Promise.all(obsPromises);\n  }\n\n  async _loadObsVariable(obs) {\n    const { store } = this;\n    const { categories } = await this.getJson(`${obs}/.zattrs`);\n    let categoriesValues;\n    if (categories) {\n      const { dtype } = await this.getJson(`/obs/${categories}/.zarray`);\n      if (dtype === '|O') {\n        categoriesValues = await this.getFlatArrDecompressed(`/obs/${categories}`);\n      }\n    }\n    const obsArr = await openArray({ store, path: obs, mode: 'r' });\n    const obsValues = await obsArr.get();\n    const { data } = obsValues;\n    const mappedObsValues = Array.from(data).map(\n      i => (!categoriesValues ? String(i) : categoriesValues[i]),\n    );\n    return mappedObsValues;\n  }\n\n  /**\n   * Class method for loading general numeric arrays.\n   * @param {string} path A string like obsm.X_pca.\n   * @returns {Promise} A promise for a zarr array containing the data.\n   */\n  loadNumeric(path) {\n    const { store } = this;\n    return openArray({\n      store,\n      path,\n      mode: 'r',\n    }).then(arr => arr.get());\n  }\n\n  /**\n   * A common method for loading flattened data\n   * i.e that which has shape [n] where n is a natural number.\n   * @param {string} path A path to a flat array location, like obs/_index\n   * @returns {Array} The data from the zarr array.\n   */\n  getFlatArrDecompressed(path) {\n    const { store } = this;\n    return openArray({\n      store,\n      path,\n      mode: 'r',\n    }).then(async (z) => {\n      let data;\n      const parseAndMergeTextBytes = (dbytes) => {\n        const text = parseVlenUtf8(dbytes);\n        if (!data) {\n          data = text;\n        } else {\n          data = data.concat(text);\n        }\n      };\n      const mergeBytes = (dbytes) => {\n        if (!data) {\n          data = dbytes;\n        } else {\n          const tmp = new Uint8Array(dbytes.buffer.byteLength + data.buffer.byteLength);\n          tmp.set(new Uint8Array(data.buffer), 0);\n          tmp.set(dbytes, data.buffer.byteLength);\n          data = tmp;\n        }\n      };\n      const numRequests = Math.ceil(z.meta.shape[0] / z.meta.chunks[0]);\n      const requests = range(numRequests).map(async item => store.getItem(`${z.keyPrefix}${String(item)}`)\n        .then(buf => z.compressor.then(compressor => compressor.decode(buf))));\n      const dbytesArr = await Promise.all(requests);\n      dbytesArr.forEach((dbytes) => {\n        // Use vlenutf-8 decoding if necessary and merge `data` as a normal array.\n        if (Array.isArray(z.meta.filters) && z.meta.filters[0].id === 'vlen-utf8') {\n          parseAndMergeTextBytes(dbytes);\n          // Otherwise just merge the bytes as a typed array.\n        } else {\n          mergeBytes(dbytes);\n        }\n      });\n      const {\n        meta: {\n          shape: [length],\n        },\n      } = z;\n      // truncate the filled in values\n      return data.slice(0, length);\n    });\n  }\n\n  /**\n   * Class method for loading the obs index.\n   * @returns {Promise} An promise for a zarr array containing the indices.\n   */\n  loadObsIndex() {\n    if (this.obsIndex) {\n      return this.obsIndex;\n    }\n    this.obsIndex = this.getJson('obs/.zattrs')\n      .then(({ _index }) => this.getFlatArrDecompressed(`/obs/${_index}`));\n    return this.obsIndex;\n  }\n\n  /**\n   * Class method for loading the var index.\n   * @returns {Promise} An promise for a zarr array containing the indices.\n   */\n  loadVarIndex() {\n    if (this.varIndex) {\n      return this.varIndex;\n    }\n    this.varIndex = this.getJson('var/.zattrs')\n      .then(({ _index }) => this.getFlatArrDecompressed(`/var/${_index}`));\n    return this.varIndex;\n  }\n}\n","import AbstractLoaderError from './AbstractLoaderError';\n\nexport default class DataSourceFetchError extends AbstractLoaderError {\n  constructor(source, url, headers) {\n    super(`${source} Error HTTP Status fetching from ${url}`);\n    this.source = source;\n    this.url = url;\n    this.headers = headers;\n  }\n\n  warnInConsole() {\n    const { source, url, headers } = this;\n    console.warn(`${source} failed to fetch from ${url} with headers ${headers}`);\n  }\n}\n","/* eslint-disable no-underscore-dangle */\nimport DataSourceFetchError from '../errors/DataSourceFetchError';\n\nexport default class JsonSource {\n  constructor({ url, requestInit }) {\n    this.url = url;\n    this.requestInit = requestInit;\n  }\n\n  get data() {\n    if (this._data) return this._data;\n    this._data = fetch(this.url, this.requestInit).then((response) => {\n      if (!response.ok) {\n        return Promise.reject(new DataSourceFetchError('JsonSource', this.url, response.headers));\n      }\n      return response.json();\n    // eslint-disable-next-line no-console\n    }).catch(() => Promise.reject(new DataSourceFetchError('JsonSource', this.url, {})));\n    return this._data;\n  }\n}\n","import { FileType } from '../app/constants';\n\nimport JsonLoader from './JsonLoader';\nimport MatrixZarrLoader from './MatrixZarrLoader';\nimport GenesJsonAsMatrixZarrLoader from './GenesJsonAsMatrixZarrLoader';\nimport ClustersJsonAsMatrixZarrLoader from './ClustersJsonAsMatrixZarrLoader';\nimport RasterJsonLoader from './RasterJsonLoader';\nimport OmeZarrLoader from './OmeZarrLoader';\nimport CellSetsJsonLoader from './CellSetsJsonLoader';\nimport AnnDataLoaders from './anndata-loaders';\nimport GenomicProfilesZarrLoader from './GenomicProfilesZarrLoader';\nimport { AnnDataSource, ZarrDataSource, JsonSource } from './data-sources';\n\nexport const fileTypeToLoaderAndSource = {\n  [FileType.EXPRESSION_MATRIX_ZARR]: [ZarrDataSource, MatrixZarrLoader],\n  [FileType.CLUSTERS_JSON]: [JsonSource, ClustersJsonAsMatrixZarrLoader],\n  [FileType.GENES_JSON]: [JsonSource, GenesJsonAsMatrixZarrLoader],\n  [FileType.CELLS_JSON]: [JsonSource, JsonLoader],\n  [FileType.MOLECULES_JSON]: [JsonSource, JsonLoader],\n  [FileType.NEIGHBORHOODS_JSON]: [JsonSource, JsonLoader],\n  [FileType.RASTER_JSON]: [JsonSource, RasterJsonLoader],\n  [FileType.RASTER_OME_ZARR]: [ZarrDataSource, OmeZarrLoader],\n  [FileType.CELL_SETS_JSON]: [JsonSource, CellSetsJsonLoader],\n  [FileType.ANNDATA_CELL_SETS_ZARR]: [AnnDataSource, AnnDataLoaders.CellSetsZarrLoader],\n  [FileType.ANNDATA_CELLS_ZARR]: [AnnDataSource, AnnDataLoaders.CellsZarrLoader],\n  [FileType.ANNDATA_EXPRESSION_MATRIX_ZARR]: [AnnDataSource, AnnDataLoaders.MatrixZarrLoader],\n  [FileType.GENOMIC_PROFILES_ZARR]: [ZarrDataSource, GenomicProfilesZarrLoader],\n};\n\nexport function getSourceAndLoaderFromFileType(type) {\n  return fileTypeToLoaderAndSource[type] || [JsonSource, JsonLoader];\n}\n","import {\n  useState, useEffect, useRef,\n} from 'react';\nimport { getSourceAndLoaderFromFileType } from '../loaders/types';\n\n/**\n * Return the bottom coordinate of the layout.\n * https://github.com/STRML/react-grid-layout/blob/20dac73f91274526034c00968b5bedb9c2ed36b9/lib/utils.js#L82\n * @param  {array} layout react-grid-layout layout array.\n * @returns {number} Bottom coordinate.\n */\nfunction getNumRows(layout) {\n  let max = 0;\n  let bottomY;\n  // eslint-disable-next-line no-plusplus\n  for (let i = 0, len = layout.length; i < len; i++) {\n    bottomY = layout[i].y + layout[i].h;\n    if (bottomY > max) max = bottomY;\n  }\n  return max;\n}\n\n/**\n * Compute the row height based on the container height, number of rows,\n * and margin/padding. Basically the reverse of the react-grid-layout's\n * `.containerHeight()` function.\n * https://github.com/STRML/react-grid-layout/blob/83251e5e682abfa3252ff89d4bacf47fdc1f4270/lib/ReactGridLayout.jsx#L223\n * @param {number} containerHeight The height of the .vitessce-container element.\n * @param {number} numRows The number of rows in the layout.\n * @param {number} margin The margin value that will be passed to VitessceGrid.\n * @param {number} padding The padding value that will be passed to VitessceGrid.\n * @returns {number} The new row height value.\n */\nfunction getRowHeight(containerHeight, numRows, margin, padding) {\n  const effectiveContainerHeight = containerHeight - 2 * padding - (numRows - 1) * margin;\n  return effectiveContainerHeight / numRows;\n}\n\nexport function useRowHeight(config, initialRowHeight, height, margin, padding) {\n  const [containerHeight, setContainerHeight] = useState(height);\n  const [rowHeight, setRowHeight] = useState(initialRowHeight);\n  const containerRef = useRef();\n\n  // Detect when the `config` or `containerHeight` variables\n  // have changed, and update `rowHeight` in response.\n  useEffect(() => {\n    const numRows = getNumRows(config.layout);\n    const newRowHeight = getRowHeight(containerHeight, numRows, margin, padding);\n    setRowHeight(newRowHeight);\n  }, [containerHeight, config, margin, padding]);\n\n  // Update the `containerHeight` state when the `height` prop has changed.\n  useEffect(() => {\n    if (height !== null && height !== undefined) {\n      setContainerHeight(height);\n    }\n  }, [height]);\n\n  // If no height prop has been provided, set the `containerHeight`\n  // using height of the `.vitessce-container` element.\n  // Check the container element height whenever the window has been\n  // resized, as it may change if `.vitessce-container` should be\n  // sized relative to its parent (and by extension, potentially the window).\n  useEffect(() => {\n    if (height !== null && height !== undefined) {\n      // eslint will complain if the return value is inconsistent,\n      // so return a no-op function.\n      return () => {};\n    }\n    function onWindowResize() {\n      if (!containerRef.current) return;\n      const containerRect = containerRef.current.getBoundingClientRect();\n      setContainerHeight(containerRect.height);\n    }\n    window.addEventListener('resize', onWindowResize);\n    onWindowResize();\n    return () => {\n      window.removeEventListener('resize', onWindowResize);\n    };\n  }, [containerRef, height]);\n\n\n  return [rowHeight, containerRef];\n}\n\n/**\n * Create a mapping from dataset ID to loader objects by data type.\n * @param {object[]} datasets The datasets array from the view config.\n * @param {string} configDescription The top-level description in the\n * view config.\n * @returns {object} Mapping from dataset ID to data type to loader\n * instance.\n */\nexport function createLoaders(datasets, configDescription) {\n  const result = {};\n  const dataSources = {};\n  datasets.forEach((dataset) => {\n    const datasetLoaders = {\n      name: dataset.name,\n      description: dataset.description || configDescription,\n      loaders: {},\n    };\n    dataset.files.forEach((file) => {\n      const [DataSourceClass, LoaderClass] = getSourceAndLoaderFromFileType(file.fileType);\n      // Create _one_ DataSourceClass instance per URL. Derived loaders share this object.\n      const { url, options, requestInit } = file;\n      const fileId = url || JSON.stringify(options);\n      if (!(fileId in dataSources)) {\n        dataSources[fileId] = new DataSourceClass({ url, requestInit });\n      }\n      const loader = new LoaderClass(dataSources[fileId], file);\n      datasetLoaders.loaders[file.type] = loader;\n    });\n    result[dataset.uid] = datasetLoaders;\n  });\n  return result;\n}\n","import {\n  useRef, useState, useEffect, useCallback, useMemo,\n} from 'react';\nimport debounce from 'lodash/debounce';\nimport { useGridResize, useEmitGridResize } from '../app/state/hooks';\nimport { VITESSCE_CONTAINER } from './classNames';\n\nfunction getWindowDimensions() {\n  const { innerWidth: width, innerHeight: height } = window;\n  return {\n    width,\n    height,\n  };\n}\n\nexport function useVitessceContainer(ref) {\n  return useCallback(() => {\n    if (ref.current) {\n      return ref.current.closest(`.${VITESSCE_CONTAINER}`);\n    }\n    return null;\n  }, [ref]);\n}\n\n/**\n * Custom hook, gets the full window dimensions.\n * @returns {array} `[width, height]` where width and height\n * are numbers.\n */\nexport function useWindowDimensions() {\n  const [windowDimensions, setWindowDimensions] = useState(\n    getWindowDimensions(),\n  );\n\n  useEffect(() => {\n    function handleResize() {\n      setWindowDimensions(getWindowDimensions());\n    }\n    const onResizeDebounced = debounce(handleResize, 100, { trailing: true });\n\n    window.addEventListener('resize', onResizeDebounced);\n    return () => window.removeEventListener('resize', onResizeDebounced);\n  }, []);\n\n  return windowDimensions;\n}\n\n/**\n * Custom hook, subscribes to GRID_RESIZE and window resize events.\n * @returns {array} `[width, height, containerRef]` where width and height\n * are numbers and containerRef is a React ref.\n */\nexport function useGridItemSize() {\n  const containerRef = useRef();\n\n  const [height, setHeight] = useState();\n  const [width, setWidth] = useState();\n\n  const resizeCount = useGridResize();\n  const incrementResizeCount = useEmitGridResize();\n\n  // On window resize events, increment the grid resize count.\n  useEffect(() => {\n    function onWindowResize() {\n      incrementResizeCount();\n    }\n    const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });\n    window.addEventListener('resize', onResizeDebounced);\n    onWindowResize();\n    return () => {\n      window.removeEventListener('resize', onResizeDebounced);\n    };\n  }, [incrementResizeCount]);\n\n  // On new grid resize counts, re-compute the component\n  // width/height.\n  useEffect(() => {\n    if (!containerRef.current) return;\n    const container = containerRef.current;\n    const containerRect = container.getBoundingClientRect();\n    setHeight(containerRect.height);\n    setWidth(containerRect.width);\n  }, [resizeCount]);\n\n  return [width, height, containerRef];\n}\n\n/**\n * Custom hook, subscribes to GRID_RESIZE and window resize events.\n * @returns {array} `[width, height, deckRef]` where width and height\n * are numbers and deckRef is a React ref to be used with\n * a <DeckGL/> element (or a forwardRef to one).\n */\nexport function useDeckCanvasSize() {\n  const deckRef = useRef();\n\n  const [height, setHeight] = useState();\n  const [width, setWidth] = useState();\n\n  const resizeCount = useGridResize();\n  const incrementResizeCount = useEmitGridResize();\n\n  // On window resize events, increment the grid resize count.\n  useEffect(() => {\n    function onWindowResize() {\n      incrementResizeCount();\n    }\n    const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });\n    window.addEventListener('resize', onResizeDebounced);\n    onWindowResize();\n    return () => {\n      window.removeEventListener('resize', onResizeDebounced);\n    };\n  }, [incrementResizeCount]);\n\n  // On new grid resize counts, re-compute the DeckGL canvas\n  // width/height.\n  useEffect(() => {\n    if (!deckRef.current) return;\n    const { canvas } = deckRef.current.deck;\n    const canvasRect = canvas.getBoundingClientRect();\n    setHeight(canvasRect.height);\n    setWidth(canvasRect.width);\n  }, [resizeCount]);\n\n  return [width, height, deckRef];\n}\n\n/**\n * This hook handles a boolean isReady value,\n * which only returns true once every item in the\n * input list has been marked as \"ready\".\n * @param {string[]} items The items to wait on.\n * Should be defined as a constant\n * (outside a function component / render function),\n * otherwise strange bugs may occur.\n * @returns {array} An array\n * [isReady, setItemIsReady, setItemIsNotReady, resetReadyItems]\n * where isReady is the boolean value,\n * setItemIsReady marks one item as ready,\n * setItemIsNotReady marks one item as not ready,\n * and resetReadyItem marks all items as waiting.\n */\nexport function useReady(supportedItems) {\n  const items = supportedItems;\n  const [waiting, setWaiting] = useState(items);\n\n  const setItemIsReady = useCallback((readyItem) => {\n    setWaiting((waitingItems) => {\n      const nextWaitingItems = waitingItems.filter(item => item !== readyItem);\n      // eslint-disable-next-line no-console\n      console.log(`cleared ${readyItem}; waiting on ${nextWaitingItems.length}: ${JSON.stringify(nextWaitingItems)}`);\n      return nextWaitingItems;\n    });\n  }, [setWaiting]);\n\n  const setItemIsNotReady = useCallback((notReadyItem) => {\n    setWaiting((waitingItems) => {\n      const nextWaitingItems = [...waitingItems, notReadyItem];\n      // eslint-disable-next-line no-console\n      console.log(`waiting on ${nextWaitingItems.length}: ${JSON.stringify(nextWaitingItems)}`);\n      return nextWaitingItems;\n    });\n  }, [setWaiting]);\n\n  const resetReadyItems = useCallback(() => {\n    setWaiting(items);\n    // eslint-disable-next-line no-console\n    console.log(`waiting on ${items.length}: ${JSON.stringify(items)}`);\n  }, [setWaiting, items]);\n\n  const isReady = waiting.length === 0;\n\n  return [isReady, setItemIsReady, setItemIsNotReady, resetReadyItems];\n}\n\n/**\n * This hook manages a list of URLs,\n * with adding and resetting helpers.\n * @returns {array} An array\n * [urls, addUrl, resetUrls]\n * where urls is the array of URL objects,\n * addUrl is a function for adding a URL to the array,\n * resetUrls is a function that clears the array.\n */\nexport function useUrls() {\n  const [urls, setUrls] = useState([]);\n\n  const addUrl = useCallback((url, name) => {\n    if (url) {\n      setUrls(prev => ([...prev, { url, name }]));\n    }\n  }, [setUrls]);\n\n  const resetUrls = useCallback(() => {\n    setUrls([]);\n  }, [setUrls]);\n\n  return [urls, addUrl, resetUrls];\n}\n\n/**\n * Custom hook, subscribes to the width and height of the closest .vitessce-container\n * element and updates upon window resize events.\n * @param {Ref} ref A React ref object within the `.vitessce-container`.\n * @returns {array} `[width, height]` where width and height\n * are numbers.\n */\nexport function useClosestVitessceContainerSize(ref) {\n  const [height, setHeight] = useState();\n  const [width, setWidth] = useState();\n\n  useEffect(() => {\n    function onWindowResize() {\n      if (ref.current) {\n        const {\n          clientHeight: componentHeight, clientWidth: componentWidth,\n        } = ref.current.closest('.vitessce-container');\n        setWidth(componentWidth);\n        setHeight(componentHeight);\n      }\n    }\n    const onResizeDebounced = debounce(onWindowResize, 100, { trailing: true });\n    window.addEventListener('resize', onResizeDebounced);\n    onWindowResize();\n    return () => {\n      window.removeEventListener('resize', onResizeDebounced);\n    };\n  }, [ref]);\n\n  return [width, height];\n}\n\nexport function useExpressionValueGetter({ attrs, expressionData }) {\n  // Get a mapping from cell ID to row index in the gene expression matrix.\n  const cellIdMap = useMemo(() => {\n    const result = {};\n    if (attrs && attrs.rows) {\n      // eslint-disable-next-line no-plusplus\n      for (let i = 0; i < attrs.rows.length; i++) {\n        result[attrs.rows[i]] = i;\n      }\n    }\n    return result;\n  }, [attrs]);\n\n  // Set up a getter function for gene expression values, to be used\n  // by the DeckGL layer to obtain values for instanced attributes.\n  const getExpressionValue = useCallback((entry) => {\n    const cellId = entry[0];\n    if (cellIdMap && expressionData && expressionData[0]) {\n      const cellIndex = cellIdMap[cellId];\n      const val = expressionData[0][cellIndex];\n      return val;\n    }\n    return 0;\n  }, [cellIdMap, expressionData]);\n  return getExpressionValue;\n}\n","import React, {\n  useEffect,\n  useCallback,\n} from 'react';\nimport { VitessceGridLayout } from './vitessce-grid-layout';\nimport { useRowHeight, createLoaders } from './vitessce-grid-utils';\nimport {\n  useViewConfigStoreApi,\n  useSetViewConfig,\n  useSetLoaders,\n  useEmitGridResize,\n  useRemoveComponent,\n  useChangeLayout,\n  useLayout,\n} from './state/hooks';\nimport {\n  useClosestVitessceContainerSize,\n} from '../components/hooks';\n\nconst padding = 10;\nconst margin = 5;\n\n/**\n * The wrapper for the VitessceGrid and LoadingIndicator components.\n * @param {object} props\n * @param {number} props.rowHeight The height of each grid row. Optional.\n * @param {object} props.config The view config.\n * @param {function} props.getComponent A function that maps component names to their\n * React counterparts.\n * @param {string} props.theme The theme name.\n * @param {number} props.height Total height for grid. Optional.\n * @param {function} props.onWarn A callback for warning messages. Optional.\n */\nexport default function VitessceGrid(props) {\n  const {\n    rowHeight: initialRowHeight,\n    config,\n    getComponent,\n    theme,\n    height,\n  } = props;\n\n  const [rowHeight, containerRef] = useRowHeight(config, initialRowHeight, height, margin, padding);\n  const onResize = useEmitGridResize();\n\n  const [componentWidth] = useClosestVitessceContainerSize(containerRef);\n\n  // When the row height has changed, publish a GRID_RESIZE event.\n  useEffect(() => {\n    onResize();\n  }, [rowHeight, onResize]);\n\n  const viewConfigStoreApi = useViewConfigStoreApi();\n  const setViewConfig = useSetViewConfig(viewConfigStoreApi);\n  const setLoaders = useSetLoaders();\n  const removeComponent = useRemoveComponent();\n  const changeLayout = useChangeLayout();\n  const layout = useLayout();\n\n  const changeLayoutPostMount = useCallback(() => (\n    componentWidth > 0 ? changeLayout : () => {}\n  ), [changeLayout, componentWidth]);\n\n  // Update the view config and loaders in the global state.\n  useEffect(() => {\n    if (config) {\n      setViewConfig(config);\n      const loaders = createLoaders(config.datasets, config.description);\n      setLoaders(loaders);\n    } else {\n      // No config found, so clear the loaders.\n      setLoaders({});\n    }\n  }, [config, setViewConfig, setLoaders]);\n\n  return (\n    <div\n      ref={containerRef}\n      className={`vitessce-container vitessce-theme-${theme}`}\n    >\n      {layout && (\n        <VitessceGridLayout\n          layout={layout}\n          height={height}\n          rowHeight={rowHeight}\n          theme={theme}\n          getComponent={getComponent}\n          draggableHandle=\".title\"\n          margin={margin}\n          padding={padding}\n          onRemoveComponent={removeComponent}\n          onLayoutChange={changeLayoutPostMount}\n          reactGridLayoutProps={{\n            onResize,\n            onResizeStop: onResize,\n          }}\n        />\n      )}\n    </div>\n  );\n}\n","import { CoordinationType, Component } from '../constants';\n\n/**\n * Coordination types may have default values,\n * which can be defined here, and used by the\n * auto initialization strategy.\n */\nexport const DEFAULT_COORDINATION_VALUES = {\n  [CoordinationType.EMBEDDING_ZOOM]: null,\n  [CoordinationType.EMBEDDING_ROTATION]: 0,\n  [CoordinationType.EMBEDDING_TARGET_X]: null,\n  [CoordinationType.EMBEDDING_TARGET_Y]: null,\n  [CoordinationType.EMBEDDING_TARGET_Z]: 0,\n  [CoordinationType.EMBEDDING_CELL_SET_POLYGONS_VISIBLE]: false,\n  [CoordinationType.EMBEDDING_CELL_SET_LABELS_VISIBLE]: false,\n  [CoordinationType.EMBEDDING_CELL_SET_LABEL_SIZE]: 14,\n  [CoordinationType.EMBEDDING_CELL_RADIUS]: 1,\n  [CoordinationType.EMBEDDING_CELL_RADIUS_MODE]: 'auto',\n  [CoordinationType.EMBEDDING_CELL_OPACITY]: 1,\n  [CoordinationType.EMBEDDING_CELL_OPACITY_MODE]: 'auto',\n  [CoordinationType.SPATIAL_ZOOM]: null,\n  [CoordinationType.SPATIAL_ROTATION]: 0,\n  [CoordinationType.SPATIAL_TARGET_X]: null,\n  [CoordinationType.SPATIAL_TARGET_Y]: null,\n  [CoordinationType.SPATIAL_TARGET_Z]: null,\n  [CoordinationType.SPATIAL_ROTATION_X]: null,\n  [CoordinationType.SPATIAL_ROTATION_Y]: null,\n  [CoordinationType.SPATIAL_ROTATION_Z]: null,\n  [CoordinationType.SPATIAL_AXIS_FIXED]: false,\n  [CoordinationType.SPATIAL_ROTATION_ORBIT]: 0,\n  [CoordinationType.SPATIAL_ORBIT_AXIS]: 'Y',\n  [CoordinationType.SPATIAL_RASTER_LAYERS]: null,\n  [CoordinationType.SPATIAL_CELLS_LAYER]: null,\n  [CoordinationType.SPATIAL_MOLECULES_LAYER]: null,\n  [CoordinationType.SPATIAL_NEIGHBORHOODS_LAYER]: null,\n  [CoordinationType.HEATMAP_ZOOM_X]: 0,\n  [CoordinationType.HEATMAP_ZOOM_Y]: 0,\n  [CoordinationType.HEATMAP_TARGET_X]: 0,\n  [CoordinationType.HEATMAP_TARGET_Y]: 0,\n  [CoordinationType.GENE_EXPRESSION_COLORMAP]: 'plasma',\n  [CoordinationType.GENE_EXPRESSION_COLORMAP_RANGE]: [0.0, 1.0],\n  [CoordinationType.GENE_EXPRESSION_TRANSFORM]: null,\n  [CoordinationType.GENE_FILTER]: null,\n  [CoordinationType.GENE_HIGHLIGHT]: null,\n  [CoordinationType.GENE_SELECTION]: null,\n  [CoordinationType.CELL_FILTER]: null,\n  [CoordinationType.CELL_HIGHLIGHT]: null,\n  [CoordinationType.CELL_SET_SELECTION]: null,\n  [CoordinationType.CELL_SET_HIGHLIGHT]: null,\n  [CoordinationType.CELL_SET_COLOR]: null,\n  [CoordinationType.CELL_COLOR_ENCODING]: 'cellSetSelection',\n  [CoordinationType.GENOMIC_ZOOM_X]: 0,\n  [CoordinationType.GENOMIC_ZOOM_Y]: 0,\n  [CoordinationType.GENOMIC_TARGET_X]: 1549999999.5,\n  [CoordinationType.GENOMIC_TARGET_Y]: 1549999999.5,\n  [CoordinationType.ADDITIONAL_CELL_SETS]: null,\n  [CoordinationType.MOLECULE_HIGHLIGHT]: null,\n};\n\n// The following coordination types should be\n// initialized to independent scopes when\n// initialized automatically.\n// These make the resulting view config\n// (after auto-initialization) behave\n// like \"legacy\" Vitessce (pre-coordination model).\nexport const AUTO_INDEPENDENT_COORDINATION_TYPES = [\n  CoordinationType.HEATMAP_ZOOM_X,\n  CoordinationType.HEATMAP_ZOOM_Y,\n  CoordinationType.HEATMAP_TARGET_X,\n  CoordinationType.HEATMAP_TARGET_Y,\n  CoordinationType.EMBEDDING_ZOOM,\n  CoordinationType.EMBEDDING_TARGET_X,\n  CoordinationType.EMBEDDING_TARGET_Y,\n  CoordinationType.EMBEDDING_TARGET_Z,\n  CoordinationType.EMBEDDING_CELL_SET_POLYGONS_VISIBLE,\n  CoordinationType.EMBEDDING_CELL_SET_LABELS_VISIBLE,\n  CoordinationType.EMBEDDING_CELL_SET_LABEL_SIZE,\n  CoordinationType.EMBEDDING_CELL_RADIUS,\n  CoordinationType.EMBEDDING_CELL_OPACITY,\n];\n\n/**\n   * Mapping from component type to\n   * supported coordination object types.\n   * This mapping can be used to determine\n   * which pieces of state that a component will\n   * need to get/set.\n   * Keys here are the component registry keys.\n   */\nexport const COMPONENT_COORDINATION_TYPES = {\n  [Component.SCATTERPLOT]: [\n    CoordinationType.DATASET,\n    CoordinationType.EMBEDDING_TYPE,\n    CoordinationType.EMBEDDING_ZOOM,\n    CoordinationType.EMBEDDING_ROTATION,\n    CoordinationType.EMBEDDING_TARGET_X,\n    CoordinationType.EMBEDDING_TARGET_Y,\n    CoordinationType.EMBEDDING_TARGET_Z,\n    CoordinationType.EMBEDDING_CELL_SET_POLYGONS_VISIBLE,\n    CoordinationType.EMBEDDING_CELL_SET_LABELS_VISIBLE,\n    CoordinationType.EMBEDDING_CELL_SET_LABEL_SIZE,\n    CoordinationType.EMBEDDING_CELL_RADIUS,\n    CoordinationType.EMBEDDING_CELL_RADIUS_MODE,\n    CoordinationType.EMBEDDING_CELL_OPACITY,\n    CoordinationType.EMBEDDING_CELL_OPACITY_MODE,\n    CoordinationType.CELL_FILTER,\n    CoordinationType.CELL_HIGHLIGHT,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.GENE_SELECTION,\n    CoordinationType.GENE_EXPRESSION_COLORMAP,\n    CoordinationType.GENE_EXPRESSION_COLORMAP_RANGE,\n    CoordinationType.CELL_COLOR_ENCODING,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n  ],\n  [Component.SPATIAL]: [\n    CoordinationType.DATASET,\n    CoordinationType.SPATIAL_ZOOM,\n    CoordinationType.SPATIAL_ROTATION,\n    CoordinationType.SPATIAL_RASTER_LAYERS,\n    CoordinationType.SPATIAL_CELLS_LAYER,\n    CoordinationType.SPATIAL_MOLECULES_LAYER,\n    CoordinationType.SPATIAL_NEIGHBORHOODS_LAYER,\n    CoordinationType.SPATIAL_TARGET_X,\n    CoordinationType.SPATIAL_TARGET_Y,\n    CoordinationType.SPATIAL_TARGET_Z,\n    CoordinationType.SPATIAL_ROTATION_X,\n    CoordinationType.SPATIAL_ROTATION_Y,\n    CoordinationType.SPATIAL_ROTATION_Z,\n    CoordinationType.SPATIAL_ROTATION_ORBIT,\n    CoordinationType.SPATIAL_ORBIT_AXIS,\n    CoordinationType.SPATIAL_AXIS_FIXED,\n    CoordinationType.CELL_FILTER,\n    CoordinationType.CELL_HIGHLIGHT,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.GENE_SELECTION,\n    CoordinationType.GENE_EXPRESSION_COLORMAP,\n    CoordinationType.GENE_EXPRESSION_COLORMAP_RANGE,\n    CoordinationType.CELL_COLOR_ENCODING,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n    CoordinationType.MOLECULE_HIGHLIGHT,\n  ],\n  [Component.HEATMAP]: [\n    CoordinationType.DATASET,\n    CoordinationType.HEATMAP_ZOOM_X,\n    CoordinationType.HEATMAP_ZOOM_Y,\n    CoordinationType.HEATMAP_TARGET_X,\n    CoordinationType.HEATMAP_TARGET_Y,\n    CoordinationType.CELL_FILTER,\n    CoordinationType.CELL_HIGHLIGHT,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.GENE_FILTER,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.GENE_SELECTION,\n    CoordinationType.GENE_EXPRESSION_COLORMAP,\n    CoordinationType.GENE_EXPRESSION_COLORMAP_RANGE,\n    CoordinationType.CELL_COLOR_ENCODING,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n  ],\n  [Component.CELL_SETS]: [\n    CoordinationType.DATASET,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.CELL_COLOR_ENCODING,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n    CoordinationType.GENE_SELECTION,\n  ],\n  [Component.CELL_SET_SIZES]: [\n    CoordinationType.DATASET,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n  ],\n  [Component.STATUS]: [\n    CoordinationType.DATASET,\n    CoordinationType.CELL_HIGHLIGHT,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.MOLECULE_HIGHLIGHT,\n  ],\n  [Component.GENES]: [\n    CoordinationType.DATASET,\n    CoordinationType.GENE_FILTER,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.GENE_SELECTION,\n    CoordinationType.CELL_COLOR_ENCODING,\n    CoordinationType.CELL_SET_SELECTION,\n  ],\n  [Component.CELL_SET_EXPRESSION]: [\n    CoordinationType.DATASET,\n    CoordinationType.GENE_SELECTION,\n    CoordinationType.GENE_EXPRESSION_TRANSFORM,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n  ],\n  [Component.EXPRESSION_HISTOGRAM]: [\n    CoordinationType.DATASET,\n    CoordinationType.GENE_SELECTION,\n  ],\n  [Component.LAYER_CONTROLLER]: [\n    CoordinationType.DATASET,\n    CoordinationType.SPATIAL_RASTER_LAYERS,\n    CoordinationType.SPATIAL_CELLS_LAYER,\n    CoordinationType.SPATIAL_MOLECULES_LAYER,\n    CoordinationType.SPATIAL_NEIGHBORHOODS_LAYER,\n    CoordinationType.SPATIAL_ZOOM,\n    CoordinationType.SPATIAL_TARGET_X,\n    CoordinationType.SPATIAL_TARGET_Y,\n    CoordinationType.SPATIAL_TARGET_Z,\n    CoordinationType.SPATIAL_ROTATION_X,\n    CoordinationType.SPATIAL_ROTATION_Y,\n    CoordinationType.SPATIAL_ROTATION_Z,\n    CoordinationType.SPATIAL_ROTATION_ORBIT,\n    CoordinationType.SPATIAL_ORBIT_AXIS,\n  ],\n  [Component.GENOMIC_PROFILES]: [\n    CoordinationType.DATASET,\n    CoordinationType.GENOMIC_ZOOM_X,\n    CoordinationType.GENOMIC_ZOOM_Y,\n    CoordinationType.GENOMIC_TARGET_X,\n    CoordinationType.GENOMIC_TARGET_Y,\n    CoordinationType.GENE_FILTER,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.GENE_SELECTION,\n    CoordinationType.CELL_SET_SELECTION,\n    CoordinationType.CELL_SET_HIGHLIGHT,\n    CoordinationType.CELL_SET_COLOR,\n    CoordinationType.ADDITIONAL_CELL_SETS,\n  ],\n  [Component.DESCRIPTION]: [\n    CoordinationType.DATASET,\n    CoordinationType.SPATIAL_RASTER_LAYERS,\n  ],\n  higlass: [\n    CoordinationType.DATASET,\n    CoordinationType.GENOMIC_ZOOM_X,\n    CoordinationType.GENOMIC_ZOOM_Y,\n    CoordinationType.GENOMIC_TARGET_X,\n    CoordinationType.GENOMIC_TARGET_Y,\n    CoordinationType.GENE_FILTER,\n    CoordinationType.GENE_HIGHLIGHT,\n    CoordinationType.GENE_SELECTION,\n  ],\n};\n","/* eslint-disable camelcase */\nimport uuidv4 from 'uuid/v4';\nimport cloneDeep from 'lodash/cloneDeep';\nimport { getNextScope, capitalize } from '../utils';\nimport {\n  COMPONENT_COORDINATION_TYPES,\n} from './state/coordination';\n\n/**\n * A helper function for the `upgrade()` function,\n * which helps convert `props.view` (for scatterplot and spatial),\n * into new coordination scopes, setting their values\n * in the coordination space and returning the new scope mappings.\n * This function does mutate the `coordinationSpace` parameter.\n * @param {string} prefix The coordination type prefix,\n * either 'embedding' or 'spatial'.\n * @param {object} view The view prop object containing\n * the properties `.target` and `.zoom`.\n * @param {object} coordinationSpace The coordination space.\n * @returns {object} The new coordination scope names.\n */\nfunction upgradeReplaceViewProp(prefix, view, coordinationSpace) {\n  const prevZScopes = Object.keys(coordinationSpace[`${prefix}Zoom`]);\n  const prevTXScopes = Object.keys(coordinationSpace[`${prefix}TargetX`]);\n  const prevTYScopes = Object.keys(coordinationSpace[`${prefix}TargetY`]);\n\n  const nextZScope = getNextScope(prevZScopes);\n  const nextTXScope = getNextScope(prevTXScopes);\n  const nextTYScope = getNextScope(prevTYScopes);\n\n  const { zoom, target: [targetX, targetY] } = view;\n  // eslint-disable-next-line no-param-reassign\n  coordinationSpace[`${prefix}Zoom`][nextZScope] = zoom;\n  // eslint-disable-next-line no-param-reassign\n  coordinationSpace[`${prefix}TargetX`][nextTXScope] = targetX;\n  // eslint-disable-next-line no-param-reassign\n  coordinationSpace[`${prefix}TargetY`][nextTYScope] = targetY;\n  return {\n    [`${prefix}Zoom`]: nextZScope,\n    [`${prefix}TargetX`]: nextTXScope,\n    [`${prefix}TargetY`]: nextTYScope,\n  };\n}\n\n/**\n * Convert an older view config to a newer view config.\n * @param {object} config A v0.1.0 \"legacy\" view config.\n * @returns {object} A v1.0.0 \"upgraded\" view config.\n */\nexport function upgradeFrom0_1_0(config, datasetUid = null) {\n  const coordinationSpace = {\n    embeddingType: {},\n    embeddingZoom: {},\n    embeddingTargetX: {},\n    embeddingTargetY: {},\n    spatialZoom: {},\n    spatialTargetX: {},\n    spatialTargetY: {},\n  };\n\n  const layout = [];\n  config.staticLayout.forEach((componentDef) => {\n    let newComponentDef = {\n      ...componentDef,\n      coordinationScopes: {},\n    };\n    if (componentDef.component === 'scatterplot') {\n      // Need to set up the coordinationSpace\n      // with embeddingType to replace scatterplot\n      // component prop \"mapping\".\n      if (componentDef.props.mapping) {\n        coordinationSpace.embeddingType[componentDef.props.mapping] = componentDef.props.mapping;\n        newComponentDef = {\n          ...newComponentDef,\n          coordinationScopes: {\n            ...newComponentDef.coordinationScopes,\n            embeddingType: componentDef.props.mapping,\n          },\n        };\n      }\n      // Need to set up the coordinationSpace\n      // with embeddingZoom / embeddingTargetX/Y to replace scatterplot\n      // component prop \"view\" ({ zoom, target }).\n      if (componentDef.props.view) {\n        // Note that the below function does mutate the coordinationSpace param.\n        const newScopeValues = upgradeReplaceViewProp(\n          'embedding', componentDef.props.view, coordinationSpace,\n        );\n        newComponentDef = {\n          ...newComponentDef,\n          coordinationScopes: {\n            ...newComponentDef.coordinationScopes,\n            ...newScopeValues,\n          },\n        };\n      }\n    }\n    if (componentDef.component === 'spatial') {\n      // Need to set up the coordinationSpace\n      // with spatialZoom / spatialTargetX/Y to replace spatial\n      // component prop \"view\" ({ zoom, target }).\n      if (componentDef?.props?.view) {\n        // Note that the below function does mutate the coordinationSpace param.\n        const newScopeValues = upgradeReplaceViewProp(\n          'spatial', componentDef.props.view, coordinationSpace,\n        );\n        newComponentDef = {\n          ...newComponentDef,\n          coordinationScopes: {\n            ...newComponentDef.coordinationScopes,\n            ...newScopeValues,\n          },\n        };\n      }\n    }\n    layout.push(newComponentDef);\n  });\n\n  // Use a random dataset ID when initializing automatically,\n  // so that it changes with each new v0.1.0 view config.\n  // However, check if the `datasetUid` parameter was passed,\n  // which allows for unit testing.\n  const newDatasetUid = datasetUid || uuidv4();\n\n  return {\n    version: '1.0.1',\n    name: config.name,\n    description: config.description,\n    public: config.public,\n    datasets: [\n      {\n        uid: newDatasetUid,\n        name: newDatasetUid,\n        files: config.layers.map(layer => ({\n          type: layer.type.toLowerCase(),\n          fileType: layer.fileType,\n          url: layer.url,\n        })),\n      },\n    ],\n    initStrategy: 'auto',\n    coordinationSpace,\n    layout,\n  };\n}\n\nexport function upgradeFrom1_0_0(config) {\n  const coordinationSpace = { ...config.coordinationSpace };\n\n  function replaceLayerType(layerType) {\n    // Layer type could be one of a few things, bitmask or raster at the moment.\n    const isRaster = layerType === 'raster';\n    coordinationSpace[`spatial${capitalize(layerType)}Layer${isRaster ? 's' : ''}`] = {};\n    Object.entries(coordinationSpace.spatialLayers).forEach(([scope, layers]) => {\n      if (Array.isArray(layers) && layers.find(layer => layer.type === layerType)) {\n        const typedLayers = layers\n          .filter(layer => layer.type === layerType)\n          .map((layer) => {\n            const newLayer = { ...layer };\n            delete newLayer.type;\n            return newLayer;\n          });\n        coordinationSpace[`spatial${capitalize(layerType)}Layer${isRaster ? 's' : ''}`][scope] = isRaster ? typedLayers : typedLayers[0];\n      } else {\n        coordinationSpace[`spatial${capitalize(layerType)}Layer${isRaster ? 's' : ''}`][scope] = null;\n      }\n    });\n  }\n\n  if (coordinationSpace.spatialLayers) {\n    replaceLayerType('raster');\n    replaceLayerType('cells');\n    replaceLayerType('molecules');\n    replaceLayerType('neighborhoods');\n    delete coordinationSpace.spatialLayers;\n  }\n\n  const layout = config.layout.map((component) => {\n    const newComponent = { ...component };\n\n    function replaceCoordinationScope(layerType) {\n      const isRaster = layerType === 'raster';\n      if (COMPONENT_COORDINATION_TYPES[newComponent.component].includes(`spatial${capitalize(layerType)}Layer${isRaster ? 's' : ''}`)) {\n        newComponent.coordinationScopes[`spatial${capitalize(layerType)}Layer${isRaster ? 's' : ''}`] = newComponent.coordinationScopes.spatialLayers;\n      }\n    }\n\n    if (newComponent.coordinationScopes && newComponent.coordinationScopes.spatialLayers) {\n      replaceCoordinationScope('raster');\n      replaceCoordinationScope('cells');\n      replaceCoordinationScope('molecules');\n      replaceCoordinationScope('neighborhoods');\n      delete newComponent.coordinationScopes.spatialLayers;\n    }\n    return newComponent;\n  });\n\n  return {\n    ...config,\n    coordinationSpace,\n    layout,\n    version: '1.0.1',\n  };\n}\n\n\nexport function upgradeFrom1_0_1(config) {\n  // Need to add the globalDisable3d prop to any layer controller views,\n  // to match the previous lack of 3D auto-detection behavior.\n\n  const layout = config.layout.map((component) => {\n    const newComponent = { ...component };\n    if (newComponent.component === 'layerController') {\n      newComponent.props = {\n        ...newComponent.props,\n        globalDisable3d: true,\n      };\n    }\n    return newComponent;\n  });\n\n  // Enforce bitmask or raster as spatial raster layer type, defaulting\n  // to raster layer if it is not one of bitmask or raster from the old config.\n\n  const newConfig = cloneDeep(config);\n  Object.keys((newConfig?.coordinationSpace?.spatialRasterLayers || {})).forEach((key) => {\n    if (newConfig.coordinationSpace.spatialRasterLayers[key]) {\n      newConfig.coordinationSpace.spatialRasterLayers[key].forEach((layer, index) => {\n        newConfig.coordinationSpace.spatialRasterLayers[key][index].type = ['bitmask', 'raster'].includes(layer.type) ? layer.type : 'raster';\n      });\n    }\n  });\n\n  return {\n    ...newConfig,\n    layout,\n    version: '1.0.2',\n  };\n}\n\nexport function upgradeFrom1_0_2(config) {\n  // Need to add the globalDisable3d prop to any layer controller views,\n  // to match the previous lack of 3D auto-detection behavior.\n\n  const layout = config.layout.map((component) => {\n    const newComponent = { ...component };\n    if (newComponent.component === 'layerController') {\n      newComponent.props = {\n        ...newComponent.props,\n        disableChannelsIfRgbDetected: true,\n      };\n    }\n    return newComponent;\n  });\n\n  // Enforce bitmask or raster as spatial raster layer type, defaulting\n  // to raster layer if it is not one of bitmask or raster from the old config.\n\n  const newConfig = cloneDeep(config);\n\n  return {\n    ...newConfig,\n    layout,\n    version: '1.0.3',\n  };\n}\n\nexport function upgradeFrom1_0_3(config) {\n  const newConfig = cloneDeep(config);\n\n  return {\n    ...newConfig,\n    version: '1.0.4',\n  };\n}\n\n// Added in version 1.0.5:\n// - Support for an array of strings in the setName property within options array items\n//   for the anndata-cell-sets.zarr file type.\nexport function upgradeFrom1_0_4(config) {\n  const newConfig = cloneDeep(config);\n\n  return {\n    ...newConfig,\n    version: '1.0.5',\n  };\n}\n\n\n// Added in version 1.0.6:\n// - Support for the scoreName property within options array items\n//   for the anndata-cell-sets.zarr file type.\nexport function upgradeFrom1_0_5(config) {\n  const newConfig = cloneDeep(config);\n\n  return {\n    ...newConfig,\n    version: '1.0.6',\n  };\n}\n","/* eslint-disable camelcase */\nimport Ajv from 'ajv';\nimport configSchema0_1_0 from '../schemas/config-0.1.0.schema.json';\nimport configSchema1_0_0 from '../schemas/config-1.0.0.schema.json';\nimport configSchema1_0_1 from '../schemas/config-1.0.1.schema.json';\nimport configSchema1_0_2 from '../schemas/config-1.0.2.schema.json';\nimport configSchema1_0_3 from '../schemas/config-1.0.3.schema.json';\nimport configSchema1_0_4 from '../schemas/config-1.0.4.schema.json';\nimport configSchema1_0_5 from '../schemas/config-1.0.5.schema.json';\nimport configSchema1_0_6 from '../schemas/config-1.0.6.schema.json';\nimport cellSetsSchema from '../schemas/cell-sets.schema.json';\nimport rasterSchema from '../schemas/raster.schema.json';\nimport {\n  upgradeFrom0_1_0,\n  upgradeFrom1_0_0,\n  upgradeFrom1_0_1,\n  upgradeFrom1_0_2,\n  upgradeFrom1_0_3,\n  upgradeFrom1_0_4,\n  upgradeFrom1_0_5,\n} from './view-config-upgraders';\n\n/**\n * Mapping from view config versions to view config schemas and upgrade functions.\n * Add a new schema and upgrade function here when bumping the view config version.\n * The latest view config version should always have a null value instead of an upgrade function.\n */\nexport const LATEST_VERSION = '1.0.6';\nexport const SCHEMA_HANDLERS = {\n  '0.1.0': [new Ajv().compile(configSchema0_1_0), upgradeFrom0_1_0],\n  '1.0.0': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_0), upgradeFrom1_0_0],\n  '1.0.1': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_1), upgradeFrom1_0_1],\n  '1.0.2': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_2), upgradeFrom1_0_2],\n  '1.0.3': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_3), upgradeFrom1_0_3],\n  '1.0.4': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_4), upgradeFrom1_0_4],\n  '1.0.5': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_5), upgradeFrom1_0_5],\n  '1.0.6': [new Ajv().addSchema(cellSetsSchema).addSchema(rasterSchema).compile(configSchema1_0_6), null],\n};\n","import { useEffect } from 'react';\nimport { SCHEMA_HANDLERS, LATEST_VERSION } from './view-config-versions';\nimport { useViewConfigStoreApi, useLoaders, useWarning } from './state/hooks';\n\nfunction validateViewConfig(viewConfig) {\n  // Need the try-catch here since Zustand will actually\n  // just catch and ignore errors in its subscription callbacks.\n  try {\n    const validate = SCHEMA_HANDLERS[LATEST_VERSION][0];\n    const valid = validate(viewConfig);\n    if (!valid) {\n      const failureReason = JSON.stringify(validate.errors, null, 2);\n      throw new Error(`Config validation failed: ${failureReason}`);\n    }\n  } catch (e) {\n    console.error(e);\n  }\n  // Do nothing if successful.\n}\n\n/**\n * This is a dummy component which handles\n * publishing new view configs and loaders to\n * the provided callbacks on changes.\n * @param {object} props\n * @param {function} props.onConfigChange A callback function\n * to execute on each change of the Vitessce view config.\n * @param {function} props.onLoaderChange A callback function\n * to execute on each change of the loaders object.\n * @param {boolean} props.validateOnConfigChange Whether to validate\n * against the view config schema when publishing changes.\n */\nexport default function CallbackPublisher(props) {\n  const {\n    onWarn,\n    onConfigChange,\n    onLoaderChange,\n    validateOnConfigChange,\n  } = props;\n\n  const warning = useWarning();\n  const loaders = useLoaders();\n\n  const viewConfigStoreApi = useViewConfigStoreApi();\n\n  // View config updates are often-occurring, so\n  // we want to use the \"transient update\" approach\n  // to subscribe to view config changes.\n  // Reference: https://github.com/react-spring/zustand#transient-updates-for-often-occuring-state-changes\n  useEffect(() => viewConfigStoreApi.subscribe(\n    // The function to run on each publish.\n    (viewConfig) => {\n      if (validateOnConfigChange && viewConfig) {\n        validateViewConfig(viewConfig);\n      }\n      if (onConfigChange && viewConfig) {\n        onConfigChange(viewConfig);\n      }\n    },\n    // The function to specify which part of the store\n    // we want to subscribe to.\n    state => state.viewConfig,\n  ), [onConfigChange, validateOnConfigChange, viewConfigStoreApi]);\n\n  // Emit updates to the warning message.\n  useEffect(() => {\n    if (onWarn && warning) {\n      onWarn(warning);\n    }\n  }, [warning, onWarn]);\n\n  // Emit updates to the loaders.\n  useEffect(() => {\n    if (onLoaderChange && loaders) {\n      onLoaderChange(loaders);\n    }\n  }, [loaders, onLoaderChange]);\n\n  // Render nothing.\n  return null;\n}\n","import { useState, useEffect } from 'react';\nimport equal from 'fast-deep-equal';\nimport { capitalize } from '../utils';\nimport { useSetWarning } from '../app/state/hooks';\nimport {\n  AbstractLoaderError,\n  LoaderNotFoundError,\n} from '../loaders/errors/index';\nimport {\n  DEFAULT_MOLECULES_LAYER,\n  DEFAULT_CELLS_LAYER,\n  DEFAULT_NEIGHBORHOODS_LAYER,\n} from './spatial/constants';\nimport { DEFAULT_COORDINATION_VALUES } from '../app/state/coordination';\n\n/**\n * Warn via publishing to the console\n * and to the global warning store.\n * @param {AbstractLoaderError} error An error instance.\n */\nfunction warn(error, setWarning) {\n  setWarning(error.message);\n  console.warn(error.message);\n  if (error instanceof AbstractLoaderError) {\n    error.warnInConsole();\n  }\n}\n\n/**\n * Initialize values in the coordination space.\n * @param {object} values Object where\n * keys are coordination type names,\n * values are initial coordination values.\n * @param {object} setters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialValues Object where\n * keys are coordination type names and keys are values.\n */\nfunction initCoordinationSpace(values, setters, initialValues) {\n  if (!values || !setters) {\n    return;\n  }\n  Object.entries(values).forEach(([coordinationType, value]) => {\n    const setterName = `set${capitalize(coordinationType)}`;\n    const setterFunc = setters[setterName];\n    const initialValue = initialValues && initialValues[coordinationType];\n    const shouldInit = equal(initialValue, DEFAULT_COORDINATION_VALUES[coordinationType]);\n    if (shouldInit && setterFunc) {\n      setterFunc(value);\n    }\n  });\n}\n\n/**\n * Get the dataset description string.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @returns {array} [description] where\n * description is a string.\n */\nexport function useDescription(loaders, dataset) {\n  const [description, setDescription] = useState();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].description) {\n      setDescription(loaders[dataset].description);\n    } else {\n      setDescription(null);\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [description];\n}\n\n/**\n * Get data from a cells data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names with the prefix 'initialize',\n * values are initialization preferences as boolean values.\n * @returns {array} [cells, cellsCount] where\n * cells is an object and cellsCount is the\n * number of items in the cells object.\n */\nexport function useCellsData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [cells, setCells] = useState({});\n  const [cellsCount, setCellsCount] = useState(0);\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders.cells) {\n      loaders[dataset].loaders.cells.load().catch(e => warn(e, setWarning)).then((payload) => {\n        if (!payload) return;\n        const { data, url, coordinationValues } = payload;\n        setCells(data);\n        setCellsCount(Object.keys(data).length);\n        addUrl(url, 'Cells');\n        // This dataset has cells, so set up the\n        // spatial cells layer coordination value\n        // using the cell layer singleton.\n        const coordinationValuesOrDefault = {\n          spatialCellsLayer: DEFAULT_CELLS_LAYER,\n          ...coordinationValues,\n        };\n        initCoordinationSpace(\n          coordinationValuesOrDefault,\n          coordinationSetters, initialCoordinationValues,\n        );\n        setItemIsReady('cells');\n      });\n    } else {\n      setCells({});\n      setCellsCount(0);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'cells', null, null), setWarning);\n      } else {\n        setItemIsReady('cells');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [cells, cellsCount];\n}\n\n/**\n * Get data from a cell sets data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names and values are the current values.\n * @returns {array} [cellSets] where\n * cellSets is a sets tree object.\n */\nexport function useCellSetsData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [cellSets, setCellSets] = useState();\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders['cell-sets']) {\n      // Load the data initially.\n      loaders[dataset].loaders['cell-sets'].load().catch(e => warn(e, setWarning)).then((payload) => {\n        if (!payload) return;\n        const { data, url, coordinationValues } = payload;\n        setCellSets(data);\n        addUrl(url, 'Cell Sets');\n        initCoordinationSpace(\n          coordinationValues,\n          coordinationSetters,\n          initialCoordinationValues,\n        );\n        setItemIsReady('cell-sets');\n      });\n    } else {\n      setCellSets(null);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'cell-sets', null, null), setWarning);\n      } else {\n        setItemIsReady('cell-sets');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [cellSets];\n}\n\n/**\n * Get (potentially filtered) data from an expression matrix data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.  Should not be used in conjunction (called in the same component)\n * with useExpressionAttrs as this returns a potentially filtered set of attributes\n * specifically for the returned expression data.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names with the prefix 'initialize',\n * values are initialization preferences as boolean values.\n * @returns {array} [expressionMatrix] where\n * expressionMatrix is an object with\n * shape { cols, rows, matrix }.\n */\nexport function useExpressionMatrixData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [expressionMatrix, setExpressionMatrix] = useState();\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders['expression-matrix']) {\n      loaders[dataset].loaders['expression-matrix'].load().catch(e => warn(e, setWarning)).then((payload) => {\n        if (!payload) return;\n        const { data, url, coordinationValues } = payload;\n        const [attrs, arr] = data;\n        setExpressionMatrix({\n          cols: attrs.cols,\n          rows: attrs.rows,\n          matrix: arr.data,\n        });\n        addUrl(url, 'Expression Matrix');\n        initCoordinationSpace(\n          coordinationValues,\n          coordinationSetters,\n          initialCoordinationValues,\n        );\n        setItemIsReady('expression-matrix');\n      });\n    } else {\n      setExpressionMatrix(null);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'expression-matrix', null, null), setWarning);\n      } else {\n        setItemIsReady('expression-matrix');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [expressionMatrix];\n}\n\n/**\n * Get data from the expression matrix data type loader for a given gene selection.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {boolean} selection A list of gene names to get expression data for.\n * @returns {array} [geneData] where geneData is an array [Uint8Array, ..., Uint8Array]\n * for however many genes are in the selection.\n */\nexport function useGeneSelection(\n  loaders,\n  dataset,\n  setItemIsReady,\n  isRequired,\n  selection,\n  setItemIsNotReady,\n) {\n  const [geneData, setGeneData] = useState();\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n    if (!selection) {\n      setItemIsReady('expression-matrix');\n      return;\n    }\n    const loader = loaders[dataset].loaders['expression-matrix'];\n    if (loader) {\n      setItemIsNotReady('expression-matrix');\n      const implementsGeneSelection = typeof loader.loadGeneSelection === 'function';\n      if (implementsGeneSelection) {\n        loaders[dataset].loaders['expression-matrix']\n          .loadGeneSelection({ selection })\n          .catch(e => warn(e, setWarning))\n          .then((payload) => {\n            if (!payload) return;\n            const { data } = payload;\n            setGeneData(data);\n            setItemIsReady('expression-matrix');\n          });\n      } else {\n        loader.load().catch(e => warn(e, setWarning)).then((payload) => {\n          if (!payload) return;\n          const { data } = payload;\n          const [attrs, { data: matrix }] = data;\n          const expressionDataForSelection = selection.map((sel) => {\n            const geneIndex = attrs.cols.indexOf(sel);\n            const numGenes = attrs.cols.length;\n            const numCells = attrs.rows.length;\n            const expressionData = new Uint8Array(numCells);\n            for (let cellIndex = 0; cellIndex < numCells; cellIndex += 1) {\n              expressionData[cellIndex] = matrix[cellIndex * numGenes + geneIndex];\n            }\n            return expressionData;\n          });\n          setGeneData(expressionDataForSelection);\n          setItemIsReady('expression-matrix');\n        });\n      }\n    } else {\n      setGeneData(null);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'expression-matrix', null, null), setWarning);\n      } else {\n        setItemIsReady('expression-matrix');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset, selection]);\n\n  return [geneData];\n}\n\n/**\n * Get the attributes for the expression matrix data type loader,\n * i.e names of cells and genes.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.  Should not be used in conjunction (called in the same component)\n * with useExpressionMatrixData.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @returns {object} [attrs] { rows, cols } object containing cell and gene names.\n */\nexport function useExpressionAttrs(loaders, dataset, setItemIsReady, addUrl, isRequired) {\n  const [attrs, setAttrs] = useState();\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n    const loader = loaders[dataset].loaders['expression-matrix'];\n    if (loader) {\n      const implementsLoadAttrs = typeof loader.loadAttrs === 'function';\n      if (implementsLoadAttrs) {\n        loader.loadAttrs().catch(e => warn(e, setWarning)).then((payload) => {\n          if (!payload) return;\n          const { data, url } = payload;\n          setAttrs(data);\n          addUrl(url, 'Expression Matrix');\n          setItemIsReady('expression-matrix');\n        });\n      } else {\n        loader.load().catch(e => warn(e, setWarning)).then((payload) => {\n          if (!payload) return;\n          const { data, url } = payload;\n          setAttrs(data[0]);\n          addUrl(url, 'Expression Matrix');\n          setItemIsReady('expression-matrix');\n        });\n      }\n    } else {\n      setAttrs(null);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'expression-matrix', null, null), setWarning);\n      } else {\n        setItemIsReady('expression-matrix');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [attrs];\n}\n\n/**\n * Get data from a molecules data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names with the prefix 'initialize',\n * values are initialization preferences as boolean values.\n * @returns {array} [molecules, moleculesCount, locationsCount] where\n * molecules is an object,\n * moleculesCount is the number of unique molecule types, and\n * locationsCount is the number of molecules.\n */\nexport function useMoleculesData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [molecules, setMolecules] = useState();\n  const [moleculesCount, setMoleculesCount] = useState(0);\n  const [locationsCount, setLocationsCount] = useState(0);\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders.molecules) {\n      loaders[dataset].loaders.molecules.load().catch(e => warn(e, setWarning)).then((payload) => {\n        if (!payload) return;\n        const { data, url, coordinationValues } = payload;\n        setMolecules(data);\n        setMoleculesCount(Object.keys(data).length);\n        setLocationsCount(Object.values(data)\n          .map(l => l.length)\n          .reduce((a, b) => a + b, 0));\n        addUrl(url, 'Molecules');\n        const coordinationValuesOrDefault = {\n          spatialMoleculesLayer: DEFAULT_MOLECULES_LAYER,\n          ...coordinationValues,\n        };\n        initCoordinationSpace(\n          coordinationValuesOrDefault,\n          coordinationSetters,\n          initialCoordinationValues,\n        );\n        setItemIsReady('molecules');\n      });\n    } else {\n      setMolecules({});\n      setMoleculesCount(0);\n      setLocationsCount(0);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'molecules', null, null), setWarning);\n      } else {\n        setItemIsReady('molecules');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [molecules, moleculesCount, locationsCount];\n}\n\n/**\n * Get data from a neighborhoods data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names with the prefix 'initialize',\n * values are initialization preferences as boolean values.\n * @returns {array} [neighborhoods] where\n * neighborhoods is an object.\n */\nexport function useNeighborhoodsData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [neighborhoods, setNeighborhoods] = useState();\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders.neighborhoods) {\n      loaders[dataset].loaders.neighborhoods.load().catch(e => warn(e, setWarning))\n        .then((payload) => {\n          if (!payload) return;\n          const { data, url, coordinationValues } = payload;\n          setNeighborhoods(data);\n          addUrl(url, 'Neighborhoods');\n          const coordinationValuesOrDefault = {\n            spatialNeighborhoodsLayer: DEFAULT_NEIGHBORHOODS_LAYER,\n            ...coordinationValues,\n          };\n          initCoordinationSpace(\n            coordinationValuesOrDefault,\n            coordinationSetters,\n            initialCoordinationValues,\n          );\n          setItemIsReady('neighborhoods');\n        });\n    } else {\n      setNeighborhoods({});\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'neighborhoods', null, null), setWarning);\n      } else {\n        setItemIsReady('neighborhoods');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [neighborhoods];\n}\n\n/**\n * Get data from a raster data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names with the prefix 'initialize',\n * values are initialization preferences as boolean values.\n * @returns {array} [raster, imageLayerLoaders, imageLayerMeta] where\n * raster is an object,\n * imageLayerLoaders is an object, and\n * imageLayerMeta is an object.\n */\nexport function useRasterData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [raster, setRaster] = useState();\n  // Since we want the image layer / channel definitions to come from the\n  // coordination space stored as JSON in the view config,\n  // we need to set up a separate state variable here to store the\n  // non-JSON objects, such as layer loader instances.\n  const [imageLayerLoaders, setImageLayerLoaders] = useState([]);\n  const [imageLayerMeta, setImageLayerMeta] = useState([]);\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders.raster) {\n      loaders[dataset].loaders.raster.load().catch(e => warn(e, setWarning)).then((payload) => {\n        if (!payload) return;\n        const { data, url: urls, coordinationValues } = payload;\n        setRaster(data);\n        urls.forEach(([url, name]) => {\n          addUrl(url, name);\n        });\n        const { loaders: nextImageLoaders, meta: nextImageMeta } = data;\n        setImageLayerLoaders(nextImageLoaders);\n        setImageLayerMeta(nextImageMeta);\n        initCoordinationSpace(\n          coordinationValues,\n          coordinationSetters,\n          initialCoordinationValues,\n        );\n        setItemIsReady('raster');\n      });\n    } else {\n      // There was no raster loader for this dataset,\n      // and raster should be optional.\n      setImageLayerLoaders([]);\n      setImageLayerMeta([]);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'raster', null, null), setWarning);\n      } else {\n        setItemIsReady('raster');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n  return [raster, imageLayerLoaders, imageLayerMeta];\n}\n\n/**\n * Get data from a genomic-profiles data type loader,\n * updating \"ready\" and URL state appropriately.\n * Throw warnings if the data is marked as required.\n * Subscribe to loader updates.\n * @param {object} loaders The object mapping\n * datasets and data types to loader instances.\n * @param {string} dataset The key for a dataset,\n * used to identify which loader to use.\n * @param {function} setItemIsReady A function to call\n * when done loading.\n * @param {function} addUrl A function to call to update\n * the URL list.\n * @param {boolean} isRequired Should a warning be thrown if\n * loading is unsuccessful?\n * @param {object} coordinationSetters Object where\n * keys are coordination type names with the prefix 'set',\n * values are coordination setter functions.\n * @param {object} initialCoordinationValues Object where\n * keys are coordination type names with the prefix 'initialize',\n * values are initialization preferences as boolean values.\n * @returns {array} [neighborhoods] where\n * neighborhoods is an object.\n */\nexport function useGenomicProfilesData(\n  loaders, dataset, setItemIsReady, addUrl, isRequired,\n  coordinationSetters, initialCoordinationValues,\n) {\n  const [genomicProfilesAttrs, setGenomicProfilesAttrs] = useState();\n\n  const setWarning = useSetWarning();\n\n  useEffect(() => {\n    if (!loaders[dataset]) {\n      return;\n    }\n\n    if (loaders[dataset].loaders['genomic-profiles']) {\n      loaders[dataset].loaders['genomic-profiles'].load().catch(e => warn(e, setWarning))\n        .then((payload) => {\n          if (!payload) return;\n          const { data, url, coordinationValues } = payload;\n          setGenomicProfilesAttrs(data);\n          addUrl(url);\n          initCoordinationSpace(\n            coordinationValues,\n            coordinationSetters,\n            initialCoordinationValues,\n          );\n          setItemIsReady('genomic-profiles');\n        });\n    } else {\n      setGenomicProfilesAttrs(null);\n      if (isRequired) {\n        warn(new LoaderNotFoundError(dataset, 'genomic-profiles', null, null), setWarning);\n      } else {\n        setItemIsReady('genomic-profiles');\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return [genomicProfilesAttrs];\n}\n","import React from 'react';\nimport CircularProgress from '@material-ui/core/CircularProgress';\n\nexport default function LoadingIndicator() {\n  return (\n    <div className=\"loading-indicator-backdrop\">\n      <div className=\"loading-indicator-container\">\n        <CircularProgress />\n      </div>\n    </div>\n  );\n}\n","import React, { useRef } from 'react';\nimport Paper from '@material-ui/core/Paper';\nimport Popper from '@material-ui/core/Popper';\nimport IconButton from '@material-ui/core/IconButton';\nimport MenuList from '@material-ui/core/MenuList';\nimport ClickAwayListener from '@material-ui/core/ClickAwayListener';\nimport Fade from '@material-ui/core/Fade';\nimport { useVitessceContainer } from '../hooks';\nimport { styles } from './styles';\n\nexport function MuiSpan(props) {\n  const { children } = props;\n  const classes = styles();\n  return <span className={classes.span}>{children}</span>;\n}\n\nexport function PopperMenu(props) {\n  const {\n    buttonIcon,\n    open,\n    setOpen,\n    children,\n    buttonClassName,\n    placement = 'bottom-end',\n  } = props;\n  const classes = styles();\n\n  const anchorRef = useRef();\n\n  const handleClick = () => {\n    setOpen(prev => !prev);\n  };\n\n  const handleClose = () => {\n    setOpen(false);\n  };\n\n  const id = open ? 'v-popover-menu' : undefined;\n\n  const getTooltipContainer = useVitessceContainer(anchorRef);\n\n  return (\n    <div ref={anchorRef} className={classes.container}>\n      <IconButton\n        aria-describedby={id}\n        onClick={handleClick}\n        size=\"small\"\n        className={buttonClassName}\n      >\n        {buttonIcon}\n      </IconButton>\n      <Popper\n        id={id}\n        open={open}\n        anchorEl={anchorRef && anchorRef.current}\n        container={getTooltipContainer}\n        onClose={handleClose}\n        placement={placement}\n        transition\n      >\n        {({ TransitionProps }) => (\n          <ClickAwayListener onClickAway={handleClose}>\n            <Fade {...TransitionProps} timeout={100}>\n              <Paper elevation={4} className={classes.paper}>\n                <MenuList>{children}</MenuList>\n              </Paper>\n            </Fade>\n          </ClickAwayListener>\n        )}\n      </Popper>\n    </div>\n  );\n}\n","import React, { useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport CloudDownloadIcon from '@material-ui/icons/CloudDownload';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport IconButton from '@material-ui/core/IconButton';\nimport Link from '@material-ui/core/Link';\nimport ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';\nimport ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport CloseIcon from '@material-ui/icons/Close';\n\nimport { SCROLL_CARD, BLACK_CARD, SECONDARY_CARD } from './classNames';\nimport LoadingIndicator from './LoadingIndicator';\nimport { PopperMenu } from './shared-mui/components';\n\nconst useStyles = makeStyles(theme => ({\n  iconButton: {\n    border: 'none',\n    marginLeft: 0,\n    background: 'none',\n    color: theme.palette.primaryForeground,\n    paddingLeft: '0.25em',\n    paddingRight: '0.25em',\n    borderRadius: '2px',\n    '&:hover': {\n      backgroundColor: theme.palette.primaryBackgroundLight,\n    },\n    '&:first-child': {\n      marginLeft: '0.25em',\n    },\n    '&:last-child': {\n      marginRight: '0.25em',\n    },\n    '& svg': {\n      width: '0.7em',\n      height: '0.7em',\n      verticalAlign: 'middle',\n      overflow: 'visible',\n    },\n  },\n  downloadLink: {\n    color: theme.palette.primaryForeground,\n  },\n}));\n\nfunction SettingsIconWithArrow({ open }) {\n  return (\n    <>\n      <SettingsIcon />\n      {open ? <ArrowDropUpIcon /> : <ArrowDropDownIcon />}\n    </>\n  );\n}\n\nfunction PlotOptions(props) {\n  const { options } = props;\n  const [open, setOpen] = useState(false);\n  const classes = useStyles();\n  return (\n    <PopperMenu\n      open={open}\n      setOpen={setOpen}\n      buttonIcon={<SettingsIconWithArrow open={open} />}\n      buttonClassName={classes.iconButton}\n      placement=\"bottom-end\"\n    >\n      {options}\n    </PopperMenu>\n  );\n}\n\nfunction CloudDownloadIconWithArrow({ open }) {\n  return (\n    <>\n      <CloudDownloadIcon />\n      {open ? <ArrowDropUpIcon /> : <ArrowDropDownIcon />}\n    </>\n  );\n}\n\nfunction DownloadOptions(props) {\n  const { urls } = props;\n  const [open, setOpen] = useState(false);\n  const classes = useStyles();\n  return (\n    <PopperMenu\n      open={open}\n      setOpen={setOpen}\n      buttonIcon={<CloudDownloadIconWithArrow open={open} />}\n      buttonClassName={classes.iconButton}\n      placement=\"bottom-end\"\n    >\n      {urls.map(({ url, name }) => (\n        <MenuItem dense key={url}>\n          <Link underline=\"none\" href={url} target=\"_blank\" rel=\"noopener\" className={classes.downloadLink}>\n            Download {name}\n          </Link>\n        </MenuItem>\n      ))}\n    </PopperMenu>\n  );\n}\n\nfunction ClosePaneButton(props) {\n  const { removeGridComponent } = props;\n  const classes = useStyles();\n  return (\n    <IconButton\n      onClick={removeGridComponent}\n      size=\"small\"\n      className={classes.iconButton}\n      title=\"close\"\n    >\n      <CloseIcon />\n    </IconButton>\n  );\n}\n\nexport default function TitleInfo(props) {\n  const {\n    title, info, children, isScroll, isSpatial, removeGridComponent, urls,\n    isReady, options,\n  } = props;\n  // eslint-disable-next-line no-nested-ternary\n  const childClassName = isScroll ? SCROLL_CARD : (isSpatial ? BLACK_CARD : SECONDARY_CARD);\n  return (\n    // d-flex without wrapping div is not always full height; I don't understand the root cause.\n    <>\n      <div className=\"title\">\n        <div className=\"title-left\">\n          {title}\n        </div>\n        <div className=\"title-info\" title={info}>\n          {info}\n        </div>\n        <div className=\"title-buttons\">\n          { options && (\n            <PlotOptions\n              options={options}\n            />\n          ) }\n          {urls && urls.length > 0 && (\n            <DownloadOptions\n              urls={urls}\n            />\n          )}\n          <ClosePaneButton\n            removeGridComponent={removeGridComponent}\n          />\n        </div>\n      </div>\n      <div className={childClassName}>\n        { !isReady && <LoadingIndicator /> }\n        {children}\n      </div>\n    </>\n    // \"pl-2\" only matters when the window is very narrow.\n  );\n}\n","import React from 'react';\n\nexport default function Description(props) {\n  const { description, metadata } = props;\n\n  return (\n    <div className=\"description\">\n      <p>{description}</p>\n\n      {metadata && Array.from(metadata.entries())\n        .map(([layerIndex, { name: layerName, metadata: metadataRecord }]) => (\n          metadataRecord && Object.entries(metadataRecord).length > 0 ? (\n            <details key={layerIndex}>\n              <summary>{layerName}</summary>\n              <div className=\"metadata-container\">\n                <table>\n                  <tbody>\n                    {Object.entries(metadataRecord)\n                      .map(([key, value]) => (\n                        <tr key={key}>\n                          <th title={key}>{key}</th>\n                          <td title={value}>{value}</td>\n                        </tr>\n                      ))}\n                  </tbody>\n                </table>\n              </div>\n            </details>\n          ) : null))}\n    </div>\n  );\n}\n","import React, { useEffect, useMemo } from 'react';\nimport { useReady } from '../hooks';\nimport { useDescription, useRasterData } from '../data-hooks';\nimport { useCoordination, useLoaders } from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport TitleInfo from '../TitleInfo';\nimport Description from './Description';\n\nconst DESCRIPTION_DATA_TYPES = ['raster'];\n\n/**\n * A subscriber component for a text description component.\n * Also renders a table containing image metadata.\n * @param {object} props\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n */\nexport default function DescriptionSubscriber(props) {\n  const {\n    coordinationScopes,\n    description: descriptionOverride,\n    removeGridComponent,\n    theme,\n    title = 'Data Set',\n  } = props;\n\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    spatialRasterLayers: rasterLayers,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.description, coordinationScopes);\n\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    DESCRIPTION_DATA_TYPES,\n  );\n\n  // Reset loader progress when the dataset has changed.\n  useEffect(() => {\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [description] = useDescription(loaders, dataset);\n  const [raster, imageLayerLoaders, imageLayerMeta] = useRasterData(\n    loaders, dataset, setItemIsReady, () => {}, false,\n  );\n\n  const metadata = useMemo(() => {\n    const result = new Map();\n    if (rasterLayers && rasterLayers.length > 0 && raster && imageLayerMeta && imageLayerLoaders) {\n      rasterLayers.forEach((layer) => {\n        if (imageLayerMeta[layer.index]) {\n          // Want to ensure that layer index is a string.\n          const { format } = imageLayerLoaders[layer.index].metadata;\n          result.set(`${layer.index}`, {\n            name: raster.meta[layer.index].name,\n            metadata: format && format(),\n          });\n        }\n      });\n    }\n    return result;\n  }, [raster, rasterLayers, imageLayerMeta, imageLayerLoaders]);\n\n  return (\n    <TitleInfo\n      title={title}\n      removeGridComponent={removeGridComponent}\n      isScroll\n      theme={theme}\n      isReady={isReady}\n    >\n      <Description\n        description={descriptionOverride || description}\n        metadata={metadata}\n      />\n    </TitleInfo>\n  );\n}\n","import React from 'react';\n\nexport default function Status(props) {\n  const warnClass = 'alert alert-warning my-0 details';\n  const { info, warn } = props;\n  const messages = [];\n  if (info) {\n    messages.push(<p className=\"details\" key=\"info\">{info}</p>);\n  }\n  if (warn) {\n    messages.push(<p className={warnClass} key=\"warn\">{warn}</p>);\n  }\n  return (\n    messages\n  );\n}\n","/* eslint-disable jsx-a11y/no-noninteractive-element-to-interactive-role */\n/* eslint-disable jsx-a11y/click-events-have-key-events */\nimport React, { useEffect, useCallback, useState } from 'react';\nimport { Table, AutoSizer } from 'react-virtualized';\nimport uuidv4 from 'uuid/v4';\nimport union from 'lodash/union';\nimport difference from 'lodash/difference';\nimport isEqual from 'lodash/isEqual';\n\n/**\n * A table with \"selectable\" rows.\n * @prop {string[]} columns An array of column names, corresponding to data object properties.\n * @prop {object[]} data An array of data objects used to populate table rows.\n * @prop {function} onChange Callback function,\n * passed a selection object when `allowMultiple` is false (and `null` if `allowUncheck` is true),\n * or passed an array of selection objects when `allowMultiple` is true.\n * @prop {string} idKey The key for a unique identifier property of `data` objects.\n * @prop {string} valueKey If initially-selected rows are required,\n * this key specifies a boolean property of the `data` objects\n * indicating those rows that should be initially selected.\n * @prop {boolean} allowMultiple Whether to allow multiple rows to be selected. By default, false.\n * @prop {boolean} allowUncheck Whether to allow selected rows to be un-checked. By default, false.\n * @prop {boolean} showTableHead Whether to show the table header element. By default, true.\n * @prop {boolean} showTableInputs Whether to show the table input elements for each row.\n * By default, false.\n */\nexport default function SelectableTable(props) {\n  const {\n    hasColorEncoding,\n    columns,\n    data,\n    onChange,\n    idKey = 'id',\n    valueKey = 'value',\n    allowMultiple = false,\n    allowUncheck = false,\n    showTableHead = true,\n    showTableInputs = false,\n    testHeight = undefined,\n    testWidth = undefined,\n  } = props;\n\n  const [selectedRows, setSelectedRows] = useState(null);\n\n  // Callback function to update the `selectedRows` state.\n  const onSelectRow = useCallback((value, checked) => {\n    if (checked || allowUncheck) {\n      if (!allowMultiple) {\n        setSelectedRows(checked ? [value] : []);\n      } else {\n        setSelectedRows(\n          checked\n            ? union(selectedRows || [], [value])\n            : difference(selectedRows || [], [value]),\n        );\n      }\n    }\n  }, [allowMultiple, allowUncheck, selectedRows]);\n\n  // Handler for checkbox input elements.\n  const handleInputChange = useCallback((event) => {\n    const { target } = event;\n    const { checked } = target;\n    const { value } = target;\n    onSelectRow(value, checked);\n  }, [onSelectRow]);\n\n  // Function to map row IDs to corresponding objects\n  // to pass to the `onChange` callback.\n  const getDataFromIds = useCallback(ids => ids.map(id => ({\n    [idKey]: id,\n    data: data.find(item => item[idKey] === id),\n  })), [data, idKey]);\n\n  // Function to check if a row ID has been selected.\n  const isSelected = useCallback(id => (\n    Array.isArray(selectedRows) && selectedRows.includes(id)\n  ), [selectedRows]);\n\n  /* eslint-disable react-hooks/exhaustive-deps */\n  useEffect(() => {\n    // Check whether an initial set of rows should be selected.\n    const initialSelectedRows = data\n      .map((d) => {\n        if (d[valueKey]) {\n          return d[idKey];\n        }\n        return null;\n      })\n      .filter(Boolean);\n    if (!isEqual(initialSelectedRows, selectedRows)) {\n      if (initialSelectedRows.length > 0) {\n        setSelectedRows(initialSelectedRows);\n      } else {\n        setSelectedRows(null);\n      }\n    }\n  }, [data, idKey, valueKey]);\n\n  /* eslint-disable react-hooks/exhaustive-deps */\n  useEffect(() => {\n    // Call the `onChange` prop function with an updated row or set of rows.\n    if (!onChange || !selectedRows) {\n      return;\n    }\n    const selectedRowData = getDataFromIds(selectedRows);\n    if (allowMultiple) {\n      onChange(selectedRowData);\n    } else if (selectedRows.length === 1) {\n      onChange(selectedRowData[0]);\n    } else if (selectedRows.length === 0) {\n      onChange(null);\n    }\n  }, [selectedRows]);\n\n  // Generate a unique ID to use in (for, id) label-input pairs.\n  const inputUuid = uuidv4();\n\n  // Class for first column of inputs, to hide them if desired.\n  const hiddenInputsClass = (showTableInputs ? '' : 'hidden-input-column');\n\n  const rowRenderer = ({ index, style }) => (\n    // eslint-disable-next-line jsx-a11y/interactive-supports-focus\n    <div\n      key={data[index][idKey]}\n      className={`table-item table-row ${isSelected(data[index][idKey]) ? 'row-checked ' : ''}`}\n      style={style}\n      role=\"button\"\n      onClick={() => onSelectRow(\n        data[index][idKey],\n        !isSelected(data[index][idKey]) || !hasColorEncoding,\n      )}\n    >\n      <div className={`input-container ${hiddenInputsClass} table-cell`}>\n        <label htmlFor={`${inputUuid}_${data[index][idKey]}`}>\n          <input\n            id={`${inputUuid}_${data[index][idKey]}`}\n            type=\"checkbox\"\n            className={(allowMultiple ? 'checkbox' : 'radio')}\n            name={inputUuid}\n            value={data[index][idKey]}\n            onChange={handleInputChange}\n            checked={isSelected(data[index][idKey])}\n          />\n        </label>\n      </div>\n      {columns.map(column => (\n        <div\n          className=\"table-cell\"\n          key={column}\n        >\n          {data[index][column]}\n        </div>\n      ))}\n    </div>\n  );\n\n  const headerRowRenderer = ({ style }) => (\n    <div className={`${hiddenInputsClass} table-row`} style={style}>\n      {columns.map(column => (\n        <div key={column}>{column}</div>\n      ))}\n    </div>\n  );\n\n  return (\n    <div className=\"selectable-table\">\n      <AutoSizer>\n        {({ width, height }) => (\n          <Table\n            height={testHeight || height}\n            gridStyle={{ outline: 'none' }}\n            rowCount={data.length}\n            // 24 is 1 em + padding in either direction (see _selectable_table.scss).\n            rowHeight={24}\n            headerHeight={showTableHead ? 24 : undefined}\n            rowRenderer={rowRenderer}\n            width={testWidth || width}\n            headerRowRenderer={showTableHead ? headerRowRenderer : undefined}\n            rowGetter={({ index }) => data[index]}\n          />\n        )}\n      </AutoSizer>\n    </div>\n  );\n}\n","import React, { useEffect, useState } from 'react';\nimport { SelectableTable } from '../selectable-table/index';\n\nexport default function Genes(props) {\n  const {\n    hasColorEncoding,\n    geneList = [],\n    geneSelection = [],\n    geneFilter = null,\n    setGeneSelection,\n  } = props;\n\n  const [searchTerm, setSearchTerm] = useState('');\n  const [searchResults, setSearchResults] = useState(geneList);\n\n  useEffect(() => {\n    const results = geneList\n      .filter(gene => gene.toLowerCase().includes(searchTerm.toLowerCase()));\n    setSearchResults(results);\n  }, [searchTerm, geneList]);\n\n  function onChange(selection) {\n    if (setGeneSelection && selection && selection.name) {\n      setGeneSelection([selection.name]);\n    }\n  }\n\n  const data = searchResults\n    .filter(gene => (geneFilter ? geneFilter.includes(gene) : true))\n    .sort((a, b) => a.localeCompare(b))\n    .map(\n      gene => ({ name: gene, value: (geneSelection ? geneSelection.includes(gene) : false) }),\n    );\n\n  const handleChange = (event) => {\n    setSearchTerm(event.target.value);\n  };\n\n  return (\n    <>\n      <input\n        className=\"search-bar\"\n        type=\"text\"\n        placeholder=\"Search\"\n        value={searchTerm}\n        onChange={handleChange}\n      />\n      <SelectableTable\n        columns={['name']}\n        data={data}\n        hasColorEncoding={hasColorEncoding}\n        idKey=\"name\"\n        valueKey=\"value\"\n        onChange={onChange}\n        allowUncheck={false}\n        showTableHead={false}\n      />\n    </>\n  );\n}\n","import React, { useEffect } from 'react';\nimport { pluralize } from '../../utils';\nimport { useReady, useUrls } from '../hooks';\nimport { useExpressionAttrs } from '../data-hooks';\nimport { useCoordination, useLoaders } from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\n\nimport TitleInfo from '../TitleInfo';\nimport Genes from './Genes';\n\nconst GENES_DATA_TYPES = ['expression-matrix'];\n\n/**\n * A subscriber component for a gene listing component.\n * @param {object} props\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n * @param {string} props.variablesLabelOverride The singular form\n * of the name of the variable.\n * @param {string} props.variablesPluralLabelOverride The plural\n * form of the name of the variable.\n */\nexport default function GenesSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    variablesLabelOverride: variablesLabel = 'gene',\n    variablesPluralLabelOverride: variablesPluralLabel = `${variablesLabel}s`,\n    theme,\n    title = 'Expression Levels',\n  } = props;\n\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    geneSelection,\n    geneFilter,\n    cellColorEncoding,\n  }, {\n    setGeneSelection,\n    setGeneFilter,\n    setGeneHighlight,\n    setCellColorEncoding,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.genes, coordinationScopes);\n\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    GENES_DATA_TYPES,\n  );\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [attrs] = useExpressionAttrs(\n    loaders, dataset, setItemIsReady, addUrl, true,\n  );\n  const geneList = attrs ? attrs.cols : [];\n  const numGenes = geneList.length;\n\n  function setGeneSelectionAndColorEncoding(newSelection) {\n    setGeneSelection(newSelection);\n    setCellColorEncoding('geneSelection');\n  }\n\n  return (\n    <TitleInfo\n      title={title}\n      info={`${numGenes} ${pluralize(variablesLabel, variablesPluralLabel, numGenes)}`}\n      theme={theme}\n      // Virtual scroll is used but this allows for the same styling as a scroll component\n      // even though this no longer uses the TitleInfo component's\n      // scroll css (SelectableTable is virtual scroll).\n      isScroll\n      removeGridComponent={removeGridComponent}\n      isReady={isReady}\n      urls={urls}\n    >\n      <Genes\n        hasColorEncoding={cellColorEncoding === 'geneSelection'}\n        geneList={geneList}\n        geneSelection={geneSelection}\n        geneFilter={geneFilter}\n        setGeneSelection={setGeneSelectionAndColorEncoding}\n        setGeneFilter={setGeneFilter}\n        setGeneHighlight={setGeneHighlight}\n      />\n    </TitleInfo>\n  );\n}\n","import React from 'react';\nimport RcTree from 'rc-tree';\nimport classNames from 'classnames';\n\n/**\n * A helper component around the rc-tree\n * library's tree component, to set\n * default props.\n */\nconst Tree = React.forwardRef((props, ref) => {\n  const {\n    prefixCls,\n    className,\n    showIcon,\n    blockNode,\n    children,\n    checkable,\n  } = props;\n  return (\n    <RcTree\n      itemHeight={32}\n      ref={ref}\n      {...props}\n      className={classNames(className, {\n        [`${prefixCls}-icon-hide`]: !showIcon,\n        [`${prefixCls}-block-node`]: blockNode,\n      })}\n      checkable={checkable ? <span className={`${prefixCls}-checkbox-inner`} /> : checkable}\n    >\n      {children}\n    </RcTree>\n  );\n});\n\nTree.defaultProps = {\n  virtual: false,\n  checkable: false,\n  showIcon: false,\n  blockNode: true,\n  prefixCls: 'rc-tree',\n};\n\nexport default Tree;\n","import React, { useRef } from 'react';\nimport RcTooltip from 'rc-tooltip';\nimport { useVitessceContainer } from '../hooks';\n\n/**\n * This is a small wrapper around the Tooltip component from the rc-tooltip library,\n * which is required to be able to apply theme styles to the tooltip.\n * The default `getTooltipContainer` function used by rc-tooltip\n * just returns `document.body` (see https://github.com/react-component/tooltip#props),\n * We want theme styles to be applied relative to the closest `.vitessce-container`\n * ancestor element.\n * https://github.com/vitessce/vitessce/pull/494#discussion_r395957914\n * @param {object} props Props are passed through to the <RcTooltip/> from the library.\n */\nexport default function HelpTooltip(props) {\n  const { title, content, overlayClassName } = props;\n  const spanRef = useRef();\n  const getTooltipContainer = useVitessceContainer(spanRef);\n\n  const overlay = title || content;\n\n  return (\n    <>\n      <span ref={spanRef} />\n      <RcTooltip\n        getTooltipContainer={getTooltipContainer}\n        overlayClassName={overlayClassName}\n        overlay={overlay}\n        {...props}\n      />\n    </>\n  );\n}\n\nHelpTooltip.defaultProps = {\n  overlayClassName: 'help-tooltip',\n  placement: 'top',\n  trigger: 'hover',\n  mouseEnterDelay: 0.2,\n  mouseLeaveDelay: 0,\n};\n","import React from 'react';\nimport HelpTooltip from './HelpTooltip';\n\n/**\n * This is a wrapper around the HelpTooltip component, to style it as a popover,\n * and change the trigger to \"click\" rather than \"hover\".\n * @param {*} props Props are passed through to the HelpTooltip component.\n */\nexport default function Popover(props) {\n  return (\n    <HelpTooltip {...props} />\n  );\n}\n\nPopover.defaultProps = {\n  overlayClassName: 'popover',\n  placement: 'top',\n  trigger: 'click',\n  mouseEnterDelay: 0,\n  mouseLeaveDelay: 0,\n};\n","import React, { useState, useEffect } from 'react';\nimport { TwitterPicker } from 'react-color';\nimport { colorArrayToString, callbackOnKeyPress } from './utils';\nimport { PALETTE } from '../utils';\nimport Popover from './Popover';\n\n/**\n * Wrapper around a button element that supports asking for confirmation.\n * @param {object} props\n * @param {string} props.title The main button text.\n * @param {string} props.subtitle Smaller text on a line beneath the main text. Optional.\n * @param {function} props.onClick A \"clean up\" handler passed from the parent,\n * to alert the parent Popover component that it should close the popover after the button has\n * fired its handler.\n * @param {function} props.handler A function to call on button click (or after confirmation).\n * @param {string} props.handlerKey A key associated with the button, to support accessibility.\n * @param {boolean} props.confirm Does the user need to press the button again to confirm?\n * By default, false.\n * @param {boolean} props.visible The visibility state from the parent popover,\n * so that on visibility change, the button can clear its confirmation state.\n */\nfunction PopoverMenuListButton(props) {\n  const {\n    title, subtitle, onClick, handler, handlerKey, confirm,\n    visible,\n  } = props;\n\n  const [isConfirming, setIsConfirming] = useState(false);\n\n  useEffect(() => {\n    // Want to clear the \"confirming\",\n    // state if the user hides the popover.\n    setIsConfirming(false);\n  }, [visible]);\n\n  function handleOrRequireConfirm() {\n    if (!confirm || isConfirming) {\n      onClick();\n      handler();\n    } else {\n      setIsConfirming(true);\n    }\n  }\n\n  const titleWithConfirm = `${isConfirming ? 'Confirm ' : ''}${title}`;\n\n  return (\n    <button\n      title={titleWithConfirm}\n      type=\"button\"\n      onClick={handleOrRequireConfirm}\n      onKeyPress={e => callbackOnKeyPress(e, handlerKey, handleOrRequireConfirm)}\n    >{titleWithConfirm}\n      {subtitle && (<><br /><span className=\"small\">{subtitle}</span></>)}\n    </button>\n  );\n}\n\n/**\n * Helper component to create a list of buttons for the body of a popover.\n * If the color, setColor, and palette props are provided then a color picker\n * will be rendered at the top of the button list.\n * @param {object} props\n * @param {object[]} props.menuConfig The list of button definition objects.\n * `{ title, subtitle, confirm, handler, handlerKey }`\n * @param {function} props.onClick A \"clean up\" handler passed from the parent,\n * to alert the parent Popover component that it should close the popover after the button has\n * fired its handler.\n * @param {number[]} props.color The current color. Optional.\n * @param {string} props.palette The color palette for the color picker. Optional.\n * @param {boolean} props.setColor The handler to call when a color has been selected. Optional.\n * @param {boolean} props.visible The visibility state from the parent popover,\n * so that on visibility change, buttons can clear confirmation states.\n */\nfunction PopoverMenuList(props) {\n  const {\n    menuConfig,\n    onClick,\n    color = null,\n    palette = null,\n    setColor = null,\n    visible,\n  } = props;\n\n  function handleColorChange({ rgb }) {\n    if (rgb && setColor) {\n      setColor([rgb.r, rgb.g, rgb.b]);\n    }\n  }\n\n  const defaultPalette = palette\n    ? palette.map(colorArrayToString)\n    : PALETTE.concat([[255, 255, 255], [128, 128, 128], [0, 0, 0]]).map(colorArrayToString);\n\n  return (\n    <div>\n      {color && setColor && defaultPalette && (\n        <TwitterPicker\n          className=\"popover-menu-color\"\n          disableAlpha\n          width={108}\n          triangle=\"hide\"\n          colors={defaultPalette}\n          color={colorArrayToString(color)}\n          onChangeComplete={handleColorChange}\n        />\n      )}\n      <ul className=\"popover-menu-list\">\n        {menuConfig.map(item => (\n          <li key={item.title + item.subtitle}>\n            <PopoverMenuListButton\n              {...item}\n              onClick={onClick}\n              visible={visible}\n            />\n          </li>\n        ))}\n      </ul>\n    </div>\n  );\n}\n\n/**\n * Helper component to create a popover component with a list of buttons.\n * If the color, setColor, and palette props are provided then a color picker\n * will be rendered at the top of the button list.\n * @param {object} props\n * @param {object[]} props.menuConfig The list of button definition objects.\n * `{ title, subtitle, confirm, handler, handlerKey }`\n * @param {string} placement Where to place the popover (top, bottom, left, right).\n * @param {number[]} props.color The current color. Optional.\n * @param {string} props.palette The color palette for the color picker. Optional.\n * @param {boolean} props.setColor The handler to call when a color has been selected. Optional.\n * @param {Element|React.Component} props.children Children to render,\n * which will trigger the popover on click.\n */\nexport default function PopoverMenu(props) {\n  const {\n    menuConfig, placement, children,\n    color = null, setColor = null, palette = null,\n  } = props;\n\n  const [visible, setVisible] = useState(false);\n\n  return (\n    <Popover\n      content={(\n        <PopoverMenuList\n          menuConfig={menuConfig}\n          onClick={() => setVisible(false)}\n          color={color}\n          setColor={setColor}\n          palette={palette}\n          visible={visible}\n        />\n)}\n      placement={placement}\n      visible={visible}\n      onVisibleChange={setVisible}\n    >\n      {children}\n    </Popover>\n  );\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"path\", {\n  d: \"M12 18c1.657 0 3 1.343 3 3s-1.343 3-3 3-3-1.343-3-3 1.343-3 3-3zm0-9c1.657 0 3 1.343 3 3s-1.343 3-3 3-3-1.343-3-3 1.343-3 3-3zm0-9c1.657 0 3 1.343 3 3s-1.343 3-3 3-3-1.343-3-3 1.343-3 3-3z\"\n});\n\nfunction SvgMenu(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    width: 24,\n    height: 24,\n    viewBox: \"0 0 24 24\",\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, _ref2);\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgMenu, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/menu.bc56e94a.svg\";\nexport { ForwardRef as ReactComponent };","import React, { useState } from 'react';\nimport clsx from 'clsx';\nimport { TreeNode as RcTreeNode } from 'rc-tree';\nimport { getDataAndAria } from 'rc-tree/es/util';\nimport classNames from 'classnames';\nimport range from 'lodash/range';\nimport isEqual from 'lodash/isEqual';\nimport PopoverMenu from './PopoverMenu';\nimport HelpTooltip from './HelpTooltip';\nimport { callbackOnKeyPress, colorArrayToString, getLevelTooltipText } from './utils';\nimport { ReactComponent as MenuSVG } from '../../assets/menu.svg';\nimport { getDefaultColor } from '../utils';\n\n\n/**\n * Construct a `menuConfig` array for the PopoverMenu component.\n * @param {object} props The props for the TreeNode component.\n * @returns {object[]} An array of menu items to pass to PopoverMenu.\n */\nfunction makeNodeViewMenuConfig(props) {\n  const {\n    path,\n    level,\n    height,\n    onCheckNode,\n    onNodeRemove,\n    onNodeSetIsEditing,\n    onExportLevelZeroNodeJSON,\n    onExportLevelZeroNodeTabular,\n    onExportSetJSON,\n    checkable,\n    editable,\n    exportable,\n    checked,\n  } = props;\n\n  return [\n    ...(editable ? [\n      {\n        title: 'Rename',\n        handler: () => { onNodeSetIsEditing(path, true); },\n        handlerKey: 'r',\n      },\n      {\n        title: 'Delete',\n        confirm: true,\n        handler: () => { onNodeRemove(path); },\n        handlerKey: 'd',\n      },\n    ] : []),\n    ...(level === 0 && exportable ? [\n      {\n        title: 'Export hierarchy',\n        subtitle: '(to JSON file)',\n        handler: () => { onExportLevelZeroNodeJSON(path); },\n        handlerKey: 'j',\n      },\n      ...(height <= 1 ? [\n        {\n          title: 'Export hierarchy',\n          subtitle: '(to CSV file)',\n          handler: () => { onExportLevelZeroNodeTabular(path); },\n          handlerKey: 't',\n        },\n      ] : []),\n    ] : []),\n    ...(level > 0 ? [\n      ...(checkable ? [\n        {\n          title: (checked ? 'Uncheck' : 'Check'),\n          handler: () => { onCheckNode(path, !checked); },\n          handlerKey: 's',\n        },\n      ] : []),\n      ...(exportable ? [\n        {\n          title: 'Export set',\n          subtitle: '(to JSON file)',\n          handler: () => { onExportSetJSON(path); },\n          handlerKey: 'e',\n        },\n      ] : []),\n    ] : []),\n  ];\n}\n\n/**\n * The \"static\" node component to render when the user is not renaming.\n * @param {object} props The props for the TreeNode component.\n */\nfunction NamedSetNodeStatic(props) {\n  const {\n    title,\n    path,\n    nodeKey,\n    level,\n    height,\n    color,\n    checkbox,\n    isChecking,\n    isLeaf,\n    onNodeSetColor,\n    onNodeView,\n    expanded,\n    onCheckLevel,\n    checkedLevelPath,\n    checkedLevelIndex,\n    disableTooltip,\n    size,\n    datatype,\n    editable,\n    theme,\n  } = props;\n  const shouldCheckNextLevel = (level === 0 && !expanded);\n  const nextLevelToCheck = (\n    (checkedLevelIndex && isEqual(path, checkedLevelPath) && checkedLevelIndex < height)\n      ? checkedLevelIndex + 1\n      : 1\n  );\n  const numberFormatter = new Intl.NumberFormat('en-US');\n  const niceSize = numberFormatter.format(size);\n  let tooltipText;\n  if (shouldCheckNextLevel) {\n    tooltipText = getLevelTooltipText(nextLevelToCheck);\n  } else if (isLeaf || !expanded) {\n    tooltipText = `Color individual set (${niceSize} ${datatype}${(size === 1 ? '' : 's')})`;\n  } else {\n    tooltipText = 'Color by expanded descendants';\n  }\n  // If this is a level zero node and is _not_ expanded, then upon click,\n  // the behavior should be to color by the first or next cluster level.\n  // If this is a level zero node and _is_ expanded, or if any other node,\n  // click should trigger onNodeView.\n  const onClick = (level === 0 && !expanded\n    ? () => onCheckLevel(nodeKey, nextLevelToCheck)\n    : () => onNodeView(path)\n  );\n  const tooltipProps = (disableTooltip ? { visible: false } : {});\n  const popoverMenuConfig = makeNodeViewMenuConfig(props);\n  return (\n    <span>\n      <HelpTooltip title={tooltipText} {...tooltipProps}>\n        <button\n          type=\"button\"\n          onClick={onClick}\n          onKeyPress={e => callbackOnKeyPress(e, 'v', () => onNodeView(path))}\n          className=\"title-button\"\n        >\n          {title}\n        </button>\n      </HelpTooltip>\n      {popoverMenuConfig.length > 0 ? (\n        <PopoverMenu\n          menuConfig={makeNodeViewMenuConfig(props)}\n          color={level > 0 && editable ? (color || getDefaultColor(theme)) : null}\n          setColor={c => onNodeSetColor(path, c)}\n        >\n          <MenuSVG className=\"node-menu-icon\" />\n        </PopoverMenu>\n      ) : null}\n      {level > 0 && isChecking ? checkbox : null}\n      {level > 0 && (<span className=\"node-size-label\">{niceSize}</span>)}\n    </span>\n  );\n}\n\n/**\n * The \"editing\" node component to render when the user is renaming,\n * containing a text input field and a save button.\n * @param {object} props The props for the TreeNode component.\n */\nfunction NamedSetNodeEditing(props) {\n  const {\n    title,\n    path,\n    onNodeSetName,\n    onNodeCheckNewName,\n  } = props;\n  const [currentTitle, setCurrentTitle] = useState(title);\n\n  // Do not allow the user to save a potential name if it conflicts with\n  // another name in the hierarchy.\n  const hasConflicts = onNodeCheckNewName(path, currentTitle);\n  function trySetName() {\n    if (!hasConflicts) {\n      onNodeSetName(path, currentTitle, true);\n    }\n  }\n  return (\n    <span className=\"title-button-with-input\">\n      <input\n        // eslint-disable-next-line jsx-a11y/no-autofocus\n        autoFocus\n        className=\"title-input\"\n        type=\"text\"\n        value={currentTitle}\n        onChange={(e) => { setCurrentTitle(e.target.value); }}\n        onKeyPress={e => callbackOnKeyPress(\n          e,\n          'Enter',\n          trySetName,\n        )}\n        onFocus={e => e.target.select()}\n      />\n      {!hasConflicts && (\n        <button\n          type=\"button\"\n          className=\"title-save-button\"\n          onClick={trySetName}\n        >\n          Save\n        </button>\n      )}\n    </span>\n  );\n}\n\n/**\n * A \"delegation\" component, to decide whether to render\n * an \"editing\" vs. \"static\" node component.\n * @param {object} props The props for the TreeNode component.\n */\nfunction NamedSetNode(props) {\n  const {\n    isEditing,\n    isCurrentSet,\n  } = props;\n  return (\n    (isEditing || isCurrentSet)\n      ? (<NamedSetNodeEditing {...props} />)\n      : (<NamedSetNodeStatic {...props} />)\n  );\n}\n\n/**\n * Buttons for viewing each hierarchy level,\n * rendered below collapsed level zero nodes.\n * @param {object} props The props for the (level zero) TreeNode component.\n */\nfunction LevelsButtons(props) {\n  const {\n    nodeKey,\n    path,\n    height,\n    onCheckLevel,\n    checkedLevelPath,\n    checkedLevelIndex,\n    hasColorEncoding,\n  } = props;\n  function onCheck(event) {\n    if (event.target.checked) {\n      const newLevel = parseInt(event.target.value, 10);\n      onCheckLevel(nodeKey, newLevel);\n    }\n  }\n  return (\n    <div className=\"level-buttons-container\">\n      {range(1, height + 1).map((i) => {\n        const isChecked = isEqual(path, checkedLevelPath) && i === checkedLevelIndex;\n        return (\n          <div className=\"level-buttons\" key={i}>\n            <HelpTooltip title={getLevelTooltipText(i)}>\n              <input\n                className={clsx('level-radio-button', { checked: isChecked && !hasColorEncoding })}\n                type=\"checkbox\"\n                value={i}\n                checked={isChecked && hasColorEncoding}\n                onChange={onCheck}\n              />\n            </HelpTooltip>\n          </div>\n        );\n      })}\n    </div>\n  );\n}\n\n/**\n * Render the \"switcher\" icon.\n * Arrow for collapsed/expanded non-leaf nodes,\n * or square for leaf nodes.\n * @param {object} props The props for the TreeNode component.\n */\nfunction SwitcherIcon(props) {\n  const {\n    isLeaf, isOpen, color,\n  } = props;\n  const hexColor = (color ? colorArrayToString(color) : undefined);\n  if (isLeaf) {\n    return (\n      <i\n        className=\"anticon anticon-circle rc-tree-switcher-icon\"\n      >\n        <svg\n          viewBox=\"0 0 1024 1024\"\n          focusable=\"false\"\n          data-icon=\"caret-down\"\n          width=\"1em\"\n          height=\"1em\"\n          aria-hidden=\"true\"\n        >\n          <rect fill={hexColor} x={600 / 2} y={600 / 2} width={1024 - 600} height={1024 - 600} />\n        </svg>\n      </i>\n    );\n  }\n  return (\n    <i\n      className=\"anticon anticon-caret-down rc-tree-switcher-icon\"\n    >\n      <svg\n        viewBox=\"0 0 1024 1024\"\n        focusable=\"false\"\n        data-icon=\"caret-down\"\n        width=\"1em\"\n        height=\"1em\"\n        aria-hidden=\"true\"\n      >\n        <path\n          fill={(isOpen ? '#444' : hexColor)}\n          d=\"M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z\"\n        />\n      </svg>\n    </i>\n  );\n}\n\n/**\n * A custom TreeNode component.\n * @extends {RcTreeNode} TreeNode from the rc-tree library.\n */\nexport default class TreeNode extends RcTreeNode {\n  /**\n   * Override the main node text elements.\n   */\n  renderSelector = () => {\n    const {\n      title,\n      isCurrentSet,\n      isSelected,\n      isEditing,\n      onDragStart: onDragStartProp,\n    } = this.props;\n    const {\n      rcTree: {\n        prefixCls: prefixClass,\n        draggable,\n      },\n    } = this.context;\n\n    const onDragStart = (e) => {\n      onDragStartProp();\n      this.onDragStart(e);\n    };\n\n    const wrapClass = `${prefixClass}-node-content-wrapper`;\n    const isDraggable = (!isCurrentSet && !isEditing && draggable);\n    return (\n      <span\n        ref={this.setSelectHandle}\n        title={title}\n        className={classNames(\n          wrapClass,\n          `${wrapClass}-${this.getNodeState() || 'normal'}`,\n          isSelected && `${prefixClass}-node-selected`,\n          isDraggable && 'draggable',\n        )}\n        draggable={isDraggable}\n        aria-grabbed={isDraggable}\n        onDragStart={isDraggable ? onDragStart : undefined}\n      >\n        <NamedSetNode\n          {...this.props}\n          prefixClass={prefixClass}\n          checkbox={this.renderCheckbox()}\n        />\n        {this.renderLevels()}\n      </span>\n    );\n  };\n\n  /**\n   * Render the LevelsButtons component if this node\n   * is a collapsed level zero node.\n   */\n  renderLevels = () => {\n    const { level, expanded } = this.props;\n    if (level !== 0 || expanded) {\n      return null;\n    }\n    return (\n      <LevelsButtons\n        {...this.props}\n      />\n    );\n  }\n\n  /**\n   * Override the switcher element.\n   */\n  renderSwitcher = () => {\n    const { expanded, isLeaf, color } = this.props;\n    const {\n      rcTree: {\n        prefixCls: prefixClass,\n        onNodeExpand,\n      },\n    } = this.context;\n\n    const onNodeExpandWrapper = (e) => {\n      // Do not call onNodeExpand if the node is a leaf node.\n      if (!isLeaf) {\n        onNodeExpand(e, this);\n      }\n    };\n\n    const switcherClass = classNames(\n      `${prefixClass}-switcher`,\n      { [`${prefixClass}-switcher_${(expanded ? 'open' : 'close')}`]: !isLeaf },\n    );\n    return (\n      <span\n        className={switcherClass}\n        onClick={onNodeExpandWrapper}\n        onKeyPress={e => callbackOnKeyPress(e, 'd', onNodeExpandWrapper)}\n        role=\"button\"\n        tabIndex=\"0\"\n      >\n        <SwitcherIcon\n          isLeaf={isLeaf}\n          isOpen={expanded}\n          color={color}\n        />\n      </span>\n    );\n  };\n\n  /**\n   * Override main render function,\n   * to enable overriding the sub-render functions\n   * for switcher, selector, etc.\n   */\n  render() {\n    const {\n      style, loading, level,\n      dragOver, dragOverGapTop, dragOverGapBottom,\n      isLeaf,\n      expanded, selected, checked, halfChecked,\n      onDragEnd: onDragEndProp,\n      expandable,\n      ...otherProps\n    } = this.props;\n    const {\n      rcTree: {\n        prefixCls: prefixClass,\n        filterTreeNode,\n        draggable,\n      },\n    } = this.context;\n    const disabled = this.isDisabled();\n    const dataAndAriaAttributeProps = getDataAndAria(otherProps);\n\n    const onDragEnd = (e) => {\n      onDragEndProp();\n      this.onDragEnd(e);\n    };\n\n    return (\n      <li\n        className={classNames('rc-tree-treenode', `level-${level}-treenode`, {\n          [`${prefixClass}-treenode-disabled`]: disabled,\n          [`${prefixClass}-treenode-switcher-${expanded ? 'open' : 'close'}`]: !isLeaf,\n          [`${prefixClass}-treenode-checkbox-checked`]: checked,\n          [`${prefixClass}-treenode-checkbox-indeterminate`]: halfChecked,\n          [`${prefixClass}-treenode-selected`]: selected,\n          [`${prefixClass}-treenode-loading`]: loading,\n\n          'drag-over': !disabled && dragOver,\n          'drag-over-gap-top': !disabled && dragOverGapTop,\n          'drag-over-gap-bottom': !disabled && dragOverGapBottom,\n          'filter-node': filterTreeNode && filterTreeNode(this),\n        })}\n        style={style}\n        role=\"treeitem\"\n        onDragEnter={draggable ? this.onDragEnter : undefined}\n        onDragOver={draggable ? this.onDragOver : undefined}\n        onDragLeave={draggable ? this.onDragLeave : undefined}\n        onDrop={draggable ? this.onDrop.bind(this) : undefined}\n        onDragEnd={draggable ? onDragEnd : undefined}\n        {...dataAndAriaAttributeProps}\n      >\n        {expandable ? this.renderSwitcher() : null}\n        {this.renderSelector()}\n        {this.renderChildren()}\n      </li>\n    );\n  }\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nfunction SvgUnion(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    viewBox: \"0 0 16.433999 10.234\",\n    height: 12,\n    width: 18,\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, /*#__PURE__*/React.createElement(\"g\", {\n    transform: \"translate(0.117,-2.883)\"\n  }, /*#__PURE__*/React.createElement(\"path\", {\n    d: \"m 11.467471,11.811278 c 0.198237,-0.322177 0.508,-1.011333 0.653661,-1.454255 0.659343,-2.0049141 0.44323,-4.2620847 -0.577734,-6.0340822 l -0.168844,-0.2930481 0.105744,0.017887 c 0.759902,0.1285441 1.368762,0.3699553 1.856675,0.7361658 1.988296,1.4923476 2.192477,4.3353549 0.434717,6.0529895 -0.641216,0.626581 -1.299647,0.94683 -2.294136,1.115833 l -0.108488,0.01844 z M 4.3162122,11.919169 C 1.9278944,11.487872 0.46692382,9.0323123 1.234873,6.7401372 1.5621727,5.763213 2.2610593,4.9489746 3.1840041,4.4693005 3.5978035,4.2542401 3.9427842,4.145371 4.5197023,4.0477802 L 4.6254464,4.0298927 4.4571836,4.3223069 C 3.4332707,6.1017061 3.2180432,8.3476022 3.878868,10.357023 c 0.1458466,0.443487 0.4554716,1.132155 0.6542959,1.455285 0.054471,0.08853 0.087814,0.159599 0.074096,0.157937 -0.013718,-0.0017 -0.1446898,-0.02465 -0.2910477,-0.05108 z M 5.0000001,3 C 2.2,3 0,5.2 0,8 c 0,2.8 2.2,5 5.0000001,5 0.6,0 1.1,-0.1 1.6,-0.3 C 5.3000001,11.6 4.5,9.7999998 4.5,8 4.5,6.2 5.3000001,4.5 6.6000001,3.3 c -0.5,-0.2 -1,-0.3 -1.6,-0.3 z M 4.65,4.02 C 3.92,5.17 3.51,6.54 3.51,8 c 0,1.4599998 0.42,2.83 1.14,3.98 C 2.61,11.8 1.01,10.08 1.01,8 1.01,5.92 2.61,4.2 4.65,4.02 Z M 8,4 C 6.8,4.9 6,6.4 6,8 6,9.6 6.8,11.1 8,12 9.2,11.1 10,9.7 10,8 10,6.3 9.2,4.9 8,4 Z m 3,-1 c 2.8,0 5,2.2 5,5 0,2.8 -2.2,5 -5,5 C 10.4,13 9.9,12.9 9.4,12.7 10.7,11.6 11.5,9.8 11.5,8 11.5,6.2 10.7,4.5 9.4,3.3 9.9,3.1 10.4,3 11,3 Z m 0.35,1.02 c 0.73,1.15 1.14,2.52 1.14,3.98 0,1.46 -0.42,2.83 -1.14,3.98 2.04,-0.18 3.64,-1.9 3.64,-3.98 0,-2.08 -1.6,-3.8 -3.64,-3.98 z\",\n    style: {\n      strokeWidth: 0.234,\n      strokeMiterlimit: 4,\n      strokeDasharray: \"none\",\n      strokeOpacity: 1\n    }\n  })));\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgUnion, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/union.de5168c6.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nfunction SvgIntersection(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    width: 18,\n    height: 12,\n    viewBox: \"0 0 16 10\",\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, /*#__PURE__*/React.createElement(\"g\", {\n    transform: \"translate(0,-3)\"\n  }, /*#__PURE__*/React.createElement(\"path\", {\n    d: \"M 5.0000001,3 C 2.2,3 0,5.2 0,8 c 0,2.8 2.2,5 5.0000001,5 0.6,0 1.1,-0.1 1.6,-0.3 C 5.3000001,11.6 4.5,9.7999998 4.5,8 4.5,6.2 5.3000001,4.5 6.6000001,3.3 c -0.5,-0.2 -1,-0.3 -1.6,-0.3 z M 4.65,4.02 C 3.92,5.17 3.51,6.54 3.51,8 c 0,1.4599998 0.42,2.83 1.14,3.98 C 2.61,11.8 1.01,10.08 1.01,8 1.01,5.92 2.61,4.2 4.65,4.02 Z M 8,4 C 6.8,4.9 6,6.4 6,8 6,9.6 6.8,11.1 8,12 9.2,11.1 10,9.7 10,8 10,6.3 9.2,4.9 8,4 Z m 3,-1 c 2.8,0 5,2.2 5,5 0,2.8 -2.2,5 -5,5 C 10.4,13 9.9,12.9 9.4,12.7 10.7,11.6 11.5,9.8 11.5,8 11.5,6.2 10.7,4.5 9.4,3.3 9.9,3.1 10.4,3 11,3 Z m 0.35,1.02 c 0.73,1.15 1.14,2.52 1.14,3.98 0,1.46 -0.42,2.83 -1.14,3.98 2.04,-0.18 3.64,-1.9 3.64,-3.98 0,-2.08 -1.6,-3.8 -3.64,-3.98 z\",\n    style: {\n      strokeWidth: 0.234,\n      strokeMiterlimit: 4,\n      strokeDasharray: \"none\",\n      strokeOpacity: 1\n    }\n  })));\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgIntersection, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/intersection.b0003109.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"rect\", {\n  x: \"5%\",\n  width: \"90%\",\n  height: \"100%\",\n  fill: \"white\"\n});\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"g\", null, /*#__PURE__*/React.createElement(\"rect\", {\n  x: 0,\n  y: 0,\n  width: 25.3804963846,\n  height: 16,\n  mask: \"url(#union-mask)\"\n}));\n\nfunction SvgComplement(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    id: \"svg14\",\n    viewBox: \"0 0 25.3804963846 16\",\n    height: 16,\n    width: 25.3804963846,\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, /*#__PURE__*/React.createElement(\"defs\", null, /*#__PURE__*/React.createElement(\"mask\", {\n    id: \"union-mask\",\n    x: 0,\n    y: 0,\n    width: 25.3804963846,\n    height: 16\n  }, _ref2, /*#__PURE__*/React.createElement(\"g\", {\n    transform: \"translate(4.69,0)\"\n  }, /*#__PURE__*/React.createElement(\"path\", {\n    d: \"m 11.467471,11.811278 c 0.198237,-0.322177 0.508,-1.011333 0.653661,-1.454255 0.659343,-2.0049141 0.44323,-4.2620847 -0.577734,-6.0340822 l -0.168844,-0.2930481 0.105744,0.017887 c 0.759902,0.1285441 1.368762,0.3699553 1.856675,0.7361658 1.988296,1.4923476 2.192477,4.3353549 0.434717,6.0529895 -0.641216,0.626581 -1.299647,0.94683 -2.294136,1.115833 l -0.108488,0.01844 z M 4.3162122,11.919169 C 1.9278944,11.487872 0.46692382,9.0323123 1.234873,6.7401372 1.5621727,5.763213 2.2610593,4.9489746 3.1840041,4.4693005 3.5978035,4.2542401 3.9427842,4.145371 4.5197023,4.0477802 L 4.6254464,4.0298927 4.4571836,4.3223069 C 3.4332707,6.1017061 3.2180432,8.3476022 3.878868,10.357023 c 0.1458466,0.443487 0.4554716,1.132155 0.6542959,1.455285 0.054471,0.08853 0.087814,0.159599 0.074096,0.157937 -0.013718,-0.0017 -0.1446898,-0.02465 -0.2910477,-0.05108 z M 5.0000001,3 C 2.2,3 0,5.2 0,8 c 0,2.8 2.2,5 5.0000001,5 0.6,0 1.1,-0.1 1.6,-0.3 C 5.3000001,11.6 4.5,9.7999998 4.5,8 4.5,6.2 5.3000001,4.5 6.6000001,3.3 c -0.5,-0.2 -1,-0.3 -1.6,-0.3 z M 4.65,4.02 C 3.92,5.17 3.51,6.54 3.51,8 c 0,1.4599998 0.42,2.83 1.14,3.98 C 2.61,11.8 1.01,10.08 1.01,8 1.01,5.92 2.61,4.2 4.65,4.02 Z M 8,4 C 6.8,4.9 6,6.4 6,8 6,9.6 6.8,11.1 8,12 9.2,11.1 10,9.7 10,8 10,6.3 9.2,4.9 8,4 Z m 3,-1 c 2.8,0 5,2.2 5,5 0,2.8 -2.2,5 -5,5 C 10.4,13 9.9,12.9 9.4,12.7 10.7,11.6 11.5,9.8 11.5,8 11.5,6.2 10.7,4.5 9.4,3.3 9.9,3.1 10.4,3 11,3 Z m 0.35,1.02 c 0.73,1.15 1.14,2.52 1.14,3.98 0,1.46 -0.42,2.83 -1.14,3.98 2.04,-0.18 3.64,-1.9 3.64,-3.98 0,-2.08 -1.6,-3.8 -3.64,-3.98 z\",\n    style: {\n      strokeWidth: 0.234,\n      strokeMiterlimit: 4,\n      strokeDasharray: \"none\",\n      strokeOpacity: 1\n    },\n    fill: \"black\"\n  })))), _ref3);\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgComplement, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/complement.c220ca8c.svg\";\nexport { ForwardRef as ReactComponent };","import React, { useCallback } from 'react';\nimport PopoverMenu from './PopoverMenu';\nimport {\n  handleImportJSON,\n  handleImportTabular,\n} from './io';\nimport {\n  MIME_TYPE_JSON,\n  MIME_TYPE_TABULAR,\n} from './constants';\n\nimport { ReactComponent as SetUnionSVG } from '../../assets/sets/union.svg';\nimport { ReactComponent as SetIntersectionSVG } from '../../assets/sets/intersection.svg';\nimport { ReactComponent as SetComplementSVG } from '../../assets/sets/complement.svg';\n\n/**\n * A plus button for creating or importing set hierarchies.\n * @param {object} props\n * @param {string} props.datatype The data type to validate imported hierarchies against.\n * @param {function} props.onError A callback to pass error message strings.\n * @param {function} props.onImportTree A callback to pass successfully-validated tree objects.\n * @param {function} props.onCreateLevelZeroNode A callback to create a new empty\n * level zero node.\n * @param {boolean} props.importable Is importing allowed?\n * If not, the import button will not be rendered.\n * @param {boolean} props.editable Is editing allowed?\n * If not, the create button will not be rendered.\n */\nexport function PlusButton(props) {\n  const {\n    datatype, onError, onImportTree, onCreateLevelZeroNode,\n    importable, editable,\n  } = props;\n\n  /**\n   * Import a file, then process the imported data via the supplied handler function.\n   * @param {Function} importHandler The function to process the imported data.\n   * @param {string} mimeType The accepted mime type for the file upload input.\n   * @returns {Function} An import function corresponding to the supplied parameters.\n   */\n  const onImport = useCallback((importHandler, mimeType) => () => {\n    const uploadInputNode = document.createElement('input');\n    uploadInputNode.setAttribute('type', 'file');\n    uploadInputNode.setAttribute('accept', mimeType);\n    document.body.appendChild(uploadInputNode); // required for firefox\n    uploadInputNode.click();\n    uploadInputNode.addEventListener('change', (event) => {\n      if (!(window.File && window.FileReader && window.FileList && window.Blob)) {\n        onError('Local file reading APIs are not fully supported in this browser.');\n        return;\n      }\n      const { files } = event.target;\n      if (!files || files.length !== 1) {\n        onError('Incorrect number of files selected.');\n        return;\n      }\n      const reader = new FileReader();\n      reader.addEventListener('load', () => {\n        const { result } = reader;\n        try {\n          const treeToImport = importHandler(result, datatype);\n          onError(false); // Clear any previous import error.\n          onImportTree(treeToImport);\n        } catch (e) {\n          onError(e.message);\n        }\n      }, false);\n      reader.readAsText(files[0]);\n    });\n    uploadInputNode.remove();\n  }, [datatype, onError, onImportTree]);\n\n  const menuConfig = [\n    ...(editable ? [\n      {\n        title: 'Create hierarchy',\n        handler: onCreateLevelZeroNode,\n        handlerKey: 'n',\n      },\n    ] : []),\n    ...(importable ? [\n      {\n        title: 'Import hierarchy',\n        subtitle: '(from CSV file)',\n        handler: onImport(handleImportTabular, MIME_TYPE_TABULAR),\n        handlerKey: 'c',\n      },\n      {\n        title: 'Import hierarchy',\n        subtitle: '(from JSON file)',\n        handler: onImport(handleImportJSON, MIME_TYPE_JSON),\n        handlerKey: 'j',\n      },\n    ] : []),\n  ];\n\n  return (menuConfig.length > 0 ? (\n    <PopoverMenu\n      menuConfig={menuConfig}\n    >\n      <button className=\"plus-button\" type=\"submit\">+</button>\n    </PopoverMenu>\n  ) : null);\n}\n\n/**\n * Set operations buttons (union, intersection, complement)\n * and a view checked sets button.\n * @param {object} props\n * @param {function} props.onUnion A callback for the union button.\n * @param {function} props.onIntersection A callback for the intersection button.\n * @param {function} props.onComplement A callback for the complement button.\n * @param {boolean} props.operatable Are set operations allowed?\n * If not, the union, intersection, and complement buttons will not be rendered.\n */\nexport function SetOperationButtons(props) {\n  const {\n    onUnion,\n    onIntersection,\n    onComplement,\n    operatable,\n    hasCheckedSetsToUnion,\n    hasCheckedSetsToIntersect,\n    hasCheckedSetsToComplement,\n  } = props;\n\n  return (\n    <>\n      {operatable && (\n        <>\n          <button\n            onClick={onUnion}\n            title=\"New set from union of checked sets\"\n            type=\"submit\"\n            disabled={!hasCheckedSetsToUnion}\n          >\n            <SetUnionSVG />\n          </button>\n          <button\n            onClick={onIntersection}\n            title=\"New set from intersection of checked sets\"\n            type=\"submit\"\n            disabled={!hasCheckedSetsToIntersect}\n          >\n            <SetIntersectionSVG />\n          </button>\n          <button\n            onClick={onComplement}\n            title=\"New set from complement of checked sets\"\n            type=\"submit\"\n            disabled={!hasCheckedSetsToComplement}\n          >\n            <SetComplementSVG />\n          </button>\n        </>\n      )}\n    </>\n  );\n}\n","/* eslint-disable no-underscore-dangle */\nimport React, { useState, useMemo } from 'react';\nimport isEqual from 'lodash/isEqual';\nimport Tree from './Tree';\nimport TreeNode from './TreeNode';\nimport { PlusButton, SetOperationButtons } from './SetsManagerButtons';\nimport { nodeToRenderProps } from './cell-set-utils';\nimport { getDefaultColor } from '../utils';\nimport { pathToKey } from './utils';\n\nfunction processNode(node, prevPath, setColor, theme) {\n  const nodePath = [...prevPath, node.name];\n  return {\n    ...node,\n    ...(node.children ? ({\n      children: node.children\n        .map(c => processNode(c, nodePath, setColor)),\n    }) : {}),\n    color: setColor?.find(d => isEqual(d.path, nodePath))?.color || getDefaultColor(theme),\n  };\n}\n\nfunction processSets(sets, setColor, theme) {\n  return {\n    ...sets,\n    tree: sets ? sets.tree.map(lzn => processNode(lzn, [], setColor, theme)) : [],\n  };\n}\n\nfunction getAllKeys(node, path = []) {\n  if (!node) {\n    return null;\n  }\n  const newPath = [...path, node.name];\n  if (node.children) {\n    return [pathToKey(newPath), ...node.children.flatMap(v => getAllKeys(v, newPath))];\n  }\n  return pathToKey(newPath);\n}\n\n/**\n * A generic hierarchical set manager component.\n * @prop {object} tree An object representing set hierarchies.\n * @prop {string} datatype The data type for sets (e.g. \"cell\")\n * @prop {function} clearPleaseWait A callback to signal that loading is complete.\n * @prop {boolean} draggable Whether tree nodes can be rearranged via drag-and-drop.\n * By default, true.\n * @prop {boolean} checkable Whether to show the \"Check\" menu button\n * and checkboxes for selecting multiple sets. By default, true.\n * @prop {boolean} editable Whether to show rename, delete, color, or create options.\n * By default, true.\n * @prop {boolean} expandable Whether to allow hierarchies to be expanded\n * to show the list or tree of sets contained. By default, true.\n * @prop {boolean} operatable Whether to enable union, intersection,\n * and complement operations on checked sets. By default, true.\n * @prop {boolean} exportable Whether to enable exporting hierarchies and sets to files.\n * By default, true.\n * @prop {boolean} importable Whether to enable importing hierarchies from files.\n * By default, true.\n * @prop {function} onError Function to call with error messages (failed import validation, etc).\n * @prop {function} onCheckNode Function to call when a single node has been checked or un-checked.\n * @prop {function} onExpandNode Function to call when a node has been expanded.\n * @prop {function} onDropNode Function to call when a node has been dragged-and-dropped.\n * @prop {function} onCheckLevel Function to call when an entire hierarchy level has been selected,\n * via the \"Color by cluster\" and \"Color by subcluster\" buttons below collapsed level zero nodes.\n * @prop {function} onNodeSetColor Function to call when a new node color has been selected.\n * @prop {function} onNodeSetName Function to call when a node has been renamed.\n * @prop {function} onNodeRemove Function to call when the user clicks the \"Delete\" menu button\n * to remove a node.\n * @prop {function} onNodeView Function to call when the user wants to view the set associated\n * with a particular node.\n * @prop {function} onImportTree Function to call when a tree has been imported\n * using the \"plus\" button.\n * @prop {function} onCreateLevelZeroNode Function to call when a user clicks the \"Create hierarchy\"\n * menu option using the \"plus\" button.\n * @prop {function} onExportLevelZeroNode Function to call when a user wants to\n * export an entire hierarchy via the \"Export hierarchy\" menu button for a\n * particular level zero node.\n * @prop {function} onExportSet Function to call when a user wants to export a set associated with\n * a particular node via the \"Export set\" menu button.\n * @prop {function} onUnion Function to call when a user wants to create a new set from the union\n * of the sets associated with the currently-checked nodes.\n * @prop {function} onIntersection Function to call when a user wants to create a new set from the\n * intersection of the sets associated with the currently-checked nodes.\n * @prop {function} onComplement Function to call when a user wants to create a new set from the\n * complement of the (union of the) sets associated with the currently-checked nodes.\n * @prop {function} onView Function to call when a user wants to view the sets\n * associated with the currently-checked nodes.\n * @prop {string} theme \"light\" or \"dark\" for the vitessce theme\n */\nexport default function SetsManager(props) {\n  const {\n    theme,\n    sets,\n    additionalSets,\n    setColor, // TODO: use this\n    levelSelection: checkedLevel,\n    setSelection,\n    setExpansion,\n    hasColorEncoding,\n    datatype,\n    draggable = true,\n    checkable = true,\n    editable = true,\n    expandable = true,\n    operatable = true,\n    exportable = true,\n    importable = true,\n    onError,\n    onCheckNode,\n    onExpandNode,\n    onDropNode,\n    onCheckLevel,\n    onNodeSetColor,\n    onNodeSetName,\n    onNodeCheckNewName,\n    onNodeRemove,\n    onNodeView,\n    onImportTree,\n    onCreateLevelZeroNode,\n    onExportLevelZeroNodeJSON,\n    onExportLevelZeroNodeTabular,\n    onExportSetJSON,\n    onUnion,\n    onIntersection,\n    onComplement,\n    hasCheckedSetsToUnion,\n    hasCheckedSetsToIntersect,\n    hasCheckedSetsToComplement,\n  } = props;\n\n  const isChecking = true;\n  const autoExpandParent = true;\n  const [isDragging, setIsDragging] = useState(false);\n  const [isEditingNodeName, setIsEditingNodeName] = useState(null);\n\n  const processedSets = useMemo(() => processSets(\n    sets, setColor, theme,\n  ), [sets, setColor, theme]);\n  const processedAdditionalSets = useMemo(() => processSets(\n    additionalSets, setColor, theme,\n  ), [additionalSets, setColor, theme]);\n\n  const additionalSetKeys = (processedAdditionalSets\n    ? processedAdditionalSets.tree.flatMap(v => getAllKeys(v, []))\n    : []\n  );\n\n  const allSetSelectionKeys = (setSelection || []).map(pathToKey);\n  const allSetExpansionKeys = (setExpansion || []).map(pathToKey);\n\n  const setSelectionKeys = allSetSelectionKeys.filter(k => !additionalSetKeys.includes(k));\n  const setExpansionKeys = allSetExpansionKeys.filter(k => !additionalSetKeys.includes(k));\n\n  const additionalSetSelectionKeys = allSetSelectionKeys.filter(k => additionalSetKeys.includes(k));\n  const additionalSetExpansionKeys = allSetExpansionKeys.filter(k => additionalSetKeys.includes(k));\n\n  /**\n   * Recursively render TreeNode components.\n   * @param {object[]} nodes An array of node objects.\n   * @returns {TreeNode[]|null} Array of TreeNode components or null.\n   */\n  function renderTreeNodes(nodes, readOnly, currPath) {\n    if (!nodes) {\n      return null;\n    }\n    return nodes.map((node) => {\n      const newPath = [...currPath, node.name];\n      return (\n        <TreeNode\n          theme={theme}\n          key={pathToKey(newPath)}\n          {...nodeToRenderProps(node, newPath, setColor)}\n\n          isEditing={isEqual(isEditingNodeName, newPath)}\n\n          datatype={datatype}\n          draggable={draggable && !readOnly}\n          editable={editable && !readOnly}\n          checkable={checkable}\n          expandable={expandable}\n          exportable={exportable}\n\n          hasColorEncoding={hasColorEncoding}\n          isChecking={isChecking}\n          checkedLevelPath={checkedLevel ? checkedLevel.levelZeroPath : null}\n          checkedLevelIndex={checkedLevel ? checkedLevel.levelIndex : null}\n\n          onCheckNode={onCheckNode}\n          onCheckLevel={onCheckLevel}\n          onNodeView={onNodeView}\n          onNodeSetColor={onNodeSetColor}\n          onNodeSetName={(targetPath, name) => {\n            onNodeSetName(targetPath, name);\n            setIsEditingNodeName(null);\n          }}\n          onNodeCheckNewName={onNodeCheckNewName}\n          onNodeSetIsEditing={setIsEditingNodeName}\n          onNodeRemove={onNodeRemove}\n          onExportLevelZeroNodeJSON={onExportLevelZeroNodeJSON}\n          onExportLevelZeroNodeTabular={onExportLevelZeroNodeTabular}\n          onExportSetJSON={onExportSetJSON}\n\n          disableTooltip={isDragging}\n          onDragStart={() => setIsDragging(true)}\n          onDragEnd={() => setIsDragging(false)}\n        >\n          {renderTreeNodes(node.children, readOnly, newPath, theme)}\n        </TreeNode>\n      );\n    });\n  }\n\n  return (\n    <div className=\"sets-manager\">\n      <div className=\"sets-manager-tree\">\n        <Tree\n          draggable={false}\n          checkable={checkable}\n\n          checkedKeys={setSelectionKeys}\n          expandedKeys={setExpansionKeys}\n          autoExpandParent={autoExpandParent}\n\n          onCheck={(checkedKeys, info) => onCheckNode(\n            info.node.props.nodeKey,\n            info.checked,\n          )}\n          onExpand={(expandedKeys, info) => onExpandNode(\n            expandedKeys,\n            info.node.props.nodeKey,\n            info.expanded,\n          )}\n        >\n          {renderTreeNodes(processedSets.tree, true, [], theme)}\n        </Tree>\n        <Tree\n          draggable /* TODO */\n          checkable={checkable}\n\n          checkedKeys={additionalSetSelectionKeys}\n          expandedKeys={additionalSetExpansionKeys}\n          autoExpandParent={autoExpandParent}\n\n          onCheck={(checkedKeys, info) => onCheckNode(\n            info.node.props.nodeKey,\n            info.checked,\n          )}\n          onExpand={(expandedKeys, info) => onExpandNode(\n            expandedKeys,\n            info.node.props.nodeKey,\n            info.expanded,\n          )}\n          onDrop={(info) => {\n            const { eventKey: dropKey } = info.node.props;\n            const { eventKey: dragKey } = info.dragNode.props;\n            const { dropToGap, dropPosition } = info;\n            onDropNode(dropKey, dragKey, dropPosition, dropToGap);\n          }}\n        >\n          {renderTreeNodes(processedAdditionalSets.tree, false, [], theme)}\n        </Tree>\n\n        <PlusButton\n          datatype={datatype}\n          onError={onError}\n          onImportTree={onImportTree}\n          onCreateLevelZeroNode={onCreateLevelZeroNode}\n          importable={importable}\n          editable={editable}\n        />\n      </div>\n      {isChecking ? (\n        <div className=\"set-operation-buttons\">\n          <SetOperationButtons\n            onUnion={onUnion}\n            onIntersection={onIntersection}\n            onComplement={onComplement}\n            operatable={operatable}\n\n            hasCheckedSetsToUnion={hasCheckedSetsToUnion}\n            hasCheckedSetsToIntersect={hasCheckedSetsToIntersect}\n            hasCheckedSetsToComplement={hasCheckedSetsToComplement}\n          />\n        </div>\n      ) : null}\n    </div>\n  );\n}\n","import React, {\n  useEffect,\n  useState,\n  useMemo,\n} from 'react';\nimport isEqual from 'lodash/isEqual';\nimport packageJson from '../../../package.json';\nimport {\n  useCoordination,\n  useLoaders,\n  useSetWarning,\n} from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport SetsManager from './SetsManager';\nimport TitleInfo from '../TitleInfo';\nimport {\n  treeExportLevelZeroNode,\n  treeExportSet,\n  treeToExpectedCheckedLevel,\n  nodeToLevelDescendantNamePaths,\n  treeToIntersection,\n  treeToUnion,\n  treeToComplement,\n  treeFindNodeByNamePath,\n  treesConflict,\n  nodeTransform,\n  nodeAppendChild,\n  nodePrependChild,\n  nodeInsertChild,\n  filterNode,\n  treeInitialize,\n  initializeCellSetColor,\n} from './cell-set-utils';\nimport {\n  isEqualOrPrefix,\n  tryRenamePath,\n  PATH_SEP,\n} from './utils';\nimport {\n  downloadForUser,\n  handleExportJSON,\n  handleExportTabular,\n  tryUpgradeTreeToLatestSchema,\n} from './io';\nimport {\n  FILE_EXTENSION_JSON,\n  FILE_EXTENSION_TABULAR,\n  SETS_DATATYPE_CELL,\n} from './constants';\nimport { useUrls, useReady } from '../hooks';\nimport {\n  setCellSelection,\n  mergeCellSets,\n  getNextNumberedNodeName,\n} from '../utils';\nimport { useCellsData, useCellSetsData } from '../data-hooks';\n\nconst CELL_SETS_DATA_TYPES = ['cells', 'cell-sets'];\n\n/**\n * A subscriber wrapper around the SetsManager component\n * for the 'cell' datatype.\n * @param {object} props\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n */\nexport default function CellSetsManagerSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n    title = 'Cell Sets',\n  } = props;\n\n  const loaders = useLoaders();\n  const setWarning = useSetWarning();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    cellSetSelection,\n    cellSetColor,\n    additionalCellSets,\n    cellColorEncoding,\n  }, {\n    setCellSetSelection,\n    setCellColorEncoding,\n    setCellSetColor,\n    setAdditionalCellSets,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.cellSets, coordinationScopes);\n\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    CELL_SETS_DATA_TYPES,\n  );\n\n  const [cellSetExpansion, setCellSetExpansion] = useState([]);\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n    setCellSetExpansion([]);\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [cells] = useCellsData(loaders, dataset, setItemIsReady, addUrl, true);\n  const [cellSets] = useCellSetsData(\n    loaders, dataset, setItemIsReady, addUrl, true,\n    { setCellSetSelection, setCellSetColor },\n    { cellSetSelection, cellSetColor },\n  );\n\n  // Validate and upgrade the additionalCellSets.\n  useEffect(() => {\n    if (additionalCellSets) {\n      let upgradedCellSets;\n      try {\n        upgradedCellSets = tryUpgradeTreeToLatestSchema(additionalCellSets, SETS_DATATYPE_CELL);\n      } catch (e) {\n        setWarning(e.message);\n        return;\n      }\n      setAdditionalCellSets(upgradedCellSets);\n    }\n  }, [additionalCellSets, setAdditionalCellSets, setWarning]);\n\n  // Get an array of all cell IDs to use for set complement operations.\n  const allCellIds = useMemo(() => (cells ? Object.keys(cells) : []), [cells]);\n\n  // A helper function for updating the encoding for cell colors,\n  // which may have previously been set to 'geneSelection'.\n  function setCellSetColorEncoding() {\n    setCellColorEncoding('cellSetSelection');\n  }\n\n  // Merged cell sets are only to be used for convenience when reading\n  // (if writing: update either `cellSets` _or_ `additionalCellSets`).\n  const mergedCellSets = useMemo(\n    () => mergeCellSets(cellSets, additionalCellSets),\n    [cellSets, additionalCellSets],\n  );\n\n  // Infer the state of the \"checked level\" radio button based on the selected cell sets.\n  const checkedLevel = useMemo(() => {\n    if (cellSetSelection && cellSetSelection.length > 0\n    && mergedCellSets && mergedCellSets.tree.length > 0) {\n      return treeToExpectedCheckedLevel(mergedCellSets, cellSetSelection);\n    }\n    return null;\n  }, [cellSetSelection, mergedCellSets]);\n\n  // Callback functions\n\n  // The user wants to select all nodes at a particular hierarchy level.\n  function onCheckLevel(levelZeroName, levelIndex) {\n    const lzn = mergedCellSets.tree.find(n => n.name === levelZeroName);\n    if (lzn) {\n      const newCellSetSelection = nodeToLevelDescendantNamePaths(lzn, levelIndex, [], true);\n      setCellSetSelection(newCellSetSelection);\n      setCellSetColorEncoding();\n    }\n  }\n\n  // The user wants to check or uncheck a cell set node.\n  function onCheckNode(targetKey, checked) {\n    const targetPath = (Array.isArray(targetKey) ? targetKey : targetKey.split(PATH_SEP));\n    if (!targetKey) {\n      return;\n    }\n    if (checked) {\n      setCellSetSelection([...cellSetSelection, targetPath]);\n    } else {\n      setCellSetSelection(cellSetSelection.filter(d => !isEqual(d, targetPath)));\n    }\n    setCellSetColorEncoding();\n  }\n\n  // The user wants to expand or collapse a node in the tree.\n  function onExpandNode(expandedKeys, targetKey, expanded) {\n    if (expanded) {\n      setCellSetExpansion(prev => ([...prev, targetKey.split(PATH_SEP)]));\n    } else {\n      setCellSetExpansion(prev => prev.filter(d => !isEqual(d, targetKey.split(PATH_SEP))));\n    }\n  }\n\n  // The user dragged a tree node and dropped it somewhere else in the tree\n  // to re-arrange or re-order the nodes.\n  // We need to verify that their drop target is valid, and if so, complete\n  // the tree re-arrangement.\n  function onDropNode(dropKey, dragKey, dropPosition, dropToGap) {\n    const dropPath = dropKey.split(PATH_SEP);\n    const dropNode = treeFindNodeByNamePath(additionalCellSets, dropPath);\n    if (!dropNode.children && !dropToGap) {\n      // Do not allow a node with a set (i.e. leaf) to become a child of another node with a set,\n      // as this will result in an internal node having a set, which we do not allow.\n      return;\n    }\n    const dropNodeLevel = dropPath.length - 1;\n    const dropNodeIsLevelZero = dropNodeLevel === 0;\n\n    // Get drag node.\n    const dragPath = dragKey.split(PATH_SEP);\n    const dragNode = treeFindNodeByNamePath(additionalCellSets, dragPath);\n\n    if (dropNodeIsLevelZero && dropToGap && !dragNode.children) {\n      // Do not allow a leaf node to become a level zero node.\n      return;\n    }\n\n    let dropParentNode;\n    let dropParentPath;\n    let dropNodeCurrIndex;\n    if (!dropNodeIsLevelZero) {\n      dropParentPath = dropPath.slice(0, -1);\n      dropParentNode = treeFindNodeByNamePath(additionalCellSets, dropParentPath);\n      dropNodeCurrIndex = dropParentNode.children.findIndex(c => c.name === dropNode.name);\n    } else {\n      dropNodeCurrIndex = additionalCellSets.tree.findIndex(\n        lzn => lzn.name === dropNode.name,\n      );\n    }\n    // Further, only allow dragging if the dragged node will have a unique\n    // name among its new siblings.\n    let hasSiblingNameConflict;\n    const dragNodeName = dragNode.name;\n    if (!dropNodeIsLevelZero && dropToGap) {\n      hasSiblingNameConflict = dropParentNode.children\n        .find(c => c !== dragNode && c.name === dragNodeName);\n    } else if (!dropToGap) {\n      hasSiblingNameConflict = dropNode.children\n        .find(c => c !== dragNode && c.name === dragNodeName);\n    } else {\n      hasSiblingNameConflict = additionalCellSets.tree\n        .find(lzn => lzn !== dragNode && lzn.name === dragNodeName);\n    }\n\n    if (hasSiblingNameConflict) {\n      return;\n    }\n\n    // Remove the dragged object from its current position.\n    // Recursively check whether each node path\n    // matches the path of the node to delete.\n    // If so, return null, and then always use\n    // .filter(Boolean) to eliminate any null array elements.\n    const nextAdditionalCellSets = {\n      ...additionalCellSets,\n      tree: additionalCellSets.tree.map(lzn => filterNode(lzn, [], dragPath)).filter(Boolean),\n    };\n\n    // Update index values after temporarily removing the dragged node.\n    // Names are unique as children of their parents.\n    if (!dropNodeIsLevelZero) {\n      dropNodeCurrIndex = dropParentNode.children.findIndex(c => c.name === dropNode.name);\n    } else {\n      dropNodeCurrIndex = nextAdditionalCellSets.tree.findIndex(\n        lzn => lzn.name === dropNode.name,\n      );\n    }\n    let newDragPath = [];\n    if (!dropToGap || !dropNodeIsLevelZero) {\n      let addChildFunction;\n      let checkPathFunction;\n      const newPath = [];\n      if (!dropToGap) {\n        // Append the dragNode to dropNode's children if dropping _onto_ the dropNode.\n        // Set dragNode as the last child of dropNode.\n        addChildFunction = n => nodeAppendChild(n, dragNode);\n        checkPathFunction = path => isEqual(path, dropPath);\n      } else if (!dropNodeIsLevelZero) {\n        // Prepend or insert the dragNode if dropping _between_ (above or below dropNode).\n        // The dropNode is at a level greater than zero,\n        // so it has a parent.\n        checkPathFunction = path => isEqual(path, dropParentPath);\n        if (dropPosition === -1) {\n          // Set dragNode as first child of dropParentNode.\n          addChildFunction = n => nodePrependChild(n, dragNode);\n        } else {\n          // Set dragNode before or after dropNode.\n          const insertIndex = dropNodeCurrIndex + (dropPosition > dropNodeCurrIndex ? 1 : 0);\n          addChildFunction = n => nodeInsertChild(n, dragNode, insertIndex);\n        }\n      }\n      nextAdditionalCellSets.tree = nextAdditionalCellSets.tree.map(\n        node => nodeTransform(\n          node,\n          (n, path) => checkPathFunction(path),\n          (n) => {\n            const newNode = addChildFunction(n);\n            return newNode;\n          },\n          newPath,\n        ),\n      );\n      // Done\n      setAdditionalCellSets(nextAdditionalCellSets);\n      newDragPath = [...newPath[0], dragNode.name];\n      setCellSetSelection([newDragPath]);\n    } else if (dropPosition === -1) {\n      // We need to drop the dragNode to level zero,\n      // and level zero nodes do not have parents.\n      // Set dragNode as first level zero node of the tree.\n      nextAdditionalCellSets.tree.unshift(dragNode);\n      setAdditionalCellSets(nextAdditionalCellSets);\n      newDragPath = [dragNode.name];\n      setCellSetSelection([newDragPath]);\n    } else {\n      // Set dragNode before or after dropNode in level zero.\n      const insertIndex = dropNodeCurrIndex + (dropPosition > dropNodeCurrIndex ? 1 : 0);\n      const newLevelZero = Array.from(nextAdditionalCellSets.tree);\n      newLevelZero.splice(insertIndex, 0, dragNode);\n      nextAdditionalCellSets.tree = newLevelZero;\n      setAdditionalCellSets(nextAdditionalCellSets);\n      newDragPath = [dragNode.name];\n      setCellSetSelection([newDragPath]);\n    }\n    const oldColors = cellSetColor.filter(\n      i => isEqualOrPrefix(dragPath, i.path),\n    );\n    const newColors = oldColors.map(\n      i => (\n        {\n          ...i,\n          path: !isEqual(i.path, dragPath)\n            ? newDragPath.concat(i.path.slice(dragPath.length))\n            : newDragPath,\n        }\n      ),\n    );\n    const newCellSetColor = cellSetColor.filter(\n      i => !isEqualOrPrefix(dragPath, i.path),\n    );\n    newCellSetColor.push(...newColors);\n    setCellSetColor(newCellSetColor);\n  }\n\n  // The user wants to change the color of a cell set node.\n  function onNodeSetColor(targetPath, color) {\n    // Replace the color if an array element for this path already exists.\n    const prevNodeColor = cellSetColor?.find(d => isEqual(d.path, targetPath));\n    if (!prevNodeColor) {\n      setCellSetColor([\n        ...(cellSetColor || []),\n        {\n          path: targetPath,\n          color,\n        },\n      ]);\n    } else {\n      setCellSetColor([\n        ...cellSetColor.filter(d => !isEqual(d.path, targetPath)),\n        {\n          path: targetPath,\n          color,\n        },\n      ]);\n    }\n  }\n\n  // The user wants to change the name of a cell set node.\n  function onNodeSetName(targetPath, name) {\n    const nextNamePath = [...targetPath];\n    nextNamePath.pop();\n    nextNamePath.push(name);\n\n    // Recursively check whether each node path\n    // matches the path or a prefix of the path of the node to rename.\n    // If so, rename the node using the new path.\n    function renameNode(node, prevPath) {\n      if (isEqual([...prevPath, node.name], targetPath)) {\n        return {\n          ...node,\n          name,\n        };\n      }\n      if (!node.children) {\n        return node;\n      }\n      return {\n        ...node,\n        children: node.children.map(c => renameNode(c, [...prevPath, node.name])),\n      };\n    }\n    const nextAdditionalCellSets = {\n      ...additionalCellSets,\n      tree: additionalCellSets.tree.map(lzn => renameNode(lzn, [])),\n    };\n    // Change all paths that have this node as a prefix (i.e. descendants).\n    const nextCellSetColor = cellSetColor.map(d => ({\n      path: tryRenamePath(targetPath, d.path, nextNamePath),\n      color: d.color,\n    }));\n    const nextCellSetSelection = cellSetSelection.map(d => (\n      tryRenamePath(targetPath, d, nextNamePath)\n    ));\n    const nextCellSetExpansion = cellSetExpansion.map(d => (\n      tryRenamePath(targetPath, d, nextNamePath)\n    ));\n    // Need to update the node path everywhere it may be present.\n    setAdditionalCellSets(nextAdditionalCellSets);\n    setCellSetColor(nextCellSetColor);\n    setCellSetSelection(nextCellSetSelection);\n    setCellSetExpansion(nextCellSetExpansion);\n  }\n\n  // Each time the user types while renaming a cell set node,\n  // we need to check whether the potential new name conflicts\n  // with any existing cell set node names.\n  // If there are conflicts, we want to disable the \"Save\" button.\n  function onNodeCheckNewName(targetPath, name) {\n    const nextNamePath = [...targetPath];\n    nextNamePath.pop();\n    nextNamePath.push(name);\n    const hasConflicts = (\n      !isEqual(targetPath, nextNamePath)\n      && treeFindNodeByNamePath(additionalCellSets, nextNamePath)\n    );\n    return hasConflicts;\n  }\n\n  // The user wants to delete a cell set node, and has confirmed their choice.\n  function onNodeRemove(targetPath) {\n    // Recursively check whether each node path\n    // matches the path of the node to delete.\n    // If so, return null, and then always use\n    // .filter(Boolean) to eliminate any null array elements.\n    const nextAdditionalCellSets = {\n      ...additionalCellSets,\n      tree: additionalCellSets.tree.map(lzn => filterNode(lzn, [], targetPath)).filter(Boolean),\n    };\n    // Delete state for all paths that have this node\n    // path as a prefix (i.e. delete all descendents).\n    const nextCellSetColor = cellSetColor.filter(d => !isEqualOrPrefix(targetPath, d.path));\n    const nextCellSetSelection = cellSetSelection.filter(d => !isEqualOrPrefix(targetPath, d));\n    const nextCellSetExpansion = cellSetExpansion.filter(d => !isEqualOrPrefix(targetPath, d));\n    setAdditionalCellSets(nextAdditionalCellSets);\n    setCellSetColor(nextCellSetColor);\n    setCellSetSelection(nextCellSetSelection);\n    setCellSetExpansion(nextCellSetExpansion);\n  }\n\n  // The user wants to view (i.e. select) a particular node,\n  // or its expanded descendents.\n  function onNodeView(targetPath) {\n    // If parent node is clicked, and if it is expanded,\n    // then select the expanded descendent nodes.\n    const setsToView = [];\n    // Recursively determine which descendent nodes are currently expanded.\n    function viewNode(node, nodePath) {\n      if (cellSetExpansion.find(expandedPath => isEqual(nodePath, expandedPath))) {\n        if (node.children) {\n          node.children.forEach((c) => {\n            viewNode(c, [...nodePath, c.name]);\n          });\n        } else {\n          setsToView.push(nodePath);\n        }\n      } else {\n        setsToView.push(nodePath);\n      }\n    }\n    const targetNode = treeFindNodeByNamePath(mergedCellSets, targetPath);\n    viewNode(targetNode, targetPath);\n    setCellSetSelection(setsToView);\n    setCellSetColorEncoding();\n  }\n\n  // The user wants to create a new level zero node.\n  function onCreateLevelZeroNode() {\n    const nextName = getNextNumberedNodeName(additionalCellSets?.tree, 'My hierarchy ');\n    setAdditionalCellSets({\n      ...(additionalCellSets || treeInitialize(SETS_DATATYPE_CELL)),\n      tree: [\n        ...(additionalCellSets ? additionalCellSets.tree : []),\n        {\n          name: nextName,\n          children: [],\n        },\n      ],\n    });\n  }\n\n  // The user wants to create a new node corresponding to\n  // the union of the selected sets.\n  function onUnion() {\n    const newSet = treeToUnion(mergedCellSets, cellSetSelection);\n    setCellSelection(\n      newSet, additionalCellSets, cellSetColor,\n      setCellSetSelection, setAdditionalCellSets, setCellSetColor,\n      setCellColorEncoding,\n      'Union ',\n    );\n  }\n\n  // The user wants to create a new node corresponding to\n  // the intersection of the selected sets.\n  function onIntersection() {\n    const newSet = treeToIntersection(mergedCellSets, cellSetSelection);\n    setCellSelection(\n      newSet, additionalCellSets, cellSetColor,\n      setCellSetSelection, setAdditionalCellSets, setCellSetColor,\n      setCellColorEncoding,\n      'Intersection ',\n    );\n  }\n\n  // The user wants to create a new node corresponding to\n  // the complement of the selected sets.\n  function onComplement() {\n    const newSet = treeToComplement(mergedCellSets, cellSetSelection, allCellIds);\n    setCellSelection(\n      newSet, additionalCellSets, cellSetColor,\n      setCellSetSelection, setAdditionalCellSets, setCellSetColor,\n      setCellColorEncoding,\n      'Complement ',\n    );\n  }\n\n  // The user wants to import a cell set hierarchy,\n  // probably from a CSV or JSON file.\n  function onImportTree(treeToImport) {\n    // Check for any naming conflicts with the current sets\n    // (both user-defined and dataset-defined) before importing.\n    const hasConflict = treesConflict(mergedCellSets, treeToImport);\n    if (!hasConflict) {\n      setAdditionalCellSets({\n        ...(additionalCellSets || treeInitialize(SETS_DATATYPE_CELL)),\n        tree: [\n          ...(additionalCellSets ? additionalCellSets.tree : []),\n          ...treeToImport.tree,\n        ],\n      });\n      // Automatically initialize set colors for the imported sets.\n      const importAutoSetColors = initializeCellSetColor(treeToImport, cellSetColor);\n      setCellSetColor([\n        ...cellSetColor,\n        ...importAutoSetColors,\n      ]);\n    }\n  }\n\n  // The user wants to download a particular hierarchy to a JSON file.\n  function onExportLevelZeroNodeJSON(nodePath) {\n    const {\n      treeToExport, nodeName,\n    } = treeExportLevelZeroNode(mergedCellSets, nodePath, SETS_DATATYPE_CELL, cellSetColor, theme);\n    downloadForUser(\n      handleExportJSON(treeToExport),\n      `${nodeName}_${packageJson.name}-${SETS_DATATYPE_CELL}-hierarchy.${FILE_EXTENSION_JSON}`,\n    );\n  }\n\n  // The user wants to download a particular hierarchy to a CSV file.\n  function onExportLevelZeroNodeTabular(nodePath) {\n    const {\n      treeToExport, nodeName,\n    } = treeExportLevelZeroNode(mergedCellSets, nodePath, SETS_DATATYPE_CELL, cellSetColor, theme);\n    downloadForUser(\n      handleExportTabular(treeToExport),\n      `${nodeName}_${packageJson.name}-${SETS_DATATYPE_CELL}-hierarchy.${FILE_EXTENSION_TABULAR}`,\n    );\n  }\n\n  // The user wants to download a particular set to a JSON file.\n  function onExportSetJSON(nodePath) {\n    const { setToExport, nodeName } = treeExportSet(mergedCellSets, nodePath);\n    downloadForUser(\n      handleExportJSON(setToExport),\n      `${nodeName}_${packageJson.name}-${SETS_DATATYPE_CELL}-set.${FILE_EXTENSION_JSON}`,\n      FILE_EXTENSION_JSON,\n    );\n  }\n  return (\n    <TitleInfo\n      title={title}\n      isScroll\n      removeGridComponent={removeGridComponent}\n      urls={urls}\n      theme={theme}\n      isReady={isReady}\n    >\n      <SetsManager\n        setColor={cellSetColor}\n        sets={cellSets}\n        additionalSets={additionalCellSets}\n        levelSelection={checkedLevel}\n        setSelection={cellSetSelection}\n        setExpansion={cellSetExpansion}\n        hasColorEncoding={cellColorEncoding === 'cellSetSelection'}\n        draggable\n        datatype={SETS_DATATYPE_CELL}\n        onError={setWarning}\n        onCheckNode={onCheckNode}\n        onExpandNode={onExpandNode}\n        onDropNode={onDropNode}\n        onCheckLevel={onCheckLevel}\n        onNodeSetColor={onNodeSetColor}\n        onNodeSetName={onNodeSetName}\n        onNodeCheckNewName={onNodeCheckNewName}\n        onNodeRemove={onNodeRemove}\n        onNodeView={onNodeView}\n        onImportTree={onImportTree}\n        onCreateLevelZeroNode={onCreateLevelZeroNode}\n        onExportLevelZeroNodeJSON={onExportLevelZeroNodeJSON}\n        onExportLevelZeroNodeTabular={onExportLevelZeroNodeTabular}\n        onExportSetJSON={onExportSetJSON}\n        onUnion={onUnion}\n        onIntersection={onIntersection}\n        onComplement={onComplement}\n        hasCheckedSetsToUnion={cellSetSelection?.length > 1}\n        hasCheckedSetsToIntersect={cellSetSelection?.length > 1}\n        hasCheckedSetsToComplement={cellSetSelection?.length > 0}\n        theme={theme}\n      />\n    </TitleInfo>\n  );\n}\n","/* eslint-disable no-nested-ternary */\n/* eslint-disable no-param-reassign */\nimport { treeToCellColorsBySetNames } from './sets/cell-set-utils';\n\n// The functions defined here have been adapted from d3-interpolate,\n// d3-color, and d3-scale-chromatic.\n// Color string \"rgb(r,g,b)\" representations are replaced by color array [r, g, b]\n// representations, to allow them to work nicely with deck.gl,\n// without the need to converting back and forth between string and array formats.\n\n// Reference: https://github.com/d3/d3-scale-chromatic/blob/431d21da776f97c632f53a855bd822edfbbcd56e/src/diverging/RdBu.js\n// eslint-disable-next-line max-len\nconst schemeRdBu = [[103, 0, 31], [178, 24, 43], [214, 96, 77], [244, 165, 130], [253, 219, 199], [247, 247, 247], [209, 229, 240], [146, 197, 222], [67, 147, 195], [33, 102, 172], [5, 48, 97]];\n// eslint-disable-next-line max-len\nconst schemePlasma = [[13, 8, 135], [16, 7, 136], [19, 7, 137], [22, 7, 138], [25, 6, 140], [27, 6, 141], [29, 6, 142], [32, 6, 143], [34, 6, 144], [36, 6, 145], [38, 5, 145], [40, 5, 146], [42, 5, 147], [44, 5, 148], [46, 5, 149], [47, 5, 150], [49, 5, 151], [51, 5, 151], [53, 4, 152], [55, 4, 153], [56, 4, 154], [58, 4, 154], [60, 4, 155], [62, 4, 156], [63, 4, 156], [65, 4, 157], [67, 3, 158], [68, 3, 158], [70, 3, 159], [72, 3, 159], [73, 3, 160], [75, 3, 161], [76, 2, 161], [78, 2, 162], [80, 2, 162], [81, 2, 163], [83, 2, 163], [85, 2, 164], [86, 1, 164], [88, 1, 164], [89, 1, 165], [91, 1, 165], [92, 1, 166], [94, 1, 166], [96, 1, 166], [97, 0, 167], [99, 0, 167], [100, 0, 167], [102, 0, 167], [103, 0, 168], [105, 0, 168], [106, 0, 168], [108, 0, 168], [110, 0, 168], [111, 0, 168], [113, 0, 168], [114, 1, 168], [116, 1, 168], [117, 1, 168], [119, 1, 168], [120, 1, 168], [122, 2, 168], [123, 2, 168], [125, 3, 168], [126, 3, 168], [128, 4, 168], [129, 4, 167], [131, 5, 167], [132, 5, 167], [134, 6, 166], [135, 7, 166], [136, 8, 166], [138, 9, 165], [139, 10, 165], [141, 11, 165], [142, 12, 164], [143, 13, 164], [145, 14, 163], [146, 15, 163], [148, 16, 162], [149, 17, 161], [150, 19, 161], [152, 20, 160], [153, 21, 159], [154, 22, 159], [156, 23, 158], [157, 24, 157], [158, 25, 157], [160, 26, 156], [161, 27, 155], [162, 29, 154], [163, 30, 154], [165, 31, 153], [166, 32, 152], [167, 33, 151], [168, 34, 150], [170, 35, 149], [171, 36, 148], [172, 38, 148], [173, 39, 147], [174, 40, 146], [176, 41, 145], [177, 42, 144], [178, 43, 143], [179, 44, 142], [180, 46, 141], [181, 47, 140], [182, 48, 139], [183, 49, 138], [184, 50, 137], [186, 51, 136], [187, 52, 136], [188, 53, 135], [189, 55, 134], [190, 56, 133], [191, 57, 132], [192, 58, 131], [193, 59, 130], [194, 60, 129], [195, 61, 128], [196, 62, 127], [197, 64, 126], [198, 65, 125], [199, 66, 124], [200, 67, 123], [201, 68, 122], [202, 69, 122], [203, 70, 121], [204, 71, 120], [204, 73, 119], [205, 74, 118], [206, 75, 117], [207, 76, 116], [208, 77, 115], [209, 78, 114], [210, 79, 113], [211, 81, 113], [212, 82, 112], [213, 83, 111], [213, 84, 110], [214, 85, 109], [215, 86, 108], [216, 87, 107], [217, 88, 106], [218, 90, 106], [218, 91, 105], [219, 92, 104], [220, 93, 103], [221, 94, 102], [222, 95, 101], [222, 97, 100], [223, 98, 99], [224, 99, 99], [225, 100, 98], [226, 101, 97], [226, 102, 96], [227, 104, 95], [228, 105, 94], [229, 106, 93], [229, 107, 93], [230, 108, 92], [231, 110, 91], [231, 111, 90], [232, 112, 89], [233, 113, 88], [233, 114, 87], [234, 116, 87], [235, 117, 86], [235, 118, 85], [236, 119, 84], [237, 121, 83], [237, 122, 82], [238, 123, 81], [239, 124, 81], [239, 126, 80], [240, 127, 79], [240, 128, 78], [241, 129, 77], [241, 131, 76], [242, 132, 75], [243, 133, 75], [243, 135, 74], [244, 136, 73], [244, 137, 72], [245, 139, 71], [245, 140, 70], [246, 141, 69], [246, 143, 68], [247, 144, 68], [247, 145, 67], [247, 147, 66], [248, 148, 65], [248, 149, 64], [249, 151, 63], [249, 152, 62], [249, 154, 62], [250, 155, 61], [250, 156, 60], [250, 158, 59], [251, 159, 58], [251, 161, 57], [251, 162, 56], [252, 163, 56], [252, 165, 55], [252, 166, 54], [252, 168, 53], [252, 169, 52], [253, 171, 51], [253, 172, 51], [253, 174, 50], [253, 175, 49], [253, 177, 48], [253, 178, 47], [253, 180, 47], [253, 181, 46], [254, 183, 45], [254, 184, 44], [254, 186, 44], [254, 187, 43], [254, 189, 42], [254, 190, 42], [254, 192, 41], [253, 194, 41], [253, 195, 40], [253, 197, 39], [253, 198, 39], [253, 200, 39], [253, 202, 38], [253, 203, 38], [252, 205, 37], [252, 206, 37], [252, 208, 37], [252, 210, 37], [251, 211, 36], [251, 213, 36], [251, 215, 36], [250, 216, 36], [250, 218, 36], [249, 220, 36], [249, 221, 37], [248, 223, 37], [248, 225, 37], [247, 226, 37], [247, 228, 37], [246, 230, 38], [246, 232, 38], [245, 233, 38], [245, 235, 39], [244, 237, 39], [243, 238, 39], [243, 240, 39], [242, 242, 39], [241, 244, 38], [241, 245, 37], [240, 247, 36], [240, 249, 33]];\n\n// Reference: https://github.com/d3/d3-interpolate/blob/96d54051d1c2fec55f240edd0ec5401715b10390/src/rgb.js\nfunction rgbSpline(spline) {\n  return (colors) => {\n    const n = colors.length;\n    let r = new Array(n);\n    let g = new Array(n);\n    let b = new Array(n);\n    let i; let\n      color;\n    // eslint-disable-next-line no-plusplus\n    for (i = 0; i < n; ++i) {\n      color = [colors[i][0], colors[i][1], colors[i][2]];\n      r[i] = color[0] || 0;\n      g[i] = color[1] || 0;\n      b[i] = color[2] || 0;\n    }\n    r = spline(r);\n    g = spline(g);\n    b = spline(b);\n    return t => [r(t), g(t), b(t)];\n  };\n}\n\n// Reference: https://github.com/d3/d3-interpolate/blob/594a32af1fe1118812b439012c2cb742e907c0c0/src/basis.js\nfunction basis(values) {\n  function innerBasis(t1, v0, v1, v2, v3) {\n    const t2 = t1 * t1; const\n      t3 = t2 * t1;\n    return ((1 - 3 * t1 + 3 * t2 - t3) * v0\n          + (4 - 6 * t2 + 3 * t3) * v1\n          + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2\n          + t3 * v3) / 6;\n  }\n\n  const n = values.length - 1;\n  return (t) => {\n    const i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n);\n    const v1 = values[i];\n    const v2 = values[i + 1];\n    const v0 = i > 0 ? values[i - 1] : 2 * v1 - v2;\n    const v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;\n    return innerBasis((t - i / n) * n, v0, v1, v2, v3);\n  };\n}\n\n\n// Reference: https://github.com/d3/d3-scale-chromatic/blob/ade54c13e8dfdb9807801a794eaec1a37f926b8a/src/ramp.js\nconst interpolateRgbBasis = rgbSpline(basis);\n\nfunction interpolateSequentialMulti(range) {\n  const n = range.length;\n  return t => range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];\n}\n\nexport const interpolateRdBu = interpolateRgbBasis(schemeRdBu);\nexport const interpolatePlasma = interpolateSequentialMulti(schemePlasma);\n\n\n/**\n * Get a mapping of cell IDs to cell colors based on\n * gene / cell set selection coordination state.\n * @param {object} params\n * @param {object} params.expressionMatrix { rows, cols, matrix }\n * @param {array} params.geneSelection Array of selected gene IDs.\n * @param {object} params.cellSets The cell sets tree.\n * @param {object} params.cellSetSelection Selected cell sets.\n * @param {string} params.cellColorEncoding Which to use for\n * coloring: gene expression or cell sets?\n * @returns {Map} Mapping from cell IDs to [r, g, b] color arrays.\n */\nexport function getCellColors(params) {\n  const {\n    cellColorEncoding,\n    expressionData,\n    cellSets, cellSetSelection,\n    cellSetColor,\n    expressionDataAttrs,\n    theme,\n  } = params;\n  if (cellColorEncoding === 'geneSelection' && expressionData && expressionDataAttrs) {\n    // TODO: allow other color maps.\n    const geneExpColormap = interpolatePlasma;\n    const colors = new Map();\n    for (let i = 0; i < expressionData.length; i += 1) {\n      const value = expressionData[i];\n      const cellColor = geneExpColormap(value / 255);\n      colors.set(expressionDataAttrs.rows[i], cellColor);\n    }\n    return colors;\n  } if (cellColorEncoding === 'cellSetSelection' && cellSetSelection && cellSets) {\n    // Cell sets can potentially lack set colors since the color property\n    // is not a required part of the schema.\n    // The `initializeSets` function fills in any empty colors\n    // with defaults and returns the processed tree object.\n    return treeToCellColorsBySetNames(cellSets, cellSetSelection, cellSetColor, theme);\n  }\n  return new Map();\n}\n","/* eslint-disable import/no-extraneous-dependencies */\n/* eslint-disable no-underscore-dangle */\n// File adopted from nebula.gl's SelectionLayer\n// https://github.com/uber/nebula.gl/blob/8e9c2ec8d7cf4ca7050909ed826eb847d5e2cd9c/modules/layers/src/layers/selection-layer.js\nimport { CompositeLayer } from 'deck.gl';\nimport { polygon as turfPolygon, point as turfPoint } from '@turf/helpers';\nimport booleanWithin from '@turf/boolean-within';\nimport booleanContains from '@turf/boolean-contains';\nimport booleanOverlap from '@turf/boolean-overlap';\nimport booleanPointInPolygon from '@turf/boolean-point-in-polygon';\nimport { ScatterplotLayer } from '@deck.gl/layers';\nimport { SELECTION_TYPE } from 'nebula.gl';\nimport { EditableGeoJsonLayer } from '@nebula.gl/layers';\nimport { DrawRectangleMode, DrawPolygonByDraggingMode, ViewMode } from '@nebula.gl/edit-modes';\n\nconst EDIT_TYPE_ADD = 'addFeature';\nconst EDIT_TYPE_CLEAR = 'clearFeatures';\n\n// Customize the click handlers for the rectangle and polygon tools,\n// so that clicking triggers the `onEdit` callback.\nclass ClickableDrawRectangleMode extends DrawRectangleMode {\n  // eslint-disable-next-line class-methods-use-this\n  handleClick(event, props) {\n    props.onEdit({ editType: EDIT_TYPE_CLEAR });\n  }\n}\n\nclass ClickableDrawPolygonByDraggingMode extends DrawPolygonByDraggingMode {\n  // eslint-disable-next-line class-methods-use-this\n  handleClick(event, props) {\n    props.onEdit({ editType: EDIT_TYPE_CLEAR });\n  }\n}\n\nconst MODE_MAP = {\n  [SELECTION_TYPE.RECTANGLE]: ClickableDrawRectangleMode,\n  [SELECTION_TYPE.POLYGON]: ClickableDrawPolygonByDraggingMode,\n};\n\nconst defaultProps = {\n  selectionType: SELECTION_TYPE.RECTANGLE,\n  layerIds: [],\n  onSelect: () => {},\n};\n\nconst EMPTY_DATA = {\n  type: 'FeatureCollection',\n  features: [],\n};\n\nconst LAYER_ID_GEOJSON = 'selection-geojson';\n\nconst PASS_THROUGH_PROPS = [\n  'lineWidthScale',\n  'lineWidthMinPixels',\n  'lineWidthMaxPixels',\n  'lineWidthUnits',\n  'lineJointRounded',\n  'lineMiterLimit',\n  'pointRadiusScale',\n  'pointRadiusMinPixels',\n  'pointRadiusMaxPixels',\n  'lineDashJustified',\n  'getLineColor',\n  'getFillColor',\n  'getRadius',\n  'getLineWidth',\n  'getLineDashArray',\n  'getTentativeLineDashArray',\n  'getTentativeLineColor',\n  'getTentativeFillColor',\n  'getTentativeLineWidth',\n  'editHandlePointRadiusScale',\n  'editHandlePointRadiusMinPixels',\n  'editHandlePointRadiusMaxPixels',\n  'getEditHandlePointColor',\n  'getEditHandlePointRadius',\n  'modeHandlers',\n];\n\nexport default class SelectionLayer extends CompositeLayer {\n  _selectPolygonObjects(coordinates) {\n    const {\n      onSelect,\n      getCellCoords,\n      cellsQuadTree,\n      flipY,\n    } = this.props;\n\n    const flippedCoordinates = (flipY\n      ? coordinates.map(poly => poly.map(p => ([p[0], -p[1]])))\n      : coordinates);\n\n    // Convert the selection to a turf polygon object.\n    const selectedPolygon = turfPolygon(flippedCoordinates);\n\n    // Create an array to store the results.\n    const pickingInfos = [];\n\n    // quadtree.visit() takes a callback that returns a boolean:\n    // If true returned, then the children of the node are _not_ visited.\n    // If false returned, then the children of the node are visited.\n    // Reference: https://github.com/d3/d3-quadtree#quadtree_visit\n    cellsQuadTree.visit((node, x0, y0, x1, y1) => {\n      const nodePoints = [[[x0, y0], [x1, y0], [x1, y1], [x0, y1], [x0, y0]]];\n      const nodePolygon = turfPolygon(nodePoints);\n\n      const nodePolygonContainsSelectedPolygon = booleanContains(nodePolygon, selectedPolygon);\n      const nodePolygonWithinSelectedPolygon = booleanWithin(nodePolygon, selectedPolygon);\n      const nodePolygonOverlapsSelectedPolgyon = booleanOverlap(nodePolygon, selectedPolygon);\n\n      if (!nodePolygonContainsSelectedPolygon\n        && !nodePolygonWithinSelectedPolygon\n        && !nodePolygonOverlapsSelectedPolgyon) {\n        // We are not interested in anything below this node,\n        // so return true because we are done with this node.\n        return true;\n      }\n\n      // This node made it past the above return statement, so it must either\n      // contain, be within, or overlap with the selected polygon.\n\n      // Check if this is a leaf node.\n      if (node.data\n        && booleanPointInPolygon(\n          turfPoint([].slice.call(getCellCoords(node.data[1]))), selectedPolygon,\n        )\n      ) {\n        // This node has data, so it is a leaf node representing one data point,\n        // and we have verified that the point is in the selected polygon.\n        pickingInfos.push(node.data);\n      }\n\n      // Return false because we are not done.\n      // We want to visit the children of this node.\n      return false;\n    });\n\n    onSelect({ pickingInfos });\n  }\n\n  renderLayers() {\n    const { onSelect } = this.props;\n    const mode = MODE_MAP[this.props.selectionType] || ViewMode;\n\n    const inheritedProps = {};\n    PASS_THROUGH_PROPS.forEach((p) => {\n      if (this.props[p] !== undefined) inheritedProps[p] = this.props[p];\n    });\n    const layers = [\n      new EditableGeoJsonLayer(\n        this.getSubLayerProps({\n          id: LAYER_ID_GEOJSON,\n          pickable: true,\n          mode,\n          modeConfig: {\n            dragToDraw: true,\n          },\n          selectedFeatureIndexes: [],\n          data: EMPTY_DATA,\n          onEdit: ({ updatedData, editType }) => {\n            if (editType === EDIT_TYPE_ADD) {\n              const { coordinates } = updatedData.features[0].geometry;\n              this._selectPolygonObjects(coordinates);\n            } else if (editType === EDIT_TYPE_CLEAR) {\n              // We want to select an empty array to clear any previous selection.\n              onSelect({ pickingInfos: [] });\n            }\n          },\n          _subLayerProps: {\n            guides: {\n              pointType: 'circle',\n              _subLayerProps: {\n                'points-circle': {\n                  // Styling for editHandles goes here.\n                  // Reference: https://github.com/uber/nebula.gl/issues/618#issuecomment-898466319\n                  type: ScatterplotLayer,\n                  radiusScale: 1,\n                  stroked: true,\n                  getLineWidth: 1,\n                  radiusMinPixels: 1,\n                  radiusMaxPixels: 3,\n                  getRadius: 2,\n                },\n              },\n            },\n          },\n          ...inheritedProps,\n        }),\n      ),\n    ];\n\n    return layers;\n  }\n}\n\nSelectionLayer.layerName = 'SelectionLayer';\nSelectionLayer.defaultProps = defaultProps;\n","import { COORDINATE_SYSTEM } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport { DataFilterExtension } from '@deck.gl/extensions'; // eslint-disable-line import/no-extraneous-dependencies\nimport SelectionLayer from './SelectionLayer';\n\n/**\n * Convert a DeckGL layer ID to a \"base\" layer ID for selection.\n * @param {string} layerId The layer ID to convert.\n * @returns {string} The base layer ID.\n */\nfunction getBaseLayerId(layerId) {\n  return `base-${layerId}`;\n}\n\n/**\n * Convert a DeckGL layer ID to a \"selected\" layer ID for selection.\n * @param {string} layerId The layer ID to convert.\n * @returns {string} The base layer ID.\n */\nfunction getSelectedLayerId(layerId) {\n  return `selected-${layerId}`;\n}\n\n/**\n * Construct DeckGL selection layers.\n * @param {string} tool\n * @param {number} zoom\n * @param {string} cellBaseLayerId\n * @param {function} getCellCoords\n * @param {function} updateCellsSelection\n * @returns {object[]} The array of DeckGL selection layers.\n */\nexport function getSelectionLayers(\n  tool,\n  zoom,\n  layerId,\n  getCellCoords,\n  updateCellsSelection,\n  cellsQuadTree,\n  flipY = false,\n) {\n  if (!tool) {\n    return [];\n  }\n\n  const cellBaseLayerId = getBaseLayerId(layerId);\n  const editHandlePointRadius = 5 / (zoom + 16);\n\n  return [new SelectionLayer({\n    id: 'selection',\n    flipY,\n    cellsQuadTree,\n    getCellCoords,\n    coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n    selectionType: tool,\n    onSelect: ({ pickingInfos }) => {\n      const cellIds = pickingInfos.map(cellObj => cellObj[0]);\n      if (updateCellsSelection) {\n        updateCellsSelection(cellIds);\n      }\n    },\n    layerIds: [cellBaseLayerId],\n    getTentativeFillColor: () => [255, 255, 255, 95],\n    getTentativeLineColor: () => [143, 143, 143, 255],\n    getTentativeLineDashArray: () => [7, 4],\n    lineWidthMinPixels: 2,\n    lineWidthMaxPixels: 2,\n    getEditHandlePointColor: () => [0xff, 0xff, 0xff, 0xff],\n    getEditHandlePointRadius: () => editHandlePointRadius,\n    editHandlePointRadiusScale: 1,\n    editHandlePointRadiusMinPixels: editHandlePointRadius,\n    editHandlePointRadiusMaxPixels: 2 * editHandlePointRadius,\n  })];\n}\n\n/**\n * Get deck.gl layer props for selection overlays.\n * @param {object} props\n * @returns {object} Object with two properties,\n * overlay: overlayProps, base: baseProps,\n * where the values are deck.gl layer props.\n */\nexport function overlayBaseProps(props) {\n  const {\n    id, getColor, data, isSelected, ...rest\n  } = props;\n  return {\n    overlay: {\n      id: getSelectedLayerId(id),\n      getFillColor: getColor,\n      getLineColor: getColor,\n      data,\n      getFilterValue: isSelected,\n      extensions: [new DataFilterExtension({ filterSize: 1 })],\n      filterRange: [1, 1],\n      ...rest,\n    },\n    base: {\n      id: getBaseLayerId(id),\n      getLineColor: getColor,\n      getFillColor: getColor,\n      // Alternatively: contrast outlines with solids:\n      // getLineColor: getColor,\n      // getFillColor: [255, 255, 255],\n      data: data.slice(),\n      ...rest,\n    },\n  };\n}\n","import GL from '@luma.gl/constants'; // eslint-disable-line import/no-extraneous-dependencies\n\nexport const TILE_SIZE = 2048;\nexport const MIN_ROW_AGG = 1;\nexport const MAX_ROW_AGG = 16;\n\nexport const COLOR_BAR_SIZE = 20;\nexport const AXIS_LABEL_TEXT_SIZE = 9;\nexport const AXIS_TITLE_TEXT_SIZE = 15;\nexport const AXIS_MIN_SIZE = 10;\nexport const AXIS_MAX_SIZE = 90;\nexport const AXIS_MARGIN = 3;\nexport const THEME_TO_TEXT_COLOR = {\n  dark: [224, 224, 224],\n  light: [64, 64, 64],\n};\nexport const AXIS_FONT_FAMILY = \"-apple-system, 'Helvetica Neue', Arial, sans-serif\";\n\nexport const PIXELATED_TEXTURE_PARAMETERS = {\n  // NEAREST for integer data to prevent interpolation.\n  [GL.TEXTURE_MIN_FILTER]: GL.NEAREST,\n  [GL.TEXTURE_MAG_FILTER]: GL.NEAREST,\n  // CLAMP_TO_EDGE to remove tile artifacts.\n  [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE,\n  [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE,\n};\n","import glsl from 'glslify';\n\n/**\n * No change to the vertex shader from the base BitmapLayer.\n * Reference: https://github.com/visgl/deck.gl/blob/8.2-release/modules/layers/src/bitmap-layer/bitmap-layer-vertex.js\n */\nexport const vertexShader = glsl`\n#define SHADER_NAME heatmap-bitmap-layer-vertex-shader\n\nattribute vec2 texCoords;\nattribute vec3 positions;\nattribute vec3 positions64Low;\n\nvarying vec2 vTexCoord;\n\nconst vec3 pickingColor = vec3(1.0, 0.0, 0.0);\n\nvoid main(void) {\n  geometry.worldPosition = positions;\n  geometry.uv = texCoords;\n  geometry.pickingColor = pickingColor;\n\n  gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);\n  DECKGL_FILTER_GL_POSITION(gl_Position, geometry);\n\n  vTexCoord = texCoords;\n\n  vec4 color = vec4(0.0);\n  DECKGL_FILTER_COLOR(color, geometry);\n}\n`;\n\n/**\n * Fragment shader adapted to perform aggregation and\n * take color scale functions + sliders into account.\n * Reference: https://github.com/visgl/deck.gl/blob/8.2-release/modules/layers/src/bitmap-layer/bitmap-layer-fragment.js\n * Reference: https://github.com/hms-dbmi/viv/blob/06231ae02cac1ff57ba458c71e9bc59ed2fc4f8b/src/layers/XRLayer/xr-layer-fragment-colormap.webgl1.glsl\n */\nexport const fragmentShader = glsl`\n#define SHADER_NAME heatmap-bitmap-layer-fragment-shader\n\n#ifdef GL_ES\nprecision mediump float;\n#endif\n\n#pragma glslify: rdbu = require(\"glsl-colormap/rdbu\")\n#pragma glslify: plasma = require(\"glsl-colormap/plasma\")\n#pragma glslify: viridis = require(\"glsl-colormap/viridis\")\n#pragma glslify: greys = require(\"glsl-colormap/greys\")\n#pragma glslify: magma = require(\"glsl-colormap/magma\")\n#pragma glslify: jet = require(\"glsl-colormap/jet\")\n#pragma glslify: bone = require(\"glsl-colormap/bone\")\n#pragma glslify: copper = require(\"glsl-colormap/copper\")\n#pragma glslify: density = require(\"glsl-colormap/density\")\n#pragma glslify: inferno = require(\"glsl-colormap/inferno\")\n#pragma glslify: cool = require(\"glsl-colormap/cool\")\n#pragma glslify: hot = require(\"glsl-colormap/hot\")\n#pragma glslify: spring = require(\"glsl-colormap/spring\")\n#pragma glslify: summer = require(\"glsl-colormap/summer\")\n#pragma glslify: autumn = require(\"glsl-colormap/autumn\")\n#pragma glslify: winter = require(\"glsl-colormap/winter\")\n\n// The texture (GL.LUMINANCE & Uint8Array).\nuniform sampler2D uBitmapTexture;\n\n// What are the dimensions of the texture (width, height)?\nuniform vec2 uTextureSize;\n\n// How many consecutive pixels should be aggregated together along each axis?\nuniform vec2 uAggSize;\n\n// What are the values of the color scale sliders?\nuniform vec2 uColorScaleRange;\n\n// The texture coordinate, varying (interpolated between values set by the vertex shader).\nvarying vec2 vTexCoord;\n\nvoid main(void) {\n  // Compute 1 pixel in texture coordinates\n  vec2 onePixel = vec2(1.0, 1.0) / uTextureSize;\n  \n  vec2 viewCoord = vec2(floor(vTexCoord.x * uTextureSize.x), floor(vTexCoord.y * uTextureSize.y));\n\n  // Compute (x % aggSizeX, y % aggSizeY).\n  // These values will be the number of values to the left / above the current position to consider.\n  vec2 modAggSize = vec2(-1.0 * mod(viewCoord.x, uAggSize.x), -1.0 * mod(viewCoord.y, uAggSize.y));\n\n  // Take the sum of values along each axis.\n  float intensitySum = 0.0;\n  vec2 offsetPixels = vec2(0.0, 0.0);\n\n  for(int i = 0; i < 16; i++) {\n    // Check to break outer loop early.\n    // Uniforms cannot be used as conditions in GLSL for loops.\n    if(float(i) >= uAggSize.y) {\n      // Done in the y direction.\n      break;\n    }\n\n    offsetPixels = vec2(offsetPixels.x, (modAggSize.y + float(i)) * onePixel.y);\n\n    for(int j = 0; j < 16; j++) {\n      // Check to break inner loop early.\n      // Uniforms cannot be used as conditions in GLSL for loops.\n      if(float(j) >= uAggSize.x) {\n        // Done in the x direction.\n        break;\n      }\n\n      offsetPixels = vec2((modAggSize.x + float(j)) * onePixel.x, offsetPixels.y);\n      intensitySum += texture2D(uBitmapTexture, vTexCoord + offsetPixels).r;\n    }\n  }\n  \n  // Compute the mean value.\n  float intensityMean = intensitySum / (uAggSize.x * uAggSize.y);\n  \n  // Re-scale using the color scale slider values.\n  float scaledIntensityMean = (intensityMean - uColorScaleRange[0]) / max(0.005, (uColorScaleRange[1] - uColorScaleRange[0]));\n\n  gl_FragColor = COLORMAP_FUNC(clamp(scaledIntensityMean, 0.0, 1.0));\n\n  geometry.uv = vTexCoord;\n  DECKGL_FILTER_COLOR(gl_FragColor, geometry);\n}\n`;\n","/* eslint-disable no-underscore-dangle */\nimport GL from '@luma.gl/constants'; // eslint-disable-line import/no-extraneous-dependencies\nimport { _mergeShaders, project32, picking } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport { BitmapLayer } from '@deck.gl/layers'; // eslint-disable-line import/no-extraneous-dependencies\nimport { Texture2D } from '@luma.gl/core';\nimport { PIXELATED_TEXTURE_PARAMETERS, TILE_SIZE } from './heatmap-constants';\nimport { GLSL_COLORMAPS, GLSL_COLORMAP_DEFAULT, COLORMAP_SHADER_PLACEHOLDER } from './constants';\nimport { vertexShader, fragmentShader } from './heatmap-bitmap-layer-shaders';\n\nconst defaultProps = {\n  image: { type: 'object', value: null, async: true },\n  colormap: { type: 'string', value: GLSL_COLORMAP_DEFAULT, compare: true },\n  bounds: { type: 'array', value: [1, 0, 0, 1], compare: true },\n  aggSizeX: { type: 'number', value: 8.0, compare: true },\n  aggSizeY: { type: 'number', value: 8.0, compare: true },\n  colorScaleLo: { type: 'number', value: 0.0, compare: true },\n  colorScaleHi: { type: 'number', value: 1.0, compare: true },\n};\n\n/**\n * A BitmapLayer that performs aggregation in the fragment shader,\n * and renders its texture from a Uint8Array rather than an ImageData.\n */\nexport default class HeatmapBitmapLayer extends BitmapLayer {\n  /**\n   * Copy of getShaders from Layer (grandparent, parent of BitmapLayer).\n   * Reference: https://github.com/visgl/deck.gl/blob/0afd4e99a6199aeec979989e0c361c97e6c17a16/modules/core/src/lib/layer.js#L302\n   * @param {object} shaders\n   * @returns {object} Merged shaders.\n   */\n  _getShaders(shaders) {\n    this.props.extensions.forEach((extension) => {\n      // eslint-disable-next-line no-param-reassign\n      shaders = _mergeShaders(shaders, extension.getShaders.call(this, extension));\n    });\n    return shaders;\n  }\n\n  /**\n   * Need to override to provide custom shaders.\n   */\n  getShaders() {\n    const { colormap } = this.props;\n    const fragmentShaderWithColormap = (GLSL_COLORMAPS.includes(colormap)\n      ? fragmentShader.replace(COLORMAP_SHADER_PLACEHOLDER, colormap)\n      : fragmentShader.replace(COLORMAP_SHADER_PLACEHOLDER, GLSL_COLORMAP_DEFAULT)\n    );\n    return this._getShaders({\n      vs: vertexShader,\n      fs: fragmentShaderWithColormap,\n      modules: [project32, picking],\n    });\n  }\n\n  updateState(args) {\n    super.updateState(args);\n    this.loadTexture(this.props.image);\n    const { props, oldProps } = args;\n    if (props.colormap !== oldProps.colormap) {\n      const { gl } = this.context;\n      // eslint-disable-next-line no-unused-expressions\n      this.state.model?.delete();\n      this.state.model = this._getModel(gl);\n      this.getAttributeManager().invalidateAll();\n    }\n  }\n\n  /**\n   * Need to override to provide additional uniform values.\n   * Simplified by removing video-related code.\n   * Reference: https://github.com/visgl/deck.gl/blob/0afd4e99a6199aeec979989e0c361c97e6c17a16/modules/layers/src/bitmap-layer/bitmap-layer.js#L173\n   * @param {*} opts\n   */\n  draw(opts) {\n    const { uniforms } = opts;\n    const { bitmapTexture, model } = this.state;\n    const {\n      aggSizeX,\n      aggSizeY,\n      colorScaleLo,\n      colorScaleHi,\n    } = this.props;\n\n    // Render the image\n    if (bitmapTexture && model) {\n      model\n        .setUniforms(\n          Object.assign({}, uniforms, {\n            uBitmapTexture: bitmapTexture,\n            uTextureSize: [TILE_SIZE, TILE_SIZE],\n            uAggSize: [aggSizeX, aggSizeY],\n            uColorScaleRange: [colorScaleLo, colorScaleHi],\n          }),\n        )\n        .draw();\n    }\n  }\n\n  /**\n   * Need to override to provide the custom DEFAULT_TEXTURE_PARAMETERS\n   * object.\n   * Simplified by removing video-related code.\n   * Reference: https://github.com/visgl/deck.gl/blob/0afd4e99a6199aeec979989e0c361c97e6c17a16/modules/layers/src/bitmap-layer/bitmap-layer.js#L218\n   * @param {Uint8Array} image\n   */\n  loadTexture(image) {\n    const { gl } = this.context;\n\n    if (this.state.bitmapTexture) {\n      this.state.bitmapTexture.delete();\n    }\n\n    if (image instanceof Texture2D) {\n      this.setState({\n        bitmapTexture: image,\n      });\n    } else if (image) {\n      this.setState({\n        bitmapTexture: new Texture2D(gl, {\n          data: image,\n          mipmaps: false,\n          parameters: PIXELATED_TEXTURE_PARAMETERS,\n          // Each color contains a single luminance value.\n          // When sampled, rgb are all set to this luminance, alpha is 1.0.\n          // Reference: https://luma.gl/docs/api-reference/webgl/texture#texture-formats\n          format: GL.LUMINANCE,\n          dataFormat: GL.LUMINANCE,\n          type: GL.UNSIGNED_BYTE,\n          width: TILE_SIZE,\n          height: TILE_SIZE,\n        }),\n      });\n    }\n  }\n}\nHeatmapBitmapLayer.layerName = 'HeatmapBitmapLayer';\nHeatmapBitmapLayer.defaultProps = defaultProps;\n","import { BitmapLayer } from '@deck.gl/layers'; // eslint-disable-line import/no-extraneous-dependencies\nimport { CompositeLayer } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport { PIXELATED_TEXTURE_PARAMETERS } from './heatmap-constants';\n\n\n// These are the same defaultProps as for BitmapLayer.\nconst defaultProps = {\n  ...BitmapLayer.defaultProps,\n  image: { type: 'object', value: null, async: true },\n  bounds: { type: 'array', value: [1, 0, 0, 1], compare: true },\n  desaturate: {\n    type: 'number', min: 0, max: 1, value: 0,\n  },\n  transparentColor: { type: 'color', value: [0, 0, 0, 0] },\n  tintColor: { type: 'color', value: [255, 255, 255] },\n};\n\nexport default class PixelatedBitmapLayer extends CompositeLayer {\n  renderLayers() {\n    const { image } = this.props;\n    return new BitmapLayer(this.props, {\n      id: `${this.props.id}-wrapped`,\n      image,\n      textureParameters: PIXELATED_TEXTURE_PARAMETERS,\n    });\n  }\n}\n\nPixelatedBitmapLayer.layerName = 'PixelatedBitmapLayer';\nPixelatedBitmapLayer.defaultProps = defaultProps;\n","/* eslint-disable no-underscore-dangle */\nimport { COORDINATE_SYSTEM, CompositeLayer } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport { TextLayer } from '@deck.gl/layers'; // eslint-disable-line import/no-extraneous-dependencies\nimport {\n  AXIS_LABEL_TEXT_SIZE,\n  AXIS_TITLE_TEXT_SIZE,\n  AXIS_MARGIN,\n  THEME_TO_TEXT_COLOR,\n  AXIS_FONT_FAMILY,\n} from './heatmap-constants';\n\nexport default class HeatmapCompositeTextLayer extends CompositeLayer {\n  _renderAxisTopLayers() {\n    const {\n      axisTopLabelData, matrixLeft, width, matrixWidth, viewWidth, theme,\n      targetX, targetY, axisTopTitle, cellWidth, axisOffsetTop, scaleFactor,\n    } = this.props;\n    const showAxisTopLabels = cellWidth >= AXIS_LABEL_TEXT_SIZE;\n    const axisLabelTop = targetY + (axisOffsetTop - AXIS_MARGIN) / 2 / scaleFactor;\n    return [\n      new TextLayer({\n        id: 'axisTopLabels',\n        coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n        data: axisTopLabelData,\n        getText: d => d[1],\n        getPosition: d => [matrixLeft + ((d[0] + 0.5) / width) * matrixWidth, axisLabelTop],\n        getTextAnchor: 'start',\n        getColor: () => THEME_TO_TEXT_COLOR[theme],\n        getSize: (showAxisTopLabels ? AXIS_LABEL_TEXT_SIZE : 0),\n        getAngle: 75,\n        fontFamily: AXIS_FONT_FAMILY,\n        updateTriggers: {\n          getPosition: [axisLabelTop, matrixLeft, matrixWidth, viewWidth],\n          getSize: [showAxisTopLabels],\n          getColor: [theme],\n        },\n      }),\n      new TextLayer({\n        id: 'axisTopTitle',\n        coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n        data: [{ title: axisTopTitle }],\n        getText: d => d.title,\n        getPosition: [targetX, targetY],\n        getTextAnchor: 'middle',\n        getColor: () => THEME_TO_TEXT_COLOR[theme],\n        getSize: (!showAxisTopLabels ? AXIS_TITLE_TEXT_SIZE : 0),\n        getAngle: 0,\n        fontFamily: AXIS_FONT_FAMILY,\n        updateTriggers: {\n          getSize: [showAxisTopLabels],\n          getColor: [theme],\n        },\n      }),\n    ];\n  }\n\n  _renderAxisLeftLayers() {\n    const {\n      axisLeftLabelData, matrixTop, height, matrixHeight,\n      viewHeight, theme, axisLeftTitle, targetX, targetY, cellHeight, axisOffsetLeft,\n      scaleFactor,\n    } = this.props;\n    const showAxisLeftLabels = cellHeight >= AXIS_LABEL_TEXT_SIZE;\n    const axisLabelLeft = targetX + (axisOffsetLeft - AXIS_MARGIN) / 2 / scaleFactor;\n    return [\n      new TextLayer({\n        id: 'axisLeftLabels',\n        coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n        data: axisLeftLabelData,\n        getText: d => d[1],\n        getPosition: d => [axisLabelLeft, matrixTop + ((d[0] + 0.5) / height) * matrixHeight],\n        getTextAnchor: 'end',\n        getColor: () => THEME_TO_TEXT_COLOR[theme],\n        getSize: (showAxisLeftLabels ? AXIS_LABEL_TEXT_SIZE : 0),\n        getAngle: 0,\n        fontFamily: AXIS_FONT_FAMILY,\n        updateTriggers: {\n          getPosition: [axisLabelLeft, matrixTop, matrixHeight, viewHeight],\n          getSize: [showAxisLeftLabels],\n          getColor: [theme],\n        },\n      }),\n      new TextLayer({\n        id: 'axisLeftTitle',\n        coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n        data: [{ title: axisLeftTitle }],\n        getText: d => d.title,\n        getPosition: [targetX, targetY],\n        getTextAnchor: 'middle',\n        getColor: () => THEME_TO_TEXT_COLOR[theme],\n        getSize: (!showAxisLeftLabels ? AXIS_TITLE_TEXT_SIZE : 0),\n        getAngle: 90,\n        fontFamily: AXIS_FONT_FAMILY,\n        updateTriggers: {\n          getSize: [showAxisLeftLabels],\n          getColor: [theme],\n        },\n      }),\n    ];\n  }\n\n  renderLayers() {\n    return [\n      this._renderAxisTopLayers(),\n      this._renderAxisLeftLayers(),\n    ];\n  }\n}\n\nHeatmapCompositeTextLayer.layerName = 'HeatmapCompositeTextLayer';\n","import { quadtree } from 'd3-quadtree';\n\n/**\n * Create a d3-quadtree object for cells data points.\n * @param {array} cellsEntries Array of [cellId, cell] tuples,\n * resulting from running Object.entries on the cells object.\n * @param {function} getCellCoords Given a cell object, return the\n * spatial/scatterplot coordinates [x, y].\n * @returns {object} Quadtree instance.\n */\nexport function createCellsQuadTree(cellsEntries, getCellCoords) {\n  // Use the cellsEntries variable since it is already\n  // an array, converted by Object.entries().\n  // Only use cellsEntries in quadtree calculation if there is\n  // centroid data in the cells (i.e not just ids).\n  // eslint-disable-next-line no-unused-vars\n  if (!cellsEntries || !cellsEntries.length || !getCellCoords(cellsEntries[0][1])) {\n    // Abort if the cells data is not yet available.\n    return null;\n  }\n  const tree = quadtree()\n    .x(d => getCellCoords(d[1])[0])\n    .y(d => getCellCoords(d[1])[1])\n    .addAll(cellsEntries);\n  return tree;\n}\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"path\", {\n  fill: \"none\",\n  d: \"M0 0h24v24H0V0z\"\n});\n\nvar _ref3 = /*#__PURE__*/React.createElement(\"path\", {\n  d: \"M21 3L3 10.53v.98l6.84 2.65L12.48 21h.98L21 3z\"\n});\n\nfunction SvgNearMe(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    width: 24,\n    height: 24,\n    viewBox: \"0 0 24 24\",\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, _ref2, _ref3);\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgNearMe, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/near_me.2a308adc.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nvar _ref2 = /*#__PURE__*/React.createElement(\"path\", {\n  d: \"       M19 19h2v2h-2v-2zm0-2h2v-2h-2v2z       M3 13h2v-2H3v2zm0 4h2v-2H3v2z       m0-8h2V7H3v2zm0-4h2V3H3v2z       m4 0h2V3H7v2zm8 16h2v-2h-2v2z       m-4 0h2v-2h-2v2z       m4 0h2v-2h-2v2z       m-8 0h2v-2H7v2z       m-4 0h2v-2H3v2z       M11 5h2v-2h-2v2z       M15 5h2v-2h-2v2z       M19 5h2v-2h-2v2z       M19 9h2v-2h-2v2z       M19 13h2v-2h-2v2z     \"\n});\n\nfunction SvgSelectionRectangle(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    width: 24,\n    height: 24,\n    viewBox: \"0 0 24 24\",\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, _ref2);\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgSelectionRectangle, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/selection_rectangle.aa477261.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\nimport * as React from \"react\";\n\nfunction SvgSelectionLasso(_ref) {\n  var svgRef = _ref.svgRef,\n      title = _ref.title,\n      titleId = _ref.titleId,\n      props = _objectWithoutProperties(_ref, [\"svgRef\", \"title\", \"titleId\"]);\n\n  return /*#__PURE__*/React.createElement(\"svg\", _extends({\n    width: 24,\n    height: 24,\n    viewBox: \"0 0 24 24\",\n    ref: svgRef,\n    \"aria-labelledby\": titleId\n  }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n    id: titleId\n  }, title) : null, /*#__PURE__*/React.createElement(\"g\", {\n    transform: \"translate(0,3)\"\n  }, /*#__PURE__*/React.createElement(\"path\", {\n    style: {\n      strokeWidth: 0.343565\n    },\n    d: \"M 23.942314,4.6958443 C 23.446206,1.8868581 19.727461,0 14.687364,0 13.437819,0 12.150138,0.11543779 10.859708,0.34287772 4.1629423,1.5250844 -0.58168816,5.2884937 0.05768601,8.911385 c 0.25355086,1.439193 1.35605049,2.63583 3.04638949,3.461072 -0.2569865,0.387198 -0.4074679,0.826617 -0.4074679,1.29524 0,1.337498 1.1863293,2.457176 2.7639791,2.728248 l -1.3615475,2.333149 c -0.1576963,0.271073 -0.066308,0.61876 0.2047647,0.776457 0.090014,0.05291 0.1886171,0.07799 0.2858459,0.07799 0.1951448,0 0.3851362,-0.100665 0.4912977,-0.281723 l 1.6803757,-2.88148 C 8.41868,16.20561 9.6895264,15.063601 9.6998333,13.683844 c 6.872e-4,-0.0055 0.00137,-0.01065 0.00137,-0.01615 0,-0.02336 -0.00344,-0.04569 -0.00481,-0.06837 1.1292977,-0.0213 2.2847067,-0.130211 3.4435507,-0.334975 6.69711,-1.181863 11.44174,-4.9456164 10.802366,-8.5685077 z M 3.83312,13.667353 c 0,-0.30749 0.1281497,-0.59849 0.3470005,-0.848261 0.1219655,0.04295 0.2456489,0.08383 0.3717372,0.123339 l 1.2234344,2.352045 C 4.6865351,15.149835 3.83312,14.46408 3.83312,13.667353 Z M 7.0141869,15.216144 6.0223152,13.309702 5.4008064,12.114097 c 0.121622,-0.03161 0.2477103,-0.05634 0.3772342,-0.07387 0.1367388,-0.0189 0.2772568,-0.02886 0.420867,-0.02886 0.5067581,0 0.980534,0.11956 1.3701366,0.317454 0.5696305,0.289968 0.9554538,0.750345 0.9904974,1.262944 0.00137,0.02542 0.0055,0.05016 0.0055,0.07593 0,0.698124 -0.6562089,1.310356 -1.5508518,1.548447 z m 5.9185921,-3.126441 c -1.217251,0.214728 -2.429691,0.323982 -3.6060571,0.324669 -0.5765018,-0.911821 -1.7614569,-1.53917 -3.1278143,-1.53917 -0.4717146,0 -0.921441,0.07593 -1.332001,0.211292 -0.3061162,0.100665 -0.5878394,0.237403 -0.8427645,0.39991 C 2.4598914,10.828133 1.4360682,9.8579062 1.2319907,8.7035283 0.72660678,5.8381974 5.2307418,2.5475333 11.067221,1.5175259 c 1.222061,-0.2161023 2.439998,-0.3246688 3.620143,-0.3246688 4.371863,0 7.694479,1.5250844 8.080645,3.7101568 0.505041,2.8653309 -3.998751,6.1566821 -9.83523,7.1866891 z\",\n    id: \"path10\"\n  })));\n}\n\nvar ForwardRef = React.forwardRef(function (props, ref) {\n  return /*#__PURE__*/React.createElement(SvgSelectionLasso, _extends({\n    svgRef: ref\n  }, props));\n});\nexport default __webpack_public_path__ + \"static/media/selection_lasso.00e80a33.svg\";\nexport { ForwardRef as ReactComponent };","import React from 'react';\nimport { SELECTION_TYPE } from 'nebula.gl';\nimport { ReactComponent as PointerIconSVG } from '../../assets/tools/near_me.svg';\nimport { ReactComponent as SelectRectangleIconSVG } from '../../assets/tools/selection_rectangle.svg';\nimport { ReactComponent as SelectLassoIconSVG } from '../../assets/tools/selection_lasso.svg';\n\nexport function IconButton(props) {\n  const {\n    alt, onClick, isActive, children,\n  } = props;\n  const inactive = 'btn btn-outline-secondary mr-2 icon';\n  const active = `${inactive} active`;\n  return (\n    <button\n      className={isActive ? active : inactive}\n      onClick={onClick}\n      type=\"button\"\n      title={alt}\n    >\n      {children}\n    </button>\n  );\n}\n\nexport default function ToolMenu(props) {\n  const {\n    setActiveTool,\n    activeTool,\n    visibleTools = { pan: true, selectRectangle: true, selectLasso: true },\n  } = props;\n  return (\n    <div className=\"tool\">\n      {visibleTools.pan && (\n      <IconButton\n        alt=\"pointer tool\"\n        onClick={() => setActiveTool(null)}\n        isActive={activeTool === null}\n      ><PointerIconSVG />\n      </IconButton>\n      )}\n      {visibleTools.selectRectangle ? (\n        <IconButton\n          alt=\"select rectangle\"\n          onClick={() => setActiveTool(SELECTION_TYPE.RECTANGLE)}\n          isActive={activeTool === SELECTION_TYPE.RECTANGLE}\n        ><SelectRectangleIconSVG />\n        </IconButton>\n      ) : null}\n      {visibleTools.selectLasso ? (\n        <IconButton\n          alt=\"select lasso\"\n          onClick={() => setActiveTool(SELECTION_TYPE.POLYGON)}\n          isActive={activeTool === SELECTION_TYPE.POLYGON}\n        ><SelectLassoIconSVG />\n        </IconButton>\n      ) : null}\n    </div>\n  );\n}\n","export const getCursorWithTool = () => 'crosshair';\nexport const getCursor = interactionState => (interactionState.isDragging\n  ? 'grabbing' : 'default'\n);\n","import React, { PureComponent } from 'react';\nimport DeckGL, { OrthographicView, OrbitView } from 'deck.gl';\nimport ToolMenu from './ToolMenu';\nimport { DEFAULT_GL_OPTIONS } from '../utils';\nimport { getCursor, getCursorWithTool } from './cursor';\n\n/**\n * Abstract class component intended to be inherited by\n * the Spatial and Scatterplot class components.\n * Contains a common constructor, common DeckGL callbacks,\n * and common render function.\n */\nexport default class AbstractSpatialOrScatterplot extends PureComponent {\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      gl: null,\n      tool: null,\n    };\n\n    this.viewport = null;\n\n    this.onViewStateChange = this.onViewStateChange.bind(this);\n    this.onInitializeViewInfo = this.onInitializeViewInfo.bind(this);\n    this.onWebGLInitialized = this.onWebGLInitialized.bind(this);\n    this.onToolChange = this.onToolChange.bind(this);\n    this.onHover = this.onHover.bind(this);\n  }\n\n  /**\n   * Called by DeckGL upon a viewState change,\n   * for example zoom or pan interaction.\n   * Emit the new viewState to the `setViewState`\n   * handler prop.\n   * @param {object} params\n   * @param {object} params.viewState The next deck.gl viewState.\n   */\n  onViewStateChange({ viewState: nextViewState }) {\n    const {\n      setViewState, viewState, layers, spatialAxisFixed,\n    } = this.props;\n    const use3d = layers?.some(l => l.use3d);\n    setViewState({\n      ...nextViewState,\n      // If the axis is fixed, just use the current target in state i.e don't change target.\n      target: spatialAxisFixed && use3d ? viewState.target : nextViewState.target,\n    });\n  }\n\n  /**\n   * Called by DeckGL upon viewport\n   * initialization.\n   * @param {object} viewState\n   * @param {object} viewState.viewport\n   */\n  onInitializeViewInfo({ viewport }) {\n    this.viewport = viewport;\n  }\n\n  /**\n   * Called by DeckGL upon initialization,\n   * helps to understand when to pass layers\n   * to the DeckGL component.\n   * @param {object} gl The WebGL context object.\n   */\n  onWebGLInitialized(gl) {\n    this.setState({ gl });\n  }\n\n  /**\n   * Called by the ToolMenu buttons.\n   * Emits the new tool value to the\n   * `onToolChange` prop.\n   * @param {string} tool Name of tool.\n   */\n  onToolChange(tool) {\n    const { onToolChange: onToolChangeProp } = this.props;\n    this.setState({ tool });\n    if (onToolChangeProp) {\n      onToolChangeProp(tool);\n    }\n  }\n\n  /**\n   * Create the DeckGL layers.\n   * @returns {object[]} Array of\n   * DeckGL layer objects.\n   * Intended to be overriden by descendants.\n   */\n  // eslint-disable-next-line class-methods-use-this\n  getLayers() {\n    return [];\n  }\n\n  // eslint-disable-next-line consistent-return\n  onHover(info) {\n    const {\n      coordinate, sourceLayer: layer, tile,\n    } = info;\n    const {\n      setCellHighlight, cellHighlight, setComponentHover, layers,\n    } = this.props;\n    const hasBitmask = (layers || []).some(l => l.type === 'bitmask');\n    if (!setCellHighlight || !tile) {\n      return null;\n    }\n    if (!layer || !coordinate) {\n      if (cellHighlight && hasBitmask) {\n        setCellHighlight(null);\n      }\n      return null;\n    }\n    const { content, bbox, z } = tile;\n    if (!content) {\n      if (cellHighlight && hasBitmask) {\n        setCellHighlight(null);\n      }\n      return null;\n    }\n    const { data, width, height } = content;\n    const {\n      left, right, top, bottom,\n    } = bbox;\n    const bounds = [\n      left,\n      data.height < layer.tileSize ? height : bottom,\n      data.width < layer.tileSize ? width : right,\n      top,\n    ];\n    if (!data) {\n      if (cellHighlight && hasBitmask) {\n        setCellHighlight(null);\n      }\n      return null;\n    }\n    // Tiled layer needs a custom layerZoomScale.\n    if (layer.id.includes('bitmask')) {\n      // The zoomed out layer needs to use the fixed zoom at which it is rendered.\n      const layerZoomScale = Math.max(\n        1,\n        2 ** Math.round(-z),\n      );\n      const dataCoords = [\n        Math.floor((coordinate[0] - bounds[0]) / layerZoomScale),\n        Math.floor((coordinate[1] - bounds[3]) / layerZoomScale),\n      ];\n      const coords = dataCoords[1] * width + dataCoords[0];\n      const hoverData = data.map(d => d[coords]);\n      const cellId = hoverData.find(i => i > 0);\n      if (cellId !== Number(cellHighlight)) {\n        if (setComponentHover) {\n          setComponentHover();\n        }\n        // eslint-disable-next-line no-unused-expressions\n        setCellHighlight(cellId ? String(cellId) : null);\n      }\n    }\n  }\n\n  /**\n   * Emits a function to project from the\n   * cell ID space to the scatterplot or\n   * spatial coordinate space, via the\n   * `updateViewInfo` prop.\n   */\n  viewInfoDidUpdate(getCellCoords) {\n    const { updateViewInfo, cells, uuid } = this.props;\n    const { viewport } = this;\n    if (updateViewInfo && viewport) {\n      updateViewInfo({\n        uuid,\n        project: (cellId) => {\n          const cell = cells[cellId];\n          try {\n            const [positionX, positionY] = getCellCoords(cell);\n            return viewport.project([positionX, positionY]);\n          } catch (e) {\n            return [null, null];\n          }\n        },\n      });\n    }\n  }\n\n  /**\n   * Intended to be overriden by descendants.\n   */\n  componentDidUpdate() {\n\n  }\n\n  /**\n   * A common render function for both Spatial\n   * and Scatterplot components.\n   */\n  render() {\n    const {\n      deckRef, viewState, uuid, layers: layerProps,\n    } = this.props;\n    const { gl, tool } = this.state;\n    const layers = this.getLayers();\n    const use3d = (layerProps || []).some(l => l.use3d);\n\n    const showCellSelectionTools = this.cellsLayer !== null\n      || (this.cellsEntries.length && this.cellsEntries[0][1].xy);\n    const showPanTool = this.cellsLayer !== null || layerProps.findIndex(l => l.type === 'bitmask' || l.type === 'raster') >= 0;\n    // For large datasets or ray casting, the visual quality takes only a small\n    // hit in exchange for much better performance by setting this to false:\n    // https://deck.gl/docs/api-reference/core/deck#usedevicepixels\n    const useDevicePixels = this.cellsEntries.length < 100000 && !use3d;\n\n    return (\n      <>\n        <ToolMenu\n          activeTool={tool}\n          setActiveTool={this.onToolChange}\n          visibleTools={{\n            pan: showPanTool,\n            selectRectangle: showCellSelectionTools,\n            selectLasso: showCellSelectionTools,\n          }}\n        />\n        <DeckGL\n          id={`deckgl-overlay-${uuid}`}\n          ref={deckRef}\n          views={[\n            use3d\n              ? new OrbitView({ id: 'orbit', controller: true, orbitAxis: 'Y' })\n              : new OrthographicView({\n                id: 'ortho',\n              }),\n          ]} // id is a fix for https://github.com/uber/deck.gl/issues/3259\n          layers={\n            gl && viewState.target.slice(0, 2).every(i => typeof i === 'number')\n              ? layers\n              : []\n          }\n          glOptions={DEFAULT_GL_OPTIONS}\n          onWebGLInitialized={this.onWebGLInitialized}\n          onViewStateChange={this.onViewStateChange}\n          viewState={viewState}\n          useDevicePixels={useDevicePixels}\n          controller={tool ? { dragPan: false } : true}\n          getCursor={tool ? getCursorWithTool : getCursor}\n          onHover={this.onHover}\n        >\n          {this.onInitializeViewInfo}\n        </DeckGL>\n      </>\n    );\n  }\n}\n","/* eslint-disable no-plusplus */\n/* eslint-disable no-param-reassign */\nimport { quadtree } from 'd3-quadtree';\n\n/**\n * Returns a closure that returns a constant value.\n */\nfunction constant(v) {\n  return (() => v);\n}\n\n/**\n * Adds a tiny bit of randomness to a number.\n */\nfunction jiggle(v) {\n  return v + (Math.random() - 0.5) * 1e-6;\n}\n\n/**\n * A force function to be used with d3.forceSimulation.\n * This has been adapted for use here, with comments explaining each part.\n * Reference: https://bl.ocks.org/cmgiven/547658968d365bcc324f3e62e175709b\n */\nexport function forceCollideRects() {\n  // D3 implements things with function prototypes rather than classes.\n  // Pretend these variables are the \"instance members\" of a class.\n  // Note that this function actually returns the internal force() function,\n  // but that the force() function is a closure with access to these instance members.\n\n  let nodes;\n  let masses;\n  let strength = 1;\n  let iterations = 1;\n\n  let sizes;\n  let size = constant([0, 0]);\n\n  // Given a node, return the center point along the x-axis.\n  function xCenter(d) {\n    return d.x + d.vx + sizes[d.index][0] / 2;\n  }\n\n  // Given a node, return the center point along the y-axis.\n  function yCenter(d) {\n    return d.y + d.vy + sizes[d.index][1] / 2;\n  }\n\n  // Given a quadtree node, initialize its .size property.\n  function prepare(quad) {\n    if (quad.data) {\n      // This is a leaf node, so we set quad.size to the node's size.\n      // (No need to compute the max of internal nodes,\n      // since leaf nodes do not have any internal nodes).\n      quad.size = sizes[quad.data.index];\n    } else {\n      quad.size = [0, 0];\n      // Internal nodes of the quadtree are represented\n      // as four-element arrays in left-to-right, top-to-bottom order.\n      // Here, we are setting quad.size to [maxWidth, maxHeight]\n      // among the internal nodes of this current `quad` node.\n      for (let i = 0; i < 4; i++) {\n        if (quad[i] && quad[i].size) {\n          quad.size[0] = Math.max(quad.size[0], quad[i].size[0]);\n          quad.size[1] = Math.max(quad.size[1], quad[i].size[1]);\n        }\n      }\n    }\n  }\n\n  function force() {\n    let node;\n    let nodeSize;\n    let nodeMass;\n    let xi;\n    let yi;\n\n    // Create a quadtree based on node center points.\n    // Initialize each quadtree node's .size property by calling\n    // the prepare() function on each quadtree node.\n    const tree = quadtree(nodes, xCenter, yCenter).visitAfter(prepare);\n\n    // Update the .vx and .vy properties of both `node` and `data`\n    // (the current node pair).\n    function apply(quad, x0, y0, x1, y1) {\n      // `quad` is a quadtree node.\n      const { data } = quad;\n      const xSize = (nodeSize[0] + quad.size[0]) / 2;\n      const ySize = (nodeSize[1] + quad.size[1]) / 2;\n\n      if (data && data.index > node.index) {\n        // This is a leaf node because `data` is defined.\n        // `x` is the difference in x centers between `node` and `data`.\n        // `y` is the difference in y centers between `node` and `data`.\n        let x = jiggle(xi - xCenter(data));\n        let y = jiggle(yi - yCenter(data));\n        const xd = Math.abs(x) - xSize;\n        const yd = Math.abs(y) - ySize;\n\n        // If `xd` and `yd` is less than zero,\n        // then there is an overlap between the two nodes.\n        if (xd < 0 && yd < 0) {\n          const l = Math.sqrt(x * x + y * y);\n          const m = masses[data.index] / (nodeMass + masses[data.index]);\n\n          // We move the nodes either in the x or y direction.\n          // Nodes are moved proportionally to:\n          // their distance apart (`l`), their amount of overlap (`xd` or `yd`), their masses (`m`),\n          // and the strength parameter (`strength`).\n          if (Math.abs(xd) < Math.abs(yd)) {\n            node.vx -= (x *= xd / l * strength) * m;\n            data.vx += x * (1 - m);\n          } else {\n            node.vy -= (y *= yd / l * strength) * m;\n            data.vy += y * (1 - m);\n          }\n        }\n        // When the quadtree.visit callback returns _true_ for a node,\n        // then the node's children will _not_ be visited.\n        return x0 > xi + xSize || x1 < xi - xSize || y0 > yi + ySize || y1 < yi - ySize;\n      }\n      return false;\n    }\n\n    function iterate() {\n      // On every iteration, use the `apply` function to visit every node\n      // which has an index greater than the current node's index,\n      // (visiting every node pair).\n      for (let j = 0; j < nodes.length; j++) {\n        node = nodes[j];\n        nodeSize = sizes[j];\n        nodeMass = masses[j];\n        xi = xCenter(node);\n        yi = yCenter(node);\n\n        tree.visit(apply);\n      }\n    }\n\n    // Do the specified number of iterations.\n    for (let i = 0; i < iterations; i++) {\n      iterate();\n    }\n  }\n\n  // The \"constructor\".\n  // Takes a list of nodes as input.\n  force.initialize = (v) => {\n    nodes = v;\n    // Get the size [w, h] of each node using the size getter function.\n    sizes = nodes.map(size);\n    // Get the mass of each node,\n    // which is the sum of its horizontal and vertical edge lengths.\n    masses = sizes.map(d => d[0] + d[1]);\n  };\n\n  // Set the number of iterations.\n  // If no value is provided as a parameter, this acts as a getter function.\n  force.iterations = (...v) => {\n    if (v.length) {\n      iterations = +v[0];\n      return force;\n    }\n    return iterations;\n  };\n\n  // Set the strength value.\n  // If no value is provided as a parameter, this acts as a getter function.\n  force.strength = (...v) => {\n    if (v.length) {\n      strength = +v[0];\n      return force;\n    }\n    return strength;\n  };\n\n  // Set the size function.\n  // The size function takes a node as a parameter and returns its size.\n  // If no size function is provided as a parameter, this acts as a getter function.\n  force.size = (...v) => {\n    if (v.length) {\n      size = (typeof v[0] === 'function' ? v[0] : constant(v[0]));\n      return force;\n    }\n    return size;\n  };\n\n  // Returns the force closure.\n  return force;\n}\n","import glsl from 'glslify';\n\n/**\n *\n * Reference: https://github.com/visgl/deck.gl/blob/8.4-release/modules/layers/src/scatterplot-layer/scatterplot-layer-vertex.glsl.js\n * Reference: https://observablehq.com/@rreusser/selecting-the-right-opacity-for-2d-point-clouds\n * Reference: https://github.com/flekschas/regl-scatterplot/blob/5e3b03e/src/point.vs\n */\nconst vs = glsl`\n#pragma glslify: plasma = require(\"glsl-colormap/plasma\")\n#pragma glslify: viridis = require(\"glsl-colormap/viridis\")\n#pragma glslify: greys = require(\"glsl-colormap/greys\")\n#pragma glslify: magma = require(\"glsl-colormap/magma\")\n#pragma glslify: jet = require(\"glsl-colormap/jet\")\n#pragma glslify: bone = require(\"glsl-colormap/bone\")\n#pragma glslify: copper = require(\"glsl-colormap/copper\")\n#pragma glslify: density = require(\"glsl-colormap/density\")\n#pragma glslify: inferno = require(\"glsl-colormap/inferno\")\n#pragma glslify: cool = require(\"glsl-colormap/cool\")\n#pragma glslify: hot = require(\"glsl-colormap/hot\")\n#pragma glslify: spring = require(\"glsl-colormap/spring\")\n#pragma glslify: summer = require(\"glsl-colormap/summer\")\n#pragma glslify: autumn = require(\"glsl-colormap/autumn\")\n#pragma glslify: winter = require(\"glsl-colormap/winter\")\n\n// Custom attributes for Vitessce:\nattribute float expressionValue;\n\n// Custom uniforms for Vitessce:\nuniform vec2 uColorScaleRange;\nuniform bool uIsExpressionMode;\n\n`;\n\nconst inject = {\n  'vs:DECKGL_FILTER_COLOR': `\n    if(uIsExpressionMode) {\n      float normalizedExpressionValue = expressionValue / 255.0;\n      float scaledExpressionValue = (normalizedExpressionValue - uColorScaleRange[0]) / max(0.005, (uColorScaleRange[1] - uColorScaleRange[0]));\n      color.rgb = COLORMAP_FUNC(clamp(scaledExpressionValue, 0.0, 1.0)).rgb;\n    }\n  `,\n};\n\nexport default {\n  name: 'scaled-expression',\n  vs,\n  inject,\n};\n","/* eslint-disable no-underscore-dangle */\n/* eslint-disable import/no-extraneous-dependencies */\nimport GL from '@luma.gl/constants';\nimport { LayerExtension } from '@deck.gl/core';\nimport { GLSL_COLORMAPS, GLSL_COLORMAP_DEFAULT, COLORMAP_SHADER_PLACEHOLDER } from '../../layers/constants';\nimport module from './shader-module';\n\nconst defaultProps = {\n  colormap: { type: 'string', value: GLSL_COLORMAP_DEFAULT, compare: true },\n  colorScaleLo: { type: 'number', value: 0.0, compare: true },\n  colorScaleHi: { type: 'number', value: 1.0, compare: true },\n  isExpressionMode: false,\n  getExpressionValue: { type: 'accessor', value: 0 },\n  getSelectionState: { type: 'accessor', value: 0.0 },\n};\n\nexport default class ScaledExpressionExtension extends LayerExtension {\n  getShaders() {\n    const { colormap } = this.props;\n    return {\n      modules: [module],\n      defines: {\n        [COLORMAP_SHADER_PLACEHOLDER]: GLSL_COLORMAPS.includes(colormap)\n          ? colormap\n          : GLSL_COLORMAP_DEFAULT,\n      },\n    };\n  }\n\n  updateState({ props, oldProps }) {\n    if (props.colormap !== oldProps.colormap) {\n      const { gl } = this.context;\n      // Normal single model layers, like ScatterplotLayer\n      if (this.state.model) {\n        // eslint-disable-next-line no-unused-expressions\n        this.state.model?.delete();\n        this.state.model = this._getModel(gl);\n      } else {\n        // Special handling for PolygonLayer sublayer models.\n        if (this.state.models) {\n          // eslint-disable-next-line no-unused-expressions\n          this.state.models?.forEach(model => model?.delete());\n        }\n        if (this.state.topModel) {\n           // eslint-disable-next-line no-unused-expressions\n           this.state.topModel?.delete();\n        }\n        if (this.state.sideModel) {\n           // eslint-disable-next-line no-unused-expressions\n           this.state.sideModel?.delete();\n        }\n        if (this._getModels) {\n          this.setState(this._getModels(this.context.gl));\n        }\n      }\n      const attributeManager = this.getAttributeManager();\n      if (attributeManager) {\n        this.getAttributeManager().invalidateAll();\n      }\n    }\n  }\n\n  initializeState() {\n    const layer = this.getCurrentLayer();\n    // No need to run this on layers that don't have a `draw` call.\n    if (layer.isComposite) {\n      return;\n    }\n    const attributeManager = this.getAttributeManager();\n    if (attributeManager) {\n      // This attributes is the array of expression data needed for\n      // coloring cells against the colormap.\n      attributeManager.add({\n        expressionValue: {\n          type: GL.FLOAT,\n          size: 1,\n          transition: true,\n          accessor: 'getExpressionValue',\n          defaultValue: 1,\n          // PolygonLayer fill needs not-intsanced attribute but\n          // ScatterplotLayer and the PolygonLayer stroke needs instanced.\n          // So use another attribute's divisor property as a proxy for this divisor.\n          divisor: Object.values(attributeManager.attributes)[0].settings.divisor,\n        },\n      });\n    }\n  }\n\n  draw() {\n    const {\n      colorScaleLo,\n      colorScaleHi,\n      isExpressionMode,\n    } = this.props;\n    const {\n      topModel, sideModel, models, model,\n    } = this.state;\n    const uniforms = {\n      uColorScaleRange: [colorScaleLo, colorScaleHi],\n      uIsExpressionMode: isExpressionMode,\n    };\n    // ScatterplotLayer model\n    // eslint-disable-next-line no-unused-expressions\n    model?.setUniforms(uniforms);\n\n    // PolygonLayer models from sublayers\n    // eslint-disable-next-line no-unused-expressions\n    models?.forEach(m => m.setUniforms(uniforms));\n    // eslint-disable-next-line no-unused-expressions\n    topModel?.setUniforms(uniforms);\n    // eslint-disable-next-line no-unused-expressions\n    sideModel?.setUniforms(uniforms);\n  }\n}\n\nScaledExpressionExtension.extensionName = 'ScaledExpressionExtension';\nScaledExpressionExtension.defaultProps = defaultProps;\n","import ScaledExpressionExtension from './ScaledExpressionExtension';\n\nexport default ScaledExpressionExtension;\n","import glsl from 'glslify';\n\nconst vs = glsl`\nattribute float isSelected;\n`;\n\nconst inject = {\n  'vs:DECKGL_FILTER_GL_POSITION': `\n    position.z += (1. - isSelected) * .00005; // Add a small z offset for unselected points in the positive direction i.e into the screen.\n  `,\n  'fs:#main-start': ` // Gets rid of bad border effects (active after deck.gl 8.5): https://github.com/visgl/deck.gl/pull/6081\n    float distToCenterNew = length(unitPosition) * outerRadiusPixels;\n    float inCircleNew = step(distToCenterNew, outerRadiusPixels);\n    if (inCircleNew == 0.0) {\n      discard;\n    }\n  `,\n};\n\nexport default {\n  name: 'selection',\n  vs,\n  inject,\n};\n","/* eslint-disable no-underscore-dangle */\n/* eslint-disable import/no-extraneous-dependencies */\nimport GL from '@luma.gl/constants';\nimport { LayerExtension } from '@deck.gl/core';\nimport module from './shader-module';\n\nexport default class SelectionExtension extends LayerExtension {\n  // eslint-disable-next-line class-methods-use-this\n  getShaders() {\n    return {\n      modules: [module],\n    };\n  }\n\n  initializeState(context, extension) {\n    const attributeManager = this.getAttributeManager();\n    if (attributeManager) {\n      attributeManager.add({\n        isSelected: {\n          type: GL.FLOAT,\n          size: 1,\n          transition: true,\n          accessor: 'getCellIsSelected',\n          defaultValue: 1,\n          // PolygonLayer needs not-intsanced attribute but\n          // ScatterplotLayer needs instanced.\n          divisor: Number(extension.opts.instanced),\n        },\n      });\n    }\n  }\n}\n\nSelectionExtension.extensionName = 'SelectionExtension';\n","import SelectionExtension from './SelectionExtension';\n\nexport default SelectionExtension;\n","import React, { forwardRef } from 'react';\nimport { PolygonLayer, TextLayer, ScatterplotLayer } from '@deck.gl/layers'; // eslint-disable-line import/no-extraneous-dependencies\nimport { forceSimulation } from 'd3-force';\nimport { getSelectionLayers } from '../../layers';\nimport { cellLayerDefaultProps, getDefaultColor } from '../utils';\nimport {\n  createCellsQuadTree,\n} from '../shared-spatial-scatterplot/quadtree';\nimport AbstractSpatialOrScatterplot from '../shared-spatial-scatterplot/AbstractSpatialOrScatterplot';\nimport { forceCollideRects } from '../shared-spatial-scatterplot/force-collide-rects';\nimport { ScaledExpressionExtension, SelectionExtension } from '../../layer-extensions';\n\nconst CELLS_LAYER_ID = 'scatterplot';\nconst LABEL_FONT_FAMILY = \"-apple-system, 'Helvetica Neue', Arial, sans-serif\";\nconst NUM_FORCE_SIMULATION_TICKS = 100;\nconst LABEL_UPDATE_ZOOM_DELTA = 0.25;\n\n// Default getter function props.\nconst makeDefaultGetCellPosition = mapping => (cellEntry) => {\n  const { mappings } = cellEntry[1];\n  if (!(mapping in mappings)) {\n    const available = Object.keys(mappings).map(s => `\"${s}\"`).join(', ');\n    throw new Error(`Expected to find \"${mapping}\", but available mappings are: ${available}`);\n  }\n  const mappedCell = mappings[mapping];\n  // The negative applied to the y-axis is because\n  // graphics rendering has the y-axis positive going south.\n  return [mappedCell[0], -mappedCell[1], 0];\n};\nconst makeDefaultGetCellCoords = mapping => cell => cell.mappings[mapping];\nconst makeDefaultGetCellColors = (cellColors, theme) => (cellEntry) => {\n  const [r, g, b, a] = (cellColors && cellColors.get(cellEntry[0])) || getDefaultColor(theme);\n  return [r, g, b, 255 * (a || 1)];\n};\n\n/**\n * React component which renders a scatterplot from cell data, typically tSNE or PCA.\n * @param {object} props\n * @param {string} props.uuid A unique identifier for this component.\n * @param {string} props.theme The current vitessce theme.\n * @param {object} props.viewState The deck.gl view state.\n * @param {function} props.setViewState Function to call to update the deck.gl view state.\n * @param {object} props.cells\n * @param {string} props.mapping The name of the coordinate mapping field,\n * for each cell, for example \"PCA\" or \"t-SNE\".\n * @param {Map} props.cellColors Mapping of cell IDs to colors.\n * @param {array} props.cellSelection Array of selected cell IDs.\n * @param {array} props.cellFilter Array of filtered cell IDs. By default, null.\n * @param {number} props.cellRadius The value for `radiusScale` to pass\n * to the deck.gl cells ScatterplotLayer.\n * @param {number} props.cellOpacity The value for `opacity` to pass\n * to the deck.gl cells ScatterplotLayer.\n * @param {function} props.getCellCoords Getter function for cell coordinates\n * (used by the selection layer).\n * @param {function} props.getCellPosition Getter function for cell [x, y, z] position.\n * @param {function} props.getCellColor Getter function for cell color as [r, g, b] array.\n * @param {function} props.getCellIsSelected Getter function for cell layer isSelected.\n * @param {function} props.setCellSelection\n * @param {function} props.setCellHighlight\n * @param {function} props.updateViewInfo\n * @param {function} props.onToolChange Callback for tool changes\n * (lasso/pan/rectangle selection tools).\n * @param {function} props.onCellClick Getter function for cell layer onClick.\n */\nclass Scatterplot extends AbstractSpatialOrScatterplot {\n  constructor(props) {\n    super(props);\n\n    // To avoid storing large arrays/objects\n    // in React state, this component\n    // uses instance variables.\n    // All instance variables used in this class:\n    this.cellsEntries = [];\n    this.cellsQuadTree = null;\n    this.cellsLayer = null;\n    this.cellSetsForceSimulation = forceCollideRects();\n    this.cellSetsLabelPrevZoom = null;\n    this.cellSetsLayers = [];\n\n    // Initialize data and layers.\n    this.onUpdateCellsData();\n    this.onUpdateCellsLayer();\n    this.onUpdateCellSetsLayers();\n  }\n\n  createCellsLayer() {\n    const { cellsEntries } = this;\n    const {\n      theme,\n      mapping,\n      getCellPosition = makeDefaultGetCellPosition(mapping),\n      cellRadius = 1.0,\n      cellOpacity = 1.0,\n      cellFilter,\n      cellSelection,\n      setCellHighlight,\n      setComponentHover,\n      getCellIsSelected,\n      cellColors,\n      getCellColor = makeDefaultGetCellColors(cellColors, theme),\n      getExpressionValue,\n      onCellClick,\n      geneExpressionColormap,\n      geneExpressionColormapRange = [0.0, 1.0],\n      cellColorEncoding,\n    } = this.props;\n    const filteredCellsEntries = (cellFilter\n      ? cellsEntries.filter(cellEntry => cellFilter.includes(cellEntry[0]))\n      : cellsEntries);\n    return new ScatterplotLayer({\n      id: CELLS_LAYER_ID,\n      backgroundColor: (theme === 'dark' ? [0, 0, 0] : [241, 241, 241]),\n      getCellIsSelected,\n      opacity: cellOpacity,\n      radiusScale: cellRadius,\n      radiusMinPixels: 1,\n      radiusMaxPixels: 30,\n      // Our radius pixel setters measure in pixels.\n      radiusUnits: 'pixels',\n      lineWidthUnits: 'pixels',\n      getPosition: getCellPosition,\n      getFillColor: getCellColor,\n      getLineColor: getCellColor,\n      getRadius: 1,\n      getExpressionValue,\n      getLineWidth: 0,\n      extensions: [\n        new ScaledExpressionExtension(),\n        new SelectionExtension({ instanced: true }),\n      ],\n      colorScaleLo: geneExpressionColormapRange[0],\n      colorScaleHi: geneExpressionColormapRange[1],\n      isExpressionMode: (cellColorEncoding === 'geneSelection'),\n      colormap: geneExpressionColormap,\n      onClick: (info) => {\n        if (onCellClick) {\n          onCellClick(info);\n        }\n      },\n      updateTriggers: {\n        getExpressionValue,\n        getFillColor: [cellColorEncoding, cellSelection, cellColors],\n        getLineColor: [cellColorEncoding, cellSelection, cellColors],\n        getCellIsSelected,\n      },\n      ...cellLayerDefaultProps(\n        filteredCellsEntries, undefined, setCellHighlight, setComponentHover,\n      ),\n      stroked: 0,\n    });\n  }\n\n  createCellSetsLayers() {\n    const {\n      theme,\n      cellSetPolygons,\n      viewState,\n      cellSetPolygonsVisible,\n      cellSetLabelsVisible,\n      cellSetLabelSize,\n    } = this.props;\n\n    const result = [];\n\n    if (cellSetPolygonsVisible) {\n      result.push(new PolygonLayer({\n        id: 'cell-sets-polygon-layer',\n        data: cellSetPolygons,\n        stroked: true,\n        filled: false,\n        wireframe: true,\n        lineWidthMaxPixels: 1,\n        getPolygon: d => d.hull,\n        getLineColor: d => d.color,\n        getLineWidth: 1,\n      }));\n    }\n\n    if (cellSetLabelsVisible) {\n      const { zoom } = viewState;\n      const nodes = cellSetPolygons.map(p => ({\n        x: p.centroid[0],\n        y: p.centroid[1],\n        label: p.name,\n      }));\n\n      const collisionForce = this.cellSetsForceSimulation\n        .size(d => ([\n          cellSetLabelSize * 1 / (2 ** zoom) * 4 * d.label.length,\n          cellSetLabelSize * 1 / (2 ** zoom) * 1.5,\n        ]));\n\n      forceSimulation()\n        .nodes(nodes)\n        .force('collision', collisionForce)\n        .tick(NUM_FORCE_SIMULATION_TICKS);\n\n      result.push(new TextLayer({\n        id: 'cell-sets-text-layer',\n        data: nodes,\n        getPosition: d => ([d.x, d.y]),\n        getText: d => d.label,\n        getColor: (theme === 'dark' ? [255, 255, 255] : [0, 0, 0]),\n        getSize: cellSetLabelSize,\n        getAngle: 0,\n        getTextAnchor: 'middle',\n        getAlignmentBaseline: 'center',\n        fontFamily: LABEL_FONT_FAMILY,\n        fontWeight: 'normal',\n      }));\n    }\n\n    return result;\n  }\n\n  createSelectionLayers() {\n    const {\n      viewState,\n      mapping,\n      getCellCoords = makeDefaultGetCellCoords(mapping),\n      setCellSelection,\n    } = this.props;\n    const { tool } = this.state;\n    const { cellsQuadTree } = this;\n    const flipYTooltip = true;\n    return getSelectionLayers(\n      tool,\n      viewState.zoom,\n      CELLS_LAYER_ID,\n      getCellCoords,\n      setCellSelection,\n      cellsQuadTree,\n      flipYTooltip,\n    );\n  }\n\n  getLayers() {\n    const {\n      cellsLayer,\n      cellSetsLayers,\n    } = this;\n    return [\n      cellsLayer,\n      ...cellSetsLayers,\n      ...this.createSelectionLayers(),\n    ];\n  }\n\n  onUpdateCellsData() {\n    const {\n      cells = {},\n      mapping,\n      getCellCoords = makeDefaultGetCellCoords(mapping),\n    } = this.props;\n    const cellsEntries = Object.entries(cells);\n    this.cellsEntries = cellsEntries;\n    this.cellsQuadTree = createCellsQuadTree(cellsEntries, getCellCoords);\n  }\n\n  onUpdateCellsLayer() {\n    this.cellsLayer = this.createCellsLayer();\n  }\n\n  onUpdateCellSetsLayers(onlyViewStateChange) {\n    // Because the label sizes for the force simulation depend on the zoom level,\n    // we _could_ run the simulation every time the zoom level changes.\n    // However, this has a performance impact in firefox.\n    if (onlyViewStateChange) {\n      const { viewState, cellSetLabelsVisible } = this.props;\n      const { zoom } = viewState;\n      const { cellSetsLabelPrevZoom } = this;\n      // Instead, we can just check if the zoom level has changed\n      // by some relatively large delta, to be more conservative\n      // about re-running the force simulation.\n      if (cellSetLabelsVisible\n        && (\n          cellSetsLabelPrevZoom === null\n          || Math.abs(cellSetsLabelPrevZoom - zoom) > LABEL_UPDATE_ZOOM_DELTA\n        )\n      ) {\n        this.cellSetsLayers = this.createCellSetsLayers();\n        this.cellSetsLabelPrevZoom = zoom;\n      }\n    } else {\n      // Otherwise, something more substantial than just\n      // the viewState has changed, such as the label array\n      // itself, so we always want to update the layer\n      // in this case.\n      this.cellSetsLayers = this.createCellSetsLayers();\n    }\n  }\n\n  viewInfoDidUpdate() {\n    const {\n      mapping,\n      getCellPosition = makeDefaultGetCellPosition(mapping),\n    } = this.props;\n    super.viewInfoDidUpdate(cell => getCellPosition([null, cell]));\n  }\n\n  /**\n   * Here, asynchronously check whether props have\n   * updated which require re-computing memoized variables,\n   * followed by a re-render.\n   * This function does not follow React conventions or paradigms,\n   * it is only implemented this way to try to squeeze out\n   * performance.\n   * @param {object} prevProps The previous props to diff against.\n   */\n  componentDidUpdate(prevProps) {\n    this.viewInfoDidUpdate();\n\n    const shallowDiff = propName => (prevProps[propName] !== this.props[propName]);\n    if (['cells'].some(shallowDiff)) {\n      // Cells data changed.\n      this.onUpdateCellsData();\n      this.forceUpdate();\n    }\n\n    if ([\n      'cells', 'cellFilter', 'cellSelection', 'cellColors',\n      'cellRadius', 'cellOpacity', 'cellRadiusMode', 'geneExpressionColormap',\n      'geneExpressionColormapRange', 'geneSelection', 'cellColorEncoding',\n    ].some(shallowDiff)) {\n      // Cells layer props changed.\n      this.onUpdateCellsLayer();\n      this.forceUpdate();\n    }\n    if ([\n      'cellSetPolygons', 'cellSetPolygonsVisible',\n      'cellSetLabelsVisible', 'cellSetLabelSize',\n    ].some(shallowDiff)) {\n      // Cell sets layer props changed.\n      this.onUpdateCellSetsLayers(false);\n      this.forceUpdate();\n    }\n    if (shallowDiff('viewState')) {\n      // The viewState prop has changed (due to zoom or pan).\n      this.onUpdateCellSetsLayers(true);\n      this.forceUpdate();\n    }\n  }\n\n  // render() is implemented in the abstract parent class.\n}\n\n/**\n * Need this wrapper function here,\n * since we want to pass a forwardRef\n * so that outer components can\n * access the grandchild DeckGL ref,\n * but we are using a class component.\n */\nconst ScatterplotWrapper = forwardRef((props, deckRef) => (\n  <Scatterplot\n    {...props}\n    deckRef={deckRef}\n  />\n));\nexport default ScatterplotWrapper;\n","import { makeStyles } from '@material-ui/core/styles';\n\nexport const styles = makeStyles(() => ({\n  tooltipAnchor: {\n    position: 'relative',\n    width: '0px',\n    height: '0px',\n    pointerEvents: 'none',\n    userSelect: 'none',\n  },\n  tooltipContent: {\n    opacity: 0.9,\n    padding: '5px',\n    pointerEvents: 'none',\n    '& table > tbody > tr > th, & table > tbody > tr > td': {\n      fontSize: '80%',\n      opacity: 0.8,\n      outline: 0,\n      padding: '0 2px',\n    },\n    '& table': {\n      borderCollapse: 'collapse',\n    },\n  },\n}));\n","import React, { useEffect, useRef, useState } from 'react';\nimport Paper from '@material-ui/core/Paper';\nimport Popper from '@material-ui/core/Popper';\nimport { useVitessceContainer } from '../hooks';\nimport { styles } from './styles';\n\nexport default function Tooltip(props) {\n  const {\n    x,\n    y,\n    parentWidth,\n    parentHeight,\n    children,\n  } = props;\n  const ref = useRef();\n  const classes = styles();\n  const [placementX, setPlacementX] = useState('start');\n  const [placementY, setPlacementY] = useState('bottom');\n\n  const getTooltipContainer = useVitessceContainer(ref);\n\n  // Do collision detection based on the bounds of the tooltip ancestor element.\n  useEffect(() => {\n    if (ref && ref.current) {\n      const flipX = (x > parentWidth / 2);\n      const flipY = (y > parentHeight / 2);\n      setPlacementX(flipX ? 'end' : 'start');\n      setPlacementY(flipY ? 'top' : 'bottom');\n      ref.current.style.left = `${x + (flipX ? -20 : 5)}px`;\n      ref.current.style.top = `${y + (flipY ? -20 : 5)}px`;\n    }\n  }, [x, y, parentWidth, parentHeight]);\n\n  return (\n    <div\n      ref={ref}\n      className={classes.tooltipAnchor}\n    >\n      {ref && ref.current ? (\n        <Popper\n          open\n          anchorEl={ref.current}\n          container={getTooltipContainer}\n          transition\n          placement={`${placementY}-${placementX}`}\n        >\n          <Paper elevation={4} className={classes.tooltipContent}>\n            {children}\n          </Paper>\n        </Popper>\n      ) : null}\n    </div>\n  );\n}\n","import React from 'react';\nimport Tooltip from './Tooltip';\n\n/**\n * A tooltip component that also incorporates a crosshair element.\n * @param {object} props\n * @param {string} props.parentUuid A unique identifier corresponding to the plot\n * with which this scatterplot is associated.\n * @param {string} props.sourceUuid A unique identifier corresponding to the plot\n * from which this tooltip originated.\n * @param {number} props.x The x coordinate for the tooltip.\n * @param {number} props.y The y coordinate for the tooltip.\n * @param {number} props.parentWidth The width of the parent plot container element.\n * @param {number} props.parentHeight The height of the parent plot container element.\n * @param {React.Component} props.children The tooltip contents as a react component.\n */\nexport default function Tooltip2D(props) {\n  const {\n    parentUuid,\n    sourceUuid,\n    x,\n    y,\n    parentWidth,\n    parentHeight,\n    children,\n  } = props;\n  // Check if out of bounds.\n  if (x < 0 || x > parentWidth || y < 0 || y > parentHeight) {\n    return null;\n  }\n  // Show tooltip or crosshair?\n  const isTooltipVisible = (parentUuid === sourceUuid);\n  const crosshairWidth = 1;\n  return (\n    <>\n      {isTooltipVisible ? (\n        <Tooltip\n          x={x}\n          y={y}\n          parentWidth={parentWidth}\n          parentHeight={parentHeight}\n        >\n          {children}\n        </Tooltip>\n      ) : (\n        <>\n          {x !== null ? (\n            <div\n              className=\"cell-emphasis-crosshair\"\n              style={{\n                left: `${x - crosshairWidth / 2}px`,\n                top: 0,\n                width: `${crosshairWidth}px`,\n                height: `${parentHeight}px`,\n              }}\n            />\n          ) : null}\n          {y !== null ? (\n            <div\n              className=\"cell-emphasis-crosshair\"\n              style={{\n                left: 0,\n                top: `${y - crosshairWidth / 2}px`,\n                width: `${parentWidth}px`,\n                height: `${crosshairWidth}px`,\n              }}\n            />\n          ) : null}\n        </>\n      )}\n    </>\n  );\n}\n","import React from 'react';\n\nexport default function TooltipContent(props) {\n  const {\n    info,\n  } = props;\n\n  return (\n    <table>\n      <tbody>\n        {Object.entries(info).map(([key, value]) => (\n          <tr key={key}>\n            <th>{key}</th>\n            <td>{value}</td>\n          </tr>\n        ))}\n      </tbody>\n    </table>\n  );\n}\n","import React from 'react';\nimport Tooltip2D from '../tooltip/Tooltip2D';\nimport TooltipContent from '../tooltip/TooltipContent';\nimport { useComponentHover, useComponentViewInfo } from '../../app/state/hooks';\n\nexport default function ScatterplotTooltipSubscriber(props) {\n  const {\n    parentUuid,\n    cellHighlight,\n    width,\n    height,\n    getCellInfo,\n  } = props;\n\n  const sourceUuid = useComponentHover();\n  const viewInfo = useComponentViewInfo(parentUuid);\n\n  const [cellInfo, x, y] = (cellHighlight && getCellInfo ? (\n    [\n      getCellInfo(cellHighlight),\n      ...(viewInfo && viewInfo.project ? viewInfo.project(cellHighlight) : [null, null]),\n    ]\n  ) : ([null, null, null]));\n\n  return (\n    (cellInfo ? (\n      <Tooltip2D\n        x={x}\n        y={y}\n        parentUuid={parentUuid}\n        sourceUuid={sourceUuid}\n        parentWidth={width}\n        parentHeight={height}\n      >\n        <TooltipContent info={cellInfo} />\n      </Tooltip2D>\n    ) : null)\n  );\n}\n","import { makeStyles } from '@material-ui/core/styles';\n\nexport const useStyles = makeStyles(theme => ({\n  box: {\n    boxSizing: 'border-box',\n  },\n  checkbox: {\n    padding: '3px',\n    color: theme.palette.primaryForeground,\n    '&:checked': {\n      color: theme.palette.primaryForeground,\n    },\n    '& input': {\n      height: '100%',\n    },\n  },\n  slider: {\n    color: theme.palette.primaryForeground,\n    minWidth: '60px',\n    padding: '10px 0 10px 0',\n  },\n  sliderValueLabel: {\n    '& span': {\n      '& span': {\n        color: theme.palette.primaryBackground,\n      },\n    },\n  },\n  tableContainer: {\n    overflow: 'hidden',\n    overflowX: 'hidden !important',\n  },\n  labelCell: {\n    padding: '2px 8px 2px 16px',\n  },\n  inputCell: {\n    padding: '2px 16px 2px 8px',\n    overflow: 'visible',\n  },\n  select: {\n    '& select': {\n      fontSize: '.875rem',\n    },\n  },\n  selectRoot: {\n    padding: 0,\n    height: 'auto',\n  },\n}));\n","import React from 'react';\nimport Box from '@material-ui/core/Box';\nimport Table from '@material-ui/core/Table';\nimport TableBody from '@material-ui/core/TableBody';\nimport TableContainer from '@material-ui/core/TableContainer';\nimport { useStyles } from './styles';\n\nexport default function OptionsContainer(props) {\n  const {\n    children,\n  } = props;\n\n  const classes = useStyles();\n\n  return (\n    <Box className={classes.box}>\n      <TableContainer className={classes.tableContainer}>\n        <Table className={classes.table} size=\"small\">\n          <TableBody>\n            {children}\n          </TableBody>\n        </Table>\n      </TableContainer>\n    </Box>\n  );\n}\n","import React from 'react';\nimport Select from '@material-ui/core/Select';\nimport { useStyles } from './styles';\n\nexport default function OptionSelect(props) {\n  const { classes: classesProp = {} } = props;\n  const classes = useStyles();\n  return (\n    <Select\n      native\n      disableUnderline\n      {...props}\n      classes={{\n        root: classes.selectRoot,\n        ...classesProp,\n      }}\n    />\n  );\n}\n","import React from 'react';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableRow from '@material-ui/core/TableRow';\nimport { capitalize } from '../../utils';\nimport OptionSelect from './OptionSelect';\nimport { useStyles } from './styles';\n\nexport default function CellColorEncodingOption(props) {\n  const {\n    observationsLabel,\n    cellColorEncoding,\n    setCellColorEncoding,\n  } = props;\n\n  const classes = useStyles();\n\n  const observationsLabelNice = capitalize(observationsLabel);\n\n  function handleColorEncodingChange(event) {\n    setCellColorEncoding(event.target.value);\n  }\n\n  return (\n    <TableRow>\n      <TableCell className={classes.labelCell} htmlFor=\"cell-color-encoding-select\">\n        {observationsLabelNice} Color Encoding\n      </TableCell>\n      <TableCell className={classes.inputCell}>\n        <OptionSelect\n          className={classes.select}\n          value={cellColorEncoding}\n          onChange={handleColorEncodingChange}\n          inputProps={{\n            id: 'cell-color-encoding-select',\n          }}\n        >\n          <option value=\"cellSetSelection\">Cell Sets</option>\n          <option value=\"geneSelection\">Gene Expression</option>\n        </OptionSelect>\n      </TableCell>\n    </TableRow>\n  );\n}\n","import React, { useCallback } from 'react';\nimport debounce from 'lodash/debounce';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Slider from '@material-ui/core/Slider';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableRow from '@material-ui/core/TableRow';\nimport { capitalize } from '../../utils';\nimport { useStyles } from '../shared-plot-options/styles';\nimport OptionsContainer from '../shared-plot-options/OptionsContainer';\nimport OptionSelect from '../shared-plot-options/OptionSelect';\nimport CellColorEncodingOption from '../shared-plot-options/CellColorEncodingOption';\nimport { GLSL_COLORMAPS } from '../../layers/constants';\n\nexport default function ScatterplotOptions(props) {\n  const {\n    observationsLabel,\n    cellRadius,\n    setCellRadius,\n    cellRadiusMode,\n    setCellRadiusMode,\n    cellOpacity,\n    setCellOpacity,\n    cellOpacityMode,\n    setCellOpacityMode,\n    cellSetLabelsVisible,\n    setCellSetLabelsVisible,\n    cellSetLabelSize,\n    setCellSetLabelSize,\n    cellSetPolygonsVisible,\n    setCellSetPolygonsVisible,\n    cellColorEncoding,\n    setCellColorEncoding,\n    geneExpressionColormap,\n    setGeneExpressionColormap,\n    geneExpressionColormapRange,\n    setGeneExpressionColormapRange,\n  } = props;\n\n  const observationsLabelNice = capitalize(observationsLabel);\n\n  const classes = useStyles();\n\n  function handleCellRadiusModeChange(event) {\n    setCellRadiusMode(event.target.value);\n  }\n\n  function handleCellOpacityModeChange(event) {\n    setCellOpacityMode(event.target.value);\n  }\n\n  function handleRadiusChange(event, value) {\n    setCellRadius(value);\n  }\n\n  function handleOpacityChange(event, value) {\n    setCellOpacity(value);\n  }\n\n  function handleLabelVisibilityChange(event) {\n    setCellSetLabelsVisible(event.target.checked);\n  }\n\n  function handleLabelSizeChange(event, value) {\n    setCellSetLabelSize(value);\n  }\n\n  function handlePolygonVisibilityChange(event) {\n    setCellSetPolygonsVisible(event.target.checked);\n  }\n\n  function handleGeneExpressionColormapChange(event) {\n    setGeneExpressionColormap(event.target.value);\n  }\n\n  function handleColormapRangeChange(event, value) {\n    setGeneExpressionColormapRange(value);\n  }\n  const handleColormapRangeChangeDebounced = useCallback(\n    debounce(handleColormapRangeChange, 5, { trailing: true }),\n    [handleColormapRangeChange],\n  );\n\n  return (\n    <OptionsContainer>\n      <CellColorEncodingOption\n        observationsLabel={observationsLabel}\n        cellColorEncoding={cellColorEncoding}\n        setCellColorEncoding={setCellColorEncoding}\n      />\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          {observationsLabelNice} Set Labels Visible\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Checkbox\n            className={classes.checkbox}\n            checked={cellSetLabelsVisible}\n            onChange={handleLabelVisibilityChange}\n            name=\"scatterplot-option-cell-set-labels\"\n            color=\"default\"\n          />\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          {observationsLabelNice} Set Label Size\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Slider\n            disabled={!cellSetLabelsVisible}\n            classes={{ root: classes.slider, valueLabel: classes.sliderValueLabel }}\n            value={cellSetLabelSize}\n            onChange={handleLabelSizeChange}\n            aria-labelledby=\"cell-set-label-size-slider\"\n            valueLabelDisplay=\"auto\"\n            step={1}\n            min={8}\n            max={36}\n          />\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          {observationsLabelNice} Set Polygons Visible\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Checkbox\n            className={classes.checkbox}\n            checked={cellSetPolygonsVisible}\n            onChange={handlePolygonVisibilityChange}\n            name=\"scatterplot-option-cell-set-polygons\"\n            color=\"default\"\n          />\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell} htmlFor=\"cell-radius-mode-select\">\n          {observationsLabelNice} Radius Mode\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <OptionSelect\n            className={classes.select}\n            value={cellRadiusMode}\n            onChange={handleCellRadiusModeChange}\n            inputProps={{\n              id: 'cell-radius-mode-select',\n            }}\n          >\n            <option value=\"auto\">Auto</option>\n            <option value=\"manual\">Manual</option>\n          </OptionSelect>\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          {observationsLabelNice} Radius\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Slider\n            disabled={cellRadiusMode !== 'manual'}\n            classes={{ root: classes.slider, valueLabel: classes.sliderValueLabel }}\n            value={cellRadius}\n            onChange={handleRadiusChange}\n            aria-labelledby=\"cell-radius-slider\"\n            valueLabelDisplay=\"auto\"\n            step={0.01}\n            min={0.01}\n            max={10}\n          />\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell} htmlFor=\"cell-opacity-mode-select\">\n          {observationsLabelNice} Opacity Mode\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <OptionSelect\n            className={classes.select}\n            value={cellOpacityMode}\n            onChange={handleCellOpacityModeChange}\n            inputProps={{\n              id: 'cell-opacity-mode-select',\n            }}\n          >\n            <option value=\"auto\">Auto</option>\n            <option value=\"manual\">Manual</option>\n          </OptionSelect>\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          {observationsLabelNice} Opacity\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Slider\n            disabled={cellOpacityMode !== 'manual'}\n            classes={{ root: classes.slider, valueLabel: classes.sliderValueLabel }}\n            value={cellOpacity}\n            onChange={handleOpacityChange}\n            aria-labelledby=\"cell-opacity-slider\"\n            valueLabelDisplay=\"auto\"\n            step={0.05}\n            min={0.0}\n            max={1.0}\n          />\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell} htmlFor=\"gene-expression-colormap-select\">\n          Gene Expression Colormap\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <OptionSelect\n            className={classes.select}\n            value={geneExpressionColormap}\n            onChange={handleGeneExpressionColormapChange}\n            inputProps={{\n              id: 'gene-expression-colormap-select',\n            }}\n          >\n            {GLSL_COLORMAPS.map(cmap => (\n              <option key={cmap} value={cmap}>{cmap}</option>\n            ))}\n          </OptionSelect>\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          Gene Expression Colormap Range\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Slider\n            classes={{ root: classes.slider, valueLabel: classes.sliderValueLabel }}\n            value={geneExpressionColormapRange}\n            onChange={handleColormapRangeChangeDebounced}\n            aria-labelledby=\"gene-expression-colormap-range-slider\"\n            valueLabelDisplay=\"auto\"\n            step={0.005}\n            min={0.0}\n            max={1.0}\n          />\n        </TableCell>\n      </TableRow>\n    </OptionsContainer>\n  );\n}\n","import React, {\n  useState, useEffect, useCallback, useMemo,\n} from 'react';\nimport { extent } from 'd3-array';\nimport isEqual from 'lodash/isEqual';\nimport TitleInfo from '../TitleInfo';\nimport { pluralize, capitalize } from '../../utils';\nimport {\n  useDeckCanvasSize, useReady, useUrls, useExpressionValueGetter,\n} from '../hooks';\nimport { setCellSelection, mergeCellSets } from '../utils';\nimport { getCellSetPolygons } from '../sets/cell-set-utils';\nimport {\n  useCellsData,\n  useCellSetsData,\n  useGeneSelection,\n  useExpressionAttrs,\n} from '../data-hooks';\nimport { getCellColors } from '../interpolate-colors';\nimport Scatterplot from './Scatterplot';\nimport ScatterplotTooltipSubscriber from './ScatterplotTooltipSubscriber';\nimport ScatterplotOptions from './ScatterplotOptions';\nimport {\n  useCoordination,\n  useLoaders,\n  useSetComponentHover,\n  useSetComponentViewInfo,\n} from '../../app/state/hooks';\nimport {\n  getPointSizeDevicePixels,\n  getPointOpacity,\n} from '../shared-spatial-scatterplot/dynamic-opacity';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\n\nconst SCATTERPLOT_DATA_TYPES = ['cells', 'expression-matrix', 'cell-sets'];\n\n/**\n * A subscriber component for the scatterplot.\n * @param {object} props\n * @param {number} props.uuid The unique identifier for this component.\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {boolean} props.disableTooltip Should the tooltip be disabled?\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title An override value for the component title.\n * @param {number} props.averageFillDensity Override the average fill density calculation\n * when using dynamic opacity mode.\n */\nexport default function ScatterplotSubscriber(props) {\n  const {\n    uuid,\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n    disableTooltip = false,\n    observationsLabelOverride: observationsLabel = 'cell',\n    observationsPluralLabelOverride: observationsPluralLabel = `${observationsLabel}s`,\n    title: titleOverride,\n    // Average fill density for dynamic opacity calculation.\n    averageFillDensity,\n  } = props;\n\n  const loaders = useLoaders();\n  const setComponentHover = useSetComponentHover();\n  const setComponentViewInfo = useSetComponentViewInfo(uuid);\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    embeddingZoom: zoom,\n    embeddingTargetX: targetX,\n    embeddingTargetY: targetY,\n    embeddingTargetZ: targetZ,\n    embeddingType: mapping,\n    cellFilter,\n    cellHighlight,\n    geneSelection,\n    cellSetSelection,\n    cellSetColor,\n    cellColorEncoding,\n    additionalCellSets,\n    embeddingCellSetPolygonsVisible: cellSetPolygonsVisible,\n    embeddingCellSetLabelsVisible: cellSetLabelsVisible,\n    embeddingCellSetLabelSize: cellSetLabelSize,\n    embeddingCellRadius: cellRadiusFixed,\n    embeddingCellRadiusMode: cellRadiusMode,\n    embeddingCellOpacity: cellOpacityFixed,\n    embeddingCellOpacityMode: cellOpacityMode,\n    geneExpressionColormap,\n    geneExpressionColormapRange,\n  }, {\n    setEmbeddingZoom: setZoom,\n    setEmbeddingTargetX: setTargetX,\n    setEmbeddingTargetY: setTargetY,\n    setEmbeddingTargetZ: setTargetZ,\n    setCellFilter,\n    setCellSetSelection,\n    setCellHighlight,\n    setCellSetColor,\n    setCellColorEncoding,\n    setAdditionalCellSets,\n    setEmbeddingCellSetPolygonsVisible: setCellSetPolygonsVisible,\n    setEmbeddingCellSetLabelsVisible: setCellSetLabelsVisible,\n    setEmbeddingCellSetLabelSize: setCellSetLabelSize,\n    setEmbeddingCellRadius: setCellRadiusFixed,\n    setEmbeddingCellRadiusMode: setCellRadiusMode,\n    setEmbeddingCellOpacity: setCellOpacityFixed,\n    setEmbeddingCellOpacityMode: setCellOpacityMode,\n    setGeneExpressionColormap,\n    setGeneExpressionColormapRange,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.scatterplot, coordinationScopes);\n\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [width, height, deckRef] = useDeckCanvasSize();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    SCATTERPLOT_DATA_TYPES,\n  );\n\n  const title = titleOverride || `Scatterplot (${mapping})`;\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [cells, cellsCount] = useCellsData(loaders, dataset, setItemIsReady, addUrl, true);\n  const [cellSets] = useCellSetsData(\n    loaders,\n    dataset,\n    setItemIsReady,\n    addUrl,\n    false,\n    { setCellSetSelection, setCellSetColor },\n    { cellSetSelection, cellSetColor },\n  );\n  const [expressionData] = useGeneSelection(\n    loaders, dataset, setItemIsReady, false, geneSelection, setItemIsNotReady,\n  );\n  const [attrs] = useExpressionAttrs(\n    loaders, dataset, setItemIsReady, addUrl, false,\n  );\n\n  const [dynamicCellRadius, setDynamicCellRadius] = useState(cellRadiusFixed);\n  const [dynamicCellOpacity, setDynamicCellOpacity] = useState(cellOpacityFixed);\n\n  const mergedCellSets = useMemo(() => mergeCellSets(\n    cellSets, additionalCellSets,\n  ), [cellSets, additionalCellSets]);\n\n  const setCellSelectionProp = useCallback((v) => {\n    setCellSelection(\n      v, additionalCellSets, cellSetColor,\n      setCellSetSelection, setAdditionalCellSets, setCellSetColor,\n      setCellColorEncoding,\n    );\n  }, [additionalCellSets, cellSetColor, setCellColorEncoding,\n    setAdditionalCellSets, setCellSetColor, setCellSetSelection]);\n\n  const cellColors = useMemo(() => getCellColors({\n    cellColorEncoding,\n    expressionData: expressionData && expressionData[0],\n    geneSelection,\n    cellSets: mergedCellSets,\n    cellSetSelection,\n    cellSetColor,\n    expressionDataAttrs: attrs,\n    theme,\n  }), [cellColorEncoding, geneSelection, mergedCellSets, theme,\n    cellSetSelection, cellSetColor, expressionData, attrs]);\n\n  // cellSetPolygonCache is an array of tuples like [(key0, val0), (key1, val1), ...],\n  // where the keys are cellSetSelection arrays.\n  const [cellSetPolygonCache, setCellSetPolygonCache] = useState([]);\n  const cacheHas = (cache, key) => cache.findIndex(el => isEqual(el[0], key)) !== -1;\n  const cacheGet = (cache, key) => cache.find(el => isEqual(el[0], key))?.[1];\n  const cellSetPolygons = useMemo(() => {\n    if ((cellSetLabelsVisible || cellSetPolygonsVisible)\n      && !cacheHas(cellSetPolygonCache, cellSetSelection)\n      && mergedCellSets?.tree?.length\n      && Object.values(cells).length\n      && cellSetColor?.length) {\n      const newCellSetPolygons = getCellSetPolygons({\n        cells,\n        mapping,\n        cellSets: mergedCellSets,\n        cellSetSelection,\n        cellSetColor,\n        theme,\n      });\n      setCellSetPolygonCache(cache => [...cache, [cellSetSelection, newCellSetPolygons]]);\n      return newCellSetPolygons;\n    }\n    return cacheGet(cellSetPolygonCache, cellSetSelection) || [];\n  }, [cellSetPolygonsVisible, cellSetPolygonCache, cellSetLabelsVisible, theme,\n    cells, mapping, mergedCellSets, cellSetSelection, cellSetColor]);\n\n\n  const cellSelection = useMemo(() => Array.from(cellColors.keys()), [cellColors]);\n\n  const [xRange, yRange, xExtent, yExtent, numCells] = useMemo(() => {\n    const cellValues = cells && Object.values(cells);\n    if (cellValues?.length) {\n      const cellCoordinates = Object.values(cells)\n        .map(c => c.mappings[mapping]);\n      const xE = extent(cellCoordinates, c => c[0]);\n      const yE = extent(cellCoordinates, c => c[1]);\n      const xR = xE[1] - xE[0];\n      const yR = yE[1] - yE[0];\n      return [xR, yR, xE, yE, cellValues.length];\n    }\n    return [null, null, null, null, null];\n  }, [cells, mapping]);\n\n  // After cells have loaded or changed,\n  // compute the cell radius scale based on the\n  // extents of the cell coordinates on the x/y axes.\n  useEffect(() => {\n    if (xRange && yRange) {\n      const pointSizeDevicePixels = getPointSizeDevicePixels(\n        window.devicePixelRatio, zoom, xRange, yRange, width, height,\n      );\n      setDynamicCellRadius(pointSizeDevicePixels);\n\n      const nextCellOpacityScale = getPointOpacity(\n        zoom, xRange, yRange, width, height, numCells, averageFillDensity,\n      );\n      setDynamicCellOpacity(nextCellOpacityScale);\n\n      if (typeof targetX !== 'number' || typeof targetY !== 'number') {\n        const newTargetX = xExtent[0] + xRange / 2;\n        const newTargetY = yExtent[0] + yRange / 2;\n        const newZoom = Math.log2(Math.min(width / xRange, height / yRange));\n        setTargetX(newTargetX);\n        // Graphics rendering has the y-axis going south so we need to multiply by negative one.\n        setTargetY(-newTargetY);\n        setZoom(newZoom);\n      }\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [xRange, yRange, xExtent, yExtent, numCells, cells, mapping,\n    width, height, zoom, averageFillDensity]);\n\n  const getCellInfo = useCallback((cellId) => {\n    const cellInfo = cells[cellId];\n    return {\n      [`${capitalize(observationsLabel)} ID`]: cellId,\n      ...(cellInfo ? cellInfo.factors : {}),\n    };\n  }, [cells, observationsLabel]);\n\n  const cellSelectionSet = useMemo(() => new Set(cellSelection), [cellSelection]);\n  const getCellIsSelected = useCallback(cellEntry => (\n    (cellSelectionSet || new Set([])).has(cellEntry[0]) ? 1.0 : 0.0), [cellSelectionSet]);\n\n  const cellRadius = (cellRadiusMode === 'manual' ? cellRadiusFixed : dynamicCellRadius);\n  const cellOpacity = (cellOpacityMode === 'manual' ? cellOpacityFixed : dynamicCellOpacity);\n\n  // Set up a getter function for gene expression values, to be used\n  // by the DeckGL layer to obtain values for instanced attributes.\n  const getExpressionValue = useExpressionValueGetter({ attrs, expressionData });\n\n  return (\n    <TitleInfo\n      title={title}\n      info={`${cellsCount} ${pluralize(observationsLabel, observationsPluralLabel, cellsCount)}`}\n      removeGridComponent={removeGridComponent}\n      urls={urls}\n      theme={theme}\n      isReady={isReady}\n      options={(\n        <ScatterplotOptions\n          observationsLabel={observationsLabel}\n          cellRadius={cellRadiusFixed}\n          setCellRadius={setCellRadiusFixed}\n          cellRadiusMode={cellRadiusMode}\n          setCellRadiusMode={setCellRadiusMode}\n          cellOpacity={cellOpacityFixed}\n          setCellOpacity={setCellOpacityFixed}\n          cellOpacityMode={cellOpacityMode}\n          setCellOpacityMode={setCellOpacityMode}\n          cellSetLabelsVisible={cellSetLabelsVisible}\n          setCellSetLabelsVisible={setCellSetLabelsVisible}\n          cellSetLabelSize={cellSetLabelSize}\n          setCellSetLabelSize={setCellSetLabelSize}\n          cellSetPolygonsVisible={cellSetPolygonsVisible}\n          setCellSetPolygonsVisible={setCellSetPolygonsVisible}\n          cellColorEncoding={cellColorEncoding}\n          setCellColorEncoding={setCellColorEncoding}\n          geneExpressionColormap={geneExpressionColormap}\n          setGeneExpressionColormap={setGeneExpressionColormap}\n          geneExpressionColormapRange={geneExpressionColormapRange}\n          setGeneExpressionColormapRange={setGeneExpressionColormapRange}\n        />\n      )}\n    >\n      <Scatterplot\n        ref={deckRef}\n        uuid={uuid}\n        theme={theme}\n        viewState={{ zoom, target: [targetX, targetY, targetZ] }}\n        setViewState={({ zoom: newZoom, target }) => {\n          setZoom(newZoom);\n          setTargetX(target[0]);\n          setTargetY(target[1]);\n          setTargetZ(target[2] || 0);\n        }}\n        cells={cells}\n        mapping={mapping}\n        cellFilter={cellFilter}\n        cellSelection={cellSelection}\n        cellHighlight={cellHighlight}\n        cellColors={cellColors}\n        cellSetPolygons={cellSetPolygons}\n        cellSetLabelSize={cellSetLabelSize}\n        cellSetLabelsVisible={cellSetLabelsVisible}\n        cellSetPolygonsVisible={cellSetPolygonsVisible}\n        setCellFilter={setCellFilter}\n        setCellSelection={setCellSelectionProp}\n        setCellHighlight={setCellHighlight}\n        cellRadius={cellRadius}\n        cellOpacity={cellOpacity}\n        cellColorEncoding={cellColorEncoding}\n        geneExpressionColormap={geneExpressionColormap}\n        geneExpressionColormapRange={geneExpressionColormapRange}\n        setComponentHover={() => {\n          setComponentHover(uuid);\n        }}\n        updateViewInfo={setComponentViewInfo}\n        getExpressionValue={getExpressionValue}\n        getCellIsSelected={getCellIsSelected}\n\n      />\n      {!disableTooltip && (\n      <ScatterplotTooltipSubscriber\n        parentUuid={uuid}\n        cellHighlight={cellHighlight}\n        width={width}\n        height={height}\n        getCellInfo={getCellInfo}\n      />\n      )}\n    </TitleInfo>\n  );\n}\n","import React, { forwardRef } from 'react';\nimport isEqual from 'lodash/isEqual';\nimport { COORDINATE_SYSTEM } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport { PolygonLayer, ScatterplotLayer } from '@deck.gl/layers'; // eslint-disable-line import/no-extraneous-dependencies\nimport { Matrix4 } from 'math.gl';\nimport {\n  ScaleBarLayer,\n  MultiscaleImageLayer,\n  AdditiveColormapExtension,\n  ColorPaletteExtension,\n} from '@hms-dbmi/viv';\nimport { getSelectionLayers } from '../../layers';\nimport { cellLayerDefaultProps, PALETTE, getDefaultColor } from '../utils';\nimport { getSourceFromLoader } from '../../utils';\nimport { square, getLayerLoaderTuple, renderSubBitmaskLayers } from './utils';\nimport AbstractSpatialOrScatterplot from '../shared-spatial-scatterplot/AbstractSpatialOrScatterplot';\nimport { createCellsQuadTree } from '../shared-spatial-scatterplot/quadtree';\nimport { ScaledExpressionExtension } from '../../layer-extensions';\n\nconst CELLS_LAYER_ID = 'cells-layer';\nconst MOLECULES_LAYER_ID = 'molecules-layer';\nconst NEIGHBORHOODS_LAYER_ID = 'neighborhoods-layer';\n\n// Default getter function props.\nconst defaultGetCellCoords = cell => cell.xy;\nconst makeDefaultGetCellPolygon = radius => (cellEntry) => {\n  const cell = cellEntry[1];\n  return cell.poly?.length ? cell.poly : square(cell.xy[0], cell.xy[1], radius);\n};\nconst makeDefaultGetCellColors = (cellColors, theme) => (cellEntry) => {\n  const [r, g, b, a] = (cellColors && cellColors.get(cellEntry[0])) || getDefaultColor(theme);\n  return [r, g, b, 255 * (a || 1)];\n};\nconst makeDefaultGetCellIsSelected = (cellSelection) => {\n  if (cellSelection) {\n    // For performance, convert the Array to a Set instance.\n    // Set.has() is faster than Array.includes().\n    const cellSelectionSet = new Set(cellSelection);\n    return cellEntry => (cellSelectionSet.has(cellEntry[0]) ? 1.0 : 0.0);\n  }\n  return () => 0.0;\n};\n\n/**\n * React component which expresses the spatial relationships between cells and molecules.\n * @param {object} props\n * @param {string} props.uuid A unique identifier for this component,\n * used to determine when to show tooltips vs. crosshairs.\n * @param {number} props.height Height of the DeckGL canvas, used when\n * rendering the scale bar layer.\n * @param {number} props.width Width of the DeckGL canvas, used when\n * rendering the scale bar layer.\n * @param {object} props.viewState The DeckGL viewState object.\n * @param {function} props.setViewState A handler for updating the DeckGL\n * viewState object.\n * @param {object} props.molecules Molecules data.\n * @param {object} props.cells Cells data.\n * @param {object} props.neighborhoods Neighborhoods data.\n * @param {number} props.lineWidthScale Width of cell border in view space (deck.gl).\n * @param {number} props.lineWidthMaxPixels Max width of the cell border in pixels (deck.gl).\n * @param {object} props.imageLayerLoaders An object mapping raster layer index to Viv loader\n * instances.\n * @param {object} props.cellColors Map from cell IDs to colors [r, g, b].\n * @param {function} props.getCellCoords Getter function for cell coordinates\n * (used by the selection layer).\n * @param {function} props.getCellColor Getter function for cell color as [r, g, b] array.\n * @param {function} props.getCellPolygon Getter function for cell polygons.\n * @param {function} props.getCellIsSelected Getter function for cell layer isSelected.\n * @param {function} props.getMoleculeColor\n * @param {function} props.getMoleculePosition\n * @param {function} props.getNeighborhoodPolygon\n * @param {function} props.updateViewInfo Handler for DeckGL viewport updates,\n * used when rendering tooltips and crosshairs.\n * @param {function} props.onCellClick Getter function for cell layer onClick.\n * @param {string} props.theme \"light\" or \"dark\" for the vitessce theme\n */\nclass Spatial extends AbstractSpatialOrScatterplot {\n  constructor(props) {\n    super(props);\n\n    // To avoid storing large arrays/objects\n    // in React state, this component\n    // uses instance variables.\n    // All instance variables used in this class:\n    this.cellsEntries = [];\n    this.moleculesEntries = [];\n    this.cellsQuadTree = null;\n    this.cellsLayer = null;\n    this.moleculesLayer = null;\n    this.neighborhoodsLayer = null;\n    this.imageLayers = [];\n    this.layerLoaderSelections = {};\n    // Better for the bitmask layer when there is no color data to use this.\n    // 2048 is best for performance and for stability (4096 texture size is not always supported).\n    this.randomColorData = {\n      data: new Uint8Array(2048 * 2048 * 3)\n        .map((_, j) => (j < 4 ? 0 : Math.round(255 * Math.random()))),\n      // This buffer should be able to hold colors for 2048 x 2048 ~ 4 million cells.\n      height: 2048,\n      width: 2048,\n    };\n    this.color = { ...this.randomColorData };\n    this.expression = {\n      data: new Uint8Array(2048 * 2048),\n      // This buffer should be able to hold colors for 2048 x 2048 ~ 4 million cells.\n      height: 2048,\n      width: 2048,\n    };\n\n    // Initialize data and layers.\n    this.onUpdateCellsData();\n    this.onUpdateCellsLayer();\n    this.onUpdateMoleculesData();\n    this.onUpdateMoleculesLayer();\n    this.onUpdateNeighborhoodsData();\n    this.onUpdateNeighborhoodsLayer();\n    this.onUpdateImages();\n  }\n\n  createCellsLayer(layerDef) {\n    const {\n      radius, stroked, visible, opacity,\n    } = layerDef;\n    const { cellsEntries } = this;\n    const {\n      theme,\n      cellFilter,\n      cellSelection,\n      setCellHighlight,\n      setComponentHover,\n      getCellIsSelected = makeDefaultGetCellIsSelected(\n        cellsEntries.length === cellSelection.length ? null : cellSelection,\n      ),\n      cellColors,\n      getCellColor = makeDefaultGetCellColors(cellColors, theme),\n      getCellPolygon = makeDefaultGetCellPolygon(radius),\n      onCellClick,\n      lineWidthScale = 10,\n      lineWidthMaxPixels = 2,\n      geneExpressionColormapRange,\n      cellColorEncoding,\n      getExpressionValue,\n      geneExpressionColormap,\n    } = this.props;\n    const filteredCellsEntries = cellFilter\n      ? cellsEntries.filter(cellEntry => cellFilter.includes(cellEntry[0]))\n      : cellsEntries;\n\n    // Graphics rendering has the y-axis positive going south,\n    // so we need to flip it for rendering tooltips.\n    const flipYTooltip = true;\n\n    return new PolygonLayer({\n      id: CELLS_LAYER_ID,\n      backgroundColor: [0, 0, 0],\n      isSelected: getCellIsSelected,\n      getPolygon: getCellPolygon,\n      updateTriggers: {\n        getLineWidth: [stroked],\n        isSelected: cellSelection,\n        getExpressionValue,\n        getFillColor: [opacity, cellColorEncoding, cellSelection, cellColors],\n        getLineColor: [cellColorEncoding, cellSelection, cellColors],\n      },\n      getFillColor: (cellEntry) => {\n        const color = getCellColor(cellEntry);\n        color[3] = opacity * 255;\n        return color;\n      },\n      getLineColor: (cellEntry) => {\n        const color = getCellColor(cellEntry);\n        color[3] = 255;\n        return color;\n      },\n      onClick: (info) => {\n        if (onCellClick) {\n          onCellClick(info);\n        }\n      },\n      visible,\n      getLineWidth: stroked ? 1 : 0,\n      lineWidthScale,\n      lineWidthMaxPixels,\n      getExpressionValue,\n      extensions: [new ScaledExpressionExtension()],\n      colorScaleLo: geneExpressionColormapRange[0],\n      colorScaleHi: geneExpressionColormapRange[1],\n      isExpressionMode: cellColorEncoding === 'geneSelection',\n      colormap: geneExpressionColormap,\n      ...cellLayerDefaultProps(\n        filteredCellsEntries,\n        undefined,\n        setCellHighlight,\n        setComponentHover,\n        flipYTooltip,\n      ),\n    });\n  }\n\n  createMoleculesLayer(layerDef) {\n    const {\n      setMoleculeHighlight,\n      getMoleculeColor = d => PALETTE[d[2] % PALETTE.length],\n      getMoleculePosition = d => [d[0], d[1], 0],\n    } = this.props;\n    const { moleculesEntries } = this;\n\n    return new ScatterplotLayer({\n      id: MOLECULES_LAYER_ID,\n      coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n      data: moleculesEntries,\n      pickable: true,\n      autoHighlight: true,\n      radiusMaxPixels: 3,\n      opacity: layerDef.opacity,\n      visible: layerDef.visible,\n      getRadius: layerDef.radius,\n      getPosition: getMoleculePosition,\n      getLineColor: getMoleculeColor,\n      getFillColor: getMoleculeColor,\n      onHover: (info) => {\n        if (setMoleculeHighlight) {\n          if (info.object) {\n            setMoleculeHighlight(info.object[3]);\n          } else {\n            setMoleculeHighlight(null);\n          }\n        }\n      },\n    });\n  }\n\n  createNeighborhoodsLayer(layerDef) {\n    const {\n      getNeighborhoodPolygon = (neighborhoodsEntry) => {\n        const neighborhood = neighborhoodsEntry[1];\n        return neighborhood.poly;\n      },\n    } = this.props;\n    const { neighborhoodsEntries } = this;\n\n    return new PolygonLayer({\n      id: NEIGHBORHOODS_LAYER_ID,\n      getPolygon: getNeighborhoodPolygon,\n      coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,\n      data: neighborhoodsEntries,\n      pickable: true,\n      autoHighlight: true,\n      stroked: true,\n      filled: false,\n      getElevation: 0,\n      getLineWidth: 10,\n      visible: layerDef.visible,\n    });\n  }\n\n  createSelectionLayers() {\n    const {\n      viewState,\n      getCellCoords = defaultGetCellCoords,\n      setCellSelection,\n    } = this.props;\n    const { tool } = this.state;\n    const { cellsQuadTree } = this;\n    return getSelectionLayers(\n      tool,\n      viewState.zoom,\n      CELLS_LAYER_ID,\n      getCellCoords,\n      setCellSelection,\n      cellsQuadTree,\n    );\n  }\n\n  createScaleBarLayer() {\n    const {\n      viewState,\n      width,\n      height,\n      imageLayerLoaders = {},\n      layers,\n    } = this.props;\n    const use3d = (layers || []).some(i => i.use3d);\n    // Just get the first layer/loader since they should all be spatially\n    // resolved and therefore have the same unit size scale.\n    const loaders = Object.values(imageLayerLoaders);\n    if (!viewState || !width || !height || loaders.length < 1) return null;\n    const loader = loaders[0];\n    if (!loader) return null;\n    const source = getSourceFromLoader(loader);\n    if (!source.meta) return null;\n    const { physicalSizes } = source.meta;\n    if (physicalSizes && !use3d) {\n      const { x } = physicalSizes;\n      const { unit, size } = x;\n      if (unit && size) {\n        return new ScaleBarLayer({\n          id: 'scalebar-layer',\n          unit,\n          size,\n          viewState: { ...viewState, width, height },\n        });\n      }\n      return null;\n    }\n    return null;\n  }\n\n  createImageLayer(rawLayerDef, loader, i) {\n    const layerDef = {\n      ...rawLayerDef,\n      channels: rawLayerDef.channels.filter(\n        channel => channel.selection && channel.color && channel.slider,\n      ),\n    };\n\n    // We need to keep the same selections array reference,\n    // otherwise the Viv layer will not be re-used as we want it to,\n    // since selections is one of its `updateTriggers`.\n    // Reference: https://github.com/hms-dbmi/viv/blob/ad86d0f/src/layers/MultiscaleImageLayer/MultiscaleImageLayer.js#L127\n    let selections;\n    const nextLoaderSelection = layerDef.channels.map(c => c.selection);\n    const prevLoaderSelection = this.layerLoaderSelections[layerDef.index];\n    if (isEqual(prevLoaderSelection, nextLoaderSelection)) {\n      selections = prevLoaderSelection;\n    } else {\n      selections = nextLoaderSelection;\n      this.layerLoaderSelections[layerDef.index] = nextLoaderSelection;\n    }\n    const useTransparentColor = (!layerDef.visible\n      && typeof layerDef.visible === 'boolean')\n      || Boolean(layerDef.transparentColor);\n    const transparentColor = useTransparentColor ? [0, 0, 0] : null;\n    const layerProps = {\n      colormap: layerDef.colormap,\n      opacity: layerDef.opacity,\n      useTransparentColor,\n      transparentColor,\n      colors: layerDef.channels.map(c => c.color),\n      sliders: layerDef.channels.map(c => c.slider),\n      resolution: layerDef.resolution,\n      renderingMode: layerDef.renderingMode,\n      xSlice: layerDef.xSlice,\n      ySlice: layerDef.ySlice,\n      zSlice: layerDef.zSlice,\n      callback: layerDef.callback,\n      visibilities: layerDef.channels.map(c => (!layerDef.visible && typeof layerDef.visible === 'boolean'\n        ? false\n        : c.visible)),\n    };\n\n    if (!loader || !layerProps) return null;\n    const {\n      metadata: { transform },\n      data,\n    } = loader;\n    let modelMatrix;\n    if (transform) {\n      const { scale, translate } = transform;\n      modelMatrix = new Matrix4()\n        .translate([translate.x, translate.y, 0])\n        .scale(scale);\n    } else if (layerDef.modelMatrix) {\n      // eslint-disable-next-line prefer-destructuring\n      modelMatrix = new Matrix4(layerDef.modelMatrix);\n    }\n    if (rawLayerDef.type === 'bitmask') {\n      const {\n        geneExpressionColormap,\n        geneExpressionColormapRange = [0.0, 1.0],\n        cellColorEncoding,\n      } = this.props;\n      return new MultiscaleImageLayer({\n        // `bitmask` is used by the AbstractSpatialOrScatterplot\n        // https://github.com/vitessce/vitessce/pull/927/files#diff-9cab35a2ca0c5b6d9754b177810d25079a30ca91efa062d5795181360bc3ff2cR111\n        id: `bitmask-layer-${layerDef.index}-${i}`,\n        channelsVisible: layerProps.visibilities,\n        opacity: layerProps.opacity,\n        modelMatrix,\n        hoveredCell: Number(this.props.cellHighlight),\n        renderSubLayers: renderSubBitmaskLayers,\n        loader: data,\n        selections,\n        // For some reason, deck.gl doesn't recognize the prop diffing\n        // unless these are separated out.  I don't think it's a bug, just\n        // has to do with the fact that we don't have it in the `defaultProps`,\n        // could be wrong though.\n        cellColorData: this.color.data,\n        cellTexHeight: this.color.height,\n        cellTexWidth: this.color.width,\n        excludeBackground: true,\n        onViewportLoad: layerProps.callback,\n        colorScaleLo: geneExpressionColormapRange[0],\n        colorScaleHi: geneExpressionColormapRange[1],\n        isExpressionMode: cellColorEncoding === 'geneSelection',\n        colormap: geneExpressionColormap,\n        expressionData: this.expression.data,\n      });\n    }\n    const [Layer, layerLoader] = getLayerLoaderTuple(data, layerDef.use3d);\n\n    const extensions = (layerDef.use3d ? [] : [\n      ...(layerProps.colormap ? [\n        new AdditiveColormapExtension(),\n      ] : [\n        new ColorPaletteExtension(),\n      ]),\n    ]);\n\n    return new Layer({\n      loader: layerLoader,\n      id: `${layerDef.use3d ? 'volume' : 'image'}-layer-${layerDef.index}-${i}`,\n      colors: layerProps.colors,\n      contrastLimits: layerProps.sliders,\n      selections,\n      channelsVisible: layerProps.visibilities,\n      opacity: layerProps.opacity,\n      colormap: layerProps.colormap,\n      modelMatrix,\n      transparentColor: layerProps.transparentColor,\n      useTransparentColor: layerProps.useTransparentColor,\n      resolution: layerProps.resolution,\n      renderingMode: layerProps.renderingMode,\n      pickable: false,\n      xSlice: layerProps.xSlice,\n      ySlice: layerProps.ySlice,\n      zSlice: layerProps.zSlice,\n      onViewportLoad: layerProps.callback,\n      extensions,\n    });\n  }\n\n  createImageLayers() {\n    const {\n      layers,\n      imageLayerLoaders = {},\n      rasterLayersCallbacks = [],\n    } = this.props;\n    const use3d = (layers || []).some(i => i.use3d);\n    const use3dIndex = (layers || []).findIndex(i => i.use3d);\n    return (layers || [])\n      .filter(layer => layer.type === 'raster' || layer.type === 'bitmask')\n      .filter(layer => (use3d ? layer.use3d === use3d : true))\n      .map((layer, i) => this.createImageLayer(\n        { ...layer, callback: rasterLayersCallbacks[use3d ? use3dIndex : i] },\n        imageLayerLoaders[layer.index],\n        i,\n      ));\n  }\n\n  getLayers() {\n    const {\n      imageLayers, cellsLayer, neighborhoodsLayer, moleculesLayer,\n    } = this;\n    return [\n      ...imageLayers,\n      cellsLayer,\n      neighborhoodsLayer,\n      moleculesLayer,\n      this.createScaleBarLayer(),\n      ...this.createSelectionLayers(),\n    ];\n  }\n\n  onUpdateCellsData() {\n    const { cells = {}, getCellCoords = defaultGetCellCoords } = this.props;\n    const cellsEntries = Object.entries(cells);\n    this.cellsEntries = cellsEntries;\n    this.cellsQuadTree = createCellsQuadTree(cellsEntries, getCellCoords);\n  }\n\n  onUpdateCellsLayer() {\n    const { layers } = this.props;\n    const layerDef = (layers || []).find(layer => layer.type === 'cells');\n    if (layerDef) {\n      this.cellsLayer = this.createCellsLayer(layerDef);\n    } else {\n      this.cellsLayer = null;\n    }\n  }\n\n  onUpdateCellColors() {\n    const color = this.randomColorData;\n    const { size } = this.props.cellColors;\n    if (typeof size === 'number') {\n      const cellIds = this.props.cellColors.keys();\n      color.data = new Uint8Array(color.height * color.width * 3).fill(\n        getDefaultColor(this.props.theme)[0],\n      );\n      // 0th cell id is the empty space of the image i.e black color.\n      color.data[0] = 0;\n      color.data[1] = 0;\n      color.data[2] = 0;\n      // eslint-disable-next-line no-restricted-syntax\n      for (const id of cellIds) {\n        if (id > 0) {\n          const cellColor = this.props.cellColors.get(id);\n          if (cellColor) {\n            color.data.set(cellColor.slice(0, 3), Number(id) * 3);\n          }\n        }\n      }\n    }\n    this.color = color;\n  }\n\n  onUpdateExpressionData() {\n    const { expressionData } = this.props;\n    if (expressionData[0]?.length) {\n      this.expression.data = new Uint8Array(\n        this.expression.height * this.expression.width,\n      );\n      this.expression.data.set(expressionData[0]);\n    }\n  }\n\n  onUpdateMoleculesData() {\n    const { molecules = {} } = this.props;\n    const moleculesEntries = Object.entries(molecules).flatMap(\n      ([molecule, coords], index) => coords.map(([x, y]) => [x, y, index, molecule]),\n    );\n    this.moleculesEntries = moleculesEntries;\n  }\n\n  onUpdateMoleculesLayer() {\n    const { layers } = this.props;\n    const layerDef = (layers || []).find(layer => layer.type === 'molecules');\n    if (layerDef) {\n      this.moleculesLayer = this.createMoleculesLayer(layerDef);\n    } else {\n      this.moleculesLayer = null;\n    }\n  }\n\n  onUpdateNeighborhoodsData() {\n    const { neighborhoods = {} } = this.props;\n    const neighborhoodsEntries = Object.entries(neighborhoods);\n    this.neighborhoodsEntries = neighborhoodsEntries;\n  }\n\n  onUpdateNeighborhoodsLayer() {\n    const { layers } = this.props;\n    const layerDef = (layers || []).find(\n      layer => layer.type === 'neighborhoods',\n    );\n    if (layerDef) {\n      this.neighborhoodsLayer = this.createNeighborhoodsLayer(layerDef);\n    } else {\n      this.neighborhoodsLayer = null;\n    }\n  }\n\n  onUpdateImages() {\n    this.imageLayers = this.createImageLayers();\n  }\n\n  viewInfoDidUpdate() {\n    const { getCellCoords = defaultGetCellCoords } = this.props;\n    super.viewInfoDidUpdate(getCellCoords);\n  }\n\n  /**\n   * Here, asynchronously check whether props have\n   * updated which require re-computing memoized variables,\n   * followed by a re-render.\n   * This function does not follow React conventions or paradigms,\n   * it is only implemented this way to try to squeeze out\n   * performance.\n   * @param {object} prevProps The previous props to diff against.\n   */\n  componentDidUpdate(prevProps) {\n    this.viewInfoDidUpdate();\n\n    const shallowDiff = propName => prevProps[propName] !== this.props[propName];\n    if (['cells'].some(shallowDiff)) {\n      // Cells data changed.\n      this.onUpdateCellsData();\n      this.forceUpdate();\n    }\n\n    if (\n      [\n        'layers',\n        'cells',\n        'cellFilter',\n        'cellSelection',\n        'cellColors',\n        'geneExpressionColormapRange',\n        'cellColorEncoding',\n        'geneExpressionColormap',\n      ].some(shallowDiff)\n    ) {\n      // Cells layer props changed.\n      this.onUpdateCellsLayer();\n      this.forceUpdate();\n    }\n\n    if (['cellColors'].some(shallowDiff)) {\n      // Cells Color layer props changed.\n      this.onUpdateCellColors();\n      this.forceUpdate();\n    }\n\n    if (['expressionData'].some(shallowDiff)) {\n      // Expression data prop changed.\n      this.onUpdateExpressionData();\n      this.forceUpdate();\n    }\n\n    if (['molecules'].some(shallowDiff)) {\n      // Molecules data changed.\n      this.onUpdateMoleculesData();\n      this.forceUpdate();\n    }\n\n    if (['layers', 'molecules'].some(shallowDiff)) {\n      // Molecules layer props changed.\n      this.onUpdateMoleculesLayer();\n      this.forceUpdate();\n    }\n\n    if (['neighborhoods'].some(shallowDiff)) {\n      // Neighborhoods data changed.\n      this.onUpdateNeighborhoodsData();\n      this.forceUpdate();\n    }\n\n    if (['layers', 'neighborhoods'].some(shallowDiff)) {\n      // Neighborhoods layer props changed.\n      this.onUpdateNeighborhoodsLayer();\n      this.forceUpdate();\n    }\n\n    if (\n      [\n        'layers',\n        'imageLayerLoaders',\n        'cellColors',\n        'cellHighlight',\n        'geneExpressionColormapRange',\n        'expressionData',\n        'rasterLayersCallbacks',\n        'geneExpressionColormap',\n      ].some(shallowDiff)\n    ) {\n      // Image layers changed.\n      this.onUpdateImages();\n      this.forceUpdate();\n    }\n  }\n\n  // render() is implemented in the abstract parent class.\n}\n\n/**\n * Need this wrapper function here,\n * since we want to pass a forwardRef\n * so that outer components can\n * access the grandchild DeckGL ref,\n * but we are using a class component.\n */\nconst SpatialWrapper = forwardRef((props, deckRef) => (\n  <Spatial {...props} deckRef={deckRef} />\n));\nexport default SpatialWrapper;\n","import React, { useCallback } from 'react';\nimport debounce from 'lodash/debounce';\n\nimport Checkbox from '@material-ui/core/Checkbox';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableRow from '@material-ui/core/TableRow';\nimport Slider from '@material-ui/core/Slider';\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport { useStyles } from '../shared-plot-options/styles';\nimport OptionsContainer from '../shared-plot-options/OptionsContainer';\nimport CellColorEncodingOption from '../shared-plot-options/CellColorEncodingOption';\nimport OptionSelect from '../shared-plot-options/OptionSelect';\nimport { GLSL_COLORMAPS } from '../../layers/constants';\n\nconst useToggleStyles = makeStyles(() => createStyles({\n  cameraLabel: {\n    padding: '0px 0px 0px 16px',\n  },\n  box: {\n    padding: '0px',\n  },\n  button: {\n    padding: '0px 0px 0px 8px',\n  },\n}));\n\nconst ToggleFixedAxisButton = ({\n  setSpatialAxisFixed,\n  spatialAxisFixed,\n  use3d,\n}) => {\n  const classes = useToggleStyles();\n  return (\n    <TableRow>\n      <TableCell className={classes.cameraLabel}>\n      Fix Camera Axis\n      </TableCell>\n      <TableCell className={classes.box}>\n        <Checkbox\n          onClick={() => setSpatialAxisFixed(!spatialAxisFixed)}\n          disabled={!use3d}\n          checked={Boolean(spatialAxisFixed)}\n        />\n      </TableCell>\n    </TableRow>\n  );\n};\n\nexport default function SpatialOptions(props) {\n  const {\n    observationsLabel,\n    cellColorEncoding,\n    setCellColorEncoding,\n    setSpatialAxisFixed,\n    spatialAxisFixed,\n    use3d,\n    geneExpressionColormap,\n    setGeneExpressionColormap,\n    geneExpressionColormapRange,\n    setGeneExpressionColormapRange,\n    canShowExpressionOptions,\n    canShowColorEncodingOption,\n    canShow3DOptions,\n  } = props;\n\n  function handleGeneExpressionColormapChange(event) {\n    setGeneExpressionColormap(event.target.value);\n  }\n\n  function handleColormapRangeChange(event, value) {\n    setGeneExpressionColormapRange(value);\n  }\n  const handleColormapRangeChangeDebounced = useCallback(\n    debounce(handleColormapRangeChange, 5, { trailing: true }),\n    [handleColormapRangeChange],\n  );\n\n  const classes = useStyles();\n\n  return (\n    <OptionsContainer>\n      {canShowColorEncodingOption ? (\n        <CellColorEncodingOption\n          observationsLabel={observationsLabel}\n          cellColorEncoding={cellColorEncoding}\n          setCellColorEncoding={setCellColorEncoding}\n        />\n      ) : null}\n      {canShow3DOptions ? (\n        <ToggleFixedAxisButton\n          setSpatialAxisFixed={setSpatialAxisFixed}\n          spatialAxisFixed={spatialAxisFixed}\n          use3d={use3d}\n        />\n      ) : null}\n      {canShowExpressionOptions ? (\n        <>\n          <TableRow>\n            <TableCell className={classes.labelCell} htmlFor=\"gene-expression-colormap-select\">\n          Gene Expression Colormap\n            </TableCell>\n            <TableCell className={classes.inputCell}>\n              <OptionSelect\n                className={classes.select}\n                value={geneExpressionColormap}\n                onChange={handleGeneExpressionColormapChange}\n                inputProps={{\n                  id: 'gene-expression-colormap-select',\n                }}\n              >\n                {GLSL_COLORMAPS.map(cmap => (\n                  <option key={cmap} value={cmap}>{cmap}</option>\n                ))}\n              </OptionSelect>\n            </TableCell>\n          </TableRow>\n          <TableRow>\n            <TableCell className={classes.labelCell}>\n          Gene Expression Colormap Range\n            </TableCell>\n            <TableCell className={classes.inputCell}>\n              <Slider\n                classes={{ root: classes.slider, valueLabel: classes.sliderValueLabel }}\n                value={geneExpressionColormapRange}\n                onChange={handleColormapRangeChangeDebounced}\n                aria-labelledby=\"gene-expression-colormap-range-slider\"\n                valueLabelDisplay=\"auto\"\n                step={0.005}\n                min={0.0}\n                max={1.0}\n              />\n            </TableCell>\n          </TableRow>\n        </>\n      ) : null}\n    </OptionsContainer>\n  );\n}\n","import React from 'react';\nimport Tooltip2D from '../tooltip/Tooltip2D';\nimport TooltipContent from '../tooltip/TooltipContent';\nimport { useComponentHover, useComponentViewInfo } from '../../app/state/hooks';\n\nexport default function SpatialTooltipSubscriber(props) {\n  const {\n    parentUuid,\n    cellHighlight,\n    width,\n    height,\n    getCellInfo,\n  } = props;\n\n  const sourceUuid = useComponentHover();\n  const viewInfo = useComponentViewInfo(parentUuid);\n\n  const [cellInfo, x, y] = (cellHighlight && getCellInfo ? (\n    [\n      getCellInfo(cellHighlight),\n      ...(viewInfo && viewInfo.project ? viewInfo.project(cellHighlight) : [null, null]),\n    ]\n  ) : ([null, null, null]));\n\n  return (\n    (cellInfo ? (\n      <Tooltip2D\n        x={x}\n        y={y}\n        parentUuid={parentUuid}\n        sourceUuid={sourceUuid}\n        parentWidth={width}\n        parentHeight={height}\n      >\n        <TooltipContent info={cellInfo} />\n      </Tooltip2D>\n    ) : null)\n  );\n}\n","import React, { useEffect, useMemo, useCallback } from 'react';\nimport TitleInfo from '../TitleInfo';\nimport { capitalize } from '../../utils';\nimport {\n  useDeckCanvasSize, useReady, useUrls, useExpressionValueGetter,\n} from '../hooks';\nimport { setCellSelection, mergeCellSets, canLoadResolution } from '../utils';\nimport {\n  useCellsData,\n  useCellSetsData,\n  useGeneSelection,\n  useMoleculesData,\n  useNeighborhoodsData,\n  useRasterData,\n  useExpressionAttrs,\n} from '../data-hooks';\nimport { getCellColors } from '../interpolate-colors';\nimport Spatial from './Spatial';\nimport SpatialOptions from './SpatialOptions';\nimport SpatialTooltipSubscriber from './SpatialTooltipSubscriber';\nimport { makeSpatialSubtitle, getInitialSpatialTargets } from './utils';\nimport {\n  useCoordination,\n  useLoaders,\n  useSetComponentHover,\n  useSetComponentViewInfo,\n  useAuxiliaryCoordination,\n} from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\n\nconst SPATIAL_DATA_TYPES = [\n  'cells', 'molecules', 'raster', 'cell-sets', 'expression-matrix',\n];\n\n/**\n * A subscriber component for the spatial plot.\n * @param {object} props\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n */\nexport default function SpatialSubscriber(props) {\n  const {\n    uuid,\n    coordinationScopes,\n    removeGridComponent,\n    observationsLabelOverride: observationsLabel = 'cell',\n    observationsPluralLabelOverride: observationsPluralLabel = `${observationsLabel}s`,\n    subobservationsLabelOverride: subobservationsLabel = 'molecule',\n    subobservationsPluralLabelOverride: subobservationsPluralLabel = `${subobservationsLabel}s`,\n    theme,\n    disableTooltip = false,\n    title = 'Spatial',\n    disable3d,\n    globalDisable3d,\n  } = props;\n\n  const loaders = useLoaders();\n  const setComponentHover = useSetComponentHover();\n  const setComponentViewInfo = useSetComponentViewInfo(uuid);\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    spatialZoom: zoom,\n    spatialTargetX: targetX,\n    spatialTargetY: targetY,\n    spatialTargetZ: targetZ,\n    spatialRotationX: rotationX,\n    spatialRotationY: rotationY,\n    spatialRotationZ: rotationZ,\n    spatialRotationOrbit: rotationOrbit,\n    spatialOrbitAxis: orbitAxis,\n    spatialRasterLayers: rasterLayers,\n    spatialCellsLayer: cellsLayer,\n    spatialMoleculesLayer: moleculesLayer,\n    spatialNeighborhoodsLayer: neighborhoodsLayer,\n    cellFilter,\n    cellHighlight,\n    geneSelection,\n    cellSetSelection,\n    cellSetColor,\n    cellColorEncoding,\n    additionalCellSets,\n    spatialAxisFixed,\n    geneExpressionColormap,\n    geneExpressionColormapRange,\n  }, {\n    setSpatialZoom: setZoom,\n    setSpatialTargetX: setTargetX,\n    setSpatialTargetY: setTargetY,\n    setSpatialTargetZ: setTargetZ,\n    setSpatialRotationX: setRotationX,\n    setSpatialRotationOrbit: setRotationOrbit,\n    setSpatialOrbitAxis: setOrbitAxis,\n    setSpatialRasterLayers: setRasterLayers,\n    setSpatialCellsLayer: setCellsLayer,\n    setSpatialMoleculesLayer: setMoleculesLayer,\n    setSpatialNeighborhoodsLayer: setNeighborhoodsLayer,\n    setCellFilter,\n    setCellSetSelection,\n    setCellHighlight,\n    setCellSetColor,\n    setCellColorEncoding,\n    setAdditionalCellSets,\n    setMoleculeHighlight,\n    setSpatialAxisFixed,\n    setGeneExpressionColormap,\n    setGeneExpressionColormapRange,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.spatial, coordinationScopes);\n\n  const [\n    {\n      rasterLayersCallbacks,\n    },\n  ] = useAuxiliaryCoordination(\n    COMPONENT_COORDINATION_TYPES.layerController,\n    coordinationScopes,\n  );\n\n  const use3d = rasterLayers?.some(l => l.use3d);\n\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady,\n    resetReadyItems,\n  ] = useReady(\n    SPATIAL_DATA_TYPES,\n  );\n  const [width, height, deckRef] = useDeckCanvasSize();\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  // Also clear the array of automatically-initialized layers.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [cells, cellsCount] = useCellsData(\n    loaders, dataset, setItemIsReady, addUrl, false,\n    { setSpatialCellsLayer: setCellsLayer },\n    { spatialCellsLayer: cellsLayer },\n  );\n  const [molecules, moleculesCount, locationsCount] = useMoleculesData(\n    loaders, dataset, setItemIsReady, addUrl, false,\n    { setSpatialMoleculesLayer: setMoleculesLayer },\n    { spatialMoleculesLayer: moleculesLayer },\n  );\n  const [neighborhoods] = useNeighborhoodsData(\n    loaders, dataset, setItemIsReady, addUrl, false,\n    { setSpatialNeighborhoodsLayer: setNeighborhoodsLayer },\n    { spatialNeighborhoodsLayer: neighborhoodsLayer },\n  );\n  const [cellSets] = useCellSetsData(\n    loaders, dataset, setItemIsReady, addUrl, false,\n    { setCellSetSelection, setCellSetColor },\n    { cellSetSelection, cellSetColor },\n  );\n  const [expressionData] = useGeneSelection(\n    loaders, dataset, setItemIsReady, false, geneSelection, setItemIsNotReady,\n  );\n  const [attrs] = useExpressionAttrs(\n    loaders, dataset, setItemIsReady, addUrl, false,\n  );\n  // eslint-disable-next-line no-unused-vars\n  const [raster, imageLayerLoaders, imageLayerMeta] = useRasterData(\n    loaders, dataset, setItemIsReady, addUrl, false,\n    { setSpatialRasterLayers: setRasterLayers },\n    { spatialRasterLayers: rasterLayers },\n  );\n\n  const layers = useMemo(() => {\n    // Only want to pass in cells layer once if there is not `bitmask`.\n    // We pass in the cells data regardless because it is needed for selection,\n    // but the rendering layer itself is not needed.\n    const canPassInCellsLayer = !imageLayerMeta.some(l => l?.metadata?.isBitmask);\n    return [\n      ...(moleculesLayer ? [{ ...moleculesLayer, type: 'molecules' }] : []),\n      ...((cellsLayer && canPassInCellsLayer) ? [{ ...cellsLayer, type: 'cells' }] : []),\n      ...(neighborhoodsLayer ? [{ ...neighborhoodsLayer, type: 'neighborhoods' }] : []),\n      ...(rasterLayers ? rasterLayers.map(l => ({ ...l, type: (l.type && ['raster', 'bitmask'].includes(l.type) ? l.type : 'raster') })) : []),\n    ];\n  }, [cellsLayer, moleculesLayer, neighborhoodsLayer, rasterLayers, imageLayerMeta]);\n\n  useEffect(() => {\n    if ((typeof targetX !== 'number' || typeof targetY !== 'number')) {\n      const {\n        initialTargetX, initialTargetY, initialTargetZ, initialZoom,\n      } = getInitialSpatialTargets({\n        width,\n        height,\n        cells,\n        imageLayerLoaders,\n        useRaster: Boolean(loaders[dataset].loaders.raster),\n        use3d,\n      });\n      setTargetX(initialTargetX);\n      setTargetY(initialTargetY);\n      setTargetZ(initialTargetZ);\n      setZoom(initialZoom);\n    }\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [imageLayerLoaders, cells, targetX, targetY, setTargetX, setTargetY, setZoom, use3d]);\n\n  const mergedCellSets = useMemo(() => mergeCellSets(\n    cellSets, additionalCellSets,\n  ), [cellSets, additionalCellSets]);\n\n  const setCellSelectionProp = useCallback((v) => {\n    setCellSelection(\n      v, additionalCellSets, cellSetColor,\n      setCellSetSelection, setAdditionalCellSets, setCellSetColor,\n      setCellColorEncoding,\n    );\n  }, [additionalCellSets, cellSetColor, setCellColorEncoding,\n    setAdditionalCellSets, setCellSetColor, setCellSetSelection]);\n\n  const cellColors = useMemo(() => getCellColors({\n    cellColorEncoding,\n    expressionData: expressionData && expressionData[0],\n    geneSelection,\n    cellSets: mergedCellSets,\n    cellSetSelection,\n    cellSetColor,\n    expressionDataAttrs: attrs,\n    theme,\n  }), [cellColorEncoding, geneSelection, mergedCellSets, theme,\n    cellSetColor, cellSetSelection, expressionData, attrs]);\n\n  // The bitmask layer needs access to a array (i.e a texture) lookup of cell -> expression value\n  // where each cell id indexes into the array.\n  // Cell ids in `attrs.rows` do not necessaryily correspond to indices in that array, though,\n  // so we create a \"shifted\" array where this is the case.\n  const shiftedExpressionDataForBitmask = useMemo(() => {\n    const hasBitmask = imageLayerMeta.some(l => l?.metadata?.isBitmask);\n    if (attrs?.rows && expressionData && hasBitmask) {\n      const maxId = attrs.rows.reduce((max, curr) => Math.max(max, Number(curr)));\n      const result = new Uint8Array(maxId + 1);\n      // eslint-disable-next-line no-plusplus\n      for (let i = 0; i < attrs.rows.length; i++) {\n        const id = attrs.rows[i];\n        result.set(expressionData[0].slice(i, i + 1), Number(id));\n      }\n      return [result];\n    } return [new Uint8Array()];\n  }, [attrs, expressionData, imageLayerMeta]);\n\n  const cellSelection = useMemo(() => Array.from(cellColors.keys()), [cellColors]);\n\n  const getCellInfo = (cellId) => {\n    const cell = cells[cellId];\n    if (cell) {\n      return {\n        [`${capitalize(observationsLabel)} ID`]: cellId,\n        ...cell.factors,\n      };\n    }\n    return null;\n  };\n\n  const setViewState = ({\n    zoom: newZoom,\n    target,\n    rotationX: newRotationX,\n    rotationOrbit: newRotationOrbit,\n    orbitAxis: newOrbitAxis,\n  }) => {\n    setZoom(newZoom);\n    setTargetX(target[0]);\n    setTargetY(target[1]);\n    setTargetZ(target[2] || null);\n    setRotationX(newRotationX);\n    setRotationOrbit(newRotationOrbit);\n    setOrbitAxis(newOrbitAxis || null);\n  };\n\n  const subtitle = makeSpatialSubtitle({\n    observationsCount: cellsCount,\n    observationsLabel,\n    observationsPluralLabel,\n    subobservationsCount: moleculesCount,\n    subobservationsLabel,\n    subobservationsPluralLabel,\n    locationsCount,\n  });\n\n  // Set up a getter function for gene expression values, to be used\n  // by the DeckGL layer to obtain values for instanced attributes.\n  const getExpressionValue = useExpressionValueGetter({ attrs, expressionData });\n  const hasExpressionData = loaders[dataset].loaders['expression-matrix'];\n  const hasCellsData = loaders[dataset].loaders.cells\n    || imageLayerMeta.some(l => l?.metadata?.isBitmask);\n  const canLoad3DLayers = imageLayerLoaders.some(loader => Boolean(\n    Array.from({\n      length: loader.data.length,\n    }).filter((_, res) => canLoadResolution(loader.data, res)).length,\n  ));\n  // Only show 3D options if we can theoretically load the data and it is allowed to be loaded.\n  const canShow3DOptions = canLoad3DLayers\n    && !(disable3d?.length === imageLayerLoaders.length) && !globalDisable3d;\n\n  return (\n    <TitleInfo\n      title={title}\n      info={subtitle}\n      isSpatial\n      urls={urls}\n      theme={theme}\n      removeGridComponent={removeGridComponent}\n      isReady={isReady}\n      options={\n        // Only show button if there is expression or 3D data because only cells data\n        // does not have any options (i.e for color encoding, you need to switch to expression data)\n        canShow3DOptions || hasExpressionData ? (\n          <SpatialOptions\n            observationsLabel={observationsLabel}\n            cellColorEncoding={cellColorEncoding}\n            setCellColorEncoding={setCellColorEncoding}\n            setSpatialAxisFixed={setSpatialAxisFixed}\n            spatialAxisFixed={spatialAxisFixed}\n            use3d={use3d}\n            geneExpressionColormap={geneExpressionColormap}\n            setGeneExpressionColormap={setGeneExpressionColormap}\n            geneExpressionColormapRange={geneExpressionColormapRange}\n            setGeneExpressionColormapRange={setGeneExpressionColormapRange}\n            canShowExpressionOptions={hasExpressionData}\n            canShowColorEncodingOption={hasCellsData && hasExpressionData}\n            canShow3DOptions={canShow3DOptions}\n          />\n        ) : null\n      }\n    >\n      <Spatial\n        ref={deckRef}\n        uuid={uuid}\n        width={width}\n        height={height}\n        viewState={{\n          zoom,\n          target: [targetX, targetY, targetZ],\n          rotationX,\n          rotationY,\n          rotationZ,\n          rotationOrbit,\n          orbitAxis,\n        }}\n        setViewState={setViewState}\n        layers={layers}\n        cells={cells}\n        cellFilter={cellFilter}\n        cellSelection={cellSelection}\n        cellHighlight={cellHighlight}\n        cellColors={cellColors}\n        molecules={molecules}\n        neighborhoods={neighborhoods}\n        imageLayerLoaders={imageLayerLoaders}\n        setCellFilter={setCellFilter}\n        setCellSelection={setCellSelectionProp}\n        setCellHighlight={setCellHighlight}\n        setMoleculeHighlight={setMoleculeHighlight}\n        setComponentHover={() => {\n          setComponentHover(uuid);\n        }}\n        updateViewInfo={setComponentViewInfo}\n        rasterLayersCallbacks={rasterLayersCallbacks}\n        spatialAxisFixed={spatialAxisFixed}\n        geneExpressionColormap={geneExpressionColormap}\n        geneExpressionColormapRange={geneExpressionColormapRange}\n        expressionData={shiftedExpressionDataForBitmask}\n        cellColorEncoding={cellColorEncoding}\n        getExpressionValue={getExpressionValue}\n        theme={theme}\n      />\n      {!disableTooltip && (\n        <SpatialTooltipSubscriber\n          parentUuid={uuid}\n          cellHighlight={cellHighlight}\n          width={width}\n          height={height}\n          getCellInfo={getCellInfo}\n        />\n      )}\n    </TitleInfo>\n  );\n}\n","import clamp from 'lodash/clamp';\nimport range from 'lodash/range';\n\nimport {\n  AXIS_LABEL_TEXT_SIZE,\n  AXIS_MIN_SIZE,\n  AXIS_MAX_SIZE,\n} from '../../layers/heatmap-constants';\n\nexport function getGeneByCellTile(view, {\n  tileSize, tileI, tileJ, numCells, numGenes, cellOrdering, cells,\n}) {\n  const tileData = new Uint8Array(tileSize * tileSize);\n  let offset;\n  let value;\n  let cellI;\n  let geneI;\n  let sortedCellI;\n\n  const tileSizeRange = range(tileSize);\n\n  tileSizeRange.forEach((j) => {\n    // Need to iterate over cells in the outer loop.\n    cellI = (tileJ * tileSize) + j;\n    if (cellI < numCells) {\n      sortedCellI = cells.indexOf(cellOrdering[cellI]);\n      if (sortedCellI >= -1) {\n        tileSizeRange.forEach((i) => {\n          geneI = (tileI * tileSize) + i;\n          value = view[sortedCellI * numGenes + geneI];\n          offset = ((tileSize - i - 1) * tileSize + j);\n          tileData[offset] = value;\n        });\n      }\n    }\n  });\n  return tileData;\n}\n\nexport function getCellByGeneTile(view, {\n  tileSize, tileI, tileJ, numCells, numGenes, cellOrdering, cells,\n}) {\n  const tileData = new Uint8Array(tileSize * tileSize);\n  let offset;\n  let value;\n  let cellI;\n  let geneI;\n  let sortedCellI;\n\n  const tileSizeRange = range(tileSize);\n\n  tileSizeRange.forEach((i) => {\n    // Need to iterate over cells in the outer loop.\n    cellI = (tileI * tileSize) + i;\n    if (cellI < numCells) {\n      sortedCellI = cells.indexOf(cellOrdering[cellI]);\n      if (sortedCellI >= -1) {\n        tileSizeRange.forEach((j) => {\n          geneI = (tileJ * tileSize) + j;\n          if (geneI < numGenes) {\n            value = view[sortedCellI * numGenes + geneI];\n          } else {\n            value = 0;\n          }\n          offset = ((tileSize - i - 1) * tileSize + j);\n          tileData[offset] = value;\n        });\n      }\n    }\n  });\n\n  return tileData;\n}\n\n/**\n * Called before a layer is drawn to determine whether it should be rendered.\n * Reference: https://deck.gl/docs/api-reference/core/deck#layerfilter\n * @param {object} params A viewport, layer pair.\n * @param {object} params.layer The layer to check.\n * @param {object} params.viewport The viewport to check.\n * @returns {boolean} Should this layer be rendered in this viewport?\n */\nexport function layerFilter({ layer, viewport }) {\n  if (viewport.id === 'axisLeft') {\n    return layer.id.startsWith('axisLeft');\n  } if (viewport.id === 'axisTop') {\n    return layer.id.startsWith('axisTop');\n  } if (viewport.id === 'heatmap') {\n    return layer.id.startsWith('heatmap');\n  } if (viewport.id === 'colorsLeft') {\n    return layer.id.startsWith('colorsLeft');\n  } if (viewport.id === 'colorsTop') {\n    return layer.id.startsWith('colorsTop');\n  }\n  return false;\n}\n\n/**\n * Get the size of the left and top heatmap axes,\n * taking into account the maximum label string lengths.\n * @param {boolean} transpose Is the heatmap transposed?\n * @param {number} geneLabelMaxLength What is the maximum length gene label?\n * @param {number} cellLabelMaxLength What is the maximum length cell label?\n * @returns {number[]} [axisOffsetLeft, axisOffsetTop]\n */\nexport function getAxisSizes(transpose, geneLabelMaxLength, cellLabelMaxLength) {\n  const axisOffsetLeft = clamp(\n    (transpose ? geneLabelMaxLength : cellLabelMaxLength) * AXIS_LABEL_TEXT_SIZE,\n    AXIS_MIN_SIZE,\n    AXIS_MAX_SIZE,\n  );\n  const axisOffsetTop = clamp(\n    (transpose ? cellLabelMaxLength : geneLabelMaxLength) * AXIS_LABEL_TEXT_SIZE,\n    AXIS_MIN_SIZE,\n    AXIS_MAX_SIZE,\n  );\n  return [axisOffsetLeft, axisOffsetTop];\n}\n\n/**\n * Convert a mouse coordinate (x, y) to a heatmap coordinate (col index, row index).\n * @param {number} mouseX The mouse X of interest.\n * @param {number} mouseY The mouse Y of interest.\n * @param {object} param2 An object containing current sizes and scale factors.\n * @returns {number[]} [colI, rowI]\n */\nexport function mouseToHeatmapPosition(mouseX, mouseY, {\n  offsetLeft, offsetTop, targetX, targetY, scaleFactor, matrixWidth, matrixHeight, numRows, numCols,\n}) {\n  // TODO: use linear algebra\n  const viewMouseX = mouseX - offsetLeft;\n  const viewMouseY = mouseY - offsetTop;\n\n  if (viewMouseX < 0 || viewMouseY < 0) {\n    // The mouse is outside the heatmap.\n    return [null, null];\n  }\n\n  // Determine the rowI and colI values based on the current viewState.\n  const bboxTargetX = targetX * scaleFactor + matrixWidth * scaleFactor / 2;\n  const bboxTargetY = targetY * scaleFactor + matrixHeight * scaleFactor / 2;\n\n  const bboxLeft = bboxTargetX - matrixWidth / 2;\n  const bboxTop = bboxTargetY - matrixHeight / 2;\n\n  const zoomedOffsetLeft = bboxLeft / (matrixWidth * scaleFactor);\n  const zoomedOffsetTop = bboxTop / (matrixHeight * scaleFactor);\n\n  const zoomedViewMouseX = viewMouseX / (matrixWidth * scaleFactor);\n  const zoomedViewMouseY = viewMouseY / (matrixHeight * scaleFactor);\n\n  const zoomedMouseX = zoomedOffsetLeft + zoomedViewMouseX;\n  const zoomedMouseY = zoomedOffsetTop + zoomedViewMouseY;\n\n  const rowI = Math.floor(zoomedMouseY * numRows);\n  const colI = Math.floor(zoomedMouseX * numCols);\n  return [colI, rowI];\n}\n\n/**\n * Convert a heatmap coordinate (col index, row index) to a mouse coordinate (x, y).\n * @param {number} colI The column index of interest.\n * @param {number} rowI The row index of interest.\n * @param {object} param2 An object containing current sizes and scale factors.\n * @returns {number[]} [x, y]\n */\nexport function heatmapToMousePosition(colI, rowI, {\n  offsetLeft, offsetTop, targetX, targetY, scaleFactor, matrixWidth, matrixHeight, numRows, numCols,\n}) {\n  // TODO: use linear algebra\n  let zoomedMouseY = null;\n  let zoomedMouseX = null;\n\n  if (rowI !== null) {\n    const minY = -matrixHeight * scaleFactor / 2;\n    const maxY = matrixHeight * scaleFactor / 2;\n    const totalHeight = maxY - minY;\n\n    const minInViewY = (targetY * scaleFactor) - (matrixHeight / 2);\n    const maxInViewY = (targetY * scaleFactor) + (matrixHeight / 2);\n    const inViewHeight = maxInViewY - minInViewY;\n\n    const normalizedRowY = (rowI + 0.5) / numRows;\n    const globalRowY = minY + (normalizedRowY * totalHeight);\n\n    if (minInViewY <= globalRowY && globalRowY <= maxInViewY) {\n      zoomedMouseY = offsetTop + ((globalRowY - minInViewY) / inViewHeight) * matrixHeight;\n    }\n  }\n  if (colI !== null) {\n    const minX = -matrixWidth * scaleFactor / 2;\n    const maxX = matrixWidth * scaleFactor / 2;\n    const totalWidth = maxX - minX;\n\n    const minInViewX = (targetX * scaleFactor) - (matrixWidth / 2);\n    const maxInViewX = (targetX * scaleFactor) + (matrixWidth / 2);\n    const inViewWidth = maxInViewX - minInViewX;\n\n    const normalizedRowX = (colI + 0.5) / numCols;\n    const globalRowX = minX + (normalizedRowX * totalWidth);\n\n    if (minInViewX <= globalRowX && globalRowX <= maxInViewX) {\n      zoomedMouseX = offsetLeft + ((globalRowX - minInViewX) / inViewWidth) * matrixWidth;\n    }\n  }\n  return [zoomedMouseX, zoomedMouseY];\n}\n","// https://developer.mozilla.org/en-US/docs/Web/API/NavigatorConcurrentHardware/hardwareConcurrency\n// We need to give a different way of getting this for safari, so 4 is probably a safe bet\n// for parallel processing in the meantime.  More can't really hurt since they'll just block\n// each other and not the UI thread, which is the real benefit.\nconst defaultPoolSize = typeof navigator !== 'undefined' ? navigator.hardwareConcurrency || 4 : null;\n\n/**\n * Pool for workers to decode chunks of the images.\n * This is a line-for-line copy of GeoTIFFs old implementation: https://github.com/geotiffjs/geotiff.js/blob/v1.0.0-beta.6/src/pool.js\n */\nexport default class Pool {\n  /**\n   * @constructor\n   * @param {object} Worker The worker class to be used for processing.\n   */\n  constructor(Worker) {\n    this.workers = [];\n    this.idleWorkers = [];\n    this.waitQueue = [];\n    this.decoder = null;\n\n    // eslint-disable-next-line no-plusplus\n    for (let i = 0; i < defaultPoolSize; ++i) {\n      const w = new Worker();\n      this.workers.push(w);\n      this.idleWorkers.push(w);\n    }\n  }\n\n  // eslint-disable-next-line class-methods-use-this\n  async process() {\n    throw new Error('Pool needs to implement \"process\" method');\n  }\n\n  async waitForWorker() {\n    const idleWorker = this.idleWorkers.pop();\n    if (idleWorker) {\n      return idleWorker;\n    }\n    const waiter = {};\n    const promise = new Promise((resolve) => {\n      waiter.resolve = resolve;\n    });\n\n    this.waitQueue.push(waiter);\n    return promise;\n  }\n\n  async finishTask(currentWorker) {\n    const waiter = this.waitQueue.pop();\n    if (waiter) {\n      waiter.resolve(currentWorker);\n    } else {\n      this.idleWorkers.push(currentWorker);\n    }\n  }\n\n  destroy() {\n    // eslint-disable-next-line no-plusplus\n    for (let i = 0; i < this.workers.length; ++i) {\n      this.workers[i].terminate();\n    }\n  }\n}\n","import Worker from './heatmap.worker'; // eslint-disable-line import/no-unresolved\nimport Pool from '../../Pool';\n\n/**\n * Pool for workers to decode chunks of the images.\n * This is a line-for-line copy of GeoTIFFs old implementation: https://github.com/geotiffjs/geotiff.js/blob/v1.0.0-beta.6/src/pool.js\n */\nexport default class HeatmapPool extends Pool {\n  constructor() {\n    super(Worker);\n  }\n\n  /**\n   * Process each heatmap tile\n   * @param {object} params The arguments passed to the heatmap worker.\n   * @param {string} params.curr The current task uuid.\n   * @param {number} params.xTiles How many tiles required in the x direction?\n   * @param {number} params.yTiles How many tiles required in the y direction?\n   * @param {number} params.tileSize How many entries along each tile axis?\n   * @param {string[]} params.cellOrdering The current ordering of cells.\n   * @param {string[]} params.rows The name of each row (cell ID).\n   * Does not take transpose into account (always cells).\n   * @param {string[]} params.cols The name of each column (gene ID).\n   * Does not take transpose into account (always genes).\n   * @param {ArrayBuffer} params.data The array buffer.\n   * Need to transfer back to main thread when done.\n   * @param {boolean} params.transpose Is the heatmap transposed?\n   * @returns {array} [message, transfers]\n   * @returns {Promise.<ArrayBuffer>} the decoded result as a `Promise`\n   */\n  async process(args) {\n    const currentWorker = await this.waitForWorker();\n    return new Promise((resolve, reject) => {\n      currentWorker.onmessage = (event) => {\n        // this.workers.push(currentWorker);\n        this.finishTask(currentWorker);\n        resolve(event.data);\n      };\n      currentWorker.onerror = (error) => {\n        // this.workers.push(currentWorker);\n        this.finishTask(currentWorker);\n        reject(error);\n      };\n      currentWorker.postMessage(['getTile', args], [args.data]);\n    });\n  }\n}\n","import React, {\n  useRef, useState, useCallback, useMemo, useEffect, useReducer, forwardRef,\n} from 'react';\nimport uuidv4 from 'uuid/v4';\nimport DeckGL from 'deck.gl';\nimport { OrthographicView } from '@deck.gl/core'; // eslint-disable-line import/no-extraneous-dependencies\nimport range from 'lodash/range';\nimport clamp from 'lodash/clamp';\nimport isEqual from 'lodash/isEqual';\nimport { max } from 'd3-array';\nimport HeatmapCompositeTextLayer from '../../layers/HeatmapCompositeTextLayer';\nimport PixelatedBitmapLayer from '../../layers/PixelatedBitmapLayer';\nimport HeatmapBitmapLayer from '../../layers/HeatmapBitmapLayer';\nimport {\n  DEFAULT_GL_OPTIONS,\n  createDefaultUpdateCellsHover,\n  createDefaultUpdateGenesHover,\n  createDefaultUpdateViewInfo,\n  copyUint8Array,\n} from '../utils';\nimport {\n  layerFilter,\n  getAxisSizes,\n  mouseToHeatmapPosition,\n  heatmapToMousePosition,\n} from './utils';\nimport {\n  TILE_SIZE, MAX_ROW_AGG, MIN_ROW_AGG,\n  COLOR_BAR_SIZE,\n  AXIS_MARGIN,\n} from '../../layers/heatmap-constants';\nimport HeatmapWorkerPool from './HeatmapWorkerPool';\n/**\n * A heatmap component for cell x gene matrices.\n * @param {object} props\n * @param {string} props.uuid The uuid of this component,\n * used by tooltips to determine whether to render a tooltip or\n * a crosshair.\n * @param {string} props.theme The current theme name.\n * @param {object} props.initialViewState The initial viewState for\n * DeckGL.\n * @param {number} props.width The width of the canvas.\n * @param {number} props.height The height of the canvas.\n * @param {object} props.expressionMatrix An object { rows, cols, matrix },\n * where matrix is a flat Uint8Array, rows is a list of cell ID strings,\n * and cols is a list of gene ID strings.\n * @param {Map} props.cellColors Map of cell ID to color. Optional.\n * If defined, the key ordering is used to order the cell axis of the heatmap.\n * @param {function} props.clearPleaseWait The clear please wait callback,\n * called when the expression matrix has loaded (is not null).\n * @param {function} props.setCellHighlight Callback function called on\n * hover with the cell ID. Optional.\n * @param {function} props.setGeneHighlight Callback function called on\n * hover with the gene ID. Optional.\n * @param {function} props.updateViewInfo Callback function that gets called with an\n * object { uuid, project() } where project is a function that maps (cellId, geneId)\n * to canvas (x,y) coordinates. Used to show tooltips. Optional.\n * @param {boolean} props.transpose By default, false.\n * @param {string} props.variablesTitle By default, 'Genes'.\n * @param {string} props.observationsTitle By default, 'Cells'.\n * @param {string} props.colormap The name of the colormap function to use.\n * @param {array} props.colormapRange A tuple [lower, upper] to adjust the color scale.\n * @param {function} props.setColormapRange The setter function for colormapRange.\n */\nconst Heatmap = forwardRef((props, deckRef) => {\n  const {\n    uuid,\n    theme,\n    viewState: rawViewState,\n    setViewState,\n    width: viewWidth,\n    height: viewHeight,\n    expressionMatrix: expression,\n    cellColors,\n    colormap,\n    colormapRange,\n    clearPleaseWait,\n    setComponentHover,\n    setCellHighlight = createDefaultUpdateCellsHover('Heatmap'),\n    setGeneHighlight = createDefaultUpdateGenesHover('Heatmap'),\n    updateViewInfo = createDefaultUpdateViewInfo('Heatmap'),\n    setIsRendering = () => {},\n    transpose = false,\n    variablesTitle = 'Genes',\n    observationsTitle = 'Cells',\n  } = props;\n\n  const viewState = {\n    ...rawViewState,\n    target: (transpose ? [rawViewState.target[1], rawViewState.target[0]] : rawViewState.target),\n    minZoom: 0,\n  };\n\n  const axisLeftTitle = (transpose ? variablesTitle : observationsTitle);\n  const axisTopTitle = (transpose ? observationsTitle : variablesTitle);\n\n  const workerPool = useMemo(() => new HeatmapWorkerPool(), []);\n\n  useEffect(() => {\n    if (clearPleaseWait && expression) {\n      clearPleaseWait('expression-matrix');\n    }\n  }, [clearPleaseWait, expression]);\n\n  const tilesRef = useRef();\n  const dataRef = useRef();\n  const [axisLeftLabels, setAxisLeftLabels] = useState([]);\n  const [axisTopLabels, setAxisTopLabels] = useState([]);\n\n\n  // Since we are storing the tile data in a ref,\n  // and updating it asynchronously when the worker finishes,\n  // we need to tie it to a piece of state through this iteration value.\n  const [tileIteration, incTileIteration] = useReducer(i => i + 1, 0);\n\n  // We need to keep a backlog of the tasks for the worker thread,\n  // since the array buffer can only be held by one thread at a time.\n  const [backlog, setBacklog] = useState([]);\n\n  // Store a reference to the matrix Uint8Array in the dataRef,\n  // since we need to access its array buffer to transfer\n  // it back and forth from the worker thread.\n  useEffect(() => {\n    // Store the expression matrix Uint8Array in the dataRef.\n    if (expression && expression.matrix) {\n      dataRef.current = copyUint8Array(expression.matrix);\n    }\n  }, [dataRef, expression]);\n\n  // Check if the ordering of axis labels needs to be changed,\n  // for example if the cells \"selected\" (technically just colored)\n  // have changed.\n  useEffect(() => {\n    if (!expression) {\n      return;\n    }\n    const newCellOrdering = (!cellColors || cellColors.size === 0\n      ? expression.rows\n      : Array.from(cellColors.keys())\n    );\n    const oldCellOrdering = (transpose ? axisTopLabels : axisLeftLabels);\n\n    if (!isEqual(oldCellOrdering, newCellOrdering)) {\n      if (transpose) {\n        setAxisTopLabels(newCellOrdering);\n      } else {\n        setAxisLeftLabels(newCellOrdering);\n      }\n    }\n  }, [expression, cellColors, axisTopLabels, axisLeftLabels, transpose]);\n\n  // Set the genes ordering.\n  useEffect(() => {\n    if (!expression) {\n      return;\n    }\n    if (transpose) {\n      setAxisLeftLabels(expression.cols);\n    } else {\n      setAxisTopLabels(expression.cols);\n    }\n  }, [expression, transpose]);\n\n  const [cellLabelMaxLength, geneLabelMaxLength] = useMemo(() => {\n    if (!expression) {\n      return [0, 0];\n    }\n    return [\n      max(expression.rows.map(cellId => cellId.length)),\n      max(expression.cols.map(geneId => geneId.length)),\n    ];\n  }, [expression]);\n\n  const width = axisTopLabels.length;\n  const height = axisLeftLabels.length;\n\n  const [axisOffsetLeft, axisOffsetTop] = getAxisSizes(\n    transpose, geneLabelMaxLength, cellLabelMaxLength,\n  );\n\n  const offsetTop = axisOffsetTop + COLOR_BAR_SIZE;\n  const offsetLeft = axisOffsetLeft + COLOR_BAR_SIZE;\n\n  const matrixWidth = viewWidth - offsetLeft;\n  const matrixHeight = viewHeight - offsetTop;\n\n  const matrixLeft = -matrixWidth / 2;\n  const matrixRight = matrixWidth / 2;\n  const matrixTop = -matrixHeight / 2;\n  const matrixBottom = matrixHeight / 2;\n\n  const xTiles = Math.ceil(width / TILE_SIZE);\n  const yTiles = Math.ceil(height / TILE_SIZE);\n\n  const widthRatio = 1 - (TILE_SIZE - (width % TILE_SIZE)) / (xTiles * TILE_SIZE);\n  const heightRatio = 1 - (TILE_SIZE - (height % TILE_SIZE)) / (yTiles * TILE_SIZE);\n\n  const tileWidth = (matrixWidth / widthRatio) / (xTiles);\n  const tileHeight = (matrixHeight / heightRatio) / (yTiles);\n\n  const scaleFactor = 2 ** viewState.zoom;\n  const cellHeight = (matrixHeight * scaleFactor) / height;\n  const cellWidth = (matrixWidth * scaleFactor) / width;\n\n  // Get power of 2 between 1 and 16,\n  // for number of cells to aggregate together in each direction.\n  const aggSizeX = clamp(2 ** Math.ceil(Math.log2(1 / cellWidth)), MIN_ROW_AGG, MAX_ROW_AGG);\n  const aggSizeY = clamp(2 ** Math.ceil(Math.log2(1 / cellHeight)), MIN_ROW_AGG, MAX_ROW_AGG);\n\n  const [targetX, targetY] = viewState.target;\n\n  // Emit the viewInfo object on viewState updates\n  // (used by tooltips / crosshair elements).\n  useEffect(() => {\n    updateViewInfo({\n      uuid,\n      project: (cellId, geneId) => {\n        const colI = transpose ? axisTopLabels.indexOf(cellId) : axisTopLabels.indexOf(geneId);\n        const rowI = transpose ? axisLeftLabels.indexOf(geneId) : axisLeftLabels.indexOf(cellId);\n        return heatmapToMousePosition(\n          colI, rowI, {\n            offsetLeft,\n            offsetTop,\n            targetX: viewState.target[0],\n            targetY: viewState.target[1],\n            scaleFactor,\n            matrixWidth,\n            matrixHeight,\n            numRows: height,\n            numCols: width,\n          },\n        );\n      },\n    });\n  }, [uuid, updateViewInfo, transpose, axisTopLabels, axisLeftLabels, offsetLeft,\n    offsetTop, viewState, scaleFactor, matrixWidth, matrixHeight, height, width]);\n\n\n  // Listen for viewState changes.\n  // Do not allow the user to zoom and pan outside of the initial window.\n  const onViewStateChange = useCallback(({ viewState: nextViewState }) => {\n    const { zoom: nextZoom } = nextViewState;\n    const nextScaleFactor = 2 ** nextZoom;\n\n    const minTargetX = nextZoom === 0 ? 0 : -(matrixRight - (matrixRight / nextScaleFactor));\n    const maxTargetX = -1 * minTargetX;\n\n    const minTargetY = nextZoom === 0 ? 0 : -(matrixBottom - (matrixBottom / nextScaleFactor));\n    const maxTargetY = -1 * minTargetY;\n\n    // Manipulate view state if necessary to keep the user in the window.\n    const nextTarget = [\n      clamp(nextViewState.target[0], minTargetX, maxTargetX),\n      clamp(nextViewState.target[1], minTargetY, maxTargetY),\n    ];\n\n    setViewState({\n      zoom: nextZoom,\n      target: (transpose ? [nextTarget[1], nextTarget[0]] : nextTarget),\n    });\n  }, [matrixRight, matrixBottom, transpose, setViewState]);\n\n  // If `expression` or `cellOrdering` have changed,\n  // then new tiles need to be generated,\n  // so add a new task to the backlog.\n  useEffect(() => {\n    if (!expression) {\n      return;\n    }\n    // Use a uuid to give the task a unique ID,\n    // to help identify where in the list it is located\n    // after the worker thread asynchronously sends the data back\n    // to this thread.\n    if (\n      axisTopLabels && axisLeftLabels && xTiles && yTiles\n    ) {\n      setBacklog(prev => [...prev, uuidv4()]);\n    }\n  }, [dataRef, expression, axisTopLabels, axisLeftLabels, xTiles, yTiles]);\n\n  // When the backlog has updated, a new worker job can be submitted if:\n  // - the backlog has length >= 1 (at least one job is waiting), and\n  // - buffer.byteLength is not zero, so the worker does not currently \"own\" the buffer.\n  useEffect(() => {\n    if (backlog.length < 1) {\n      return;\n    }\n    const curr = backlog[backlog.length - 1];\n    if (dataRef.current && dataRef.current.buffer.byteLength) {\n      const { rows, cols, matrix } = expression;\n      const promises = range(yTiles).map(i => range(xTiles).map(async j => workerPool.process({\n        curr,\n        tileI: i,\n        tileJ: j,\n        tileSize: TILE_SIZE,\n        cellOrdering: transpose ? axisTopLabels : axisLeftLabels,\n        rows,\n        cols,\n        transpose,\n        data: matrix.buffer.slice(),\n      })));\n      const process = async () => {\n        const tiles = await Promise.all(promises.flat());\n        tilesRef.current = tiles.map(i => i.tile);\n        incTileIteration();\n        dataRef.current = new Uint8Array(tiles[0].buffer);\n        const { curr: currWork } = tiles[0];\n        setBacklog((prev) => {\n          const currIndex = prev.indexOf(currWork);\n          return prev.slice(currIndex + 1, prev.length);\n        });\n      };\n      process();\n    }\n  }, [axisLeftLabels, axisTopLabels, backlog, expression, transpose, xTiles, yTiles, workerPool]);\n\n  useEffect(() => {\n    setIsRendering(backlog.length > 0);\n  }, [backlog, setIsRendering]);\n\n  // Update the heatmap tiles if:\n  // - new tiles are available (`tileIteration` has changed), or\n  // - the matrix bounds have changed, or\n  // - the `aggSizeX` or `aggSizeY` have changed, or\n  // - the cell ordering has changed.\n  const heatmapLayers = useMemo(() => {\n    if (!tilesRef.current || backlog.length) {\n      return [];\n    }\n    function getLayer(i, j, tile) {\n      return new HeatmapBitmapLayer({\n        id: `heatmapLayer-${tileIteration}-${i}-${j}`,\n        image: tile,\n        bounds: [\n          matrixLeft + j * tileWidth,\n          matrixTop + i * tileHeight,\n          matrixLeft + (j + 1) * tileWidth,\n          matrixTop + (i + 1) * tileHeight,\n        ],\n        aggSizeX,\n        aggSizeY,\n        colormap,\n        colorScaleLo: colormapRange[0],\n        colorScaleHi: colormapRange[1],\n        updateTriggers: {\n          image: [axisLeftLabels, axisTopLabels],\n          bounds: [tileHeight, tileWidth],\n        },\n      });\n    }\n    const layers = tilesRef\n      .current.map((tile, index) => getLayer(Math.floor(index / xTiles), index % xTiles, tile));\n    return layers;\n  }, [backlog, tileIteration, matrixLeft, tileWidth, matrixTop, tileHeight,\n    aggSizeX, aggSizeY, colormap, colormapRange,\n    axisLeftLabels, axisTopLabels, xTiles]);\n\n\n  // Map cell and gene names to arrays with indices,\n  // to prepare to render the names in TextLayers.\n  const axisTopLabelData = useMemo(() => axisTopLabels.map((d, i) => [i, d]), [axisTopLabels]);\n  const axisLeftLabelData = useMemo(() => axisLeftLabels.map((d, i) => [i, d]), [axisLeftLabels]);\n\n  // Generate the axis label, axis title, and loading indicator text layers.\n  const textLayers = [\n    new HeatmapCompositeTextLayer({\n      targetX,\n      targetY,\n      scaleFactor,\n      axisLeftLabelData,\n      matrixTop,\n      height,\n      matrixHeight,\n      cellHeight,\n      cellWidth,\n      axisTopLabelData,\n      matrixLeft,\n      width,\n      matrixWidth,\n      viewHeight,\n      viewWidth,\n      theme,\n      axisLeftTitle,\n      axisTopTitle,\n      axisOffsetLeft,\n      axisOffsetTop,\n    }),\n  ];\n\n  // Create the left color bar with a BitmapLayer.\n  // TODO: find a way to do aggregation for this as well.\n  const cellColorsTiles = useMemo(() => {\n    if (!cellColors) {\n      return null;\n    }\n\n    let cellId;\n    let offset;\n    let color;\n    let rowI;\n\n    const cellOrdering = (transpose ? axisTopLabels : axisLeftLabels);\n    const colorBarTileWidthPx = (transpose ? TILE_SIZE : 1);\n    const colorBarTileHeightPx = (transpose ? 1 : TILE_SIZE);\n\n    const result = range((transpose ? xTiles : yTiles)).map((i) => {\n      const tileData = new Uint8ClampedArray(TILE_SIZE * 1 * 4);\n\n      range(TILE_SIZE).forEach((tileY) => {\n        rowI = (i * TILE_SIZE) + tileY; // the row / cell index\n        if (rowI < cellOrdering.length) {\n          cellId = cellOrdering[rowI];\n          color = cellColors.get(cellId);\n          offset = (transpose ? tileY : (TILE_SIZE - tileY - 1)) * 4;\n          if (color) {\n            const [rValue, gValue, bValue] = color;\n            tileData[offset + 0] = rValue;\n            tileData[offset + 1] = gValue;\n            tileData[offset + 2] = bValue;\n            tileData[offset + 3] = 255;\n          }\n        }\n      });\n\n      return new ImageData(tileData, colorBarTileWidthPx, colorBarTileHeightPx);\n    });\n\n    return result;\n  }, [cellColors, transpose, axisTopLabels, axisLeftLabels, xTiles, yTiles]);\n\n  const cellColorsLayers = useMemo(() => (cellColorsTiles\n    ? cellColorsTiles\n      .map((tile, i) => new PixelatedBitmapLayer({\n        id: `${(transpose ? 'colorsTopLayer' : 'colorsLeftLayer')}-${i}-${uuidv4()}`,\n        image: tile,\n        bounds: (transpose ? [\n          matrixLeft + i * tileWidth,\n          -matrixHeight / 2,\n          matrixLeft + (i + 1) * tileWidth,\n          matrixHeight / 2,\n        ] : [\n          -matrixWidth / 2,\n          matrixTop + i * tileHeight,\n          matrixWidth / 2,\n          matrixTop + (i + 1) * tileHeight,\n        ]),\n      }))\n    : []), [cellColorsTiles, matrixTop, matrixLeft, matrixHeight,\n    matrixWidth, tileWidth, tileHeight, transpose]);\n\n  const layers = heatmapLayers\n    .concat(textLayers)\n    .concat(cellColorsLayers);\n\n  // Set up the onHover function.\n  function onHover(info, event) {\n    if (!expression) {\n      return;\n    }\n    const { x: mouseX, y: mouseY } = event.offsetCenter;\n    const [colI, rowI] = mouseToHeatmapPosition(mouseX, mouseY, {\n      offsetLeft,\n      offsetTop,\n      targetX,\n      targetY,\n      scaleFactor,\n      matrixWidth,\n      matrixHeight,\n      numRows: height,\n      numCols: width,\n    });\n\n    if (colI === null) {\n      if (transpose) {\n        setCellHighlight(null);\n      } else {\n        setGeneHighlight(null);\n      }\n    }\n\n    if (rowI === null) {\n      if (transpose) {\n        setGeneHighlight(null);\n      } else {\n        setCellHighlight(null);\n      }\n    }\n\n    const obsI = expression.rows.indexOf(transpose\n      ? axisTopLabels[colI]\n      : axisLeftLabels[rowI]);\n    const varI = expression.cols.indexOf(transpose\n      ? axisLeftLabels[rowI]\n      : axisTopLabels[colI]);\n\n    const obsId = expression.rows[obsI];\n    const varId = expression.cols[varI];\n    if (setComponentHover) {\n      setComponentHover();\n    }\n    setCellHighlight(obsId || null);\n    setGeneHighlight(varId || null);\n  }\n\n  return (\n    <DeckGL\n      id={`deckgl-overlay-${uuid}`}\n      ref={deckRef}\n      views={[\n        // Note that there are multiple views here,\n        // but only one viewState.\n        new OrthographicView({\n          id: 'heatmap',\n          controller: true,\n          x: offsetLeft,\n          y: offsetTop,\n          width: matrixWidth,\n          height: matrixHeight,\n        }),\n        new OrthographicView({\n          id: 'axisLeft',\n          controller: false,\n          x: (transpose ? COLOR_BAR_SIZE : 0),\n          y: offsetTop,\n          width: axisOffsetLeft,\n          height: matrixHeight,\n        }),\n        new OrthographicView({\n          id: 'axisTop',\n          controller: false,\n          x: offsetLeft,\n          y: (transpose ? 0 : COLOR_BAR_SIZE),\n          width: matrixWidth,\n          height: axisOffsetTop,\n        }),\n        new OrthographicView({\n          id: 'colorsLeft',\n          controller: false,\n          x: axisOffsetLeft,\n          y: offsetTop,\n          width: COLOR_BAR_SIZE - AXIS_MARGIN,\n          height: matrixHeight,\n        }),\n        new OrthographicView({\n          id: 'colorsTop',\n          controller: false,\n          x: offsetLeft,\n          y: axisOffsetTop,\n          width: matrixWidth,\n          height: COLOR_BAR_SIZE - AXIS_MARGIN,\n        }),\n      ]}\n      layers={layers}\n      layerFilter={layerFilter}\n      getCursor={interactionState => (interactionState.isDragging ? 'grabbing' : 'default')}\n      glOptions={DEFAULT_GL_OPTIONS}\n      onViewStateChange={onViewStateChange}\n      viewState={viewState}\n      onHover={onHover}\n    />\n  );\n});\n\nexport default Heatmap;\n","import React from 'react';\nimport Tooltip2D from '../tooltip/Tooltip2D';\nimport TooltipContent from '../tooltip/TooltipContent';\nimport { useComponentHover, useComponentViewInfo } from '../../app/state/hooks';\n\nexport default function HeatmapTooltipSubscriber(props) {\n  const {\n    parentUuid,\n    width, height, transpose,\n    getCellInfo, getGeneInfo,\n    cellHighlight, geneHighlight,\n  } = props;\n\n  const sourceUuid = useComponentHover();\n  const viewInfo = useComponentViewInfo(parentUuid);\n\n  const [cellInfo, cellCoord] = (cellHighlight && getCellInfo ? (\n    [\n      getCellInfo(cellHighlight),\n      (viewInfo && viewInfo.project\n        ? viewInfo.project(cellHighlight, null)[(transpose ? 0 : 1)]\n        : null),\n    ]\n  ) : ([null, null]));\n\n  const [geneInfo, geneCoord] = (geneHighlight && getGeneInfo ? (\n    [\n      getGeneInfo(geneHighlight),\n      (viewInfo && viewInfo.project\n        ? viewInfo.project(null, geneHighlight)[(transpose ? 1 : 0)]\n        : null),\n    ]\n  ) : ([null, null]));\n\n  const x = (transpose ? cellCoord : geneCoord);\n  const y = (transpose ? geneCoord : cellCoord);\n\n  return (\n    (cellInfo || geneInfo ? (\n      <Tooltip2D\n        x={x}\n        y={y}\n        parentUuid={parentUuid}\n        parentWidth={width}\n        parentHeight={height}\n        sourceUuid={sourceUuid}\n      >\n        <TooltipContent info={{ ...geneInfo, ...cellInfo }} />\n      </Tooltip2D>\n    ) : null)\n  );\n}\n","import React, { useCallback } from 'react';\nimport debounce from 'lodash/debounce';\nimport Slider from '@material-ui/core/Slider';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableRow from '@material-ui/core/TableRow';\nimport { useStyles } from '../shared-plot-options/styles';\nimport OptionsContainer from '../shared-plot-options/OptionsContainer';\nimport OptionSelect from '../shared-plot-options/OptionSelect';\nimport { GLSL_COLORMAPS } from '../../layers/constants';\n\nexport default function HeatmapOptions(props) {\n  const {\n    geneExpressionColormap,\n    setGeneExpressionColormap,\n    geneExpressionColormapRange,\n    setGeneExpressionColormapRange,\n  } = props;\n\n  const classes = useStyles();\n\n  function handleGeneExpressionColormapChange(event) {\n    setGeneExpressionColormap(event.target.value);\n  }\n\n  function handleColormapRangeChange(event, value) {\n    setGeneExpressionColormapRange(value);\n  }\n  const handleColormapRangeChangeDebounced = useCallback(\n    debounce(handleColormapRangeChange, 5, { trailing: true }),\n    [handleColormapRangeChange],\n  );\n\n  return (\n    <OptionsContainer>\n      <TableRow>\n        <TableCell className={classes.labelCell} htmlFor=\"gene-expression-colormap-select\">\n          Gene Expression Colormap\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <OptionSelect\n            className={classes.select}\n            value={geneExpressionColormap}\n            onChange={handleGeneExpressionColormapChange}\n            inputProps={{\n              id: 'gene-expression-colormap-select',\n            }}\n          >\n            {GLSL_COLORMAPS.map(cmap => (\n              <option key={cmap} value={cmap}>{cmap}</option>\n            ))}\n          </OptionSelect>\n        </TableCell>\n      </TableRow>\n      <TableRow>\n        <TableCell className={classes.labelCell}>\n          Gene Expression Colormap Range\n        </TableCell>\n        <TableCell className={classes.inputCell}>\n          <Slider\n            classes={{ root: classes.slider, valueLabel: classes.sliderValueLabel }}\n            value={geneExpressionColormapRange}\n            onChange={handleColormapRangeChangeDebounced}\n            aria-labelledby=\"gene-expression-colormap-range-slider\"\n            valueLabelDisplay=\"auto\"\n            step={0.005}\n            min={0.0}\n            max={1.0}\n          />\n        </TableCell>\n      </TableRow>\n    </OptionsContainer>\n  );\n}\n","import React, {\n  useEffect, useState, useCallback, useMemo,\n} from 'react';\nimport TitleInfo from '../TitleInfo';\nimport { pluralize, capitalize } from '../../utils';\nimport { useDeckCanvasSize, useReady, useUrls } from '../hooks';\nimport { mergeCellSets } from '../utils';\nimport {\n  useCellsData,\n  useCellSetsData,\n  useExpressionMatrixData,\n} from '../data-hooks';\nimport { getCellColors } from '../interpolate-colors';\nimport {\n  useCoordination, useLoaders,\n  useSetComponentHover, useSetComponentViewInfo,\n} from '../../app/state/hooks';\nimport {\n  COMPONENT_COORDINATION_TYPES,\n} from '../../app/state/coordination';\nimport Heatmap from './Heatmap';\nimport HeatmapTooltipSubscriber from './HeatmapTooltipSubscriber';\nimport HeatmapOptions from './HeatmapOptions';\n\nconst HEATMAP_DATA_TYPES = ['cells', 'cell-sets', 'expression-matrix'];\n\n/**\n * @param {object} props\n * @param {number} props.uuid The unique identifier for this component.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n * @param {boolean} props.transpose Whether to\n * render as cell-by-gene or gene-by-cell.\n * @param {string} props.observationsLabelOverride The singular\n * form of the name of the observation.\n * @param {string} props.observationsPluralLabelOverride The\n * plural form of the name of the observation.\n * @param {string} props.variablesLabelOverride The singular\n * form of the name of the variable.\n * @param {string} props.variablesPluralLabelOverride The plural\n * form of the name of the variable.\n * @param {boolean} props.disableTooltip Whether to disable the\n * tooltip on mouse hover.\n */\nexport default function HeatmapSubscriber(props) {\n  const {\n    uuid,\n    coordinationScopes,\n    removeGridComponent, theme, transpose,\n    observationsLabelOverride: observationsLabel = 'cell',\n    observationsPluralLabelOverride: observationsPluralLabel = `${observationsLabel}s`,\n    variablesLabelOverride: variablesLabel = 'gene',\n    variablesPluralLabelOverride: variablesPluralLabel = `${variablesLabel}s`,\n    disableTooltip = false,\n    title = 'Heatmap',\n  } = props;\n\n  const loaders = useLoaders();\n  const setComponentHover = useSetComponentHover();\n  const setComponentViewInfo = useSetComponentViewInfo(uuid);\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    heatmapZoomX: zoomX,\n    heatmapTargetX: targetX,\n    heatmapTargetY: targetY,\n    geneSelection,\n    cellHighlight,\n    geneHighlight,\n    cellSetSelection,\n    cellSetColor,\n    additionalCellSets,\n    geneExpressionColormap,\n    geneExpressionColormapRange,\n  }, {\n    setHeatmapZoomX: setZoomX,\n    setHeatmapZoomY: setZoomY,\n    setHeatmapTargetX: setTargetX,\n    setHeatmapTargetY: setTargetY,\n    setCellHighlight,\n    setGeneHighlight,\n    setCellSetSelection,\n    setCellSetColor,\n    setGeneExpressionColormapRange,\n    setGeneExpressionColormap,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.heatmap, coordinationScopes);\n\n  const observationsTitle = capitalize(observationsPluralLabel);\n  const variablesTitle = capitalize(variablesPluralLabel);\n\n  const [isRendering, setIsRendering] = useState(false);\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    HEATMAP_DATA_TYPES,\n  );\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [width, height, deckRef] = useDeckCanvasSize();\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [cells] = useCellsData(loaders, dataset, setItemIsReady, addUrl, true);\n  const [expressionMatrix] = useExpressionMatrixData(\n    loaders, dataset, setItemIsReady, addUrl, true,\n  );\n  const [cellSets] = useCellSetsData(\n    loaders, dataset, setItemIsReady, addUrl, false,\n    { setCellSetSelection, setCellSetColor },\n    { cellSetSelection, cellSetColor },\n  );\n\n  const mergedCellSets = useMemo(() => mergeCellSets(\n    cellSets, additionalCellSets,\n  ), [cellSets, additionalCellSets]);\n\n  const cellColors = useMemo(() => getCellColors({\n    // Only show cell set selection on heatmap labels.\n    cellColorEncoding: 'cellSetSelection',\n    geneSelection,\n    cellSets: mergedCellSets,\n    cellSetSelection,\n    cellSetColor,\n    expressionDataAttrs: expressionMatrix,\n    theme,\n  }), [mergedCellSets, geneSelection, theme,\n    cellSetColor, cellSetSelection, expressionMatrix]);\n\n  const getCellInfo = useCallback((cellId) => {\n    if (cellId) {\n      const cellInfo = cells[cellId];\n      return {\n        [`${capitalize(observationsLabel)} ID`]: cellId,\n        ...(cellInfo ? cellInfo.factors : {}),\n      };\n    }\n    return null;\n  }, [cells, observationsLabel]);\n\n  const getGeneInfo = useCallback((geneId) => {\n    if (geneId) {\n      return { [`${capitalize(variablesLabel)} ID`]: geneId };\n    }\n    return null;\n  }, [variablesLabel]);\n\n  const cellsCount = expressionMatrix && expressionMatrix.rows\n    ? expressionMatrix.rows.length : 0;\n  const genesCount = expressionMatrix && expressionMatrix.cols\n    ? expressionMatrix.cols.length : 0;\n  const selectedCount = cellColors.size;\n  return (\n    <TitleInfo\n      title={title}\n      info={`${cellsCount} ${pluralize(observationsLabel, observationsPluralLabel, cellsCount)} × ${genesCount} ${pluralize(variablesLabel, variablesPluralLabel, genesCount)},\n             with ${selectedCount} ${pluralize(observationsLabel, observationsPluralLabel, selectedCount)} selected`}\n      urls={urls}\n      theme={theme}\n      removeGridComponent={removeGridComponent}\n      isReady={isReady && !isRendering}\n      options={(\n        <HeatmapOptions\n          geneExpressionColormap={geneExpressionColormap}\n          setGeneExpressionColormap={setGeneExpressionColormap}\n          geneExpressionColormapRange={geneExpressionColormapRange}\n          setGeneExpressionColormapRange={setGeneExpressionColormapRange}\n        />\n      )}\n    >\n      <Heatmap\n        ref={deckRef}\n        transpose={transpose}\n        viewState={{ zoom: zoomX, target: [targetX, targetY] }}\n        setViewState={({ zoom, target }) => {\n          setZoomX(zoom);\n          setZoomY(zoom);\n          setTargetX(target[0]);\n          setTargetY(target[1]);\n        }}\n        colormapRange={geneExpressionColormapRange}\n        setColormapRange={setGeneExpressionColormapRange}\n        height={height}\n        width={width}\n        theme={theme}\n        uuid={uuid}\n        expressionMatrix={expressionMatrix}\n        cellColors={cellColors}\n        colormap={geneExpressionColormap}\n        setIsRendering={setIsRendering}\n        setCellHighlight={setCellHighlight}\n        setGeneHighlight={setGeneHighlight}\n        setComponentHover={() => {\n          setComponentHover(uuid);\n        }}\n        updateViewInfo={setComponentViewInfo}\n        observationsTitle={observationsTitle}\n        variablesTitle={variablesTitle}\n      />\n      {!disableTooltip && (\n      <HeatmapTooltipSubscriber\n        parentUuid={uuid}\n        width={width}\n        height={height}\n        transpose={transpose}\n        getCellInfo={getCellInfo}\n        getGeneInfo={getGeneInfo}\n        cellHighlight={cellHighlight}\n        geneHighlight={geneHighlight}\n      />\n      )}\n    </TitleInfo>\n  );\n}\n","import React from 'react';\nimport IconButton from '@material-ui/core/IconButton';\nimport LensIcon from '@material-ui/icons/Lens';\nimport { makeStyles } from '@material-ui/core/styles';\n\n\nimport { VIEWER_PALETTE } from '../utils';\n\nconst useStyles = makeStyles(theme => ({\n  container: {\n    width: '70px',\n    height: '40px',\n    display: 'flex',\n    justifyContent: 'space-between',\n    alignItems: 'center',\n    flexWrap: 'wrap',\n  },\n  button: {\n    padding: '3px',\n    width: '16px',\n  },\n  icon: {\n    width: '17px',\n    height: '17px',\n    stroke: theme.palette.action.selected,\n    'stroke-width': '1px',\n  },\n}));\n\nconst ColorPalette = ({ handleChange }) => {\n  const classes = useStyles();\n  return (\n    <div className={classes.container} aria-label=\"color-swatch\">\n      {VIEWER_PALETTE.map(color => (\n        <IconButton\n          className={classes.button}\n          key={color}\n          onClick={() => handleChange(color)}\n        >\n          <LensIcon\n            fontSize=\"small\"\n            style={{ color: `rgb(${color})` }}\n            className={classes.icon}\n          />\n        </IconButton>\n      ))}\n    </div>\n  );\n};\n\nexport default ColorPalette;\n","import React, { useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport { PopperMenu, MuiSpan } from '../shared-mui/components';\n\nimport ColorPalette from './ColorPalette';\n\nconst useStyles = makeStyles(() => ({\n  menuButton: {\n    backgroundColor: 'transparent',\n  },\n  colors: {\n    '&:hover': {\n      backgroundColor: 'transparent',\n    },\n    paddingLeft: '2px',\n    paddingRight: '2px',\n  },\n}));\n\n/**\n * Dropdown for options for a channel on the three dots button.\n * @prop {function} handlePropertyChange Callback for changing property (color, IQR of sliders).\n * @prop {function} handleChannelRemove Callback for channel removal.\n * @prop {function} handleIQRUpdate Callback for IQR slider update.\n */\nfunction ChannelOptions({ handlePropertyChange, handleChannelRemove, handleIQRUpdate }) {\n  const [open, setOpen] = useState(false);\n\n  const classes = useStyles();\n\n  const handleColorSelect = (color) => {\n    handlePropertyChange('color', color);\n  };\n\n  const handleRemove = () => {\n    setOpen(false);\n    handleChannelRemove();\n  };\n\n  return (\n    <PopperMenu\n      open={open}\n      setOpen={setOpen}\n      buttonIcon={<MoreVertIcon fontSize=\"small\" />}\n      buttonClassName={classes.menuButton}\n    >\n      <MenuItem dense disableGutters onClick={handleRemove}>\n        <MuiSpan>Remove</MuiSpan>\n      </MenuItem>\n      <MenuItem dense disableGutters onClick={handleIQRUpdate}>\n        <MuiSpan>Use IQR</MuiSpan>\n      </MenuItem>\n      <MenuItem dense disableGutters className={classes.colors}>\n        <ColorPalette handleChange={handleColorSelect} />\n      </MenuItem>\n    </PopperMenu>\n  );\n}\n\nexport default ChannelOptions;\n","import { DTYPE_VALUES } from '@hms-dbmi/viv';\n\nfunction getDomains() {\n  const domains = {};\n  const needMin = ['Int8', 'Int16', 'Int32'];\n  Object.keys(DTYPE_VALUES).forEach((dtype) => {\n    const { max } = DTYPE_VALUES[dtype];\n    const min = needMin.includes(dtype) ? -(max + 1) : 0;\n    domains[dtype] = [min, max];\n  });\n  return domains;\n}\n\nexport const DOMAINS = getDomains();\n","import { makeStyles, withStyles } from '@material-ui/core/styles';\nimport AccordionSummary from '@material-ui/core/AccordionSummary';\nimport AccordionDetails from '@material-ui/core/AccordionDetails';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport Slider from '@material-ui/core/Slider';\nimport Grid from '@material-ui/core/Grid';\n\nexport const useSelectStyles = makeStyles(() => ({\n  selectRoot: {\n    padding: 0,\n    height: 'auto',\n    margin: '4px 0',\n  },\n}));\n\nexport const useOptionStyles = withStyles(theme => ({\n  paper: {\n    backgroundColor: theme.palette.background.paper,\n  },\n  span: {\n    width: '70px',\n    textAlign: 'center',\n    paddingLeft: '2px',\n    paddingRight: '2px',\n  },\n  colors: {\n    '&:hover': {\n      backgroundColor: 'transparent',\n    },\n    paddingLeft: '2px',\n    paddingRight: '2px',\n  },\n  popper: {\n    zIndex: 4,\n  },\n}));\n\nconst sharedControllerStyles = {\n  width: '100%',\n  flexDirection: 'column',\n};\n\nexport const useControllerSectionStyles = makeStyles(() => ({\n  root: {\n    ...sharedControllerStyles,\n    padding: '0px 8px',\n  },\n}));\n\nexport const StyledAccordionDetails = withStyles(() => ({\n  root: {\n    ...sharedControllerStyles,\n    padding: '8px 8px 24px 8px',\n  },\n}))(AccordionDetails);\n\nexport const StyledAccordionSummary = withStyles(theme => ({\n  root: {\n    padding: '0px 8px',\n  },\n  content: {\n    margin: '4px 0px',\n    minWidth: '0px',\n  },\n  expanded: {\n    marginBottom: theme.spacing(-3),\n    top: theme.spacing(-1),\n  },\n  expandIcon: {\n    '&$expanded': {\n      top: theme.spacing(-1.3),\n    },\n  },\n}))(AccordionSummary);\n\nexport const StyledInputLabel = withStyles(() => ({\n  root: {\n    fontSize: '14px',\n  },\n}))(InputLabel);\n\nexport const OverflowEllipsisGrid = withStyles(() => ({\n  item: {\n    width: '100%',\n    overflow: 'hidden',\n    whiteSpace: 'nowrap',\n    textOverflow: 'ellipsis',\n  },\n}))(Grid);\n\nexport const StyledSelectionSlider = withStyles(() => ({\n  root: {\n    marginTop: '7px',\n  },\n  markActive: {\n    backgroundColor: 'rgba(128, 128, 128, 0.7)',\n  },\n}))(Slider);\n","import React from 'react';\n\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Select from '@material-ui/core/Select';\nimport { useSelectStyles } from './styles';\n\n/**\n * Dropdown for selecting a channel.\n * @prop {function} handleChange Callback for each new selection.\n * @prop {array} channelOptions List of available selections, like ['DAPI', 'FITC', ...].\n * @prop {boolean} disabled Whether or not the component is disabled.\n * @prop {number} selectionIndex Current numeric index of a selection.\n */\nexport function ChannelSelectionDropdown({\n  handleChange,\n  disabled,\n  channelOptions,\n  selectionIndex,\n}) {\n  const classes = useSelectStyles();\n  return (\n    <Select\n      classes={{ root: classes.selectRoot }}\n      native\n      value={selectionIndex}\n      onChange={e => handleChange(Number(e.target.value))}\n    >\n      {channelOptions.map((opt, i) => (\n        <option disabled={disabled} key={opt} value={i}>\n          {opt}\n        </option>\n      ))}\n    </Select>\n  );\n}\n\n/**\n * Checkbox for toggling on/off of a channel.\n * @prop {string} color Current color for this channel.\n * @prop {boolean} checked Whether or not this channel is \"on\".\n * @prop {boolean} disabled Whether or not the component is disabled.\n * @prop {function} toggle Callback for toggling on/off.\n */\nexport function ChannelVisibilityCheckbox({\n  color, checked, toggle, disabled,\n}) {\n  return (\n    <Checkbox\n      onChange={toggle}\n      checked={checked}\n      disabled={disabled}\n      style={{ color, '&$checked': { color } }}\n    />\n  );\n}\n","import React, { useCallback, useState, useEffect } from 'react';\n\nimport Grid from '@material-ui/core/Grid';\nimport Slider from '@material-ui/core/Slider';\nimport debounce from 'lodash/debounce';\nimport isEqual from 'lodash/isEqual';\n\nimport ChannelOptions from './ChannelOptions';\nimport { DOMAINS } from './constants';\nimport { getSourceFromLoader } from '../../utils';\nimport { getMultiSelectionStats } from './utils';\nimport {\n  ChannelSelectionDropdown,\n  ChannelVisibilityCheckbox,\n} from './shared-channel-controls';\n\n// Returns an rgb string for display, and changes the color (arr)\n// to use a grey for light theme + white color or if the colormap is on.\nexport const toRgbUIString = (on, arr, theme) => {\n  const color = on || (theme === 'light' && arr.every(i => i === 255))\n    ? [220, 220, 220]\n    : arr;\n  return `rgb(${color})`;\n};\n\nfunction abbreviateNumber(value) {\n  // Return an abbreviated representation of value, in 5 characters or less.\n\n  const maxLength = 5;\n  let maxNaiveDigits = maxLength;\n\n  /* eslint-disable no-plusplus */\n  if (!Number.isInteger(value)) {\n    --maxNaiveDigits;\n  } // Wasted on \".\"\n  if (value < 1) {\n    --maxNaiveDigits;\n  } // Wasted on \"0.\"\n  /* eslint-disable no-plusplus */\n\n  const naive = Intl.NumberFormat('en-US', {\n    maximumSignificantDigits: maxNaiveDigits,\n    useGrouping: false,\n  }).format(value);\n  if (naive.length <= maxLength) return naive;\n\n  // \"e+9\" consumes 3 characters, so if we even had two significant digits,\n  // it would take take us to six characters, including the decimal point.\n  return value.toExponential(0);\n}\n\n/**\n * Slider for controlling current colormap.\n * @prop {string} color Current color for this channel.\n * @prop {arry} slider Current value of the slider.\n * @prop {function} handleChange Callback for each slider change.\n * @prop {array} domain Current max/min allowable slider values.\n */\nfunction ChannelSlider({\n  color,\n  slider = [0, 0],\n  handleChange,\n  domain = [0, 0],\n  dtype,\n  disabled,\n}) {\n  const [min, max] = domain;\n  const handleChangeDebounced = useCallback(\n    debounce(handleChange, 3, { trailing: true }),\n    [handleChange],\n  );\n  const step = max - min < 500 && dtype === 'Float32' ? (max - min) / 500 : 1;\n  return (\n    <Slider\n      value={slider}\n      valueLabelFormat={abbreviateNumber}\n      onChange={(e, v) => handleChangeDebounced(v)}\n      valueLabelDisplay=\"auto\"\n      getAriaLabel={() => `${color}-${slider}`}\n      min={min}\n      max={max}\n      step={step}\n      orientation=\"horizontal\"\n      style={{ color, marginTop: '7px' }}\n      disabled={disabled}\n    />\n  );\n}\n\n/**\n * Controller for the handling the colormapping sliders.\n * @prop {boolean} visibility Whether or not this channel is \"on\"\n * @prop {array} slider Current slider range.\n * @prop {array} color Current color for this channel.\n * @prop {array} domain Current max/min for this channel.\n * @prop {string} dimName Name of the dimensions this slider controls (usually \"channel\").\n * @prop {boolean} colormapOn Whether or not the colormap (viridis, magma etc.) is on.\n * @prop {object} channelOptions All available options for this dimension (i.e channel names).\n * @prop {function} handlePropertyChange Callback for when a property (color, slider etc.) changes.\n * @prop {function} handleChannelRemove When a channel is removed, this is called.\n * @prop {function} handleIQRUpdate When the IQR button is clicked, this is called.\n * @prop {number} selectionIndex The current numeric index of the selection.\n */\nfunction RasterChannelController({\n  visibility = false,\n  slider,\n  color,\n  channels,\n  channelId,\n  domainType: newDomainType,\n  dimName,\n  theme,\n  loader,\n  colormapOn,\n  channelOptions,\n  handlePropertyChange,\n  handleChannelRemove,\n  handleIQRUpdate,\n  selectionIndex,\n  isLoading,\n  use3d: newUse3d,\n}) {\n  const { dtype } = getSourceFromLoader(loader);\n  const [domain, setDomain] = useState(null);\n  const [domainType, setDomainType] = useState(null);\n  const [use3d, setUse3d] = useState(null);\n  const [selection, setSelection] = useState([\n    { ...channels[channelId].selection },\n  ]);\n  const rgbColor = toRgbUIString(colormapOn, color, theme);\n\n  useEffect(() => {\n    // Use mounted to prevent state updates/re-renders after the component has been unmounted.\n    // All state updates should happen within the mounted check.\n    let mounted = true;\n    if (dtype && loader && channels) {\n      const selections = [{ ...channels[channelId].selection }];\n      let domains;\n      const hasDomainChanged = newDomainType !== domainType;\n      const has3dChanged = use3d !== newUse3d;\n      const hasSelectionChanged = !isEqual(selections, selection);\n      if (hasDomainChanged || hasSelectionChanged || has3dChanged) {\n        if (newDomainType === 'Full') {\n          domains = [DOMAINS[dtype]];\n          const [newDomain] = domains;\n          if (mounted) {\n            setDomain(newDomain);\n            setDomainType(newDomainType);\n            if (hasSelectionChanged) {\n              setSelection(selections);\n            }\n            if (has3dChanged) {\n              setUse3d(newUse3d);\n            }\n          }\n        } else {\n          getMultiSelectionStats({\n            loader: loader.data,\n            selections,\n            use3d: newUse3d,\n          }).then((stats) => {\n            // eslint-disable-next-line prefer-destructuring\n            domains = stats.domains;\n            const [newDomain] = domains;\n            if (mounted) {\n              setDomain(newDomain);\n              setDomainType(newDomainType);\n              if (hasSelectionChanged) {\n                setSelection(selections);\n              }\n              if (has3dChanged) {\n                setUse3d(newUse3d);\n              }\n            }\n          });\n        }\n      }\n    }\n    return () => {\n      mounted = false;\n    };\n  }, [\n    domainType,\n    channels,\n    channelId,\n    loader,\n    dtype,\n    newDomainType,\n    selection,\n    newUse3d,\n    use3d,\n  ]);\n  /* A valid selection is defined by an object where the keys are\n   *  the name of a dimension of the data, and the values are the\n   *  index of the image along that particular dimension.\n   *\n   *  Since we currently only support making a selection along one\n   *  addtional dimension (i.e. the dropdown just has channels or mz)\n   *  we have a helper function to create the selection.\n   *\n   *  e.g { channel: 2 } // channel dimension, third channel\n   */\n  const createSelection = index => ({ [dimName]: index });\n  return (\n    <Grid container direction=\"column\" m={1} justifyContent=\"center\">\n      <Grid container direction=\"row\" justifyContent=\"space-between\">\n        <Grid item xs={10}>\n          <ChannelSelectionDropdown\n            handleChange={v => handlePropertyChange('selection', createSelection(v))\n            }\n            selectionIndex={selectionIndex}\n            channelOptions={channelOptions}\n            disabled={isLoading}\n          />\n        </Grid>\n        <Grid item xs={1} style={{ marginTop: '4px' }}>\n          <ChannelOptions\n            handlePropertyChange={handlePropertyChange}\n            handleChannelRemove={handleChannelRemove}\n            handleIQRUpdate={handleIQRUpdate}\n            disabled={isLoading}\n          />\n        </Grid>\n      </Grid>\n      <Grid container direction=\"row\" justifyContent=\"space-between\">\n        <Grid item xs={2}>\n          <ChannelVisibilityCheckbox\n            color={rgbColor}\n            checked={visibility}\n            toggle={() => handlePropertyChange('visible', !visibility)}\n            disabled={isLoading}\n          />\n        </Grid>\n        <Grid item xs={9}>\n          <ChannelSlider\n            color={rgbColor}\n            slider={slider}\n            domain={domain || DOMAINS[dtype]}\n            dtype={dtype}\n            handleChange={v => handlePropertyChange('slider', v)}\n            disabled={isLoading}\n          />\n        </Grid>\n      </Grid>\n    </Grid>\n  );\n}\n\nexport default RasterChannelController;\n","import React from 'react';\n\nimport RemoveCircleIcon from '@material-ui/icons/RemoveCircle';\nimport IconButton from '@material-ui/core/IconButton';\n\nimport Grid from '@material-ui/core/Grid';\n\nimport { ChannelSelectionDropdown, ChannelVisibilityCheckbox } from './shared-channel-controls';\n\n/**\n * Controller for the handling the bitmask channels.\n * @prop {boolean} visibility Whether or not this channel is \"on\"\n * @prop {string} dimName Name of the dimensions this slider controls (usually \"channel\").\n * @prop {object} channelOptions All available options for this dimension (i.e channel names).\n * @prop {function} handlePropertyChange Callback for when a property (color, slider etc.) changes.\n * @prop {function} handleChannelRemove When a channel is removed, this is called.\n * @prop {number} selectionIndex The current numeric index of the selection.\n * @prop {boolean} disableOptions Whether or not channel options are be disabled (default: false).\n */\nfunction BitmaskChannelController({\n  visibility = false,\n  dimName,\n  channelOptions,\n  handlePropertyChange,\n  handleChannelRemove,\n  selectionIndex,\n  disableOptions = false,\n}) {\n  /* A valid selection is defined by an object where the keys are\n  *  the name of a dimension of the data, and the values are the\n  *  index of the image along that particular dimension.\n  *\n  *  Since we currently only support making a selection along one\n  *  addtional dimension (i.e. the dropdown just has channels or mz)\n  *  we have a helper function to create the selection.\n  *\n  *  e.g { channel: 2 } // channel dimension, third channel\n  */\n  const createSelection = index => ({ [dimName]: index });\n  return (\n    <Grid container direction=\"row\" justify=\"space-between\">\n      <Grid item xs={2}>\n        <ChannelVisibilityCheckbox\n          color={[220, 220, 220]}\n          checked={visibility}\n          toggle={() => handlePropertyChange('visible', !visibility)}\n        />\n      </Grid>\n      <Grid item xs={9}>\n        <ChannelSelectionDropdown\n          handleChange={v => handlePropertyChange('selection', createSelection(v))}\n          selectionIndex={selectionIndex}\n          disableOptions={disableOptions}\n          channelOptions={channelOptions}\n        />\n      </Grid>\n      <Grid item xs={1}>\n        <IconButton onClick={handleChannelRemove} style={{ padding: '6px 6px 6px 0px' }}>\n          <RemoveCircleIcon />\n        </IconButton>\n      </Grid>\n    </Grid>\n  );\n}\n\nexport default BitmaskChannelController;\n","import React from 'react';\n\nimport Grid from '@material-ui/core/Grid';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport Slider from '@material-ui/core/Slider';\nimport { useControllerSectionStyles } from './styles';\n\nexport default function VectorLayerController(props) {\n  const {\n    label,\n    layer,\n    layerType,\n    handleLayerChange,\n  } = props;\n\n  const slider = layer.opacity;\n  const isOn = layer.visible;\n\n  function handleSliderChange(v) {\n    if (layerType === 'cells') {\n      const stroked = v < 0.7;\n      handleLayerChange({ ...layer, opacity: v, stroked });\n    } else {\n      handleLayerChange({ ...layer, opacity: v });\n    }\n  }\n\n  function handleCheckBoxChange(v) {\n    handleLayerChange({ ...layer, visible: v });\n  }\n\n  const classes = useControllerSectionStyles();\n  return (\n    <Grid item style={{ marginTop: '10px' }}>\n      <Paper className={classes.root}>\n        <Typography\n          style={{\n            padding: '15px 8px 0px 8px',\n            marginBottom: '-5px',\n          }}\n        >\n          {label}\n        </Typography>\n        <Grid container direction=\"row\" justifyContent=\"space-between\">\n          <Grid item xs={2}>\n            <Checkbox color=\"primary\" checked={isOn} onChange={(e, v) => handleCheckBoxChange(v)} />\n          </Grid>\n          <Grid item xs={9} style={{ paddingRight: '8px' }}>\n            <Slider\n              value={slider}\n              min={0}\n              max={1}\n              step={0.001}\n              onChange={(e, v) => handleSliderChange(v)}\n              style={{ marginTop: '7px' }}\n              orientation=\"horizontal\"\n            />\n          </Grid>\n        </Grid>\n      </Paper>\n    </Grid>\n  );\n}\n","import React from 'react';\nimport range from 'lodash/range';\nimport { Matrix4 } from 'math.gl';\nimport Grid from '@material-ui/core/Grid';\nimport Slider from '@material-ui/core/Slider';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport Select from '@material-ui/core/Select';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport { getDefaultInitialViewState } from '@hms-dbmi/viv';\n\nimport {\n  getBoundingCube, getMultiSelectionStats,\n} from './utils';\nimport {\n  COLORMAP_OPTIONS,\n  canLoadResolution,\n  formatBytes,\n  getStatsForResolution,\n} from '../utils';\nimport { DEFAULT_RASTER_DOMAIN_TYPE } from '../spatial/constants';\nimport { StyledSelectionSlider, useSelectStyles } from './styles';\n\nconst DOMAIN_OPTIONS = ['Full', 'Min/Max'];\n\n/**\n * Wrapper for the dropdown that selects a colormap (None, viridis, magma, etc.).\n * @prop {Object} loader Loader object with metadata.\n * @prop {function} handleMultiPropertyChange Function to propgate multiple layer changes at once.\n * This prevents updates from overridding each other.\n * @prop {number} resolution Current 3D resolution.\n * @prop {boolean} disable3d Whether or not to enable 3D selection\n * @prop {function} setRasterLayerCallback Setter for callbacks that fire after raster/volume loads.\n * @prop {function} setAreAllChannelsLoading Setter for whether or not a given channel is loading.\n * @prop {Object} setViewState Setter for the current view state.\n * @prop {number} spatialHeight Height of the spatial component.\n * @prop {number} spatialWidth Width of the spatial component.\n * @prop {object} channels Channels object.\n * @prop {boolean} use3d Whether or not 3D is enabled for this layer.\n */\nfunction VolumeDropdown({\n  loader: loaderWithMeta,\n  handleMultiPropertyChange,\n  resolution: currResolution,\n  disable3d,\n  setRasterLayerCallback,\n  setAreAllChannelsLoading,\n  setViewState,\n  spatialHeight,\n  spatialWidth,\n  channels,\n  use3d,\n  modelMatrix,\n}) {\n  const classes = useSelectStyles();\n  const selections = channels.map(i => i.selection);\n  const { data: loader } = loaderWithMeta;\n  const handleChange = async (val) => {\n    // val is the resolution - null indicates 2D\n    const shouldUse3D = typeof val === 'number';\n    setAreAllChannelsLoading(true);\n    setRasterLayerCallback(() => {\n      setAreAllChannelsLoading(false);\n      setRasterLayerCallback(null);\n    });\n    if (shouldUse3D) {\n      const [xSlice, ySlice, zSlice] = getBoundingCube(loader);\n      const propertiesChanged = {\n        resolution: val,\n        xSlice,\n        ySlice,\n        zSlice,\n        use3d: shouldUse3D,\n      };\n      // Only make the fetch if needed i.e if the 3d was just being turned on.\n      if (!use3d) {\n        const { sliders } = await getMultiSelectionStats({\n          loader,\n          selections,\n          use3d: shouldUse3D,\n        });\n        propertiesChanged.channels = [...channels];\n        propertiesChanged.channels.forEach((ch, i) => {\n          // eslint-disable-next-line no-param-reassign\n          ch.slider = sliders[i];\n        });\n      }\n      // Update all properties at once to avoid overriding calls.\n      handleMultiPropertyChange(propertiesChanged);\n      const defaultViewState = getDefaultInitialViewState(loader,\n        { height: spatialHeight, width: spatialWidth }, 1.5, true, new Matrix4(modelMatrix));\n      setViewState({\n        ...defaultViewState,\n        rotationX: 0,\n        rotationOrbit: 0,\n      });\n    } else {\n      const { sliders } = await getMultiSelectionStats({\n        loader, selections, use3d: shouldUse3D,\n      });\n      const newChannels = [...channels];\n      newChannels.forEach((ch, i) => {\n        // eslint-disable-next-line no-param-reassign\n        ch.slider = sliders[i];\n      });\n      // Update all properties at once to avoid overriding calls.\n      handleMultiPropertyChange({\n        resolution: val,\n        use3d: shouldUse3D,\n        spatialAxisFixed: false,\n        channels: newChannels,\n      });\n      const defaultViewState = getDefaultInitialViewState(loader,\n        { height: spatialHeight, width: spatialWidth }, 0.5, false, new Matrix4(modelMatrix));\n      setViewState({\n        ...defaultViewState,\n        rotationX: null,\n        rotationOrbit: null,\n        orbitAxis: null,\n      });\n    }\n  };\n  const { labels, shape } = Array.isArray(loader) ? loader[0] : loader;\n  const hasZStack = shape[labels.indexOf('z')] > 1;\n  return (\n    <>\n      <Select\n        native\n        value={currResolution}\n        onChange={e => handleChange(\n          e.target.value === '2D' ? e.target.value : Number(e.target.value),\n        )\n        }\n        classes={{ root: classes.selectRoot }}\n      >\n        {\n          <option key=\"2D\" value=\"2D\">\n            2D Visualization\n          </option>\n        }\n        {Array.from({ length: loader.length })\n          .fill(0)\n          // eslint-disable-next-line no-unused-vars\n          .map((_, resolution) => {\n            if (loader) {\n              if (canLoadResolution(loader, resolution)) {\n                const {\n                  height,\n                  width,\n                  depthDownsampled,\n                  totalBytes,\n                } = getStatsForResolution(loader, resolution);\n                return (\n                  <option\n                    key={`(${height}, ${width}, ${depthDownsampled})`}\n                    value={resolution}\n                    disabled={\n                      disable3d\n                      || !hasZStack\n                    }\n                  >\n                    {`3D: ${resolution}x Downsampled, ~${formatBytes(\n                      totalBytes,\n                    )} per channel, (${height}, ${width}, ${depthDownsampled})`}\n                  </option>\n                );\n              }\n            }\n            return null;\n          })}\n      </Select>\n    </>\n  );\n}\n\n\n/**\n * Wrapper for the dropdown that selects a colormap (None, viridis, magma, etc.).\n * @prop {string} value Currently selected value for the colormap.\n * @prop {string} inputId Css id.\n * @prop {function} handleChange Callback for every change in colormap.\n */\nfunction ColormapSelect({ value, inputId, handleChange }) {\n  const classes = useSelectStyles();\n  return (\n    <Select\n      native\n      onChange={e => handleChange(e.target.value === '' ? null : e.target.value)}\n      value={value}\n      inputProps={{ name: 'colormap', id: inputId }}\n      style={{ width: '100%' }}\n      classes={{ root: classes.selectRoot }}\n    >\n      <option aria-label=\"None\" value=\"\">None</option>\n      {COLORMAP_OPTIONS.map(name => (\n        <option key={name} value={name}>\n          {name}\n        </option>\n      ))}\n    </Select>\n  );\n}\n\nfunction TransparentColorCheckbox({ value, handleChange }) {\n  return (\n    <Checkbox\n      style={{ float: 'left', padding: 0 }}\n      color=\"default\"\n      onChange={() => {\n        if (value) {\n          handleChange(null);\n        } else {\n          handleChange([0, 0, 0]);\n        }\n      }}\n      checked={Boolean(value)}\n    />\n  );\n}\n\n/**\n * Wrapper for the slider that updates opacity.\n * @prop {string} value Currently selected value between 0 and 1.\n * @prop {function} handleChange Callback for every change in opacity.\n */\nfunction OpacitySlider({ value, handleChange }) {\n  return (\n    <Slider\n      value={value}\n      onChange={(e, v) => handleChange(v)}\n      valueLabelDisplay=\"auto\"\n      getAriaLabel={() => 'opacity slider'}\n      min={0}\n      max={1}\n      step={0.01}\n      orientation=\"horizontal\"\n      style={{ marginTop: '7px' }}\n    />\n  );\n}\n\n/**\n * Wrapper for the dropdown that chooses the domain type.\n * @prop {string} value Currently selected value (i.e 'Max/Min').\n * @prop {string} inputId Css id.\n * @prop {function} handleChange Callback for every change in domain.\n */\nfunction SliderDomainSelector({ value, inputId, handleChange }) {\n  const classes = useSelectStyles();\n  return (\n    <Select\n      native\n      onChange={e => handleChange(e.target.value)}\n      value={value}\n      inputProps={{ name: 'domain-selector', id: inputId }}\n      style={{ width: '100%' }}\n      classes={{ root: classes.selectRoot }}\n    >\n      {DOMAIN_OPTIONS.map(name => (\n        <option key={name} value={name}>\n          {name}\n        </option>\n      ))}\n    </Select>\n  );\n}\n\n/**\n * Wrapper for the slider that chooses global selections (z, t etc.).\n * @prop {string} field The dimension this selects for (z, t etc.).\n * @prop {number} value Currently selected index (1, 4, etc.).\n * @prop {function} handleChange Callback for every change in selection.\n * @prop {function} possibleValues All available values for the field.\n */\nfunction GlobalSelectionSlider({\n  field,\n  value,\n  handleChange,\n  possibleValues,\n}) {\n  return (\n    <StyledSelectionSlider\n      value={value}\n      // See https://github.com/hms-dbmi/viv/issues/176 for why\n      // we have the two handlers.\n      onChange={\n        (event, newValue) => {\n          handleChange({ selection: { [field]: newValue }, event });\n        }\n      }\n      onChangeCommitted={\n        (event, newValue) => {\n          handleChange({ selection: { [field]: newValue }, event });\n        }\n      }\n      valueLabelDisplay=\"auto\"\n      getAriaLabel={() => `${field} slider`}\n      marks={possibleValues.map(val => ({ value: val }))}\n      min={Number(possibleValues[0])}\n      max={Number(possibleValues.slice(-1))}\n      orientation=\"horizontal\"\n      step={null}\n    />\n  );\n}\n\n/**\n * Wrapper for each of the options to show its name and then its UI component.\n * @prop {string} name Display name for option.\n * @prop {number} opacity Current opacity value.\n * @prop {string} inputId An id for css.\n * @prop {object} children Components to be rendered next to the name (slider, dropdown etc.).\n */\nfunction LayerOption({ name, inputId, children }) {\n  return (\n    <Grid container direction=\"row\" alignItems=\"center\" justifyContent=\"center\">\n      <Grid item xs={6}>\n        <InputLabel htmlFor={inputId}>{name}:</InputLabel>\n      </Grid>\n      <Grid item xs={6}>\n        {children}\n      </Grid>\n    </Grid>\n  );\n}\n\n/**\n * Gloabl options for all channels (opacity, colormap, etc.).\n * @prop {string} colormap What colormap is currently selected (None, viridis etc.).\n * @prop {number} opacity Current opacity value.\n * @prop {function} handleColormapChange Callback for when colormap changes.\n * @prop {function} handleOpacityChange Callback for when opacity changes.\n * @prop {object} globalControlLabels All available options for global control (z and t).\n * @prop {function} handleGlobalChannelsSelectionChange Callback for global selection changes.\n * @prop {function} handleDomainChange Callback for domain type changes (full or min/max).\n * @prop {array} channels Current channel object for inferring the current global selection.\n * @prop {array} dimensions Currently available dimensions (channel, z, t etc.).\n * @prop {string} domainType One of Max/Min or Full (soon presets as well).\n * @prop {boolean} disableChannelsIfRgbDetected Whether or not we need colormap controllers if RGB.\n */\nfunction LayerOptions({\n  colormap,\n  opacity,\n  handleColormapChange,\n  handleOpacityChange,\n  handleTransparentColorChange,\n  globalControlLabels,\n  globalLabelValues,\n  handleGlobalChannelsSelectionChange,\n  handleSliderChange,\n  handleDomainChange,\n  transparentColor,\n  channels,\n  domainType,\n  disableChannelsIfRgbDetected,\n  shouldShowTransparentColor,\n  shouldShowDomain,\n  shouldShowColormap,\n  use3d,\n  loader,\n  handleMultiPropertyChange,\n  resolution,\n  disable3d,\n  setRasterLayerCallback,\n  setAreAllChannelsLoading,\n  setViewState,\n  spatialHeight,\n  spatialWidth,\n  modelMatrix,\n}) {\n  const { labels, shape } = Array.isArray(loader.data) ? loader.data[0] : loader.data;\n  const hasDimensionsAndChannels = labels.length > 0 && channels.length > 0;\n  const hasZStack = shape[labels.indexOf('z')] > 1;\n  // Only show volume button if we can actually view resolutions.\n  const hasViewableResolutions = Boolean(Array.from({\n    length: loader.data.length,\n  }).filter((_, res) => canLoadResolution(loader.data, res)).length);\n  return (\n    <Grid container direction=\"column\" style={{ width: '100%' }}>\n      {hasZStack\n        && !disable3d\n        && hasViewableResolutions\n        && (\n        <VolumeDropdown\n          loader={loader}\n          handleSliderChange={handleSliderChange}\n          handleDomainChange={handleDomainChange}\n          channels={channels}\n          handleMultiPropertyChange={handleMultiPropertyChange}\n          resolution={resolution}\n          disable3d={disable3d}\n          setRasterLayerCallback={setRasterLayerCallback}\n          setAreAllChannelsLoading={setAreAllChannelsLoading}\n          setViewState={setViewState}\n          spatialHeight={spatialHeight}\n          spatialWidth={spatialWidth}\n          use3d={use3d}\n          modelMatrix={modelMatrix}\n        />\n        )\n      }\n      {hasDimensionsAndChannels\n        && !use3d\n        && globalControlLabels.map(\n          field => shape[labels.indexOf(field)] > 1 && (\n          <LayerOption name={field} inputId={`${field}-slider`} key={field}>\n            <GlobalSelectionSlider\n              field={field}\n              value={globalLabelValues[field]}\n              handleChange={handleGlobalChannelsSelectionChange}\n              possibleValues={range(shape[labels.indexOf(field)])}\n            />\n          </LayerOption>\n          ),\n        )}\n      {!disableChannelsIfRgbDetected ? (\n        <>\n          {shouldShowColormap && (\n            <Grid item>\n              <LayerOption name=\"Colormap\" inputId=\"colormap-select\">\n                <ColormapSelect\n                  value={colormap || ''}\n                  inputId=\"colormap-select\"\n                  handleChange={handleColormapChange}\n                />\n              </LayerOption>\n            </Grid>\n          )}\n          {shouldShowDomain && (\n            <Grid item>\n              <LayerOption name=\"Domain\" inputId=\"domain-selector\">\n                <SliderDomainSelector\n                  value={domainType || DEFAULT_RASTER_DOMAIN_TYPE}\n                  handleChange={(value) => {\n                    handleDomainChange(value);\n                  }}\n                />\n              </LayerOption>\n            </Grid>\n          )}\n        </>\n      ) : null}\n      {!use3d && (\n        <Grid item>\n          <LayerOption name=\"Opacity\" inputId=\"opacity-slider\">\n            <OpacitySlider value={opacity} handleChange={handleOpacityChange} />\n          </LayerOption>\n        </Grid>\n      )}\n      {shouldShowTransparentColor && !use3d && (\n        <Grid item>\n          <LayerOption\n            name=\"Zero Transparent\"\n            inputId=\"transparent-color-selector\"\n          >\n            <TransparentColorCheckbox\n              value={transparentColor}\n              handleChange={handleTransparentColorChange}\n            />\n          </LayerOption>\n        </Grid>\n      )}\n    </Grid>\n  );\n}\n\nexport default LayerOptions;\n","import React from 'react';\nimport { Matrix4 } from 'math.gl';\nimport Grid from '@material-ui/core/Grid';\nimport Typography from '@material-ui/core/Typography';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles, createStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport Select from '@material-ui/core/Select';\nimport InputLabel from '@material-ui/core/InputLabel';\nimport Slider from '@material-ui/core/Slider';\nimport { RENDERING_MODES, getDefaultInitialViewState } from '@hms-dbmi/viv';\nimport { abbreviateNumber, getBoundingCube } from './utils';\nimport { useSelectStyles } from './styles';\n\nconst useSlicerStyles = makeStyles(theme => createStyles({\n  enabled: {},\n  disabled: {\n    color: theme.palette.text.disabled,\n    // Because of the .5 opacity of the disabled color in the theme, and the fact\n    // that there are multiple overlaid parts to the slider,\n    // this needs to be set manually for the desired effect.\n    '& .MuiSlider-thumb': {\n      color: 'rgb(100, 100, 100, 1.0)',\n    },\n    '&  .MuiSlider-track': {\n      color: 'rgb(100, 100, 100, 1.0)',\n    },\n  },\n}));\n\nconst Slicer = ({\n  xSlice,\n  ySlice,\n  zSlice,\n  handleSlicerSetting,\n  loader,\n  use3d,\n}) => {\n  const [xSliceInit, ySliceInit, zSliceInit] = getBoundingCube(loader.data);\n  const sliceValuesAndSetSliceFunctions = [\n    [\n      xSlice,\n      xSliceNew => handleSlicerSetting('x', xSliceNew),\n      'x',\n      xSliceInit,\n    ],\n    [\n      ySlice,\n      ySliceNew => handleSlicerSetting('y', ySliceNew),\n      'y',\n      ySliceInit,\n    ],\n    [\n      zSlice,\n      zSliceNew => handleSlicerSetting('z', zSliceNew),\n      'z',\n      zSliceInit,\n    ],\n  ];\n  const classes = useSlicerStyles();\n  const Slicers = sliceValuesAndSetSliceFunctions.map(\n    ([val, setVal, label, [min, max]]) => (\n      <Grid\n        container\n        direction=\"row\"\n        justifyContent=\"flex-start\"\n        alignItems=\"center\"\n        key={label}\n      >\n        <Grid item xs={1}>\n          <Typography\n            className={!use3d ? classes.disabled : classes.enabled}\n            style={{ marginBottom: 0 }}\n          >\n            {label}:\n          </Typography>\n        </Grid>\n        <Grid item xs={11}>\n          <Slider\n            disabled={!use3d}\n            className={!use3d ? classes.disabled : classes.enabled}\n            value={val}\n            onChange={(e, v) => setVal(v)}\n            valueLabelDisplay=\"auto\"\n            valueLabelFormat={v => abbreviateNumber(v)}\n            getAriaLabel={() => `${label} slider`}\n            min={min}\n            max={max}\n            step={0.005}\n            orientation=\"horizontal\"\n          />\n        </Grid>\n      </Grid>\n    ),\n  );\n  return (\n    <>\n      <Typography\n        className={!use3d ? classes.disabled : classes.enabled}\n        style={{ marginTop: 16, marginBottom: 0 }}\n      >\n        Clipping Planes:{' '}\n      </Typography>{' '}\n      {Slicers}\n    </>\n  );\n};\n\nconst renderingOptions = Object.values(RENDERING_MODES);\n\nfunction RenderingModeSelect({\n  handleRenderingModeChange,\n  renderingMode,\n  use3d,\n}) {\n  const classes = useSelectStyles();\n  // Empty option allows for displaying the title of the dropdown fully in the UI.\n  const options = !use3d ? [...renderingOptions, ''] : renderingOptions;\n  return (\n    <FormControl fullWidth>\n      <InputLabel htmlFor=\"rendering-mode-select\">Rendering Mode</InputLabel>\n      <Select\n        native\n        onChange={e => handleRenderingModeChange(e.target.value)}\n        value={use3d ? renderingMode : ''}\n        inputProps={{\n          name: 'rendering-mode',\n          id: 'rendering-mode-select',\n        }}\n        disabled={!use3d}\n        classes={{ root: classes.selectRoot }}\n      >\n        {options.map(name => (\n          <option key={name} value={name}>\n            {name}\n          </option>\n        ))}\n      </Select>\n    </FormControl>\n  );\n}\n\nconst ReCenterButton = ({\n  setViewState,\n  use3d,\n  spatialHeight,\n  spatialWidth,\n  loader,\n  modelMatrix,\n}) => (\n  <Grid item xs=\"auto\" key=\"recenter\">\n    <Button\n      onClick={() => {\n        const defaultViewState = getDefaultInitialViewState(\n          loader.data,\n          { height: spatialHeight, width: spatialWidth },\n          1.5,\n          use3d,\n          new Matrix4(modelMatrix),\n        );\n        setViewState({\n          ...defaultViewState,\n          rotationX: 0,\n          rotationOrbit: 0,\n        });\n      }\n        }\n      disabled={!use3d}\n      style={{\n        padding: 0,\n        marginBottom: 6,\n      }}\n    >\n        Re-Center\n    </Button>\n  </Grid>\n);\n\nconst VolumeOptions = ({\n  handleSlicerSetting,\n  handleRenderingModeChange,\n  renderingMode,\n  xSlice,\n  ySlice,\n  zSlice,\n  use3d,\n  loader,\n  setViewState,\n  spatialHeight,\n  spatialWidth,\n  modelMatrix,\n}) => (\n  <>\n    <RenderingModeSelect\n      handleRenderingModeChange={handleRenderingModeChange}\n      renderingMode={renderingMode}\n      use3d={use3d}\n    />\n    <Slicer\n      xSlice={xSlice}\n      ySlice={ySlice}\n      zSlice={zSlice}\n      handleSlicerSetting={handleSlicerSetting}\n      use3d={use3d}\n      loader={loader}\n    />\n    <ReCenterButton\n      setViewState={setViewState}\n      use3d={use3d}\n      spatialHeight={spatialHeight}\n      spatialWidth={spatialWidth}\n      loader={loader}\n      modelMatrix={modelMatrix}\n    />\n  </>\n);\n\nexport default VolumeOptions;\n","import React, { useState, useRef, useEffect } from 'react';\nimport { MAX_CHANNELS, getChannelStats } from '@hms-dbmi/viv';\n\nimport Grid from '@material-ui/core/Grid';\nimport Button from '@material-ui/core/Button';\nimport AddIcon from '@material-ui/icons/Add';\nimport Slider from '@material-ui/core/Slider';\nimport Tabs from '@material-ui/core/Tabs';\nimport Tab from '@material-ui/core/Tab';\n\nimport Accordion from '@material-ui/core/Accordion';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport VisibilityIcon from '@material-ui/icons/Visibility';\nimport VisibilityOffIcon from '@material-ui/icons/VisibilityOff';\n\nimport LayerOptions from './LayerOptions';\nimport VolumeOptions from './VolumeOptions';\nimport {\n  useControllerSectionStyles,\n  StyledAccordionDetails,\n  StyledAccordionSummary,\n  StyledInputLabel,\n  OverflowEllipsisGrid,\n} from './styles';\nimport { getMultiSelectionStats } from './utils';\n\nimport { GLOBAL_LABELS } from '../spatial/constants';\nimport { getSourceFromLoader, isRgb } from '../../utils';\nimport { canLoadResolution } from '../utils';\nimport { DOMAINS } from './constants';\n\nfunction TabPanel(props) {\n  const {\n    children, value, index, ...other\n  } = props;\n\n  return (\n    <div\n      role=\"tabpanel\"\n      hidden={value !== index}\n      id={`simple-tabpanel-${index}`}\n      aria-labelledby={`simple-tab-${index}`}\n      {...other}\n    >\n      {value === index && children}\n    </div>\n  );\n}\n\n// Set the domain of the sliders based on either a full range or min/max.\nasync function getDomainsAndSliders(loader, selections, domainType, use3d) {\n  let domains;\n  const stats = await getMultiSelectionStats({\n    loader: loader.data,\n    selections,\n    use3d,\n  });\n  const { sliders } = stats;\n  if (domainType === 'Min/Max') {\n    // eslint-disable-next-line prefer-destructuring\n    domains = stats.domains;\n  }\n  if (domainType === 'Full') {\n    const source = getSourceFromLoader(loader);\n    domains = selections.map(() => DOMAINS[source.dtype]);\n  }\n  return { domains, sliders };\n}\n\nconst buttonStyles = {\n  borderStyle: 'dashed',\n  marginTop: '10px',\n  fontWeight: 400,\n};\n\n/**\n * Controller for the various imaging options (color, opactiy, sliders etc.)\n * @prop {object} imageData Image config object, one of the `images` in the raster schema.\n * @prop {object} layerId Randomly generated id for the image layer that this controller handles.\n * @prop {function} handleLayerRemove Callback for handling the removal of a layer.\n * @prop {object} loader Loader object for the current imaging layer.\n * @prop {function} handleLayerChange Callback for handling the changing of layer properties.\n */\nexport default function LayerController(props) {\n  const {\n    layer,\n    name,\n    loader,\n    theme,\n    handleLayerRemove,\n    handleLayerChange,\n    shouldShowTransparentColor,\n    shouldShowDomain,\n    shouldShowColormap,\n    ChannelController,\n    setViewState,\n    disable3d,\n    setRasterLayerCallback,\n    setAreLayerChannelsLoading,\n    areLayerChannelsLoading,\n    disabled,\n    spatialHeight,\n    spatialWidth,\n    disableChannelsIfRgbDetected,\n    shouldShowRemoveLayerButton,\n  } = props;\n\n  const {\n    colormap,\n    opacity,\n    channels,\n    transparentColor,\n    renderingMode,\n    xSlice,\n    ySlice,\n    zSlice,\n    resolution,\n    use3d,\n    modelMatrix,\n  } = layer;\n  // Channels are used in a lot of callbacks and change handlers\n  // so ensuring they have an up to date copy of the data ensures consistency.\n  // See: https://github.com/vitessce/vitessce/issues/1036\n  const channelRef = useRef(channels);\n  useEffect(() => {\n    channelRef.current = channels;\n    return undefined;\n  }, [channels]);\n\n  const firstSelection = channels[0]?.selection || {};\n\n  const { data, channels: channelOptions } = loader;\n  const [tab, setTab] = useState(0);\n\n  const handleTabChange = (event, newTab) => {\n    setTab(newTab);\n  };\n  const { labels, shape } = Array.isArray(data) ? data[data.length - 1] : data;\n  const [domainType, setDomainType] = useState(layer.domainType);\n  const [isExpanded, setIsExpanded] = useState(true);\n  const [globalLabelValues, setGlobalLabelValues] = useState(\n    GLOBAL_LABELS.filter(\n      field => typeof firstSelection[field] === 'number',\n    ).reduce((o, key) => ({ ...o, [key]: firstSelection[key] }), {}),\n  );\n\n  function setVisible(v) {\n    handleLayerChange({ ...layer, visible: v });\n  }\n\n  function setColormap(v) {\n    handleLayerChange({ ...layer, colormap: v });\n  }\n\n  function setOpacity(v) {\n    handleLayerChange({ ...layer, opacity: v });\n  }\n\n  function setChannels(v) {\n    handleLayerChange({ ...layer, channels: v });\n  }\n  function setTransparentColor(v) {\n    handleLayerChange({ ...layer, transparentColor: v });\n  }\n  function setRenderingMode(v) {\n    handleLayerChange({ ...layer, renderingMode: v });\n  }\n\n  function handleMultiPropertyChange(obj) {\n    handleLayerChange({ ...layer, ...obj });\n  }\n\n  function handleSlicerSetting(slice, val) {\n    handleLayerChange({ ...layer, [`${slice}Slice`]: val });\n  }\n\n  function setChannelsAndDomainType(newChannels, newDomainType) {\n    handleLayerChange({\n      ...layer,\n      channels: newChannels,\n      domainType: newDomainType,\n    });\n  }\n\n  function setChannel(v, i) {\n    const newChannels = [...channelRef.current];\n    newChannels[i] = v;\n    handleLayerChange({ ...layer, channels: newChannels });\n  }\n\n  function addChannel(v) {\n    const newChannels = [...channelRef.current, v];\n    handleLayerChange({ ...layer, channels: newChannels });\n  }\n\n  function removeChannel(i) {\n    const newChannels = [...channelRef.current];\n    newChannels.splice(i, 1);\n    handleLayerChange({ ...layer, channels: newChannels });\n  }\n\n  const setAreAllChannelsLoading = (val) => {\n    const newAreLayerChannelsLoading = channelRef.current.map(() => val);\n    setAreLayerChannelsLoading(newAreLayerChannelsLoading);\n  };\n\n  // Handles adding a channel, creating a default selection\n  // for the current global settings and domain type.\n  const handleChannelAdd = async () => {\n    const selection = {};\n    labels.forEach((label) => {\n      // Set new image to default selection for non-global selections (0)\n      // and use current global selection otherwise.\n      selection[label] = GLOBAL_LABELS.includes(label)\n        ? globalLabelValues[label] || 0\n        : 0;\n    });\n    const { domains, sliders } = await getDomainsAndSliders(\n      loader,\n      [selection],\n      domainType,\n      use3d,\n    );\n    const domain = domains[0];\n    const slider = domain;\n    const color = [255, 255, 255];\n    const visible = true;\n    const newChannelId = channels.length;\n    const newAreLayerChannelsLoading = [...areLayerChannelsLoading];\n    newAreLayerChannelsLoading[newChannelId] = true;\n    setAreLayerChannelsLoading(newAreLayerChannelsLoading);\n    const channel = {\n      selection,\n      slider,\n      visible,\n      color,\n    };\n    setRasterLayerCallback(() => {\n      setChannel({ ...channel, slider: sliders[0] }, newChannelId);\n      const areLayerChannelsLoadingCallback = [...newAreLayerChannelsLoading];\n      areLayerChannelsLoadingCallback[newChannelId] = false;\n      setAreLayerChannelsLoading(areLayerChannelsLoadingCallback);\n      setRasterLayerCallback(null);\n    });\n    addChannel(channel);\n  };\n\n  const handleDomainChange = async (value) => {\n    setDomainType(value);\n    const selections = channels.map(channel => channel.selection);\n    let sliders = channels.map(channel => channel.slider);\n    const { domains } = await getDomainsAndSliders(\n      loader,\n      selections,\n      value,\n      use3d,\n    );\n\n    // If it's the right-most slider, we take the minimum of that and the new value.\n    // Otherwise, we use the maximum of the left-hand side and the new value.\n    sliders = sliders.map((slider, i) => {\n      const [left, right] = slider;\n      return [Math.max(left, domains[i][0]), Math.min(right, domains[i][1])];\n    });\n\n    const newChannels = channels.map((c, i) => ({ ...c, slider: sliders[i] }));\n    setChannelsAndDomainType(newChannels, value);\n  };\n\n  // This call updates all channel selections with new global selection from the UI.\n  const handleGlobalChannelsSelectionChange = async ({ selection, event }) => {\n    const selections = channels.map(channel => ({\n      ...channel.selection,\n      ...selection,\n    }));\n    const canUpdateChannels = event.type === 'mouseup' || event.type === 'keydown';\n    // Only update domains on a mouseup event for the same reason as above.\n    if (canUpdateChannels) {\n      setAreAllChannelsLoading(true);\n      getDomainsAndSliders(loader, selections, domainType, use3d).then(\n        ({ sliders }) => {\n          const newChannelsWithSelection = channels.map(c => ({\n            ...c,\n            selection: { ...c.selection, ...selection },\n          }));\n          // Set the callback before changing the selection\n          // so the callback is used when the layer (re)loads its data.\n          setRasterLayerCallback(() => {\n            setRasterLayerCallback(null);\n            setAreAllChannelsLoading(false);\n            const newChannelsWithSliders = [...newChannelsWithSelection].map(\n              (c, i) => ({\n                ...c,\n                slider: sliders[i],\n              }),\n            );\n            setChannels(newChannelsWithSliders);\n          });\n          setChannels(newChannelsWithSelection);\n        },\n      );\n    }\n    setGlobalLabelValues(prev => ({ ...prev, ...selection }));\n  };\n\n  let channelControllers = [];\n  if (labels.length > 0) {\n    const channelLabel = labels.find(c => c === 'channel' || c === 'c') || labels[0];\n    // Create the channel controllers for each channel.\n    channelControllers = channels.map(\n      // c is an object like { color, selection, slider, visible }.\n      (c, channelId) => {\n        // Update the auxiliary store with the current loading state of a channel.\n        const setIsLoading = (val) => {\n          const newAreLayerChannelsLoading = [...areLayerChannelsLoading];\n          newAreLayerChannelsLoading[channelId] = val;\n          setAreLayerChannelsLoading(newAreLayerChannelsLoading);\n        };\n        // Change one property of a channel (for now - soon\n        // nested structures allowing for multiple z/t selecitons at once, for example).\n        const handleChannelPropertyChange = (property, value) => {\n          // property is something like \"selection\" or \"slider.\"\n          // value is the actual change, like { channel: \"DAPI\" }.\n          const update = { [property]: value };\n          if (property === 'selection') {\n            // Channel is loading until the layer callback is called\n            // by the layer, which fetches the raster data.\n            setIsLoading(true);\n            update.selection = {\n              ...globalLabelValues,\n              ...update.selection,\n            };\n            setChannel({ ...c, ...update }, channelId);\n            // Call back for raster layer handles update of UI\n            // like sliders and the loading state of the channel.\n            setRasterLayerCallback(async () => {\n              const selections = [\n                { ...channels[channelId][property], ...value },\n              ];\n              const { sliders } = await getDomainsAndSliders(\n                loader,\n                selections,\n                domainType,\n                use3d,\n              );\n              [update.slider] = sliders;\n              setChannel({ ...c, ...update }, channelId);\n              setRasterLayerCallback(null);\n              setIsLoading(false);\n            });\n          } else {\n            setChannel({ ...c, ...update }, channelId);\n          }\n        };\n        const handleChannelRemove = () => {\n          removeChannel(channelId);\n        };\n        const handleIQRUpdate = async () => {\n          const { data: loaderData } = loader;\n          const source = Array.isArray(loaderData)\n            ? loaderData[loaderData.length - 1]\n            : loaderData;\n          const raster = await source.getRaster({\n            selection: channels[channelId].selection,\n          });\n          const stats = getChannelStats(raster.data);\n          const { q1, q3 } = stats;\n          setChannel({ ...c, slider: [q1, q3] }, channelId);\n        };\n        return (\n          <ChannelController\n            // eslint-disable-next-line react/no-array-index-key\n            key={`channel-controller-${channelId}`}\n            dimName={channelLabel}\n            visibility={c.visible}\n            selectionIndex={c.selection[channelLabel]}\n            slider={c.slider}\n            color={c.color}\n            channels={channels}\n            channelId={channelId}\n            domainType={domainType}\n            loader={loader}\n            globalLabelValues={globalLabelValues}\n            theme={theme}\n            channelOptions={channelOptions}\n            colormapOn={Boolean(colormap)}\n            handlePropertyChange={handleChannelPropertyChange}\n            handleChannelRemove={handleChannelRemove}\n            handleIQRUpdate={handleIQRUpdate}\n            setRasterLayerCallback={setRasterLayerCallback}\n            isLoading={areLayerChannelsLoading[channelId]}\n            use3d={use3d}\n          />\n        );\n      },\n    );\n  }\n\n  const controllerSectionClasses = useControllerSectionStyles();\n\n  const { visible } = layer;\n  const visibleSetting = typeof visible === 'boolean' ? visible : true;\n  const Visibility = visibleSetting ? VisibilityIcon : VisibilityOffIcon;\n  // Only show Volume tabs if 3D is available.\n  const hasViewableResolutions = Boolean(\n    Array.from({\n      length: loader.data.length,\n    }).filter((_, res) => canLoadResolution(loader.data, res)).length,\n  );\n  const useVolumeTabs = !disable3d && shape[labels.indexOf('z')] > 1 && hasViewableResolutions;\n  const FullController = (\n    <>\n      <LayerOptions\n        channels={channels}\n        opacity={opacity}\n        colormap={colormap}\n        transparentColor={transparentColor}\n        domainType={domainType}\n        // Only allow for global dimension controllers that\n        // exist in the `dimensions` part of the loader.\n        globalControlLabels={labels.filter(label => GLOBAL_LABELS.includes(label))}\n        globalLabelValues={globalLabelValues}\n        handleOpacityChange={setOpacity}\n        handleColormapChange={setColormap}\n        handleGlobalChannelsSelectionChange={\n          handleGlobalChannelsSelectionChange\n        }\n        handleTransparentColorChange={setTransparentColor}\n        disableChannelsIfRgbDetected={\n          isRgb(loader) && disableChannelsIfRgbDetected\n        }\n        handleDomainChange={handleDomainChange}\n        shouldShowTransparentColor={shouldShowTransparentColor}\n        shouldShowDomain={shouldShowDomain}\n        shouldShowColormap={shouldShowColormap}\n        use3d={use3d}\n        loader={loader}\n        handleMultiPropertyChange={handleMultiPropertyChange}\n        resolution={resolution}\n        disable3d={disable3d}\n        setRasterLayerCallback={setRasterLayerCallback}\n        setAreAllChannelsLoading={setAreAllChannelsLoading}\n        setViewState={setViewState}\n        spatialHeight={spatialHeight}\n        spatialWidth={spatialWidth}\n        modelMatrix={modelMatrix}\n      />\n      {isRgb(loader) && disableChannelsIfRgbDetected\n        ? null\n        : channelControllers}\n      {isRgb(loader) && disableChannelsIfRgbDetected ? null : (\n        <Button\n          disabled={channels.length === MAX_CHANNELS}\n          onClick={handleChannelAdd}\n          fullWidth\n          variant=\"outlined\"\n          style={buttonStyles}\n          startIcon={<AddIcon />}\n          size=\"small\"\n        >\n          Add Channel\n        </Button>\n      )}\n    </>\n  );\n  return (\n    <Accordion\n      className={controllerSectionClasses.root}\n      onChange={(e, expanded) => !disabled\n        && setIsExpanded(\n          expanded && e?.target?.attributes?.role?.value === 'presentation',\n        )\n      }\n      TransitionProps={{ enter: false }}\n      expanded={!disabled && isExpanded}\n    >\n      <StyledAccordionSummary\n        expandIcon={<ExpandMoreIcon role=\"presentation\" />}\n        aria-controls={`layer-${name}-controls`}\n      >\n        <Grid container direction=\"column\" m={1} justifyContent=\"center\">\n          <OverflowEllipsisGrid item>\n            <Button\n              onClick={(e) => {\n                if (!disabled) {\n                  // Needed to prevent affecting the expansion panel from changing\n                  e.stopPropagation();\n                  const nextVisible = typeof visible === 'boolean' ? !visible : false;\n                  setVisible(nextVisible);\n                }\n              }}\n              style={{\n                marginRight: 8,\n                marginBottom: 2,\n                padding: 0,\n                minWidth: 0,\n              }}\n            >\n              <Visibility />\n            </Button>\n            {name}\n          </OverflowEllipsisGrid>\n          {!disabled && !isExpanded && !use3d && (\n            <Grid\n              container\n              direction=\"row\"\n              alignItems=\"center\"\n              justifyContent=\"center\"\n            >\n              <Grid item xs={6}>\n                <StyledInputLabel htmlFor={`layer-${name}-opacity-closed`}>\n                  Opacity:\n                </StyledInputLabel>\n              </Grid>\n              <Grid item xs={6}>\n                <Slider\n                  id={`layer-${name}-opacity-closed`}\n                  value={opacity}\n                  onChange={(e, v) => setOpacity(v)}\n                  valueLabelDisplay=\"auto\"\n                  getAriaLabel={() => 'opacity slider'}\n                  min={0}\n                  max={1}\n                  step={0.01}\n                  orientation=\"horizontal\"\n                />\n              </Grid>\n            </Grid>\n          )}\n        </Grid>\n      </StyledAccordionSummary>\n      <StyledAccordionDetails>\n        {useVolumeTabs ? (\n          <>\n            <Tabs\n              value={tab}\n              onChange={handleTabChange}\n              aria-label=\"simple tabs example\"\n              style={{ height: '24px', minHeight: '24px' }}\n            >\n              <Tab\n                label=\"Channels\"\n                style={{\n                  fontSize: '.75rem',\n                  bottom: 12,\n                  width: '50%',\n                  minWidth: '50%',\n                }}\n                disableRipple\n              />\n              <Tab\n                label=\"Volume\"\n                style={{\n                  fontSize: '.75rem',\n                  bottom: 12,\n                  width: '50%',\n                  minWidth: '50%',\n                }}\n              />\n            </Tabs>\n            <TabPanel value={tab} index={0}>\n              {FullController}\n            </TabPanel>\n            <TabPanel value={tab} index={1} style={{ marginTop: 4 }}>\n              <VolumeOptions\n                loader={loader}\n                handleSlicerSetting={handleSlicerSetting}\n                handleRenderingModeChange={setRenderingMode}\n                renderingMode={renderingMode}\n                xSlice={xSlice}\n                ySlice={ySlice}\n                zSlice={zSlice}\n                use3d={use3d}\n                setViewState={setViewState}\n                spatialHeight={spatialHeight}\n                spatialWidth={spatialWidth}\n                modelMatrix={modelMatrix}\n              />\n            </TabPanel>\n          </>\n        ) : (\n          FullController\n        )}\n        {shouldShowRemoveLayerButton ? (\n          <Button\n            onClick={handleLayerRemove}\n            fullWidth\n            variant=\"outlined\"\n            style={buttonStyles}\n            size=\"small\"\n          >\n            Remove Image Layer\n          </Button>\n        ) : null}\n      </StyledAccordionDetails>\n    </Accordion>\n  );\n}\n","import React, { useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport AddIcon from '@material-ui/icons/Add';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport { PopperMenu } from '../shared-mui/components';\n\nconst useStyles = makeStyles(() => ({\n  addButton: {\n    marginTop: '10px',\n    marginBottom: '10px',\n    fontWeight: 400,\n  },\n}));\n\nfunction ImageAddIcon() {\n  return (\n    <>\n      <AddIcon />\n      Add Image Layer\n    </>\n  );\n}\n\nfunction ImageAddButton({ imageOptions, handleImageAdd }) {\n  const [open, setOpen] = useState(false);\n  const classes = useStyles();\n\n  const handleAdd = (imgData) => {\n    setOpen(prev => !prev);\n    handleImageAdd(imgData);\n  };\n\n  if (!imageOptions) return null;\n  return (\n    <PopperMenu\n      open={open}\n      setOpen={setOpen}\n      buttonIcon={<ImageAddIcon />}\n      buttonClassName={classes.addButton}\n      placement=\"bottom-start\"\n    >\n      {imageOptions.map((imgData, i) => (\n        <MenuItem dense key={imgData.name} onClick={() => handleAdd(i)}>\n          <span>{imgData.name}</span>\n        </MenuItem>\n      ))}\n    </PopperMenu>\n  );\n}\n\nexport default ImageAddButton;\n","/* eslint-disable dot-notation */\nimport React, {\n  useEffect, useCallback, useRef, forwardRef,\n} from 'react';\nimport Grid from '@material-ui/core/Grid';\nimport TitleInfo from '../TitleInfo';\nimport RasterChannelController from './RasterChannelController';\nimport BitmaskChannelController from './BitmaskChannelController';\nimport VectorLayerController from './VectorLayerController';\nimport LayerController from './LayerController';\nimport ImageAddButton from './ImageAddButton';\nimport { useReady, useClosestVitessceContainerSize, useWindowDimensions } from '../hooks';\nimport { useCellsData, useMoleculesData, useRasterData } from '../data-hooks';\nimport {\n  useCoordination,\n  useLoaders,\n  useAuxiliaryCoordination,\n  useComponentLayout,\n} from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport { initializeLayerChannels } from '../spatial/utils';\nimport { DEFAULT_RASTER_LAYER_PROPS } from '../spatial/constants';\n\nconst LAYER_CONTROLLER_DATA_TYPES = ['raster'];\n\n// LayerController is memoized to prevent updates from prop changes that\n// are caused by view state updates i.e zooming and panning within\n// the actual Spatial component.  Re-rendering this component is very\n// expensive so we have to be careful with props in this file in general.\nconst LayerControllerMemoized = React.memo(\n  forwardRef((props, ref) => {\n    const {\n      title,\n      removeGridComponent,\n      theme,\n      isReady,\n      moleculesLayer,\n      dataset,\n      setMoleculesLayer,\n      cellsLayer,\n      canShowCellVecmask,\n      setCellsLayer,\n      rasterLayers,\n      imageLayerLoaders,\n      imageLayerMeta,\n      rasterLayersCallbacks,\n      setRasterLayersCallbacks,\n      areLoadingRasterChannnels,\n      setAreLoadingRasterChannnels,\n      handleRasterLayerChange,\n      handleRasterLayerRemove,\n      disable3d,\n      globalDisable3d,\n      disableChannelsIfRgbDetected,\n      layerIs3DIndex,\n      setZoom,\n      setTargetX,\n      setTargetY,\n      setTargetZ,\n      setRotationX,\n      setRotationOrbit,\n      componentHeight,\n      componentWidth,\n      spatialLayout,\n      handleImageAdd,\n      enableLayerButtonsWithOneLayer,\n    } = props;\n    const shouldShowImageLayerButton = Boolean(\n      enableLayerButtonsWithOneLayer || imageLayerLoaders?.length > 1,\n    );\n    return (\n      <TitleInfo\n        title={title}\n        isScroll\n        removeGridComponent={removeGridComponent}\n        theme={theme}\n        isReady={isReady}\n      >\n        <div className=\"layer-controller-container\" ref={ref}>\n          {moleculesLayer && (\n            <VectorLayerController\n              key={`${dataset}-molecules`}\n              label=\"Molecules\"\n              layerType=\"molecules\"\n              layer={moleculesLayer}\n              handleLayerChange={setMoleculesLayer}\n            />\n          )}\n          {cellsLayer && canShowCellVecmask && (\n            <VectorLayerController\n              key={`${dataset}-cells`}\n              label=\"Cell Segmentations\"\n              layerType=\"cells\"\n              layer={cellsLayer}\n              handleLayerChange={setCellsLayer}\n            />\n          )}\n          {rasterLayers\n            && rasterLayers.map((layer, i) => {\n              const { index } = layer;\n              const loader = imageLayerLoaders[index];\n              const layerMeta = imageLayerMeta[index];\n              // Could also be bitmask at the moment.\n              const isRaster = !layerMeta?.metadata?.isBitmask;\n              const ChannelController = isRaster\n                ? RasterChannelController\n                : BitmaskChannelController;\n              // Set up the call back mechanism so that each layer manages\n              // callbacks/loading state for itself and its channels.\n              const setRasterLayerCallback = (cb) => {\n                const newRasterLayersCallbacks = [\n                  ...(rasterLayersCallbacks || []),\n                ];\n                newRasterLayersCallbacks[i] = cb;\n                setRasterLayersCallbacks(newRasterLayersCallbacks);\n              };\n              const areLayerChannelsLoading = (areLoadingRasterChannnels || [])[i] || [];\n              const setAreLayerChannelsLoading = (v) => {\n                const newAreLoadingRasterChannnels = [\n                  ...(areLoadingRasterChannnels || []),\n                ];\n                newAreLoadingRasterChannnels[i] = v;\n                setAreLoadingRasterChannnels(newAreLoadingRasterChannnels);\n              };\n              return loader && layerMeta ? (\n                <Grid\n                  // eslint-disable-next-line react/no-array-index-key\n                  key={`${dataset}-raster-${index}-${i}`}\n                  item\n                  style={{ marginTop: '10px' }}\n                >\n                  <LayerController\n                    name={layerMeta.name}\n                    layer={layer}\n                    loader={loader}\n                    theme={theme}\n                    handleLayerChange={v => handleRasterLayerChange(v, i)}\n                    handleLayerRemove={() => handleRasterLayerRemove(i)}\n                    ChannelController={ChannelController}\n                    shouldShowTransparentColor={isRaster}\n                    shouldShowDomain={isRaster}\n                    shouldShowColormap={isRaster}\n                    // Disable 3D if given explicit instructions to do so\n                    // or if another layer is using 3D mode.\n                    disable3d={\n                      globalDisable3d\n                      || (disable3d || []).indexOf(layerMeta.name) >= 0\n                      || (typeof layerIs3DIndex === 'number'\n                        && layerIs3DIndex !== -1\n                        && layerIs3DIndex !== i)\n                    }\n                    disabled={\n                      typeof layerIs3DIndex === 'number'\n                      && layerIs3DIndex !== -1\n                      && layerIs3DIndex !== i\n                    }\n                    disableChannelsIfRgbDetected={disableChannelsIfRgbDetected}\n                    rasterLayersCallbacks={rasterLayersCallbacks}\n                    setRasterLayerCallback={setRasterLayerCallback}\n                    setViewState={({\n                      zoom: newZoom,\n                      target,\n                      rotationX: newRotationX,\n                      rotationOrbit: newRotationOrbit,\n                    }) => {\n                      setZoom(newZoom);\n                      setTargetX(target[0]);\n                      setTargetY(target[1]);\n                      setTargetZ(target[2]);\n                      setRotationX(newRotationX);\n                      setRotationOrbit(newRotationOrbit);\n                    }}\n                    setAreLayerChannelsLoading={setAreLayerChannelsLoading}\n                    areLayerChannelsLoading={areLayerChannelsLoading}\n                    spatialHeight={(componentHeight * (spatialLayout ? spatialLayout.h : 1)) / 12}\n                    spatialWidth={(componentWidth * (spatialLayout ? spatialLayout.w : 1)) / 12}\n                    shouldShowRemoveLayerButton={shouldShowImageLayerButton}\n                  />\n                </Grid>\n              ) : null;\n            })}\n          {shouldShowImageLayerButton\n            ? (\n              <Grid item>\n                <ImageAddButton\n                  imageOptions={imageLayerMeta}\n                  handleImageAdd={handleImageAdd}\n                />\n              </Grid>\n            ) : null}\n        </div>\n      </TitleInfo>\n    );\n  }),\n);\n\n/**\n * A subscriber component for the spatial layer controller.\n * @param {object} props\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n * @param {Object} props.disable3d Which layers should have 3D disabled (from `raster.json` names).\n * @param {boolean} props.globalDisable3d Disable 3D for all layers. Overrides the `disable3d` prop.\n * @param {boolean} props.disableChannelsIfRgbDetected Disable channel controls if an\n * RGB image is detected i.e 3 channel 8 bit.\n * @param {boolean} props.enableLayerButtonsWithOneLayer If there is only one layer,\n * show the the layer add/remove buttons.\n */\nfunction LayerControllerSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n    title = 'Spatial Layers',\n    disable3d,\n    globalDisable3d,\n    disableChannelsIfRgbDetected,\n    enableLayerButtonsWithOneLayer,\n  } = props;\n\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [\n    {\n      dataset,\n      spatialRasterLayers: rasterLayers,\n      spatialCellsLayer: cellsLayer,\n      spatialMoleculesLayer: moleculesLayer,\n    },\n    {\n      setSpatialRasterLayers: setRasterLayers,\n      setSpatialCellsLayer: setCellsLayer,\n      setSpatialMoleculesLayer: setMoleculesLayer,\n      setSpatialTargetX: setTargetX,\n      setSpatialTargetY: setTargetY,\n      setSpatialTargetZ: setTargetZ,\n      setSpatialRotationX: setRotationX,\n      setSpatialRotationOrbit: setRotationOrbit,\n      setSpatialZoom: setZoom,\n    },\n  ] = useCoordination(\n    COMPONENT_COORDINATION_TYPES.layerController,\n    coordinationScopes,\n  );\n\n  const [\n    {\n      rasterLayersCallbacks,\n      areLoadingRasterChannnels,\n    },\n    {\n      setRasterLayersCallbacks,\n      setAreLoadingRasterChannnels,\n    },\n  ] = useAuxiliaryCoordination(\n    COMPONENT_COORDINATION_TYPES.layerController,\n    coordinationScopes,\n  );\n  // Spatial layout + window size is needed for the \"re-center\" button to work properly.\n  // Dimensions of the Spatial component can be inferred and used for resetting view state to\n  // a nice, centered view.\n  const [spatialLayout] = useComponentLayout('spatial', ['spatialRasterLayers'], coordinationScopes);\n  const layerControllerRef = useRef();\n  const [componentWidth, componentHeight] = useClosestVitessceContainerSize(layerControllerRef);\n  const { height: windowHeight, width: windowWidth } = useWindowDimensions();\n\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    LAYER_CONTROLLER_DATA_TYPES,\n  );\n\n  // Reset loader progress when the dataset has changed.\n  useEffect(() => {\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  // eslint-disable-next-line no-unused-vars\n  const [raster, imageLayerLoaders, imageLayerMeta] = useRasterData(\n    loaders, dataset, setItemIsReady, () => { }, false,\n    { setSpatialRasterLayers: setRasterLayers },\n    { spatialRasterLayers: rasterLayers },\n  );\n\n  useCellsData(\n    loaders, dataset, setItemIsReady, () => {}, false,\n    { setSpatialCellsLayer: setCellsLayer },\n    { spatialCellsLayer: cellsLayer },\n  );\n  useMoleculesData(\n    loaders, dataset, setItemIsReady, () => {}, false,\n    { setSpatialMoleculesLayer: setMoleculesLayer },\n    { spatialMoleculesLayer: moleculesLayer },\n  );\n\n  // useCallback prevents new functions from propogating\n  // changes to the underlying component.\n  const handleImageAdd = useCallback(async (index) => {\n    const loader = imageLayerLoaders[index];\n    const newChannels = await initializeLayerChannels(\n      loader,\n      (rasterLayers[index] || {}).use3d,\n    );\n    const newLayer = {\n      index,\n      modelMatrix: imageLayerMeta[index]?.metadata?.transform?.matrix,\n      ...DEFAULT_RASTER_LAYER_PROPS,\n      channels: newChannels,\n      type: imageLayerMeta[index]?.metadata?.isBitmask ? 'bitmask' : 'raster',\n    };\n    const newLayers = [...rasterLayers, newLayer];\n    setRasterLayers(newLayers);\n  }, [imageLayerLoaders, imageLayerMeta, rasterLayers, setRasterLayers]);\n\n  const handleRasterLayerChange = useCallback((newLayer, i) => {\n    const newLayers = [...rasterLayers];\n    newLayers[i] = newLayer;\n    setRasterLayers(newLayers);\n  }, [rasterLayers, setRasterLayers]);\n\n  const handleRasterLayerRemove = useCallback((i) => {\n    const newLayers = [...rasterLayers];\n    newLayers.splice(i, 1);\n    setRasterLayers(newLayers);\n  }, [rasterLayers, setRasterLayers]);\n\n  const hasNoBitmask = (\n    imageLayerMeta.length ? imageLayerMeta : [{ metadata: { isBitmask: true } }]\n  ).every(l => !l?.metadata?.isBitmask);\n  // Only want to show vector cells controller if there is no bitmask\n  const canShowCellVecmask = hasNoBitmask;\n  const layerIs3DIndex = rasterLayers?.findIndex && rasterLayers.findIndex(layer => layer.use3d);\n  return (\n    <LayerControllerMemoized\n      ref={layerControllerRef}\n      title={title}\n      removeGridComponent={removeGridComponent}\n      theme={theme}\n      isReady={isReady}\n      moleculesLayer={moleculesLayer}\n      dataset={dataset}\n      setMoleculesLayer={setMoleculesLayer}\n      cellsLayer={cellsLayer}\n      canShowCellVecmask={canShowCellVecmask}\n      setCellsLayer={setCellsLayer}\n      rasterLayers={rasterLayers}\n      imageLayerLoaders={imageLayerLoaders}\n      imageLayerMeta={imageLayerMeta}\n      rasterLayersCallbacks={rasterLayersCallbacks}\n      setRasterLayersCallbacks={setRasterLayersCallbacks}\n      areLoadingRasterChannnels={areLoadingRasterChannnels}\n      setAreLoadingRasterChannnels={setAreLoadingRasterChannnels}\n      handleRasterLayerChange={handleRasterLayerChange}\n      handleRasterLayerRemove={handleRasterLayerRemove}\n      disable3d={disable3d}\n      globalDisable3d={globalDisable3d}\n      layerIs3DIndex={layerIs3DIndex}\n      disableChannelsIfRgbDetected={disableChannelsIfRgbDetected}\n      enableLayerButtonsWithOneLayer={enableLayerButtonsWithOneLayer}\n      setZoom={setZoom}\n      setTargetX={setTargetX}\n      setTargetY={setTargetY}\n      setTargetZ={setTargetZ}\n      setRotationX={setRotationX}\n      setRotationOrbit={setRotationOrbit}\n      // Fall back to window for height and width.\n      componentHeight={componentHeight || windowHeight}\n      componentWidth={componentWidth || windowWidth}\n      spatialLayout={spatialLayout}\n      handleImageAdd={handleImageAdd}\n    />\n  );\n}\n\nexport default LayerControllerSubscriber;\n","import React, {\n  useMemo, useEffect, useRef, Suspense, useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport dynamicImportPolyfill from 'dynamic-import-polyfill';\nimport register from 'higlass-register';\nimport { ZarrMultivecDataFetcher } from 'higlass-zarr-datafetchers';\nimport packageJson from '../../../package.json';\nimport { createWarningComponent, asEsModule } from '../utils';\nimport { useGridItemSize } from '../hooks';\nimport {\n  useCoordination,\n} from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\n\nconst PIXI_BUNDLE_VERSION = packageJson.dependencies['window-pixi'];\nconst HIGLASS_BUNDLE_VERSION = packageJson.dependencies.higlass;\nconst BUNDLE_FILE_EXT = process.env.NODE_ENV === 'development' ? 'js' : 'min.js';\nconst PIXI_BUNDLE_URL = `https://unpkg.com/window-pixi@${PIXI_BUNDLE_VERSION}/dist/pixi.${BUNDLE_FILE_EXT}`;\nconst HIGLASS_BUNDLE_URL = `https://unpkg.com/higlass@${HIGLASS_BUNDLE_VERSION}/dist/hglib.${BUNDLE_FILE_EXT}`;\n\n\n// Initialize the dynamic __import__() function.\nif (dynamicImportPolyfill) {\n  dynamicImportPolyfill.initialize();\n}\n\n// Register the zarr-multivec plugin data fetcher.\n// References:\n// https://github.com/higlass/higlass-register\n// https://github.com/higlass/higlass-zarr-datafetchers\nregister(\n  { dataFetcher: ZarrMultivecDataFetcher, config: ZarrMultivecDataFetcher.config },\n  { pluginType: 'dataFetcher' },\n);\n\n// Lazy load the HiGlass React component,\n// using dynamic imports with absolute URLs.\nconst HiGlassComponent = React.lazy(() => {\n  if (!window.React) {\n    window.React = React;\n  }\n  if (!window.ReactDOM) {\n    window.ReactDOM = ReactDOM;\n  }\n  return new Promise((resolve) => {\n    const handleImportError = (e) => {\n      console.warn(e);\n      resolve(asEsModule(createWarningComponent({\n        title: 'Could not load HiGlass',\n        message: 'The HiGlass scripts could not be dynamically imported.',\n      })));\n    };\n      // eslint-disable-next-line no-undef\n    __import__(PIXI_BUNDLE_URL).then(() => {\n      // eslint-disable-next-line no-undef\n      __import__(HIGLASS_BUNDLE_URL).then(() => {\n        // React.lazy promise must return an ES module with the\n        // component as the default export.\n        resolve(asEsModule(window.hglib.HiGlassComponent));\n      }).catch(handleImportError);\n    }).catch(handleImportError);\n  });\n});\n\n// Use an arbitrary size for normalization of the zoom level.\n// (800 means 800 px width for the full genome)\nconst HG_SIZE = 800;\n\n/**\n   * A wrapper around HiGlass (http://higlass.io/).\n   * The HiGlassComponent react component is loaded lazily.\n   * @prop {object} hgViewConfig A HiGlass viewconfig object to pass\n   * to the HiGlassComponent viewConfig prop.\n   * @prop {object} hgOptions An optional HiGlass object to pass\n   * to the HiGlassComponent hgOptions prop.\n   * @prop {function} removeGridComponent A grid component removal handler\n   * to pass to the TitleInfo component.\n   * @prop {function} onReady A callback function to signal that the component is ready.\n   */\nexport default function HiGlassLazy(props) {\n  const {\n    coordinationScopes,\n    theme,\n    hgViewConfig: hgViewConfigProp,\n    hgOptions: hgOptionsProp,\n    genomeSize,\n    height,\n  } = props;\n\n  // Get \"props\" from the coordination space.\n  const [{\n    genomicZoomX,\n    genomicZoomY,\n    genomicTargetX,\n    genomicTargetY,\n  }, {\n    setGenomicZoomX,\n    setGenomicZoomY,\n    setGenomicTargetX,\n    setGenomicTargetY,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.higlass, coordinationScopes);\n\n  // eslint-disable-next-line no-unused-vars\n  const [width, computedHeight, containerRef] = useGridItemSize();\n  const [hgInstance, setHgInstance] = useState();\n  const isActiveRef = useRef();\n\n  const hgOptions = useMemo(() => ({\n    ...hgOptionsProp,\n    theme,\n  }), [hgOptionsProp, theme]);\n\n  const hgViewConfig = useMemo(() => {\n    // HiGlass needs the start and end absolute genome coordinates\n    const centerX = genomicTargetX;\n    const genomesPerUnitX = genomeSize / (2 ** genomicZoomX);\n    const unitX = width / HG_SIZE;\n    const initialXDomain = [\n      centerX - genomesPerUnitX * unitX / 2,\n      centerX + genomesPerUnitX * unitX / 2,\n    ];\n    const centerY = genomicTargetY;\n    const genomesPerUnitY = genomeSize / (2 ** genomicZoomY);\n    const unitY = height / HG_SIZE;\n    const initialYDomain = [\n      centerY - genomesPerUnitY * unitY / 2,\n      centerY + genomesPerUnitY * unitY / 2,\n    ];\n    return {\n      editable: false,\n      zoomFixed: false,\n      trackSourceServers: [\n        '//higlass.io/api/v1',\n      ],\n      exportViewUrl: '//higlass.io/api/v1/viewconfs',\n      views: [\n        {\n          uid: 'main',\n          ...hgViewConfigProp,\n          initialXDomain,\n          initialYDomain,\n        },\n      ],\n      zoomLocks: {\n        locksByViewUid: {},\n        locksDict: {},\n      },\n      locationLocks: {\n        locksByViewUid: {},\n        locksDict: {},\n      },\n      valueScaleLocks: {\n        locksByViewUid: {},\n        locksDict: {},\n      },\n    };\n  }, [genomicTargetX, genomeSize, genomicZoomX, width, genomicTargetY,\n    genomicZoomY, height, hgViewConfigProp]);\n\n  useEffect(() => {\n    const handleMouseEnter = () => {\n      isActiveRef.current = true;\n    };\n    const handleMouseLeave = () => {\n      isActiveRef.current = false;\n    };\n    const container = containerRef.current;\n    container.addEventListener('mouseenter', handleMouseEnter);\n    container.addEventListener('mouseleave', handleMouseLeave);\n    return () => {\n      container.removeEventListener('mouseenter', handleMouseEnter);\n      container.removeEventListener('mouseenter', handleMouseLeave);\n    };\n  }, [containerRef]);\n\n\n  useEffect(() => {\n    if (!hgInstance) {\n      return () => {};\n    }\n    hgInstance.api.on('viewConfig', (viewConfigString) => {\n      // Only set if the user mouse is over this component (\"is active\").\n      // Otherwise, this could be an initial on viewConfig change callback from a sibling,\n      // which will cause an infinite loop.\n      if (!isActiveRef.current) {\n        return;\n      }\n      const viewConfig = JSON.parse(viewConfigString);\n      const xDomain = viewConfig.views[0].initialXDomain;\n      const yDomain = viewConfig.views[0].initialYDomain;\n\n      const nextGenomicZoomX = Math.log2(\n        genomeSize / ((xDomain[1] - xDomain[0]) * (HG_SIZE / width)),\n      );\n      const nextGenomicZoomY = Math.log2(\n        genomeSize / ((yDomain[1] - yDomain[0]) * (HG_SIZE / height)),\n      );\n      const nextGenomicTargetX = xDomain[0] + (xDomain[1] - xDomain[0]) / 2;\n      const nextGenomicTargetY = yDomain[0] + (yDomain[1] - yDomain[0]) / 2;\n      setGenomicZoomX(nextGenomicZoomX);\n      setGenomicZoomY(nextGenomicZoomY);\n      setGenomicTargetX(nextGenomicTargetX);\n      setGenomicTargetY(nextGenomicTargetY);\n    });\n    return () => hgInstance.api.off('viewConfig');\n  }, [hgInstance, genomeSize, width, height, setGenomicZoomX, setGenomicZoomY,\n    setGenomicTargetX, setGenomicTargetY]);\n\n  return (\n    <div className=\"higlass-wrapper-parent\">\n      <div className=\"higlass-wrapper\" ref={containerRef} style={{ height: `${height}px` }}>\n        <Suspense fallback={<div>Loading...</div>}>\n          <HiGlassComponent\n            ref={setHgInstance}\n            zoomFixed={false}\n            viewConfig={hgViewConfig}\n            options={hgOptions}\n          />\n        </Suspense>\n      </div>\n    </div>\n  );\n}\n\nHiGlassLazy.defaultProps = {\n  hgOptions: {\n    bounded: true,\n    pixelPreciseMarginPadding: true,\n    containerPaddingX: 0,\n    containerPaddingY: 0,\n    sizeMode: 'default',\n  },\n  genomeSize: 3100000000,\n};\n","import React from 'react';\nimport TitleInfo from '../TitleInfo';\nimport { useReady, useUrls, useGridItemSize } from '../hooks';\nimport HiGlassLazy from './HiGlassLazy';\n\nconst HIGLASS_DATA_TYPES = [];\n\n/**\n * A wrapper around HiGlass (http://higlass.io/).\n * The HiGlassComponent react component is loaded lazily.\n * @prop {object} hgViewConfig A HiGlass viewconfig object to pass\n * to the HiGlassComponent viewConfig prop.\n * @prop {object} hgOptions An optional HiGlass object to pass\n * to the HiGlassComponent hgOptions prop.\n * @prop {function} removeGridComponent A grid component removal handler\n * to pass to the TitleInfo component.\n * @prop {function} onReady A callback function to signal that the component is ready.\n */\nexport default function HiGlassSubscriber(props) {\n  const {\n    coordinationScopes,\n    theme,\n    hgViewConfig,\n    removeGridComponent,\n  } = props;\n\n  // eslint-disable-next-line no-unused-vars\n  const [width, height, containerRef] = useGridItemSize();\n\n  const [\n    isReady,\n    setItemIsReady, // eslint-disable-line no-unused-vars\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems, // eslint-disable-line no-unused-vars\n  ] = useReady(\n    HIGLASS_DATA_TYPES,\n  );\n  // eslint-disable-next-line no-unused-vars\n  const [urls, addUrl, resetUrls] = useUrls();\n\n  return (\n    <div className=\"higlass-title-wrapper\">\n      <TitleInfo\n        title=\"HiGlass\"\n        removeGridComponent={removeGridComponent}\n        theme={theme}\n        isReady={isReady}\n        urls={urls}\n      >\n        <div className=\"higlass-lazy-wrapper\" ref={containerRef}>\n          <HiGlassLazy\n            coordinationScopes={coordinationScopes}\n            theme={theme}\n            hgViewConfig={hgViewConfig}\n            height={height}\n          />\n        </div>\n      </TitleInfo>\n    </div>\n  );\n}\n","import React, { Suspense, useMemo } from 'react';\nimport { Handler } from 'vega-tooltip';\nimport ReactVega from './ReactVega';\n\n// TODO: React.lazy is not working with Vitessce in the portal-ui.\n// For now, we can work around this by not using React.lazy,\n// but for performance benefits that come with lazy-loading\n// we should eventually try to resolve this issue.\n// const ReactVega = React.lazy(() => import('./ReactVega'));\n\nexport const DATASET_NAME = 'table';\n\nfunction isVega(spec) {\n  return spec.$schema === 'https://vega.github.io/schema/vega/v5.json';\n}\n\n/**\n * A wrapper around the react-vega Vega component.\n * @param {object} props\n * @param {object} spec A vega or vega-lite spec.\n * @param {object[]} data The plot data as an array of objects.\n * @param {object} signalListeners Vega signal listeners. Optional.\n */\nexport default function VegaPlot(props) {\n  const {\n    spec: partialSpec,\n    data,\n    signalListeners,\n  } = props;\n\n  const spec = {\n    ...partialSpec,\n    data: (isVega(partialSpec)\n      ? [\n        { name: DATASET_NAME },\n        ...partialSpec.data,\n      ]\n      : { name: DATASET_NAME }\n    ),\n  };\n\n  const vegaComponent = useMemo(() => (\n    <ReactVega\n      spec={spec}\n      data={{\n        [DATASET_NAME]: data,\n      }}\n      signalListeners={signalListeners}\n      tooltip={new Handler().call}\n      renderer=\"canvas\"\n      scaleFactor={3}\n    />\n  ), [spec, data, signalListeners]);\n\n  return (\n    spec && data && data.length > 0 ? (\n      <Suspense fallback={<div>Loading...</div>}>\n        {vegaComponent}\n      </Suspense>\n    ) : null\n  );\n}\n","/**\n * Vega-Lite themes that can be passed to the `config` property\n * of the vega-lite spec.\n */\nexport const VEGA_THEMES = {\n  dark: {\n    // The vega-themes dark theme.\n    // Reference: https://github.com/vega/vega-themes/blob/master/src/theme-dark.ts\n    background: null,\n    title: { color: '#fff' },\n    style: {\n      'guide-label': {\n        fill: '#fff',\n      },\n      'guide-title': {\n        fill: '#fff',\n      },\n    },\n    axis: {\n      domainColor: '#fff',\n      gridColor: '#888',\n      tickColor: '#fff',\n    },\n  },\n  light: {\n    // The default vega theme.\n    background: null,\n  },\n};\n","import React from 'react';\nimport clamp from 'lodash/clamp';\nimport { VegaPlot, VEGA_THEMES } from '../vega';\nimport { colorArrayToString } from './utils';\n\n/**\n * Cell set sizes displayed as a bar chart,\n * implemented with the VegaPlot component.\n * @param {object} props\n * @param {object[]} props.data The set size data, an array\n * of objects with properties `name`, `key`, `color`, and `size`.\n * @param {string} props.theme The name of the current Vitessce theme.\n * @param {number} props.width The container width.\n * @param {number} props.height The container height.\n * @param {number} props.marginRight The size of the margin\n * on the right side of the plot, to account for the vega menu button.\n * By default, 90.\n * @param {number} props.marginBottom The size of the margin\n * on the bottom of the plot, to account for long x-axis labels.\n * By default, 120.\n * @param {number} props.keyLength The length of the `key` property of\n * each data point. Assumes all key strings have the same length.\n * By default, 36.\n */\nexport default function CellSetSizesPlot(props) {\n  const {\n    data: rawData,\n    theme,\n    width,\n    height,\n    marginRight = 90,\n    marginBottom = 120,\n    keyLength = 36,\n  } = props;\n\n  // Add a property `keyName` which concatenates the key and the name,\n  // which is both unique and can easily be converted\n  // back to the name by taking a substring.\n  // Add a property `colorString` which contains the `[r, g, b]` color\n  // after converting to a color hex string.\n  const data = rawData.map(d => ({\n    ...d,\n    keyName: d.key + d.name,\n    colorString: colorArrayToString(d.color),\n  }));\n\n  // Manually set the color scale so that Vega-Lite does\n  // not choose the colors automatically.\n  const colors = {\n    domain: data.map(d => d.key),\n    range: data.map(d => d.colorString),\n  };\n\n  // Get an array of keys for sorting purposes.\n  const keys = data.map(d => d.keyName);\n\n  const spec = {\n    mark: { type: 'bar' },\n    encoding: {\n      x: {\n        field: 'keyName',\n        type: 'nominal',\n        axis: { labelExpr: `substring(datum.label, ${keyLength})` },\n        title: 'Cell Set',\n        sort: keys,\n      },\n      y: {\n        field: 'size',\n        type: 'quantitative',\n        title: 'Cell Set Size',\n      },\n      color: {\n        field: 'key',\n        type: 'nominal',\n        scale: colors,\n        legend: null,\n      },\n      tooltip: {\n        field: 'size',\n        type: 'quantitative',\n      },\n    },\n    width: clamp(width - marginRight, 10, Infinity),\n    height: clamp(height - marginBottom, 10, Infinity),\n    config: VEGA_THEMES[theme],\n  };\n\n  return (\n    <VegaPlot\n      data={data}\n      spec={spec}\n    />\n  );\n}\n","import React, { useMemo, useEffect } from 'react';\nimport TitleInfo from '../TitleInfo';\nimport { useCoordination, useLoaders } from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport { useUrls, useReady, useGridItemSize } from '../hooks';\nimport { mergeCellSets } from '../utils';\nimport { useCellSetsData } from '../data-hooks';\nimport { treeToSetSizesBySetNames } from './cell-set-utils';\nimport CellSetSizesPlot from './CellSetSizesPlot';\n\nconst CELL_SET_SIZES_DATA_TYPES = ['cell-sets'];\n\n/**\n * A subscriber component for `CellSetSizePlot`,\n * which listens for cell sets data updates and\n * `GRID_RESIZE` events.\n * @param {object} props\n * @param {function} props.removeGridComponent The grid component removal function.\n * @param {function} props.onReady The function to call when the subscriptions\n * have been made.\n * @param {string} props.theme The name of the current Vitessce theme.\n * @param {string} props.title The component title.\n */\nexport default function CellSetSizesPlotSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n    title = 'Cell Set Sizes',\n  } = props;\n\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    cellSetSelection,\n    cellSetColor,\n    additionalCellSets,\n  }, {\n    setCellSetSelection,\n    setCellSetColor,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.cellSetSizes, coordinationScopes);\n\n  const [width, height, containerRef] = useGridItemSize();\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    CELL_SET_SIZES_DATA_TYPES,\n  );\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [cellSets] = useCellSetsData(\n    loaders, dataset, setItemIsReady, addUrl, true,\n    { setCellSetSelection, setCellSetColor },\n    { cellSetSelection, cellSetColor },\n  );\n\n  const mergedCellSets = useMemo(\n    () => mergeCellSets(cellSets, additionalCellSets),\n    [cellSets, additionalCellSets],\n  );\n\n  // From the cell sets hierarchy and the list of selected cell sets,\n  // generate the array of set sizes data points for the bar plot.\n  const data = useMemo(() => (mergedCellSets && cellSetSelection && cellSetColor\n    ? treeToSetSizesBySetNames(mergedCellSets, cellSetSelection, cellSetColor, theme)\n    : []\n  ), [mergedCellSets, cellSetSelection, cellSetColor, theme]);\n\n  return (\n    <TitleInfo\n      title={title}\n      removeGridComponent={removeGridComponent}\n      urls={urls}\n      theme={theme}\n      isReady={isReady}\n    >\n      <div ref={containerRef} className=\"vega-container\">\n        <CellSetSizesPlot\n          data={data}\n          theme={theme}\n          width={width}\n          height={height}\n        />\n      </div>\n    </TitleInfo>\n  );\n}\n","import React, {\n  useMemo, useEffect,\n} from 'react';\nimport isEqual from 'lodash/isEqual';\nimport { sum } from 'd3-array';\nimport TitleInfo from '../TitleInfo';\nimport { useReady, useUrls, useGridItemSize } from '../hooks';\nimport {\n  useCoordination, useLoaders,\n} from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport { useGenomicProfilesData } from '../data-hooks';\nimport HiGlassLazy from './HiGlassLazy';\n\nconst GENOMIC_PROFILES_DATA_TYPES = ['genomic-profiles'];\n\nconst REFERENCE_TILESETS = {\n  hg38: {\n    chromosomes: 'NyITQvZsS_mOFNlz5C2LJg',\n    genes: 'P0PLbQMwTYGy-5uPIQid7A',\n  },\n  hg19: {\n    chromosomes: 'N12wVGG9SPiTkk03yUayUw',\n    genes: 'OHJakQICQD6gTD7skx4EWA',\n  },\n  mm9: {\n    chromosomes: 'WAVhNHYxQVueq6KulwgWiQ',\n    genes: 'GUm5aBiLRCyz2PsBea7Yzg',\n  },\n  mm10: {\n    chromosomes: 'EtrWT0VtScixmsmwFSd7zg',\n    genes: 'QDutvmyiSrec5nX4pA5WGQ',\n  },\n};\n\n/**\n * A component for visualization of genomic profiles\n * with genome-wide bar plots.\n * @param {object} props The component props.\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.profileTrackUidKey The key in the genomic profiles row_info that identifies\n * each track. By default, 'path'.\n * @param {string} props.profileTrackNameKey The key in the genomic profiles row_info that\n * gives a name for each track. By default, null. When null is provided, uses the\n * profileTrackUidKey for both UID and name. If UID values are path arrays,\n * they will be converted to name strings.\n * @param {string} props.higlassServer The URL for the higlass server used to retreive\n * reference tilesets for the chromosome and gene annotations.\n * @param {string} props.assembly The genome assembly to use for the reference\n * tilesets for the chromosome and gene annotations.\n * @param {string} props.title The title of the component.\n */\nexport default function GenomicProfilesSubscriber(props) {\n  const {\n    coordinationScopes,\n    theme,\n    removeGridComponent,\n    profileTrackUidKey = 'path',\n    profileTrackNameKey = null,\n    higlassServer = 'https://higlass.io/api/v1',\n    assembly = 'hg38',\n    title = 'Genomic Profiles',\n  } = props;\n\n  // eslint-disable-next-line no-unused-vars\n  const [width, height, containerRef] = useGridItemSize();\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    cellSetColor,\n    cellSetSelection,\n  }] = useCoordination(\n    COMPONENT_COORDINATION_TYPES.genomicProfiles,\n    coordinationScopes,\n  );\n\n  // eslint-disable-next-line no-unused-vars\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    GENOMIC_PROFILES_DATA_TYPES,\n  );\n    // eslint-disable-next-line no-unused-vars\n  const [urls, addUrl, resetUrls] = useUrls();\n\n  const [genomicProfilesAttrs] = useGenomicProfilesData(\n    loaders, dataset, setItemIsReady, addUrl, true,\n  );\n\n  const hgViewConfig = useMemo(() => {\n    if (!genomicProfilesAttrs || urls.length !== 1) {\n      return null;\n    }\n    // Get the URL to the data file from the downloadable URLs array.\n    const { url } = urls[0];\n\n    // Set up the colors to use in the HiGlass view config based on the current theme.\n    const foregroundColor = (theme === 'dark' ? '#C0C0C0' : '#000000');\n    const backgroundColor = (theme === 'dark' ? '#000000' : '#f1f1f1');\n    const dimColor = (theme === 'dark' ? 'dimgray' : 'silver');\n\n    // Define the \"reference tracks\" for chromosome labels and gene annotations.\n    const referenceTracks = [\n      {\n        type: 'horizontal-chromosome-labels',\n        server: higlassServer,\n        tilesetUid: REFERENCE_TILESETS[assembly].chromosomes,\n        uid: 'chromosome-labels',\n        options: {\n          color: foregroundColor,\n          fontSize: 12,\n          fontIsLeftAligned: false,\n          showMousePosition: true,\n          mousePositionColor: foregroundColor,\n        },\n        height: 30,\n      },\n      {\n        type: 'horizontal-gene-annotations',\n        server: higlassServer,\n        tilesetUid: REFERENCE_TILESETS[assembly].genes,\n        uid: 'gene-annotations',\n        options: {\n          name: 'Gene Annotations (hg38)',\n          fontSize: 10,\n          labelPosition: 'hidden',\n          labelLeftMargin: 0,\n          labelRightMargin: 0,\n          labelTopMargin: 0,\n          labelBottomMargin: 0,\n          minHeight: 24,\n          geneAnnotationHeight: 16,\n          geneLabelPosition: 'outside',\n          geneStrandSpacing: 4,\n          showMousePosition: true,\n          mousePositionColor: foregroundColor,\n          plusStrandColor: foregroundColor,\n          minusStrandColor: foregroundColor,\n          labelColor: 'black',\n          labelBackgroundColor: backgroundColor,\n          trackBorderWidth: 0,\n          trackBorderColor: 'black',\n        },\n        height: 70,\n      },\n    ];\n    // Determine the heights of each profile track by subtracting the\n    // reference track heights from the component height, then\n    // dividing by the number of profiles.\n    const referenceTracksHeightSum = sum(referenceTracks.map(t => t.height));\n    const profileTracksHeightSum = height - referenceTracksHeightSum - 10;\n    const profileTrackHeight = profileTracksHeightSum / genomicProfilesAttrs.row_infos.length;\n    const profileTracks = genomicProfilesAttrs.row_infos.map((rowInfo, i) => {\n      // Get the uid for the HiGlass track.\n      const trackUid = rowInfo[profileTrackUidKey];\n      // When profiles correspond to cell sets, the profile UID will be the cell set path array.\n      const isPath = Array.isArray(trackUid);\n      // Get the name for the HiGlass track: try the name key first,\n      // then try the tail of the path, and otherwise the track UID.\n      // eslint-disable-next-line no-nested-ternary\n      const trackName = profileTrackNameKey\n        ? rowInfo[profileTrackNameKey]\n        : (isPath ? trackUid[trackUid.length - 1] : trackUid);\n      // If the uid is a path, then try to get the corresponding cell set's color,\n      // if it is currently selected.\n      const setInSelection = isPath ? cellSetSelection?.find(s => isEqual(s, trackUid)) : false;\n      const setColor = isPath ? cellSetColor?.find(s => isEqual(s.path, trackUid))?.color : null;\n      // Get the track UID as a string before passing to HiGlass.\n      const trackUidString = isPath ? trackUid.join('__') : trackUid;\n      // Create the HiGlass track definition for this profile.\n      const track = {\n        type: 'horizontal-bar',\n        uid: `bar-track-${trackUidString}`,\n        data: {\n          type: 'zarr-multivec',\n          url,\n          row: i,\n        },\n        options: {\n          name: trackName,\n          showMousePosition: true,\n          mousePositionColor: foregroundColor,\n          labelColor: (theme === 'dark' ? 'white' : 'black'),\n          labelBackgroundColor: (theme === 'dark' ? 'black' : 'white'),\n          labelShowAssembly: false,\n        },\n        height: profileTrackHeight,\n      };\n      // Set the track color if it is available.\n      if (setColor && setInSelection) {\n        const c = setColor;\n        track.options.barFillColor = `rgb(${c[0]},${c[1]},${c[2]})`;\n      } else {\n        track.options.barFillColor = dimColor;\n      }\n      return track;\n    });\n\n    // Create the higlass view.\n    // The HiGlassLazy component will fill in the fields 'uid',\n    // 'initialXDomain', and 'initialYDomain'.\n    const hgView = {\n      tracks: {\n        top: [\n          ...referenceTracks,\n          ...profileTracks,\n        ],\n        left: [],\n        center: [],\n        right: [],\n        bottom: [],\n        whole: [],\n        gallery: [],\n      },\n      layout: {\n        w: 12,\n        h: 12,\n        x: 0,\n        y: 0,\n        static: false,\n      },\n    };\n    return hgView;\n  }, [genomicProfilesAttrs, urls, theme, height, profileTrackUidKey,\n    profileTrackNameKey, cellSetSelection, cellSetColor,\n    higlassServer, assembly]);\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  return (\n    <div className=\"higlass-title-wrapper\">\n      <TitleInfo\n        title={title}\n        removeGridComponent={removeGridComponent}\n        theme={theme}\n        isReady={isReady}\n        urls={urls}\n      >\n        <div className=\"higlass-lazy-wrapper\" ref={containerRef}>\n          {hgViewConfig ? (\n            <HiGlassLazy\n              coordinationScopes={coordinationScopes}\n              theme={theme}\n              hgViewConfig={hgViewConfig}\n              height={height}\n            />\n          ) : null}\n        </div>\n      </TitleInfo>\n    </div>\n  );\n}\n","import React from 'react';\nimport clamp from 'lodash/clamp';\nimport { VegaPlot, VEGA_THEMES } from '../vega';\n\n/**\n * Gene expression histogram displayed as a bar chart,\n * implemented with the VegaPlot component.\n * @param {object} props\n * @param {string[]} props.geneSelection The list of genes\n * currently selected.\n * @param {object[]} props.data The expression data, an array\n * of objects with properties `value` and `gene`.\n * @param {string} props.theme The name of the current Vitessce theme.\n * @param {number} props.width The container width.\n * @param {number} props.height The container height.\n * @param {number} props.marginRight The size of the margin\n * on the right side of the plot, to account for the vega menu button.\n * By default, 90.\n * @param {number} props.marginBottom The size of the margin\n * on the bottom of the plot, to account for long x-axis labels.\n * By default, 50.\n */\nexport default function ExpressionHistogram(props) {\n  const {\n    geneSelection,\n    data,\n    theme,\n    width,\n    height,\n    marginRight = 90,\n    marginBottom = 50,\n  } = props;\n\n  const xTitle = geneSelection && geneSelection.length >= 1\n    ? 'Normalized Expression Value'\n    : 'Total Normalized Transcript Count';\n\n  const spec = {\n    mark: { type: 'bar' },\n    encoding: {\n      x: {\n        field: 'value',\n        type: 'quantitative',\n        bin: { maxbins: 50 },\n        title: xTitle,\n      },\n      y: {\n        type: 'quantitative',\n        aggregate: 'count',\n        title: 'Number of Cells',\n      },\n      color: { value: 'gray' },\n    },\n    width: clamp(width - marginRight, 10, Infinity),\n    height: clamp(height - marginBottom, 10, Infinity),\n    config: VEGA_THEMES[theme],\n  };\n\n  return (\n    <VegaPlot\n      data={data}\n      spec={spec}\n    />\n  );\n}\n","import React, { useMemo, useEffect } from 'react';\nimport { sum } from 'd3-array';\n\nimport TitleInfo from '../TitleInfo';\nimport { useCoordination, useLoaders } from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport { useUrls, useReady, useGridItemSize } from '../hooks';\nimport { useExpressionMatrixData, useGeneSelection } from '../data-hooks';\nimport ExpressionHistogram from './ExpressionHistogram';\n\nconst EXPRESSION_HISTOGRAM_DATA_TYPES = ['expression-matrix'];\n\n/**\n * A subscriber component for `ExpressionHistogram`,\n * which listens for gene selection updates and\n * `GRID_RESIZE` events.\n * @param {object} props\n * @param {function} props.removeGridComponent The grid component removal function.\n * @param {object} props.coordinationScopes An object mapping coordination\n * types to coordination scopes.\n * @param {string} props.theme The name of the current Vitessce theme.\n */\nexport default function ExpressionHistogramSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n  } = props;\n\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    geneSelection,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.expressionHistogram, coordinationScopes);\n\n  const [width, height, containerRef] = useGridItemSize();\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    EXPRESSION_HISTOGRAM_DATA_TYPES,\n  );\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [expressionMatrix] = useExpressionMatrixData(\n    loaders, dataset, setItemIsReady, addUrl, true,\n  );\n  // Get data from loaders using the data hooks.\n  const [expressionData] = useGeneSelection(\n    loaders, dataset, setItemIsReady, false, geneSelection, setItemIsNotReady,\n  );\n\n  const firstGeneSelected = geneSelection && geneSelection.length >= 1\n    ? geneSelection[0]\n    : null;\n\n  // From the expression matrix and the list of selected genes,\n  // generate the array of data points for the histogram.\n  const data = useMemo(() => {\n    if (firstGeneSelected && expressionMatrix && expressionData) {\n      // Create new cellColors map based on the selected gene.\n      return Array.from(expressionData[0]).map((_, index) => {\n        const value = expressionData[0][index];\n        const normValue = value * 100 / 255;\n        return { value: normValue, gene: firstGeneSelected };\n      });\n    }\n    if (expressionMatrix) {\n      const numGenes = expressionMatrix.cols.length;\n      return expressionMatrix.rows.map((cellId, cellIndex) => {\n        const values = expressionMatrix.matrix\n          .subarray(cellIndex * numGenes, (cellIndex + 1) * numGenes);\n        const sumValue = sum(values) * 100 / 255;\n        return { value: sumValue, gene: null };\n      });\n    }\n    return null;\n  }, [expressionMatrix, firstGeneSelected, expressionData]);\n\n  return (\n    <TitleInfo\n      title={`Expression Histogram${(firstGeneSelected ? ` (${firstGeneSelected})` : '')}`}\n      removeGridComponent={removeGridComponent}\n      urls={urls}\n      theme={theme}\n      isReady={isReady}\n    >\n      <div ref={containerRef} className=\"vega-container\">\n        <ExpressionHistogram\n          geneSelection={geneSelection}\n          data={data}\n          theme={theme}\n          width={width}\n          height={height}\n        />\n      </div>\n    </TitleInfo>\n  );\n}\n","import { useMemo } from 'react';\nimport { mergeCellSets } from '../utils';\nimport { treeToObjectsBySetNames, treeToSetSizesBySetNames } from './cell-set-utils';\n\n/**\n * Get expression data for the cells\n * in the selected cell sets.\n * @param {object} expressionMatrix\n * @param {string[]} expressionMatrix.rows Cell IDs.\n * @param {string[]} expressionMatrix.cols Gene names.\n * @param {Uint8Array} expressionMatrix.matrix The\n * flattened expression matrix as a typed array.\n * @param {object} cellSets The cell sets from the dataset.\n * @param {object} additionalCellSets The user-defined cell sets\n * from the coordination space.\n * @param {array} geneSelection Array of selected genes.\n * @param {array} cellSetSelection Array of selected cell set paths.\n * @param {object[]} cellSetColor Array of objects with properties\n * @param {string} theme \"light\" or \"dark\" for the vitessce theme\n * `path` and `color`.\n */\nexport function useExpressionByCellSet(\n  expressionData, expressionDataAttrs, cellSets, additionalCellSets,\n  geneSelection, cellSetSelection, cellSetColor, useGeneExpressionTransform,\n  theme,\n) {\n  const mergedCellSets = useMemo(\n    () => mergeCellSets(cellSets, additionalCellSets),\n    [cellSets, additionalCellSets],\n  );\n\n  // From the expression matrix and the list of selected genes / cell sets,\n  // generate the array of data points for the plot.\n  const [expressionArr, expressionMax] = useMemo(() => {\n    if (mergedCellSets && cellSetSelection\n        && geneSelection && geneSelection.length >= 1\n        && expressionData\n    ) {\n      const cellObjects = treeToObjectsBySetNames(\n        mergedCellSets, cellSetSelection, cellSetColor, theme,\n      );\n\n      const firstGeneSelected = geneSelection[0];\n      // Create new cellColors map based on the selected gene.\n      let exprMax = -Infinity;\n      const cellIndices = {};\n      for (let i = 0; i < expressionDataAttrs.rows.length; i += 1) {\n        cellIndices[expressionDataAttrs.rows[i]] = i;\n      }\n      const exprValues = cellObjects.map((cell) => {\n        const cellIndex = cellIndices[cell.obsId];\n        const value = expressionData[0][cellIndex];\n        const normValue = value * 100 / 255;\n        const transformedValue = useGeneExpressionTransform ? Math.log(1 + normValue) : normValue;\n        exprMax = Math.max(transformedValue, exprMax);\n        return { value: transformedValue, gene: firstGeneSelected, set: cell.name };\n      });\n      return [exprValues, exprMax];\n    }\n    return [null, null];\n  }, [expressionData, expressionDataAttrs, geneSelection, theme,\n    mergedCellSets, cellSetSelection, cellSetColor, useGeneExpressionTransform]);\n\n  // From the cell sets hierarchy and the list of selected cell sets,\n  // generate the array of set sizes data points for the bar plot.\n  const setArr = useMemo(() => (mergedCellSets && cellSetSelection && cellSetColor\n    ? treeToSetSizesBySetNames(mergedCellSets, cellSetSelection, cellSetColor, theme)\n    : []\n  ), [mergedCellSets, cellSetSelection, cellSetColor, theme]);\n\n  return [expressionArr, setArr, expressionMax];\n}\n","import React from 'react';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableRow from '@material-ui/core/TableRow';\nimport { useStyles } from '../shared-plot-options/styles';\nimport OptionsContainer from '../shared-plot-options/OptionsContainer';\n\nexport default function CellSetExpressionPlotOptions(props) {\n  const { toggleGeneExpressionTransform, useGeneExpressionTransform } = props;\n  const classes = useStyles();\n\n  function handleGeneExpressionTransformChange() {\n    toggleGeneExpressionTransform();\n  }\n\n  return (\n    <OptionsContainer>\n      <TableRow>\n        <TableCell className={classes.labelCell}>Log Transform</TableCell>\n        <TableCell className={classes.inputCell}>\n          <Checkbox\n            className={classes.checkbox}\n            checked={Boolean(useGeneExpressionTransform)}\n            onChange={handleGeneExpressionTransformChange}\n            name=\"scatterplot-option-cell-set-labels\"\n            color=\"default\"\n          />\n        </TableCell>\n      </TableRow>\n    </OptionsContainer>\n  );\n}\n","import React from 'react';\nimport clamp from 'lodash/clamp';\nimport { VegaPlot, VEGA_THEMES, DATASET_NAME } from '../vega';\nimport { colorArrayToString } from './utils';\n\n/**\n * Gene expression histogram displayed as a bar chart,\n * implemented with the VegaPlot component.\n * @param {object} props\n * @param {object[]} props.data The expression data, an array\n * of objects with properties `value`, `gene`, and `set`.\n * @param {number} props.domainMax The maximum gene expression value.\n * @param {object[]} props.colors An object for each\n * cell set, with properties `name` and `color`.\n * @param {string} props.theme The name of the current Vitessce theme.\n * @param {number} props.width The container width.\n * @param {number} props.height The container height.\n * @param {number} props.marginRight The size of the margin\n * on the right side of the plot, to account for the vega menu button.\n * By default, 90.\n * @param {number} props.marginBottom The size of the margin\n * on the bottom of the plot, to account for long x-axis labels.\n * Default is allowing the component to automatically determine the margin.\n * @param {boolean} props.useGeneExpressionTransform Boolean representing\n * whether or not the expression values are log-transformed.\n */\nexport default function CellSetExpressionPlot(props) {\n  const {\n    domainMax = 100,\n    colors,\n    data,\n    theme,\n    width,\n    height,\n    marginRight = 90,\n    marginBottom,\n    useGeneExpressionTransform,\n  } = props;\n  // Get the max characters in an axis label for autsizing the bottom margin.\n  const maxCharactersForLabel = data.reduce((acc, val) => {\n    // eslint-disable-next-line no-param-reassign\n    acc = acc === undefined || val.set.length > acc ? val.set.length : acc;\n    return acc;\n  }, 0);\n  // Use a square-root term because the angle of the labels is 45 degrees (see below)\n  // so the perpendicular distance to the bottom of the labels is proportional to the\n  // square root of the length of the labels along the imaginary hypotenuse.\n  // 30 is an estimate of the pixel size of a given character and seems to work well.\n  const autoMarginBottom = marginBottom\n    || 30 + Math.sqrt(maxCharactersForLabel / 2) * 30;\n  // Manually set the color scale so that Vega-Lite does\n  // not choose the colors automatically.\n  const colorScale = {\n    domain: colors.map(d => d.name),\n    range: colors.map(d => colorArrayToString(d.color)),\n  };\n\n  const plotWidth = clamp(width - marginRight, 10, Infinity);\n  const plotHeight = clamp(height - autoMarginBottom, 10, Infinity);\n\n  const numBands = colors.length;\n  const bandWidth = plotWidth / numBands;\n\n  const rectColor = (theme === 'dark' ? 'white' : 'black');\n\n  const spec = {\n    $schema: 'https://vega.github.io/schema/vega/v5.json',\n    description: 'A violin plot showing distributions of expression levels for selected cell sets.',\n    width: plotWidth,\n    height: plotHeight,\n    config: {\n      ...VEGA_THEMES[theme],\n      axisBand: {\n        bandPosition: 1,\n        tickExtra: true,\n        tickOffset: 0,\n      },\n    },\n\n    signals: [\n      { name: 'bandWidth', value: bandWidth },\n      { name: 'width', value: plotWidth },\n      { name: 'height', value: plotHeight },\n      { name: 'trim', value: true },\n    ],\n\n    data: [\n      {\n        name: 'density',\n        source: DATASET_NAME,\n        transform: [\n          {\n            type: 'kde',\n            field: 'value',\n            groupby: ['set'],\n            bandwidth: 0,\n            extent: [0, domainMax],\n          },\n        ],\n      },\n      {\n        name: 'stats',\n        source: DATASET_NAME,\n        transform: [\n          {\n            type: 'aggregate',\n            groupby: ['set'],\n            fields: ['value', 'value', 'value'],\n            ops: ['q1', 'median', 'q3'],\n            as: ['q1', 'median', 'q3'],\n          },\n        ],\n      },\n    ],\n\n    scales: [\n      {\n        name: 'layout',\n        type: 'band',\n        range: 'width',\n        domain: { data: DATASET_NAME, field: 'set' },\n      },\n      {\n        name: 'yscale',\n        type: 'linear',\n        range: 'height',\n        domain: [0, domainMax],\n      },\n      {\n        name: 'wscale',\n        type: 'linear',\n        range: [0, { signal: 'bandWidth' }],\n        domain: { data: 'density', field: 'density' },\n      },\n      {\n        name: 'wscaleReversed',\n        type: 'linear',\n        reverse: true,\n        range: [0, { signal: 'bandWidth' }],\n        domain: { data: 'density', field: 'density' },\n      },\n      {\n        name: 'color',\n        type: 'ordinal',\n        ...colorScale,\n      },\n    ],\n\n    axes: [\n      {\n        orient: 'left',\n        scale: 'yscale',\n        zindex: 1,\n        // title: useGeneExpressionTransform\n        //   ? 'Log-Normalized Expression Values' : 'Normalized Expression Values',\n        title: useGeneExpressionTransform\n          ? ['Log-Transformed', 'Normalized Expression Values']\n          : 'Normalized Expression Values',\n      },\n      {\n        orient: 'bottom',\n        scale: 'layout',\n        tickCount: 5,\n        zindex: 1,\n        title: 'Cell Set',\n        labelAngle: -45,\n        labelAlign: 'right',\n      },\n    ],\n\n    marks: [\n      {\n        type: 'group',\n        from: {\n          facet: {\n            data: 'density',\n            name: 'violin',\n            groupby: 'set',\n          },\n        },\n\n        encode: {\n          enter: {\n            xc: { scale: 'layout', field: 'set', band: 0.5 },\n            width: { signal: 'bandWidth' },\n            height: { signal: 'height' },\n          },\n        },\n\n        data: [\n          {\n            name: 'summary',\n            source: 'stats',\n            transform: [\n              {\n                type: 'filter',\n                expr: 'datum.set === parent.set',\n              },\n            ],\n          },\n        ],\n\n        marks: [\n          {\n            type: 'area',\n            orient: 'vertical',\n            from: { data: 'violin' },\n            encode: {\n              enter: {\n                fill: { scale: 'color', field: { parent: 'set' } },\n              },\n              update: {\n                width: { scale: 'wscale', field: 'density' },\n                xc: { signal: 'bandWidth / 2' },\n                y2: { scale: 'yscale', field: 'value' },\n                y: { scale: 'yscale', value: 0 },\n              },\n            },\n          },\n          {\n            type: 'area',\n            orient: 'vertical',\n            from: { data: 'violin' },\n            encode: {\n              enter: {\n                fill: { scale: 'color', field: { parent: 'set' } },\n              },\n              update: {\n                width: { scale: 'wscaleReversed', field: 'density' },\n                xc: { signal: 'bandWidth' },\n                y2: { scale: 'yscale', field: 'value' },\n                y: { scale: 'yscale', value: 0 },\n              },\n            },\n          },\n          {\n            type: 'rect',\n            from: { data: 'summary' },\n            encode: {\n              enter: {\n                fill: { value: rectColor },\n                width: { value: 2 },\n              },\n              update: {\n                y: { scale: 'yscale', field: 'q1' },\n                y2: { scale: 'yscale', field: 'q3' },\n                xc: { signal: 'bandWidth / 2' },\n              },\n            },\n          },\n          {\n            type: 'rect',\n            from: { data: 'summary' },\n            encode: {\n              enter: {\n                fill: { value: rectColor },\n                height: { value: 2 },\n                width: { value: 8 },\n              },\n              update: {\n                y: { scale: 'yscale', field: 'median' },\n                xc: { signal: 'bandWidth / 2' },\n              },\n            },\n          },\n        ],\n      },\n    ],\n  };\n\n  return (\n    <VegaPlot\n      data={data}\n      spec={spec}\n    />\n  );\n}\n","import React, { useEffect, useReducer } from 'react';\nimport TitleInfo from '../TitleInfo';\nimport { useCoordination, useLoaders } from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport { useUrls, useReady, useGridItemSize } from '../hooks';\nimport { useGeneSelection, useExpressionAttrs, useCellSetsData } from '../data-hooks';\nimport { useExpressionByCellSet } from './hooks';\nimport CellSetExpressionPlotOptions from './CellSetExpressionPlotOptions';\n\nimport CellSetExpressionPlot from './CellSetExpressionPlot';\n\nconst CELL_SET_EXPRESSION_DATA_TYPES = ['cell-sets', 'expression-matrix'];\n\n/**\n * A subscriber component for `CellSetExpressionPlot`,\n * which listens for gene selection updates and\n * `GRID_RESIZE` events.\n * @param {object} props\n * @param {function} props.removeGridComponent The grid component removal function.\n * @param {object} props.coordinationScopes An object mapping coordination\n * types to coordination scopes.\n * @param {string} props.theme The name of the current Vitessce theme.\n */\nexport default function CellSetExpressionPlotSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n  } = props;\n\n  const loaders = useLoaders();\n\n  // Get \"props\" from the coordination space.\n  const [{\n    dataset,\n    geneSelection,\n    geneExpressionTransform,\n    cellSetSelection,\n    cellSetColor,\n    additionalCellSets,\n  }, {\n    setGeneExpressionTransform,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.cellSetExpression, coordinationScopes);\n\n  const [width, height, containerRef] = useGridItemSize();\n  const [urls, addUrl, resetUrls] = useUrls();\n  const [\n    isReady,\n    setItemIsReady,\n    setItemIsNotReady, // eslint-disable-line no-unused-vars\n    resetReadyItems,\n  ] = useReady(\n    CELL_SET_EXPRESSION_DATA_TYPES,\n  );\n\n  const [useGeneExpressionTransform, toggleGeneExpressionTransform] = useReducer((v) => {\n    const newValue = !v;\n    setGeneExpressionTransform(newValue ? 'log1p' : null);\n    return newValue;\n  }, geneExpressionTransform);\n\n  // Reset file URLs and loader progress when the dataset has changed.\n  useEffect(() => {\n    resetUrls();\n    resetReadyItems();\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [loaders, dataset]);\n\n  // Get data from loaders using the data hooks.\n  const [expressionData] = useGeneSelection(\n    loaders, dataset, setItemIsReady, false, geneSelection, setItemIsNotReady,\n  );\n  const [attrs] = useExpressionAttrs(\n    loaders, dataset, setItemIsReady, addUrl, false,\n  );\n  const [cellSets] = useCellSetsData(\n    loaders, dataset, setItemIsReady, addUrl, true,\n  );\n\n  const [expressionArr, setArr, expressionMax] = useExpressionByCellSet(\n    expressionData, attrs, cellSets, additionalCellSets,\n    geneSelection, cellSetSelection, cellSetColor, useGeneExpressionTransform,\n    theme,\n  );\n\n  const firstGeneSelected = geneSelection && geneSelection.length >= 1\n    ? geneSelection[0]\n    : null;\n  return (\n    <TitleInfo\n      title={`Expression by Cell Set${(firstGeneSelected ? ` (${firstGeneSelected})` : '')}`}\n      removeGridComponent={removeGridComponent}\n      urls={urls}\n      theme={theme}\n      isReady={isReady}\n      options={(\n        <CellSetExpressionPlotOptions\n          useGeneExpressionTransform={useGeneExpressionTransform}\n          toggleGeneExpressionTransform={toggleGeneExpressionTransform}\n        />\n      )}\n    >\n      <div ref={containerRef} className=\"vega-container\">\n        {expressionArr ? (\n          <CellSetExpressionPlot\n            domainMax={expressionMax}\n            colors={setArr}\n            data={expressionArr}\n            theme={theme}\n            width={width}\n            height={height}\n            useGeneExpressionTransform={useGeneExpressionTransform}\n          />\n        ) : (\n          <span>Select a gene.</span>\n        )}\n      </div>\n    </TitleInfo>\n  );\n}\n","import { Component } from './constants';\n\nimport DescriptionSubscriber from '../components/description/DescriptionSubscriber';\nimport StatusSubscriber from '../components/status/StatusSubscriber';\nimport GenesSubscriber from '../components/genes/GenesSubscriber';\nimport CellSetsManagerSubscriber from '../components/sets/CellSetsManagerSubscriber';\nimport ScatterplotSubscriber from '../components/scatterplot/ScatterplotSubscriber';\nimport SpatialSubscriber from '../components/spatial/SpatialSubscriber';\nimport HeatmapSubscriber from '../components/heatmap/HeatmapSubscriber';\nimport LayerControllerSubscriber from '../components/layer-controller/LayerControllerSubscriber';\nimport HiGlassSubscriber from '../components/higlass/HiGlassSubscriber';\nimport CellSetSizesPlotSubscriber from '../components/sets/CellSetSizesPlotSubscriber';\nimport GenomicProfilesSubscriber from '../components/higlass/GenomicProfilesSubscriber';\nimport ExpressionHistogramSubscriber from '../components/genes/ExpressionHistogramSubscriber';\nimport CellSetExpressionPlotSubscriber from '../components/sets/CellSetExpressionPlotSubscriber';\n\n\nconst registry = {\n  [Component.DESCRIPTION]: DescriptionSubscriber,\n  [Component.STATUS]: StatusSubscriber,\n  [Component.GENES]: GenesSubscriber,\n  [Component.CELL_SETS]: CellSetsManagerSubscriber,\n  [Component.SCATTERPLOT]: ScatterplotSubscriber,\n  [Component.SPATIAL]: SpatialSubscriber,\n  [Component.HEATMAP]: HeatmapSubscriber,\n  [Component.LAYER_CONTROLLER]: LayerControllerSubscriber,\n  [Component.CELL_SET_SIZES]: CellSetSizesPlotSubscriber,\n  [Component.GENOMIC_PROFILES]: GenomicProfilesSubscriber,\n  [Component.EXPRESSION_HISTOGRAM]: ExpressionHistogramSubscriber,\n  [Component.CELL_SET_EXPRESSION]: CellSetExpressionPlotSubscriber,\n  // The plain higlass component does not abstract away the HiGlass view config,\n  // so we probably want to avoid documenting it, only use it for development purposes.\n  higlass: HiGlassSubscriber,\n};\n\nexport function getComponent(name) {\n  const component = registry[name];\n  if (component === undefined) {\n    throw new Error(`Could not find definition for \"${name}\" in registry.`);\n  }\n  return registry[name];\n}\n","import React from 'react';\nimport { useCoordination, useWarning } from '../../app/state/hooks';\nimport { COMPONENT_COORDINATION_TYPES } from '../../app/state/coordination';\nimport TitleInfo from '../TitleInfo';\nimport Status from './Status';\n\n/**\n * A subscriber component for the status component,\n * which renders hovered cell/gene/molecule information\n * as well as schema validation and data loading errors.\n * @param {object} props\n * @param {string} props.theme The current theme name.\n * @param {object} props.coordinationScopes The mapping from coordination types to coordination\n * scopes.\n * @param {function} props.removeGridComponent The callback function to pass to TitleInfo,\n * to call when the component has been removed from the grid.\n * @param {string} props.title The component title.\n */\nexport default function StatusSubscriber(props) {\n  const {\n    coordinationScopes,\n    removeGridComponent,\n    theme,\n    title = 'Status',\n  } = props;\n\n  // Get \"props\" from the coordination space.\n  const [{\n    cellHighlight,\n    geneHighlight,\n    moleculeHighlight,\n  }] = useCoordination(COMPONENT_COORDINATION_TYPES.status, coordinationScopes);\n\n  const warn = useWarning();\n\n  const infos = [\n    ...(cellHighlight\n      ? [`Hovered cell ${cellHighlight}`]\n      : []\n    ),\n    ...(geneHighlight\n      ? [`Hovered gene ${geneHighlight}`]\n      : []\n    ),\n    ...(moleculeHighlight\n      ? [`Hovered gene ${moleculeHighlight}`]\n      : []\n    ),\n  ];\n  const info = infos.join('; ');\n\n  return (\n    <TitleInfo\n      title={title}\n      theme={theme}\n      removeGridComponent={removeGridComponent}\n      isScroll\n      isReady\n    >\n      <Status warn={warn} info={info} />\n    </TitleInfo>\n  );\n}\n","import { OrthographicView } from 'deck.gl';\nimport clamp from 'lodash/clamp';\n\n// Reference: https://observablehq.com/@rreusser/selecting-the-right-opacity-for-2d-point-clouds\n// Reference: https://observablehq.com/@bmschmidt/dot-density-election-maps-with-webgl\nexport function getPointSizeDevicePixels(devicePixelRatio, zoom, xRange, yRange, width, height) {\n  // Size of a point, in units of the diagonal axis.\n  const pointSize = 0.001;\n  // Point size maximum, in screen pixels.\n  const pointScreenSizeMax = 10;\n\n  // Point size minimum, in screen pixels.\n  const pointScreenSizeMin = 1 / devicePixelRatio;\n\n  const scaleFactor = 2 ** zoom;\n  const xAxisRange = 2.0 / ((xRange * scaleFactor) / width);\n  const yAxisRange = 2.0 / ((yRange * scaleFactor) / height);\n\n  // The diagonal screen size as a fraction of the current diagonal axis range,\n  // then converted to device pixels.\n  const diagonalScreenSize = Math.sqrt((width ** 2) + (height ** 2));\n  const diagonalAxisRange = Math.sqrt((xAxisRange ** 2) + (yAxisRange ** 2));\n  const diagonalFraction = pointSize / diagonalAxisRange;\n  const deviceSize = diagonalFraction * diagonalScreenSize;\n\n  const pointSizeDevicePixels = clamp(\n    deviceSize,\n    pointScreenSizeMin,\n    pointScreenSizeMax,\n  );\n  return pointSizeDevicePixels;\n}\n\n// Reference: https://observablehq.com/@rreusser/selecting-the-right-opacity-for-2d-point-clouds\nexport function getPointOpacity(zoom, xRange, yRange, width, height, numCells, avgFillDensity) {\n  const N = numCells;\n  const [minX, minY, maxX, maxY] = new OrthographicView({ zoom }).makeViewport({\n    height,\n    width,\n    viewState: { zoom, target: [0, 0, 0] },\n  }).getBounds();\n  const X = maxY - minY;\n  const Y = maxX - minX;\n  const X0 = xRange;\n  const Y0 = yRange;\n  const W = width;\n  const H = height;\n\n  let rho = avgFillDensity;\n  if (!rho) {\n    rho = Math.min(1, 1 / (10 ** (Math.log10(N) - 3)));\n  }\n  // p in the calculation is the pixel length/width of a given point, which for us is 1\n  // so it does not factor into our calculation here.\n  const alpha = ((rho * W * H) / N) * (Y0 / Y) * (X0 / X);\n  const pointOpacity = clamp(alpha, 1.01 / 255, 1.0);\n  return pointOpacity;\n}\n","/* eslint-disable no-plusplus */\n/* eslint-disable camelcase */\nimport packageJson from '../../package.json';\nimport { getNextScope } from '../utils';\nimport {\n  DEFAULT_COORDINATION_VALUES,\n  COMPONENT_COORDINATION_TYPES,\n  AUTO_INDEPENDENT_COORDINATION_TYPES,\n} from './state/coordination';\nimport { CoordinationType } from './constants';\nimport { SCHEMA_HANDLERS } from './view-config-versions';\n\n/**\n * Get a list of all unique scope names for a\n * particular coordination type, which exist in\n * a particular view config.\n * @param {object} config A view config object.\n * @param {string} coordinationType A coordination type,\n * for example 'spatialZoom' or 'dataset'.\n * @returns {string[]} Array of existing coordination scope names.\n */\nexport function getExistingScopesForCoordinationType(config, coordinationType) {\n  const spaceScopes = Object.keys(config?.coordinationSpace?.[coordinationType] || {});\n  const componentScopes = config.layout.map(c => c.coordinationScopes?.[coordinationType]);\n  return Array.from(new Set([...spaceScopes, ...componentScopes]));\n}\n\n/**\n * Give each component the same scope name for this coordination type.\n * @param {object} config A view config object.\n * @param {string} coordinationType A coordination type,\n * for example 'spatialZoom' or 'dataset'.\n * @param {*} scopeValue The initial value for the coordination scope,\n * to set in the coordination space.\n * @returns {object} The new view config.\n */\nfunction coordinateComponentsTogether(config, coordinationType, scopeValue) {\n  const scopeName = getNextScope(getExistingScopesForCoordinationType(config, coordinationType));\n  const newConfig = {\n    ...config,\n    coordinationSpace: {\n      ...config.coordinationSpace,\n      [coordinationType]: {\n        ...config?.coordinationSpace?.[coordinationType],\n        // Add the new scope name and value to the coordination space.\n        [scopeName]: scopeValue,\n      },\n    },\n    layout: config.layout.map(component => ({\n      ...component,\n      coordinationScopes: {\n        ...component.coordinationScopes,\n        // Only set the coordination scope if this component uses this coordination type,\n        // and the component is missing a coordination scope for this coordination type.\n        ...((\n          COMPONENT_COORDINATION_TYPES[component.component].includes(coordinationType)\n          && !component.coordinationScopes?.[coordinationType]\n        ) ? {\n          // Only set the new scope name if the scope name\n          // for this component and coordination type is currently undefined.\n            [coordinationType]: scopeName,\n          } : {}),\n      },\n    })),\n  };\n  return newConfig;\n}\n\n/**\n * Give each component a different scope name for this coordination type.\n * @param {object} config A view config object.\n * @param {string} coordinationType A coordination type,\n * for example 'spatialZoom' or 'dataset'.\n * @param {*} scopeValue The initial value for the coordination scope,\n * to set in the coordination space.\n * @returns {object} The new view config.\n */\nfunction coordinateComponentsIndependent(config, coordinationType, scopeValue) {\n  const newConfig = {\n    ...config,\n    layout: [...config.layout],\n  };\n  const newScopes = {};\n  newConfig.layout.forEach((component, i) => {\n    // Only set the coordination scope if this component uses this coordination type,\n    // and the component is missing a coordination scope for this coordination type.\n    if (COMPONENT_COORDINATION_TYPES[component.component].includes(coordinationType)\n      && !component.coordinationScopes?.[coordinationType]\n    ) {\n      const scopeName = getNextScope([\n        ...getExistingScopesForCoordinationType(config, coordinationType),\n        ...Object.keys(newScopes),\n      ]);\n      newScopes[scopeName] = scopeValue;\n      newConfig.layout[i] = {\n        ...component,\n        coordinationScopes: {\n          ...component.coordinationScopes,\n          [coordinationType]: scopeName,\n        },\n      };\n    }\n  });\n  newConfig.coordinationSpace = {\n    ...newConfig.coordinationSpace,\n    [coordinationType]: {\n      ...newConfig.coordinationSpace[coordinationType],\n      // Add the new scope name and value to the coordination space.\n      ...newScopes,\n    },\n  };\n  return newConfig;\n}\n\nfunction initializeAuto(config) {\n  let newConfig = config;\n  const { layout, datasets } = newConfig;\n\n  // For each coordination type, check whether it requires initialization.\n  Object.values(CoordinationType).forEach((coordinationType) => {\n    // A coordination type requires coordination if at least one component is missing\n    // a (coordination type, coordination scope) tuple.\n    // Components may only use a subset of all coordination types.\n    const requiresCoordination = !layout\n      .every(c => (\n        !COMPONENT_COORDINATION_TYPES[c.component].includes(coordinationType)\n                || c.coordinationScopes?.[coordinationType]\n      ));\n    if (requiresCoordination) {\n      // Note that the default value may be undefined.\n      let defaultValue = DEFAULT_COORDINATION_VALUES[coordinationType];\n      // Check whether this is the special 'dataset' coordination type.\n      if (coordinationType === 'dataset' && datasets.length >= 1) {\n        // Use the first dataset ID as the default\n        // if there is at least one dataset.\n        defaultValue = datasets[0].uid;\n      }\n      // Use the list of \"independent\" coordination types\n      // to determine whether a particular coordination type\n      // should be initialized to\n      // a unique scope for every component (\"independent\")\n      // vs. the same scope for every component (\"together\").\n      if (AUTO_INDEPENDENT_COORDINATION_TYPES.includes(coordinationType)) {\n        newConfig = coordinateComponentsIndependent(newConfig, coordinationType, defaultValue);\n      } else {\n        newConfig = coordinateComponentsTogether(newConfig, coordinationType, defaultValue);\n      }\n    }\n  });\n\n  return newConfig;\n}\n\n\n/**\n * Initialize the view config:\n * - Fill in missing coordination objects with default values.\n * - Fill in missing component coordination scope mappings.\n *   based on the `initStrategy` specified in the view config.\n * Should be \"stable\": if run on the same view config twice, the return value the second\n * time should be identical to the return value the first time.\n * @param {object} config The view config prop.\n */\nexport function initialize(config) {\n  if (config.initStrategy === 'auto') {\n    return initializeAuto(config);\n  }\n  return config;\n}\n\nexport function upgradeAndValidate(oldConfig) {\n  // oldConfig object must have a `version` property.\n  let nextConfig = oldConfig;\n  let fromVersion;\n  let upgradeFunction; let\n    validateFunction;\n\n  do {\n    fromVersion = nextConfig.version;\n\n    if (!Object.keys(SCHEMA_HANDLERS).includes(fromVersion)) {\n      return [{\n        title: 'Config validation failed',\n        preformatted: 'Unknown config version.',\n      }, false];\n    }\n\n    [validateFunction, upgradeFunction] = SCHEMA_HANDLERS[fromVersion];\n\n    // Validate under the legacy schema before upgrading.\n    const validLegacy = validateFunction(nextConfig);\n    if (!validLegacy) {\n      const failureReason = JSON.stringify(validateFunction.errors, null, 2);\n      return [{\n        title: 'Config validation failed',\n        preformatted: failureReason,\n      }, false];\n    }\n\n    if (upgradeFunction) {\n      nextConfig = upgradeFunction(nextConfig);\n    }\n  } while (upgradeFunction);\n\n  // NOTE: Remove when a view config viewer/editor is available in UI.\n  console.groupCollapsed(`🚄 Vitessce (${packageJson.version}) view configuration`);\n  console.info(`data:,${JSON.stringify(nextConfig)}`);\n  console.info(JSON.stringify(nextConfig, null, 2));\n  console.groupEnd();\n\n  return [nextConfig, true];\n}\n","/* eslint-disable camelcase */\nimport React, { useEffect, useMemo } from 'react';\nimport {\n  ThemeProvider, StylesProvider,\n  createGenerateClassName,\n} from '@material-ui/core/styles';\nimport isEqual from 'lodash/isEqual';\nimport { muiTheme } from '../components/shared-mui/styles';\nimport {\n  ViewConfigProvider, createViewConfigStore,\n  AuxiliaryProvider, createAuxiliaryStore,\n} from './state/hooks';\n\nimport VitessceGrid from './VitessceGrid';\nimport Warning from './Warning';\nimport CallbackPublisher from './CallbackPublisher';\nimport { getComponent } from './component-registry';\nimport { initialize, upgradeAndValidate } from './view-config-utils';\n\nconst generateClassName = createGenerateClassName({\n  disableGlobal: true,\n});\n\n/**\n * The Vitessce component.\n * @param {object} props\n * @param {object} props.config A Vitessce view config.\n * If the config is valid, the VitessceGrid will be rendered as a child.\n * If the config is invalid, a Warning will be rendered instead.\n * @param {number} props.rowHeight Row height for grid layout. Optional.\n * @param {number} props.height Total height for grid layout. Optional.\n * @param {string} props.theme The theme, used for styling as\n * light or dark. Optional. By default, \"dark\"\n * @param {function} props.onWarn A callback for warning messages. Optional.\n * @param {function} props.onConfigChange A callback for view config\n * updates. Optional.\n * @param {function} props.onLoaderChange A callback for loader\n * updates. Optional.\n * @param {boolean} props.validateOnConfigChange Whether to validate\n * against the view config schema when publishing changes. Use for debugging\n * purposes, as this may have a performance impact. By default, false.\n */\nexport default function Vitessce(props) {\n  const {\n    config,\n    rowHeight,\n    height,\n    theme,\n    onWarn,\n    onConfigChange,\n    onLoaderChange,\n    validateOnConfigChange = false,\n  } = props;\n\n  // Process the view config and memoize the result:\n  // - Validate.\n  // - Upgrade, if legacy schema.\n  // - Validate after upgrade, if legacy schema.\n  // - Initialize (based on initStrategy).\n  const [configOrWarning, success] = useMemo(() => {\n    // If the config value is undefined, show a warning message.\n    if (!config) {\n      return [{\n        title: 'No such dataset',\n        unformatted: 'The dataset configuration could not be found.',\n      }, false];\n    }\n    // If the view config is missing a version, show a warning message.\n    if (!config.version) {\n      return [{\n        title: 'Missing version',\n        unformatted: 'The dataset configuration is missing a version, preventing validation.',\n      }, false];\n    }\n    // Check if this is a \"legacy\" view config.\n    const [upgradedConfig, upgradeSuccess] = upgradeAndValidate(config);\n    if (upgradeSuccess) {\n      // Initialize the view config according to the initStrategy.\n      const initializedConfig = initialize(upgradedConfig);\n      return [initializedConfig, true];\n    }\n    return [upgradedConfig, false];\n  }, [config]);\n\n  // Emit the upgraded/initialized view config\n  // to onConfigChange if necessary.\n  useEffect(() => {\n    if (success && !isEqual(configOrWarning, config) && onConfigChange) {\n      onConfigChange(configOrWarning);\n    }\n  }, [success, config, configOrWarning, onConfigChange]);\n\n  return success ? (\n    <StylesProvider generateClassName={generateClassName}>\n      <ThemeProvider theme={muiTheme[theme]}>\n        <ViewConfigProvider createStore={createViewConfigStore}>\n          <AuxiliaryProvider createStore={createAuxiliaryStore}>\n            <VitessceGrid\n              config={configOrWarning}\n              getComponent={getComponent}\n              rowHeight={rowHeight}\n              height={height}\n              theme={theme}\n            />\n            <CallbackPublisher\n              onWarn={onWarn}\n              onConfigChange={onConfigChange}\n              onLoaderChange={onLoaderChange}\n              validateOnConfigChange={validateOnConfigChange}\n            />\n          </AuxiliaryProvider>\n        </ViewConfigProvider>\n      </ThemeProvider>\n    </StylesProvider>\n  ) : (\n    <Warning\n      theme={theme}\n      {...configOrWarning}\n    />\n  );\n}\n","import React, { useEffect, useRef, useState } from 'react';\nimport { getConfig } from './api';\nimport Warning from './Warning';\nimport Vitessce from './Vitessce';\n\nimport '../css/index.scss';\nimport '../../node_modules/react-grid-layout/css/styles.css';\nimport '../../node_modules/react-resizable/css/styles.css';\n\nfunction AwaitResponse(props) {\n  const {\n    response,\n    theme,\n  } = props;\n  const [isLoading, setIsLoading] = useState(true);\n  const responseRef = useRef();\n  useEffect(() => {\n    response.then((c) => {\n      responseRef.current = c;\n      setIsLoading(false);\n    });\n  }, [response]);\n  return (!isLoading ? React.createElement(responseRef.current)\n    : <Warning title=\"Loading...\" theme={theme} />);\n}\n\nfunction preformattedDetails(response) {\n  return `\n    ok: ${response.ok}\n    status: ${response.status}\n    statusText: ${response.statusText}\n    redirected: ${response.redirected}\n    type: ${response.type}\n    url: ${response.url}`; // TODO: headers\n}\n\n\nfunction checkResponse(response, theme) {\n  if (!response.ok) {\n    return Promise.resolve(\n      () => (\n        <Warning\n          title=\"Fetch response not OK\"\n          preformatted={preformattedDetails(response)}\n          theme={theme}\n        />\n      ),\n    );\n  }\n  return response.text().then((text) => {\n    try {\n      const url = window.location.href;\n      const base = url.split('?')[0];\n      const json = text.replaceAll('http://localhost/', base);\n      const config = JSON.parse(json);\n      return Promise.resolve(() => (\n        <Vitessce\n          config={config}\n          rowHeight={600}\n          theme={theme}\n        />\n      ));\n    } catch (e) {\n      return Promise.resolve(() => (\n        <Warning\n          title=\"Error parsing JSON\"\n          preformatted={preformattedDetails(response)}\n          unformatted={`${e.message}: ${text}`}\n          theme={theme}\n        />\n      ));\n    }\n  });\n}\n\n/**\n * Use the theme provided if it is valid, otherwise fall back to the 'dark' theme.\n * @param {string} theme A potentially invalid theme name.\n * @returns {string} A valid theme name.\n */\n// function validateTheme(theme) {\n//   return (['light', 'dark'].includes(theme) ? theme : 'dark');\n// }\n\n/**\n * Convenience function for creating the minimal Vitessce demo and demo listing\n * components based on the current URL parameters.\n * @param {object} params\n * @param {number|null} params.rowHeight The row height to pass to the Vitessce grid.\n * Optional. By default, null.\n * @returns A component, either <Welcome/> or <Vitessce/> depending on the URL params.\n */\nexport function createApp() {\n  // const { rowHeight = null } = params || {};\n  const urlParams = new URLSearchParams(window.location.search);\n  const datasetId = urlParams.get('dataset');\n  // const debug = urlParams.get('debug') === 'true';\n  // const datasetUrl = urlParams.get('url');\n  // const showAll = urlParams.get('show') === 'all';\n  // const theme = validateTheme(urlParams.get('theme'));\n  const theme = 'dark';\n\n  if (datasetId) {\n    const config = getConfig(datasetId);\n    return (\n      <Vitessce\n        config={config}\n        rowHeight={600}\n        theme={theme}\n        // eslint-disable-next-line no-console\n        // onConfigChange={(debug ? console.log : undefined)}\n        // validateOnConfigChange={debug}\n      />\n    );\n  }\n  const responsePromise = fetch('config.json')\n    .then(response => checkResponse(response, theme))\n    .catch(error => Promise.resolve(() => (\n      <Warning\n        title=\"Error fetching\"\n        unformatted={error.message}\n        theme={theme}\n      />\n    )));\n  return (\n    <AwaitResponse response={responsePromise} theme={theme} />\n  );\n}\n","import 'whatwg-fetch';\nimport ReactDOM from 'react-dom';\nimport { createApp } from '../app';\n\nfunction renderComponent(react, id) {\n  ReactDOM.render(react, document.getElementById(id));\n}\n\n// const urlParams = new URLSearchParams(window.location.search);\n// if (urlParams.has('small')) {\n//   renderComponent(createApp({ rowHeight: 100 }), 'small-app');\n// } else {\nrenderComponent(createApp(), 'full-app');\n","import { configs } from '../demo/configs';\n\nexport function listConfigs(showAll) {\n  return Object.entries(configs).filter(\n    entry => showAll || entry[1].public,\n  ).map(\n    ([id, config]) => ({\n      id,\n      name: config.name,\n      description: config.description,\n    }),\n  );\n}\n\nexport function getConfig(id) {\n  return configs[id];\n}\n","module.exports = function() {\n  return require(\"!!/Users/guq/projects/vitessce/node_modules/worker-loader/dist/workers/InlineWorker.js\")(\"!function(t){var n={};function e(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,e),o.l=!0,o.exports}e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{enumerable:!0,get:r})},e.r=function(t){\\\"undefined\\\"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:\\\"Module\\\"}),Object.defineProperty(t,\\\"__esModule\\\",{value:!0})},e.t=function(t,n){if(1&n&&(t=e(t)),8&n)return t;if(4&n&&\\\"object\\\"===typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(e.r(r),Object.defineProperty(r,\\\"default\\\",{enumerable:!0,value:t}),2&n&&\\\"string\\\"!=typeof t)for(var o in t)e.d(r,o,function(n){return t[n]}.bind(null,o));return r},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,\\\"a\\\",n),n},e.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},e.p=\\\"./\\\",e(e.s=23)}([function(t,n){t.exports=function(t){var n=typeof t;return null!=t&&(\\\"object\\\"==n||\\\"function\\\"==n)}},function(t,n,e){var r=e(6),o=e(3);t.exports=function(t,n,e){return void 0===e&&(e=n,n=void 0),void 0!==e&&(e=(e=o(e))===e?e:0),void 0!==n&&(n=(n=o(n))===n?n:0),r(o(t),n,e)}},function(t,n,e){var r=e(14)();t.exports=r},function(t,n,e){var r=e(0),o=e(7),i=/^\\\\s+|\\\\s+$/g,u=/^[-+]0x[0-9a-f]+$/i,c=/^0b[01]+$/i,f=/^0o[0-7]+$/i,l=parseInt;t.exports=function(t){if(\\\"number\\\"==typeof t)return t;if(o(t))return NaN;if(r(t)){var n=\\\"function\\\"==typeof t.valueOf?t.valueOf():t;t=r(n)?n+\\\"\\\":n}if(\\\"string\\\"!=typeof t)return 0===t?t:+t;t=t.replace(i,\\\"\\\");var e=c.test(t);return e||f.test(t)?l(t.slice(2),e?2:8):u.test(t)?NaN:+t}},function(t,n,e){var r=e(5),o=e(11),i=e(12),u=r?r.toStringTag:void 0;t.exports=function(t){return null==t?void 0===t?\\\"[object Undefined]\\\":\\\"[object Null]\\\":u&&u in Object(t)?o(t):i(t)}},function(t,n,e){var r=e(8).Symbol;t.exports=r},function(t,n){t.exports=function(t,n,e){return t===t&&(void 0!==e&&(t=t<=e?t:e),void 0!==n&&(t=t>=n?t:n)),t}},function(t,n,e){var r=e(4),o=e(13);t.exports=function(t){return\\\"symbol\\\"==typeof t||o(t)&&\\\"[object Symbol]\\\"==r(t)}},function(t,n,e){var r=e(9),o=\\\"object\\\"==typeof self&&self&&self.Object===Object&&self,i=r||o||Function(\\\"return this\\\")();t.exports=i},function(t,n,e){(function(n){var e=\\\"object\\\"==typeof n&&n&&n.Object===Object&&n;t.exports=e}).call(this,e(10))},function(t,n){var e;e=function(){return this}();try{e=e||new Function(\\\"return this\\\")()}catch(r){\\\"object\\\"===typeof window&&(e=window)}t.exports=e},function(t,n,e){var r=e(5),o=Object.prototype,i=o.hasOwnProperty,u=o.toString,c=r?r.toStringTag:void 0;t.exports=function(t){var n=i.call(t,c),e=t[c];try{t[c]=void 0;var r=!0}catch(f){}var o=u.call(t);return r&&(n?t[c]=e:delete t[c]),o}},function(t,n){var e=Object.prototype.toString;t.exports=function(t){return e.call(t)}},function(t,n){t.exports=function(t){return null!=t&&\\\"object\\\"==typeof t}},function(t,n,e){var r=e(15),o=e(16),i=e(22);t.exports=function(t){return function(n,e,u){return u&&\\\"number\\\"!=typeof u&&o(n,e,u)&&(e=u=void 0),n=i(n),void 0===e?(e=n,n=0):e=i(e),u=void 0===u?n<e?1:-1:i(u),r(n,e,u,t)}}},function(t,n){var e=Math.ceil,r=Math.max;t.exports=function(t,n,o,i){for(var u=-1,c=r(e((n-t)/(o||1)),0),f=Array(c);c--;)f[i?c:++u]=t,t+=o;return f}},function(t,n,e){var r=e(17),o=e(18),i=e(21),u=e(0);t.exports=function(t,n,e){if(!u(e))return!1;var c=typeof n;return!!(\\\"number\\\"==c?o(e)&&i(n,e.length):\\\"string\\\"==c&&n in e)&&r(e[n],t)}},function(t,n){t.exports=function(t,n){return t===n||t!==t&&n!==n}},function(t,n,e){var r=e(19),o=e(20);t.exports=function(t){return null!=t&&o(t.length)&&!r(t)}},function(t,n,e){var r=e(4),o=e(0);t.exports=function(t){if(!o(t))return!1;var n=r(t);return\\\"[object Function]\\\"==n||\\\"[object GeneratorFunction]\\\"==n||\\\"[object AsyncFunction]\\\"==n||\\\"[object Proxy]\\\"==n}},function(t,n){t.exports=function(t){return\\\"number\\\"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},function(t,n){var e=/^(?:0|[1-9]\\\\d*)$/;t.exports=function(t,n){var r=typeof t;return!!(n=null==n?9007199254740991:n)&&(\\\"number\\\"==r||\\\"symbol\\\"!=r&&e.test(t))&&t>-1&&t%1==0&&t<n}},function(t,n,e){var r=e(3);t.exports=function(t){return t?(t=r(t))===1/0||t===-1/0?17976931348623157e292*(t<0?-1:1):t===t?t:0:0===t?t:0}},function(t,n,e){\\\"use strict\\\";e.r(n);e(1);var r=e(2),o=e.n(r);function i(t,n,e){return n in t?Object.defineProperty(t,n,{value:e,enumerable:!0,configurable:!0,writable:!0}):t[n]=e,t}var u,c=9728,f=10240,l=10241,a=10242,s=10243,p=33071;i(u={},l,c),i(u,f,c),i(u,a,p),i(u,s,p);function v(t,n){var e,r,i,u=n.tileSize,c=n.tileI,f=n.tileJ,l=n.numCells,a=n.numGenes,s=n.cellOrdering,p=n.cells,v=new Uint8Array(u*u),d=o()(u);return d.forEach((function(n){(r=f*u+n)<l&&(i=p.indexOf(s[r]))>=-1&&d.forEach((function(r){e=t[i*a+(c*u+r)],v[(u-r-1)*u+n]=e}))})),v}function d(t,n){var e,r,i,u,c=n.tileSize,f=n.tileI,l=n.tileJ,a=n.numCells,s=n.numGenes,p=n.cellOrdering,v=n.cells,d=new Uint8Array(c*c),b=o()(c);return b.forEach((function(n){(r=f*c+n)<a&&(u=v.indexOf(p[r]))>=-1&&b.forEach((function(r){e=(i=l*c+r)<s?t[u*s+i]:0,d[(c-n-1)*c+r]=e}))})),d}if(\\\"undefined\\\"!==typeof self){const t={getTile:function({curr:t,tileI:n,tileJ:e,tileSize:r,cellOrdering:o,rows:i,cols:u,data:c,transpose:f}){const l=new Uint8Array(c),a=u.length;return[{tile:(f?v:d)(l,{tileSize:r,tileI:n,tileJ:e,numCells:o.length,numGenes:a,cellOrdering:o,cells:i}),buffer:c,curr:t},[c]]}};self.addEventListener(\\\"message\\\",n=>{try{const[e,r]=n.data,[o,i]=t[e](r);self.postMessage(o,i)}catch(e){console.warn(e)}})}}]);\\n//# sourceMappingURL=6f6f723a7874f4178a42.worker.js.map\", null);\n};"],"sourceRoot":""}