@jbrowse/plugin-linear-genome-view 1.5.6 → 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
@@ -6,6 +6,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau
6
6
 
7
7
  var React = require('react');
8
8
  var React__default = _interopDefault(React);
9
+ var mobx = require('mobx');
9
10
  var configuration = require('@jbrowse/core/configuration');
10
11
  var models = require('@jbrowse/core/pluggableElementTypes/models');
11
12
  var TrackType = _interopDefault(require('@jbrowse/core/pluggableElementTypes/TrackType'));
@@ -14,15 +15,12 @@ var ViewType = _interopDefault(require('@jbrowse/core/pluggableElementTypes/View
14
15
  var Plugin = _interopDefault(require('@jbrowse/core/Plugin'));
15
16
  var util = require('@jbrowse/core/util');
16
17
  var LineStyleIcon = _interopDefault(require('@material-ui/icons/LineStyle'));
18
+ var core = require('@material-ui/core');
17
19
  var CompositeMap = _interopDefault(require('@jbrowse/core/util/compositeMap'));
18
20
  var simpleFeature = require('@jbrowse/core/util/simpleFeature');
19
21
  var tracks = require('@jbrowse/core/util/tracks');
20
- var Button = _interopDefault(require('@material-ui/core/Button'));
21
- var Typography = _interopDefault(require('@material-ui/core/Typography'));
22
- var MenuOpenIcon = _interopDefault(require('@material-ui/icons/MenuOpen'));
23
- var mobx = require('mobx');
24
22
  var mobxStateTree = require('mobx-state-tree');
25
- var core = require('@material-ui/core');
23
+ var MenuOpenIcon = _interopDefault(require('@material-ui/icons/MenuOpen'));
26
24
  var ui = require('@jbrowse/core/ui');
27
25
  var mobxReact = require('mobx-react');
28
26
  var reactPopper = require('react-popper');
@@ -30,6 +28,8 @@ var styles = require('@material-ui/core/styles');
30
28
  var blockTypes = require('@jbrowse/core/util/blockTypes');
31
29
  var mst = require('@jbrowse/core/util/types/mst');
32
30
  var types = require('@jbrowse/core/util/types');
31
+ var Typography = _interopDefault(require('@material-ui/core/Typography'));
32
+ var Button = _interopDefault(require('@material-ui/core/Button'));
33
33
  var RefreshIcon = _interopDefault(require('@material-ui/icons/Refresh'));
34
34
  var configurationSchema = require('@jbrowse/core/configuration/configurationSchema');
35
35
  var calculateDynamicBlocks = _interopDefault(require('@jbrowse/core/util/calculateDynamicBlocks'));
@@ -65,8 +65,8 @@ var normalizeWheel = _interopDefault(require('normalize-wheel'));
65
65
  var colorManipulator = require('@material-ui/core/styles/colorManipulator');
66
66
  var Popover = _interopDefault(require('@material-ui/core/Popover'));
67
67
  var Tooltip$1 = _interopDefault(require('@material-ui/core/Tooltip'));
68
- var AssemblySelector = _interopDefault(require('@jbrowse/core/ui/AssemblySelector'));
69
68
  var ErrorMessage = _interopDefault(require('@jbrowse/core/ui/ErrorMessage'));
69
+ var AssemblySelector = _interopDefault(require('@jbrowse/core/ui/AssemblySelector'));
70
70
  var ArrowDown = _interopDefault(require('@material-ui/icons/KeyboardArrowDown'));
71
71
  var Menu = _interopDefault(require('@jbrowse/core/ui/Menu'));
72
72
  var copy = _interopDefault(require('copy-to-clipboard'));
@@ -190,14 +190,14 @@ function _inherits(subClass, superClass) {
190
190
  throw new TypeError("Super expression must either be null or a function");
191
191
  }
192
192
 
193
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
194
+ constructor: {
195
+ value: subClass,
196
+ writable: true,
197
+ configurable: true
198
+ }
199
+ });
193
200
  Object.defineProperty(subClass, "prototype", {
194
- value: Object.create(superClass && superClass.prototype, {
195
- constructor: {
196
- value: subClass,
197
- writable: true,
198
- configurable: true
199
- }
200
- }),
201
201
  writable: false
202
202
  });
203
203
  if (superClass) _setPrototypeOf(subClass, superClass);
@@ -437,16 +437,6 @@ function _createForOfIteratorHelper(o, allowArrayLike) {
437
437
  };
438
438
  }
439
439
 
440
- var baseLinearDisplayConfigSchema = /*#__PURE__*/configuration.ConfigurationSchema('BaseLinearDisplay', {
441
- maxDisplayedBpPerPx: {
442
- type: 'number',
443
- description: 'maximum bpPerPx that is displayed in the view',
444
- defaultValue: Number.MAX_VALUE
445
- }
446
- }, {
447
- explicitIdentifier: 'displayId'
448
- });
449
-
450
440
  function createCommonjsModule(fn, module) {
451
441
  return module = { exports: {} }, fn(module, module.exports), module.exports;
452
442
  }
@@ -1176,6 +1166,21 @@ var runtime_1 = /*#__PURE__*/createCommonjsModule(function (module) {
1176
1166
  }
1177
1167
  });
1178
1168
 
1169
+ var baseLinearDisplayConfigSchema = /*#__PURE__*/configuration.ConfigurationSchema('BaseLinearDisplay', {
1170
+ maxFeatureScreenDensity: {
1171
+ type: 'number',
1172
+ description: 'maximum features per pixel that is displayed in the view, used if byte size estimates not available',
1173
+ defaultValue: 0.3
1174
+ },
1175
+ fetchSizeLimit: {
1176
+ type: 'number',
1177
+ defaultValue: 1000000,
1178
+ description: "maximum data to attempt to download for a given track, used if adapter doesn't specify one"
1179
+ }
1180
+ }, {
1181
+ explicitIdentifier: 'displayId'
1182
+ });
1183
+
1179
1184
  var useStyles = /*#__PURE__*/styles.makeStyles(function (theme) {
1180
1185
  return {
1181
1186
  contentBlock: {
@@ -1960,6 +1965,26 @@ function _renderBlockEffect() {
1960
1965
  }
1961
1966
 
1962
1967
  var _excluded = ["blockState"];
1968
+
1969
+ function getId(id, index) {
1970
+ var isJest = typeof jest === 'undefined';
1971
+ return "clip-".concat(isJest ? id : 'jest', "-").concat(index);
1972
+ }
1973
+
1974
+ function getDisplayStr(totalBytes) {
1975
+ var displayBp;
1976
+
1977
+ if (Math.floor(totalBytes / 1000000) > 0) {
1978
+ displayBp = "".concat(parseFloat((totalBytes / 1000000).toPrecision(3)), " Mb");
1979
+ } else if (Math.floor(totalBytes / 1000) > 0) {
1980
+ displayBp = "".concat(parseFloat((totalBytes / 1000).toPrecision(3)), " Kb");
1981
+ } else {
1982
+ displayBp = "".concat(Math.floor(totalBytes), " bytes");
1983
+ }
1984
+
1985
+ return displayBp;
1986
+ }
1987
+
1963
1988
  var minDisplayHeight = 20;
1964
1989
  var defaultDisplayHeight = 100;
1965
1990
  var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDisplay', models.BaseDisplay, mobxStateTree.types.model({
@@ -1967,13 +1992,17 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
1967
1992
  return n >= minDisplayHeight;
1968
1993
  }), defaultDisplayHeight),
1969
1994
  blockState: mobxStateTree.types.map(blockState),
1970
- userBpPerPxLimit: mobxStateTree.types.maybe(mobxStateTree.types.number)
1995
+ userBpPerPxLimit: mobxStateTree.types.maybe(mobxStateTree.types.number),
1996
+ userByteSizeLimit: mobxStateTree.types.maybe(mobxStateTree.types.number)
1971
1997
  }))["volatile"](function () {
1972
1998
  return {
1999
+ currBpPerPx: 0,
1973
2000
  message: '',
1974
2001
  featureIdUnderMouse: undefined,
1975
2002
  contextMenuFeature: undefined,
1976
- scrollTop: 0
2003
+ scrollTop: 0,
2004
+ estimatedRegionStatsP: undefined,
2005
+ estimatedRegionStats: undefined
1977
2006
  };
1978
2007
  }).views(function (self) {
1979
2008
  return {
@@ -1995,13 +2024,6 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
1995
2024
  };
1996
2025
  }).views(function (self) {
1997
2026
  return {
1998
- /**
1999
- * set limit to config amount, or user amount if they force load,
2000
- */
2001
- get maxViewBpPerPx() {
2002
- return self.userBpPerPxLimit || configuration.getConf(self, 'maxDisplayedBpPerPx');
2003
- },
2004
-
2005
2027
  /**
2006
2028
  * how many milliseconds to wait for the display to
2007
2029
  * "settle" before re-rendering a block
@@ -2071,7 +2093,8 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2071
2093
  },
2072
2094
 
2073
2095
  get featureUnderMouse() {
2074
- return self.featureIdUnderMouse ? this.features.get(self.featureIdUnderMouse) : undefined;
2096
+ var feat = self.featureIdUnderMouse;
2097
+ return feat ? this.features.get(feat) : undefined;
2075
2098
  },
2076
2099
 
2077
2100
  getFeatureOverlapping: function getFeatureOverlapping(blockKey, x, y) {
@@ -2097,16 +2120,49 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2097
2120
  }
2098
2121
  });
2099
2122
  return ret;
2123
+ },
2124
+
2125
+ get currentBytesRequested() {
2126
+ var _self$estimatedRegion;
2127
+
2128
+ return ((_self$estimatedRegion = self.estimatedRegionStats) === null || _self$estimatedRegion === void 0 ? void 0 : _self$estimatedRegion.bytes) || 0;
2129
+ },
2130
+
2131
+ get currentFeatureScreenDensity() {
2132
+ var _self$estimatedRegion2;
2133
+
2134
+ var view = util.getContainingView(self);
2135
+ return (((_self$estimatedRegion2 = self.estimatedRegionStats) === null || _self$estimatedRegion2 === void 0 ? void 0 : _self$estimatedRegion2.featureDensity) || 0) * view.bpPerPx;
2136
+ },
2137
+
2138
+ get maxFeatureScreenDensity() {
2139
+ return configuration.getConf(self, 'maxFeatureScreenDensity');
2140
+ },
2141
+
2142
+ get estimatedStatsReady() {
2143
+ return !!self.estimatedRegionStats;
2144
+ },
2145
+
2146
+ get maxAllowableBytes() {
2147
+ var _self$estimatedRegion3;
2148
+
2149
+ return self.userByteSizeLimit || ((_self$estimatedRegion3 = self.estimatedRegionStats) === null || _self$estimatedRegion3 === void 0 ? void 0 : _self$estimatedRegion3.fetchSizeLimit) || configuration.getConf(self, 'fetchSizeLimit');
2100
2150
  }
2151
+
2101
2152
  };
2102
2153
  }).actions(function (self) {
2103
2154
  return {
2155
+ // base display reload does nothing, see specialized displays for details
2156
+ setMessage: function setMessage(message) {
2157
+ self.message = message;
2158
+ },
2104
2159
  afterAttach: function afterAttach() {
2105
2160
  var _this = this;
2106
2161
 
2107
- // watch the parent's blocks to update our block state when they change
2162
+ // watch the parent's blocks to update our block state when they change,
2163
+ // then we recreate the blocks on our own model (creating and deleting to
2164
+ // match the parent blocks)
2108
2165
  var blockWatchDisposer = mobx.autorun(function () {
2109
- // create any blocks that we need to create
2110
2166
  var blocksPresent = {};
2111
2167
  var view = util.getContainingView(self);
2112
2168
 
@@ -2117,8 +2173,7 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2117
2173
  if (!self.blockState.has(block.key)) {
2118
2174
  _this.addBlock(block.key, block);
2119
2175
  }
2120
- }); // delete any blocks we need go delete
2121
-
2176
+ });
2122
2177
  self.blockState.forEach(function (_, key) {
2123
2178
  if (!blocksPresent[key]) {
2124
2179
  _this.deleteBlock(key);
@@ -2128,6 +2183,47 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2128
2183
  });
2129
2184
  mobxStateTree.addDisposer(self, blockWatchDisposer);
2130
2185
  },
2186
+ estimateRegionsStats: function estimateRegionsStats(regions, opts) {
2187
+ var _this2 = this;
2188
+
2189
+ if (self.estimatedRegionStatsP) {
2190
+ return self.estimatedRegionStatsP;
2191
+ }
2192
+
2193
+ var _getSession2 = util.getSession(self),
2194
+ rpcManager = _getSession2.rpcManager;
2195
+
2196
+ var adapterConfig = self.adapterConfig;
2197
+ var sessionId = tracks.getRpcSessionId(self);
2198
+
2199
+ var params = _objectSpread2({
2200
+ sessionId: sessionId,
2201
+ regions: regions,
2202
+ adapterConfig: adapterConfig,
2203
+ statusCallback: function statusCallback(message) {
2204
+ if (mobxStateTree.isAlive(self)) {
2205
+ _this2.setMessage(message);
2206
+ }
2207
+ }
2208
+ }, opts);
2209
+
2210
+ self.estimatedRegionStatsP = rpcManager.call(sessionId, 'CoreEstimateRegionStats', params)["catch"](function (e) {
2211
+ _this2.setRegionStatsP(undefined);
2212
+
2213
+ throw e;
2214
+ });
2215
+ return self.estimatedRegionStatsP;
2216
+ },
2217
+ setRegionStatsP: function setRegionStatsP(p) {
2218
+ self.estimatedRegionStatsP = p;
2219
+ },
2220
+ setRegionStats: function setRegionStats(estimatedRegionStats) {
2221
+ self.estimatedRegionStats = estimatedRegionStats;
2222
+ },
2223
+ clearRegionStats: function clearRegionStats() {
2224
+ self.estimatedRegionStatsP = undefined;
2225
+ self.estimatedRegionStats = undefined;
2226
+ },
2131
2227
  setHeight: function setHeight(displayHeight) {
2132
2228
  if (displayHeight > minDisplayHeight) {
2133
2229
  self.height = displayHeight;
@@ -2145,13 +2241,14 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2145
2241
  setScrollTop: function setScrollTop(scrollTop) {
2146
2242
  self.scrollTop = scrollTop;
2147
2243
  },
2148
- // sets the new bpPerPxLimit if user chooses to force load
2149
- setUserBpPerPxLimit: function setUserBpPerPxLimit(limit) {
2150
- self.userBpPerPxLimit = limit;
2151
- },
2152
- // base display reload does nothing, see specialized displays for details
2153
- setMessage: function setMessage(message) {
2154
- self.message = message;
2244
+ updateStatsLimit: function updateStatsLimit(stats) {
2245
+ var view = util.getContainingView(self);
2246
+
2247
+ if (stats.bytes) {
2248
+ self.userByteSizeLimit = stats.bytes;
2249
+ } else {
2250
+ self.userBpPerPxLimit = view.bpPerPx;
2251
+ }
2155
2252
  },
2156
2253
  addBlock: function addBlock(key, block) {
2157
2254
  self.blockState.set(key, blockState.create({
@@ -2159,6 +2256,9 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2159
2256
  region: block.toRegion()
2160
2257
  }));
2161
2258
  },
2259
+ setCurrBpPerPx: function setCurrBpPerPx(n) {
2260
+ self.currBpPerPx = n;
2261
+ },
2162
2262
  deleteBlock: function deleteBlock(key) {
2163
2263
  self.blockState["delete"](key);
2164
2264
  },
@@ -2196,14 +2296,178 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2196
2296
  };
2197
2297
  }).views(function (self) {
2198
2298
  return {
2199
- regionCannotBeRenderedText: function regionCannotBeRenderedText(_region) {
2299
+ // region is too large if:
2300
+ // - stats are ready
2301
+ // - region is greater than 20kb (don't warn when zoomed in less than that)
2302
+ // - and bytes > max allowed bytes || curr density>max density
2303
+ get regionTooLarge() {
2200
2304
  var view = util.getContainingView(self);
2201
2305
 
2202
- if (view && view.bpPerPx > self.maxViewBpPerPx) {
2203
- return 'Zoom in to see features';
2306
+ if (!self.estimatedStatsReady || view.dynamicBlocks.totalBp < 20000) {
2307
+ return false;
2204
2308
  }
2205
2309
 
2206
- return '';
2310
+ var bpLimitOrDensity = self.userBpPerPxLimit ? view.bpPerPx > self.userBpPerPxLimit : self.currentFeatureScreenDensity > self.maxFeatureScreenDensity;
2311
+ return self.currentBytesRequested > self.maxAllowableBytes || bpLimitOrDensity;
2312
+ },
2313
+
2314
+ // only shows a message of bytes requested is defined, the feature density
2315
+ // based stats don't produce any helpful message besides to zoom in
2316
+ get regionTooLargeReason() {
2317
+ var req = self.currentBytesRequested;
2318
+ var max = self.maxAllowableBytes;
2319
+ return req && req > max ? "Requested too much data (".concat(getDisplayStr(req), ")") : '';
2320
+ }
2321
+
2322
+ };
2323
+ }).actions(function (self) {
2324
+ var superReload = self.reload;
2325
+ return {
2326
+ reload: function reload() {
2327
+ return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
2328
+ var aborter, view, estimatedRegionStats;
2329
+ return runtime_1.wrap(function _callee$(_context) {
2330
+ while (1) {
2331
+ switch (_context.prev = _context.next) {
2332
+ case 0:
2333
+ self.setError();
2334
+ aborter = new AbortController();
2335
+ view = util.getContainingView(self);
2336
+
2337
+ if (view.initialized) {
2338
+ _context.next = 5;
2339
+ break;
2340
+ }
2341
+
2342
+ return _context.abrupt("return");
2343
+
2344
+ case 5:
2345
+ _context.prev = 5;
2346
+ self.estimatedRegionStatsP = self.estimateRegionsStats(view.staticBlocks.contentBlocks, {
2347
+ signal: aborter.signal
2348
+ });
2349
+ _context.next = 9;
2350
+ return self.estimatedRegionStatsP;
2351
+
2352
+ case 9:
2353
+ estimatedRegionStats = _context.sent;
2354
+
2355
+ if (!mobxStateTree.isAlive(self)) {
2356
+ _context.next = 15;
2357
+ break;
2358
+ }
2359
+
2360
+ self.setRegionStats(estimatedRegionStats);
2361
+ superReload();
2362
+ _context.next = 16;
2363
+ break;
2364
+
2365
+ case 15:
2366
+ return _context.abrupt("return");
2367
+
2368
+ case 16:
2369
+ _context.next = 21;
2370
+ break;
2371
+
2372
+ case 18:
2373
+ _context.prev = 18;
2374
+ _context.t0 = _context["catch"](5);
2375
+ self.setError(_context.t0);
2376
+
2377
+ case 21:
2378
+ case "end":
2379
+ return _context.stop();
2380
+ }
2381
+ }
2382
+ }, _callee, null, [[5, 18]]);
2383
+ }))();
2384
+ },
2385
+ afterAttach: function afterAttach() {
2386
+ // this autorun performs stats estimation
2387
+ //
2388
+ // the chain of events calls estimateRegionStats against the data
2389
+ // adapter which by default uses featureDensity, but can also respond
2390
+ // with a byte size estimate and fetch size limit (data adapter can
2391
+ // define what is too much data)
2392
+ mobxStateTree.addDisposer(self, mobx.autorun( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2() {
2393
+ var _self$estimatedRegion4, aborter, view, statsP, estimatedRegionStats;
2394
+
2395
+ return runtime_1.wrap(function _callee2$(_context2) {
2396
+ while (1) {
2397
+ switch (_context2.prev = _context2.next) {
2398
+ case 0:
2399
+ _context2.prev = 0;
2400
+ aborter = new AbortController();
2401
+ view = util.getContainingView(self);
2402
+
2403
+ if (view.initialized) {
2404
+ _context2.next = 5;
2405
+ break;
2406
+ }
2407
+
2408
+ return _context2.abrupt("return");
2409
+
2410
+ case 5:
2411
+ if (!(((_self$estimatedRegion4 = self.estimatedRegionStats) === null || _self$estimatedRegion4 === void 0 ? void 0 : _self$estimatedRegion4.featureDensity) !== undefined)) {
2412
+ _context2.next = 8;
2413
+ break;
2414
+ }
2415
+
2416
+ self.setCurrBpPerPx(view.bpPerPx);
2417
+ return _context2.abrupt("return");
2418
+
2419
+ case 8:
2420
+ if (!(view.bpPerPx === self.currBpPerPx)) {
2421
+ _context2.next = 10;
2422
+ break;
2423
+ }
2424
+
2425
+ return _context2.abrupt("return");
2426
+
2427
+ case 10:
2428
+ self.clearRegionStats();
2429
+ self.setCurrBpPerPx(view.bpPerPx);
2430
+ statsP = self.estimateRegionsStats(view.staticBlocks.contentBlocks, {
2431
+ signal: aborter.signal
2432
+ });
2433
+ self.setRegionStatsP(statsP);
2434
+ _context2.next = 16;
2435
+ return statsP;
2436
+
2437
+ case 16:
2438
+ estimatedRegionStats = _context2.sent;
2439
+
2440
+ if (mobxStateTree.isAlive(self)) {
2441
+ self.setRegionStats(estimatedRegionStats);
2442
+ }
2443
+
2444
+ _context2.next = 23;
2445
+ break;
2446
+
2447
+ case 20:
2448
+ _context2.prev = 20;
2449
+ _context2.t0 = _context2["catch"](0);
2450
+
2451
+ if (!util.isAbortException(_context2.t0) && mobxStateTree.isAlive(self)) {
2452
+ console.error(_context2.t0);
2453
+ self.setError(_context2.t0);
2454
+ }
2455
+
2456
+ case 23:
2457
+ case "end":
2458
+ return _context2.stop();
2459
+ }
2460
+ }
2461
+ }, _callee2, null, [[0, 20]]);
2462
+ })), {
2463
+ delay: 500
2464
+ }));
2465
+ }
2466
+ };
2467
+ }).views(function (self) {
2468
+ return {
2469
+ regionCannotBeRenderedText: function regionCannotBeRenderedText(_region) {
2470
+ return self.regionTooLarge ? 'Force load to see features' : '';
2207
2471
  },
2208
2472
 
2209
2473
  /**
@@ -2214,20 +2478,25 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2214
2478
  * react node allows user to force load at current setting
2215
2479
  */
2216
2480
  regionCannotBeRendered: function regionCannotBeRendered(_region) {
2217
- var view = util.getContainingView(self);
2481
+ var regionTooLarge = self.regionTooLarge,
2482
+ regionTooLargeReason = self.regionTooLargeReason;
2218
2483
 
2219
- if (view && view.bpPerPx > self.maxViewBpPerPx) {
2220
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Typography, {
2484
+ if (regionTooLarge) {
2485
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(core.Typography, {
2221
2486
  component: "span",
2222
2487
  variant: "body2"
2223
- }, "Zoom in to see features or", ' '), /*#__PURE__*/React__default.createElement(Button, {
2224
- "data-testid": "reload_button",
2488
+ }, regionTooLargeReason ? regionTooLargeReason + '. ' : '', "Zoom in to see features or", ' '), /*#__PURE__*/React__default.createElement(core.Button, {
2489
+ "data-testid": "force_reload_button",
2225
2490
  onClick: function onClick() {
2226
- self.setUserBpPerPxLimit(view.bpPerPx);
2227
- self.reload();
2491
+ if (!self.estimatedRegionStats) {
2492
+ console.error('No global stats?');
2493
+ } else {
2494
+ self.updateStatsLimit(self.estimatedRegionStats);
2495
+ self.reload();
2496
+ }
2228
2497
  },
2229
2498
  variant: "outlined"
2230
- }, "Force Load"), /*#__PURE__*/React__default.createElement(Typography, {
2499
+ }, "Force Load"), /*#__PURE__*/React__default.createElement(core.Typography, {
2231
2500
  component: "span",
2232
2501
  variant: "body2"
2233
2502
  }, "(force load may be slow)"));
@@ -2250,7 +2519,9 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2250
2519
  }] : [];
2251
2520
  },
2252
2521
  renderProps: function renderProps() {
2522
+ var view = util.getContainingView(self);
2253
2523
  return _objectSpread2(_objectSpread2({}, tracks.getParentRenderProps(self)), {}, {
2524
+ notReady: self.currBpPerPx !== view.bpPerPx || !self.estimatedRegionStats,
2254
2525
  rpcDriverName: self.rpcDriverName,
2255
2526
  displayModel: self,
2256
2527
  onFeatureClick: function onFeatureClick(_, featureId) {
@@ -2260,7 +2531,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2260
2531
  self.clearFeatureSelection();
2261
2532
  } else {
2262
2533
  var feature = self.features.get(f);
2263
- self.selectFeature(feature);
2534
+
2535
+ if (feature) {
2536
+ self.selectFeature(feature);
2537
+ }
2264
2538
  }
2265
2539
  },
2266
2540
  onClick: function onClick() {
@@ -2293,18 +2567,18 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2293
2567
  }).actions(function (self) {
2294
2568
  return {
2295
2569
  renderSvg: function renderSvg(opts) {
2296
- return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
2297
- var height, id, overrideHeight, view, viewOffsetPx, dynamicBlocks, width, renderings;
2298
- return runtime_1.wrap(function _callee$(_context) {
2570
+ return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3() {
2571
+ var height, id, overrideHeight, view, viewOffsetPx, roundedDynamicBlocks, width, renderings;
2572
+ return runtime_1.wrap(function _callee3$(_context3) {
2299
2573
  while (1) {
2300
- switch (_context.prev = _context.next) {
2574
+ switch (_context3.prev = _context3.next) {
2301
2575
  case 0:
2302
2576
  height = self.height, id = self.id;
2303
2577
  overrideHeight = opts.overrideHeight;
2304
2578
  view = util.getContainingView(self);
2305
- viewOffsetPx = view.offsetPx, dynamicBlocks = view.roundedDynamicBlocks, width = view.width;
2306
- _context.next = 6;
2307
- return Promise.all(dynamicBlocks.map(function (block) {
2579
+ viewOffsetPx = view.offsetPx, roundedDynamicBlocks = view.roundedDynamicBlocks, width = view.width;
2580
+ _context3.next = 6;
2581
+ return Promise.all(roundedDynamicBlocks.map(function (block) {
2308
2582
  var blockState$1 = blockState.create({
2309
2583
  key: block.key,
2310
2584
  region: block
@@ -2342,13 +2616,11 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2342
2616
  }));
2343
2617
 
2344
2618
  case 6:
2345
- renderings = _context.sent;
2346
- return _context.abrupt("return", /*#__PURE__*/React__default.createElement(React__default.Fragment, null, renderings.map(function (rendering, index) {
2347
- var offsetPx = dynamicBlocks[index].offsetPx;
2348
- var offset = offsetPx - viewOffsetPx; // stabalize clipid under test for snapshot
2349
-
2350
- // stabalize clipid under test for snapshot
2351
- var clipid = "clip-".concat(typeof jest === 'undefined' ? id : 'jest', "-").concat(index);
2619
+ renderings = _context3.sent;
2620
+ return _context3.abrupt("return", /*#__PURE__*/React__default.createElement(React__default.Fragment, null, renderings.map(function (rendering, index) {
2621
+ var offsetPx = roundedDynamicBlocks[index].offsetPx;
2622
+ var offset = offsetPx - viewOffsetPx;
2623
+ var clipid = getId(id, index);
2352
2624
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, {
2353
2625
  key: "frag-".concat(index)
2354
2626
  }, /*#__PURE__*/React__default.createElement("defs", null, /*#__PURE__*/React__default.createElement("clipPath", {
@@ -2362,7 +2634,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2362
2634
  transform: "translate(".concat(offset, " 0)")
2363
2635
  }, /*#__PURE__*/React__default.createElement("g", {
2364
2636
  clipPath: "url(#".concat(clipid, ")")
2365
- }, /*#__PURE__*/React__default.isValidElement(rendering.reactElement) ? rendering.reactElement : /*#__PURE__*/React__default.createElement("g", {
2637
+ }, /*#__PURE__*/React__default.isValidElement(rendering.reactElement) ? rendering.reactElement :
2638
+ /*#__PURE__*/
2639
+ // eslint-disable-next-line react/no-danger
2640
+ React__default.createElement("g", {
2366
2641
  dangerouslySetInnerHTML: {
2367
2642
  __html: rendering.html
2368
2643
  }
@@ -2371,10 +2646,10 @@ var BaseLinearDisplay$1 = /*#__PURE__*/mobxStateTree.types.compose('BaseLinearDi
2371
2646
 
2372
2647
  case 8:
2373
2648
  case "end":
2374
- return _context.stop();
2649
+ return _context3.stop();
2375
2650
  }
2376
2651
  }
2377
- }, _callee);
2652
+ }, _callee3);
2378
2653
  }))();
2379
2654
  }
2380
2655
  };
@@ -3572,6 +3847,8 @@ var MyPopper = function MyPopper(props) {
3572
3847
 
3573
3848
  function RefNameAutocomplete(_ref) {
3574
3849
  var model = _ref.model,
3850
+ _ref$showHelp = _ref.showHelp,
3851
+ showHelp = _ref$showHelp === void 0 ? true : _ref$showHelp,
3575
3852
  onSelect = _ref.onSelect,
3576
3853
  assemblyName = _ref.assemblyName,
3577
3854
  style = _ref.style,
@@ -3782,11 +4059,11 @@ function RefNameAutocomplete(_ref) {
3782
4059
  style: {
3783
4060
  marginRight: 7
3784
4061
  }
3785
- }, /*#__PURE__*/React__default.createElement(SearchIcon, null), /*#__PURE__*/React__default.createElement(core.IconButton, {
4062
+ }, /*#__PURE__*/React__default.createElement(SearchIcon, null), showHelp ? /*#__PURE__*/React__default.createElement(core.IconButton, {
3786
4063
  onClick: function onClick() {
3787
4064
  return setHelpDialogDisplayed(true);
3788
4065
  }
3789
- }, /*#__PURE__*/React__default.createElement(HelpIcon, null))), params.InputProps.endAdornment)
4066
+ }, /*#__PURE__*/React__default.createElement(HelpIcon, null)) : null), params.InputProps.endAdornment)
3790
4067
  }),
3791
4068
  placeholder: "Search for location",
3792
4069
  onChange: function onChange(e) {
@@ -3820,65 +4097,233 @@ function RefNameAutocomplete(_ref) {
3820
4097
 
3821
4098
  var RefNameAutocomplete$1 = /*#__PURE__*/mobxReact.observer(RefNameAutocomplete);
3822
4099
 
3823
- var useStyles$7 = /*#__PURE__*/styles.makeStyles(function (theme) {
4100
+ var useStyles$7 = /*#__PURE__*/core.makeStyles(function () {
3824
4101
  return {
3825
- closeButton: {
3826
- position: 'absolute',
3827
- right: theme.spacing(1),
3828
- top: theme.spacing(1),
3829
- color: theme.palette.grey[500]
4102
+ headerRefName: {
4103
+ minWidth: 100
3830
4104
  }
3831
4105
  };
3832
4106
  });
3833
- function ExportSvgDlg(_ref) {
4107
+
4108
+ function SearchBox(_ref) {
3834
4109
  var model = _ref.model,
3835
- handleClose = _ref.handleClose;
3836
- // @ts-ignore
3837
- var offscreenCanvas = typeof OffscreenCanvas !== 'undefined';
4110
+ showHelp = _ref.showHelp;
4111
+ var classes = useStyles$7();
4112
+ var theme = core.useTheme();
4113
+ var session = util.getSession(model);
4114
+ var textSearchManager = session.textSearchManager,
4115
+ assemblyManager = session.assemblyManager;
4116
+ var assemblyNames = model.assemblyNames,
4117
+ rankSearchResults = model.rankSearchResults;
4118
+ var assemblyName = assemblyNames[0];
4119
+ var assembly = assemblyManager.get(assemblyName);
4120
+ var searchScope = model.searchScope(assemblyName);
3838
4121
 
3839
- var _useState = React.useState(offscreenCanvas),
3840
- _useState2 = _slicedToArray(_useState, 2),
3841
- rasterizeLayers = _useState2[0],
3842
- setRasterizeLayers = _useState2[1];
4122
+ function fetchResults(_x, _x2) {
4123
+ return _fetchResults.apply(this, arguments);
4124
+ }
3843
4125
 
3844
- var _useState3 = React.useState(false),
3845
- _useState4 = _slicedToArray(_useState3, 2),
3846
- loading = _useState4[0],
3847
- setLoading = _useState4[1];
4126
+ function _fetchResults() {
4127
+ _fetchResults = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(query, searchType) {
4128
+ var _assembly$allRefNames;
3848
4129
 
3849
- var _useState5 = React.useState(),
3850
- _useState6 = _slicedToArray(_useState5, 2),
3851
- error = _useState6[0],
3852
- setError = _useState6[1];
4130
+ var textSearchResults, refNameResults;
4131
+ return runtime_1.wrap(function _callee$(_context) {
4132
+ while (1) {
4133
+ switch (_context.prev = _context.next) {
4134
+ case 0:
4135
+ if (!textSearchManager) {
4136
+ console.warn('No text search manager');
4137
+ }
3853
4138
 
3854
- var classes = useStyles$7();
3855
- return /*#__PURE__*/React__default.createElement(core.Dialog, {
3856
- open: true,
3857
- onClose: handleClose
3858
- }, /*#__PURE__*/React__default.createElement(core.DialogTitle, null, "Export SVG", /*#__PURE__*/React__default.createElement(core.IconButton, {
3859
- className: classes.closeButton,
3860
- onClick: handleClose
3861
- }, /*#__PURE__*/React__default.createElement(CloseIcon, null))), /*#__PURE__*/React__default.createElement(core.DialogContent, null, error ? /*#__PURE__*/React__default.createElement("div", {
3862
- style: {
3863
- color: 'red'
3864
- }
3865
- }, "".concat(error)) : loading ? /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement(core.CircularProgress, {
3866
- size: 20,
3867
- style: {
3868
- marginRight: 20
3869
- }
3870
- }), /*#__PURE__*/React__default.createElement(core.Typography, {
3871
- display: "inline"
3872
- }, "Creating SVG")) : null, offscreenCanvas ? /*#__PURE__*/React__default.createElement(core.FormControlLabel, {
3873
- control: /*#__PURE__*/React__default.createElement(core.Checkbox, {
3874
- checked: rasterizeLayers,
3875
- onChange: function onChange() {
3876
- return setRasterizeLayers(function (val) {
3877
- return !val;
3878
- });
3879
- }
3880
- }),
3881
- label: "Rasterize canvas based tracks? File may be much larger if this is turned off"
4139
+ _context.next = 3;
4140
+ return textSearchManager === null || textSearchManager === void 0 ? void 0 : textSearchManager.search({
4141
+ queryString: query,
4142
+ searchType: searchType
4143
+ }, searchScope, rankSearchResults);
4144
+
4145
+ case 3:
4146
+ textSearchResults = _context.sent;
4147
+ refNameResults = assembly === null || assembly === void 0 ? void 0 : (_assembly$allRefNames = assembly.allRefNames) === null || _assembly$allRefNames === void 0 ? void 0 : _assembly$allRefNames.filter(function (refName) {
4148
+ return refName.startsWith(query);
4149
+ }).map(function (r) {
4150
+ return new BaseResult__default({
4151
+ label: r
4152
+ });
4153
+ }).slice(0, 10);
4154
+ return _context.abrupt("return", dedupe([].concat(_toConsumableArray(refNameResults || []), _toConsumableArray(textSearchResults || [])), function (elt) {
4155
+ return elt.getId();
4156
+ }));
4157
+
4158
+ case 6:
4159
+ case "end":
4160
+ return _context.stop();
4161
+ }
4162
+ }
4163
+ }, _callee);
4164
+ }));
4165
+ return _fetchResults.apply(this, arguments);
4166
+ }
4167
+
4168
+ function handleSelectedRegion(_x3) {
4169
+ return _handleSelectedRegion.apply(this, arguments);
4170
+ }
4171
+
4172
+ function _handleSelectedRegion() {
4173
+ _handleSelectedRegion = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(option) {
4174
+ var trackId, location, label, _assembly$allRefNames2, results;
4175
+
4176
+ return runtime_1.wrap(function _callee2$(_context2) {
4177
+ while (1) {
4178
+ switch (_context2.prev = _context2.next) {
4179
+ case 0:
4180
+ trackId = option.getTrackId();
4181
+ location = option.getLocation();
4182
+ label = option.getLabel();
4183
+ _context2.prev = 3;
4184
+
4185
+ if (!(assembly !== null && assembly !== void 0 && (_assembly$allRefNames2 = assembly.allRefNames) !== null && _assembly$allRefNames2 !== void 0 && _assembly$allRefNames2.includes(location))) {
4186
+ _context2.next = 8;
4187
+ break;
4188
+ }
4189
+
4190
+ model.navToLocString(location);
4191
+ _context2.next = 19;
4192
+ break;
4193
+
4194
+ case 8:
4195
+ _context2.next = 10;
4196
+ return fetchResults(label, 'exact');
4197
+
4198
+ case 10:
4199
+ results = _context2.sent;
4200
+
4201
+ if (!(results && results.length > 1)) {
4202
+ _context2.next = 16;
4203
+ break;
4204
+ }
4205
+
4206
+ model.setSearchResults(results, label.toLowerCase());
4207
+ return _context2.abrupt("return");
4208
+
4209
+ case 16:
4210
+ if ((results === null || results === void 0 ? void 0 : results.length) === 1) {
4211
+ location = results[0].getLocation();
4212
+ trackId = results[0].getTrackId();
4213
+ }
4214
+
4215
+ case 17:
4216
+ model.navToLocString(location, assemblyName);
4217
+
4218
+ if (trackId) {
4219
+ model.showTrack(trackId);
4220
+ }
4221
+
4222
+ case 19:
4223
+ _context2.next = 25;
4224
+ break;
4225
+
4226
+ case 21:
4227
+ _context2.prev = 21;
4228
+ _context2.t0 = _context2["catch"](3);
4229
+ console.error(_context2.t0);
4230
+ session.notify("".concat(_context2.t0), 'warning');
4231
+
4232
+ case 25:
4233
+ case "end":
4234
+ return _context2.stop();
4235
+ }
4236
+ }
4237
+ }, _callee2, null, [[3, 21]]);
4238
+ }));
4239
+ return _handleSelectedRegion.apply(this, arguments);
4240
+ }
4241
+
4242
+ return /*#__PURE__*/React__default.createElement(RefNameAutocomplete$1, {
4243
+ showHelp: showHelp,
4244
+ onSelect: handleSelectedRegion,
4245
+ assemblyName: assemblyName,
4246
+ fetchResults: fetchResults,
4247
+ model: model,
4248
+ TextFieldProps: {
4249
+ variant: 'outlined',
4250
+ className: classes.headerRefName,
4251
+ style: {
4252
+ margin: SPACING,
4253
+ minWidth: '175px'
4254
+ },
4255
+ InputProps: {
4256
+ style: {
4257
+ padding: 0,
4258
+ height: WIDGET_HEIGHT,
4259
+ background: core.alpha(theme.palette.background.paper, 0.8)
4260
+ }
4261
+ }
4262
+ }
4263
+ });
4264
+ }
4265
+
4266
+ var SearchBox$1 = /*#__PURE__*/mobxReact.observer(SearchBox);
4267
+
4268
+ var useStyles$8 = /*#__PURE__*/styles.makeStyles(function (theme) {
4269
+ return {
4270
+ closeButton: {
4271
+ position: 'absolute',
4272
+ right: theme.spacing(1),
4273
+ top: theme.spacing(1),
4274
+ color: theme.palette.grey[500]
4275
+ }
4276
+ };
4277
+ });
4278
+ function ExportSvgDlg(_ref) {
4279
+ var model = _ref.model,
4280
+ handleClose = _ref.handleClose;
4281
+ // @ts-ignore
4282
+ var offscreenCanvas = typeof OffscreenCanvas !== 'undefined';
4283
+
4284
+ var _useState = React.useState(offscreenCanvas),
4285
+ _useState2 = _slicedToArray(_useState, 2),
4286
+ rasterizeLayers = _useState2[0],
4287
+ setRasterizeLayers = _useState2[1];
4288
+
4289
+ var _useState3 = React.useState(false),
4290
+ _useState4 = _slicedToArray(_useState3, 2),
4291
+ loading = _useState4[0],
4292
+ setLoading = _useState4[1];
4293
+
4294
+ var _useState5 = React.useState(),
4295
+ _useState6 = _slicedToArray(_useState5, 2),
4296
+ error = _useState6[0],
4297
+ setError = _useState6[1];
4298
+
4299
+ var classes = useStyles$8();
4300
+ return /*#__PURE__*/React__default.createElement(core.Dialog, {
4301
+ open: true,
4302
+ onClose: handleClose
4303
+ }, /*#__PURE__*/React__default.createElement(core.DialogTitle, null, "Export SVG", /*#__PURE__*/React__default.createElement(core.IconButton, {
4304
+ className: classes.closeButton,
4305
+ onClick: handleClose
4306
+ }, /*#__PURE__*/React__default.createElement(CloseIcon, null))), /*#__PURE__*/React__default.createElement(core.DialogContent, null, error ? /*#__PURE__*/React__default.createElement("div", {
4307
+ style: {
4308
+ color: 'red'
4309
+ }
4310
+ }, "".concat(error)) : loading ? /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement(core.CircularProgress, {
4311
+ size: 20,
4312
+ style: {
4313
+ marginRight: 20
4314
+ }
4315
+ }), /*#__PURE__*/React__default.createElement(core.Typography, {
4316
+ display: "inline"
4317
+ }, "Creating SVG")) : null, offscreenCanvas ? /*#__PURE__*/React__default.createElement(core.FormControlLabel, {
4318
+ control: /*#__PURE__*/React__default.createElement(core.Checkbox, {
4319
+ checked: rasterizeLayers,
4320
+ onChange: function onChange() {
4321
+ return setRasterizeLayers(function (val) {
4322
+ return !val;
4323
+ });
4324
+ }
4325
+ }),
4326
+ label: "Rasterize canvas based tracks? File may be much larger if this is turned off"
3882
4327
  }) : /*#__PURE__*/React__default.createElement(core.Typography, null, "Note: rasterizing layers not yet supported in this browser, so SVG size may be large")), /*#__PURE__*/React__default.createElement(core.DialogActions, null, /*#__PURE__*/React__default.createElement(core.Button, {
3883
4328
  variant: "contained",
3884
4329
  color: "secondary",
@@ -3936,7 +4381,7 @@ function ExportSvgDlg(_ref) {
3936
4381
  }, "Submit")));
3937
4382
  }
3938
4383
 
3939
- var useStyles$8 = /*#__PURE__*/styles.makeStyles(function (theme) {
4384
+ var useStyles$9 = /*#__PURE__*/styles.makeStyles(function (theme) {
3940
4385
  return {
3941
4386
  closeButton: {
3942
4387
  position: 'absolute',
@@ -3950,7 +4395,7 @@ var useStyles$8 = /*#__PURE__*/styles.makeStyles(function (theme) {
3950
4395
  function ReturnToImportFormDialog(_ref) {
3951
4396
  var model = _ref.model,
3952
4397
  handleClose = _ref.handleClose;
3953
- var classes = useStyles$8();
4398
+ var classes = useStyles$9();
3954
4399
  return /*#__PURE__*/React__default.createElement(core.Dialog, {
3955
4400
  maxWidth: "xl",
3956
4401
  open: true,
@@ -3980,7 +4425,7 @@ function ReturnToImportFormDialog(_ref) {
3980
4425
 
3981
4426
  var ReturnToImportFormDlg = /*#__PURE__*/mobxReact.observer(ReturnToImportFormDialog);
3982
4427
 
3983
- var useStyles$9 = /*#__PURE__*/styles.makeStyles({
4428
+ var useStyles$a = /*#__PURE__*/styles.makeStyles({
3984
4429
  container: {
3985
4430
  display: 'flex',
3986
4431
  flexDirection: 'row',
@@ -3993,7 +4438,7 @@ var useStyles$9 = /*#__PURE__*/styles.makeStyles({
3993
4438
 
3994
4439
  function ZoomControls(_ref) {
3995
4440
  var model = _ref.model;
3996
- var classes = useStyles$9();
4441
+ var classes = useStyles$a();
3997
4442
  var maxBpPerPx = model.maxBpPerPx,
3998
4443
  minBpPerPx = model.minBpPerPx,
3999
4444
  bpPerPx = model.bpPerPx,
@@ -4040,9 +4485,7 @@ function ZoomControls(_ref) {
4040
4485
 
4041
4486
  var ZoomControls$1 = /*#__PURE__*/mobxReact.observer(ZoomControls);
4042
4487
 
4043
- var WIDGET_HEIGHT = 32;
4044
- var SPACING = 7;
4045
- var useStyles$a = /*#__PURE__*/core.makeStyles(function (theme) {
4488
+ var useStyles$b = /*#__PURE__*/core.makeStyles(function (theme) {
4046
4489
  return {
4047
4490
  headerBar: {
4048
4491
  height: HEADER_BAR_HEIGHT,
@@ -4055,10 +4498,6 @@ var useStyles$a = /*#__PURE__*/core.makeStyles(function (theme) {
4055
4498
  spacer: {
4056
4499
  flexGrow: 1
4057
4500
  },
4058
- input: {},
4059
- headerRefName: {
4060
- minWidth: 100
4061
- },
4062
4501
  panButton: {
4063
4502
  background: core.alpha(theme.palette.background.paper, 0.8),
4064
4503
  height: WIDGET_HEIGHT,
@@ -4079,9 +4518,9 @@ var useStyles$a = /*#__PURE__*/core.makeStyles(function (theme) {
4079
4518
  }
4080
4519
  };
4081
4520
  });
4082
- var Controls = /*#__PURE__*/mobxReact.observer(function (_ref) {
4521
+ var HeaderButtons = /*#__PURE__*/mobxReact.observer(function (_ref) {
4083
4522
  var model = _ref.model;
4084
- var classes = useStyles$a();
4523
+ var classes = useStyles$b();
4085
4524
  return /*#__PURE__*/React__default.createElement(core.Button, {
4086
4525
  onClick: model.activateTrackSelector,
4087
4526
  className: classes.toggleButton,
@@ -4095,7 +4534,7 @@ var Controls = /*#__PURE__*/mobxReact.observer(function (_ref) {
4095
4534
 
4096
4535
  function PanControls(_ref2) {
4097
4536
  var model = _ref2.model;
4098
- var classes = useStyles$a();
4537
+ var classes = useStyles$b();
4099
4538
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(core.Button, {
4100
4539
  variant: "outlined",
4101
4540
  className: classes.panButton,
@@ -4113,150 +4552,21 @@ function PanControls(_ref2) {
4113
4552
 
4114
4553
  var RegionWidth = /*#__PURE__*/mobxReact.observer(function (_ref3) {
4115
4554
  var model = _ref3.model;
4116
- var classes = useStyles$a();
4555
+ var classes = useStyles$b();
4117
4556
  var coarseTotalBp = model.coarseTotalBp;
4118
4557
  return /*#__PURE__*/React__default.createElement(core.Typography, {
4119
4558
  variant: "body2",
4120
4559
  color: "textSecondary",
4121
4560
  className: classes.bp
4122
- }, "".concat(Math.round(coarseTotalBp).toLocaleString('en-US'), " bp"));
4561
+ }, Math.round(coarseTotalBp).toLocaleString('en-US'), " bp");
4123
4562
  });
4124
- var LinearGenomeViewHeader = /*#__PURE__*/mobxReact.observer(function (_ref4) {
4125
- var model = _ref4.model;
4126
- var classes = useStyles$a();
4127
- var theme = core.useTheme();
4128
- var session = util.getSession(model);
4129
- var textSearchManager = session.textSearchManager,
4130
- assemblyManager = session.assemblyManager;
4131
- var assemblyNames = model.assemblyNames,
4132
- rankSearchResults = model.rankSearchResults;
4133
- var assemblyName = assemblyNames[0];
4134
- var assembly = assemblyManager.get(assemblyName);
4135
- var searchScope = model.searchScope(assemblyName);
4136
-
4137
- function fetchResults(_x, _x2) {
4138
- return _fetchResults.apply(this, arguments);
4139
- }
4140
-
4141
- function _fetchResults() {
4142
- _fetchResults = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(query, searchType) {
4143
- var _assembly$allRefNames;
4144
-
4145
- var textSearchResults, refNameResults;
4146
- return runtime_1.wrap(function _callee$(_context) {
4147
- while (1) {
4148
- switch (_context.prev = _context.next) {
4149
- case 0:
4150
- if (!textSearchManager) {
4151
- console.warn('No text search manager');
4152
- }
4153
-
4154
- _context.next = 3;
4155
- return textSearchManager === null || textSearchManager === void 0 ? void 0 : textSearchManager.search({
4156
- queryString: query,
4157
- searchType: searchType
4158
- }, searchScope, rankSearchResults);
4159
-
4160
- case 3:
4161
- textSearchResults = _context.sent;
4162
- refNameResults = assembly === null || assembly === void 0 ? void 0 : (_assembly$allRefNames = assembly.allRefNames) === null || _assembly$allRefNames === void 0 ? void 0 : _assembly$allRefNames.filter(function (refName) {
4163
- return refName.startsWith(query);
4164
- }).map(function (r) {
4165
- return new BaseResult__default({
4166
- label: r
4167
- });
4168
- }).slice(0, 10);
4169
- return _context.abrupt("return", dedupe([].concat(_toConsumableArray(refNameResults || []), _toConsumableArray(textSearchResults || [])), function (elt) {
4170
- return elt.getId();
4171
- }));
4172
-
4173
- case 6:
4174
- case "end":
4175
- return _context.stop();
4176
- }
4177
- }
4178
- }, _callee);
4179
- }));
4180
- return _fetchResults.apply(this, arguments);
4181
- }
4182
-
4183
- function handleSelectedRegion(_x3) {
4184
- return _handleSelectedRegion.apply(this, arguments);
4185
- }
4186
-
4187
- function _handleSelectedRegion() {
4188
- _handleSelectedRegion = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(option) {
4189
- var trackId, location, label, _assembly$allRefNames2, results;
4190
-
4191
- return runtime_1.wrap(function _callee2$(_context2) {
4192
- while (1) {
4193
- switch (_context2.prev = _context2.next) {
4194
- case 0:
4195
- trackId = option.getTrackId();
4196
- location = option.getLocation();
4197
- label = option.getLabel();
4198
- _context2.prev = 3;
4199
-
4200
- if (!(assembly !== null && assembly !== void 0 && (_assembly$allRefNames2 = assembly.allRefNames) !== null && _assembly$allRefNames2 !== void 0 && _assembly$allRefNames2.includes(location))) {
4201
- _context2.next = 8;
4202
- break;
4203
- }
4204
-
4205
- model.navToLocString(location);
4206
- _context2.next = 19;
4207
- break;
4208
-
4209
- case 8:
4210
- _context2.next = 10;
4211
- return fetchResults(label, 'exact');
4212
-
4213
- case 10:
4214
- results = _context2.sent;
4215
-
4216
- if (!(results && results.length > 1)) {
4217
- _context2.next = 16;
4218
- break;
4219
- }
4220
-
4221
- model.setSearchResults(results, label.toLowerCase());
4222
- return _context2.abrupt("return");
4223
-
4224
- case 16:
4225
- if ((results === null || results === void 0 ? void 0 : results.length) === 1) {
4226
- location = results[0].getLocation();
4227
- trackId = results[0].getTrackId();
4228
- }
4229
-
4230
- case 17:
4231
- model.navToLocString(location, assemblyName);
4232
-
4233
- if (trackId) {
4234
- model.showTrack(trackId);
4235
- }
4236
-
4237
- case 19:
4238
- _context2.next = 25;
4239
- break;
4240
-
4241
- case 21:
4242
- _context2.prev = 21;
4243
- _context2.t0 = _context2["catch"](3);
4244
- console.error(_context2.t0);
4245
- session.notify("".concat(_context2.t0), 'warning');
4246
4563
 
4247
- case 25:
4248
- case "end":
4249
- return _context2.stop();
4250
- }
4251
- }
4252
- }, _callee2, null, [[3, 21]]);
4253
- }));
4254
- return _handleSelectedRegion.apply(this, arguments);
4255
- }
4256
-
4257
- var controls = /*#__PURE__*/React__default.createElement("div", {
4564
+ var Controls = function Controls(_ref4) {
4565
+ var model = _ref4.model;
4566
+ var classes = useStyles$b();
4567
+ return /*#__PURE__*/React__default.createElement("div", {
4258
4568
  className: classes.headerBar
4259
- }, /*#__PURE__*/React__default.createElement(Controls, {
4569
+ }, /*#__PURE__*/React__default.createElement(HeaderButtons, {
4260
4570
  model: model
4261
4571
  }), /*#__PURE__*/React__default.createElement("div", {
4262
4572
  className: classes.spacer
@@ -4265,26 +4575,8 @@ var LinearGenomeViewHeader = /*#__PURE__*/mobxReact.observer(function (_ref4) {
4265
4575
  className: classes.headerForm
4266
4576
  }, /*#__PURE__*/React__default.createElement(PanControls, {
4267
4577
  model: model
4268
- }), /*#__PURE__*/React__default.createElement(RefNameAutocomplete$1, {
4269
- onSelect: handleSelectedRegion,
4270
- assemblyName: assemblyName,
4271
- fetchResults: fetchResults,
4272
- model: model,
4273
- TextFieldProps: {
4274
- variant: 'outlined',
4275
- className: classes.headerRefName,
4276
- style: {
4277
- margin: SPACING,
4278
- minWidth: '175px'
4279
- },
4280
- InputProps: {
4281
- style: {
4282
- padding: 0,
4283
- height: WIDGET_HEIGHT,
4284
- background: core.alpha(theme.palette.background.paper, 0.8)
4285
- }
4286
- }
4287
- }
4578
+ }), /*#__PURE__*/React__default.createElement(SearchBox$1, {
4579
+ model: model
4288
4580
  })), /*#__PURE__*/React__default.createElement(RegionWidth, {
4289
4581
  model: model
4290
4582
  }), /*#__PURE__*/React__default.createElement(ZoomControls$1, {
@@ -4292,20 +4584,23 @@ var LinearGenomeViewHeader = /*#__PURE__*/mobxReact.observer(function (_ref4) {
4292
4584
  }), /*#__PURE__*/React__default.createElement("div", {
4293
4585
  className: classes.spacer
4294
4586
  }));
4587
+ };
4295
4588
 
4296
- if (model.hideHeaderOverview) {
4297
- return controls;
4298
- }
4299
-
4300
- return /*#__PURE__*/React__default.createElement(OverviewScaleBar$1, {
4589
+ var LinearGenomeViewHeader = /*#__PURE__*/mobxReact.observer(function (_ref5) {
4590
+ var model = _ref5.model;
4591
+ return model.hideHeaderOverview ? /*#__PURE__*/React__default.createElement(Controls, {
4592
+ model: model
4593
+ }) : /*#__PURE__*/React__default.createElement(OverviewScaleBar$1, {
4594
+ model: model
4595
+ }, /*#__PURE__*/React__default.createElement(Controls, {
4301
4596
  model: model
4302
- }, controls);
4597
+ }));
4303
4598
  });
4304
4599
 
4305
- var useStyles$b = /*#__PURE__*/styles.makeStyles(function (theme) {
4600
+ var useStyles$c = /*#__PURE__*/core.makeStyles(function (theme) {
4306
4601
  return {
4307
4602
  root: {
4308
- background: styles.alpha(theme.palette.background.paper, 0.8),
4603
+ background: core.alpha(theme.palette.background.paper, 0.8),
4309
4604
  '&:hover': {
4310
4605
  background: theme.palette.background.paper
4311
4606
  },
@@ -4336,7 +4631,7 @@ var useStyles$b = /*#__PURE__*/styles.makeStyles(function (theme) {
4336
4631
  var TrackLabel = /*#__PURE__*/React__default.forwardRef(function (props, ref) {
4337
4632
  var _session$getTrackActi;
4338
4633
 
4339
- var classes = useStyles$b();
4634
+ var classes = useStyles$c();
4340
4635
 
4341
4636
  var _React$useState = React__default.useState(null),
4342
4637
  _React$useState2 = _slicedToArray(_React$useState, 2),
@@ -4388,7 +4683,7 @@ var TrackLabel = /*#__PURE__*/React__default.forwardRef(function (props, ref) {
4388
4683
  }
4389
4684
 
4390
4685
  var items = track.trackMenuItems();
4391
- return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Paper, {
4686
+ return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(core.Paper, {
4392
4687
  ref: ref,
4393
4688
  className: clsx(className, classes.root)
4394
4689
  }, /*#__PURE__*/React__default.createElement("span", {
@@ -4399,18 +4694,18 @@ var TrackLabel = /*#__PURE__*/React__default.forwardRef(function (props, ref) {
4399
4694
  "data-testid": "dragHandle-".concat(view.id, "-").concat(trackId)
4400
4695
  }, /*#__PURE__*/React__default.createElement(DragIcon, {
4401
4696
  className: classes.dragHandleIcon
4402
- })), /*#__PURE__*/React__default.createElement(IconButton, {
4697
+ })), /*#__PURE__*/React__default.createElement(core.IconButton, {
4403
4698
  onClick: function onClick() {
4404
4699
  return view.hideTrack(trackId);
4405
4700
  },
4406
4701
  className: classes.iconButton,
4407
4702
  title: "close this track",
4408
4703
  color: "secondary"
4409
- }, /*#__PURE__*/React__default.createElement(CloseIcon, null)), /*#__PURE__*/React__default.createElement(Typography, {
4704
+ }, /*#__PURE__*/React__default.createElement(CloseIcon, null)), /*#__PURE__*/React__default.createElement(core.Typography, {
4410
4705
  variant: "body1",
4411
4706
  component: "span",
4412
4707
  className: classes.trackName
4413
- }, trackName), /*#__PURE__*/React__default.createElement(IconButton, {
4708
+ }, trackName), /*#__PURE__*/React__default.createElement(core.IconButton, {
4414
4709
  "aria-controls": "simple-menu",
4415
4710
  "aria-haspopup": "true",
4416
4711
  onClick: handleClick,
@@ -4430,7 +4725,7 @@ var TrackLabel = /*#__PURE__*/React__default.forwardRef(function (props, ref) {
4430
4725
  });
4431
4726
  var TrackLabel$1 = /*#__PURE__*/mobxReact.observer(TrackLabel);
4432
4727
 
4433
- var useStyles$c = /*#__PURE__*/styles.makeStyles(function (theme) {
4728
+ var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4434
4729
  return {
4435
4730
  root: {},
4436
4731
  resizeHandle: {
@@ -4479,7 +4774,7 @@ var useStyles$c = /*#__PURE__*/styles.makeStyles(function (theme) {
4479
4774
  });
4480
4775
 
4481
4776
  function TrackContainer(props) {
4482
- var classes = useStyles$c();
4777
+ var classes = useStyles$d();
4483
4778
  var model = props.model,
4484
4779
  track = props.track;
4485
4780
  var display = track.displays[0];
@@ -4561,7 +4856,7 @@ function TrackContainer(props) {
4561
4856
 
4562
4857
  var TrackContainer$1 = /*#__PURE__*/mobxReact.observer(TrackContainer);
4563
4858
 
4564
- var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4859
+ var useStyles$e = /*#__PURE__*/styles.makeStyles(function (theme) {
4565
4860
  var background = theme.palette.tertiary ? colorManipulator.alpha(theme.palette.tertiary.main, 0.7) : colorManipulator.alpha(theme.palette.primary.main, 0.7);
4566
4861
  return {
4567
4862
  rubberBand: {
@@ -4600,7 +4895,7 @@ var useStyles$d = /*#__PURE__*/styles.makeStyles(function (theme) {
4600
4895
  var VerticalGuide = /*#__PURE__*/mobxReact.observer(function (_ref) {
4601
4896
  var model = _ref.model,
4602
4897
  coordX = _ref.coordX;
4603
- var classes = useStyles$d();
4898
+ var classes = useStyles$e();
4604
4899
  return /*#__PURE__*/React__default.createElement(Tooltip$1, {
4605
4900
  open: true,
4606
4901
  placement: "top",
@@ -4644,7 +4939,7 @@ function RubberBand(_ref2) {
4644
4939
 
4645
4940
  var controlsRef = React.useRef(null);
4646
4941
  var rubberBandRef = React.useRef(null);
4647
- var classes = useStyles$d();
4942
+ var classes = useStyles$e();
4648
4943
  var mouseDragging = startX !== undefined && anchorPosition === undefined;
4649
4944
  var setOffsets = model.setOffsets,
4650
4945
  pxToBp = model.pxToBp;
@@ -4847,7 +5142,7 @@ RubberBand.defaultProps = {
4847
5142
  var RubberBand$1 = /*#__PURE__*/mobxReact.observer(RubberBand);
4848
5143
 
4849
5144
  var _excluded$1 = ["model", "style", "className"];
4850
- var useStyles$e = /*#__PURE__*/styles.makeStyles(function (theme) {
5145
+ var useStyles$f = /*#__PURE__*/styles.makeStyles(function (theme) {
4851
5146
  return {
4852
5147
  scaleBarContainer: {
4853
5148
  overflow: 'hidden',
@@ -4891,7 +5186,7 @@ var useStyles$e = /*#__PURE__*/styles.makeStyles(function (theme) {
4891
5186
  });
4892
5187
  var RenderedRefNameLabels = /*#__PURE__*/mobxReact.observer(function (_ref) {
4893
5188
  var model = _ref.model;
4894
- var classes = useStyles$e(); // find the block that needs pinning to the left side for context
5189
+ var classes = useStyles$f(); // find the block that needs pinning to the left side for context
4895
5190
 
4896
5191
  var lastLeftBlock = 0;
4897
5192
  model.staticBlocks.forEach(function (block, i) {
@@ -4913,7 +5208,7 @@ var RenderedRefNameLabels = /*#__PURE__*/mobxReact.observer(function (_ref) {
4913
5208
  });
4914
5209
  var RenderedScaleBarLabels = /*#__PURE__*/mobxReact.observer(function (_ref2) {
4915
5210
  var model = _ref2.model;
4916
- var classes = useStyles$e();
5211
+ var classes = useStyles$f();
4917
5212
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, model.staticBlocks.map(function (block, index) {
4918
5213
  if (block instanceof blockTypes.ContentBlock) {
4919
5214
  var ticks = makeTicks(block.start, block.end, model.bpPerPx, true, false);
@@ -4966,7 +5261,7 @@ var ScaleBar$2 = /*#__PURE__*/React__default.forwardRef(function (_ref3, ref) {
4966
5261
  className = _ref3.className,
4967
5262
  other = _objectWithoutProperties(_ref3, _excluded$1);
4968
5263
 
4969
- var classes = useStyles$e();
5264
+ var classes = useStyles$f();
4970
5265
  var offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
4971
5266
  return /*#__PURE__*/React__default.createElement(Paper, Object.assign({
4972
5267
  "data-resizer": "true" // used to avoid click-and-drag scrolls on trackscontainer
@@ -4994,7 +5289,7 @@ var ScaleBar$2 = /*#__PURE__*/React__default.forwardRef(function (_ref3, ref) {
4994
5289
  });
4995
5290
  var ScaleBar$3 = /*#__PURE__*/mobxReact.observer(ScaleBar$2);
4996
5291
 
4997
- var useStyles$f = /*#__PURE__*/styles.makeStyles(function (theme) {
5292
+ var useStyles$g = /*#__PURE__*/styles.makeStyles(function (theme) {
4998
5293
  return {
4999
5294
  verticalGuidesZoomContainer: {
5000
5295
  position: 'absolute',
@@ -5025,7 +5320,7 @@ var useStyles$f = /*#__PURE__*/styles.makeStyles(function (theme) {
5025
5320
  });
5026
5321
  var RenderedVerticalGuides = /*#__PURE__*/mobxReact.observer(function (_ref) {
5027
5322
  var model = _ref.model;
5028
- var classes = useStyles$f();
5323
+ var classes = useStyles$g();
5029
5324
  return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, model.staticBlocks.map(function (block, index) {
5030
5325
  if (block instanceof blockTypes.ContentBlock) {
5031
5326
  var ticks = makeTicks(block.start, block.end, model.bpPerPx);
@@ -5065,7 +5360,7 @@ var RenderedVerticalGuides = /*#__PURE__*/mobxReact.observer(function (_ref) {
5065
5360
 
5066
5361
  function VerticalGuides(_ref2) {
5067
5362
  var model = _ref2.model;
5068
- var classes = useStyles$f(); // find the block that needs pinning to the left side for context
5363
+ var classes = useStyles$g(); // find the block that needs pinning to the left side for context
5069
5364
 
5070
5365
  var offsetLeft = model.staticBlocks.offsetPx - model.offsetPx;
5071
5366
  return /*#__PURE__*/React__default.createElement("div", {
@@ -5086,7 +5381,7 @@ function VerticalGuides(_ref2) {
5086
5381
 
5087
5382
  var VerticalGuides$1 = /*#__PURE__*/mobxReact.observer(VerticalGuides);
5088
5383
 
5089
- var useStyles$g = /*#__PURE__*/styles.makeStyles(function () {
5384
+ var useStyles$h = /*#__PURE__*/styles.makeStyles(function () {
5090
5385
  return {
5091
5386
  centerLineContainer: {
5092
5387
  background: 'transparent',
@@ -5115,7 +5410,7 @@ function CenterLine(_ref) {
5115
5410
  tracks = model.tracks,
5116
5411
  width = model.width;
5117
5412
  var ref = React.useRef(null);
5118
- var classes = useStyles$g();
5413
+ var classes = useStyles$h();
5119
5414
  var startingPosition = width / 2;
5120
5415
  return tracks.length ? /*#__PURE__*/React__default.createElement("div", {
5121
5416
  "data-testid": "centerline_container",
@@ -5142,7 +5437,7 @@ CenterLine.propTypes = {
5142
5437
  };
5143
5438
  var CenterLine$1 = /*#__PURE__*/mobxReact.observer(CenterLine);
5144
5439
 
5145
- var useStyles$h = /*#__PURE__*/styles.makeStyles(function (theme) {
5440
+ var useStyles$i = /*#__PURE__*/styles.makeStyles(function (theme) {
5146
5441
  return {
5147
5442
  tracksContainer: {
5148
5443
  position: 'relative',
@@ -5159,7 +5454,7 @@ var useStyles$h = /*#__PURE__*/styles.makeStyles(function (theme) {
5159
5454
  function TracksContainer(_ref) {
5160
5455
  var children = _ref.children,
5161
5456
  model = _ref.model;
5162
- var classes = useStyles$h(); // refs are to store these variables to avoid repeated rerenders associated
5457
+ var classes = useStyles$i(); // refs are to store these variables to avoid repeated rerenders associated
5163
5458
  // with useState/setState
5164
5459
 
5165
5460
  var delta = React.useRef(0);
@@ -5325,7 +5620,7 @@ var TracksContainer$1 = /*#__PURE__*/mobxReact.observer(TracksContainer);
5325
5620
  var SearchResultsDialog = /*#__PURE__*/React.lazy(function () {
5326
5621
  return Promise.resolve().then(function () { return SearchResultsDialog$2; });
5327
5622
  });
5328
- var useStyles$i = /*#__PURE__*/core.makeStyles(function (theme) {
5623
+ var useStyles$j = /*#__PURE__*/core.makeStyles(function (theme) {
5329
5624
  return {
5330
5625
  importFormContainer: {
5331
5626
  padding: theme.spacing(2)
@@ -5339,7 +5634,7 @@ var ImportForm = /*#__PURE__*/mobxReact.observer(function (_ref) {
5339
5634
  var _regions$;
5340
5635
 
5341
5636
  var model = _ref.model;
5342
- var classes = useStyles$i();
5637
+ var classes = useStyles$j();
5343
5638
  var session = util.getSession(model);
5344
5639
  var assemblyNames = session.assemblyNames,
5345
5640
  assemblyManager = session.assemblyManager,
@@ -5639,7 +5934,7 @@ var MiniControls = /*#__PURE__*/mobxReact.observer(function (props) {
5639
5934
  }));
5640
5935
  });
5641
5936
 
5642
- var useStyles$j = /*#__PURE__*/core.makeStyles(function (theme) {
5937
+ var useStyles$k = /*#__PURE__*/core.makeStyles(function (theme) {
5643
5938
  return {
5644
5939
  loadingMessage: {
5645
5940
  padding: theme.spacing(5)
@@ -5735,7 +6030,7 @@ function _fetchSequence() {
5735
6030
  function SequenceDialog(_ref) {
5736
6031
  var model = _ref.model,
5737
6032
  handleClose = _ref.handleClose;
5738
- var classes = useStyles$j();
6033
+ var classes = useStyles$k();
5739
6034
  var session = util.getSession(model);
5740
6035
 
5741
6036
  var _useState = React.useState(),
@@ -5900,7 +6195,7 @@ function SequenceDialog(_ref) {
5900
6195
 
5901
6196
  var SequenceDialog$1 = /*#__PURE__*/mobxReact.observer(SequenceDialog);
5902
6197
 
5903
- var useStyles$k = /*#__PURE__*/core.makeStyles(function (theme) {
6198
+ var useStyles$l = /*#__PURE__*/core.makeStyles(function (theme) {
5904
6199
  return {
5905
6200
  dialogContent: {
5906
6201
  width: '80em'
@@ -5919,7 +6214,7 @@ function SearchResultsDialog$1(_ref) {
5919
6214
  var model = _ref.model,
5920
6215
  optAssemblyName = _ref.optAssemblyName,
5921
6216
  handleClose = _ref.handleClose;
5922
- var classes = useStyles$k();
6217
+ var classes = useStyles$l();
5923
6218
  var session = util.getSession(model);
5924
6219
 
5925
6220
  var _getEnv = mobxStateTree.getEnv(session),
@@ -6040,11 +6335,11 @@ function SearchResultsDialog$1(_ref) {
6040
6335
 
6041
6336
  var SearchResultsDialog$2 = {
6042
6337
  __proto__: null,
6043
- useStyles: useStyles$k,
6338
+ useStyles: useStyles$l,
6044
6339
  'default': SearchResultsDialog$1
6045
6340
  };
6046
6341
 
6047
- var useStyles$l = /*#__PURE__*/core.makeStyles(function (theme) {
6342
+ var useStyles$m = /*#__PURE__*/core.makeStyles(function (theme) {
6048
6343
  return {
6049
6344
  note: {
6050
6345
  textAlign: 'center',
@@ -6080,7 +6375,7 @@ var LinearGenomeView = /*#__PURE__*/mobxReact.observer(function (_ref) {
6080
6375
  hideHeader = model.hideHeader,
6081
6376
  initialized = model.initialized,
6082
6377
  hasDisplayedRegions = model.hasDisplayedRegions;
6083
- var classes = useStyles$l();
6378
+ var classes = useStyles$m();
6084
6379
 
6085
6380
  if (!initialized && !error) {
6086
6381
  return /*#__PURE__*/React__default.createElement(core.Typography, {
@@ -6169,6 +6464,8 @@ var HEADER_OVERVIEW_HEIGHT = 20;
6169
6464
  var SCALE_BAR_HEIGHT = 17;
6170
6465
  var RESIZE_HANDLE_HEIGHT = 3;
6171
6466
  var INTER_REGION_PADDING_WIDTH = 2;
6467
+ var WIDGET_HEIGHT = 32;
6468
+ var SPACING = 7;
6172
6469
  function stateModelFactory$1(pluginManager) {
6173
6470
  return mobxStateTree.types.compose(models.BaseViewModel, mobxStateTree.types.model('LinearGenomeView', {
6174
6471
  id: mst.ElementId,
@@ -6182,9 +6479,17 @@ function stateModelFactory$1(pluginManager) {
6182
6479
  hideHeader: false,
6183
6480
  hideHeaderOverview: false,
6184
6481
  trackSelectorType: mobxStateTree.types.optional(mobxStateTree.types.enumeration(['hierarchical']), 'hierarchical'),
6185
- trackLabels: 'overlapping',
6186
- showCenterLine: false,
6187
- showCytobandsSetting: true
6482
+ trackLabels: mobxStateTree.types.optional(mobxStateTree.types.string, function () {
6483
+ return localStorage.getItem('lgv-trackLabels') || 'overlapping';
6484
+ }),
6485
+ showCenterLine: mobxStateTree.types.optional(mobxStateTree.types["boolean"], function () {
6486
+ var setting = localStorage.getItem('lgv-showCenterLine');
6487
+ return setting !== undefined ? !!setting : false;
6488
+ }),
6489
+ showCytobandsSetting: mobxStateTree.types.optional(mobxStateTree.types["boolean"], function () {
6490
+ var setting = localStorage.getItem('lgv-showCytobands');
6491
+ return setting !== undefined ? !!setting : true;
6492
+ })
6188
6493
  }))["volatile"](function () {
6189
6494
  return {
6190
6495
  volatileWidth: undefined,
@@ -6291,11 +6596,9 @@ function stateModelFactory$1(pluginManager) {
6291
6596
  },
6292
6597
 
6293
6598
  get totalBp() {
6294
- var totalbp = 0;
6295
- self.displayedRegions.forEach(function (region) {
6296
- totalbp += region.end - region.start;
6297
- });
6298
- return totalbp;
6599
+ return self.displayedRegions.reduce(function (a, b) {
6600
+ return a + b.end - b.start;
6601
+ }, 0);
6299
6602
  },
6300
6603
 
6301
6604
  get maxBpPerPx() {
@@ -6358,39 +6661,12 @@ function stateModelFactory$1(pluginManager) {
6358
6661
  var refName = _ref.refName,
6359
6662
  coord = _ref.coord,
6360
6663
  regionNumber = _ref.regionNumber;
6361
- var offsetBp = 0;
6362
- var interRegionPaddingBp = self.interRegionPaddingWidth * self.bpPerPx;
6363
- var minimumBlockBp = self.minimumBlockWidth * self.bpPerPx;
6364
- var index = self.displayedRegions.findIndex(function (region, idx) {
6365
- var len = region.end - region.start;
6366
-
6367
- if (refName === region.refName && coord >= region.start && coord <= region.end) {
6368
- if (regionNumber ? regionNumber === idx : true) {
6369
- offsetBp += region.reversed ? region.end - coord : coord - region.start;
6370
- return true;
6371
- }
6372
- } // add the interRegionPaddingWidth if the boundary is in the screen
6373
- // e.g. offset>=0 && offset<width
6374
-
6375
-
6376
- if (len > minimumBlockBp && offsetBp / self.bpPerPx >= 0 && offsetBp / self.bpPerPx < self.width) {
6377
- offsetBp += len + interRegionPaddingBp;
6378
- } else {
6379
- offsetBp += len;
6380
- }
6381
-
6382
- return false;
6664
+ return util.viewBpToPx({
6665
+ refName: refName,
6666
+ coord: coord,
6667
+ regionNumber: regionNumber,
6668
+ self: self
6383
6669
  });
6384
- var foundRegion = self.displayedRegions[index];
6385
-
6386
- if (foundRegion) {
6387
- return {
6388
- index: index,
6389
- offsetPx: Math.round(offsetBp / self.bpPerPx)
6390
- };
6391
- }
6392
-
6393
- return undefined;
6394
6670
  },
6395
6671
 
6396
6672
  /**
@@ -6542,6 +6818,7 @@ function stateModelFactory$1(pluginManager) {
6542
6818
  return {
6543
6819
  setShowCytobands: function setShowCytobands(flag) {
6544
6820
  self.showCytobandsSetting = flag;
6821
+ localStorage.setItem('lgv-showCytobands', "".concat(+flag));
6545
6822
  },
6546
6823
  setWidth: function setWidth(newWidth) {
6547
6824
  self.volatileWidth = newWidth;
@@ -6611,13 +6888,13 @@ function stateModelFactory$1(pluginManager) {
6611
6888
  var configuration = mobxStateTree.resolveIdentifier(trackConfigSchema, mobxStateTree.getRoot(self), trackId);
6612
6889
 
6613
6890
  if (!configuration) {
6614
- throw new Error("Could not resolve identifier");
6891
+ throw new Error("Could not resolve identifier \"".concat(trackId, "\""));
6615
6892
  }
6616
6893
 
6617
6894
  var trackType = pluginManager.getTrackType(configuration === null || configuration === void 0 ? void 0 : configuration.type);
6618
6895
 
6619
6896
  if (!trackType) {
6620
- throw new Error("unknown track type ".concat(configuration.type));
6897
+ throw new Error("Unknown track type ".concat(configuration.type));
6621
6898
  }
6622
6899
 
6623
6900
  var viewType = pluginManager.getViewType(self.type);
@@ -6629,7 +6906,7 @@ function stateModelFactory$1(pluginManager) {
6629
6906
  });
6630
6907
 
6631
6908
  if (!displayConf) {
6632
- throw new Error("could not find a compatible display for view type ".concat(self.type));
6909
+ throw new Error("Could not find a compatible display for view type ".concat(self.type));
6633
6910
  }
6634
6911
 
6635
6912
  var shownTracks = self.tracks.filter(function (t) {
@@ -6712,9 +6989,11 @@ function stateModelFactory$1(pluginManager) {
6712
6989
  },
6713
6990
  setTrackLabels: function setTrackLabels(setting) {
6714
6991
  self.trackLabels = setting;
6992
+ localStorage.setItem('lgv-trackLabels', setting);
6715
6993
  },
6716
6994
  toggleCenterLine: function toggleCenterLine() {
6717
6995
  self.showCenterLine = !self.showCenterLine;
6996
+ localStorage.setItem('lgv-showCenterLine', "".concat(+self.showCenterLine));
6718
6997
  },
6719
6998
  setDisplayedRegions: function setDisplayedRegions(regions) {
6720
6999
  self.displayedRegions = mobxStateTree.cast(regions);
@@ -7628,13 +7907,7 @@ function configSchemaFactory$1(pluginManager) {
7628
7907
  defaultValue: "jexl:get(feature,'name')",
7629
7908
  contextVariable: ['feature']
7630
7909
  },
7631
- renderer: pluginManager.pluggableConfigSchemaType('renderer'),
7632
- // overrides base
7633
- maxDisplayedBpPerPx: {
7634
- type: 'number',
7635
- description: 'maximum bpPerPx that is displayed in the view',
7636
- defaultValue: 1000
7637
- }
7910
+ renderer: pluginManager.pluggableConfigSchemaType('renderer')
7638
7911
  }, {
7639
7912
  baseConfiguration: baseLinearDisplayConfigSchema,
7640
7913
  explicitlyTyped: true
@@ -7717,6 +7990,81 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
7717
7990
  })
7718
7991
  });
7719
7992
  });
7993
+ pluginManager.addToExtensionPoint('LaunchView-LinearGenomeView',
7994
+ /*#__PURE__*/
7995
+ // @ts-ignore
7996
+ function () {
7997
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(_ref) {
7998
+ var session, assembly, loc, _ref$tracks, tracks, assemblyManager, view, asm, idsNotFound;
7999
+
8000
+ return runtime_1.wrap(function _callee$(_context) {
8001
+ while (1) {
8002
+ switch (_context.prev = _context.next) {
8003
+ case 0:
8004
+ session = _ref.session, assembly = _ref.assembly, loc = _ref.loc, _ref$tracks = _ref.tracks, tracks = _ref$tracks === void 0 ? [] : _ref$tracks;
8005
+ assemblyManager = session.assemblyManager;
8006
+ view = session.addView('LinearGenomeView', {});
8007
+ _context.next = 5;
8008
+ return mobx.when(function () {
8009
+ return !!view.volatileWidth;
8010
+ });
8011
+
8012
+ case 5:
8013
+ if (assembly) {
8014
+ _context.next = 7;
8015
+ break;
8016
+ }
8017
+
8018
+ throw new Error('No assembly provided when launching linear genome view');
8019
+
8020
+ case 7:
8021
+ _context.next = 9;
8022
+ return assemblyManager.waitForAssembly(assembly);
8023
+
8024
+ case 9:
8025
+ asm = _context.sent;
8026
+
8027
+ if (asm) {
8028
+ _context.next = 12;
8029
+ break;
8030
+ }
8031
+
8032
+ throw new Error("Assembly \"".concat(assembly, "\" not found when launching linear genome view"));
8033
+
8034
+ case 12:
8035
+ view.navToLocString(loc, assembly);
8036
+ idsNotFound = [];
8037
+ tracks.forEach(function (track) {
8038
+ try {
8039
+ view.showTrack(track);
8040
+ } catch (e) {
8041
+ if ("".concat(e).match('Could not resolve identifier')) {
8042
+ idsNotFound.push(track);
8043
+ } else {
8044
+ throw e;
8045
+ }
8046
+ }
8047
+ });
8048
+
8049
+ if (!idsNotFound.length) {
8050
+ _context.next = 17;
8051
+ break;
8052
+ }
8053
+
8054
+ throw new Error("Could not resolve identifiers: ".concat(idsNotFound.join(',')));
8055
+
8056
+ case 17:
8057
+ case "end":
8058
+ return _context.stop();
8059
+ }
8060
+ }
8061
+ }, _callee);
8062
+ }));
8063
+
8064
+ return function (_x) {
8065
+ return _ref2.apply(this, arguments);
8066
+ };
8067
+ }());
7720
8068
  }
7721
8069
  }, {
7722
8070
  key: "configure",
@@ -7736,7 +8084,7 @@ var LinearGenomeViewPlugin = /*#__PURE__*/function (_Plugin) {
7736
8084
  return LinearGenomeViewPlugin;
7737
8085
  }(Plugin);
7738
8086
 
7739
- var useStyles$m = /*#__PURE__*/core.makeStyles(function (theme) {
8087
+ var useStyles$n = /*#__PURE__*/core.makeStyles(function (theme) {
7740
8088
  return {
7741
8089
  closeButton: {
7742
8090
  position: 'absolute',
@@ -7748,7 +8096,7 @@ var useStyles$m = /*#__PURE__*/core.makeStyles(function (theme) {
7748
8096
  });
7749
8097
  function HelpDialog$1(_ref) {
7750
8098
  var handleClose = _ref.handleClose;
7751
- var classes = useStyles$m();
8099
+ var classes = useStyles$n();
7752
8100
  return /*#__PURE__*/React__default.createElement(core.Dialog, {
7753
8101
  open: true,
7754
8102
  maxWidth: "xl",
@@ -7769,11 +8117,11 @@ function HelpDialog$1(_ref) {
7769
8117
 
7770
8118
  var HelpDialog$2 = {
7771
8119
  __proto__: null,
7772
- useStyles: useStyles$m,
8120
+ useStyles: useStyles$n,
7773
8121
  'default': HelpDialog$1
7774
8122
  };
7775
8123
 
7776
- var useStyles$n = /*#__PURE__*/core.makeStyles(function (theme) {
8124
+ var useStyles$o = /*#__PURE__*/core.makeStyles(function (theme) {
7777
8125
  return {
7778
8126
  root: {
7779
8127
  width: 500
@@ -7793,7 +8141,7 @@ var useStyles$n = /*#__PURE__*/core.makeStyles(function (theme) {
7793
8141
  function SetMaxHeightDlg$1(props) {
7794
8142
  var model = props.model,
7795
8143
  handleClose = props.handleClose;
7796
- var classes = useStyles$n();
8144
+ var classes = useStyles$o();
7797
8145
  var _model$maxHeight = model.maxHeight,
7798
8146
  maxHeight = _model$maxHeight === void 0 ? '' : _model$maxHeight;
7799
8147
 
@@ -7845,6 +8193,7 @@ var SetMaxHeight$1 = {
7845
8193
  exports.BaseLinearDisplay = BaseLinearDisplay$1;
7846
8194
  exports.BaseLinearDisplayComponent = BaseLinearDisplay;
7847
8195
  exports.RefNameAutocomplete = RefNameAutocomplete$1;
8196
+ exports.SearchBox = SearchBox$1;
7848
8197
  exports.baseLinearDisplayConfigSchema = baseLinearDisplayConfigSchema;
7849
8198
  exports.default = LinearGenomeViewPlugin;
7850
8199
  exports.linearBareDisplayConfigSchemaFactory = configSchemaFactory;