@jbrowse/plugin-linear-genome-view 2.0.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js +28 -55
  2. package/dist/BaseLinearDisplay/components/BaseLinearDisplay.js.map +1 -1
  3. package/dist/BaseLinearDisplay/components/Block.js +17 -28
  4. package/dist/BaseLinearDisplay/components/Block.js.map +1 -1
  5. package/dist/BaseLinearDisplay/components/LinearBlocks.js +19 -21
  6. package/dist/BaseLinearDisplay/components/LinearBlocks.js.map +1 -1
  7. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +28 -48
  8. package/dist/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  9. package/dist/BaseLinearDisplay/components/Tooltip.js +29 -58
  10. package/dist/BaseLinearDisplay/components/Tooltip.js.map +1 -1
  11. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js +242 -363
  12. package/dist/BaseLinearDisplay/models/BaseLinearDisplayModel.js.map +1 -1
  13. package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js +1 -1
  14. package/dist/BaseLinearDisplay/models/baseLinearDisplayConfigSchema.js.map +1 -1
  15. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js +77 -129
  16. package/dist/BaseLinearDisplay/models/serverSideRenderedBlock.js.map +1 -1
  17. package/dist/LinearBareDisplay/configSchema.js +2 -2
  18. package/dist/LinearBareDisplay/configSchema.js.map +1 -1
  19. package/dist/LinearBareDisplay/model.js +13 -19
  20. package/dist/LinearBareDisplay/model.js.map +1 -1
  21. package/dist/LinearBasicDisplay/components/SetMaxHeight.js +14 -31
  22. package/dist/LinearBasicDisplay/components/SetMaxHeight.js.map +1 -1
  23. package/dist/LinearBasicDisplay/configSchema.js +3 -3
  24. package/dist/LinearBasicDisplay/configSchema.js.map +1 -1
  25. package/dist/LinearBasicDisplay/model.js +119 -147
  26. package/dist/LinearBasicDisplay/model.js.map +1 -1
  27. package/dist/LinearGenomeView/components/CenterLine.js +11 -12
  28. package/dist/LinearGenomeView/components/CenterLine.js.map +1 -1
  29. package/dist/LinearGenomeView/components/ExportSvgDialog.js +30 -96
  30. package/dist/LinearGenomeView/components/ExportSvgDialog.js.map +1 -1
  31. package/dist/LinearGenomeView/components/GetSequenceDialog.d.ts +9 -0
  32. package/dist/LinearGenomeView/components/GetSequenceDialog.js +172 -0
  33. package/dist/LinearGenomeView/components/GetSequenceDialog.js.map +1 -0
  34. package/dist/LinearGenomeView/components/{VerticalGuides.d.ts → Gridlines.d.ts} +0 -0
  35. package/dist/LinearGenomeView/components/{VerticalGuides.js → Gridlines.js} +19 -21
  36. package/dist/LinearGenomeView/components/Gridlines.js.map +1 -0
  37. package/dist/LinearGenomeView/components/Header.js +26 -31
  38. package/dist/LinearGenomeView/components/Header.js.map +1 -1
  39. package/dist/LinearGenomeView/components/HelpDialog.js +10 -11
  40. package/dist/LinearGenomeView/components/HelpDialog.js.map +1 -1
  41. package/dist/LinearGenomeView/components/ImportForm.js +91 -154
  42. package/dist/LinearGenomeView/components/ImportForm.js.map +1 -1
  43. package/dist/LinearGenomeView/components/LinearGenomeView.js +20 -25
  44. package/dist/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  45. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js +86 -157
  46. package/dist/LinearGenomeView/components/LinearGenomeViewSvg.js.map +1 -1
  47. package/dist/LinearGenomeView/components/MiniControls.js +16 -32
  48. package/dist/LinearGenomeView/components/MiniControls.js.map +1 -1
  49. package/dist/LinearGenomeView/components/OverviewRubberBand.d.ts +0 -11
  50. package/dist/LinearGenomeView/components/OverviewRubberBand.js +55 -84
  51. package/dist/LinearGenomeView/components/OverviewRubberBand.js.map +1 -1
  52. package/dist/LinearGenomeView/components/OverviewScaleBar.js +94 -117
  53. package/dist/LinearGenomeView/components/OverviewScaleBar.js.map +1 -1
  54. package/dist/LinearGenomeView/components/RefNameAutocomplete.js +90 -172
  55. package/dist/LinearGenomeView/components/RefNameAutocomplete.js.map +1 -1
  56. package/dist/LinearGenomeView/components/RubberBand.js +51 -72
  57. package/dist/LinearGenomeView/components/RubberBand.js.map +1 -1
  58. package/dist/LinearGenomeView/components/Ruler.js +17 -18
  59. package/dist/LinearGenomeView/components/Ruler.js.map +1 -1
  60. package/dist/LinearGenomeView/components/ScaleBar.js +37 -58
  61. package/dist/LinearGenomeView/components/ScaleBar.js.map +1 -1
  62. package/dist/LinearGenomeView/components/SearchBox.js +69 -133
  63. package/dist/LinearGenomeView/components/SearchBox.js.map +1 -1
  64. package/dist/LinearGenomeView/components/SearchResultsDialog.js +32 -33
  65. package/dist/LinearGenomeView/components/SearchResultsDialog.js.map +1 -1
  66. package/dist/LinearGenomeView/components/{SequenceDialog.d.ts → SequenceSearchDialog.d.ts} +0 -0
  67. package/dist/LinearGenomeView/components/SequenceSearchDialog.js +104 -0
  68. package/dist/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -0
  69. package/dist/LinearGenomeView/components/TrackContainer.d.ts +2 -1
  70. package/dist/LinearGenomeView/components/TrackContainer.js +36 -43
  71. package/dist/LinearGenomeView/components/TrackContainer.js.map +1 -1
  72. package/dist/LinearGenomeView/components/TrackLabel.js +50 -85
  73. package/dist/LinearGenomeView/components/TrackLabel.js.map +1 -1
  74. package/dist/LinearGenomeView/components/TracksContainer.js +33 -50
  75. package/dist/LinearGenomeView/components/TracksContainer.js.map +1 -1
  76. package/dist/LinearGenomeView/components/ZoomControls.js +15 -32
  77. package/dist/LinearGenomeView/components/ZoomControls.js.map +1 -1
  78. package/dist/LinearGenomeView/components/util.js +14 -87
  79. package/dist/LinearGenomeView/components/util.js.map +1 -1
  80. package/dist/LinearGenomeView/index.d.ts +66 -79
  81. package/dist/LinearGenomeView/index.js +534 -710
  82. package/dist/LinearGenomeView/index.js.map +1 -1
  83. package/dist/LinearGenomeView/util.js +17 -36
  84. package/dist/LinearGenomeView/util.js.map +1 -1
  85. package/dist/index.js +75 -146
  86. package/dist/index.js.map +1 -1
  87. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +1 -1
  88. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js.map +1 -1
  89. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +1 -0
  90. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js.map +1 -1
  91. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +9 -0
  92. package/esm/LinearGenomeView/components/{SequenceDialog.js → GetSequenceDialog.js} +5 -8
  93. package/esm/LinearGenomeView/components/GetSequenceDialog.js.map +1 -0
  94. package/esm/LinearGenomeView/components/{VerticalGuides.d.ts → Gridlines.d.ts} +0 -0
  95. package/esm/LinearGenomeView/components/{VerticalGuides.js → Gridlines.js} +1 -1
  96. package/esm/LinearGenomeView/components/Gridlines.js.map +1 -0
  97. package/esm/LinearGenomeView/components/ImportForm.js +1 -0
  98. package/esm/LinearGenomeView/components/ImportForm.js.map +1 -1
  99. package/esm/LinearGenomeView/components/LinearGenomeView.js +3 -7
  100. package/esm/LinearGenomeView/components/LinearGenomeView.js.map +1 -1
  101. package/esm/LinearGenomeView/components/OverviewRubberBand.d.ts +0 -11
  102. package/esm/LinearGenomeView/components/OverviewRubberBand.js +16 -21
  103. package/esm/LinearGenomeView/components/OverviewRubberBand.js.map +1 -1
  104. package/esm/LinearGenomeView/components/OverviewScaleBar.js +0 -2
  105. package/esm/LinearGenomeView/components/OverviewScaleBar.js.map +1 -1
  106. package/esm/LinearGenomeView/components/RubberBand.js +0 -2
  107. package/esm/LinearGenomeView/components/RubberBand.js.map +1 -1
  108. package/esm/LinearGenomeView/components/SearchBox.js.map +1 -1
  109. package/esm/LinearGenomeView/components/{SequenceDialog.d.ts → SequenceSearchDialog.d.ts} +0 -0
  110. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +76 -0
  111. package/esm/LinearGenomeView/components/SequenceSearchDialog.js.map +1 -0
  112. package/esm/LinearGenomeView/components/TrackContainer.d.ts +2 -1
  113. package/esm/LinearGenomeView/components/TrackContainer.js +15 -20
  114. package/esm/LinearGenomeView/components/TrackContainer.js.map +1 -1
  115. package/esm/LinearGenomeView/components/TrackLabel.js +22 -23
  116. package/esm/LinearGenomeView/components/TrackLabel.js.map +1 -1
  117. package/esm/LinearGenomeView/components/TracksContainer.js +2 -2
  118. package/esm/LinearGenomeView/components/TracksContainer.js.map +1 -1
  119. package/esm/LinearGenomeView/index.d.ts +66 -79
  120. package/esm/LinearGenomeView/index.js +268 -407
  121. package/esm/LinearGenomeView/index.js.map +1 -1
  122. package/package.json +3 -4
  123. package/src/BaseLinearDisplay/components/BaseLinearDisplay.tsx +0 -1
  124. package/src/BaseLinearDisplay/components/ServerSideRenderedBlockContent.tsx +2 -1
  125. package/src/LinearGenomeView/components/{SequenceDialog.tsx → GetSequenceDialog.tsx} +5 -18
  126. package/src/LinearGenomeView/components/{VerticalGuides.tsx → Gridlines.tsx} +0 -0
  127. package/src/LinearGenomeView/components/ImportForm.tsx +1 -0
  128. package/src/LinearGenomeView/components/LinearGenomeView.tsx +4 -8
  129. package/src/LinearGenomeView/components/OverviewRubberBand.tsx +19 -34
  130. package/src/LinearGenomeView/components/OverviewScaleBar.tsx +0 -2
  131. package/src/LinearGenomeView/components/RubberBand.tsx +0 -2
  132. package/src/LinearGenomeView/components/SearchBox.tsx +1 -1
  133. package/src/LinearGenomeView/components/SequenceSearchDialog.tsx +165 -0
  134. package/src/LinearGenomeView/components/TrackContainer.tsx +18 -28
  135. package/src/LinearGenomeView/components/TrackLabel.tsx +60 -53
  136. package/src/LinearGenomeView/components/TracksContainer.tsx +2 -2
  137. package/src/LinearGenomeView/components/__snapshots__/LinearGenomeView.test.js.snap +14 -17
  138. package/src/LinearGenomeView/index.test.ts +14 -36
  139. package/src/LinearGenomeView/index.tsx +389 -541
  140. package/dist/LinearGenomeView/components/SequenceDialog.js +0 -242
  141. package/dist/LinearGenomeView/components/SequenceDialog.js.map +0 -1
  142. package/dist/LinearGenomeView/components/VerticalGuides.js.map +0 -1
  143. package/esm/LinearGenomeView/components/SequenceDialog.js.map +0 -1
  144. package/esm/LinearGenomeView/components/VerticalGuides.js.map +0 -1
@@ -1,130 +1,76 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (_) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __read = (this && this.__read) || function (o, n) {
50
- var m = typeof Symbol === "function" && o[Symbol.iterator];
51
- if (!m) return o;
52
- var i = m.call(o), r, ar = [], e;
53
- try {
54
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
55
7
  }
56
- catch (error) { e = { error: error }; }
57
- finally {
58
- try {
59
- if (r && !r.done && (m = i["return"])) m.call(i);
60
- }
61
- finally { if (e) throw e.error; }
62
- }
63
- return ar;
64
- };
65
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
66
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
67
- if (ar || !(i in from)) {
68
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
69
- ar[i] = from[i];
70
- }
71
- }
72
- return to.concat(ar || Array.prototype.slice.call(from));
73
- };
74
- var __values = (this && this.__values) || function(o) {
75
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
76
- if (m) return m.call(o);
77
- if (o && typeof o.length === "number") return {
78
- next: function () {
79
- if (o && i >= o.length) o = void 0;
80
- return { value: o && o[i++], done: !o };
81
- }
82
- };
83
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
84
24
  };
85
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
86
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
87
27
  };
88
28
  Object.defineProperty(exports, "__esModule", { value: true });
89
29
  exports.ReactComponent = exports.SearchBox = exports.RefNameAutocomplete = exports.renderToSvg = exports.stateModelFactory = exports.WIDGET_HEIGHT = exports.SPACING = exports.INTER_REGION_PADDING_WIDTH = exports.RESIZE_HANDLE_HEIGHT = exports.SCALE_BAR_HEIGHT = exports.HEADER_OVERVIEW_HEIGHT = exports.HEADER_BAR_HEIGHT = void 0;
90
- var configuration_1 = require("@jbrowse/core/configuration");
91
- var models_1 = require("@jbrowse/core/pluggableElementTypes/models");
92
- var mst_1 = require("@jbrowse/core/util/types/mst");
93
- var ui_1 = require("@jbrowse/core/ui");
94
- var util_1 = require("@jbrowse/core/util");
95
- var calculateDynamicBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateDynamicBlocks"));
96
- var calculateStaticBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateStaticBlocks"));
97
- var tracks_1 = require("@jbrowse/core/util/tracks");
98
- var mobx_1 = require("mobx");
99
- var mobx_state_tree_1 = require("mobx-state-tree");
100
- var Base1DViewModel_1 = __importDefault(require("@jbrowse/core/util/Base1DViewModel"));
101
- var clone_1 = __importDefault(require("clone"));
102
- var file_saver_1 = require("file-saver");
30
+ const react_1 = require("react");
31
+ const configuration_1 = require("@jbrowse/core/configuration");
32
+ const models_1 = require("@jbrowse/core/pluggableElementTypes/models");
33
+ const mst_1 = require("@jbrowse/core/util/types/mst");
34
+ const ui_1 = require("@jbrowse/core/ui");
35
+ const util_1 = require("@jbrowse/core/util");
36
+ const calculateDynamicBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateDynamicBlocks"));
37
+ const calculateStaticBlocks_1 = __importDefault(require("@jbrowse/core/util/calculateStaticBlocks"));
38
+ const tracks_1 = require("@jbrowse/core/util/tracks");
39
+ const mobx_1 = require("mobx");
40
+ const mobx_state_tree_1 = require("mobx-state-tree");
41
+ const Base1DViewModel_1 = __importDefault(require("@jbrowse/core/util/Base1DViewModel"));
42
+ const Base1DUtils_1 = require("@jbrowse/core/util/Base1DUtils");
43
+ const file_saver_1 = require("file-saver");
44
+ const clone_1 = __importDefault(require("clone"));
103
45
  // icons
104
- var Icons_1 = require("@jbrowse/core/ui/Icons");
105
- var SyncAlt_1 = __importDefault(require("@mui/icons-material/SyncAlt"));
106
- var Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
107
- var Label_1 = __importDefault(require("@mui/icons-material/Label"));
108
- var FolderOpen_1 = __importDefault(require("@mui/icons-material/FolderOpen"));
109
- var PhotoCamera_1 = __importDefault(require("@mui/icons-material/PhotoCamera"));
110
- var ZoomIn_1 = __importDefault(require("@mui/icons-material/ZoomIn"));
111
- var MenuOpen_1 = __importDefault(require("@mui/icons-material/MenuOpen"));
46
+ const Icons_1 = require("@jbrowse/core/ui/Icons");
47
+ const SyncAlt_1 = __importDefault(require("@mui/icons-material/SyncAlt"));
48
+ const Visibility_1 = __importDefault(require("@mui/icons-material/Visibility"));
49
+ const Label_1 = __importDefault(require("@mui/icons-material/Label"));
50
+ const FolderOpen_1 = __importDefault(require("@mui/icons-material/FolderOpen"));
51
+ const PhotoCamera_1 = __importDefault(require("@mui/icons-material/PhotoCamera"));
52
+ const ZoomIn_1 = __importDefault(require("@mui/icons-material/ZoomIn"));
53
+ const MenuOpen_1 = __importDefault(require("@mui/icons-material/MenuOpen"));
112
54
  // locals
113
- var LinearGenomeViewSvg_1 = require("./components/LinearGenomeViewSvg");
55
+ const LinearGenomeViewSvg_1 = require("./components/LinearGenomeViewSvg");
114
56
  Object.defineProperty(exports, "renderToSvg", { enumerable: true, get: function () { return LinearGenomeViewSvg_1.renderToSvg; } });
115
- var RefNameAutocomplete_1 = __importDefault(require("./components/RefNameAutocomplete"));
57
+ const RefNameAutocomplete_1 = __importDefault(require("./components/RefNameAutocomplete"));
116
58
  exports.RefNameAutocomplete = RefNameAutocomplete_1.default;
117
- var SearchBox_1 = __importDefault(require("./components/SearchBox"));
59
+ const SearchBox_1 = __importDefault(require("./components/SearchBox"));
118
60
  exports.SearchBox = SearchBox_1.default;
119
- var ExportSvgDialog_1 = __importDefault(require("./components/ExportSvgDialog"));
61
+ const ExportSvgDialog_1 = __importDefault(require("./components/ExportSvgDialog"));
62
+ const SequenceSearchDialog = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require('./components/SequenceSearchDialog'))));
120
63
  function calculateVisibleLocStrings(contentBlocks) {
121
64
  if (!contentBlocks.length) {
122
65
  return '';
123
66
  }
124
- var isSingleAssemblyName = contentBlocks.every(function (block) { return block.assemblyName === contentBlocks[0].assemblyName; });
125
- var locs = contentBlocks.map(function (block) {
126
- return (0, util_1.assembleLocString)(__assign(__assign({}, block), { start: Math.round(block.start), end: Math.round(block.end), assemblyName: isSingleAssemblyName ? undefined : block.assemblyName }));
127
- });
67
+ const isSingleAssemblyName = contentBlocks.every(block => block.assemblyName === contentBlocks[0].assemblyName);
68
+ const locs = contentBlocks.map(block => (0, util_1.assembleLocString)({
69
+ ...block,
70
+ start: Math.round(block.start),
71
+ end: Math.round(block.end),
72
+ assemblyName: isSingleAssemblyName ? undefined : block.assemblyName,
73
+ }));
128
74
  return locs.join(' ');
129
75
  }
130
76
  exports.HEADER_BAR_HEIGHT = 48;
@@ -154,17 +100,18 @@ function stateModelFactory(pluginManager) {
154
100
  hideHeaderOverview: false,
155
101
  hideNoTracksActive: false,
156
102
  trackSelectorType: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.enumeration(['hierarchical']), 'hierarchical'),
157
- trackLabels: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, function () { return localStorageGetItem('lgv-trackLabels') || 'overlapping'; }),
158
- showCenterLine: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, function () {
159
- var setting = localStorageGetItem('lgv-showCenterLine');
103
+ trackLabels: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.string, () => localStorageGetItem('lgv-trackLabels') || 'overlapping'),
104
+ showCenterLine: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => {
105
+ const setting = localStorageGetItem('lgv-showCenterLine');
160
106
  return setting !== undefined && setting !== null ? !!+setting : false;
161
107
  }),
162
- showCytobandsSetting: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, function () {
163
- var setting = localStorageGetItem('lgv-showCytobands');
108
+ showCytobandsSetting: mobx_state_tree_1.types.optional(mobx_state_tree_1.types.boolean, () => {
109
+ const setting = localStorageGetItem('lgv-showCytobands');
164
110
  return setting !== undefined && setting !== null ? !!+setting : true;
165
111
  }),
112
+ showGridlines: true,
166
113
  }))
167
- .volatile(function () { return ({
114
+ .volatile(() => ({
168
115
  volatileWidth: undefined,
169
116
  minimumBlockWidth: 3,
170
117
  draggingTrackId: undefined,
@@ -182,8 +129,8 @@ function stateModelFactory(pluginManager) {
182
129
  searchResults: undefined,
183
130
  searchQuery: undefined,
184
131
  seqDialogDisplayed: false,
185
- }); })
186
- .views(function (self) { return ({
132
+ }))
133
+ .views(self => ({
187
134
  get width() {
188
135
  if (self.volatileWidth === undefined) {
189
136
  throw new Error('width undefined, make sure to check for model.initialized');
@@ -194,22 +141,24 @@ function stateModelFactory(pluginManager) {
194
141
  return exports.INTER_REGION_PADDING_WIDTH;
195
142
  },
196
143
  get assemblyNames() {
197
- return __spreadArray([], __read(new Set(self.displayedRegions.map(function (region) { return region.assemblyName; }))), false);
144
+ return [
145
+ ...new Set(self.displayedRegions.map(region => region.assemblyName)),
146
+ ];
198
147
  },
199
- }); })
200
- .views(function (self) { return ({
148
+ }))
149
+ .views(self => ({
201
150
  get assemblyErrors() {
202
- var assemblyManager = (0, util_1.getSession)(self).assemblyManager;
203
- var assemblyNames = self.assemblyNames;
151
+ const { assemblyManager } = (0, util_1.getSession)(self);
152
+ const { assemblyNames } = self;
204
153
  return assemblyNames
205
- .map(function (a) { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.error; })
206
- .filter(function (f) { return !!f; })
154
+ .map(a => { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.error; })
155
+ .filter(f => !!f)
207
156
  .join(', ');
208
157
  },
209
158
  get assembliesInitialized() {
210
- var assemblyManager = (0, util_1.getSession)(self).assemblyManager;
211
- var assemblyNames = self.assemblyNames;
212
- return assemblyNames.every(function (a) { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.initialized; });
159
+ const { assemblyManager } = (0, util_1.getSession)(self);
160
+ const { assemblyNames } = self;
161
+ return assemblyNames.every(a => { var _a; return (_a = assemblyManager.get(a)) === null || _a === void 0 ? void 0 : _a.initialized; });
213
162
  },
214
163
  get initialized() {
215
164
  return self.volatileWidth !== undefined && this.assembliesInitialized;
@@ -234,8 +183,8 @@ function stateModelFactory(pluginManager) {
234
183
  },
235
184
  get trackHeights() {
236
185
  return self.tracks
237
- .map(function (t) { return t.displays[0].height; })
238
- .reduce(function (a, b) { return a + b; }, 0);
186
+ .map(t => t.displays[0].height)
187
+ .reduce((a, b) => a + b, 0);
239
188
  },
240
189
  get trackHeightsWithResizeHandles() {
241
190
  return this.trackHeights + self.tracks.length * exports.RESIZE_HANDLE_HEIGHT;
@@ -246,7 +195,7 @@ function stateModelFactory(pluginManager) {
246
195
  this.scaleBarHeight);
247
196
  },
248
197
  get totalBp() {
249
- return self.displayedRegions.reduce(function (a, b) { return a + b.end - b.start; }, 0);
198
+ return self.displayedRegions.reduce((a, b) => a + b.end - b.start, 0);
250
199
  },
251
200
  get maxBpPerPx() {
252
201
  return this.totalBp / (self.width * 0.9);
@@ -259,99 +208,38 @@ function stateModelFactory(pluginManager) {
259
208
  },
260
209
  get maxOffset() {
261
210
  // objectively determined to keep the linear genome on the main screen
262
- var leftPadding = 10;
211
+ const leftPadding = 10;
263
212
  return this.displayedRegionsTotalPx - leftPadding;
264
213
  },
265
214
  get minOffset() {
266
215
  // objectively determined to keep the linear genome on the main screen
267
- var rightPadding = 30;
216
+ const rightPadding = 30;
268
217
  return -self.width + rightPadding;
269
218
  },
270
219
  get displayedRegionsTotalPx() {
271
220
  return this.totalBp / self.bpPerPx;
272
221
  },
273
- renderProps: function () {
274
- return __assign(__assign({}, (0, tracks_1.getParentRenderProps)(self)), { bpPerPx: self.bpPerPx, highResolutionScaling: (0, configuration_1.getConf)((0, util_1.getSession)(self), 'highResolutionScaling') });
275
- },
276
- searchScope: function (assemblyName) {
222
+ renderProps() {
277
223
  return {
278
- assemblyName: assemblyName,
279
- includeAggregateIndexes: true,
280
- tracks: self.tracks,
224
+ ...(0, tracks_1.getParentRenderProps)(self),
225
+ bpPerPx: self.bpPerPx,
226
+ highResolutionScaling: (0, configuration_1.getConf)((0, util_1.getSession)(self), 'highResolutionScaling'),
281
227
  };
282
228
  },
283
- bpToPx: function (_a) {
284
- var refName = _a.refName, coord = _a.coord, regionNumber = _a.regionNumber;
285
- return (0, util_1.viewBpToPx)({ refName: refName, coord: coord, regionNumber: regionNumber, self: self });
286
- },
287
- /**
288
- *
289
- * @param px - px in the view area, return value is the displayed regions
290
- * @returns BpOffset of the displayed region that it lands in
291
- */
292
- pxToBp: function (px) {
293
- var bpSoFar = 0;
294
- var bp = (self.offsetPx + px) * self.bpPerPx;
295
- var n = self.displayedRegions.length;
296
- if (bp < 0) {
297
- var region = self.displayedRegions[0];
298
- var offset = bp;
299
- var snap = (0, mobx_state_tree_1.getSnapshot)(region);
300
- return __assign(__assign({}, snap), { oob: true, coord: region.reversed
301
- ? Math.floor(region.end - offset) + 1
302
- : Math.floor(region.start + offset) + 1, offset: offset, index: 0 });
303
- }
304
- var interRegionPaddingBp = self.interRegionPaddingWidth * self.bpPerPx;
305
- var minimumBlockBp = self.minimumBlockWidth * self.bpPerPx;
306
- for (var index = 0; index < self.displayedRegions.length; index += 1) {
307
- var region = self.displayedRegions[index];
308
- var len = region.end - region.start;
309
- var offset = bp - bpSoFar;
310
- if (len + bpSoFar > bp && bpSoFar <= bp) {
311
- var snap = (0, mobx_state_tree_1.getSnapshot)(region);
312
- return __assign(__assign({}, snap), { oob: false, offset: offset, coord: region.reversed
313
- ? Math.floor(region.end - offset) + 1
314
- : Math.floor(region.start + offset) + 1, index: index });
315
- }
316
- // add the interRegionPaddingWidth if the boundary is in the screen
317
- // e.g. offset>0 && offset<width
318
- if (region.end - region.start > minimumBlockBp &&
319
- offset / self.bpPerPx > 0 &&
320
- offset / self.bpPerPx < self.width) {
321
- bpSoFar += len + interRegionPaddingBp;
322
- }
323
- else {
324
- bpSoFar += len;
325
- }
326
- }
327
- if (bp >= bpSoFar) {
328
- var region = self.displayedRegions[n - 1];
329
- var len = region.end - region.start;
330
- var offset = bp - bpSoFar + len;
331
- var snap = (0, mobx_state_tree_1.getSnapshot)(region);
332
- return __assign(__assign({}, snap), { oob: true, offset: offset, coord: region.reversed
333
- ? Math.floor(region.end - offset) + 1
334
- : Math.floor(region.start + offset) + 1, index: n - 1 });
335
- }
229
+ searchScope(assemblyName) {
336
230
  return {
337
- coord: 0,
338
- index: 0,
339
- refName: '',
340
- oob: true,
341
- assemblyName: '',
342
- offset: 0,
343
- start: 0,
344
- end: 0,
345
- reversed: false,
231
+ assemblyName,
232
+ includeAggregateIndexes: true,
233
+ tracks: self.tracks,
346
234
  };
347
235
  },
348
- getTrack: function (id) {
349
- return self.tracks.find(function (t) { return t.configuration.trackId === id; });
236
+ getTrack(id) {
237
+ return self.tracks.find(t => t.configuration.trackId === id);
350
238
  },
351
- rankSearchResults: function (results) {
239
+ rankSearchResults(results) {
352
240
  // order of rank
353
- var openTrackIds = self.tracks.map(function (track) { return track.configuration.trackId; });
354
- results.forEach(function (result) {
241
+ const openTrackIds = self.tracks.map(track => track.configuration.trackId);
242
+ results.forEach(result => {
355
243
  if (openTrackIds.includes(result.trackId)) {
356
244
  result.updateScore(result.getScore() + 1);
357
245
  }
@@ -359,23 +247,18 @@ function stateModelFactory(pluginManager) {
359
247
  return results;
360
248
  },
361
249
  // modifies view menu action onClick to apply to all tracks of same type
362
- rewriteOnClicks: function (trackType, viewMenuActions) {
363
- var _this = this;
364
- viewMenuActions.forEach(function (action) {
250
+ rewriteOnClicks(trackType, viewMenuActions) {
251
+ viewMenuActions.forEach(action => {
365
252
  // go to lowest level menu
366
253
  if ('subMenu' in action) {
367
- _this.rewriteOnClicks(trackType, action.subMenu);
254
+ this.rewriteOnClicks(trackType, action.subMenu);
368
255
  }
369
256
  if ('onClick' in action) {
370
- var holdOnClick_1 = action.onClick;
371
- action.onClick = function () {
372
- var args = [];
373
- for (var _i = 0; _i < arguments.length; _i++) {
374
- args[_i] = arguments[_i];
375
- }
376
- self.tracks.forEach(function (track) {
257
+ const holdOnClick = action.onClick;
258
+ action.onClick = (...args) => {
259
+ self.tracks.forEach(track => {
377
260
  if (track.type === trackType) {
378
- holdOnClick_1.apply(track, __spreadArray([track], __read(args), false));
261
+ holdOnClick.apply(track, [track, ...args]);
379
262
  }
380
263
  });
381
264
  };
@@ -383,143 +266,145 @@ function stateModelFactory(pluginManager) {
383
266
  });
384
267
  },
385
268
  get trackTypeActions() {
386
- var _this = this;
387
- var allActions = new Map();
388
- self.tracks.forEach(function (track) {
389
- var trackInMap = allActions.get(track.type);
269
+ const allActions = new Map();
270
+ self.tracks.forEach(track => {
271
+ const trackInMap = allActions.get(track.type);
390
272
  if (!trackInMap) {
391
- var viewMenuActions = (0, clone_1.default)(track.viewMenuActions);
392
- _this.rewriteOnClicks(track.type, viewMenuActions);
273
+ const viewMenuActions = (0, clone_1.default)(track.viewMenuActions);
274
+ this.rewriteOnClicks(track.type, viewMenuActions);
393
275
  allActions.set(track.type, viewMenuActions);
394
276
  }
395
277
  });
396
278
  return allActions;
397
279
  },
398
- get centerLineInfo() {
399
- return self.displayedRegions.length
400
- ? this.pxToBp(self.width / 2)
401
- : undefined;
402
- },
403
- }); })
404
- .actions(function (self) { return ({
405
- setShowCytobands: function (flag) {
280
+ }))
281
+ .actions(self => ({
282
+ setShowCytobands(flag) {
406
283
  self.showCytobandsSetting = flag;
407
- localStorage.setItem('lgv-showCytobands', "".concat(+flag));
284
+ localStorage.setItem('lgv-showCytobands', `${+flag}`);
408
285
  },
409
- setWidth: function (newWidth) {
286
+ setWidth(newWidth) {
410
287
  self.volatileWidth = newWidth;
411
288
  },
412
- setError: function (error) {
289
+ setError(error) {
413
290
  self.volatileError = error;
414
291
  },
415
- toggleHeader: function () {
292
+ toggleHeader() {
416
293
  self.hideHeader = !self.hideHeader;
417
294
  },
418
- toggleHeaderOverview: function () {
295
+ toggleHeaderOverview() {
419
296
  self.hideHeaderOverview = !self.hideHeaderOverview;
420
297
  },
421
- toggleNoTracksActive: function () {
298
+ toggleNoTracksActive() {
422
299
  self.hideNoTracksActive = !self.hideNoTracksActive;
423
300
  },
424
- scrollTo: function (offsetPx) {
425
- var newOffsetPx = (0, util_1.clamp)(offsetPx, self.minOffset, self.maxOffset);
301
+ toggleShowGridlines() {
302
+ self.showGridlines = !self.showGridlines;
303
+ },
304
+ scrollTo(offsetPx) {
305
+ const newOffsetPx = (0, util_1.clamp)(offsetPx, self.minOffset, self.maxOffset);
426
306
  self.offsetPx = newOffsetPx;
427
307
  return newOffsetPx;
428
308
  },
429
- zoomTo: function (bpPerPx) {
430
- var newBpPerPx = (0, util_1.clamp)(bpPerPx, self.minBpPerPx, self.maxBpPerPx);
309
+ zoomTo(bpPerPx) {
310
+ const newBpPerPx = (0, util_1.clamp)(bpPerPx, self.minBpPerPx, self.maxBpPerPx);
431
311
  if (newBpPerPx === self.bpPerPx) {
432
312
  return newBpPerPx;
433
313
  }
434
- var oldBpPerPx = self.bpPerPx;
314
+ const oldBpPerPx = self.bpPerPx;
435
315
  self.bpPerPx = newBpPerPx;
436
316
  if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
437
317
  console.warn('zoomTo bpPerPx rounding error');
438
318
  return oldBpPerPx;
439
319
  }
440
320
  // tweak the offset so that the center of the view remains at the same coordinate
441
- var viewWidth = self.width;
321
+ const viewWidth = self.width;
442
322
  this.scrollTo(Math.round(((self.offsetPx + viewWidth / 2) * oldBpPerPx) / newBpPerPx -
443
323
  viewWidth / 2));
444
324
  return newBpPerPx;
445
325
  },
446
- setOffsets: function (left, right) {
326
+ setOffsets(left, right) {
447
327
  // sets offsets used in the get sequence dialog
448
328
  self.leftOffset = left;
449
329
  self.rightOffset = right;
450
330
  },
451
- setSearchResults: function (results, query) {
331
+ setSearchResults(results, query) {
452
332
  self.searchResults = results;
453
333
  self.searchQuery = query;
454
334
  },
455
- setSequenceDialogOpen: function (open) {
335
+ setGetSequenceDialogOpen(open) {
456
336
  self.seqDialogDisplayed = open;
457
337
  },
458
- setNewView: function (bpPerPx, offsetPx) {
338
+ setNewView(bpPerPx, offsetPx) {
459
339
  this.zoomTo(bpPerPx);
460
340
  this.scrollTo(offsetPx);
461
341
  },
462
- horizontallyFlip: function () {
342
+ horizontallyFlip() {
463
343
  self.displayedRegions = (0, mobx_state_tree_1.cast)(self.displayedRegions
464
344
  .slice()
465
345
  .reverse()
466
- .map(function (region) { return (__assign(__assign({}, region), { reversed: !region.reversed })); }));
346
+ .map(region => ({ ...region, reversed: !region.reversed })));
467
347
  this.scrollTo(self.totalBp / self.bpPerPx - self.offsetPx - self.width);
468
348
  },
469
- showTrack: function (trackId, initialSnapshot, displayInitialSnapshot) {
470
- if (initialSnapshot === void 0) { initialSnapshot = {}; }
471
- if (displayInitialSnapshot === void 0) { displayInitialSnapshot = {}; }
472
- var schema = pluginManager.pluggableConfigSchemaType('track');
473
- var conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
349
+ showTrack(trackId, initialSnapshot = {}, displayInitialSnapshot = {}) {
350
+ const schema = pluginManager.pluggableConfigSchemaType('track');
351
+ const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
474
352
  if (!conf) {
475
- throw new Error("Could not resolve identifier \"".concat(trackId, "\""));
353
+ throw new Error(`Could not resolve identifier "${trackId}"`);
476
354
  }
477
- var trackType = pluginManager.getTrackType(conf === null || conf === void 0 ? void 0 : conf.type);
355
+ const trackType = pluginManager.getTrackType(conf === null || conf === void 0 ? void 0 : conf.type);
478
356
  if (!trackType) {
479
- throw new Error("Unknown track type ".concat(conf.type));
357
+ throw new Error(`Unknown track type ${conf.type}`);
480
358
  }
481
- var viewType = pluginManager.getViewType(self.type);
482
- var supportedDisplays = viewType.displayTypes.map(function (d) { return d.name; });
483
- var displayConf = conf.displays.find(function (d) {
484
- return supportedDisplays.includes(d.type);
485
- });
359
+ const viewType = pluginManager.getViewType(self.type);
360
+ const supportedDisplays = viewType.displayTypes.map(d => d.name);
361
+ const displayConf = conf.displays.find((d) => supportedDisplays.includes(d.type));
486
362
  if (!displayConf) {
487
- throw new Error("Could not find a compatible display for view type ".concat(self.type));
363
+ throw new Error(`Could not find a compatible display for view type ${self.type}`);
488
364
  }
489
- var t = self.tracks.filter(function (t) { return t.configuration === conf; });
365
+ const t = self.tracks.filter(t => t.configuration === conf);
490
366
  if (t.length === 0) {
491
- var track = trackType.stateModel.create(__assign(__assign({}, initialSnapshot), { type: conf.type, configuration: conf, displays: [
492
- __assign({ type: displayConf.type, configuration: displayConf }, displayInitialSnapshot),
493
- ] }));
367
+ const track = trackType.stateModel.create({
368
+ ...initialSnapshot,
369
+ type: conf.type,
370
+ configuration: conf,
371
+ displays: [
372
+ {
373
+ type: displayConf.type,
374
+ configuration: displayConf,
375
+ ...displayInitialSnapshot,
376
+ },
377
+ ],
378
+ });
494
379
  self.tracks.push(track);
495
380
  return track;
496
381
  }
497
382
  return t[0];
498
383
  },
499
- hideTrack: function (trackId) {
500
- var schema = pluginManager.pluggableConfigSchemaType('track');
501
- var conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
502
- var t = self.tracks.filter(function (t) { return t.configuration === conf; });
503
- (0, mobx_1.transaction)(function () { return t.forEach(function (t) { return self.tracks.remove(t); }); });
384
+ hideTrack(trackId) {
385
+ const schema = pluginManager.pluggableConfigSchemaType('track');
386
+ const conf = (0, mobx_state_tree_1.resolveIdentifier)(schema, (0, mobx_state_tree_1.getRoot)(self), trackId);
387
+ const t = self.tracks.filter(t => t.configuration === conf);
388
+ (0, mobx_1.transaction)(() => t.forEach(t => self.tracks.remove(t)));
504
389
  return t.length;
505
390
  },
506
- }); })
507
- .actions(function (self) { return ({
508
- moveTrack: function (movingId, targetId) {
509
- var oldIndex = self.tracks.findIndex(function (track) { return track.id === movingId; });
391
+ }))
392
+ .actions(self => ({
393
+ moveTrack(movingId, targetId) {
394
+ const oldIndex = self.tracks.findIndex(track => track.id === movingId);
510
395
  if (oldIndex === -1) {
511
- throw new Error("Track ID ".concat(movingId, " not found"));
396
+ throw new Error(`Track ID ${movingId} not found`);
512
397
  }
513
- var newIndex = self.tracks.findIndex(function (track) { return track.id === targetId; });
398
+ const newIndex = self.tracks.findIndex(track => track.id === targetId);
514
399
  if (newIndex === -1) {
515
- throw new Error("Track ID ".concat(targetId, " not found"));
400
+ throw new Error(`Track ID ${targetId} not found`);
516
401
  }
517
- var track = (0, mobx_state_tree_1.getSnapshot)(self.tracks[oldIndex]);
402
+ const track = (0, mobx_state_tree_1.getSnapshot)(self.tracks[oldIndex]);
518
403
  self.tracks.splice(oldIndex, 1);
519
404
  self.tracks.splice(newIndex, 0, track);
520
405
  },
521
- closeView: function () {
522
- var parent = (0, util_1.getContainingView)(self);
406
+ closeView() {
407
+ const parent = (0, util_1.getContainingView)(self);
523
408
  if (parent) {
524
409
  // I am embedded in a some other view
525
410
  if ((0, util_1.isViewContainer)(parent)) {
@@ -531,260 +416,36 @@ function stateModelFactory(pluginManager) {
531
416
  (0, util_1.getSession)(self).removeView(self);
532
417
  }
533
418
  },
534
- toggleTrack: function (trackId) {
419
+ toggleTrack(trackId) {
535
420
  // if we have any tracks with that configuration, turn them off
536
- var hiddenCount = self.hideTrack(trackId);
421
+ const hiddenCount = self.hideTrack(trackId);
537
422
  // if none had that configuration, turn one on
538
423
  if (!hiddenCount) {
539
424
  self.showTrack(trackId);
540
425
  }
541
426
  },
542
- setTrackLabels: function (setting) {
427
+ setTrackLabels(setting) {
543
428
  self.trackLabels = setting;
544
429
  localStorage.setItem('lgv-trackLabels', setting);
545
430
  },
546
- toggleCenterLine: function () {
431
+ toggleCenterLine() {
547
432
  self.showCenterLine = !self.showCenterLine;
548
- localStorage.setItem('lgv-showCenterLine', "".concat(+self.showCenterLine));
433
+ localStorage.setItem('lgv-showCenterLine', `${+self.showCenterLine}`);
549
434
  },
550
- setDisplayedRegions: function (regions) {
435
+ setDisplayedRegions(regions) {
551
436
  self.displayedRegions = (0, mobx_state_tree_1.cast)(regions);
552
437
  self.zoomTo(self.bpPerPx);
553
438
  },
554
- activateTrackSelector: function () {
439
+ activateTrackSelector() {
555
440
  if (self.trackSelectorType === 'hierarchical') {
556
- var session = (0, util_1.getSession)(self);
441
+ const session = (0, util_1.getSession)(self);
557
442
  if ((0, util_1.isSessionModelWithWidgets)(session)) {
558
- var selector = session.addWidget('HierarchicalTrackSelectorWidget', 'hierarchicalTrackSelector', { view: self });
443
+ const selector = session.addWidget('HierarchicalTrackSelectorWidget', 'hierarchicalTrackSelector', { view: self });
559
444
  session.showWidget(selector);
560
445
  return selector;
561
446
  }
562
447
  }
563
- throw new Error("invalid track selector type ".concat(self.trackSelectorType));
564
- },
565
- navToLocString: function (locString, optAssemblyName) {
566
- var assemblyNames = self.assemblyNames;
567
- var assemblyManager = (0, util_1.getSession)(self).assemblyManager;
568
- var isValidRefName = assemblyManager.isValidRefName;
569
- var assemblyName = optAssemblyName || assemblyNames[0];
570
- var parsedLocStrings;
571
- var inputs = locString
572
- .split(/(\s+)/)
573
- .map(function (f) { return f.trim(); })
574
- .filter(function (f) { return !!f; });
575
- // first try interpreting as a whitespace-separated sequence of
576
- // multiple locstrings
577
- try {
578
- parsedLocStrings = inputs.map(function (l) {
579
- return (0, util_1.parseLocString)(l, function (ref) { return isValidRefName(ref, assemblyName); });
580
- });
581
- }
582
- catch (e) {
583
- // if this fails, try interpreting as a whitespace-separated refname,
584
- // start, end if start and end are integer inputs
585
- var _a = __read(inputs, 3), refName = _a[0], start = _a[1], end = _a[2];
586
- if ("".concat(e).match(/Unknown reference sequence/) &&
587
- Number.isInteger(+start) &&
588
- Number.isInteger(+end)) {
589
- parsedLocStrings = [
590
- (0, util_1.parseLocString)(refName + ':' + start + '..' + end, function (ref) {
591
- return isValidRefName(ref, assemblyName);
592
- }),
593
- ];
594
- }
595
- else {
596
- throw e;
597
- }
598
- }
599
- var locations = parsedLocStrings === null || parsedLocStrings === void 0 ? void 0 : parsedLocStrings.map(function (region) {
600
- var asmName = region.assemblyName || assemblyName;
601
- var asm = assemblyManager.get(asmName);
602
- var refName = region.refName;
603
- if (!asm) {
604
- throw new Error("assembly ".concat(asmName, " not found"));
605
- }
606
- var regions = asm.regions;
607
- if (!regions) {
608
- throw new Error("regions not loaded yet for ".concat(asmName));
609
- }
610
- var canonicalRefName = asm.getCanonicalRefName(region.refName);
611
- if (!canonicalRefName) {
612
- throw new Error("Could not find refName ".concat(refName, " in ").concat(asm.name));
613
- }
614
- var parentRegion = regions.find(function (region) { return region.refName === canonicalRefName; });
615
- if (!parentRegion) {
616
- throw new Error("Could not find refName ".concat(refName, " in ").concat(asmName));
617
- }
618
- return __assign(__assign({}, region), { assemblyName: asmName, parentRegion: parentRegion });
619
- });
620
- if (locations.length === 1) {
621
- var loc = locations[0];
622
- this.setDisplayedRegions([
623
- __assign({ reversed: loc.reversed }, loc.parentRegion),
624
- ]);
625
- var start = loc.start, end = loc.end, parentRegion = loc.parentRegion;
626
- this.navTo(__assign(__assign({}, loc), { start: (0, util_1.clamp)(start !== null && start !== void 0 ? start : 0, 0, parentRegion.end), end: (0, util_1.clamp)(end !== null && end !== void 0 ? end : parentRegion.end, 0, parentRegion.end) }));
627
- }
628
- else {
629
- this.setDisplayedRegions(
630
- // @ts-ignore
631
- locations.map(function (r) { return (r.start === undefined ? r.parentRegion : r); }));
632
- this.showAllRegions();
633
- }
634
- },
635
- /**
636
- * Navigate to a location based on its refName and optionally start, end,
637
- * and assemblyName. Can handle if there are multiple displayedRegions
638
- * from same refName. Only navigates to a location if it is entirely
639
- * within a displayedRegion. Navigates to the first matching location
640
- * encountered.
641
- *
642
- * Throws an error if navigation was unsuccessful
643
- *
644
- * @param location - a proposed location to navigate to
645
- */
646
- navTo: function (query) {
647
- this.navToMultiple([query]);
648
- },
649
- navToMultiple: function (locations) {
650
- var firstLocation = locations[0];
651
- var refName = firstLocation.refName;
652
- var start = firstLocation.start, end = firstLocation.end, _a = firstLocation.assemblyName, assemblyName = _a === void 0 ? self.assemblyNames[0] : _a;
653
- if (start !== undefined && end !== undefined && start > end) {
654
- throw new Error("start \"".concat(start + 1, "\" is greater than end \"").concat(end, "\""));
655
- }
656
- var session = (0, util_1.getSession)(self);
657
- var assemblyManager = session.assemblyManager;
658
- var assembly = assemblyManager.get(assemblyName);
659
- if (assembly) {
660
- var canonicalRefName = assembly.getCanonicalRefName(refName);
661
- if (canonicalRefName) {
662
- refName = canonicalRefName;
663
- }
664
- }
665
- var s = start;
666
- var e = end;
667
- var refNameMatched = false;
668
- var predicate = function (r) {
669
- if (refName === r.refName) {
670
- refNameMatched = true;
671
- if (s === undefined) {
672
- s = r.start;
673
- }
674
- if (e === undefined) {
675
- e = r.end;
676
- }
677
- if (s >= r.start && s <= r.end && e <= r.end && e >= r.start) {
678
- return true;
679
- }
680
- s = start;
681
- e = end;
682
- }
683
- return false;
684
- };
685
- var lastIndex = (0, util_1.findLastIndex)(self.displayedRegions, predicate);
686
- var index;
687
- while (index !== lastIndex) {
688
- try {
689
- var previousIndex = index;
690
- index = self.displayedRegions
691
- .slice(previousIndex === undefined ? 0 : previousIndex + 1)
692
- .findIndex(predicate);
693
- if (previousIndex !== undefined) {
694
- index += previousIndex + 1;
695
- }
696
- if (!refNameMatched) {
697
- throw new Error("could not find a region with refName \"".concat(refName, "\""));
698
- }
699
- if (s === undefined) {
700
- throw new Error("could not find a region with refName \"".concat(refName, "\" that contained an end position ").concat(e));
701
- }
702
- if (e === undefined) {
703
- throw new Error("could not find a region with refName \"".concat(refName, "\" that contained a start position ").concat(s + 1));
704
- }
705
- if (index === -1) {
706
- throw new Error("could not find a region that completely contained \"".concat((0, util_1.assembleLocString)(firstLocation), "\""));
707
- }
708
- if (locations.length === 1) {
709
- var f = self.displayedRegions[index];
710
- this.moveTo({ index: index, offset: f.reversed ? f.end - e : s - f.start }, { index: index, offset: f.reversed ? f.end - s : e - f.start });
711
- return;
712
- }
713
- var locationIndex = 0;
714
- var locationStart = 0;
715
- var locationEnd = 0;
716
- for (locationIndex; locationIndex < locations.length; locationIndex++) {
717
- var location_1 = locations[locationIndex];
718
- var region = self.displayedRegions[index + locationIndex];
719
- locationStart = location_1.start || region.start;
720
- locationEnd = location_1.end || region.end;
721
- if (location_1.refName !== region.refName) {
722
- throw new Error("Entered location ".concat((0, util_1.assembleLocString)(location_1), " does not match with displayed regions"));
723
- }
724
- }
725
- locationIndex -= 1;
726
- var startDisplayedRegion = self.displayedRegions[index];
727
- var endDisplayedRegion = self.displayedRegions[index + locationIndex];
728
- this.moveTo({
729
- index: index,
730
- offset: startDisplayedRegion.reversed
731
- ? startDisplayedRegion.end - e
732
- : s - startDisplayedRegion.start,
733
- }, {
734
- index: index + locationIndex,
735
- offset: endDisplayedRegion.reversed
736
- ? endDisplayedRegion.end - locationStart
737
- : locationEnd - endDisplayedRegion.start,
738
- });
739
- return;
740
- }
741
- catch (error) {
742
- if (index === lastIndex) {
743
- throw error;
744
- }
745
- }
746
- }
747
- },
748
- /**
749
- * Navigate to a location based on user clicking and dragging on the
750
- * overview scale bar to select a region to zoom into.
751
- * Can handle if there are multiple displayedRegions from same refName.
752
- * Only navigates to a location if it is entirely within a displayedRegion.
753
- *
754
- * @param leftPx- `object as {start, end, index, offset}`, offset = start of user drag
755
- * @param rightPx- `object as {start, end, index, offset}`, offset = end of user drag
756
- */
757
- zoomToDisplayedRegions: function (leftPx, rightPx) {
758
- var _a;
759
- if (leftPx === undefined || rightPx === undefined) {
760
- return;
761
- }
762
- var singleRefSeq = leftPx.refName === rightPx.refName && leftPx.index === rightPx.index;
763
- // zooming into one displayed Region
764
- if ((singleRefSeq && rightPx.offset < leftPx.offset) ||
765
- leftPx.index > rightPx.index) {
766
- ;
767
- _a = __read([rightPx, leftPx], 2), leftPx = _a[0], rightPx = _a[1];
768
- }
769
- var startOffset = {
770
- start: leftPx.start,
771
- end: leftPx.end,
772
- index: leftPx.index,
773
- offset: leftPx.offset,
774
- };
775
- var endOffset = {
776
- start: rightPx.start,
777
- end: rightPx.end,
778
- index: rightPx.index,
779
- offset: rightPx.offset,
780
- };
781
- if (startOffset && endOffset) {
782
- this.moveTo(startOffset, endOffset);
783
- }
784
- else {
785
- var session = (0, util_1.getSession)(self);
786
- session.notify('No regions found to navigate to', 'warning');
787
- }
448
+ throw new Error(`invalid track selector type ${self.trackSelectorType}`);
788
449
  },
789
450
  /**
790
451
  * Helper method for the fetchSequence.
@@ -794,112 +455,56 @@ function stateModelFactory(pluginManager) {
794
455
  * @param rightOffset - `object as {start, end, index, offset}`, offset = end of user drag
795
456
  * @returns array of Region[]
796
457
  */
797
- getSelectedRegions: function (leftOffset, rightOffset) {
798
- var snap = (0, mobx_state_tree_1.getSnapshot)(self);
799
- var simView = Base1DViewModel_1.default.create(__assign(__assign({}, snap), { interRegionPaddingWidth: self.interRegionPaddingWidth }));
458
+ getSelectedRegions(leftOffset, rightOffset) {
459
+ const snap = (0, mobx_state_tree_1.getSnapshot)(self);
460
+ const simView = Base1DViewModel_1.default.create({
461
+ ...snap,
462
+ interRegionPaddingWidth: self.interRegionPaddingWidth,
463
+ });
800
464
  simView.setVolatileWidth(self.width);
801
- simView.zoomToDisplayedRegions(leftOffset, rightOffset);
802
- return simView.dynamicBlocks.contentBlocks.map(function (region) { return (__assign(__assign({}, region), { start: Math.floor(region.start), end: Math.ceil(region.end) })); });
465
+ simView.moveTo(leftOffset, rightOffset);
466
+ return simView.dynamicBlocks.contentBlocks.map(region => ({
467
+ ...region,
468
+ start: Math.floor(region.start),
469
+ end: Math.ceil(region.end),
470
+ }));
803
471
  },
804
472
  // schedule something to be run after the next time displayedRegions is set
805
- afterDisplayedRegionsSet: function (cb) {
473
+ afterDisplayedRegionsSet(cb) {
806
474
  self.afterDisplayedRegionsSetCallbacks.push(cb);
807
475
  },
808
- /**
809
- * offset is the base-pair-offset in the displayed region, index is the index of the
810
- * displayed region in the linear genome view
811
- *
812
- * @param start - object as `{start, end, offset, index}`
813
- * @param end - object as `{start, end, offset, index}`
814
- */
815
- moveTo: function (start, end) {
816
- // find locations in the modellist
817
- var bpSoFar = 0;
818
- if (start.index === end.index) {
819
- bpSoFar += end.offset - start.offset;
820
- }
821
- else {
822
- var s = self.displayedRegions[start.index];
823
- bpSoFar += s.end - s.start - start.offset;
824
- if (end.index - start.index >= 2) {
825
- for (var i = start.index + 1; i < end.index; i += 1) {
826
- bpSoFar +=
827
- self.displayedRegions[i].end - self.displayedRegions[i].start;
828
- }
829
- }
830
- bpSoFar += end.offset;
831
- }
832
- var targetBpPerPx = bpSoFar /
833
- (self.width -
834
- self.interRegionPaddingWidth * (end.index - start.index));
835
- var newBpPerPx = self.zoomTo(targetBpPerPx);
836
- // If our target bpPerPx was smaller than the allowed minBpPerPx, adjust
837
- // the scroll so the requested range is in the middle of the screen
838
- var extraBp = 0;
839
- if (targetBpPerPx < newBpPerPx) {
840
- extraBp = ((newBpPerPx - targetBpPerPx) * self.width) / 2;
841
- }
842
- var bpToStart = -extraBp;
843
- for (var i = 0; i < self.displayedRegions.length; i += 1) {
844
- var region = self.displayedRegions[i];
845
- if (start.index === i) {
846
- bpToStart += start.offset;
847
- break;
848
- }
849
- else {
850
- bpToStart += region.end - region.start;
851
- }
852
- }
853
- self.scrollTo(Math.round(bpToStart / self.bpPerPx) +
854
- self.interRegionPaddingWidth * start.index);
855
- },
856
- horizontalScroll: function (distance) {
857
- var oldOffsetPx = self.offsetPx;
476
+ horizontalScroll(distance) {
477
+ const oldOffsetPx = self.offsetPx;
858
478
  // newOffsetPx is the actual offset after the scroll is clamped
859
- var newOffsetPx = self.scrollTo(self.offsetPx + distance);
479
+ const newOffsetPx = self.scrollTo(self.offsetPx + distance);
860
480
  return newOffsetPx - oldOffsetPx;
861
481
  },
862
- /**
863
- * scrolls the view to center on the given bp. if that is not in any
864
- * of the displayed regions, does nothing
865
- * @param bp - basepair at which you want to center the view
866
- * @param refName - refName of the displayedRegion you are centering at
867
- * @param regionIndex - index of the displayedRegion
868
- */
869
- centerAt: function (bp, refName, regionIndex) {
870
- var centerPx = self.bpToPx({
871
- refName: refName,
872
- coord: bp,
873
- regionNumber: regionIndex,
874
- });
875
- if (centerPx) {
876
- self.scrollTo(Math.round(centerPx.offsetPx - self.width / 2));
877
- }
482
+ center() {
483
+ const centerBp = self.totalBp / 2;
484
+ const centerPx = centerBp / self.bpPerPx;
485
+ self.scrollTo(Math.round(centerPx - self.width / 2));
878
486
  },
879
- center: function () {
880
- var centerBp = self.totalBp / 2;
881
- self.scrollTo(Math.round(centerBp / self.bpPerPx - self.width / 2));
882
- },
883
- showAllRegions: function () {
487
+ showAllRegions() {
884
488
  self.zoomTo(self.maxBpPerPx);
885
489
  this.center();
886
490
  },
887
- showAllRegionsInAssembly: function (assemblyName) {
888
- var _a;
889
- var session = (0, util_1.getSession)(self);
890
- var assemblyManager = session.assemblyManager;
491
+ showAllRegionsInAssembly(assemblyName) {
492
+ const session = (0, util_1.getSession)(self);
493
+ const { assemblyManager } = session;
891
494
  if (!assemblyName) {
892
- var assemblyNames = __spreadArray([], __read(new Set(self.displayedRegions.map(function (region) { return region.assemblyName; }))), false);
495
+ const assemblyNames = [
496
+ ...new Set(self.displayedRegions.map(region => region.assemblyName)),
497
+ ];
893
498
  if (assemblyNames.length > 1) {
894
- session.notify("Can't perform this with multiple assemblies currently");
499
+ session.notify(`Can't perform this with multiple assemblies currently`);
895
500
  return;
896
501
  }
897
502
  ;
898
- _a = __read(assemblyNames, 1), assemblyName = _a[0];
503
+ [assemblyName] = assemblyNames;
899
504
  }
900
- var assembly = assemblyManager.get(assemblyName);
505
+ const assembly = assemblyManager.get(assemblyName);
901
506
  if (assembly) {
902
- var regions = assembly.regions;
507
+ const { regions } = assembly;
903
508
  if (regions) {
904
509
  this.setDisplayedRegions(regions);
905
510
  self.zoomTo(self.maxBpPerPx);
@@ -907,25 +512,25 @@ function stateModelFactory(pluginManager) {
907
512
  }
908
513
  }
909
514
  },
910
- setDraggingTrackId: function (idx) {
515
+ setDraggingTrackId(idx) {
911
516
  self.draggingTrackId = idx;
912
517
  },
913
- setScaleFactor: function (factor) {
518
+ setScaleFactor(factor) {
914
519
  self.scaleFactor = factor;
915
520
  },
916
- }); })
917
- .actions(function (self) {
918
- var cancelLastAnimation = function () { };
521
+ }))
522
+ .actions(self => {
523
+ let cancelLastAnimation = () => { };
919
524
  function slide(viewWidths) {
920
- var _a = __read((0, util_1.springAnimate)(self.offsetPx, self.offsetPx + self.width * viewWidths, self.scrollTo), 2), animate = _a[0], cancelAnimation = _a[1];
525
+ const [animate, cancelAnimation] = (0, util_1.springAnimate)(self.offsetPx, self.offsetPx + self.width * viewWidths, self.scrollTo);
921
526
  cancelLastAnimation();
922
527
  cancelLastAnimation = cancelAnimation;
923
528
  animate();
924
529
  }
925
- return { slide: slide };
530
+ return { slide };
926
531
  })
927
- .actions(function (self) {
928
- var cancelLastAnimation = function () { };
532
+ .actions(self => {
533
+ let cancelLastAnimation = () => { };
929
534
  function zoom(targetBpPerPx) {
930
535
  self.zoomTo(self.bpPerPx);
931
536
  if (
@@ -935,18 +540,18 @@ function stateModelFactory(pluginManager) {
935
540
  (targetBpPerPx > self.bpPerPx && self.bpPerPx === self.maxBpPerPx)) {
936
541
  return;
937
542
  }
938
- var factor = self.bpPerPx / targetBpPerPx;
939
- var _a = __read((0, util_1.springAnimate)(1, factor, self.setScaleFactor, function () {
543
+ const factor = self.bpPerPx / targetBpPerPx;
544
+ const [animate, cancelAnimation] = (0, util_1.springAnimate)(1, factor, self.setScaleFactor, () => {
940
545
  self.zoomTo(targetBpPerPx);
941
546
  self.setScaleFactor(1);
942
- }), 2), animate = _a[0], cancelAnimation = _a[1];
547
+ });
943
548
  cancelLastAnimation();
944
549
  cancelLastAnimation = cancelAnimation;
945
550
  animate();
946
551
  }
947
- return { zoom: zoom };
552
+ return { zoom };
948
553
  })
949
- .views(function (self) { return ({
554
+ .views(self => ({
950
555
  get canShowCytobands() {
951
556
  return self.displayedRegions.length === 1 && this.anyCytobandsExist;
952
557
  },
@@ -954,39 +559,47 @@ function stateModelFactory(pluginManager) {
954
559
  return this.canShowCytobands && self.showCytobandsSetting;
955
560
  },
956
561
  get anyCytobandsExist() {
957
- var assemblyManager = (0, util_1.getSession)(self).assemblyManager;
958
- var assemblyNames = self.assemblyNames;
959
- return assemblyNames.some(function (asm) { var _a, _b; return (_b = (_a = assemblyManager.get(asm)) === null || _a === void 0 ? void 0 : _a.cytobands) === null || _b === void 0 ? void 0 : _b.length; });
562
+ const { assemblyManager } = (0, util_1.getSession)(self);
563
+ const { assemblyNames } = self;
564
+ return assemblyNames.some(asm => { var _a, _b; return (_b = (_a = assemblyManager.get(asm)) === null || _a === void 0 ? void 0 : _a.cytobands) === null || _b === void 0 ? void 0 : _b.length; });
960
565
  },
961
566
  get cytobandOffset() {
962
567
  return this.showCytobands
963
568
  ? (0, util_1.measureText)(self.displayedRegions[0].refName, 12) + 15
964
569
  : 0;
965
570
  },
966
- }); })
967
- .views(function (self) { return ({
968
- menuItems: function () {
969
- var e_1, _a;
970
- var canShowCytobands = self.canShowCytobands, showCytobands = self.showCytobands;
971
- var menuItems = __spreadArray([
571
+ }))
572
+ .views(self => ({
573
+ menuItems() {
574
+ const { canShowCytobands, showCytobands } = self;
575
+ const menuItems = [
972
576
  {
973
577
  label: 'Return to import form',
974
- onClick: function () {
975
- (0, util_1.getSession)(self).queueDialog(function (handleClose) { return [
578
+ onClick: () => {
579
+ (0, util_1.getSession)(self).queueDialog(handleClose => [
976
580
  ui_1.ReturnToImportFormDialog,
977
- { model: self, handleClose: handleClose },
978
- ]; });
581
+ { model: self, handleClose },
582
+ ]);
979
583
  },
980
584
  icon: FolderOpen_1.default,
981
585
  },
586
+ {
587
+ label: 'Sequence search',
588
+ onClick: () => {
589
+ (0, util_1.getSession)(self).queueDialog(handleClose => [
590
+ SequenceSearchDialog,
591
+ { model: self, handleClose },
592
+ ]);
593
+ },
594
+ },
982
595
  {
983
596
  label: 'Export SVG',
984
597
  icon: PhotoCamera_1.default,
985
- onClick: function () {
986
- (0, util_1.getSession)(self).queueDialog(function (handleClose) { return [
598
+ onClick: () => {
599
+ (0, util_1.getSession)(self).queueDialog(handleClose => [
987
600
  ExportSvgDialog_1.default,
988
- { model: self, handleClose: handleClose },
989
- ]; });
601
+ { model: self, handleClose },
602
+ ]);
990
603
  },
991
604
  },
992
605
  {
@@ -1034,6 +647,24 @@ function stateModelFactory(pluginManager) {
1034
647
  checked: !self.hideNoTracksActive,
1035
648
  onClick: self.toggleNoTracksActive,
1036
649
  },
650
+ {
651
+ label: 'Show guidelines',
652
+ icon: Visibility_1.default,
653
+ type: 'checkbox',
654
+ checked: self.showGridlines,
655
+ onClick: self.toggleShowGridlines,
656
+ },
657
+ ...(canShowCytobands
658
+ ? [
659
+ {
660
+ label: 'Show ideogram',
661
+ icon: Visibility_1.default,
662
+ type: 'checkbox',
663
+ checked: self.showCytobands,
664
+ onClick: () => self.setShowCytobands(!showCytobands),
665
+ },
666
+ ]
667
+ : []),
1037
668
  {
1038
669
  label: 'Track labels',
1039
670
  icon: Label_1.default,
@@ -1043,63 +674,42 @@ function stateModelFactory(pluginManager) {
1043
674
  icon: Visibility_1.default,
1044
675
  type: 'radio',
1045
676
  checked: self.trackLabels === 'overlapping',
1046
- onClick: function () { return self.setTrackLabels('overlapping'); },
677
+ onClick: () => self.setTrackLabels('overlapping'),
1047
678
  },
1048
679
  {
1049
680
  label: 'Offset',
1050
681
  icon: Visibility_1.default,
1051
682
  type: 'radio',
1052
683
  checked: self.trackLabels === 'offset',
1053
- onClick: function () { return self.setTrackLabels('offset'); },
684
+ onClick: () => self.setTrackLabels('offset'),
1054
685
  },
1055
686
  {
1056
687
  label: 'Hidden',
1057
688
  icon: Visibility_1.default,
1058
689
  type: 'radio',
1059
690
  checked: self.trackLabels === 'hidden',
1060
- onClick: function () { return self.setTrackLabels('hidden'); },
691
+ onClick: () => self.setTrackLabels('hidden'),
1061
692
  },
1062
693
  ],
694
+ },
695
+ ];
696
+ // add track's view level menu options
697
+ for (const [key, value] of self.trackTypeActions.entries()) {
698
+ if (value.length) {
699
+ menuItems.push({ type: 'divider' }, { type: 'subHeader', label: key });
700
+ value.forEach(action => menuItems.push(action));
1063
701
  }
1064
- ], __read((canShowCytobands
1065
- ? [
1066
- {
1067
- label: showCytobands ? 'Hide ideogram' : 'Show ideograms',
1068
- onClick: function () {
1069
- self.setShowCytobands(!showCytobands);
1070
- },
1071
- },
1072
- ]
1073
- : [])), false);
1074
- try {
1075
- // add track's view level menu options
1076
- for (var _b = __values(self.trackTypeActions.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
1077
- var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
1078
- if (value.length) {
1079
- menuItems.push({ type: 'divider' }, { type: 'subHeader', label: key });
1080
- value.forEach(function (action) {
1081
- menuItems.push(action);
1082
- });
1083
- }
1084
- }
1085
- }
1086
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1087
- finally {
1088
- try {
1089
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1090
- }
1091
- finally { if (e_1) throw e_1.error; }
1092
702
  }
1093
703
  return menuItems;
1094
704
  },
1095
- }); })
1096
- .views(function (self) {
1097
- var currentlyCalculatedStaticBlocks;
1098
- var stringifiedCurrentlyCalculatedStaticBlocks = '';
705
+ }))
706
+ .views(self => {
707
+ let currentlyCalculatedStaticBlocks;
708
+ let stringifiedCurrentlyCalculatedStaticBlocks = '';
1099
709
  return {
1100
710
  get staticBlocks() {
1101
- var ret = (0, calculateStaticBlocks_1.default)(self);
1102
- var sret = JSON.stringify(ret);
711
+ const ret = (0, calculateStaticBlocks_1.default)(self);
712
+ const sret = JSON.stringify(ret);
1103
713
  if (stringifiedCurrentlyCalculatedStaticBlocks !== sret) {
1104
714
  currentlyCalculatedStaticBlocks = ret;
1105
715
  stringifiedCurrentlyCalculatedStaticBlocks = sret;
@@ -1110,8 +720,12 @@ function stateModelFactory(pluginManager) {
1110
720
  return (0, calculateDynamicBlocks_1.default)(self);
1111
721
  },
1112
722
  get roundedDynamicBlocks() {
1113
- return this.dynamicBlocks.contentBlocks.map(function (block) {
1114
- return __assign(__assign({}, block), { start: Math.floor(block.start), end: Math.ceil(block.end) });
723
+ return this.dynamicBlocks.contentBlocks.map(block => {
724
+ return {
725
+ ...block,
726
+ start: Math.floor(block.start),
727
+ end: Math.ceil(block.end),
728
+ };
1115
729
  });
1116
730
  },
1117
731
  get visibleLocStrings() {
@@ -1122,9 +736,9 @@ function stateModelFactory(pluginManager) {
1122
736
  },
1123
737
  };
1124
738
  })
1125
- .actions(function (self) { return ({
739
+ .actions(self => ({
1126
740
  // this "clears the view" and makes the view return to the import form
1127
- clearView: function () {
741
+ clearView() {
1128
742
  self.setDisplayedRegions([]);
1129
743
  self.tracks.clear();
1130
744
  // it is necessary to run these after setting displayed regions empty
@@ -1133,60 +747,270 @@ function stateModelFactory(pluginManager) {
1133
747
  self.scrollTo(0);
1134
748
  self.zoomTo(10);
1135
749
  },
1136
- setCoarseDynamicBlocks: function (blocks) {
750
+ setCoarseDynamicBlocks(blocks) {
1137
751
  self.coarseDynamicBlocks = blocks.contentBlocks;
1138
752
  self.coarseTotalBp = blocks.totalBp;
1139
753
  },
1140
- afterAttach: function () {
1141
- var _this = this;
1142
- (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(function () {
754
+ afterAttach() {
755
+ (0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
1143
756
  if (self.initialized) {
1144
- _this.setCoarseDynamicBlocks(self.dynamicBlocks);
757
+ this.setCoarseDynamicBlocks(self.dynamicBlocks);
1145
758
  }
1146
759
  }, { delay: 150 }));
1147
760
  },
1148
- }); })
1149
- .actions(function (self) { return ({
1150
- exportSvg: function (opts) {
1151
- if (opts === void 0) { opts = {}; }
1152
- return __awaiter(this, void 0, void 0, function () {
1153
- var html, blob;
1154
- return __generator(this, function (_a) {
1155
- switch (_a.label) {
1156
- case 0: return [4 /*yield*/, (0, LinearGenomeViewSvg_1.renderToSvg)(self, opts)];
1157
- case 1:
1158
- html = _a.sent();
1159
- blob = new Blob([html], { type: 'image/svg+xml' });
1160
- (0, file_saver_1.saveAs)(blob, opts.filename || 'image.svg');
1161
- return [2 /*return*/];
1162
- }
1163
- });
761
+ }))
762
+ .actions(self => ({
763
+ async exportSvg(opts = {}) {
764
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
765
+ const html = await (0, LinearGenomeViewSvg_1.renderToSvg)(self, opts);
766
+ const blob = new Blob([html], { type: 'image/svg+xml' });
767
+ (0, file_saver_1.saveAs)(blob, opts.filename || 'image.svg');
768
+ },
769
+ /**
770
+ * offset is the base-pair-offset in the displayed region, index is the index of the
771
+ * displayed region in the linear genome view
772
+ *
773
+ * @param start - object as `{start, end, offset, index}`
774
+ * @param end - object as `{start, end, offset, index}`
775
+ */
776
+ moveTo(start, end) {
777
+ (0, Base1DUtils_1.moveTo)(self, start, end);
778
+ },
779
+ navToLocString(locString, optAssemblyName) {
780
+ const { assemblyNames } = self;
781
+ const { assemblyManager } = (0, util_1.getSession)(self);
782
+ const { isValidRefName } = assemblyManager;
783
+ const assemblyName = optAssemblyName || assemblyNames[0];
784
+ let parsedLocStrings;
785
+ const inputs = locString
786
+ .split(/(\s+)/)
787
+ .map(f => f.trim())
788
+ .filter(f => !!f);
789
+ // first try interpreting as a whitespace-separated sequence of
790
+ // multiple locstrings
791
+ try {
792
+ parsedLocStrings = inputs.map(l => (0, util_1.parseLocString)(l, ref => isValidRefName(ref, assemblyName)));
793
+ }
794
+ catch (e) {
795
+ // if this fails, try interpreting as a whitespace-separated refname,
796
+ // start, end if start and end are integer inputs
797
+ const [refName, start, end] = inputs;
798
+ if (`${e}`.match(/Unknown reference sequence/) &&
799
+ Number.isInteger(+start) &&
800
+ Number.isInteger(+end)) {
801
+ parsedLocStrings = [
802
+ (0, util_1.parseLocString)(refName + ':' + start + '..' + end, ref => isValidRefName(ref, assemblyName)),
803
+ ];
804
+ }
805
+ else {
806
+ throw e;
807
+ }
808
+ }
809
+ const locations = parsedLocStrings === null || parsedLocStrings === void 0 ? void 0 : parsedLocStrings.map(region => {
810
+ const asmName = region.assemblyName || assemblyName;
811
+ const asm = assemblyManager.get(asmName);
812
+ const { refName } = region;
813
+ if (!asm) {
814
+ throw new Error(`assembly ${asmName} not found`);
815
+ }
816
+ const { regions } = asm;
817
+ if (!regions) {
818
+ throw new Error(`regions not loaded yet for ${asmName}`);
819
+ }
820
+ const canonicalRefName = asm.getCanonicalRefName(region.refName);
821
+ if (!canonicalRefName) {
822
+ throw new Error(`Could not find refName ${refName} in ${asm.name}`);
823
+ }
824
+ const parentRegion = regions.find(region => region.refName === canonicalRefName);
825
+ if (!parentRegion) {
826
+ throw new Error(`Could not find refName ${refName} in ${asmName}`);
827
+ }
828
+ return {
829
+ ...region,
830
+ assemblyName: asmName,
831
+ parentRegion,
832
+ };
1164
833
  });
834
+ if (locations.length === 1) {
835
+ const loc = locations[0];
836
+ self.setDisplayedRegions([
837
+ { reversed: loc.reversed, ...loc.parentRegion },
838
+ ]);
839
+ const { start, end, parentRegion } = loc;
840
+ this.navTo({
841
+ ...loc,
842
+ start: (0, util_1.clamp)(start !== null && start !== void 0 ? start : 0, 0, parentRegion.end),
843
+ end: (0, util_1.clamp)(end !== null && end !== void 0 ? end : parentRegion.end, 0, parentRegion.end),
844
+ });
845
+ }
846
+ else {
847
+ self.setDisplayedRegions(
848
+ // @ts-ignore
849
+ locations.map(r => (r.start === undefined ? r.parentRegion : r)));
850
+ self.showAllRegions();
851
+ }
1165
852
  },
1166
- }); })
1167
- .views(function (self) { return ({
1168
- rubberBandMenuItems: function () {
853
+ /**
854
+ * Navigate to a location based on its refName and optionally start, end,
855
+ * and assemblyName. Can handle if there are multiple displayedRegions
856
+ * from same refName. Only navigates to a location if it is entirely
857
+ * within a displayedRegion. Navigates to the first matching location
858
+ * encountered.
859
+ *
860
+ * Throws an error if navigation was unsuccessful
861
+ *
862
+ * @param location - a proposed location to navigate to
863
+ */
864
+ navTo(query) {
865
+ this.navToMultiple([query]);
866
+ },
867
+ navToMultiple(locations) {
868
+ const firstLocation = locations[0];
869
+ let { refName } = firstLocation;
870
+ const { start, end, assemblyName = self.assemblyNames[0], } = firstLocation;
871
+ if (start !== undefined && end !== undefined && start > end) {
872
+ throw new Error(`start "${start + 1}" is greater than end "${end}"`);
873
+ }
874
+ const session = (0, util_1.getSession)(self);
875
+ const { assemblyManager } = session;
876
+ const assembly = assemblyManager.get(assemblyName);
877
+ if (assembly) {
878
+ const canonicalRefName = assembly.getCanonicalRefName(refName);
879
+ if (canonicalRefName) {
880
+ refName = canonicalRefName;
881
+ }
882
+ }
883
+ let s = start;
884
+ let e = end;
885
+ let refNameMatched = false;
886
+ const predicate = (r) => {
887
+ if (refName === r.refName) {
888
+ refNameMatched = true;
889
+ if (s === undefined) {
890
+ s = r.start;
891
+ }
892
+ if (e === undefined) {
893
+ e = r.end;
894
+ }
895
+ if (s >= r.start && s <= r.end && e <= r.end && e >= r.start) {
896
+ return true;
897
+ }
898
+ s = start;
899
+ e = end;
900
+ }
901
+ return false;
902
+ };
903
+ const lastIndex = (0, util_1.findLastIndex)(self.displayedRegions, predicate);
904
+ let index;
905
+ while (index !== lastIndex) {
906
+ try {
907
+ const previousIndex = index;
908
+ index = self.displayedRegions
909
+ .slice(previousIndex === undefined ? 0 : previousIndex + 1)
910
+ .findIndex(predicate);
911
+ if (previousIndex !== undefined) {
912
+ index += previousIndex + 1;
913
+ }
914
+ if (!refNameMatched) {
915
+ throw new Error(`could not find a region with refName "${refName}"`);
916
+ }
917
+ if (s === undefined) {
918
+ throw new Error(`could not find a region with refName "${refName}" that contained an end position ${e}`);
919
+ }
920
+ if (e === undefined) {
921
+ throw new Error(`could not find a region with refName "${refName}" that contained a start position ${s + 1}`);
922
+ }
923
+ if (index === -1) {
924
+ throw new Error(`could not find a region that completely contained "${(0, util_1.assembleLocString)(firstLocation)}"`);
925
+ }
926
+ if (locations.length === 1) {
927
+ const f = self.displayedRegions[index];
928
+ this.moveTo({ index, offset: f.reversed ? f.end - e : s - f.start }, { index, offset: f.reversed ? f.end - s : e - f.start });
929
+ return;
930
+ }
931
+ let locationIndex = 0;
932
+ let locationStart = 0;
933
+ let locationEnd = 0;
934
+ for (locationIndex; locationIndex < locations.length; locationIndex++) {
935
+ const location = locations[locationIndex];
936
+ const region = self.displayedRegions[index + locationIndex];
937
+ locationStart = location.start || region.start;
938
+ locationEnd = location.end || region.end;
939
+ if (location.refName !== region.refName) {
940
+ throw new Error(`Entered location ${(0, util_1.assembleLocString)(location)} does not match with displayed regions`);
941
+ }
942
+ }
943
+ locationIndex -= 1;
944
+ const startDisplayedRegion = self.displayedRegions[index];
945
+ const endDisplayedRegion = self.displayedRegions[index + locationIndex];
946
+ this.moveTo({
947
+ index,
948
+ offset: startDisplayedRegion.reversed
949
+ ? startDisplayedRegion.end - e
950
+ : s - startDisplayedRegion.start,
951
+ }, {
952
+ index: index + locationIndex,
953
+ offset: endDisplayedRegion.reversed
954
+ ? endDisplayedRegion.end - locationStart
955
+ : locationEnd - endDisplayedRegion.start,
956
+ });
957
+ return;
958
+ }
959
+ catch (error) {
960
+ if (index === lastIndex) {
961
+ throw error;
962
+ }
963
+ }
964
+ }
965
+ },
966
+ }))
967
+ .views(self => ({
968
+ rubberBandMenuItems() {
1169
969
  return [
1170
970
  {
1171
971
  label: 'Zoom to region',
1172
972
  icon: ZoomIn_1.default,
1173
- onClick: function () {
1174
- var leftOffset = self.leftOffset, rightOffset = self.rightOffset;
1175
- if (leftOffset && rightOffset) {
1176
- self.moveTo(leftOffset, rightOffset);
1177
- }
973
+ onClick: () => {
974
+ const { leftOffset, rightOffset } = self;
975
+ self.moveTo(leftOffset, rightOffset);
1178
976
  },
1179
977
  },
1180
978
  {
1181
979
  label: 'Get sequence',
1182
980
  icon: MenuOpen_1.default,
1183
- onClick: function () {
1184
- self.setSequenceDialogOpen(true);
1185
- },
981
+ onClick: () => self.setGetSequenceDialogOpen(true),
1186
982
  },
1187
983
  ];
1188
984
  },
1189
- }); });
985
+ bpToPx({ refName, coord, regionNumber, }) {
986
+ return (0, Base1DUtils_1.bpToPx)({ refName, coord, regionNumber, self });
987
+ },
988
+ /**
989
+ * scrolls the view to center on the given bp. if that is not in any
990
+ * of the displayed regions, does nothing
991
+ * @param coord - basepair at which you want to center the view
992
+ * @param refName - refName of the displayedRegion you are centering at
993
+ * @param regionNumber - index of the displayedRegion
994
+ */
995
+ centerAt(coord, refName, regionNumber) {
996
+ const centerPx = this.bpToPx({
997
+ refName,
998
+ coord,
999
+ regionNumber,
1000
+ });
1001
+ if (centerPx) {
1002
+ self.scrollTo(Math.round(centerPx.offsetPx - self.width / 2));
1003
+ }
1004
+ },
1005
+ pxToBp(px) {
1006
+ return (0, Base1DUtils_1.pxToBp)(self, px);
1007
+ },
1008
+ get centerLineInfo() {
1009
+ return self.displayedRegions.length
1010
+ ? this.pxToBp(self.width / 2)
1011
+ : undefined;
1012
+ },
1013
+ }));
1190
1014
  }
1191
1015
  exports.stateModelFactory = stateModelFactory;
1192
1016
  var LinearGenomeView_1 = require("./components/LinearGenomeView");