@jbrowse/plugin-linear-genome-view 1.5.9 → 1.6.0

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 (28) hide show
  1. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.d.ts +35 -17
  2. package/dist/LinearBareDisplay/model.d.ts +28 -4
  3. package/dist/LinearBasicDisplay/model.d.ts +28 -4
  4. package/dist/LinearGenomeView/components/Header.d.ts +2 -1
  5. package/dist/LinearGenomeView/components/RefNameAutocomplete.d.ts +2 -1
  6. package/dist/LinearGenomeView/components/ScaleBar.d.ts +8 -8
  7. package/dist/LinearGenomeView/components/SearchBox.d.ts +8 -0
  8. package/dist/LinearGenomeView/index.d.ts +7 -4
  9. package/dist/index.d.ts +85 -14
  10. package/dist/plugin-linear-genome-view.cjs.development.js +738 -389
  11. package/dist/plugin-linear-genome-view.cjs.development.js.map +1 -1
  12. package/dist/plugin-linear-genome-view.cjs.production.min.js +1 -1
  13. package/dist/plugin-linear-genome-view.cjs.production.min.js.map +1 -1
  14. package/dist/plugin-linear-genome-view.esm.js +749 -401
  15. package/dist/plugin-linear-genome-view.esm.js.map +1 -1
  16. package/package.json +2 -2
  17. package/src/BaseLinearDisplay/models/BaseLinearDisplayModel.tsx +308 -88
  18. package/src/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.ts +10 -3
  19. package/src/LinearBasicDisplay/configSchema.ts +0 -6
  20. package/src/LinearGenomeView/components/Header.tsx +38 -120
  21. package/src/LinearGenomeView/components/ImportForm.tsx +1 -1
  22. package/src/LinearGenomeView/components/LinearGenomeView.test.js +6 -4
  23. package/src/LinearGenomeView/components/RefNameAutocomplete.tsx +9 -5
  24. package/src/LinearGenomeView/components/SearchBox.tsx +111 -0
  25. package/src/LinearGenomeView/components/TrackLabel.tsx +10 -6
  26. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +10 -11
  27. package/src/LinearGenomeView/index.tsx +25 -53
  28. package/src/index.ts +61 -2
@@ -1,28 +1,28 @@
1
1
  import React, { useRef, useState, useMemo, useEffect, Suspense, lazy } from 'react';
2
+ import { autorun, when, transaction } from 'mobx';
2
3
  import { ConfigurationSchema, getConf, readConfObject, ConfigurationReference as ConfigurationReference$1 } from '@jbrowse/core/configuration';
3
4
  import { BaseDisplay, BaseViewModel, createBaseTrackConfig, createBaseTrackModel } from '@jbrowse/core/pluggableElementTypes/models';
4
5
  import TrackType from '@jbrowse/core/pluggableElementTypes/TrackType';
5
6
  import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType';
6
7
  import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType';
7
8
  import Plugin from '@jbrowse/core/Plugin';
8
- import { getContainingView, getContainingDisplay, makeAbortableReaction, assembleLocString, getSession, isSessionModelWithWidgets, isSelectionContainer, stringify, useDebounce, measureText, useDebouncedCallback, clamp, isViewContainer, parseLocString, findLastIndex, springAnimate, isAbstractMenuManager } from '@jbrowse/core/util';
9
+ import { getContainingView, getContainingDisplay, makeAbortableReaction, assembleLocString, getSession, isSessionModelWithWidgets, isSelectionContainer, isAbortException, stringify, useDebounce, measureText, useDebouncedCallback, viewBpToPx, clamp, isViewContainer, parseLocString, findLastIndex, springAnimate, isAbstractMenuManager } from '@jbrowse/core/util';
9
10
  import LineStyleIcon from '@material-ui/icons/LineStyle';
11
+ import { useTheme, makeStyles as makeStyles$1, alpha, Portal, Typography as Typography$1, Button as Button$1, Popover, Tooltip as Tooltip$1, TextField, Popper, CircularProgress, InputAdornment, IconButton, Dialog, DialogTitle, DialogContent, FormControlLabel, Checkbox, DialogActions, Divider, FormGroup, Paper, Container, Grid, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from '@material-ui/core';
10
12
  import CompositeMap from '@jbrowse/core/util/compositeMap';
11
13
  import { isFeature } from '@jbrowse/core/util/simpleFeature';
12
14
  import { getParentRenderProps, getTrackAssemblyNames, getRpcSessionId } from '@jbrowse/core/util/tracks';
13
- import Button from '@material-ui/core/Button';
14
- import Typography from '@material-ui/core/Typography';
15
- import MenuOpenIcon from '@material-ui/icons/MenuOpen';
16
- import { autorun, when, transaction } from 'mobx';
17
15
  import { getParent, types, cast, isAlive, addDisposer, getEnv, resolveIdentifier, getRoot, getSnapshot } from 'mobx-state-tree';
18
- import { useTheme, makeStyles as makeStyles$1, alpha, Portal, Popover, Typography as Typography$1, Tooltip as Tooltip$1, TextField, Popper, CircularProgress, InputAdornment, IconButton, Dialog, DialogTitle, DialogContent, FormControlLabel, Checkbox, DialogActions, Button as Button$1, Divider, FormGroup, Container, Grid, TableContainer, Paper as Paper$1, Table, TableHead, TableRow, TableCell, TableBody } from '@material-ui/core';
16
+ import MenuOpenIcon from '@material-ui/icons/MenuOpen';
19
17
  import { Menu, ResizeHandle } from '@jbrowse/core/ui';
20
18
  import { observer, PropTypes } from 'mobx-react';
21
19
  import { usePopper } from 'react-popper';
22
- import { makeStyles, alpha as alpha$1 } from '@material-ui/core/styles';
20
+ import { makeStyles } from '@material-ui/core/styles';
23
21
  import { ContentBlock as ContentBlock$1, ElidedBlock as ElidedBlock$1, InterRegionPaddingBlock as InterRegionPaddingBlock$1 } from '@jbrowse/core/util/blockTypes';
24
22
  import { Region, ElementId } from '@jbrowse/core/util/types/mst';
25
23
  import { isRetryException } from '@jbrowse/core/util/types';
24
+ import Typography from '@material-ui/core/Typography';
25
+ import Button from '@material-ui/core/Button';
26
26
  import RefreshIcon from '@material-ui/icons/Refresh';
27
27
  import { ConfigurationReference } from '@jbrowse/core/configuration/configurationSchema';
28
28
  import calculateDynamicBlocks from '@jbrowse/core/util/calculateDynamicBlocks';
@@ -50,15 +50,15 @@ import ArrowBackIcon from '@material-ui/icons/ArrowBack';
50
50
  import IconButton$1 from '@material-ui/core/IconButton';
51
51
  import Slider from '@material-ui/core/Slider';
52
52
  import ZoomOut from '@material-ui/icons/ZoomOut';
53
- import Paper from '@material-ui/core/Paper';
53
+ import Paper$1 from '@material-ui/core/Paper';
54
54
  import MoreVertIcon from '@material-ui/icons/MoreVert';
55
55
  import DragIcon from '@material-ui/icons/DragIndicator';
56
56
  import normalizeWheel from 'normalize-wheel';
57
- import { alpha as alpha$2 } from '@material-ui/core/styles/colorManipulator';
57
+ import { alpha as alpha$1 } from '@material-ui/core/styles/colorManipulator';
58
58
  import Popover$1 from '@material-ui/core/Popover';
59
59
  import Tooltip$2 from '@material-ui/core/Tooltip';
60
- import AssemblySelector from '@jbrowse/core/ui/AssemblySelector';
61
60
  import ErrorMessage from '@jbrowse/core/ui/ErrorMessage';
61
+ import AssemblySelector from '@jbrowse/core/ui/AssemblySelector';
62
62
  import ArrowDown from '@material-ui/icons/KeyboardArrowDown';
63
63
  import Menu$1 from '@jbrowse/core/ui/Menu';
64
64
  import copy from 'copy-to-clipboard';
@@ -182,14 +182,14 @@ function _inherits(subClass, superClass) {
182
182
  throw new TypeError("Super expression must either be null or a function");
183
183
  }
184
184
 
185
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
186
+ constructor: {
187
+ value: subClass,
188
+ writable: true,
189
+ configurable: true
190
+ }
191
+ });
185
192
  Object.defineProperty(subClass, "prototype", {
186
- value: Object.create(superClass && superClass.prototype, {
187
- constructor: {
188
- value: subClass,
189
- writable: true,
190
- configurable: true
191
- }
192
- }),
193
193
  writable: false
194
194
  });
195
195
  if (superClass) _setPrototypeOf(subClass, superClass);
@@ -429,16 +429,6 @@ function _createForOfIteratorHelper(o, allowArrayLike) {
429
429
  };
430
430
  }
431
431
 
432
- var baseLinearDisplayConfigSchema = /*#__PURE__*/ConfigurationSchema('BaseLinearDisplay', {
433
- maxDisplayedBpPerPx: {
434
- type: 'number',
435
- description: 'maximum bpPerPx that is displayed in the view',
436
- defaultValue: Number.MAX_VALUE
437
- }
438
- }, {
439
- explicitIdentifier: 'displayId'
440
- });
441
-
442
432
  function createCommonjsModule(fn, module) {
443
433
  return module = { exports: {} }, fn(module, module.exports), module.exports;
444
434
  }
@@ -1168,6 +1158,21 @@ var runtime_1 = /*#__PURE__*/createCommonjsModule(function (module) {
1168
1158
  }
1169
1159
  });
1170
1160
 
1161
+ var baseLinearDisplayConfigSchema = /*#__PURE__*/ConfigurationSchema('BaseLinearDisplay', {
1162
+ maxFeatureScreenDensity: {
1163
+ type: 'number',
1164
+ description: 'maximum features per pixel that is displayed in the view, used if byte size estimates not available',
1165
+ defaultValue: 0.3
1166
+ },
1167
+ fetchSizeLimit: {
1168
+ type: 'number',
1169
+ defaultValue: 1000000,
1170
+ description: "maximum data to attempt to download for a given track, used if adapter doesn't specify one"
1171
+ }
1172
+ }, {
1173
+ explicitIdentifier: 'displayId'
1174
+ });
1175
+
1171
1176
  var useStyles = /*#__PURE__*/makeStyles(function (theme) {
1172
1177
  return {
1173
1178
  contentBlock: {
@@ -1952,6 +1957,26 @@ function _renderBlockEffect() {
1952
1957
  }
1953
1958
 
1954
1959
  var _excluded = ["blockState"];
1960
+
1961
+ function getId(id, index) {
1962
+ var isJest = typeof jest === 'undefined';
1963
+ return "clip-".concat(isJest ? id : 'jest', "-").concat(index);
1964
+ }
1965
+
1966
+ function getDisplayStr(totalBytes) {
1967
+ var displayBp;
1968
+
1969
+ if (Math.floor(totalBytes / 1000000) > 0) {
1970
+ displayBp = "".concat(parseFloat((totalBytes / 1000000).toPrecision(3)), " Mb");
1971
+ } else if (Math.floor(totalBytes / 1000) > 0) {
1972
+ displayBp = "".concat(parseFloat((totalBytes / 1000).toPrecision(3)), " Kb");
1973
+ } else {
1974
+ displayBp = "".concat(Math.floor(totalBytes), " bytes");
1975
+ }
1976
+
1977
+ return displayBp;
1978
+ }
1979
+
1955
1980
  var minDisplayHeight = 20;
1956
1981
  var defaultDisplayHeight = 100;
1957
1982
  var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDisplay, types.model({
@@ -1959,13 +1984,17 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
1959
1984
  return n >= minDisplayHeight;
1960
1985
  }), defaultDisplayHeight),
1961
1986
  blockState: types.map(blockState),
1962
- userBpPerPxLimit: types.maybe(types.number)
1987
+ userBpPerPxLimit: types.maybe(types.number),
1988
+ userByteSizeLimit: types.maybe(types.number)
1963
1989
  }))["volatile"](function () {
1964
1990
  return {
1991
+ currBpPerPx: 0,
1965
1992
  message: '',
1966
1993
  featureIdUnderMouse: undefined,
1967
1994
  contextMenuFeature: undefined,
1968
- scrollTop: 0
1995
+ scrollTop: 0,
1996
+ estimatedRegionStatsP: undefined,
1997
+ estimatedRegionStats: undefined
1969
1998
  };
1970
1999
  }).views(function (self) {
1971
2000
  return {
@@ -1987,13 +2016,6 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
1987
2016
  };
1988
2017
  }).views(function (self) {
1989
2018
  return {
1990
- /**
1991
- * set limit to config amount, or user amount if they force load,
1992
- */
1993
- get maxViewBpPerPx() {
1994
- return self.userBpPerPxLimit || getConf(self, 'maxDisplayedBpPerPx');
1995
- },
1996
-
1997
2019
  /**
1998
2020
  * how many milliseconds to wait for the display to
1999
2021
  * "settle" before re-rendering a block
@@ -2063,7 +2085,8 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2063
2085
  },
2064
2086
 
2065
2087
  get featureUnderMouse() {
2066
- return self.featureIdUnderMouse ? this.features.get(self.featureIdUnderMouse) : undefined;
2088
+ var feat = self.featureIdUnderMouse;
2089
+ return feat ? this.features.get(feat) : undefined;
2067
2090
  },
2068
2091
 
2069
2092
  getFeatureOverlapping: function getFeatureOverlapping(blockKey, x, y) {
@@ -2089,16 +2112,49 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2089
2112
  }
2090
2113
  });
2091
2114
  return ret;
2115
+ },
2116
+
2117
+ get currentBytesRequested() {
2118
+ var _self$estimatedRegion;
2119
+
2120
+ return ((_self$estimatedRegion = self.estimatedRegionStats) === null || _self$estimatedRegion === void 0 ? void 0 : _self$estimatedRegion.bytes) || 0;
2121
+ },
2122
+
2123
+ get currentFeatureScreenDensity() {
2124
+ var _self$estimatedRegion2;
2125
+
2126
+ var view = getContainingView(self);
2127
+ return (((_self$estimatedRegion2 = self.estimatedRegionStats) === null || _self$estimatedRegion2 === void 0 ? void 0 : _self$estimatedRegion2.featureDensity) || 0) * view.bpPerPx;
2128
+ },
2129
+
2130
+ get maxFeatureScreenDensity() {
2131
+ return getConf(self, 'maxFeatureScreenDensity');
2132
+ },
2133
+
2134
+ get estimatedStatsReady() {
2135
+ return !!self.estimatedRegionStats;
2136
+ },
2137
+
2138
+ get maxAllowableBytes() {
2139
+ var _self$estimatedRegion3;
2140
+
2141
+ return self.userByteSizeLimit || ((_self$estimatedRegion3 = self.estimatedRegionStats) === null || _self$estimatedRegion3 === void 0 ? void 0 : _self$estimatedRegion3.fetchSizeLimit) || getConf(self, 'fetchSizeLimit');
2092
2142
  }
2143
+
2093
2144
  };
2094
2145
  }).actions(function (self) {
2095
2146
  return {
2147
+ // base display reload does nothing, see specialized displays for details
2148
+ setMessage: function setMessage(message) {
2149
+ self.message = message;
2150
+ },
2096
2151
  afterAttach: function afterAttach() {
2097
2152
  var _this = this;
2098
2153
 
2099
- // watch the parent's blocks to update our block state when they change
2154
+ // watch the parent's blocks to update our block state when they change,
2155
+ // then we recreate the blocks on our own model (creating and deleting to
2156
+ // match the parent blocks)
2100
2157
  var blockWatchDisposer = autorun(function () {
2101
- // create any blocks that we need to create
2102
2158
  var blocksPresent = {};
2103
2159
  var view = getContainingView(self);
2104
2160
 
@@ -2109,8 +2165,7 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2109
2165
  if (!self.blockState.has(block.key)) {
2110
2166
  _this.addBlock(block.key, block);
2111
2167
  }
2112
- }); // delete any blocks we need go delete
2113
-
2168
+ });
2114
2169
  self.blockState.forEach(function (_, key) {
2115
2170
  if (!blocksPresent[key]) {
2116
2171
  _this.deleteBlock(key);
@@ -2120,6 +2175,47 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2120
2175
  });
2121
2176
  addDisposer(self, blockWatchDisposer);
2122
2177
  },
2178
+ estimateRegionsStats: function estimateRegionsStats(regions, opts) {
2179
+ var _this2 = this;
2180
+
2181
+ if (self.estimatedRegionStatsP) {
2182
+ return self.estimatedRegionStatsP;
2183
+ }
2184
+
2185
+ var _getSession2 = getSession(self),
2186
+ rpcManager = _getSession2.rpcManager;
2187
+
2188
+ var adapterConfig = self.adapterConfig;
2189
+ var sessionId = getRpcSessionId(self);
2190
+
2191
+ var params = _objectSpread2({
2192
+ sessionId: sessionId,
2193
+ regions: regions,
2194
+ adapterConfig: adapterConfig,
2195
+ statusCallback: function statusCallback(message) {
2196
+ if (isAlive(self)) {
2197
+ _this2.setMessage(message);
2198
+ }
2199
+ }
2200
+ }, opts);
2201
+
2202
+ self.estimatedRegionStatsP = rpcManager.call(sessionId, 'CoreEstimateRegionStats', params)["catch"](function (e) {
2203
+ _this2.setRegionStatsP(undefined);
2204
+
2205
+ throw e;
2206
+ });
2207
+ return self.estimatedRegionStatsP;
2208
+ },
2209
+ setRegionStatsP: function setRegionStatsP(p) {
2210
+ self.estimatedRegionStatsP = p;
2211
+ },
2212
+ setRegionStats: function setRegionStats(estimatedRegionStats) {
2213
+ self.estimatedRegionStats = estimatedRegionStats;
2214
+ },
2215
+ clearRegionStats: function clearRegionStats() {
2216
+ self.estimatedRegionStatsP = undefined;
2217
+ self.estimatedRegionStats = undefined;
2218
+ },
2123
2219
  setHeight: function setHeight(displayHeight) {
2124
2220
  if (displayHeight > minDisplayHeight) {
2125
2221
  self.height = displayHeight;
@@ -2137,13 +2233,14 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2137
2233
  setScrollTop: function setScrollTop(scrollTop) {
2138
2234
  self.scrollTop = scrollTop;
2139
2235
  },
2140
- // sets the new bpPerPxLimit if user chooses to force load
2141
- setUserBpPerPxLimit: function setUserBpPerPxLimit(limit) {
2142
- self.userBpPerPxLimit = limit;
2143
- },
2144
- // base display reload does nothing, see specialized displays for details
2145
- setMessage: function setMessage(message) {
2146
- self.message = message;
2236
+ updateStatsLimit: function updateStatsLimit(stats) {
2237
+ var view = getContainingView(self);
2238
+
2239
+ if (stats.bytes) {
2240
+ self.userByteSizeLimit = stats.bytes;
2241
+ } else {
2242
+ self.userBpPerPxLimit = view.bpPerPx;
2243
+ }
2147
2244
  },
2148
2245
  addBlock: function addBlock(key, block) {
2149
2246
  self.blockState.set(key, blockState.create({
@@ -2151,6 +2248,9 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2151
2248
  region: block.toRegion()
2152
2249
  }));
2153
2250
  },
2251
+ setCurrBpPerPx: function setCurrBpPerPx(n) {
2252
+ self.currBpPerPx = n;
2253
+ },
2154
2254
  deleteBlock: function deleteBlock(key) {
2155
2255
  self.blockState["delete"](key);
2156
2256
  },
@@ -2188,14 +2288,178 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2188
2288
  };
2189
2289
  }).views(function (self) {
2190
2290
  return {
2191
- regionCannotBeRenderedText: function regionCannotBeRenderedText(_region) {
2291
+ // region is too large if:
2292
+ // - stats are ready
2293
+ // - region is greater than 20kb (don't warn when zoomed in less than that)
2294
+ // - and bytes > max allowed bytes || curr density>max density
2295
+ get regionTooLarge() {
2192
2296
  var view = getContainingView(self);
2193
2297
 
2194
- if (view && view.bpPerPx > self.maxViewBpPerPx) {
2195
- return 'Zoom in to see features';
2298
+ if (!self.estimatedStatsReady || view.dynamicBlocks.totalBp < 20000) {
2299
+ return false;
2196
2300
  }
2197
2301
 
2198
- return '';
2302
+ var bpLimitOrDensity = self.userBpPerPxLimit ? view.bpPerPx > self.userBpPerPxLimit : self.currentFeatureScreenDensity > self.maxFeatureScreenDensity;
2303
+ return self.currentBytesRequested > self.maxAllowableBytes || bpLimitOrDensity;
2304
+ },
2305
+
2306
+ // only shows a message of bytes requested is defined, the feature density
2307
+ // based stats don't produce any helpful message besides to zoom in
2308
+ get regionTooLargeReason() {
2309
+ var req = self.currentBytesRequested;
2310
+ var max = self.maxAllowableBytes;
2311
+ return req && req > max ? "Requested too much data (".concat(getDisplayStr(req), ")") : '';
2312
+ }
2313
+
2314
+ };
2315
+ }).actions(function (self) {
2316
+ var superReload = self.reload;
2317
+ return {
2318
+ reload: function reload() {
2319
+ return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
2320
+ var aborter, view, estimatedRegionStats;
2321
+ return runtime_1.wrap(function _callee$(_context) {
2322
+ while (1) {
2323
+ switch (_context.prev = _context.next) {
2324
+ case 0:
2325
+ self.setError();
2326
+ aborter = new AbortController();
2327
+ view = getContainingView(self);
2328
+
2329
+ if (view.initialized) {
2330
+ _context.next = 5;
2331
+ break;
2332
+ }
2333
+
2334
+ return _context.abrupt("return");
2335
+
2336
+ case 5:
2337
+ _context.prev = 5;
2338
+ self.estimatedRegionStatsP = self.estimateRegionsStats(view.staticBlocks.contentBlocks, {
2339
+ signal: aborter.signal
2340
+ });
2341
+ _context.next = 9;
2342
+ return self.estimatedRegionStatsP;
2343
+
2344
+ case 9:
2345
+ estimatedRegionStats = _context.sent;
2346
+
2347
+ if (!isAlive(self)) {
2348
+ _context.next = 15;
2349
+ break;
2350
+ }
2351
+
2352
+ self.setRegionStats(estimatedRegionStats);
2353
+ superReload();
2354
+ _context.next = 16;
2355
+ break;
2356
+
2357
+ case 15:
2358
+ return _context.abrupt("return");
2359
+
2360
+ case 16:
2361
+ _context.next = 21;
2362
+ break;
2363
+
2364
+ case 18:
2365
+ _context.prev = 18;
2366
+ _context.t0 = _context["catch"](5);
2367
+ self.setError(_context.t0);
2368
+
2369
+ case 21:
2370
+ case "end":
2371
+ return _context.stop();
2372
+ }
2373
+ }
2374
+ }, _callee, null, [[5, 18]]);
2375
+ }))();
2376
+ },
2377
+ afterAttach: function afterAttach() {
2378
+ // this autorun performs stats estimation
2379
+ //
2380
+ // the chain of events calls estimateRegionStats against the data
2381
+ // adapter which by default uses featureDensity, but can also respond
2382
+ // with a byte size estimate and fetch size limit (data adapter can
2383
+ // define what is too much data)
2384
+ addDisposer(self, autorun( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2() {
2385
+ var _self$estimatedRegion4, aborter, view, statsP, estimatedRegionStats;
2386
+
2387
+ return runtime_1.wrap(function _callee2$(_context2) {
2388
+ while (1) {
2389
+ switch (_context2.prev = _context2.next) {
2390
+ case 0:
2391
+ _context2.prev = 0;
2392
+ aborter = new AbortController();
2393
+ view = getContainingView(self);
2394
+
2395
+ if (view.initialized) {
2396
+ _context2.next = 5;
2397
+ break;
2398
+ }
2399
+
2400
+ return _context2.abrupt("return");
2401
+
2402
+ case 5:
2403
+ if (!(((_self$estimatedRegion4 = self.estimatedRegionStats) === null || _self$estimatedRegion4 === void 0 ? void 0 : _self$estimatedRegion4.featureDensity) !== undefined)) {
2404
+ _context2.next = 8;
2405
+ break;
2406
+ }
2407
+
2408
+ self.setCurrBpPerPx(view.bpPerPx);
2409
+ return _context2.abrupt("return");
2410
+
2411
+ case 8:
2412
+ if (!(view.bpPerPx === self.currBpPerPx)) {
2413
+ _context2.next = 10;
2414
+ break;
2415
+ }
2416
+
2417
+ return _context2.abrupt("return");
2418
+
2419
+ case 10:
2420
+ self.clearRegionStats();
2421
+ self.setCurrBpPerPx(view.bpPerPx);
2422
+ statsP = self.estimateRegionsStats(view.staticBlocks.contentBlocks, {
2423
+ signal: aborter.signal
2424
+ });
2425
+ self.setRegionStatsP(statsP);
2426
+ _context2.next = 16;
2427
+ return statsP;
2428
+
2429
+ case 16:
2430
+ estimatedRegionStats = _context2.sent;
2431
+
2432
+ if (isAlive(self)) {
2433
+ self.setRegionStats(estimatedRegionStats);
2434
+ }
2435
+
2436
+ _context2.next = 23;
2437
+ break;
2438
+
2439
+ case 20:
2440
+ _context2.prev = 20;
2441
+ _context2.t0 = _context2["catch"](0);
2442
+
2443
+ if (!isAbortException(_context2.t0) && isAlive(self)) {
2444
+ console.error(_context2.t0);
2445
+ self.setError(_context2.t0);
2446
+ }
2447
+
2448
+ case 23:
2449
+ case "end":
2450
+ return _context2.stop();
2451
+ }
2452
+ }
2453
+ }, _callee2, null, [[0, 20]]);
2454
+ })), {
2455
+ delay: 500
2456
+ }));
2457
+ }
2458
+ };
2459
+ }).views(function (self) {
2460
+ return {
2461
+ regionCannotBeRenderedText: function regionCannotBeRenderedText(_region) {
2462
+ return self.regionTooLarge ? 'Force load to see features' : '';
2199
2463
  },
2200
2464
 
2201
2465
  /**
@@ -2206,20 +2470,25 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2206
2470
  * react node allows user to force load at current setting
2207
2471
  */
2208
2472
  regionCannotBeRendered: function regionCannotBeRendered(_region) {
2209
- var view = getContainingView(self);
2473
+ var regionTooLarge = self.regionTooLarge,
2474
+ regionTooLargeReason = self.regionTooLargeReason;
2210
2475
 
2211
- if (view && view.bpPerPx > self.maxViewBpPerPx) {
2212
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography, {
2476
+ if (regionTooLarge) {
2477
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography$1, {
2213
2478
  component: "span",
2214
2479
  variant: "body2"
2215
- }, "Zoom in to see features or", ' '), /*#__PURE__*/React.createElement(Button, {
2216
- "data-testid": "reload_button",
2480
+ }, regionTooLargeReason ? regionTooLargeReason + '. ' : '', "Zoom in to see features or", ' '), /*#__PURE__*/React.createElement(Button$1, {
2481
+ "data-testid": "force_reload_button",
2217
2482
  onClick: function onClick() {
2218
- self.setUserBpPerPxLimit(view.bpPerPx);
2219
- self.reload();
2483
+ if (!self.estimatedRegionStats) {
2484
+ console.error('No global stats?');
2485
+ } else {
2486
+ self.updateStatsLimit(self.estimatedRegionStats);
2487
+ self.reload();
2488
+ }
2220
2489
  },
2221
2490
  variant: "outlined"
2222
- }, "Force Load"), /*#__PURE__*/React.createElement(Typography, {
2491
+ }, "Force Load"), /*#__PURE__*/React.createElement(Typography$1, {
2223
2492
  component: "span",
2224
2493
  variant: "body2"
2225
2494
  }, "(force load may be slow)"));
@@ -2242,7 +2511,9 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2242
2511
  }] : [];
2243
2512
  },
2244
2513
  renderProps: function renderProps() {
2514
+ var view = getContainingView(self);
2245
2515
  return _objectSpread2(_objectSpread2({}, getParentRenderProps(self)), {}, {
2516
+ notReady: self.currBpPerPx !== view.bpPerPx || !self.estimatedRegionStats,
2246
2517
  rpcDriverName: self.rpcDriverName,
2247
2518
  displayModel: self,
2248
2519
  onFeatureClick: function onFeatureClick(_, featureId) {
@@ -2252,7 +2523,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2252
2523
  self.clearFeatureSelection();
2253
2524
  } else {
2254
2525
  var feature = self.features.get(f);
2255
- self.selectFeature(feature);
2526
+
2527
+ if (feature) {
2528
+ self.selectFeature(feature);
2529
+ }
2256
2530
  }
2257
2531
  },
2258
2532
  onClick: function onClick() {
@@ -2285,18 +2559,18 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2285
2559
  }).actions(function (self) {
2286
2560
  return {
2287
2561
  renderSvg: function renderSvg(opts) {
2288
- return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
2289
- var height, id, overrideHeight, view, viewOffsetPx, dynamicBlocks, width, renderings;
2290
- return runtime_1.wrap(function _callee$(_context) {
2562
+ return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3() {
2563
+ var height, id, overrideHeight, view, viewOffsetPx, roundedDynamicBlocks, width, renderings;
2564
+ return runtime_1.wrap(function _callee3$(_context3) {
2291
2565
  while (1) {
2292
- switch (_context.prev = _context.next) {
2566
+ switch (_context3.prev = _context3.next) {
2293
2567
  case 0:
2294
2568
  height = self.height, id = self.id;
2295
2569
  overrideHeight = opts.overrideHeight;
2296
2570
  view = getContainingView(self);
2297
- viewOffsetPx = view.offsetPx, dynamicBlocks = view.roundedDynamicBlocks, width = view.width;
2298
- _context.next = 6;
2299
- return Promise.all(dynamicBlocks.map(function (block) {
2571
+ viewOffsetPx = view.offsetPx, roundedDynamicBlocks = view.roundedDynamicBlocks, width = view.width;
2572
+ _context3.next = 6;
2573
+ return Promise.all(roundedDynamicBlocks.map(function (block) {
2300
2574
  var blockState$1 = blockState.create({
2301
2575
  key: block.key,
2302
2576
  region: block
@@ -2334,13 +2608,11 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2334
2608
  }));
2335
2609
 
2336
2610
  case 6:
2337
- renderings = _context.sent;
2338
- return _context.abrupt("return", /*#__PURE__*/React.createElement(React.Fragment, null, renderings.map(function (rendering, index) {
2339
- var offsetPx = dynamicBlocks[index].offsetPx;
2340
- var offset = offsetPx - viewOffsetPx; // stabalize clipid under test for snapshot
2341
-
2342
- // stabalize clipid under test for snapshot
2343
- var clipid = "clip-".concat(typeof jest === 'undefined' ? id : 'jest', "-").concat(index);
2611
+ renderings = _context3.sent;
2612
+ return _context3.abrupt("return", /*#__PURE__*/React.createElement(React.Fragment, null, renderings.map(function (rendering, index) {
2613
+ var offsetPx = roundedDynamicBlocks[index].offsetPx;
2614
+ var offset = offsetPx - viewOffsetPx;
2615
+ var clipid = getId(id, index);
2344
2616
  return /*#__PURE__*/React.createElement(React.Fragment, {
2345
2617
  key: "frag-".concat(index)
2346
2618
  }, /*#__PURE__*/React.createElement("defs", null, /*#__PURE__*/React.createElement("clipPath", {
@@ -2354,7 +2626,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2354
2626
  transform: "translate(".concat(offset, " 0)")
2355
2627
  }, /*#__PURE__*/React.createElement("g", {
2356
2628
  clipPath: "url(#".concat(clipid, ")")
2357
- }, /*#__PURE__*/React.isValidElement(rendering.reactElement) ? rendering.reactElement : /*#__PURE__*/React.createElement("g", {
2629
+ }, /*#__PURE__*/React.isValidElement(rendering.reactElement) ? rendering.reactElement :
2630
+ /*#__PURE__*/
2631
+ // eslint-disable-next-line react/no-danger
2632
+ React.createElement("g", {
2358
2633
  dangerouslySetInnerHTML: {
2359
2634
  __html: rendering.html
2360
2635
  }
@@ -2363,10 +2638,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/types.compose('BaseLinearDisplay', BaseDi
2363
2638
 
2364
2639
  case 8:
2365
2640
  case "end":
2366
- return _context.stop();
2641
+ return _context3.stop();
2367
2642
  }
2368
2643
  }
2369
- }, _callee);
2644
+ }, _callee3);
2370
2645
  }))();
2371
2646
  }
2372
2647
  };
@@ -3564,6 +3839,8 @@ var MyPopper = function MyPopper(props) {
3564
3839
 
3565
3840
  function RefNameAutocomplete(_ref) {
3566
3841
  var model = _ref.model,
3842
+ _ref$showHelp = _ref.showHelp,
3843
+ showHelp = _ref$showHelp === void 0 ? true : _ref$showHelp,
3567
3844
  onSelect = _ref.onSelect,
3568
3845
  assemblyName = _ref.assemblyName,
3569
3846
  style = _ref.style,
@@ -3774,11 +4051,11 @@ function RefNameAutocomplete(_ref) {
3774
4051
  style: {
3775
4052
  marginRight: 7
3776
4053
  }
3777
- }, /*#__PURE__*/React.createElement(SearchIcon, null), /*#__PURE__*/React.createElement(IconButton, {
4054
+ }, /*#__PURE__*/React.createElement(SearchIcon, null), showHelp ? /*#__PURE__*/React.createElement(IconButton, {
3778
4055
  onClick: function onClick() {
3779
4056
  return setHelpDialogDisplayed(true);
3780
4057
  }
3781
- }, /*#__PURE__*/React.createElement(HelpIcon, null))), params.InputProps.endAdornment)
4058
+ }, /*#__PURE__*/React.createElement(HelpIcon, null)) : null), params.InputProps.endAdornment)
3782
4059
  }),
3783
4060
  placeholder: "Search for location",
3784
4061
  onChange: function onChange(e) {
@@ -3812,67 +4089,235 @@ function RefNameAutocomplete(_ref) {
3812
4089
 
3813
4090
  var RefNameAutocomplete$1 = /*#__PURE__*/observer(RefNameAutocomplete);
3814
4091
 
3815
- var useStyles$7 = /*#__PURE__*/makeStyles(function (theme) {
4092
+ var useStyles$7 = /*#__PURE__*/makeStyles$1(function () {
3816
4093
  return {
3817
- closeButton: {
3818
- position: 'absolute',
3819
- right: theme.spacing(1),
3820
- top: theme.spacing(1),
3821
- color: theme.palette.grey[500]
4094
+ headerRefName: {
4095
+ minWidth: 100
3822
4096
  }
3823
4097
  };
3824
4098
  });
3825
- function ExportSvgDlg(_ref) {
4099
+
4100
+ function SearchBox(_ref) {
3826
4101
  var model = _ref.model,
3827
- handleClose = _ref.handleClose;
3828
- // @ts-ignore
3829
- var offscreenCanvas = typeof OffscreenCanvas !== 'undefined';
4102
+ showHelp = _ref.showHelp;
4103
+ var classes = useStyles$7();
4104
+ var theme = useTheme();
4105
+ var session = getSession(model);
4106
+ var textSearchManager = session.textSearchManager,
4107
+ assemblyManager = session.assemblyManager;
4108
+ var assemblyNames = model.assemblyNames,
4109
+ rankSearchResults = model.rankSearchResults;
4110
+ var assemblyName = assemblyNames[0];
4111
+ var assembly = assemblyManager.get(assemblyName);
4112
+ var searchScope = model.searchScope(assemblyName);
3830
4113
 
3831
- var _useState = useState(offscreenCanvas),
3832
- _useState2 = _slicedToArray(_useState, 2),
3833
- rasterizeLayers = _useState2[0],
3834
- setRasterizeLayers = _useState2[1];
4114
+ function fetchResults(_x, _x2) {
4115
+ return _fetchResults.apply(this, arguments);
4116
+ }
3835
4117
 
3836
- var _useState3 = useState(false),
3837
- _useState4 = _slicedToArray(_useState3, 2),
3838
- loading = _useState4[0],
3839
- setLoading = _useState4[1];
4118
+ function _fetchResults() {
4119
+ _fetchResults = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(query, searchType) {
4120
+ var _assembly$allRefNames;
3840
4121
 
3841
- var _useState5 = useState(),
3842
- _useState6 = _slicedToArray(_useState5, 2),
3843
- error = _useState6[0],
3844
- setError = _useState6[1];
4122
+ var textSearchResults, refNameResults;
4123
+ return runtime_1.wrap(function _callee$(_context) {
4124
+ while (1) {
4125
+ switch (_context.prev = _context.next) {
4126
+ case 0:
4127
+ if (!textSearchManager) {
4128
+ console.warn('No text search manager');
4129
+ }
3845
4130
 
3846
- var classes = useStyles$7();
3847
- return /*#__PURE__*/React.createElement(Dialog, {
3848
- open: true,
3849
- onClose: handleClose
3850
- }, /*#__PURE__*/React.createElement(DialogTitle, null, "Export SVG", /*#__PURE__*/React.createElement(IconButton, {
3851
- className: classes.closeButton,
3852
- onClick: handleClose
3853
- }, /*#__PURE__*/React.createElement(CloseIcon, null))), /*#__PURE__*/React.createElement(DialogContent, null, error ? /*#__PURE__*/React.createElement("div", {
3854
- style: {
3855
- color: 'red'
3856
- }
3857
- }, "".concat(error)) : loading ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(CircularProgress, {
3858
- size: 20,
3859
- style: {
3860
- marginRight: 20
3861
- }
3862
- }), /*#__PURE__*/React.createElement(Typography$1, {
3863
- display: "inline"
3864
- }, "Creating SVG")) : null, offscreenCanvas ? /*#__PURE__*/React.createElement(FormControlLabel, {
3865
- control: /*#__PURE__*/React.createElement(Checkbox, {
3866
- checked: rasterizeLayers,
3867
- onChange: function onChange() {
3868
- return setRasterizeLayers(function (val) {
3869
- return !val;
3870
- });
3871
- }
3872
- }),
3873
- label: "Rasterize canvas based tracks? File may be much larger if this is turned off"
3874
- }) : /*#__PURE__*/React.createElement(Typography$1, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large")), /*#__PURE__*/React.createElement(DialogActions, null, /*#__PURE__*/React.createElement(Button$1, {
3875
- variant: "contained",
4131
+ _context.next = 3;
4132
+ return textSearchManager === null || textSearchManager === void 0 ? void 0 : textSearchManager.search({
4133
+ queryString: query,
4134
+ searchType: searchType
4135
+ }, searchScope, rankSearchResults);
4136
+
4137
+ case 3:
4138
+ textSearchResults = _context.sent;
4139
+ refNameResults = assembly === null || assembly === void 0 ? void 0 : (_assembly$allRefNames = assembly.allRefNames) === null || _assembly$allRefNames === void 0 ? void 0 : _assembly$allRefNames.filter(function (refName) {
4140
+ return refName.startsWith(query);
4141
+ }).map(function (r) {
4142
+ return new BaseResult({
4143
+ label: r
4144
+ });
4145
+ }).slice(0, 10);
4146
+ return _context.abrupt("return", dedupe([].concat(_toConsumableArray(refNameResults || []), _toConsumableArray(textSearchResults || [])), function (elt) {
4147
+ return elt.getId();
4148
+ }));
4149
+
4150
+ case 6:
4151
+ case "end":
4152
+ return _context.stop();
4153
+ }
4154
+ }
4155
+ }, _callee);
4156
+ }));
4157
+ return _fetchResults.apply(this, arguments);
4158
+ }
4159
+
4160
+ function handleSelectedRegion(_x3) {
4161
+ return _handleSelectedRegion.apply(this, arguments);
4162
+ }
4163
+
4164
+ function _handleSelectedRegion() {
4165
+ _handleSelectedRegion = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(option) {
4166
+ var trackId, location, label, _assembly$allRefNames2, results;
4167
+
4168
+ return runtime_1.wrap(function _callee2$(_context2) {
4169
+ while (1) {
4170
+ switch (_context2.prev = _context2.next) {
4171
+ case 0:
4172
+ trackId = option.getTrackId();
4173
+ location = option.getLocation();
4174
+ label = option.getLabel();
4175
+ _context2.prev = 3;
4176
+
4177
+ if (!(assembly !== null && assembly !== void 0 && (_assembly$allRefNames2 = assembly.allRefNames) !== null && _assembly$allRefNames2 !== void 0 && _assembly$allRefNames2.includes(location))) {
4178
+ _context2.next = 8;
4179
+ break;
4180
+ }
4181
+
4182
+ model.navToLocString(location);
4183
+ _context2.next = 19;
4184
+ break;
4185
+
4186
+ case 8:
4187
+ _context2.next = 10;
4188
+ return fetchResults(label, 'exact');
4189
+
4190
+ case 10:
4191
+ results = _context2.sent;
4192
+
4193
+ if (!(results && results.length > 1)) {
4194
+ _context2.next = 16;
4195
+ break;
4196
+ }
4197
+
4198
+ model.setSearchResults(results, label.toLowerCase());
4199
+ return _context2.abrupt("return");
4200
+
4201
+ case 16:
4202
+ if ((results === null || results === void 0 ? void 0 : results.length) === 1) {
4203
+ location = results[0].getLocation();
4204
+ trackId = results[0].getTrackId();
4205
+ }
4206
+
4207
+ case 17:
4208
+ model.navToLocString(location, assemblyName);
4209
+
4210
+ if (trackId) {
4211
+ model.showTrack(trackId);
4212
+ }
4213
+
4214
+ case 19:
4215
+ _context2.next = 25;
4216
+ break;
4217
+
4218
+ case 21:
4219
+ _context2.prev = 21;
4220
+ _context2.t0 = _context2["catch"](3);
4221
+ console.error(_context2.t0);
4222
+ session.notify("".concat(_context2.t0), 'warning');
4223
+
4224
+ case 25:
4225
+ case "end":
4226
+ return _context2.stop();
4227
+ }
4228
+ }
4229
+ }, _callee2, null, [[3, 21]]);
4230
+ }));
4231
+ return _handleSelectedRegion.apply(this, arguments);
4232
+ }
4233
+
4234
+ return /*#__PURE__*/React.createElement(RefNameAutocomplete$1, {
4235
+ showHelp: showHelp,
4236
+ onSelect: handleSelectedRegion,
4237
+ assemblyName: assemblyName,
4238
+ fetchResults: fetchResults,
4239
+ model: model,
4240
+ TextFieldProps: {
4241
+ variant: 'outlined',
4242
+ className: classes.headerRefName,
4243
+ style: {
4244
+ margin: SPACING,
4245
+ minWidth: '175px'
4246
+ },
4247
+ InputProps: {
4248
+ style: {
4249
+ padding: 0,
4250
+ height: WIDGET_HEIGHT,
4251
+ background: alpha(theme.palette.background.paper, 0.8)
4252
+ }
4253
+ }
4254
+ }
4255
+ });
4256
+ }
4257
+
4258
+ var SearchBox$1 = /*#__PURE__*/observer(SearchBox);
4259
+
4260
+ var useStyles$8 = /*#__PURE__*/makeStyles(function (theme) {
4261
+ return {
4262
+ closeButton: {
4263
+ position: 'absolute',
4264
+ right: theme.spacing(1),
4265
+ top: theme.spacing(1),
4266
+ color: theme.palette.grey[500]
4267
+ }
4268
+ };
4269
+ });
4270
+ function ExportSvgDlg(_ref) {
4271
+ var model = _ref.model,
4272
+ handleClose = _ref.handleClose;
4273
+ // @ts-ignore
4274
+ var offscreenCanvas = typeof OffscreenCanvas !== 'undefined';
4275
+
4276
+ var _useState = useState(offscreenCanvas),
4277
+ _useState2 = _slicedToArray(_useState, 2),
4278
+ rasterizeLayers = _useState2[0],
4279
+ setRasterizeLayers = _useState2[1];
4280
+
4281
+ var _useState3 = useState(false),
4282
+ _useState4 = _slicedToArray(_useState3, 2),
4283
+ loading = _useState4[0],
4284
+ setLoading = _useState4[1];
4285
+
4286
+ var _useState5 = useState(),
4287
+ _useState6 = _slicedToArray(_useState5, 2),
4288
+ error = _useState6[0],
4289
+ setError = _useState6[1];
4290
+
4291
+ var classes = useStyles$8();
4292
+ return /*#__PURE__*/React.createElement(Dialog, {
4293
+ open: true,
4294
+ onClose: handleClose
4295
+ }, /*#__PURE__*/React.createElement(DialogTitle, null, "Export SVG", /*#__PURE__*/React.createElement(IconButton, {
4296
+ className: classes.closeButton,
4297
+ onClick: handleClose
4298
+ }, /*#__PURE__*/React.createElement(CloseIcon, null))), /*#__PURE__*/React.createElement(DialogContent, null, error ? /*#__PURE__*/React.createElement("div", {
4299
+ style: {
4300
+ color: 'red'
4301
+ }
4302
+ }, "".concat(error)) : loading ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(CircularProgress, {
4303
+ size: 20,
4304
+ style: {
4305
+ marginRight: 20
4306
+ }
4307
+ }), /*#__PURE__*/React.createElement(Typography$1, {
4308
+ display: "inline"
4309
+ }, "Creating SVG")) : null, offscreenCanvas ? /*#__PURE__*/React.createElement(FormControlLabel, {
4310
+ control: /*#__PURE__*/React.createElement(Checkbox, {
4311
+ checked: rasterizeLayers,
4312
+ onChange: function onChange() {
4313
+ return setRasterizeLayers(function (val) {
4314
+ return !val;
4315
+ });
4316
+ }
4317
+ }),
4318
+ label: "Rasterize canvas based tracks? File may be much larger if this is turned off"
4319
+ }) : /*#__PURE__*/React.createElement(Typography$1, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large")), /*#__PURE__*/React.createElement(DialogActions, null, /*#__PURE__*/React.createElement(Button$1, {
4320
+ variant: "contained",
3876
4321
  color: "secondary",
3877
4322
  onClick: function onClick() {
3878
4323
  return handleClose();
@@ -3928,7 +4373,7 @@ function ExportSvgDlg(_ref) {
3928
4373
  }, "Submit")));
3929
4374
  }
3930
4375
 
3931
- var useStyles$8 = /*#__PURE__*/makeStyles(function (theme) {
4376
+ var useStyles$9 = /*#__PURE__*/makeStyles(function (theme) {
3932
4377
  return {
3933
4378
  closeButton: {
3934
4379
  position: 'absolute',
@@ -3942,7 +4387,7 @@ var useStyles$8 = /*#__PURE__*/makeStyles(function (theme) {
3942
4387
  function ReturnToImportFormDialog(_ref) {
3943
4388
  var model = _ref.model,
3944
4389
  handleClose = _ref.handleClose;
3945
- var classes = useStyles$8();
4390
+ var classes = useStyles$9();
3946
4391
  return /*#__PURE__*/React.createElement(Dialog, {
3947
4392
  maxWidth: "xl",
3948
4393
  open: true,
@@ -3972,7 +4417,7 @@ function ReturnToImportFormDialog(_ref) {
3972
4417
 
3973
4418
  var ReturnToImportFormDlg = /*#__PURE__*/observer(ReturnToImportFormDialog);
3974
4419
 
3975
- var useStyles$9 = /*#__PURE__*/makeStyles({
4420
+ var useStyles$a = /*#__PURE__*/makeStyles({
3976
4421
  container: {
3977
4422
  display: 'flex',
3978
4423
  flexDirection: 'row',
@@ -3985,7 +4430,7 @@ var useStyles$9 = /*#__PURE__*/makeStyles({
3985
4430
 
3986
4431
  function ZoomControls(_ref) {
3987
4432
  var model = _ref.model;
3988
- var classes = useStyles$9();
4433
+ var classes = useStyles$a();
3989
4434
  var maxBpPerPx = model.maxBpPerPx,
3990
4435
  minBpPerPx = model.minBpPerPx,
3991
4436
  bpPerPx = model.bpPerPx,
@@ -4032,9 +4477,7 @@ function ZoomControls(_ref) {
4032
4477
 
4033
4478
  var ZoomControls$1 = /*#__PURE__*/observer(ZoomControls);
4034
4479
 
4035
- var WIDGET_HEIGHT = 32;
4036
- var SPACING = 7;
4037
- var useStyles$a = /*#__PURE__*/makeStyles$1(function (theme) {
4480
+ var useStyles$b = /*#__PURE__*/makeStyles$1(function (theme) {
4038
4481
  return {
4039
4482
  headerBar: {
4040
4483
  height: HEADER_BAR_HEIGHT,
@@ -4047,10 +4490,6 @@ var useStyles$a = /*#__PURE__*/makeStyles$1(function (theme) {
4047
4490
  spacer: {
4048
4491
  flexGrow: 1
4049
4492
  },
4050
- input: {},
4051
- headerRefName: {
4052
- minWidth: 100
4053
- },
4054
4493
  panButton: {
4055
4494
  background: alpha(theme.palette.background.paper, 0.8),
4056
4495
  height: WIDGET_HEIGHT,
@@ -4071,9 +4510,9 @@ var useStyles$a = /*#__PURE__*/makeStyles$1(function (theme) {
4071
4510
  }
4072
4511
  };
4073
4512
  });
4074
- var Controls = /*#__PURE__*/observer(function (_ref) {
4513
+ var HeaderButtons = /*#__PURE__*/observer(function (_ref) {
4075
4514
  var model = _ref.model;
4076
- var classes = useStyles$a();
4515
+ var classes = useStyles$b();
4077
4516
  return /*#__PURE__*/React.createElement(Button$1, {
4078
4517
  onClick: model.activateTrackSelector,
4079
4518
  className: classes.toggleButton,
@@ -4087,7 +4526,7 @@ var Controls = /*#__PURE__*/observer(function (_ref) {
4087
4526
 
4088
4527
  function PanControls(_ref2) {
4089
4528
  var model = _ref2.model;
4090
- var classes = useStyles$a();
4529
+ var classes = useStyles$b();
4091
4530
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button$1, {
4092
4531
  variant: "outlined",
4093
4532
  className: classes.panButton,
@@ -4105,150 +4544,21 @@ function PanControls(_ref2) {
4105
4544
 
4106
4545
  var RegionWidth = /*#__PURE__*/observer(function (_ref3) {
4107
4546
  var model = _ref3.model;
4108
- var classes = useStyles$a();
4547
+ var classes = useStyles$b();
4109
4548
  var coarseTotalBp = model.coarseTotalBp;
4110
4549
  return /*#__PURE__*/React.createElement(Typography$1, {
4111
4550
  variant: "body2",
4112
4551
  color: "textSecondary",
4113
4552
  className: classes.bp
4114
- }, "".concat(Math.round(coarseTotalBp).toLocaleString('en-US'), " bp"));
4553
+ }, Math.round(coarseTotalBp).toLocaleString('en-US'), " bp");
4115
4554
  });
4116
- var LinearGenomeViewHeader = /*#__PURE__*/observer(function (_ref4) {
4117
- var model = _ref4.model;
4118
- var classes = useStyles$a();
4119
- var theme = useTheme();
4120
- var session = getSession(model);
4121
- var textSearchManager = session.textSearchManager,
4122
- assemblyManager = session.assemblyManager;
4123
- var assemblyNames = model.assemblyNames,
4124
- rankSearchResults = model.rankSearchResults;
4125
- var assemblyName = assemblyNames[0];
4126
- var assembly = assemblyManager.get(assemblyName);
4127
- var searchScope = model.searchScope(assemblyName);
4128
-
4129
- function fetchResults(_x, _x2) {
4130
- return _fetchResults.apply(this, arguments);
4131
- }
4132
-
4133
- function _fetchResults() {
4134
- _fetchResults = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(query, searchType) {
4135
- var _assembly$allRefNames;
4136
-
4137
- var textSearchResults, refNameResults;
4138
- return runtime_1.wrap(function _callee$(_context) {
4139
- while (1) {
4140
- switch (_context.prev = _context.next) {
4141
- case 0:
4142
- if (!textSearchManager) {
4143
- console.warn('No text search manager');
4144
- }
4145
-
4146
- _context.next = 3;
4147
- return textSearchManager === null || textSearchManager === void 0 ? void 0 : textSearchManager.search({
4148
- queryString: query,
4149
- searchType: searchType
4150
- }, searchScope, rankSearchResults);
4151
-
4152
- case 3:
4153
- textSearchResults = _context.sent;
4154
- refNameResults = assembly === null || assembly === void 0 ? void 0 : (_assembly$allRefNames = assembly.allRefNames) === null || _assembly$allRefNames === void 0 ? void 0 : _assembly$allRefNames.filter(function (refName) {
4155
- return refName.startsWith(query);
4156
- }).map(function (r) {
4157
- return new BaseResult({
4158
- label: r
4159
- });
4160
- }).slice(0, 10);
4161
- return _context.abrupt("return", dedupe([].concat(_toConsumableArray(refNameResults || []), _toConsumableArray(textSearchResults || [])), function (elt) {
4162
- return elt.getId();
4163
- }));
4164
4555
 
4165
- case 6:
4166
- case "end":
4167
- return _context.stop();
4168
- }
4169
- }
4170
- }, _callee);
4171
- }));
4172
- return _fetchResults.apply(this, arguments);
4173
- }
4174
-
4175
- function handleSelectedRegion(_x3) {
4176
- return _handleSelectedRegion.apply(this, arguments);
4177
- }
4178
-
4179
- function _handleSelectedRegion() {
4180
- _handleSelectedRegion = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(option) {
4181
- var trackId, location, label, _assembly$allRefNames2, results;
4182
-
4183
- return runtime_1.wrap(function _callee2$(_context2) {
4184
- while (1) {
4185
- switch (_context2.prev = _context2.next) {
4186
- case 0:
4187
- trackId = option.getTrackId();
4188
- location = option.getLocation();
4189
- label = option.getLabel();
4190
- _context2.prev = 3;
4191
-
4192
- if (!(assembly !== null && assembly !== void 0 && (_assembly$allRefNames2 = assembly.allRefNames) !== null && _assembly$allRefNames2 !== void 0 && _assembly$allRefNames2.includes(location))) {
4193
- _context2.next = 8;
4194
- break;
4195
- }
4196
-
4197
- model.navToLocString(location);
4198
- _context2.next = 19;
4199
- break;
4200
-
4201
- case 8:
4202
- _context2.next = 10;
4203
- return fetchResults(label, 'exact');
4204
-
4205
- case 10:
4206
- results = _context2.sent;
4207
-
4208
- if (!(results && results.length > 1)) {
4209
- _context2.next = 16;
4210
- break;
4211
- }
4212
-
4213
- model.setSearchResults(results, label.toLowerCase());
4214
- return _context2.abrupt("return");
4215
-
4216
- case 16:
4217
- if ((results === null || results === void 0 ? void 0 : results.length) === 1) {
4218
- location = results[0].getLocation();
4219
- trackId = results[0].getTrackId();
4220
- }
4221
-
4222
- case 17:
4223
- model.navToLocString(location, assemblyName);
4224
-
4225
- if (trackId) {
4226
- model.showTrack(trackId);
4227
- }
4228
-
4229
- case 19:
4230
- _context2.next = 25;
4231
- break;
4232
-
4233
- case 21:
4234
- _context2.prev = 21;
4235
- _context2.t0 = _context2["catch"](3);
4236
- console.error(_context2.t0);
4237
- session.notify("".concat(_context2.t0), 'warning');
4238
-
4239
- case 25:
4240
- case "end":
4241
- return _context2.stop();
4242
- }
4243
- }
4244
- }, _callee2, null, [[3, 21]]);
4245
- }));
4246
- return _handleSelectedRegion.apply(this, arguments);
4247
- }
4248
-
4249
- var controls = /*#__PURE__*/React.createElement("div", {
4556
+ var Controls = function Controls(_ref4) {
4557
+ var model = _ref4.model;
4558
+ var classes = useStyles$b();
4559
+ return /*#__PURE__*/React.createElement("div", {
4250
4560
  className: classes.headerBar
4251
- }, /*#__PURE__*/React.createElement(Controls, {
4561
+ }, /*#__PURE__*/React.createElement(HeaderButtons, {
4252
4562
  model: model
4253
4563
  }), /*#__PURE__*/React.createElement("div", {
4254
4564
  className: classes.spacer
@@ -4257,26 +4567,8 @@ var LinearGenomeViewHeader = /*#__PURE__*/observer(function (_ref4) {
4257
4567
  className: classes.headerForm
4258
4568
  }, /*#__PURE__*/React.createElement(PanControls, {
4259
4569
  model: model
4260
- }), /*#__PURE__*/React.createElement(RefNameAutocomplete$1, {
4261
- onSelect: handleSelectedRegion,
4262
- assemblyName: assemblyName,
4263
- fetchResults: fetchResults,
4264
- model: model,
4265
- TextFieldProps: {
4266
- variant: 'outlined',
4267
- className: classes.headerRefName,
4268
- style: {
4269
- margin: SPACING,
4270
- minWidth: '175px'
4271
- },
4272
- InputProps: {
4273
- style: {
4274
- padding: 0,
4275
- height: WIDGET_HEIGHT,
4276
- background: alpha(theme.palette.background.paper, 0.8)
4277
- }
4278
- }
4279
- }
4570
+ }), /*#__PURE__*/React.createElement(SearchBox$1, {
4571
+ model: model
4280
4572
  })), /*#__PURE__*/React.createElement(RegionWidth, {
4281
4573
  model: model
4282
4574
  }), /*#__PURE__*/React.createElement(ZoomControls$1, {
@@ -4284,20 +4576,23 @@ var LinearGenomeViewHeader = /*#__PURE__*/observer(function (_ref4) {
4284
4576
  }), /*#__PURE__*/React.createElement("div", {
4285
4577
  className: classes.spacer
4286
4578
  }));
4579
+ };
4287
4580
 
4288
- if (model.hideHeaderOverview) {
4289
- return controls;
4290
- }
4291
-
4292
- return /*#__PURE__*/React.createElement(OverviewScaleBar$1, {
4581
+ var LinearGenomeViewHeader = /*#__PURE__*/observer(function (_ref5) {
4582
+ var model = _ref5.model;
4583
+ return model.hideHeaderOverview ? /*#__PURE__*/React.createElement(Controls, {
4584
+ model: model
4585
+ }) : /*#__PURE__*/React.createElement(OverviewScaleBar$1, {
4586
+ model: model
4587
+ }, /*#__PURE__*/React.createElement(Controls, {
4293
4588
  model: model
4294
- }, controls);
4589
+ }));
4295
4590
  });
4296
4591
 
4297
- var useStyles$b = /*#__PURE__*/makeStyles(function (theme) {
4592
+ var useStyles$c = /*#__PURE__*/makeStyles$1(function (theme) {
4298
4593
  return {
4299
4594
  root: {
4300
- background: alpha$1(theme.palette.background.paper, 0.8),
4595
+ background: alpha(theme.palette.background.paper, 0.8),
4301
4596
  '&:hover': {
4302
4597
  background: theme.palette.background.paper
4303
4598
  },
@@ -4328,7 +4623,7 @@ var useStyles$b = /*#__PURE__*/makeStyles(function (theme) {
4328
4623
  var TrackLabel = /*#__PURE__*/React.forwardRef(function (props, ref) {
4329
4624
  var _session$getTrackActi;
4330
4625
 
4331
- var classes = useStyles$b();
4626
+ var classes = useStyles$c();
4332
4627
 
4333
4628
  var _React$useState = React.useState(null),
4334
4629
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -4391,18 +4686,18 @@ var TrackLabel = /*#__PURE__*/React.forwardRef(function (props, ref) {
4391
4686
  "data-testid": "dragHandle-".concat(view.id, "-").concat(trackId)
4392
4687
  }, /*#__PURE__*/React.createElement(DragIcon, {
4393
4688
  className: classes.dragHandleIcon
4394
- })), /*#__PURE__*/React.createElement(IconButton$1, {
4689
+ })), /*#__PURE__*/React.createElement(IconButton, {
4395
4690
  onClick: function onClick() {
4396
4691
  return view.hideTrack(trackId);
4397
4692
  },
4398
4693
  className: classes.iconButton,
4399
4694
  title: "close this track",
4400
4695
  color: "secondary"
4401
- }, /*#__PURE__*/React.createElement(CloseIcon, null)), /*#__PURE__*/React.createElement(Typography, {
4696
+ }, /*#__PURE__*/React.createElement(CloseIcon, null)), /*#__PURE__*/React.createElement(Typography$1, {
4402
4697
  variant: "body1",
4403
4698
  component: "span",
4404
4699
  className: classes.trackName
4405
- }, trackName), /*#__PURE__*/React.createElement(IconButton$1, {
4700
+ }, trackName), /*#__PURE__*/React.createElement(IconButton, {
4406
4701
  "aria-controls": "simple-menu",
4407
4702
  "aria-haspopup": "true",
4408
4703
  onClick: handleClick,
@@ -4422,7 +4717,7 @@ var TrackLabel = /*#__PURE__*/React.forwardRef(function (props, ref) {
4422
4717
  });
4423
4718
  var TrackLabel$1 = /*#__PURE__*/observer(TrackLabel);
4424
4719
 
4425
- var useStyles$c = /*#__PURE__*/makeStyles(function (theme) {
4720
+ var useStyles$d = /*#__PURE__*/makeStyles(function (theme) {
4426
4721
  return {
4427
4722
  root: {},
4428
4723
  resizeHandle: {
@@ -4471,7 +4766,7 @@ var useStyles$c = /*#__PURE__*/makeStyles(function (theme) {
4471
4766
  });
4472
4767
 
4473
4768
  function TrackContainer(props) {
4474
- var classes = useStyles$c();
4769
+ var classes = useStyles$d();
4475
4770
  var model = props.model,
4476
4771
  track = props.track;
4477
4772
  var display = track.displays[0];
@@ -4507,7 +4802,7 @@ function TrackContainer(props) {
4507
4802
  }, view.trackLabels !== 'hidden' ? /*#__PURE__*/React.createElement(TrackLabel$1, {
4508
4803
  track: track,
4509
4804
  className: clsx(classes.trackLabel, view.trackLabels === 'overlapping' ? classes.trackLabelOverlap : classes.trackLabelInline)
4510
- }) : null, /*#__PURE__*/React.createElement(Paper, {
4805
+ }) : null, /*#__PURE__*/React.createElement(Paper$1, {
4511
4806
  variant: "outlined",
4512
4807
  className: classes.trackRenderingContainer,
4513
4808
  style: {
@@ -4553,8 +4848,8 @@ function TrackContainer(props) {
4553
4848
 
4554
4849
  var TrackContainer$1 = /*#__PURE__*/observer(TrackContainer);
4555
4850
 
4556
- var useStyles$d = /*#__PURE__*/makeStyles(function (theme) {
4557
- var background = theme.palette.tertiary ? alpha$2(theme.palette.tertiary.main, 0.7) : alpha$2(theme.palette.primary.main, 0.7);
4851
+ var useStyles$e = /*#__PURE__*/makeStyles(function (theme) {
4852
+ var background = theme.palette.tertiary ? alpha$1(theme.palette.tertiary.main, 0.7) : alpha$1(theme.palette.primary.main, 0.7);
4558
4853
  return {
4559
4854
  rubberBand: {
4560
4855
  height: '100%',
@@ -4592,7 +4887,7 @@ var useStyles$d = /*#__PURE__*/makeStyles(function (theme) {
4592
4887
  var VerticalGuide = /*#__PURE__*/observer(function (_ref) {
4593
4888
  var model = _ref.model,
4594
4889
  coordX = _ref.coordX;
4595
- var classes = useStyles$d();
4890
+ var classes = useStyles$e();
4596
4891
  return /*#__PURE__*/React.createElement(Tooltip$2, {
4597
4892
  open: true,
4598
4893
  placement: "top",
@@ -4636,7 +4931,7 @@ function RubberBand(_ref2) {
4636
4931
 
4637
4932
  var controlsRef = useRef(null);
4638
4933
  var rubberBandRef = useRef(null);
4639
- var classes = useStyles$d();
4934
+ var classes = useStyles$e();
4640
4935
  var mouseDragging = startX !== undefined && anchorPosition === undefined;
4641
4936
  var setOffsets = model.setOffsets,
4642
4937
  pxToBp = model.pxToBp;
@@ -4839,7 +5134,7 @@ RubberBand.defaultProps = {
4839
5134
  var RubberBand$1 = /*#__PURE__*/observer(RubberBand);
4840
5135
 
4841
5136
  var _excluded$1 = ["model", "style", "className"];
4842
- var useStyles$e = /*#__PURE__*/makeStyles(function (theme) {
5137
+ var useStyles$f = /*#__PURE__*/makeStyles(function (theme) {
4843
5138
  return {
4844
5139
  scaleBarContainer: {
4845
5140
  overflow: 'hidden',
@@ -4883,7 +5178,7 @@ var useStyles$e = /*#__PURE__*/makeStyles(function (theme) {
4883
5178
  });
4884
5179
  var RenderedRefNameLabels = /*#__PURE__*/observer(function (_ref) {
4885
5180
  var model = _ref.model;
4886
- var classes = useStyles$e(); // find the block that needs pinning to the left side for context
5181
+ var classes = useStyles$f(); // find the block that needs pinning to the left side for context
4887
5182
 
4888
5183
  var lastLeftBlock = 0;
4889
5184
  model.staticBlocks.forEach(function (block, i) {
@@ -4905,7 +5200,7 @@ var RenderedRefNameLabels = /*#__PURE__*/observer(function (_ref) {
4905
5200
  });
4906
5201
  var RenderedScaleBarLabels = /*#__PURE__*/observer(function (_ref2) {
4907
5202
  var model = _ref2.model;
4908
- var classes = useStyles$e();
5203
+ var classes = useStyles$f();
4909
5204
  return /*#__PURE__*/React.createElement(React.Fragment, null, model.staticBlocks.map(function (block, index) {
4910
5205
  if (block instanceof ContentBlock$1) {
4911
5206
  var ticks = makeTicks(block.start, block.end, model.bpPerPx, true, false);
@@ -4958,9 +5253,9 @@ var ScaleBar$2 = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
4958
5253
  className = _ref3.className,
4959
5254
  other = _objectWithoutProperties(_ref3, _excluded$1);
4960
5255
 
4961
- var classes = useStyles$e();
5256
+ var classes = useStyles$f();
4962
5257
  var offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
4963
- return /*#__PURE__*/React.createElement(Paper, Object.assign({
5258
+ return /*#__PURE__*/React.createElement(Paper$1, Object.assign({
4964
5259
  "data-resizer": "true" // used to avoid click-and-drag scrolls on trackscontainer
4965
5260
  ,
4966
5261
  className: clsx(classes.scaleBarContainer, className),
@@ -4986,7 +5281,7 @@ var ScaleBar$2 = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
4986
5281
  });
4987
5282
  var ScaleBar$3 = /*#__PURE__*/observer(ScaleBar$2);
4988
5283
 
4989
- var useStyles$f = /*#__PURE__*/makeStyles(function (theme) {
5284
+ var useStyles$g = /*#__PURE__*/makeStyles(function (theme) {
4990
5285
  return {
4991
5286
  verticalGuidesZoomContainer: {
4992
5287
  position: 'absolute',
@@ -5017,7 +5312,7 @@ var useStyles$f = /*#__PURE__*/makeStyles(function (theme) {
5017
5312
  });
5018
5313
  var RenderedVerticalGuides = /*#__PURE__*/observer(function (_ref) {
5019
5314
  var model = _ref.model;
5020
- var classes = useStyles$f();
5315
+ var classes = useStyles$g();
5021
5316
  return /*#__PURE__*/React.createElement(React.Fragment, null, model.staticBlocks.map(function (block, index) {
5022
5317
  if (block instanceof ContentBlock$1) {
5023
5318
  var ticks = makeTicks(block.start, block.end, model.bpPerPx);
@@ -5057,7 +5352,7 @@ var RenderedVerticalGuides = /*#__PURE__*/observer(function (_ref) {
5057
5352
 
5058
5353
  function VerticalGuides(_ref2) {
5059
5354
  var model = _ref2.model;
5060
- var classes = useStyles$f(); // find the block that needs pinning to the left side for context
5355
+ var classes = useStyles$g(); // find the block that needs pinning to the left side for context
5061
5356
 
5062
5357
  var offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
5063
5358
  return /*#__PURE__*/React.createElement("div", {
@@ -5078,7 +5373,7 @@ function VerticalGuides(_ref2) {
5078
5373
 
5079
5374
  var VerticalGuides$1 = /*#__PURE__*/observer(VerticalGuides);
5080
5375
 
5081
- var useStyles$g = /*#__PURE__*/makeStyles(function () {
5376
+ var useStyles$h = /*#__PURE__*/makeStyles(function () {
5082
5377
  return {
5083
5378
  centerLineContainer: {
5084
5379
  background: 'transparent',
@@ -5107,7 +5402,7 @@ function CenterLine(_ref) {
5107
5402
  tracks = model.tracks,
5108
5403
  width = model.width;
5109
5404
  var ref = useRef(null);
5110
- var classes = useStyles$g();
5405
+ var classes = useStyles$h();
5111
5406
  var startingPosition = width / 2;
5112
5407
  return tracks.length ? /*#__PURE__*/React.createElement("div", {
5113
5408
  "data-testid": "centerline_container",
@@ -5134,7 +5429,7 @@ CenterLine.propTypes = {
5134
5429
  };
5135
5430
  var CenterLine$1 = /*#__PURE__*/observer(CenterLine);
5136
5431
 
5137
- var useStyles$h = /*#__PURE__*/makeStyles(function (theme) {
5432
+ var useStyles$i = /*#__PURE__*/makeStyles(function (theme) {
5138
5433
  return {
5139
5434
  tracksContainer: {
5140
5435
  position: 'relative',
@@ -5151,7 +5446,7 @@ var useStyles$h = /*#__PURE__*/makeStyles(function (theme) {
5151
5446
  function TracksContainer(_ref) {
5152
5447
  var children = _ref.children,
5153
5448
  model = _ref.model;
5154
- var classes = useStyles$h(); // refs are to store these variables to avoid repeated rerenders associated
5449
+ var classes = useStyles$i(); // refs are to store these variables to avoid repeated rerenders associated
5155
5450
  // with useState/setState
5156
5451
 
5157
5452
  var delta = useRef(0);
@@ -5317,7 +5612,7 @@ var TracksContainer$1 = /*#__PURE__*/observer(TracksContainer);
5317
5612
  var SearchResultsDialog = /*#__PURE__*/lazy(function () {
5318
5613
  return Promise.resolve().then(function () { return SearchResultsDialog$2; });
5319
5614
  });
5320
- var useStyles$i = /*#__PURE__*/makeStyles$1(function (theme) {
5615
+ var useStyles$j = /*#__PURE__*/makeStyles$1(function (theme) {
5321
5616
  return {
5322
5617
  importFormContainer: {
5323
5618
  padding: theme.spacing(2)
@@ -5331,7 +5626,7 @@ var ImportForm = /*#__PURE__*/observer(function (_ref) {
5331
5626
  var _regions$;
5332
5627
 
5333
5628
  var model = _ref.model;
5334
- var classes = useStyles$i();
5629
+ var classes = useStyles$j();
5335
5630
  var session = getSession(model);
5336
5631
  var assemblyNames = session.assemblyNames,
5337
5632
  assemblyManager = session.assemblyManager,
@@ -5594,7 +5889,7 @@ var MiniControls = /*#__PURE__*/observer(function (props) {
5594
5889
  anchorEl = _useState2[0],
5595
5890
  setAnchorEl = _useState2[1];
5596
5891
 
5597
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Paper, {
5892
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Paper$1, {
5598
5893
  style: {
5599
5894
  background: '#aaa7'
5600
5895
  }
@@ -5631,7 +5926,7 @@ var MiniControls = /*#__PURE__*/observer(function (props) {
5631
5926
  }));
5632
5927
  });
5633
5928
 
5634
- var useStyles$j = /*#__PURE__*/makeStyles$1(function (theme) {
5929
+ var useStyles$k = /*#__PURE__*/makeStyles$1(function (theme) {
5635
5930
  return {
5636
5931
  loadingMessage: {
5637
5932
  padding: theme.spacing(5)
@@ -5727,7 +6022,7 @@ function _fetchSequence() {
5727
6022
  function SequenceDialog(_ref) {
5728
6023
  var model = _ref.model,
5729
6024
  handleClose = _ref.handleClose;
5730
- var classes = useStyles$j();
6025
+ var classes = useStyles$k();
5731
6026
  var session = getSession(model);
5732
6027
 
5733
6028
  var _useState = useState(),
@@ -5892,7 +6187,7 @@ function SequenceDialog(_ref) {
5892
6187
 
5893
6188
  var SequenceDialog$1 = /*#__PURE__*/observer(SequenceDialog);
5894
6189
 
5895
- var useStyles$k = /*#__PURE__*/makeStyles$1(function (theme) {
6190
+ var useStyles$l = /*#__PURE__*/makeStyles$1(function (theme) {
5896
6191
  return {
5897
6192
  dialogContent: {
5898
6193
  width: '80em'
@@ -5911,7 +6206,7 @@ function SearchResultsDialog$1(_ref) {
5911
6206
  var model = _ref.model,
5912
6207
  optAssemblyName = _ref.optAssemblyName,
5913
6208
  handleClose = _ref.handleClose;
5914
- var classes = useStyles$k();
6209
+ var classes = useStyles$l();
5915
6210
  var session = getSession(model);
5916
6211
 
5917
6212
  var _getEnv = getEnv(session),
@@ -5988,7 +6283,7 @@ function SearchResultsDialog$1(_ref) {
5988
6283
  handleClose();
5989
6284
  }
5990
6285
  }, /*#__PURE__*/React.createElement(CloseIcon, null)) : null), /*#__PURE__*/React.createElement(Divider, null), /*#__PURE__*/React.createElement(DialogContent, null, !((_model$searchResults = model.searchResults) !== null && _model$searchResults !== void 0 && _model$searchResults.length) ? /*#__PURE__*/React.createElement(Typography$1, null, "No results found for ", /*#__PURE__*/React.createElement("b", null, model.searchQuery)) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Typography$1, null, "Showing results for ", /*#__PURE__*/React.createElement("b", null, model.searchQuery)), /*#__PURE__*/React.createElement(TableContainer, {
5991
- component: Paper$1
6286
+ component: Paper
5992
6287
  }, /*#__PURE__*/React.createElement(Table, null, /*#__PURE__*/React.createElement(TableHead, null, /*#__PURE__*/React.createElement(TableRow, null, /*#__PURE__*/React.createElement(TableCell, null, "Name"), /*#__PURE__*/React.createElement(TableCell, {
5993
6288
  align: "right"
5994
6289
  }, "Location"), /*#__PURE__*/React.createElement(TableCell, {
@@ -6032,11 +6327,11 @@ function SearchResultsDialog$1(_ref) {
6032
6327
 
6033
6328
  var SearchResultsDialog$2 = {
6034
6329
  __proto__: null,
6035
- useStyles: useStyles$k,
6330
+ useStyles: useStyles$l,
6036
6331
  'default': SearchResultsDialog$1
6037
6332
  };
6038
6333
 
6039
- var useStyles$l = /*#__PURE__*/makeStyles$1(function (theme) {
6334
+ var useStyles$m = /*#__PURE__*/makeStyles$1(function (theme) {
6040
6335
  return {
6041
6336
  note: {
6042
6337
  textAlign: 'center',
@@ -6072,7 +6367,7 @@ var LinearGenomeView = /*#__PURE__*/observer(function (_ref) {
6072
6367
  hideHeader = model.hideHeader,
6073
6368
  initialized = model.initialized,
6074
6369
  hasDisplayedRegions = model.hasDisplayedRegions;
6075
- var classes = useStyles$l();
6370
+ var classes = useStyles$m();
6076
6371
 
6077
6372
  if (!initialized && !error) {
6078
6373
  return /*#__PURE__*/React.createElement(Typography$1, {
@@ -6113,7 +6408,7 @@ var LinearGenomeView = /*#__PURE__*/observer(function (_ref) {
6113
6408
  model: model
6114
6409
  })), /*#__PURE__*/React.createElement(TracksContainer$1, {
6115
6410
  model: model
6116
- }, !tracks.length ? /*#__PURE__*/React.createElement(Paper$1, {
6411
+ }, !tracks.length ? /*#__PURE__*/React.createElement(Paper, {
6117
6412
  variant: "outlined",
6118
6413
  className: classes.note
6119
6414
  }, /*#__PURE__*/React.createElement(Typography$1, null, "No tracks active."), /*#__PURE__*/React.createElement(Button$1, {
@@ -6161,6 +6456,8 @@ var HEADER_OVERVIEW_HEIGHT = 20;
6161
6456
  var SCALE_BAR_HEIGHT = 17;
6162
6457
  var RESIZE_HANDLE_HEIGHT = 3;
6163
6458
  var INTER_REGION_PADDING_WIDTH = 2;
6459
+ var WIDGET_HEIGHT = 32;
6460
+ var SPACING = 7;
6164
6461
  function stateModelFactory$1(pluginManager) {
6165
6462
  return types.compose(BaseViewModel, types.model('LinearGenomeView', {
6166
6463
  id: ElementId,
@@ -6174,9 +6471,17 @@ function stateModelFactory$1(pluginManager) {
6174
6471
  hideHeader: false,
6175
6472
  hideHeaderOverview: false,
6176
6473
  trackSelectorType: types.optional(types.enumeration(['hierarchical']), 'hierarchical'),
6177
- trackLabels: 'overlapping',
6178
- showCenterLine: false,
6179
- showCytobandsSetting: true
6474
+ trackLabels: types.optional(types.string, function () {
6475
+ return localStorage.getItem('lgv-trackLabels') || 'overlapping';
6476
+ }),
6477
+ showCenterLine: types.optional(types["boolean"], function () {
6478
+ var setting = localStorage.getItem('lgv-showCenterLine');
6479
+ return setting !== undefined ? !!setting : false;
6480
+ }),
6481
+ showCytobandsSetting: types.optional(types["boolean"], function () {
6482
+ var setting = localStorage.getItem('lgv-showCytobands');
6483
+ return setting !== undefined ? !!setting : true;
6484
+ })
6180
6485
  }))["volatile"](function () {
6181
6486
  return {
6182
6487
  volatileWidth: undefined,
@@ -6283,11 +6588,9 @@ function stateModelFactory$1(pluginManager) {
6283
6588
  },
6284
6589
 
6285
6590
  get totalBp() {
6286
- var totalbp = 0;
6287
- self.displayedRegions.forEach(function (region) {
6288
- totalbp += region.end - region.start;
6289
- });
6290
- return totalbp;
6591
+ return self.displayedRegions.reduce(function (a, b) {
6592
+ return a + b.end - b.start;
6593
+ }, 0);
6291
6594
  },
6292
6595
 
6293
6596
  get maxBpPerPx() {
@@ -6350,39 +6653,12 @@ function stateModelFactory$1(pluginManager) {
6350
6653
  var refName = _ref.refName,
6351
6654
  coord = _ref.coord,
6352
6655
  regionNumber = _ref.regionNumber;
6353
- var offsetBp = 0;
6354
- var interRegionPaddingBp = self.interRegionPaddingWidth * self.bpPerPx;
6355
- var minimumBlockBp = self.minimumBlockWidth * self.bpPerPx;
6356
- var index = self.displayedRegions.findIndex(function (region, idx) {
6357
- var len = region.end - region.start;
6358
-
6359
- if (refName === region.refName && coord >= region.start && coord <= region.end) {
6360
- if (regionNumber ? regionNumber === idx : true) {
6361
- offsetBp += region.reversed ? region.end - coord : coord - region.start;
6362
- return true;
6363
- }
6364
- } // add the interRegionPaddingWidth if the boundary is in the screen
6365
- // e.g. offset>=0 && offset<width
6366
-
6367
-
6368
- if (len > minimumBlockBp && offsetBp / self.bpPerPx >= 0 && offsetBp / self.bpPerPx < self.width) {
6369
- offsetBp += len + interRegionPaddingBp;
6370
- } else {
6371
- offsetBp += len;
6372
- }
6373
-
6374
- return false;
6656
+ return viewBpToPx({
6657
+ refName: refName,
6658
+ coord: coord,
6659
+ regionNumber: regionNumber,
6660
+ self: self
6375
6661
  });
6376
- var foundRegion = self.displayedRegions[index];
6377
-
6378
- if (foundRegion) {
6379
- return {
6380
- index: index,
6381
- offsetPx: Math.round(offsetBp / self.bpPerPx)
6382
- };
6383
- }
6384
-
6385
- return undefined;
6386
6662
  },
6387
6663
 
6388
6664
  /**
@@ -6534,6 +6810,7 @@ function stateModelFactory$1(pluginManager) {
6534
6810
  return {
6535
6811
  setShowCytobands: function setShowCytobands(flag) {
6536
6812
  self.showCytobandsSetting = flag;
6813
+ localStorage.setItem('lgv-showCytobands', "".concat(+flag));
6537
6814
  },
6538
6815
  setWidth: function setWidth(newWidth) {
6539
6816
  self.volatileWidth = newWidth;
@@ -6603,13 +6880,13 @@ function stateModelFactory$1(pluginManager) {
6603
6880
  var configuration = resolveIdentifier(trackConfigSchema, getRoot(self), trackId);
6604
6881
 
6605
6882
  if (!configuration) {
6606
- throw new Error("Could not resolve identifier");
6883
+ throw new Error("Could not resolve identifier \"".concat(trackId, "\""));
6607
6884
  }
6608
6885
 
6609
6886
  var trackType = pluginManager.getTrackType(configuration === null || configuration === void 0 ? void 0 : configuration.type);
6610
6887
 
6611
6888
  if (!trackType) {
6612
- throw new Error("unknown track type ".concat(configuration.type));
6889
+ throw new Error("Unknown track type ".concat(configuration.type));
6613
6890
  }
6614
6891
 
6615
6892
  var viewType = pluginManager.getViewType(self.type);
@@ -6621,7 +6898,7 @@ function stateModelFactory$1(pluginManager) {
6621
6898
  });
6622
6899
 
6623
6900
  if (!displayConf) {
6624
- throw new Error("could not find a compatible display for view type ".concat(self.type));
6901
+ throw new Error("Could not find a compatible display for view type ".concat(self.type));
6625
6902
  }
6626
6903
 
6627
6904
  var shownTracks = self.tracks.filter(function (t) {
@@ -6704,9 +6981,11 @@ function stateModelFactory$1(pluginManager) {
6704
6981
  },
6705
6982
  setTrackLabels: function setTrackLabels(setting) {
6706
6983
  self.trackLabels = setting;
6984
+ localStorage.setItem('lgv-trackLabels', setting);
6707
6985
  },
6708
6986
  toggleCenterLine: function toggleCenterLine() {
6709
6987
  self.showCenterLine = !self.showCenterLine;
6988
+ localStorage.setItem('lgv-showCenterLine', "".concat(+self.showCenterLine));
6710
6989
  },
6711
6990
  setDisplayedRegions: function setDisplayedRegions(regions) {
6712
6991
  self.displayedRegions = cast(regions);
@@ -7620,13 +7899,7 @@ function configSchemaFactory$1(pluginManager) {
7620
7899
  defaultValue: "jexl:get(feature,'name')",
7621
7900
  contextVariable: ['feature']
7622
7901
  },
7623
- renderer: pluginManager.pluggableConfigSchemaType('renderer'),
7624
- // overrides base
7625
- maxDisplayedBpPerPx: {
7626
- type: 'number',
7627
- description: 'maximum bpPerPx that is displayed in the view',
7628
- defaultValue: 1000
7629
- }
7902
+ renderer: pluginManager.pluggableConfigSchemaType('renderer')
7630
7903
  }, {
7631
7904
  baseConfiguration: baseLinearDisplayConfigSchema,
7632
7905
  explicitlyTyped: true
@@ -7709,6 +7982,81 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
7709
7982
  })
7710
7983
  });
7711
7984
  });
7985
+ pluginManager.addToExtensionPoint('LaunchView-LinearGenomeView',
7986
+ /*#__PURE__*/
7987
+ // @ts-ignore
7988
+ function () {
7989
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(_ref) {
7990
+ var session, assembly, loc, _ref$tracks, tracks, assemblyManager, view, asm, idsNotFound;
7991
+
7992
+ return runtime_1.wrap(function _callee$(_context) {
7993
+ while (1) {
7994
+ switch (_context.prev = _context.next) {
7995
+ case 0:
7996
+ session = _ref.session, assembly = _ref.assembly, loc = _ref.loc, _ref$tracks = _ref.tracks, tracks = _ref$tracks === void 0 ? [] : _ref$tracks;
7997
+ assemblyManager = session.assemblyManager;
7998
+ view = session.addView('LinearGenomeView', {});
7999
+ _context.next = 5;
8000
+ return when(function () {
8001
+ return !!view.volatileWidth;
8002
+ });
8003
+
8004
+ case 5:
8005
+ if (assembly) {
8006
+ _context.next = 7;
8007
+ break;
8008
+ }
8009
+
8010
+ throw new Error('No assembly provided when launching linear genome view');
8011
+
8012
+ case 7:
8013
+ _context.next = 9;
8014
+ return assemblyManager.waitForAssembly(assembly);
8015
+
8016
+ case 9:
8017
+ asm = _context.sent;
8018
+
8019
+ if (asm) {
8020
+ _context.next = 12;
8021
+ break;
8022
+ }
8023
+
8024
+ throw new Error("Assembly \"".concat(assembly, "\" not found when launching linear genome view"));
8025
+
8026
+ case 12:
8027
+ view.navToLocString(loc, assembly);
8028
+ idsNotFound = [];
8029
+ tracks.forEach(function (track) {
8030
+ try {
8031
+ view.showTrack(track);
8032
+ } catch (e) {
8033
+ if ("".concat(e).match('Could not resolve identifier')) {
8034
+ idsNotFound.push(track);
8035
+ } else {
8036
+ throw e;
8037
+ }
8038
+ }
8039
+ });
8040
+
8041
+ if (!idsNotFound.length) {
8042
+ _context.next = 17;
8043
+ break;
8044
+ }
8045
+
8046
+ throw new Error("Could not resolve identifiers: ".concat(idsNotFound.join(',')));
8047
+
8048
+ case 17:
8049
+ case "end":
8050
+ return _context.stop();
8051
+ }
8052
+ }
8053
+ }, _callee);
8054
+ }));
8055
+
8056
+ return function (_x) {
8057
+ return _ref2.apply(this, arguments);
8058
+ };
8059
+ }());
7712
8060
  }
7713
8061
  }, {
7714
8062
  key: "configure",
@@ -7728,7 +8076,7 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
7728
8076
  return LinearGenomeViewPlugin;
7729
8077
  }(Plugin);
7730
8078
 
7731
- var useStyles$m = /*#__PURE__*/makeStyles$1(function (theme) {
8079
+ var useStyles$n = /*#__PURE__*/makeStyles$1(function (theme) {
7732
8080
  return {
7733
8081
  closeButton: {
7734
8082
  position: 'absolute',
@@ -7740,7 +8088,7 @@ var useStyles$m = /*#__PURE__*/makeStyles$1(function (theme) {
7740
8088
  });
7741
8089
  function HelpDialog$1(_ref) {
7742
8090
  var handleClose = _ref.handleClose;
7743
- var classes = useStyles$m();
8091
+ var classes = useStyles$n();
7744
8092
  return /*#__PURE__*/React.createElement(Dialog, {
7745
8093
  open: true,
7746
8094
  maxWidth: "xl",
@@ -7761,11 +8109,11 @@ function HelpDialog$1(_ref) {
7761
8109
 
7762
8110
  var HelpDialog$2 = {
7763
8111
  __proto__: null,
7764
- useStyles: useStyles$m,
8112
+ useStyles: useStyles$n,
7765
8113
  'default': HelpDialog$1
7766
8114
  };
7767
8115
 
7768
- var useStyles$n = /*#__PURE__*/makeStyles$1(function (theme) {
8116
+ var useStyles$o = /*#__PURE__*/makeStyles$1(function (theme) {
7769
8117
  return {
7770
8118
  root: {
7771
8119
  width: 500
@@ -7785,7 +8133,7 @@ var useStyles$n = /*#__PURE__*/makeStyles$1(function (theme) {
7785
8133
  function SetMaxHeightDlg$1(props) {
7786
8134
  var model = props.model,
7787
8135
  handleClose = props.handleClose;
7788
- var classes = useStyles$n();
8136
+ var classes = useStyles$o();
7789
8137
  var _model$maxHeight = model.maxHeight,
7790
8138
  maxHeight = _model$maxHeight === void 0 ? '' : _model$maxHeight;
7791
8139
 
@@ -7835,5 +8183,5 @@ var SetMaxHeight$1 = {
7835
8183
  };
7836
8184
 
7837
8185
  export default LinearGenomeViewPlugin;
7838
- export { BaseLinearDisplay$1 as BaseLinearDisplay, BaseLinearDisplay as BaseLinearDisplayComponent, RefNameAutocomplete$1 as RefNameAutocomplete, baseLinearDisplayConfigSchema, configSchemaFactory as linearBareDisplayConfigSchemaFactory, configSchemaFactory$1 as linearBasicDisplayConfigSchemaFactory, stateModelFactory$2 as linearBasicDisplayModelFactory, renderToSvg };
8186
+ export { BaseLinearDisplay$1 as BaseLinearDisplay, BaseLinearDisplay as BaseLinearDisplayComponent, RefNameAutocomplete$1 as RefNameAutocomplete, SearchBox$1 as SearchBox, baseLinearDisplayConfigSchema, configSchemaFactory as linearBareDisplayConfigSchemaFactory, configSchemaFactory$1 as linearBasicDisplayConfigSchemaFactory, stateModelFactory$2 as linearBasicDisplayModelFactory, renderToSvg };
7839
8187
  //# sourceMappingURL=plugin-linear-genome-view.esm.js.map