@jbrowse/plugin-linear-genome-view 4.3.0 → 5.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/FeatureTrack/configSchema.d.ts +104 -65
- package/esm/FeatureTrack/configSchema.js +47 -1
- package/esm/FeatureTrack/index.js +1 -1
- package/esm/LaunchLinearGenomeView/index.d.ts +14 -0
- package/esm/LaunchLinearGenomeView/index.js +6 -12
- package/esm/LinearGenomeView/afterAttach.d.ts +20 -2
- package/esm/LinearGenomeView/afterAttach.js +250 -121
- package/esm/LinearGenomeView/components/CenterLine.d.ts +1 -1
- package/esm/LinearGenomeView/components/CenterLine.js +16 -7
- package/esm/LinearGenomeView/components/ConnectedHoverHighlight.d.ts +7 -0
- package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +22 -0
- package/esm/LinearGenomeView/components/CrisprGuidePanel.d.ts +3 -0
- package/esm/LinearGenomeView/components/CrisprGuidePanel.js +144 -0
- package/esm/LinearGenomeView/components/Cytobands.d.ts +6 -6
- package/esm/LinearGenomeView/components/Cytobands.js +76 -53
- package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +7 -3
- package/esm/LinearGenomeView/components/ExportSvgDialog.js +11 -67
- package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +5 -9
- package/esm/LinearGenomeView/components/GetSequenceDialog.js +84 -88
- package/esm/LinearGenomeView/components/Gridlines.d.ts +1 -1
- package/esm/LinearGenomeView/components/Gridlines.js +29 -58
- package/esm/LinearGenomeView/components/Header.d.ts +1 -1
- package/esm/LinearGenomeView/components/Header.js +32 -16
- package/esm/LinearGenomeView/components/HeaderClearHighlightButton.d.ts +21 -0
- package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +35 -0
- package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -2
- package/esm/LinearGenomeView/components/HeaderPanControls.js +16 -7
- package/esm/LinearGenomeView/components/HeaderRegionWidth.d.ts +1 -1
- package/esm/LinearGenomeView/components/HeaderRegionWidth.js +9 -6
- package/esm/LinearGenomeView/components/HeaderSearchBoxRow.d.ts +6 -0
- package/esm/LinearGenomeView/components/HeaderSearchBoxRow.js +27 -0
- package/esm/LinearGenomeView/components/HeaderSearchBoxes.d.ts +5 -0
- package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +28 -0
- package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.d.ts +3 -2
- package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.js +11 -4
- package/esm/LinearGenomeView/components/HeaderZoomControls.d.ts +3 -2
- package/esm/LinearGenomeView/components/HeaderZoomControls.js +67 -51
- package/esm/LinearGenomeView/components/Highlight.d.ts +1 -1
- package/esm/LinearGenomeView/components/Highlight.js +19 -23
- package/esm/LinearGenomeView/components/HighlightBand.d.ts +3 -2
- package/esm/LinearGenomeView/components/HighlightBand.js +25 -8
- package/esm/LinearGenomeView/components/HighlightChip.d.ts +9 -0
- package/esm/LinearGenomeView/components/HighlightChip.js +15 -0
- package/esm/LinearGenomeView/components/HoverPositionHighlight.d.ts +12 -0
- package/esm/LinearGenomeView/components/HoverPositionHighlight.js +25 -0
- package/esm/LinearGenomeView/components/ImportForm.d.ts +3 -4
- package/esm/LinearGenomeView/components/ImportForm.js +95 -61
- package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +1 -1
- package/esm/LinearGenomeView/components/LinearGenomeView.js +6 -5
- package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +1 -1
- package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +89 -30
- package/esm/LinearGenomeView/components/MiniControls.d.ts +1 -1
- package/esm/LinearGenomeView/components/MiniControls.js +13 -10
- package/esm/LinearGenomeView/components/MotifListPanel.d.ts +3 -0
- package/esm/LinearGenomeView/components/MotifListPanel.js +59 -0
- package/esm/LinearGenomeView/components/NavigationAnnouncer.d.ts +32 -0
- package/esm/LinearGenomeView/components/NavigationAnnouncer.js +51 -0
- package/esm/LinearGenomeView/components/NoTracksActiveButton.d.ts +1 -1
- package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
- package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +2 -4
- package/esm/LinearGenomeView/components/OverviewHighlight.js +23 -44
- package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +9 -0
- package/esm/LinearGenomeView/components/OverviewHighlightBand.js +26 -0
- package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +3 -3
- package/esm/LinearGenomeView/components/OverviewRubberband.js +44 -57
- package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +4 -5
- package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +13 -20
- package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +3 -2
- package/esm/LinearGenomeView/components/OverviewScalebar.js +84 -79
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +19 -5
- package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +55 -32
- package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.d.ts +4 -5
- package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.js +16 -18
- package/esm/LinearGenomeView/components/PaddingBlocks.d.ts +7 -0
- package/esm/LinearGenomeView/components/PaddingBlocks.js +61 -0
- package/esm/LinearGenomeView/components/RangeSelectOverlay.d.ts +9 -0
- package/esm/LinearGenomeView/components/RangeSelectOverlay.js +20 -0
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +2 -3
- package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +19 -26
- package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -1
- package/esm/LinearGenomeView/components/Rubberband.js +13 -16
- package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -0
- package/esm/LinearGenomeView/components/SVGHighlightBand.js +9 -0
- package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -2
- package/esm/LinearGenomeView/components/Scalebar.js +16 -21
- package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.d.ts +1 -1
- package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.js +54 -35
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.d.ts +1 -1
- package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +142 -126
- package/esm/LinearGenomeView/components/SearchBox.d.ts +22 -2
- package/esm/LinearGenomeView/components/SearchBox.js +58 -66
- package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +9 -0
- package/esm/LinearGenomeView/components/SearchPanelForm.js +18 -0
- package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +3 -3
- package/esm/LinearGenomeView/components/SearchResultsDialog.js +5 -7
- package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -3
- package/esm/LinearGenomeView/components/SearchResultsTable.js +45 -53
- package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.d.ts +5 -0
- package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +37 -0
- package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.d.ts +2 -0
- package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.js +5 -0
- package/esm/LinearGenomeView/components/SequencePatternPanel.d.ts +3 -0
- package/esm/LinearGenomeView/components/SequencePatternPanel.js +42 -0
- package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -2
- package/esm/LinearGenomeView/components/SequenceSearchDialog.js +31 -53
- package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +8 -0
- package/esm/LinearGenomeView/components/StrandCheckboxes.js +13 -0
- package/esm/LinearGenomeView/components/TrackContainer.d.ts +1 -1
- package/esm/LinearGenomeView/components/TrackContainer.js +83 -39
- package/esm/LinearGenomeView/components/TrackLabel.d.ts +2 -3
- package/esm/LinearGenomeView/components/TrackLabel.js +11 -24
- package/esm/LinearGenomeView/components/TrackLabelButtons.d.ts +7 -0
- package/esm/LinearGenomeView/components/TrackLabelButtons.js +33 -0
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.d.ts +2 -5
- package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +6 -2
- package/esm/LinearGenomeView/components/TrackLabelMenu.d.ts +1 -1
- package/esm/LinearGenomeView/components/TrackLabelMenu.js +32 -85
- package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +22 -0
- package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +46 -0
- package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +1 -1
- package/esm/LinearGenomeView/components/TrackRenderingContainer.js +72 -18
- package/esm/LinearGenomeView/components/TracksContainer.d.ts +1 -1
- package/esm/LinearGenomeView/components/TracksContainer.js +65 -32
- package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -1
- package/esm/LinearGenomeView/components/VerticalGuide.js +6 -13
- package/esm/LinearGenomeView/components/ZoomButton.d.ts +7 -0
- package/esm/LinearGenomeView/components/ZoomButton.js +27 -0
- package/esm/LinearGenomeView/components/ZoomTransform.d.ts +9 -0
- package/esm/LinearGenomeView/components/ZoomTransform.js +37 -0
- package/esm/LinearGenomeView/components/defaultMotifs.d.ts +1 -0
- package/esm/LinearGenomeView/components/defaultMotifs.js +22 -0
- package/esm/LinearGenomeView/components/fetchSequence.d.ts +7 -8
- package/esm/LinearGenomeView/components/fetchSequence.js +17 -9
- package/esm/LinearGenomeView/components/recentLocationsMenu.d.ts +15 -0
- package/esm/LinearGenomeView/components/recentLocationsMenu.js +36 -0
- package/esm/LinearGenomeView/components/searchModes.d.ts +13 -0
- package/esm/LinearGenomeView/components/searchModes.js +22 -0
- package/esm/LinearGenomeView/components/trackLabelMenuItems.d.ts +7 -0
- package/esm/LinearGenomeView/components/trackLabelMenuItems.js +67 -0
- package/esm/LinearGenomeView/components/useRangeSelect.d.ts +11 -66
- package/esm/LinearGenomeView/components/useRangeSelect.js +82 -91
- package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +26 -0
- package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +58 -0
- package/esm/LinearGenomeView/components/useSideScroll.d.ts +1 -1
- package/esm/LinearGenomeView/components/useSideScroll.js +87 -19
- package/esm/LinearGenomeView/components/util.d.ts +20 -6
- package/esm/LinearGenomeView/components/util.js +27 -6
- package/esm/LinearGenomeView/consts.d.ts +7 -2
- package/esm/LinearGenomeView/consts.js +18 -2
- package/esm/LinearGenomeView/flyTo.d.ts +38 -0
- package/esm/LinearGenomeView/flyTo.js +135 -0
- package/esm/LinearGenomeView/headerFit.d.ts +27 -0
- package/esm/LinearGenomeView/headerFit.js +59 -0
- package/esm/LinearGenomeView/index.d.ts +32 -2
- package/esm/LinearGenomeView/index.js +16 -6
- package/esm/LinearGenomeView/initKeys.d.ts +12 -0
- package/esm/LinearGenomeView/initKeys.js +68 -0
- package/esm/LinearGenomeView/keyboardHandler.d.ts +7 -0
- package/esm/LinearGenomeView/keyboardHandler.js +10 -0
- package/esm/LinearGenomeView/launchKeys.d.ts +2 -0
- package/esm/LinearGenomeView/launchKeys.js +23 -0
- package/esm/LinearGenomeView/lazyDialogs.d.ts +7 -11
- package/esm/LinearGenomeView/lazyDialogs.js +3 -3
- package/esm/LinearGenomeView/linkedViewSync.d.ts +20 -0
- package/esm/LinearGenomeView/linkedViewSync.js +58 -0
- package/esm/LinearGenomeView/menuItems.d.ts +27 -2
- package/esm/LinearGenomeView/menuItems.js +137 -101
- package/esm/LinearGenomeView/model.d.ts +3238 -136
- package/esm/LinearGenomeView/model.js +2425 -528
- package/esm/LinearGenomeView/sharedScaleContainer.d.ts +18 -0
- package/esm/LinearGenomeView/sharedScaleContainer.js +17 -0
- package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +35 -0
- package/esm/LinearGenomeView/showRegionsWithUndo.js +44 -0
- package/esm/LinearGenomeView/stickyChrome.d.ts +19 -0
- package/esm/LinearGenomeView/stickyChrome.js +30 -0
- package/esm/LinearGenomeView/svgcomponents/SVGGridlines.d.ts +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +15 -16
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +2 -3
- package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +45 -33
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +5 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +26 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +5 -0
- package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +13 -0
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +1 -3
- package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +77 -41
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +23 -3
- package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.d.ts +8 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +37 -0
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +3 -3
- package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +64 -36
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +1 -1
- package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +7 -5
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +5 -3
- package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +43 -7
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +8 -14
- package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +16 -21
- package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +18 -0
- package/esm/LinearGenomeView/svgcomponents/SVGView.js +13 -0
- package/esm/LinearGenomeView/svgcomponents/figureContract.d.ts +45 -0
- package/esm/LinearGenomeView/svgcomponents/figureContract.js +130 -0
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +76 -0
- package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +66 -0
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.d.ts +70 -0
- package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +263 -0
- package/esm/LinearGenomeView/svgcomponents/util.d.ts +92 -5
- package/esm/LinearGenomeView/svgcomponents/util.js +236 -3
- package/esm/LinearGenomeView/types.d.ts +17 -31
- package/esm/LinearGenomeView/types.js +1 -0
- package/esm/LinearGenomeView/util.d.ts +332 -12
- package/esm/LinearGenomeView/util.js +606 -62
- package/esm/MultiLevelRubberband/MultiLevelRubberband.d.ts +6 -0
- package/esm/MultiLevelRubberband/MultiLevelRubberband.js +37 -0
- package/esm/MultiLevelRubberband/VerticalGuide.d.ts +6 -0
- package/esm/MultiLevelRubberband/VerticalGuide.js +21 -0
- package/esm/MultiLevelRubberband/index.d.ts +2 -0
- package/esm/MultiLevelRubberband/index.js +1 -0
- package/esm/MultiLevelRubberband/types.d.ts +6 -0
- package/esm/MultiLevelRubberband/useRangeSelect.d.ts +24 -0
- package/esm/MultiLevelRubberband/useRangeSelect.js +136 -0
- package/esm/displayKitTests/perRegionTestEnv.d.ts +1286 -0
- package/esm/displayKitTests/perRegionTestEnv.js +138 -0
- package/esm/index.d.ts +122 -1235
- package/esm/index.js +101 -24
- package/esm/lazyPluginExports.d.ts +23 -0
- package/esm/lazyPluginExports.js +36 -0
- package/esm/searchUtils.d.ts +55 -11
- package/esm/searchUtils.js +342 -45
- package/esm/shared/RubberbandSpan.d.ts +15 -0
- package/esm/shared/RubberbandSpan.js +33 -0
- package/esm/shared/coordLabels.d.ts +40 -0
- package/esm/shared/coordLabels.js +119 -0
- package/package.json +18 -19
- package/esm/BaseLinearDisplay/SVGLegend.d.ts +0 -6
- package/esm/BaseLinearDisplay/SVGLegend.js +0 -17
- package/esm/BaseLinearDisplay/calculateSvgLegendWidth.d.ts +0 -2
- package/esm/BaseLinearDisplay/calculateSvgLegendWidth.js +0 -11
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +0 -8
- package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +0 -53
- package/esm/BaseLinearDisplay/components/Block.d.ts +0 -14
- package/esm/BaseLinearDisplay/components/Block.js +0 -45
- package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +0 -7
- package/esm/BaseLinearDisplay/components/BlockErrorMessage.js +0 -22
- package/esm/BaseLinearDisplay/components/BlockMsg.d.ts +0 -6
- package/esm/BaseLinearDisplay/components/BlockMsg.js +0 -26
- package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.d.ts +0 -9
- package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.js +0 -42
- package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.d.ts +0 -11
- package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.js +0 -40
- package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.d.ts +0 -19
- package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.js +0 -45
- package/esm/BaseLinearDisplay/components/FloatingLabels.d.ts +0 -5
- package/esm/BaseLinearDisplay/components/FloatingLabels.js +0 -75
- package/esm/BaseLinearDisplay/components/FloatingLegend.d.ts +0 -8
- package/esm/BaseLinearDisplay/components/FloatingLegend.js +0 -43
- package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +0 -5
- package/esm/BaseLinearDisplay/components/LinearBlocks.js +0 -23
- package/esm/BaseLinearDisplay/components/LoadingOverlay.d.ts +0 -5
- package/esm/BaseLinearDisplay/components/LoadingOverlay.js +0 -49
- package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.d.ts +0 -4
- package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.js +0 -26
- package/esm/BaseLinearDisplay/components/MenuPage.d.ts +0 -8
- package/esm/BaseLinearDisplay/components/MenuPage.js +0 -24
- package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.d.ts +0 -21
- package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.js +0 -52
- package/esm/BaseLinearDisplay/components/RenderedBlocks.d.ts +0 -12
- package/esm/BaseLinearDisplay/components/RenderedBlocks.js +0 -22
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +0 -12
- package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +0 -18
- package/esm/BaseLinearDisplay/components/TooLargeMessage.d.ts +0 -10
- package/esm/BaseLinearDisplay/components/TooLargeMessage.js +0 -20
- package/esm/BaseLinearDisplay/components/Tooltip.d.ts +0 -13
- package/esm/BaseLinearDisplay/components/Tooltip.js +0 -22
- package/esm/BaseLinearDisplay/components/types.d.ts +0 -1
- package/esm/BaseLinearDisplay/components/util.d.ts +0 -21
- package/esm/BaseLinearDisplay/components/util.js +0 -107
- package/esm/BaseLinearDisplay/index.d.ts +0 -17
- package/esm/BaseLinearDisplay/index.js +0 -13
- package/esm/BaseLinearDisplay/model.d.ts +0 -1197
- package/esm/BaseLinearDisplay/model.js +0 -432
- package/esm/BaseLinearDisplay/models/FeatureDensityMixin.d.ts +0 -32
- package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +0 -113
- package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.d.ts +0 -26
- package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.js +0 -57
- package/esm/BaseLinearDisplay/models/SvgFloatingLabels.d.ts +0 -8
- package/esm/BaseLinearDisplay/models/SvgFloatingLabels.js +0 -19
- package/esm/BaseLinearDisplay/models/TrackHeightMixin.d.ts +0 -11
- package/esm/BaseLinearDisplay/models/TrackHeightMixin.js +0 -31
- package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.d.ts +0 -2
- package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.js +0 -29
- package/esm/BaseLinearDisplay/models/configSchema.d.ts +0 -29
- package/esm/BaseLinearDisplay/models/configSchema.js +0 -33
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +0 -98
- package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -242
- package/esm/BaseLinearDisplay/models/util.d.ts +0 -9
- package/esm/BaseLinearDisplay/models/util.js +0 -43
- package/esm/BaseLinearDisplay/renderSvg.d.ts +0 -3
- package/esm/BaseLinearDisplay/renderSvg.js +0 -63
- package/esm/BaseLinearDisplay/types.d.ts +0 -43
- package/esm/BaseLinearDisplay/types.js +0 -3
- package/esm/BaseLinearDisplay/util.d.ts +0 -16
- package/esm/BaseLinearDisplay/util.js +0 -71
- package/esm/BasicTrack/configSchema.d.ts +0 -85
- package/esm/BasicTrack/configSchema.js +0 -8
- package/esm/BasicTrack/index.d.ts +0 -2
- package/esm/BasicTrack/index.js +0 -12
- package/esm/LinearBareDisplay/configSchema.d.ts +0 -32
- package/esm/LinearBareDisplay/configSchema.js +0 -11
- package/esm/LinearBareDisplay/index.d.ts +0 -4
- package/esm/LinearBareDisplay/index.js +0 -20
- package/esm/LinearBareDisplay/model.d.ts +0 -1196
- package/esm/LinearBareDisplay/model.js +0 -32
- package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.d.ts +0 -5
- package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.js +0 -9
- package/esm/LinearBasicDisplay/configSchema.d.ts +0 -32
- package/esm/LinearBasicDisplay/configSchema.js +0 -11
- package/esm/LinearBasicDisplay/index.d.ts +0 -4
- package/esm/LinearBasicDisplay/index.js +0 -20
- package/esm/LinearBasicDisplay/model.d.ts +0 -1391
- package/esm/LinearBasicDisplay/model.js +0 -158
- package/esm/LinearFeatureDisplay/components/AddFiltersDialog.d.ts +0 -9
- package/esm/LinearFeatureDisplay/components/AddFiltersDialog.js +0 -58
- package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.d.ts +0 -8
- package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.js +0 -26
- package/esm/LinearFeatureDisplay/configSchema.d.ts +0 -32
- package/esm/LinearFeatureDisplay/configSchema.js +0 -11
- package/esm/LinearFeatureDisplay/index.d.ts +0 -3
- package/esm/LinearFeatureDisplay/index.js +0 -2
- package/esm/LinearFeatureDisplay/model.d.ts +0 -1443
- package/esm/LinearFeatureDisplay/model.js +0 -305
- package/esm/LinearGenomeView/SVGErrorBox.d.ts +0 -5
- package/esm/LinearGenomeView/SVGErrorBox.js +0 -4
- package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +0 -11
- package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +0 -27
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.d.ts +0 -5
- package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +0 -13
- package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.d.ts +0 -3
- package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +0 -17
- package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.d.ts +0 -3
- package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +0 -8
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +0 -16
- package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +0 -101
- package/esm/LinearGenomeView/components/RefNameAutocomplete/util.d.ts +0 -10
- package/esm/LinearGenomeView/components/RefNameAutocomplete/util.js +0 -45
- package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +0 -15
- package/esm/LinearGenomeView/components/RubberbandSpan.js +0 -32
- package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +0 -5
- package/esm/LinearGenomeView/components/RubberbandTooltip.js +0 -17
- package/esm/LinearGenomeView/components/TrackLabelContainer.d.ts +0 -8
- package/esm/LinearGenomeView/components/TrackLabelContainer.js +0 -25
- package/esm/LinearGenomeView/components/useWheelScroll.d.ts +0 -7
- package/esm/LinearGenomeView/components/useWheelScroll.js +0 -69
- package/esm/LinearGenomeView/svgExportUtil.d.ts +0 -9
- package/esm/LinearGenomeView/svgExportUtil.js +0 -6
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +0 -5
- package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +0 -7
- /package/esm/{BaseLinearDisplay/components → MultiLevelRubberband}/types.js +0 -0
|
@@ -1,144 +1,273 @@
|
|
|
1
|
-
import { getSession, localStorageSetItem,
|
|
1
|
+
import { getSession, isSessionModelWithWidgets, localStorageSetItem, resolveNamedRegions, } from '@jbrowse/core/util';
|
|
2
|
+
import { coerceHighlight } from '@jbrowse/core/util/highlights';
|
|
3
|
+
import { installInitAutorun } from '@jbrowse/core/util/installInitAutorun';
|
|
4
|
+
import { normalizeTrackInit } from '@jbrowse/core/util/tracks';
|
|
2
5
|
import { addDisposer } from '@jbrowse/mobx-state-tree';
|
|
3
6
|
import { autorun, when } from 'mobx';
|
|
4
|
-
|
|
7
|
+
import { SearchResultsNotFoundError } from '../searchUtils.js';
|
|
8
|
+
// `init` is a frozen blob that often comes from hand-authored JSON, where a
|
|
9
|
+
// lone entry gets written bare (`tracks: 'genes'`). A string is iterable, so
|
|
10
|
+
// looping over it directly walked its characters — one track opened per letter.
|
|
11
|
+
function asArray(arg) {
|
|
12
|
+
return arg === undefined ? [] : Array.isArray(arg) ? arg : [arg];
|
|
13
|
+
}
|
|
14
|
+
// Activate tracklist first so the drawer opens before we navigate, so
|
|
15
|
+
// volatileWidth accounts for the drawer; otherwise navigation computes the
|
|
16
|
+
// region at full width and the drawer then obscures part of it. Opening the
|
|
17
|
+
// drawer shrinks the view, which the ResizeObserver reports as a volatileWidth
|
|
18
|
+
// change — but only if the drawer wasn't already taking that width. So wait for
|
|
19
|
+
// the change only when activating it actually opens the column.
|
|
20
|
+
async function openTracklist(self, session, superseded) {
|
|
21
|
+
// activateTrackSelector throws without widget support, which would abort the
|
|
22
|
+
// rest of init (navigation included) over an optional extra
|
|
23
|
+
if (isSessionModelWithWidgets(session)) {
|
|
24
|
+
// `poppedOut` — the visible widget rendered in a modal, leaving the drawer
|
|
25
|
+
// column free — lives on SessionWithDrawerWidgets, whose type guard is
|
|
26
|
+
// product-core's, so duck-type it here rather than take an upward
|
|
27
|
+
// dependency. A session without the key has no modal to pop out into, so
|
|
28
|
+
// false is the right answer for it.
|
|
29
|
+
const poppedOut = 'poppedOut' in session && session.poppedOut === true;
|
|
30
|
+
// the same line App.tsx draws to decide whether to render the drawer column
|
|
31
|
+
// at all. A *minimized* drawer still holds a visibleWidget while taking no
|
|
32
|
+
// width, and showWidget un-minimizes it (product-core's DrawerWidgets), so
|
|
33
|
+
// `!!visibleWidget` alone reads "already open", skips the wait below, and
|
|
34
|
+
// hands navigation the pre-drawer width — the exact thing this is here to
|
|
35
|
+
// prevent.
|
|
36
|
+
const drawerWasOpen = !!session.visibleWidget && !session.minimized && !poppedOut;
|
|
37
|
+
const widthBefore = self.volatileWidth;
|
|
38
|
+
self.activateTrackSelector();
|
|
39
|
+
// a width change is only coming if the drawer is about to start taking
|
|
40
|
+
// space; popped out it never does, so don't sit out the timeout for it
|
|
41
|
+
if (!drawerWasOpen && !poppedOut) {
|
|
42
|
+
// Bounded so init can't wedge here if the drawer doesn't shrink the view
|
|
43
|
+
// (e.g. embedded or modal-drawer layouts, where no width change is
|
|
44
|
+
// coming), and superseded so a re-launch landing mid-wait isn't held
|
|
45
|
+
// behind an init that no longer matters
|
|
46
|
+
await when(() => self.volatileWidth !== widthBefore || superseded(), {
|
|
47
|
+
timeout: 1000,
|
|
48
|
+
}).catch(() => { });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
session.notify('init.tracklist was ignored: this application has no track selector drawer', 'warning');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Restrict a whole-genome view to a named subset of the assembly's regions, in
|
|
56
|
+
// the requested order. Entries may be globs (`*_hap1`) — see selectNamedRegions,
|
|
57
|
+
// shared with the dotplot's per-axis `displayedRegionNames` so both views read
|
|
58
|
+
// the same name list the same way.
|
|
59
|
+
function showNamedRegions(self, session, assemblyName, names) {
|
|
60
|
+
const assembly = session.assemblyManager.get(assemblyName);
|
|
61
|
+
const all = assembly?.regions;
|
|
62
|
+
if (all) {
|
|
63
|
+
// resolveNamedRegions is what reports a list that matched nothing —
|
|
64
|
+
// otherwise a typo'd refName silently shows the whole genome and reads as
|
|
65
|
+
// displayedRegionNames being ignored. The FALLBACK stays here because it is
|
|
66
|
+
// this view's alone: nothing shown yet means show the whole genome rather
|
|
67
|
+
// than an empty view, but already navigated (URL params layered onto a
|
|
68
|
+
// defaultSession) means keep what's there, since a typo shouldn't discard
|
|
69
|
+
// the session's own navigation.
|
|
70
|
+
const regions = resolveNamedRegions({
|
|
71
|
+
regions: all,
|
|
72
|
+
names,
|
|
73
|
+
assemblyName,
|
|
74
|
+
getCanonicalRefName: assembly.getCanonicalRefName2,
|
|
75
|
+
allRefNames: assembly.allRefNames,
|
|
76
|
+
notify: message => {
|
|
77
|
+
session.notify(message, 'warning');
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
if (regions) {
|
|
81
|
+
// showRegions, not showAllRegionsInAssembly: `displayedRegionNames` is
|
|
82
|
+
// the spec naming what it wants shown, so it gets the width
|
|
83
|
+
self.showRegions(regions);
|
|
84
|
+
}
|
|
85
|
+
else if (!self.hasDisplayedRegions) {
|
|
86
|
+
// The fallback IS "show me everything", so it keeps the margin.
|
|
87
|
+
self.showAllRegionsInAssembly(assemblyName);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function navigateInit(self, session, init) {
|
|
5
92
|
try {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
93
|
+
if (init.loc) {
|
|
94
|
+
// navToLocString waits for the assembly itself, and this autorun only
|
|
95
|
+
// runs once `initialized` confirms init.assembly has loaded regions, so
|
|
96
|
+
// no explicit waitForAssembly is needed here
|
|
97
|
+
// a spec that listed its tracks gets those tracks; one that only named
|
|
98
|
+
// a gene gets the track the gene was found in, as the search box would
|
|
99
|
+
await self.navToLocString(init.loc, init.assembly, init.grow, {
|
|
100
|
+
showHitTrack: asArray(init.tracks).length === 0,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
else if (init.displayedRegionNames?.length) {
|
|
104
|
+
// an explicit region list is a navigation request just like `loc`, so it
|
|
105
|
+
// applies even when regions already exist (URL params layered onto a
|
|
106
|
+
// defaultSession that already navigated)
|
|
107
|
+
//
|
|
108
|
+
// `?.length`, not the bare key: an empty array is truthy, so a spec
|
|
109
|
+
// writing `displayedRegionNames: []` took this path with nothing to name
|
|
110
|
+
// and got told its list of no names had matched no regions. That is why
|
|
111
|
+
// LinearSyntenyView's doSubmit omits the key rather than passing [].
|
|
112
|
+
showNamedRegions(self, session, init.assembly, init.displayedRegionNames);
|
|
113
|
+
}
|
|
114
|
+
else if (!self.hasDisplayedRegions) {
|
|
115
|
+
// a highlight-only init (nothing to navigate to) must not clobber a
|
|
116
|
+
// defaultSession's existing navigation, so only auto-navigate when
|
|
117
|
+
// nothing is shown yet
|
|
118
|
+
self.showAllRegionsInAssembly(init.assembly);
|
|
119
|
+
}
|
|
10
120
|
}
|
|
11
|
-
catch {
|
|
12
|
-
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.error(init, e);
|
|
123
|
+
if (e instanceof SearchResultsNotFoundError) {
|
|
124
|
+
// a &loc= gene name that matched nothing is a soft miss, not an app error
|
|
125
|
+
session.notify(e.message, 'warning');
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
session.notifyError(`${e}`, e);
|
|
129
|
+
}
|
|
13
130
|
}
|
|
14
131
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
132
|
+
// launchTrack funnels through showTrackGeneric, which surfaces any failure
|
|
133
|
+
// (unresolved id, bad config, etc) as its own snackbar, and loads the picked
|
|
134
|
+
// display's state model first when it is registered lazily
|
|
135
|
+
async function showInitTracks(self, init) {
|
|
136
|
+
for (const t of asArray(init.tracks)) {
|
|
137
|
+
const { trackId, trackSnapshot, displaySnapshot } = normalizeTrackInit(t);
|
|
138
|
+
await self.launchTrack(trackId, trackSnapshot, displaySnapshot);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// backfill assemblyName on any session-authored highlights that omitted it so
|
|
142
|
+
// downstream code (bookmark widget grid, addBookmark, etc) doesn't have to keep
|
|
143
|
+
// falling back
|
|
144
|
+
function backfillHighlightAssemblies(self) {
|
|
145
|
+
const fallback = self.assemblyNames[0];
|
|
146
|
+
if (self.highlight.length && fallback) {
|
|
147
|
+
const normalized = self.highlight.map(h => h.assemblyName ? h : { ...h, assemblyName: fallback });
|
|
148
|
+
if (normalized.some((h, i) => h !== self.highlight[i])) {
|
|
149
|
+
self.setHighlight(normalized);
|
|
20
150
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
self.showAllRegionsInAssembly(init.assembly);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
catch (e) {
|
|
48
|
-
console.error(init, e);
|
|
49
|
-
session.notifyError(`${e}`, e);
|
|
50
|
-
}
|
|
51
|
-
if (init.tracks) {
|
|
52
|
-
const idsNotFound = [];
|
|
53
|
-
for (const t of init.tracks) {
|
|
54
|
-
try {
|
|
55
|
-
if (typeof t === 'string') {
|
|
56
|
-
self.showTrack(t);
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
self.showTrack(t.trackId, t.trackSnapshot ?? {}, t.displaySnapshot ?? {});
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch (e) {
|
|
63
|
-
const trackId = typeof t === 'string' ? t : t.trackId;
|
|
64
|
-
if (/Could not resolve identifier/.exec(`${e}`)) {
|
|
65
|
-
idsNotFound.push(trackId);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
throw e;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (idsNotFound.length) {
|
|
73
|
-
session.notifyError(`Could not resolve identifiers: ${idsNotFound.join(',')}`, new Error(`Could not resolve identifiers: ${idsNotFound.join(',')}`));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (init.nav !== undefined) {
|
|
77
|
-
self.setHideHeader(!init.nav);
|
|
78
|
-
}
|
|
79
|
-
if (self.highlight.length) {
|
|
80
|
-
const fallback = self.assemblyNames[0];
|
|
81
|
-
if (fallback) {
|
|
82
|
-
const normalized = self.highlight.map(h => h.assemblyName ? h : { ...h, assemblyName: fallback });
|
|
83
|
-
if (normalized.some((h, i) => h !== self.highlight[i])) {
|
|
84
|
-
self.setHighlight(normalized);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
if (init.highlight) {
|
|
89
|
-
for (const h of init.highlight) {
|
|
90
|
-
const json = h.trim().startsWith('{') && tryParseJson(h);
|
|
91
|
-
if (json &&
|
|
92
|
-
typeof json.refName === 'string' &&
|
|
93
|
-
typeof json.start === 'number' &&
|
|
94
|
-
typeof json.end === 'number') {
|
|
95
|
-
self.addToHighlights({
|
|
96
|
-
refName: json.refName,
|
|
97
|
-
start: json.start,
|
|
98
|
-
end: json.end,
|
|
99
|
-
assemblyName: typeof json.assemblyName === 'string'
|
|
100
|
-
? json.assemblyName
|
|
101
|
-
: init.assembly,
|
|
102
|
-
color: typeof json.color === 'string' ? json.color : undefined,
|
|
103
|
-
label: typeof json.label === 'string' ? json.label : undefined,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
const p = parseLocString(h, refName => assemblyManager.isValidRefName(refName, init.assembly));
|
|
108
|
-
const { start, end } = p;
|
|
109
|
-
if (start !== undefined && end !== undefined) {
|
|
110
|
-
self.addToHighlights({
|
|
111
|
-
...p,
|
|
112
|
-
start,
|
|
113
|
-
end,
|
|
114
|
-
assemblyName: init.assembly,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Apply an init blob's `highlight` entries to a view, coercing each locstring
|
|
155
|
+
* or wire-format object and reporting a bad one without taking out its
|
|
156
|
+
* siblings.
|
|
157
|
+
*
|
|
158
|
+
* Exported because a LinearSyntenyView row is a LinearGenomeView that does NOT
|
|
159
|
+
* go through this file's init autorun — the synteny view builds each row's
|
|
160
|
+
* snapshot and navigates it itself — so the row's own `highlight` had nowhere
|
|
161
|
+
* to be applied and was dropped in silence.
|
|
162
|
+
*/
|
|
163
|
+
export function applyInitHighlights(self, session, init) {
|
|
164
|
+
for (const h of asArray(init.highlight)) {
|
|
165
|
+
// parseLocString throws on an unknown refName or a malformed locstring, and
|
|
166
|
+
// one bad entry must take out neither its siblings nor the rest of init
|
|
167
|
+
try {
|
|
168
|
+
const highlight = coerceHighlight(h, init.assembly, refName => session.assemblyManager.isValidRefName(refName, init.assembly));
|
|
169
|
+
if (highlight) {
|
|
170
|
+
self.addToHighlights(highlight);
|
|
119
171
|
}
|
|
120
|
-
self.setInit(undefined);
|
|
121
172
|
}
|
|
122
|
-
|
|
173
|
+
catch (e) {
|
|
174
|
+
console.error(e);
|
|
175
|
+
session.notifyError(`Invalid init highlight ${JSON.stringify(h)}: ${e}`, e);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
123
178
|
}
|
|
124
|
-
|
|
179
|
+
async function applyInit(self, init, { superseded }) {
|
|
180
|
+
const session = getSession(self);
|
|
181
|
+
if (init.tracklist) {
|
|
182
|
+
await openTracklist(self, session, superseded);
|
|
183
|
+
}
|
|
184
|
+
// `superseded`, not a bare isAlive: it subsumes the liveness check (the view
|
|
185
|
+
// may have been removed while the drawer or the navigation resolved, and
|
|
186
|
+
// reading or mutating a detached node throws) and also covers the case
|
|
187
|
+
// isAlive misses — a newer setLaunch landed mid-apply, so the rest of *this*
|
|
188
|
+
// blob is stale. Finishing it anyway appends its tracks and highlights under
|
|
189
|
+
// the one that replaced it, and addToHighlights pushes, so a re-launch of the
|
|
190
|
+
// same spec (a StrictMode remount) doubles the bands. The drain loop applies
|
|
191
|
+
// the newer init next either way.
|
|
192
|
+
//
|
|
193
|
+
// Checked after each await rather than once at the top, and as early returns
|
|
194
|
+
// rather than nesting, so a step added later takes a guard beside it instead
|
|
195
|
+
// of another level of indent.
|
|
196
|
+
if (superseded()) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
await navigateInit(self, session, init);
|
|
200
|
+
if (superseded()) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
await showInitTracks(self, init);
|
|
204
|
+
if (superseded()) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (init.nav !== undefined) {
|
|
208
|
+
self.setHideHeader(!init.nav);
|
|
209
|
+
}
|
|
210
|
+
backfillHighlightAssemblies(self);
|
|
211
|
+
applyInitHighlights(self, session, init);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Autorun that handles the init state - navigating to initial location,
|
|
215
|
+
* showing tracks, etc.
|
|
216
|
+
*/
|
|
217
|
+
export function setupInitAutorun(self) {
|
|
218
|
+
installInitAutorun(self, {
|
|
219
|
+
name: 'LGVInit',
|
|
220
|
+
// `init` is what makes hasSomethingToShow / awaitingInitNavigation report
|
|
221
|
+
// "loading"
|
|
222
|
+
// until navigation populates displayedRegions, so the alternative gate
|
|
223
|
+
// (clearing `init` up front, the way SpreadsheetView does) would flash the
|
|
224
|
+
// import form mid-load.
|
|
225
|
+
ready: () => self.initialized,
|
|
226
|
+
// No pre-materialization phase to protect: the view is its own single row,
|
|
227
|
+
// and `error` already derives a failed init assembly declaratively (via
|
|
228
|
+
// initAssembly), so anything thrown out of applyInit is a failure of a
|
|
229
|
+
// step, not of the view coming up.
|
|
230
|
+
materialized: () => true,
|
|
231
|
+
apply: (init, ctx) => applyInit(self, init, ctx),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Autorun that updates coarse dynamic blocks with a delay
|
|
236
|
+
*/
|
|
237
|
+
function setupCoarseDynamicBlocksAutorun(self) {
|
|
125
238
|
addDisposer(self, autorun(function coarseDynamicBlocksAutorun() {
|
|
126
239
|
if (self.initialized) {
|
|
127
|
-
self.setCoarseDynamicBlocks(self.dynamicBlocks);
|
|
240
|
+
self.setCoarseDynamicBlocks(self.dynamicBlocks, self.bpPerPx);
|
|
128
241
|
}
|
|
129
|
-
}, {
|
|
242
|
+
}, {
|
|
243
|
+
delay: 500,
|
|
244
|
+
name: 'LGVCoarseDynamicBlocks',
|
|
245
|
+
}));
|
|
130
246
|
}
|
|
131
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Autorun that syncs view settings to localStorage
|
|
249
|
+
*/
|
|
250
|
+
function setupLocalStorageAutorun(self) {
|
|
132
251
|
addDisposer(self, autorun(function localStorageAutorun() {
|
|
133
252
|
const s = (s) => JSON.stringify(s);
|
|
134
|
-
const {
|
|
135
|
-
localStorageSetItem('lgv-showCytobands', s(
|
|
253
|
+
const { showCytobands, showCenterLine, colorByCDS, showAminoAcids, showTrackOutlines, trackLabels, } = self;
|
|
254
|
+
localStorageSetItem('lgv-showCytobands', s(showCytobands));
|
|
136
255
|
localStorageSetItem('lgv-showCenterLine', s(showCenterLine));
|
|
137
256
|
localStorageSetItem('lgv-colorByCDS', s(colorByCDS));
|
|
257
|
+
localStorageSetItem('lgv-showAminoAcids', s(showAminoAcids));
|
|
138
258
|
localStorageSetItem('lgv-showTrackOutlines', s(showTrackOutlines));
|
|
139
|
-
|
|
140
|
-
|
|
259
|
+
// skip writing the empty default — otherwise reads later round-trip to
|
|
260
|
+
// '' instead of null, hiding the config-fallback path
|
|
261
|
+
if (trackLabels) {
|
|
262
|
+
localStorageSetItem('lgv-trackLabels', trackLabels);
|
|
263
|
+
}
|
|
264
|
+
}, {
|
|
265
|
+
name: 'LGVLocalStorage',
|
|
266
|
+
}));
|
|
141
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Sets up all afterAttach autoruns for the LinearGenomeView
|
|
270
|
+
*/
|
|
142
271
|
export function doAfterAttach(self) {
|
|
143
272
|
setupInitAutorun(self);
|
|
144
273
|
setupCoarseDynamicBlocksAutorun(self);
|
|
@@ -2,5 +2,5 @@ import type { LinearGenomeViewModel } from '../index.ts';
|
|
|
2
2
|
type LGV = LinearGenomeViewModel;
|
|
3
3
|
declare const CenterLine: ({ model }: {
|
|
4
4
|
model: LGV;
|
|
5
|
-
}) => import("react
|
|
5
|
+
}) => import("react").JSX.Element | null;
|
|
6
6
|
export default CenterLine;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useRef } from 'react';
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
2
|
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
3
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
4
|
+
import { IconButton, Tooltip } from '@mui/material';
|
|
4
5
|
import { observer } from 'mobx-react';
|
|
5
6
|
const useStyles = makeStyles()(theme => ({
|
|
6
7
|
centerLineContainer: {
|
|
7
8
|
background: 'transparent',
|
|
8
9
|
height: '100%',
|
|
9
|
-
zIndex: 4,
|
|
10
|
+
zIndex: 4, // above the track but under menu
|
|
10
11
|
position: 'absolute',
|
|
11
12
|
left: 0,
|
|
12
13
|
border: `1px ${theme.palette.action.active} dashed`,
|
|
@@ -17,22 +18,30 @@ const useStyles = makeStyles()(theme => ({
|
|
|
17
18
|
centerLineText: {
|
|
18
19
|
position: 'absolute',
|
|
19
20
|
left: 0,
|
|
20
|
-
|
|
21
|
+
display: 'flex',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
gap: 2,
|
|
21
24
|
whiteSpace: 'nowrap',
|
|
22
25
|
fontWeight: 'bold',
|
|
23
26
|
},
|
|
27
|
+
dismiss: {
|
|
28
|
+
// re-enable clicks disabled on the pointer-events:none container
|
|
29
|
+
pointerEvents: 'auto',
|
|
30
|
+
padding: 2,
|
|
31
|
+
},
|
|
24
32
|
}));
|
|
25
33
|
const CenterLine = observer(function CenterLine({ model }) {
|
|
26
34
|
const { bpPerPx, centerLineInfo, trackHeights, tracks, width } = model;
|
|
27
|
-
const ref = useRef(null);
|
|
28
35
|
const { classes } = useStyles();
|
|
29
36
|
const startingPosition = width / 2;
|
|
30
|
-
return tracks.length ? (_jsx("div", { "data-testid": "centerline_container", className: classes.centerLineContainer, role: "presentation",
|
|
37
|
+
return tracks.length ? (_jsx("div", { "data-testid": "centerline_container", className: classes.centerLineContainer, role: "presentation", style: {
|
|
31
38
|
transform: `translateX(${startingPosition}px)`,
|
|
32
39
|
width: Math.max(1 / bpPerPx, 1),
|
|
33
40
|
}, children: centerLineInfo && (_jsxs("div", { "data-testid": "centerline_text", className: classes.centerLineText, role: "presentation", style: {
|
|
34
41
|
transform: `translateX(${Math.max(1 / bpPerPx, 1) + 5}px)`,
|
|
35
42
|
top: trackHeights,
|
|
36
|
-
}, children: [centerLineInfo.refName, ":", ' ', Math.max(Math.round(centerLineInfo.offset) + 1, 0)
|
|
43
|
+
}, children: [centerLineInfo.refName, ":", ' ', Math.max(Math.round(centerLineInfo.offset) + 1, 0).toLocaleString('en-US'), _jsx(Tooltip, { title: "Hide center line", children: _jsx(IconButton, { className: classes.dismiss, onClick: () => {
|
|
44
|
+
model.setShowCenterLine(false);
|
|
45
|
+
}, children: _jsx(CloseIcon, { fontSize: "inherit" }) }) })] })) })) : null;
|
|
37
46
|
});
|
|
38
47
|
export default CenterLine;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { LinearGenomeViewModel } from '../model.ts';
|
|
2
|
+
import type { HoverHighlightPosition } from './HoverPositionHighlight.tsx';
|
|
3
|
+
declare const ConnectedHoverHighlight: ({ model, getPosition, }: {
|
|
4
|
+
model: LinearGenomeViewModel;
|
|
5
|
+
getPosition: (widget: unknown, viewId: string) => HoverHighlightPosition | undefined;
|
|
6
|
+
}) => import("react").JSX.Element | null;
|
|
7
|
+
export default ConnectedHoverHighlight;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getSession } from '@jbrowse/core/util';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
4
|
+
import HoverPositionHighlight from './HoverPositionHighlight.js';
|
|
5
|
+
// Draws a crosshair for every session widget "connected" to this view that is
|
|
6
|
+
// currently publishing a hover position. Each cross-widget hover overlay (the
|
|
7
|
+
// feature-detail sequence panel, the MAF sequence widget) supplies only its own
|
|
8
|
+
// `getPosition`, which narrows an arbitrary widget to its model and returns the
|
|
9
|
+
// hovered interval or undefined; the widget iteration and drawing are shared.
|
|
10
|
+
const ConnectedHoverHighlight = observer(function ConnectedHoverHighlight({ model, getPosition, }) {
|
|
11
|
+
const session = getSession(model);
|
|
12
|
+
const widgets = 'widgets' in session ? session.widgets : undefined;
|
|
13
|
+
return !widgets ? null : (_jsx(_Fragment, { children: [...widgets].flatMap(([id, widget]) => {
|
|
14
|
+
const position = getPosition(widget, model.id);
|
|
15
|
+
return position
|
|
16
|
+
? [
|
|
17
|
+
_jsx(HoverPositionHighlight, { model: model, position: position }, `hover-${id}`),
|
|
18
|
+
]
|
|
19
|
+
: [];
|
|
20
|
+
}) }));
|
|
21
|
+
});
|
|
22
|
+
export default ConnectedHoverHighlight;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { LabeledCheckbox } from '@jbrowse/core/ui';
|
|
4
|
+
import { IUPAC_MOTIF_REGEX } from '@jbrowse/core/util';
|
|
5
|
+
import { makeStyles } from '@jbrowse/core/util/tss-react';
|
|
6
|
+
import { MenuItem, TextField, ToggleButton, ToggleButtonGroup, Typography, } from '@mui/material';
|
|
7
|
+
import { observer } from 'mobx-react';
|
|
8
|
+
import SearchPanelForm from './SearchPanelForm.js';
|
|
9
|
+
import StrandCheckboxes from './StrandCheckboxes.js';
|
|
10
|
+
import { addReferenceScanTrack } from './searchModes.js';
|
|
11
|
+
const useStyles = makeStyles()({
|
|
12
|
+
row: {
|
|
13
|
+
display: 'flex',
|
|
14
|
+
gap: 12,
|
|
15
|
+
'& > *': {
|
|
16
|
+
flex: 1,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
toggleRow: {
|
|
20
|
+
display: 'flex',
|
|
21
|
+
alignItems: 'center',
|
|
22
|
+
gap: 12,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
// PAM 3' of the protospacer for Cas9-type enzymes, 5' for Cas12a. The two cut
|
|
26
|
+
// offsets are bp from the PAM-proximal end of the protospacer to each strand's
|
|
27
|
+
// cut: equal for a blunt cutter, staggered for Cas12a, which leaves a 5-nt 5'
|
|
28
|
+
// overhang.
|
|
29
|
+
const ENZYME_PRESETS = {
|
|
30
|
+
SpCas9: {
|
|
31
|
+
pam: 'NGG',
|
|
32
|
+
guideLength: 20,
|
|
33
|
+
pamLocation: '3prime',
|
|
34
|
+
cutOffset: 3,
|
|
35
|
+
cutOffsetBottom: 3,
|
|
36
|
+
},
|
|
37
|
+
SaCas9: {
|
|
38
|
+
pam: 'NNGRRT',
|
|
39
|
+
guideLength: 21,
|
|
40
|
+
pamLocation: '3prime',
|
|
41
|
+
cutOffset: 3,
|
|
42
|
+
cutOffsetBottom: 3,
|
|
43
|
+
},
|
|
44
|
+
'Cas12a (Cpf1)': {
|
|
45
|
+
pam: 'TTTV',
|
|
46
|
+
guideLength: 23,
|
|
47
|
+
pamLocation: '5prime',
|
|
48
|
+
cutOffset: 18,
|
|
49
|
+
cutOffsetBottom: 23,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
// The one filter preset the panel offers. The adapter's slots are a free GC
|
|
53
|
+
// range plus a poly-T flag; these are the conventional cutoffs, named in the
|
|
54
|
+
// checkbox label so the numbers aren't hidden behind a word like "usable".
|
|
55
|
+
const GC_FILTER = { minGcPercent: 40, maxGcPercent: 60 };
|
|
56
|
+
const NO_FILTER = { minGcPercent: 0, maxGcPercent: 100 };
|
|
57
|
+
const DEFAULT_ENZYME = 'SpCas9';
|
|
58
|
+
const DEFAULT_PRESET = ENZYME_PRESETS[DEFAULT_ENZYME];
|
|
59
|
+
const toBpCount = (str) => (str.trim() ? Number(str) : Number.NaN);
|
|
60
|
+
const CrisprGuidePanel = observer(function CrisprGuidePanel({ model, handleClose, }) {
|
|
61
|
+
const { classes } = useStyles();
|
|
62
|
+
const [enzyme, setEnzyme] = useState(DEFAULT_ENZYME);
|
|
63
|
+
const [pam, setPam] = useState(DEFAULT_PRESET.pam);
|
|
64
|
+
const [pamLocation, setPamLocation] = useState(DEFAULT_PRESET.pamLocation);
|
|
65
|
+
const [guideLengthStr, setGuideLengthStr] = useState(String(DEFAULT_PRESET.guideLength));
|
|
66
|
+
const [cutOffsetStr, setCutOffsetStr] = useState(String(DEFAULT_PRESET.cutOffset));
|
|
67
|
+
// presets carry this; Custom is treated as a blunt cutter, so the panel does
|
|
68
|
+
// not grow a second offset field for a case config can express directly
|
|
69
|
+
const [cutOffsetBottom, setCutOffsetBottom] = useState(DEFAULT_PRESET.cutOffsetBottom);
|
|
70
|
+
const [searchForward, setSearchForward] = useState(true);
|
|
71
|
+
const [searchReverse, setSearchReverse] = useState(true);
|
|
72
|
+
const [filterQuality, setFilterQuality] = useState(false);
|
|
73
|
+
// `Number('')` is 0, so an emptied field would otherwise read as a valid zero
|
|
74
|
+
const guideLength = toBpCount(guideLengthStr);
|
|
75
|
+
const cutOffset = toBpCount(cutOffsetStr);
|
|
76
|
+
// both are bp counts used for fixed-length string slicing, so a fractional
|
|
77
|
+
// value would silently truncate and skew the placement
|
|
78
|
+
const guideLengthValid = Number.isInteger(guideLength) && guideLength > 0;
|
|
79
|
+
// a cut beyond either end of the protospacer draws its tick outside the glyph
|
|
80
|
+
// that is supposed to carry it, and outside the box that can be clicked
|
|
81
|
+
const cutOffsetValid = Number.isInteger(cutOffset) && cutOffset >= 0 && cutOffset <= guideLength;
|
|
82
|
+
// each PAM position must be a single IUPAC code (one base); other characters
|
|
83
|
+
// would leak into the match regex and break the fixed-length placement
|
|
84
|
+
const pamValid = IUPAC_MOTIF_REGEX.test(pam);
|
|
85
|
+
const canSubmit = pamValid &&
|
|
86
|
+
guideLengthValid &&
|
|
87
|
+
cutOffsetValid &&
|
|
88
|
+
(searchForward || searchReverse);
|
|
89
|
+
// a staggered cutter shows both offsets, e.g. "cut 18/23 bp from PAM"
|
|
90
|
+
const cutSummary = cutOffsetBottom === cutOffset
|
|
91
|
+
? cutOffset
|
|
92
|
+
: `${cutOffset}/${cutOffsetBottom}`;
|
|
93
|
+
const presetSummary = ENZYME_PRESETS[enzyme]
|
|
94
|
+
? `PAM ${pam} · ${guideLength} bp guide · cut ${cutSummary} bp from PAM`
|
|
95
|
+
: 'Set a custom PAM and geometry below';
|
|
96
|
+
function applyPreset(name) {
|
|
97
|
+
setEnzyme(name);
|
|
98
|
+
const preset = ENZYME_PRESETS[name];
|
|
99
|
+
if (preset) {
|
|
100
|
+
setPam(preset.pam);
|
|
101
|
+
setPamLocation(preset.pamLocation);
|
|
102
|
+
setGuideLengthStr(String(preset.guideLength));
|
|
103
|
+
setCutOffsetStr(String(preset.cutOffset));
|
|
104
|
+
setCutOffsetBottom(preset.cutOffsetBottom);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function handleSubmit() {
|
|
108
|
+
addReferenceScanTrack(model, {
|
|
109
|
+
trackId: `crispr_guides_${Date.now()}`,
|
|
110
|
+
name: enzyme === 'Custom'
|
|
111
|
+
? `CRISPR guides ${pam}`
|
|
112
|
+
: `CRISPR guides ${enzyme} (${pam})`,
|
|
113
|
+
adapter: {
|
|
114
|
+
type: 'CrisprGuideAdapter',
|
|
115
|
+
pam,
|
|
116
|
+
guideLength,
|
|
117
|
+
pamLocation,
|
|
118
|
+
cutOffset,
|
|
119
|
+
cutOffsetBottom: enzyme === 'Custom' ? cutOffset : cutOffsetBottom,
|
|
120
|
+
searchForward,
|
|
121
|
+
searchReverse,
|
|
122
|
+
excludePolyT: filterQuality,
|
|
123
|
+
...(filterQuality ? GC_FILTER : NO_FILTER),
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
handleClose();
|
|
127
|
+
}
|
|
128
|
+
return (_jsxs(SearchPanelForm, { onSubmit: handleSubmit, handleClose: handleClose, submitDisabled: !canSubmit, children: [_jsx(TextField, { select: true, variant: "outlined", size: "small", label: "Enzyme", value: enzyme, helperText: presetSummary, onChange: event => {
|
|
129
|
+
applyPreset(event.target.value);
|
|
130
|
+
}, children: [...Object.keys(ENZYME_PRESETS), 'Custom'].map(name => (_jsx(MenuItem, { value: name, children: name }, name))) }), enzyme === 'Custom' ? (_jsxs(_Fragment, { children: [_jsx(TextField, { size: "small", label: "PAM (IUPAC)", value: pam, error: !pamValid, helperText: pamValid ? undefined : 'Use IUPAC codes only', onChange: event => {
|
|
131
|
+
setPam(event.target.value.toUpperCase());
|
|
132
|
+
} }), _jsxs("div", { className: classes.row, children: [_jsx(TextField, { size: "small", label: "Guide length (bp)", value: guideLengthStr, error: !guideLengthValid, helperText: guideLengthValid ? undefined : 'A whole number of bp', onChange: event => {
|
|
133
|
+
setGuideLengthStr(event.target.value);
|
|
134
|
+
} }), _jsx(TextField, { size: "small", label: "Cut offset (bp)", value: cutOffsetStr, error: !cutOffsetValid, helperText: cutOffsetValid ? undefined : 'bp from the PAM, within the guide', onChange: event => {
|
|
135
|
+
setCutOffsetStr(event.target.value);
|
|
136
|
+
} })] }), _jsxs("div", { className: classes.toggleRow, children: [_jsx(Typography, { variant: "body2", color: "textSecondary", children: "PAM location" }), _jsxs(ToggleButtonGroup, { exclusive: true, size: "small", value: pamLocation, onChange: (_event, value) => {
|
|
137
|
+
if (value) {
|
|
138
|
+
setPamLocation(value);
|
|
139
|
+
}
|
|
140
|
+
}, children: [_jsx(ToggleButton, { value: "3prime", children: "3\u2032 (Cas9)" }), _jsx(ToggleButton, { value: "5prime", children: "5\u2032 (Cas12a)" })] })] })] })) : null, _jsx(StrandCheckboxes, { searchForward: searchForward, searchReverse: searchReverse, setSearchForward: setSearchForward, setSearchReverse: setSearchReverse }), _jsx(LabeledCheckbox, { size: "small", checked: filterQuality, onChange: val => {
|
|
141
|
+
setFilterQuality(val);
|
|
142
|
+
}, label: "Keep only guides with 40-60% GC and no poly-T run" })] }));
|
|
143
|
+
});
|
|
144
|
+
export default CrisprGuidePanel;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { Cytoband } from './util.ts';
|
|
2
|
+
import type { ViewLayout } from '@jbrowse/core/util/Base1DUtils';
|
|
3
3
|
import type { ContentBlock } from '@jbrowse/core/util/blockTypes';
|
|
4
|
-
declare const Cytobands: ({ overview, block,
|
|
5
|
-
overview:
|
|
6
|
-
|
|
4
|
+
declare const Cytobands: ({ overview, block, cytobands, }: {
|
|
5
|
+
overview: ViewLayout;
|
|
6
|
+
cytobands: Cytoband[];
|
|
7
7
|
block: ContentBlock;
|
|
8
|
-
}) => import("react
|
|
8
|
+
}) => import("react").JSX.Element;
|
|
9
9
|
export default Cytobands;
|