@jbrowse/plugin-linear-genome-view 4.3.0 → 5.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (357) hide show
  1. package/esm/FeatureTrack/configSchema.d.ts +104 -65
  2. package/esm/FeatureTrack/configSchema.js +47 -1
  3. package/esm/FeatureTrack/index.js +1 -1
  4. package/esm/LaunchLinearGenomeView/index.d.ts +14 -0
  5. package/esm/LaunchLinearGenomeView/index.js +17 -12
  6. package/esm/LinearGenomeView/FloatingSvgOverlay.d.ts +5 -0
  7. package/esm/LinearGenomeView/FloatingSvgOverlay.js +25 -0
  8. package/esm/LinearGenomeView/afterAttach.d.ts +20 -2
  9. package/esm/LinearGenomeView/afterAttach.js +253 -122
  10. package/esm/LinearGenomeView/components/CenterLine.d.ts +1 -1
  11. package/esm/LinearGenomeView/components/CenterLine.js +16 -7
  12. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.d.ts +7 -0
  13. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +22 -0
  14. package/esm/LinearGenomeView/components/CrisprGuidePanel.d.ts +3 -0
  15. package/esm/LinearGenomeView/components/CrisprGuidePanel.js +144 -0
  16. package/esm/LinearGenomeView/components/Cytobands.d.ts +6 -6
  17. package/esm/LinearGenomeView/components/Cytobands.js +76 -53
  18. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +7 -3
  19. package/esm/LinearGenomeView/components/ExportSvgDialog.js +11 -67
  20. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +5 -9
  21. package/esm/LinearGenomeView/components/GetSequenceDialog.js +84 -88
  22. package/esm/LinearGenomeView/components/Gridlines.d.ts +1 -1
  23. package/esm/LinearGenomeView/components/Gridlines.js +29 -58
  24. package/esm/LinearGenomeView/components/Header.d.ts +1 -1
  25. package/esm/LinearGenomeView/components/Header.js +32 -16
  26. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.d.ts +21 -0
  27. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +35 -0
  28. package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -2
  29. package/esm/LinearGenomeView/components/HeaderPanControls.js +16 -7
  30. package/esm/LinearGenomeView/components/HeaderRegionWidth.d.ts +1 -1
  31. package/esm/LinearGenomeView/components/HeaderRegionWidth.js +9 -6
  32. package/esm/LinearGenomeView/components/HeaderSearchBoxRow.d.ts +6 -0
  33. package/esm/LinearGenomeView/components/HeaderSearchBoxRow.js +27 -0
  34. package/esm/LinearGenomeView/components/HeaderSearchBoxes.d.ts +5 -0
  35. package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +28 -0
  36. package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.d.ts +3 -2
  37. package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.js +11 -4
  38. package/esm/LinearGenomeView/components/HeaderZoomControls.d.ts +3 -2
  39. package/esm/LinearGenomeView/components/HeaderZoomControls.js +67 -51
  40. package/esm/LinearGenomeView/components/Highlight.d.ts +1 -1
  41. package/esm/LinearGenomeView/components/Highlight.js +19 -23
  42. package/esm/LinearGenomeView/components/HighlightBand.d.ts +3 -2
  43. package/esm/LinearGenomeView/components/HighlightBand.js +25 -8
  44. package/esm/LinearGenomeView/components/HighlightChip.d.ts +9 -0
  45. package/esm/LinearGenomeView/components/HighlightChip.js +15 -0
  46. package/esm/LinearGenomeView/components/HoverPositionHighlight.d.ts +12 -0
  47. package/esm/LinearGenomeView/components/HoverPositionHighlight.js +25 -0
  48. package/esm/LinearGenomeView/components/ImportForm.d.ts +3 -4
  49. package/esm/LinearGenomeView/components/ImportForm.js +95 -61
  50. package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +1 -1
  51. package/esm/LinearGenomeView/components/LinearGenomeView.js +6 -5
  52. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +1 -1
  53. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +89 -30
  54. package/esm/LinearGenomeView/components/MiniControls.d.ts +1 -1
  55. package/esm/LinearGenomeView/components/MiniControls.js +13 -10
  56. package/esm/LinearGenomeView/components/MotifListPanel.d.ts +3 -0
  57. package/esm/LinearGenomeView/components/MotifListPanel.js +59 -0
  58. package/esm/LinearGenomeView/components/NavigationAnnouncer.d.ts +32 -0
  59. package/esm/LinearGenomeView/components/NavigationAnnouncer.js +51 -0
  60. package/esm/LinearGenomeView/components/NoTracksActiveButton.d.ts +1 -1
  61. package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  62. package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +2 -4
  63. package/esm/LinearGenomeView/components/OverviewHighlight.js +23 -44
  64. package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +9 -0
  65. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +26 -0
  66. package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +3 -3
  67. package/esm/LinearGenomeView/components/OverviewRubberband.js +44 -57
  68. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +4 -5
  69. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +13 -20
  70. package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +3 -2
  71. package/esm/LinearGenomeView/components/OverviewScalebar.js +84 -79
  72. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +19 -5
  73. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +55 -32
  74. package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.d.ts +4 -5
  75. package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.js +16 -18
  76. package/esm/LinearGenomeView/components/PaddingBlocks.d.ts +7 -0
  77. package/esm/LinearGenomeView/components/PaddingBlocks.js +51 -0
  78. package/esm/LinearGenomeView/components/RangeSelectOverlay.d.ts +9 -0
  79. package/esm/LinearGenomeView/components/RangeSelectOverlay.js +20 -0
  80. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +2 -3
  81. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +19 -26
  82. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -1
  83. package/esm/LinearGenomeView/components/Rubberband.js +13 -16
  84. package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -0
  85. package/esm/LinearGenomeView/components/SVGHighlightBand.js +9 -0
  86. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -2
  87. package/esm/LinearGenomeView/components/Scalebar.js +16 -21
  88. package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.d.ts +1 -1
  89. package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.js +54 -35
  90. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.d.ts +1 -1
  91. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +142 -126
  92. package/esm/LinearGenomeView/components/SearchBox.d.ts +22 -2
  93. package/esm/LinearGenomeView/components/SearchBox.js +58 -66
  94. package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +9 -0
  95. package/esm/LinearGenomeView/components/SearchPanelForm.js +18 -0
  96. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +3 -3
  97. package/esm/LinearGenomeView/components/SearchResultsDialog.js +5 -7
  98. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -3
  99. package/esm/LinearGenomeView/components/SearchResultsTable.js +45 -53
  100. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.d.ts +5 -0
  101. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +37 -0
  102. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.d.ts +2 -0
  103. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.js +5 -0
  104. package/esm/LinearGenomeView/components/SequencePatternPanel.d.ts +3 -0
  105. package/esm/LinearGenomeView/components/SequencePatternPanel.js +42 -0
  106. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +1 -1
  107. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +31 -53
  108. package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +8 -0
  109. package/esm/LinearGenomeView/components/StrandCheckboxes.js +13 -0
  110. package/esm/LinearGenomeView/components/TrackContainer.d.ts +1 -1
  111. package/esm/LinearGenomeView/components/TrackContainer.js +83 -39
  112. package/esm/LinearGenomeView/components/TrackLabel.d.ts +2 -3
  113. package/esm/LinearGenomeView/components/TrackLabel.js +11 -24
  114. package/esm/LinearGenomeView/components/TrackLabelButtons.d.ts +7 -0
  115. package/esm/LinearGenomeView/components/TrackLabelButtons.js +33 -0
  116. package/esm/LinearGenomeView/components/TrackLabelDragHandle.d.ts +2 -5
  117. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +6 -2
  118. package/esm/LinearGenomeView/components/TrackLabelMenu.d.ts +1 -1
  119. package/esm/LinearGenomeView/components/TrackLabelMenu.js +32 -85
  120. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +22 -0
  121. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +46 -0
  122. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +1 -1
  123. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +72 -18
  124. package/esm/LinearGenomeView/components/TracksContainer.d.ts +1 -1
  125. package/esm/LinearGenomeView/components/TracksContainer.js +65 -32
  126. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -1
  127. package/esm/LinearGenomeView/components/VerticalGuide.js +6 -13
  128. package/esm/LinearGenomeView/components/ZoomButton.d.ts +7 -0
  129. package/esm/LinearGenomeView/components/ZoomButton.js +22 -0
  130. package/esm/LinearGenomeView/components/ZoomTransform.d.ts +9 -0
  131. package/esm/LinearGenomeView/components/ZoomTransform.js +33 -0
  132. package/esm/LinearGenomeView/components/defaultMotifs.d.ts +1 -0
  133. package/esm/LinearGenomeView/components/defaultMotifs.js +22 -0
  134. package/esm/LinearGenomeView/components/fetchSequence.d.ts +7 -8
  135. package/esm/LinearGenomeView/components/fetchSequence.js +17 -9
  136. package/esm/LinearGenomeView/components/recentLocationsMenu.d.ts +15 -0
  137. package/esm/LinearGenomeView/components/recentLocationsMenu.js +36 -0
  138. package/esm/LinearGenomeView/components/searchModes.d.ts +13 -0
  139. package/esm/LinearGenomeView/components/searchModes.js +22 -0
  140. package/esm/LinearGenomeView/components/trackLabelMenuItems.d.ts +7 -0
  141. package/esm/LinearGenomeView/components/trackLabelMenuItems.js +67 -0
  142. package/esm/LinearGenomeView/components/useRangeSelect.d.ts +11 -66
  143. package/esm/LinearGenomeView/components/useRangeSelect.js +82 -91
  144. package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +26 -0
  145. package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +58 -0
  146. package/esm/LinearGenomeView/components/useSideScroll.d.ts +1 -1
  147. package/esm/LinearGenomeView/components/useSideScroll.js +87 -19
  148. package/esm/LinearGenomeView/components/util.d.ts +20 -6
  149. package/esm/LinearGenomeView/components/util.js +27 -6
  150. package/esm/LinearGenomeView/consts.d.ts +7 -2
  151. package/esm/LinearGenomeView/consts.js +18 -2
  152. package/esm/LinearGenomeView/flyTo.d.ts +38 -0
  153. package/esm/LinearGenomeView/flyTo.js +135 -0
  154. package/esm/LinearGenomeView/headerFit.d.ts +27 -0
  155. package/esm/LinearGenomeView/headerFit.js +59 -0
  156. package/esm/LinearGenomeView/index.d.ts +31 -2
  157. package/esm/LinearGenomeView/index.js +8 -5
  158. package/esm/LinearGenomeView/initKeys.d.ts +13 -0
  159. package/esm/LinearGenomeView/initKeys.js +104 -0
  160. package/esm/LinearGenomeView/keyboardHandler.d.ts +7 -0
  161. package/esm/LinearGenomeView/keyboardHandler.js +10 -0
  162. package/esm/LinearGenomeView/lazyDialogs.d.ts +6 -10
  163. package/esm/LinearGenomeView/lazyDialogs.js +3 -3
  164. package/esm/LinearGenomeView/linkedViewSync.d.ts +20 -0
  165. package/esm/LinearGenomeView/linkedViewSync.js +52 -0
  166. package/esm/LinearGenomeView/menuItems.d.ts +27 -2
  167. package/esm/LinearGenomeView/menuItems.js +137 -101
  168. package/esm/LinearGenomeView/model.d.ts +1536 -146
  169. package/esm/LinearGenomeView/model.js +2348 -515
  170. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +18 -0
  171. package/esm/LinearGenomeView/sharedScaleContainer.js +17 -0
  172. package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +35 -0
  173. package/esm/LinearGenomeView/showRegionsWithUndo.js +44 -0
  174. package/esm/LinearGenomeView/stickyChrome.d.ts +19 -0
  175. package/esm/LinearGenomeView/stickyChrome.js +30 -0
  176. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.d.ts +1 -1
  177. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +15 -16
  178. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +2 -3
  179. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +45 -33
  180. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +5 -0
  181. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +26 -0
  182. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +5 -0
  183. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +13 -0
  184. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +1 -3
  185. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +77 -41
  186. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +1 -1
  187. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +23 -3
  188. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.d.ts +8 -0
  189. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +37 -0
  190. package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +3 -3
  191. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +64 -36
  192. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +1 -1
  193. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +7 -5
  194. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +5 -3
  195. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +43 -7
  196. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +8 -14
  197. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +16 -21
  198. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +18 -0
  199. package/esm/LinearGenomeView/svgcomponents/SVGView.js +13 -0
  200. package/esm/LinearGenomeView/svgcomponents/figureContract.d.ts +45 -0
  201. package/esm/LinearGenomeView/svgcomponents/figureContract.js +130 -0
  202. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +76 -0
  203. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +66 -0
  204. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.d.ts +70 -0
  205. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +263 -0
  206. package/esm/LinearGenomeView/svgcomponents/util.d.ts +92 -5
  207. package/esm/LinearGenomeView/svgcomponents/util.js +236 -3
  208. package/esm/LinearGenomeView/types.d.ts +17 -31
  209. package/esm/LinearGenomeView/types.js +1 -0
  210. package/esm/LinearGenomeView/util.d.ts +332 -12
  211. package/esm/LinearGenomeView/util.js +606 -62
  212. package/esm/MultiLevelRubberband/MultiLevelRubberband.d.ts +6 -0
  213. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +37 -0
  214. package/esm/MultiLevelRubberband/VerticalGuide.d.ts +6 -0
  215. package/esm/MultiLevelRubberband/VerticalGuide.js +21 -0
  216. package/esm/MultiLevelRubberband/index.d.ts +2 -0
  217. package/esm/MultiLevelRubberband/index.js +1 -0
  218. package/esm/MultiLevelRubberband/types.d.ts +6 -0
  219. package/esm/MultiLevelRubberband/useRangeSelect.d.ts +24 -0
  220. package/esm/MultiLevelRubberband/useRangeSelect.js +136 -0
  221. package/esm/displayKitTests/perRegionTestEnv.d.ts +1263 -0
  222. package/esm/displayKitTests/perRegionTestEnv.js +141 -0
  223. package/esm/index.d.ts +112 -1237
  224. package/esm/index.js +102 -24
  225. package/esm/lazyPluginExports.d.ts +23 -0
  226. package/esm/lazyPluginExports.js +36 -0
  227. package/esm/searchUtils.d.ts +52 -11
  228. package/esm/searchUtils.js +317 -46
  229. package/esm/shared/RubberbandSpan.d.ts +15 -0
  230. package/esm/shared/RubberbandSpan.js +33 -0
  231. package/esm/shared/coordLabels.d.ts +40 -0
  232. package/esm/shared/coordLabels.js +119 -0
  233. package/package.json +18 -19
  234. package/esm/BaseLinearDisplay/SVGLegend.d.ts +0 -6
  235. package/esm/BaseLinearDisplay/SVGLegend.js +0 -17
  236. package/esm/BaseLinearDisplay/calculateSvgLegendWidth.d.ts +0 -2
  237. package/esm/BaseLinearDisplay/calculateSvgLegendWidth.js +0 -11
  238. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +0 -8
  239. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +0 -53
  240. package/esm/BaseLinearDisplay/components/Block.d.ts +0 -14
  241. package/esm/BaseLinearDisplay/components/Block.js +0 -45
  242. package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +0 -7
  243. package/esm/BaseLinearDisplay/components/BlockErrorMessage.js +0 -22
  244. package/esm/BaseLinearDisplay/components/BlockMsg.d.ts +0 -6
  245. package/esm/BaseLinearDisplay/components/BlockMsg.js +0 -26
  246. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.d.ts +0 -9
  247. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.js +0 -42
  248. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.d.ts +0 -11
  249. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.js +0 -40
  250. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.d.ts +0 -19
  251. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.js +0 -45
  252. package/esm/BaseLinearDisplay/components/FloatingLabels.d.ts +0 -5
  253. package/esm/BaseLinearDisplay/components/FloatingLabels.js +0 -75
  254. package/esm/BaseLinearDisplay/components/FloatingLegend.d.ts +0 -8
  255. package/esm/BaseLinearDisplay/components/FloatingLegend.js +0 -43
  256. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +0 -5
  257. package/esm/BaseLinearDisplay/components/LinearBlocks.js +0 -23
  258. package/esm/BaseLinearDisplay/components/LoadingOverlay.d.ts +0 -5
  259. package/esm/BaseLinearDisplay/components/LoadingOverlay.js +0 -49
  260. package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.d.ts +0 -4
  261. package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.js +0 -26
  262. package/esm/BaseLinearDisplay/components/MenuPage.d.ts +0 -8
  263. package/esm/BaseLinearDisplay/components/MenuPage.js +0 -24
  264. package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.d.ts +0 -21
  265. package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.js +0 -52
  266. package/esm/BaseLinearDisplay/components/RenderedBlocks.d.ts +0 -12
  267. package/esm/BaseLinearDisplay/components/RenderedBlocks.js +0 -22
  268. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +0 -12
  269. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +0 -18
  270. package/esm/BaseLinearDisplay/components/TooLargeMessage.d.ts +0 -10
  271. package/esm/BaseLinearDisplay/components/TooLargeMessage.js +0 -20
  272. package/esm/BaseLinearDisplay/components/Tooltip.d.ts +0 -13
  273. package/esm/BaseLinearDisplay/components/Tooltip.js +0 -22
  274. package/esm/BaseLinearDisplay/components/types.d.ts +0 -1
  275. package/esm/BaseLinearDisplay/components/util.d.ts +0 -21
  276. package/esm/BaseLinearDisplay/components/util.js +0 -107
  277. package/esm/BaseLinearDisplay/index.d.ts +0 -17
  278. package/esm/BaseLinearDisplay/index.js +0 -13
  279. package/esm/BaseLinearDisplay/model.d.ts +0 -1197
  280. package/esm/BaseLinearDisplay/model.js +0 -432
  281. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.d.ts +0 -32
  282. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +0 -113
  283. package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.d.ts +0 -26
  284. package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.js +0 -57
  285. package/esm/BaseLinearDisplay/models/SvgFloatingLabels.d.ts +0 -8
  286. package/esm/BaseLinearDisplay/models/SvgFloatingLabels.js +0 -19
  287. package/esm/BaseLinearDisplay/models/TrackHeightMixin.d.ts +0 -11
  288. package/esm/BaseLinearDisplay/models/TrackHeightMixin.js +0 -31
  289. package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.d.ts +0 -2
  290. package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.js +0 -29
  291. package/esm/BaseLinearDisplay/models/configSchema.d.ts +0 -29
  292. package/esm/BaseLinearDisplay/models/configSchema.js +0 -33
  293. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +0 -98
  294. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -242
  295. package/esm/BaseLinearDisplay/models/util.d.ts +0 -9
  296. package/esm/BaseLinearDisplay/models/util.js +0 -43
  297. package/esm/BaseLinearDisplay/renderSvg.d.ts +0 -3
  298. package/esm/BaseLinearDisplay/renderSvg.js +0 -63
  299. package/esm/BaseLinearDisplay/types.d.ts +0 -43
  300. package/esm/BaseLinearDisplay/types.js +0 -3
  301. package/esm/BaseLinearDisplay/util.d.ts +0 -16
  302. package/esm/BaseLinearDisplay/util.js +0 -71
  303. package/esm/BasicTrack/configSchema.d.ts +0 -85
  304. package/esm/BasicTrack/configSchema.js +0 -8
  305. package/esm/BasicTrack/index.d.ts +0 -2
  306. package/esm/BasicTrack/index.js +0 -12
  307. package/esm/LinearBareDisplay/configSchema.d.ts +0 -32
  308. package/esm/LinearBareDisplay/configSchema.js +0 -11
  309. package/esm/LinearBareDisplay/index.d.ts +0 -4
  310. package/esm/LinearBareDisplay/index.js +0 -20
  311. package/esm/LinearBareDisplay/model.d.ts +0 -1196
  312. package/esm/LinearBareDisplay/model.js +0 -32
  313. package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.d.ts +0 -5
  314. package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.js +0 -9
  315. package/esm/LinearBasicDisplay/configSchema.d.ts +0 -32
  316. package/esm/LinearBasicDisplay/configSchema.js +0 -11
  317. package/esm/LinearBasicDisplay/index.d.ts +0 -4
  318. package/esm/LinearBasicDisplay/index.js +0 -20
  319. package/esm/LinearBasicDisplay/model.d.ts +0 -1391
  320. package/esm/LinearBasicDisplay/model.js +0 -158
  321. package/esm/LinearFeatureDisplay/components/AddFiltersDialog.d.ts +0 -9
  322. package/esm/LinearFeatureDisplay/components/AddFiltersDialog.js +0 -58
  323. package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.d.ts +0 -8
  324. package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.js +0 -26
  325. package/esm/LinearFeatureDisplay/configSchema.d.ts +0 -32
  326. package/esm/LinearFeatureDisplay/configSchema.js +0 -11
  327. package/esm/LinearFeatureDisplay/index.d.ts +0 -3
  328. package/esm/LinearFeatureDisplay/index.js +0 -2
  329. package/esm/LinearFeatureDisplay/model.d.ts +0 -1443
  330. package/esm/LinearFeatureDisplay/model.js +0 -305
  331. package/esm/LinearGenomeView/SVGErrorBox.d.ts +0 -5
  332. package/esm/LinearGenomeView/SVGErrorBox.js +0 -4
  333. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +0 -11
  334. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +0 -27
  335. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.d.ts +0 -5
  336. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +0 -13
  337. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.d.ts +0 -3
  338. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +0 -17
  339. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.d.ts +0 -3
  340. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +0 -8
  341. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +0 -16
  342. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +0 -101
  343. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.d.ts +0 -10
  344. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.js +0 -45
  345. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +0 -15
  346. package/esm/LinearGenomeView/components/RubberbandSpan.js +0 -32
  347. package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +0 -5
  348. package/esm/LinearGenomeView/components/RubberbandTooltip.js +0 -17
  349. package/esm/LinearGenomeView/components/TrackLabelContainer.d.ts +0 -8
  350. package/esm/LinearGenomeView/components/TrackLabelContainer.js +0 -25
  351. package/esm/LinearGenomeView/components/useWheelScroll.d.ts +0 -7
  352. package/esm/LinearGenomeView/components/useWheelScroll.js +0 -69
  353. package/esm/LinearGenomeView/svgExportUtil.d.ts +0 -9
  354. package/esm/LinearGenomeView/svgExportUtil.js +0 -6
  355. package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +0 -5
  356. package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +0 -7
  357. /package/esm/{BaseLinearDisplay/components → MultiLevelRubberband}/types.js +0 -0
@@ -1,77 +1,348 @@
1
- import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
2
- import { dedupe, getEnv, getSession } from '@jbrowse/core/util';
3
- export async function navToOption({ option, model, assemblyName, }) {
4
- const location = option.getLocation();
5
- const trackId = option.getTrackId();
6
- if (location) {
7
- await model.navToLocString(location, assemblyName, 0.2);
8
- if (trackId) {
9
- model.showTrack(trackId);
10
- }
1
+ import { RefSequenceResult } from '@jbrowse/core/TextSearch/BaseResults';
2
+ import { assembleLocString, dedupe, getEnv, getNotificationSink, getSession, matchRefNames, MAX_GLOB_REGIONS, parseLocString, UnknownRefNameError, } from '@jbrowse/core/util';
3
+ import { isAlive } from '@jbrowse/mobx-state-tree';
4
+ import { parseLocStrings } from './LinearGenomeView/util.js';
5
+ // Budget for refName suggestions from a query. Deliberately far below the
6
+ // autocomplete's ~100-row display cap: refNames are returned ahead of the text
7
+ // search hits, so a scaffold-heavy assembly would otherwise fill every row with
8
+ // scaffolds and push the gene hits out of the list entirely. Raising this to
9
+ // match the display cap looks like a consistency fix and is not one.
10
+ const MAX_REFNAME_HITS = 10;
11
+ // shared dispatch used by SearchBox.onSelect and the LGV ImportForm submit:
12
+ // route a chosen result to a direct nav, a multi-result dialog, or a generic
13
+ // locstring/refname resolution
14
+ export async function navigateToSelectedOption({ option, model, assemblyName, }) {
15
+ if (option.hasLocation()) {
16
+ await navToOption({ option, model, assemblyName });
17
+ }
18
+ else if (option.results?.length) {
19
+ await showSearchResults({
20
+ results: option.results,
21
+ query: option.getLabel(),
22
+ model,
23
+ assemblyName,
24
+ });
25
+ }
26
+ else {
27
+ await handleSelectedRegion({
28
+ input: option.getLabel(),
29
+ assemblyName,
30
+ model,
31
+ });
32
+ }
33
+ }
34
+ // Whether the view already has the track this hit came from on screen.
35
+ export function isOpenInView(result, model) {
36
+ const trackId = result.getTrackId();
37
+ return trackId !== undefined && !!model.getTrack(trackId);
38
+ }
39
+ // One spelling of a locstring, so two indexes that answer `chr1:1-100` and
40
+ // `1:1..100` are recognised as one place. An unparseable string is compared
41
+ // raw, which can only ever split a group that would otherwise have merged —
42
+ // the safe direction, since the picker is what an unprovable match falls back
43
+ // to.
44
+ function canonicalLocString(locString, assembly) {
45
+ try {
46
+ const loc = parseLocString(locString, refName => assembly.isValidRefName(refName));
47
+ return assembleLocString({
48
+ ...loc,
49
+ refName: assembly.getCanonicalRefName2(loc.refName),
50
+ });
51
+ }
52
+ catch (e) {
53
+ console.warn('failed to parse location string', locString, e);
54
+ return locString;
55
+ }
56
+ }
57
+ // What a hit means as a destination: the name it shows and the place it goes.
58
+ // A hit with no location has no destination and can never join a group.
59
+ function destination(result, assembly) {
60
+ const locString = result.getLocation();
61
+ return locString
62
+ ? [
63
+ result.getDisplayString(),
64
+ assembly?.initialized
65
+ ? canonicalLocString(locString, assembly)
66
+ : locString,
67
+ ].join('\u0000')
68
+ : undefined;
69
+ }
70
+ // Which hit of an agreeing group to travel through, best rung first: a track
71
+ // the view already has on screen, then one the session could open if asked,
72
+ // then whatever the ranking put first. The middle rung is not hypothetical —
73
+ // a JBrowse 1 names index stores JBrowse 1 track *names*, and volvox's has
74
+ // four EDEN.1 entries of which two name nothing any JBrowse 2 config claims.
75
+ // Travelling through one of those navigates correctly and then drops a
76
+ // "could not resolve identifier" snackbar on top of it.
77
+ function trackRank(result, model, session) {
78
+ const trackId = result.getTrackId();
79
+ if (trackId === undefined) {
80
+ return 2;
81
+ }
82
+ else if (model.getTrack(trackId)) {
83
+ return 0;
84
+ }
85
+ else {
86
+ return session.getTrackById(trackId) ? 1 : 3;
87
+ }
88
+ }
89
+ // The picker exists to disambiguate, and hits that name one feature at one
90
+ // place are not ambiguous — they are several indexes having found it. An
91
+ // instance carrying a handful of gene tracks turns every gene search into a
92
+ // table whose only varying column is Track, which is issues #4302 and #5068.
93
+ // When the hits agree there is nothing to ask, so navigate instead.
94
+ export function unanimousResult({ results, model, session, assembly, }) {
95
+ // computed once per hit rather than once per comparison: a broad query can
96
+ // carry a hundred results, and each one costs a locstring parse
97
+ const destinations = results.map(r => destination(r, assembly));
98
+ const agree = destinations[0] !== undefined &&
99
+ destinations.every(d => d === destinations[0]);
100
+ // stable, so an agreeing group with nothing to choose between keeps the
101
+ // order the ranking handed it
102
+ return agree
103
+ ? [...results].sort((a, b) => trackRank(a, model, session) - trackRank(b, model, session))[0]
104
+ : undefined;
105
+ }
106
+ // Every multi-hit result set reaches the picker through here, so the two
107
+ // search surfaces cannot disagree about when one is worth raising. Returns
108
+ // whether the view moved.
109
+ export async function showSearchResults({ results, query, model, assemblyName, grow, }) {
110
+ const session = getSession(model);
111
+ const unanimous = unanimousResult({
112
+ results,
113
+ model,
114
+ session,
115
+ assembly: session.assemblyManager.get(assemblyName),
116
+ });
117
+ if (unanimous) {
118
+ await navToOption({ option: unanimous, model, assemblyName, grow });
119
+ return true;
11
120
  }
121
+ else {
122
+ model.setSearchResults(results, query, assemblyName);
123
+ return false;
124
+ }
125
+ }
126
+ // A search hit lands with context around it rather than flush to the feature's
127
+ // own edges, which is what this default is; a caller that asked for a specific
128
+ // padding gets that instead.
129
+ const SEARCH_HIT_GROW = 0.2;
130
+ export async function navToOption({ option, model, assemblyName, grow, }) {
131
+ // getLocation() can be an empty string when a result reports hasLocation()
132
+ // but carries no coordinates; treat that as "no location" and fall back to
133
+ // the label rather than forwarding '' into an empty, view-blanking parse
134
+ const location = option.getLocation() || option.getLabel();
135
+ const trackId = option.getTrackId();
12
136
  const session = getSession(model);
13
- const { pluginManager } = getEnv(session);
14
- await pluginManager.evaluateAsyncExtensionPoint('LinearGenomeView-searchResultSelected', undefined, { session, result: option, model, assemblyName });
137
+ const { assemblyManager } = session;
138
+ await model.navToLocations(parseLocStrings(location, assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName, grow ?? SEARCH_HIT_GROW);
139
+ if (trackId && isAlive(model)) {
140
+ model.showTrack(trackId);
141
+ }
142
+ // same detach hazard as showTrack above: navToLocations awaits, and handlers
143
+ // read off the view (the canvas one calls getSession(model) and model.tracks),
144
+ // which throws once it has left the tree. Deliberately not the Strict runner —
145
+ // this fires after the navigation has already succeeded, so a plugin's
146
+ // post-nav side effect failing must not turn a completed search into an error
147
+ if (isAlive(model)) {
148
+ const { pluginManager } = getEnv(session);
149
+ await pluginManager.evaluateAsyncExtensionPoint(
150
+ /** #extensionPoint LinearGenomeView-searchResultSelected | async | Invoked when a search result is selected */
151
+ 'LinearGenomeView-searchResultSelected', undefined, { session, result: option, model, assemblyName });
152
+ }
15
153
  }
16
- export async function handleSelectedRegion({ input, model, assembly, }) {
17
- const allRefs = assembly.allRefNamesWithLowerCase || [];
18
- const assemblyName = assembly.name;
19
- if (input.split(' ').every(entry => checkRef(entry, allRefs))) {
20
- await model.navToLocString(input, assembly.name);
154
+ // Thrown when a name search yields no hits and the input isn't coordinate-shaped.
155
+ // Typed (rather than a bare Error) so callers can render it as a soft "not found"
156
+ // warning instead of an error — string-matching the message would be brittle.
157
+ export class SearchResultsNotFoundError extends Error {
158
+ name = 'SearchResultsNotFoundError';
159
+ }
160
+ // How every search surface reports a failed navigation. A miss is the ordinary
161
+ // outcome of typing a name that isn't there, so it shows its own sentence
162
+ // rather than `${e}`, which would prefix it with the class name. Shared so the
163
+ // import form and the header box can't drift apart on it again.
164
+ export function notifySearchFailure(session, e) {
165
+ console.error(e);
166
+ session.notify(e instanceof SearchResultsNotFoundError ? e.message : `${e}`, 'warning');
167
+ }
168
+ // if input is a known ref or locstring, navigate directly;
169
+ // otherwise search and: pop a dialog for multiple results, navigate for one,
170
+ // or fall back to treating input as a locstring
171
+ //
172
+ // Returns whether the view actually moved. Three branches deliberately do not
173
+ // navigate — a glob too wide to open, a multi-hit search whose hits disagree
174
+ // about where to go and so raise the picker, and a view detached while the
175
+ // search RPC ran — and each of them resolves, so a caller awaiting this cannot
176
+ // otherwise tell "showing it" from "asked you which one".
177
+ export async function handleSelectedRegion({ input, model, assemblyName, grow, }) {
178
+ const { assemblyManager, textSearchManager } = getSession(model);
179
+ // resolves only once regions/aliases are loaded, which isValidRefName needs
180
+ // (it throws otherwise). A load failure is not this function's to report:
181
+ // swallow it and let the input fall through to the text-search path below
182
+ // rather than surfacing as a nav error
183
+ const assembly = await assemblyManager
184
+ .waitForAssembly(assemblyName)
185
+ .catch(() => undefined);
186
+ // the same predicate navToLocstrings hands parseLocStrings, so a locstring
187
+ // that passes here is one the parse below will accept
188
+ const isRef = (ref) => !!assembly && assemblyManager.isValidRefName(ref, assemblyName);
189
+ // navigate treating input as one or more whitespace-separated locstrings
190
+ const navToLocstrings = () => model.navToLocations(parseLocStrings(input, assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName, grow);
191
+ if (input
192
+ .split(/\s+/)
193
+ .filter(Boolean)
194
+ .every(entry => checkRef(entry, isRef))) {
195
+ await navToLocstrings();
196
+ return true;
197
+ }
198
+ else if (input.includes('*') && !!assembly) {
199
+ // Enter does what the dropdown's "Show all N regions matching …" row does,
200
+ // for the same text. It is NOT a blind resolution: that row, and the matches
201
+ // under it, have been on screen the whole time the pattern was being typed,
202
+ // which is the reason a glob belongs in the picker at all. What would be
203
+ // indefensible is the two disagreeing — Enter reporting no results over a
204
+ // list the box is showing is the same failure the exact-first search pass
205
+ // was written to end, and a glob is precisely the query the text index can
206
+ // never answer, since nothing PREFIX-matches the literal `chr*`.
207
+ //
208
+ // Ordered after the refName check, so a contig whose name really contains
209
+ // `*` — GRCh38's HLA decoys — navigates to itself rather than being read as
210
+ // a pattern. Same literal-first rule as selectNamedRegions.
211
+ const names = matchRefNames(assembly, input, MAX_GLOB_REGIONS);
212
+ if (names.length > MAX_GLOB_REGIONS) {
213
+ // Refused rather than truncated, and said out loud. Opening the first
214
+ // thousand of a wider match is the one outcome that would look like it
215
+ // worked.
216
+ getNotificationSink(model).notify(`"${input}" matches more than ${MAX_GLOB_REGIONS} regions — narrow the pattern`, 'warning');
217
+ return false;
218
+ }
219
+ else if (names.length) {
220
+ await model.navToLocations(parseLocStrings(names.join(' '), assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName);
221
+ return true;
222
+ }
223
+ else {
224
+ // matched nothing: a pattern is not a feature name, so there is no index
225
+ // to fall through to, and the miss is the whole answer
226
+ throw new SearchResultsNotFoundError(`No results found for "${input}"`);
227
+ }
21
228
  }
22
229
  else {
23
- const searchScope = model.searchScope(assemblyName);
24
- const { textSearchManager } = getSession(model);
25
- const results = await fetchResults({
230
+ // Ask once, unrestricted, and read exactness off the hits. Prefer the
231
+ // exact ones so a precise name navigates straight to its feature instead
232
+ // of opening a picker of everything it prefixes ("EDEN" must not pop a
233
+ // dialog for EDEN.1/.2/.3) — but an exact miss is not a no-result, since
234
+ // the autocomplete dropdown searched unrestricted and anything it just
235
+ // listed has to be reachable here too (typing "apple" and pressing enter
236
+ // once reported `No results found for "apple"` for a query the dropdown
237
+ // had two hits for).
238
+ //
239
+ // This used to be two searches, an exact one and then a broad one on the
240
+ // miss, which is two reads of the same index for the same query — the
241
+ // adapters answer 'exact' by filtering exactly this list. An adapter that
242
+ // tags nothing simply never wins the exact pass, which is the behaviour it
243
+ // had when it returned nothing for searchType: 'exact'.
244
+ const allResults = await fetchResults({
26
245
  queryString: input,
27
- searchType: 'exact',
28
- searchScope,
29
- rankSearchResults: model.rankSearchResults,
246
+ assemblyName,
30
247
  textSearchManager,
31
248
  assembly,
32
249
  });
250
+ const exactResults = allResults.filter(r => r.isExact());
251
+ const results = exactResults.length ? exactResults : allResults;
252
+ // the view may have been closed/detached while the text-search RPC ran
253
+ if (!isAlive(model)) {
254
+ return false;
255
+ }
33
256
  if (results.length > 1) {
34
- model.setSearchResults(results, input.toLowerCase(), assemblyName);
257
+ return await showSearchResults({
258
+ results,
259
+ query: input,
260
+ model,
261
+ assemblyName,
262
+ grow,
263
+ });
35
264
  }
36
265
  else if (results.length === 1) {
266
+ // `grow` reached the locstring branch above but not this one, so a
267
+ // caller's padding — a session spec's `grow`, sv-core's navToLoc — was
268
+ // honoured or silently replaced by 0.2 depending on whether the input
269
+ // happened to parse as a locstring rather than resolve to a feature
37
270
  await navToOption({
38
271
  option: results[0],
39
272
  model,
40
273
  assemblyName,
274
+ grow,
41
275
  });
276
+ return true;
42
277
  }
43
278
  else {
44
- await model.navToLocString(input, assemblyName);
279
+ // no search hits: still try to resolve the input as a locstring (bare
280
+ // refname, "ref start end" triplet, etc). if that also can't find a
281
+ // refname AND the input is a single bare token (a plausible gene name),
282
+ // reframe the unknown-ref error as a clean "no results" message; keep the
283
+ // specific ref error for coordinate/multi-part queries
284
+ try {
285
+ await navToLocstrings();
286
+ return true;
287
+ }
288
+ catch (e) {
289
+ const isPlainName = !input.includes(':') && !input.includes(' ');
290
+ if (e instanceof UnknownRefNameError && isPlainName) {
291
+ throw new SearchResultsNotFoundError(`No results found for "${input}"`);
292
+ }
293
+ else {
294
+ throw e;
295
+ }
296
+ }
45
297
  }
46
298
  }
47
299
  }
48
- export function checkRef(str, allRefs) {
300
+ export function checkRef(str, isRef) {
49
301
  const [ref, rest] = splitLast(str, ':');
50
- return (allRefs.includes(str) ||
51
- (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10))));
302
+ return isRef(str) || (isRef(ref) && /^\d/.test(rest));
52
303
  }
53
- export async function fetchResults({ queryString, searchType, searchScope, rankSearchResults, textSearchManager, assembly, }) {
54
- if (!textSearchManager) {
55
- console.warn('No text search manager');
56
- }
304
+ export async function fetchResults({ queryString, searchType, assemblyName, textSearchManager, assembly, stopToken, }) {
57
305
  const textSearchResults = await textSearchManager?.search({
58
306
  queryString,
59
307
  searchType,
60
- }, searchScope, rankSearchResults);
61
- const refNameResults = [
62
- ...new Set(assembly?.allRefNames
63
- ?.filter(ref => ref.toLowerCase().startsWith(queryString.toLowerCase()))
64
- .map(ref => assembly.getCanonicalRefName(ref) ?? ref)
65
- .slice(0, 10)),
66
- ].map(r => new BaseResult({ label: r, matchedObject: { refName: r } }));
308
+ stopToken,
309
+ }, assemblyName);
310
+ // ensure aliases are loaded: allRefNames is a pure getter, so reading it does
311
+ // not itself kick off the lazy load. A load failure just leaves allRefNames
312
+ // undefined, so this still returns whatever the text search turned up
313
+ await assembly?.load().catch(() => { });
314
+ const refNameResults = assembly
315
+ ? searchRefNames(assembly, queryString, searchType)
316
+ : [];
67
317
  return dedupe([...refNameResults, ...(textSearchResults ?? [])], elt => elt.getId());
68
318
  }
69
- export function splitLast(str, split) {
70
- const lastIndex = str.lastIndexOf(split);
71
- if (lastIndex === -1) {
72
- return [str, ''];
319
+ // Scan assembly refnames for query matches, resolving aliases (e.g. 'contigB')
320
+ // to the canonical refname ('ctgB') so the dropdown shows the name that matches
321
+ // the FASTA / displayed regions. allRefNames can hold ~10^6 entries, so stop
322
+ // once enough unique canonical hits accumulate rather than lowercasing and
323
+ // scanning the entire list on every keystroke.
324
+ function searchRefNames(assembly, queryString, searchType) {
325
+ const q = queryString.toLowerCase();
326
+ // canonical name -> whether any alias of it matched the query exactly, so
327
+ // "contigb" is an exact hit on ctgB even though the canonical name is not
328
+ // the query. Same collapsing as before, now carrying the flag through it
329
+ const canonicalHits = new Map();
330
+ for (const ref of assembly.allRefNames ?? []) {
331
+ const lower = ref.toLowerCase();
332
+ const exact = lower === q;
333
+ const isMatch = searchType === 'exact' ? exact : lower.startsWith(q);
334
+ if (isMatch) {
335
+ const canonical = assembly.getCanonicalRefName2(ref);
336
+ canonicalHits.set(canonical, exact || !!canonicalHits.get(canonical));
337
+ if (canonicalHits.size >= MAX_REFNAME_HITS) {
338
+ break;
339
+ }
340
+ }
73
341
  }
74
- const before = str.slice(0, lastIndex);
75
- const after = str.slice(lastIndex + 1);
76
- return [before, after];
342
+ return [...canonicalHits].map(([r, exact]) => new RefSequenceResult({ label: r, refName: r, exact }));
343
+ }
344
+ // splits on the last instance of a character
345
+ export function splitLast(str, split) {
346
+ const i = str.lastIndexOf(split);
347
+ return i === -1 ? [str, ''] : [str.slice(0, i), str.slice(i + 1)];
77
348
  }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The selection band of a rubberband drag, with its bp coordinates at the edges
3
+ * and an optional size in the middle. Callers format their own text, since a
4
+ * single view reads one coordinate per edge and the multi-level rubberband reads
5
+ * one per level.
6
+ */
7
+ export default function RubberbandSpan({ left, width, viewWidth, stickyTop, leftLabel, rightLabel, size, }: {
8
+ left: number;
9
+ width: number;
10
+ viewWidth: number;
11
+ stickyTop: string | undefined;
12
+ leftLabel: React.ReactNode;
13
+ rightLabel: React.ReactNode;
14
+ size?: React.ReactNode;
15
+ }): import("react").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
3
+ import { Typography, alpha } from '@mui/material';
4
+ import { LABEL_WIDTH, SpanEdgeLabels } from './coordLabels.js';
5
+ const useStyles = makeStyles()(theme => ({
6
+ rubberband: {
7
+ height: '100%',
8
+ background: alpha(theme.palette.tertiary.light, 0.7),
9
+ position: 'absolute',
10
+ left: 0,
11
+ zIndex: 830,
12
+ textAlign: 'center',
13
+ cursor: 'crosshair',
14
+ },
15
+ rubberbandText: {
16
+ color: theme.palette.tertiary.contrastText,
17
+ },
18
+ }));
19
+ /**
20
+ * The selection band of a rubberband drag, with its bp coordinates at the edges
21
+ * and an optional size in the middle. Callers format their own text, since a
22
+ * single view reads one coordinate per edge and the multi-level rubberband reads
23
+ * one per level.
24
+ */
25
+ export default function RubberbandSpan({ left, width, viewWidth, stickyTop, leftLabel, rightLabel, size, }) {
26
+ const { classes } = useStyles();
27
+ // a label only moves inside its edge when the span can hold it, so a sliver of
28
+ // a selection at a view border keeps both labels outside and takes the clip
29
+ const fitsInside = width > LABEL_WIDTH;
30
+ return (_jsxs("div", { className: classes.rubberband, style: { transform: `translateX(${left}px)`, width }, children: [_jsx(SpanEdgeLabels, { stickyTop: stickyTop, left: leftLabel, right: rightLabel, insideLeft: fitsInside && left < LABEL_WIDTH, insideRight: fitsInside && left + width > viewWidth - LABEL_WIDTH }), size ? (_jsx(Typography, { variant: "h6", className: classes.rubberbandText, style: stickyTop === undefined
31
+ ? undefined
32
+ : { position: 'sticky', top: stickyTop }, children: size })) : null] }));
33
+ }
@@ -0,0 +1,40 @@
1
+ export declare const LABEL_WIDTH = 100;
2
+ /**
3
+ * The bp coordinate under a vertical guide, drawn just above the top of the
4
+ * guide line so it covers neither the line nor the cursor hovering the scalebar
5
+ * the line starts at.
6
+ *
7
+ * A zero-height anchor marks that spot in the flow (`stickyTop` pins it to the
8
+ * scalebar it rides once that scrolls away) but the label itself portals to the
9
+ * body: sitting above the guide means sitting above the top of the tracks
10
+ * container, and that container's `contain: layout` traps its children in a
11
+ * stacking context the sticky LGV header (z-index 850, opaque background)
12
+ * paints over. So the anchor's viewport position is measured and the label
13
+ * placed at fixed coordinates outside it.
14
+ *
15
+ * Deliberately not a MUI Tooltip: it is permanently open and re-renders on
16
+ * every pan frame, and an open popper re-runs its whole modifier chain (~17
17
+ * getBoundingClientRect calls) on every render of its parent, since MUI's
18
+ * `BasePopper` calls `forceUpdate()` from a dep-less effect. Here the anchor is
19
+ * measured once per hover, not per mousemove — only `coordX` changes as the
20
+ * mouse moves, and that needs no measurement.
21
+ */
22
+ export declare function GuideLabel({ coordX, viewWidth, stickyTop, children, }: {
23
+ coordX: number;
24
+ viewWidth: number;
25
+ stickyTop: string | undefined;
26
+ children: React.ReactNode;
27
+ }): import("react").JSX.Element;
28
+ /**
29
+ * The bp coordinates of a rubberband selection, one label just outside each edge
30
+ * of the span. Renders inside the span, so the edges are its own box. A label
31
+ * with no room outside its edge flips inside instead, which is why the span it
32
+ * has to fit in is a prop.
33
+ */
34
+ export declare function SpanEdgeLabels({ stickyTop, left, right, insideLeft, insideRight, }: {
35
+ stickyTop: string | undefined;
36
+ left: React.ReactNode;
37
+ right: React.ReactNode;
38
+ insideLeft: boolean;
39
+ insideRight: boolean;
40
+ }): import("react").JSX.Element;
@@ -0,0 +1,119 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { MUI_TOOLTIP_Z_INDEX } from '@jbrowse/core/ui/zIndexes';
4
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
5
+ import { alpha } from '@mui/material';
6
+ import { createPortal } from 'react-dom';
7
+ // roughly how wide a coordinate label is. the guide clamps itself half of this
8
+ // from either border, and a rubberband label that would hang off a border goes
9
+ // inside its edge instead — the popper's `preventOverflow`, without the popper
10
+ export const LABEL_WIDTH = 100;
11
+ // gap between the bottom of a guide label and the top of the guide it labels
12
+ const LABEL_GAP = 3;
13
+ const useStyles = makeStyles()(theme => ({
14
+ // zero height so it takes no flow space while sticking with the scalebar.
15
+ // sticky positioning makes this a stacking context, so the z-index has to
16
+ // live here rather than on the labels it traps
17
+ anchor: {
18
+ height: 0,
19
+ zIndex: 1002,
20
+ },
21
+ label: {
22
+ background: alpha(theme.palette.grey[700], 0.92),
23
+ color: theme.palette.common.white,
24
+ borderRadius: theme.shape.borderRadius,
25
+ padding: '2px 6px',
26
+ fontSize: theme.typography.pxToRem(11),
27
+ fontWeight: theme.typography.fontWeightMedium,
28
+ lineHeight: 1.2,
29
+ whiteSpace: 'nowrap',
30
+ pointerEvents: 'none',
31
+ },
32
+ spanLabel: {
33
+ position: 'absolute',
34
+ },
35
+ guideLabel: {
36
+ position: 'fixed',
37
+ transform: 'translateX(-50%)',
38
+ zIndex: MUI_TOOLTIP_Z_INDEX,
39
+ },
40
+ leftOfEdge: {
41
+ right: '100%',
42
+ marginRight: 2,
43
+ },
44
+ rightOfEdge: {
45
+ left: '100%',
46
+ marginLeft: 2,
47
+ },
48
+ insideLeftEdge: {
49
+ left: 0,
50
+ },
51
+ insideRightEdge: {
52
+ right: 0,
53
+ },
54
+ }));
55
+ function anchorStyle(stickyTop) {
56
+ return stickyTop === undefined
57
+ ? { position: 'relative' }
58
+ : { position: 'sticky', top: stickyTop };
59
+ }
60
+ /**
61
+ * The bp coordinate under a vertical guide, drawn just above the top of the
62
+ * guide line so it covers neither the line nor the cursor hovering the scalebar
63
+ * the line starts at.
64
+ *
65
+ * A zero-height anchor marks that spot in the flow (`stickyTop` pins it to the
66
+ * scalebar it rides once that scrolls away) but the label itself portals to the
67
+ * body: sitting above the guide means sitting above the top of the tracks
68
+ * container, and that container's `contain: layout` traps its children in a
69
+ * stacking context the sticky LGV header (z-index 850, opaque background)
70
+ * paints over. So the anchor's viewport position is measured and the label
71
+ * placed at fixed coordinates outside it.
72
+ *
73
+ * Deliberately not a MUI Tooltip: it is permanently open and re-renders on
74
+ * every pan frame, and an open popper re-runs its whole modifier chain (~17
75
+ * getBoundingClientRect calls) on every render of its parent, since MUI's
76
+ * `BasePopper` calls `forceUpdate()` from a dep-less effect. Here the anchor is
77
+ * measured once per hover, not per mousemove — only `coordX` changes as the
78
+ * mouse moves, and that needs no measurement.
79
+ */
80
+ export function GuideLabel({ coordX, viewWidth, stickyTop, children, }) {
81
+ const { classes, cx } = useStyles();
82
+ const anchorRef = useRef(null);
83
+ const [anchorPos, setAnchorPos] = useState();
84
+ useEffect(() => {
85
+ const measure = () => {
86
+ const el = anchorRef.current;
87
+ if (el) {
88
+ const { left, top } = el.getBoundingClientRect();
89
+ setAnchorPos({ left, top, viewportHeight: window.innerHeight });
90
+ }
91
+ };
92
+ measure();
93
+ // capture phase: the anchor can ride any scrolling ancestor, not just the
94
+ // window
95
+ window.addEventListener('scroll', measure, true);
96
+ window.addEventListener('resize', measure);
97
+ return () => {
98
+ window.removeEventListener('scroll', measure, true);
99
+ window.removeEventListener('resize', measure);
100
+ };
101
+ }, [stickyTop]);
102
+ const clampedX = Math.min(Math.max(coordX, LABEL_WIDTH / 2), viewWidth - LABEL_WIDTH / 2);
103
+ return (_jsxs(_Fragment, { children: [_jsx("div", { ref: anchorRef, className: classes.anchor, style: anchorStyle(stickyTop) }), anchorPos
104
+ ? createPortal(_jsx("div", { className: cx(classes.label, classes.guideLabel), style: {
105
+ left: anchorPos.left + clampedX,
106
+ bottom: anchorPos.viewportHeight - anchorPos.top + LABEL_GAP,
107
+ }, children: children }), document.body)
108
+ : null] }));
109
+ }
110
+ /**
111
+ * The bp coordinates of a rubberband selection, one label just outside each edge
112
+ * of the span. Renders inside the span, so the edges are its own box. A label
113
+ * with no room outside its edge flips inside instead, which is why the span it
114
+ * has to fit in is a prop.
115
+ */
116
+ export function SpanEdgeLabels({ stickyTop, left, right, insideLeft, insideRight, }) {
117
+ const { classes, cx } = useStyles();
118
+ return (_jsxs("div", { className: classes.anchor, style: anchorStyle(stickyTop), children: [_jsx("div", { className: cx(classes.label, classes.spanLabel, insideLeft ? classes.insideLeftEdge : classes.leftOfEdge), children: left }), _jsx("div", { className: cx(classes.label, classes.spanLabel, insideRight ? classes.insideRightEdge : classes.rightOfEdge), children: right })] }));
119
+ }