@jbrowse/core 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/BaseFeatureWidget/BaseFeatureDetail.js +13 -9
  2. package/BaseFeatureWidget/SequencePanel.js +1 -1
  3. package/BaseFeatureWidget/index.js +2 -2
  4. package/PluginLoader.js +8 -8
  5. package/PluginManager.d.ts +1 -1
  6. package/PluginManager.js +2 -3
  7. package/ReExports/Attributes.d.ts +1 -2
  8. package/ReExports/Attributes.js +4 -3
  9. package/ReExports/BaseCard.d.ts +1 -2
  10. package/ReExports/BaseCard.js +4 -3
  11. package/ReExports/DataGrid.d.ts +1 -2
  12. package/ReExports/DataGrid.js +2 -2
  13. package/ReExports/FeatureDetails.d.ts +1 -2
  14. package/ReExports/FeatureDetails.js +4 -3
  15. package/ReExports/index.d.ts +1 -2
  16. package/ReExports/index.js +3 -2
  17. package/ReExports/modules.d.ts +1 -1
  18. package/ReExports/modules.js +2 -2
  19. package/assemblyManager/assembly.js +5 -5
  20. package/assemblyManager/assemblyConfigSchema.js +2 -2
  21. package/configuration/configurationSchema.js +1 -1
  22. package/configuration/util.js +1 -1
  23. package/data_adapters/BaseAdapter.js +1 -1
  24. package/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
  25. package/data_adapters/dataAdapterCache.d.ts +3 -2
  26. package/data_adapters/dataAdapterCache.js +2 -3
  27. package/package.json +2 -2
  28. package/pluggableElementTypes/RpcMethodType.js +1 -1
  29. package/pluggableElementTypes/index.d.ts +11 -1
  30. package/pluggableElementTypes/index.js +23 -23
  31. package/pluggableElementTypes/models/BaseConnectionModelFactory.js +2 -2
  32. package/pluggableElementTypes/models/BaseTrackModel.js +8 -13
  33. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.d.ts +2 -2
  34. package/pluggableElementTypes/renderers/ComparativeServerSideRendererType.js +1 -3
  35. package/pluggableElementTypes/renderers/ServerSideRendererType.d.ts +1 -1
  36. package/pluggableElementTypes/renderers/index.d.ts +7 -9
  37. package/pluggableElementTypes/renderers/index.js +15 -15
  38. package/pluggableElementTypes/renderers/util/serializableFilterChain.js +1 -1
  39. package/rpc/BaseRpcDriver.js +7 -8
  40. package/rpc/WebWorkerRpcDriver.js +18 -12
  41. package/rpc/coreRpcMethods.d.ts +9 -11
  42. package/rpc/coreRpcMethods.js +17 -17
  43. package/rpc/methods/CoreGetFeatureDetails.js +1 -1
  44. package/rpc/methods/util.d.ts +2 -2
  45. package/rpc/methods/util.js +2 -2
  46. package/rpc/remoteAbortSignals.js +0 -1
  47. package/tsconfig.build.tsbuildinfo +1 -1
  48. package/ui/App.js +1 -1
  49. package/ui/AppLogo.js +1 -6
  50. package/ui/ColorPicker.js +1 -1
  51. package/ui/Dialog.js +1 -1
  52. package/ui/DrawerWidget.js +4 -4
  53. package/ui/EditableTypography.js +1 -1
  54. package/ui/FileSelector/FileSelector.d.ts +2 -2
  55. package/ui/FileSelector/FileSelector.js +24 -35
  56. package/ui/FileSelector/index.d.ts +1 -2
  57. package/ui/FileSelector/index.js +3 -2
  58. package/ui/LoadingEllipses.js +4 -4
  59. package/ui/Menu.js +45 -32
  60. package/ui/ResizeBar.js +6 -1
  61. package/ui/ResizeHandle.js +3 -6
  62. package/ui/ViewContainer.js +4 -6
  63. package/ui/theme.js +7 -7
  64. package/util/Base1DUtils.js +16 -14
  65. package/util/Base1DViewModel.d.ts +1 -1
  66. package/util/Base1DViewModel.js +9 -8
  67. package/util/aborting.js +1 -1
  68. package/util/analytics.js +1 -1
  69. package/util/blockTypes.js +10 -10
  70. package/util/color/index.d.ts +1 -2
  71. package/util/color/index.js +4 -3
  72. package/util/idMaker.js +5 -8
  73. package/util/index.d.ts +6 -7
  74. package/util/index.js +25 -48
  75. package/util/io/RemoteFileWithRangeCache.js +2 -2
  76. package/util/io/index.d.ts +1 -2
  77. package/util/io/index.js +6 -6
  78. package/util/jexl.js +3 -1
  79. package/util/layouts/GranularRectLayout.js +10 -4
  80. package/util/layouts/MultiLayout.js +1 -1
  81. package/util/layouts/SceneGraph.js +3 -7
  82. package/util/offscreenCanvasPonyfill.js +4 -3
  83. package/util/offscreenCanvasUtils.js +1 -0
  84. package/util/tracks.d.ts +1 -1
  85. package/util/tracks.js +0 -1
  86. package/util/types/index.d.ts +1 -1
  87. package/util/types/index.js +3 -3
  88. package/util/types/mst.js +3 -3
package/ui/App.js CHANGED
@@ -103,7 +103,7 @@ const App = (0, mobx_react_1.observer)(function (props) {
103
103
  react_1.default.createElement(material_1.AppBar, { className: classes.appBar, position: "static" },
104
104
  react_1.default.createElement(AppToolbar_1.default, { ...props }))),
105
105
  react_1.default.createElement("div", { className: classes.components },
106
- views.length ? (views.map(view => (react_1.default.createElement(ViewPanel_1.default, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher_1.default, { ...props })),
106
+ views.length > 0 ? (views.map(view => (react_1.default.createElement(ViewPanel_1.default, { key: `view-${view.id}`, view: view, session: session })))) : (react_1.default.createElement(ViewLauncher_1.default, { ...props })),
107
107
  react_1.default.createElement("div", { style: { height: 300 } }))),
108
108
  activeWidgets.size > 0 && minimized ? (react_1.default.createElement(material_1.Tooltip, { title: "Open drawer widget" },
109
109
  react_1.default.createElement(material_1.Fab, { className: drawerPosition === 'right' ? classes.fabRight : classes.fabLeft, color: "primary", "data-testid": "drawer-maximize", onClick: () => session.showWidgetDrawer() },
package/ui/AppLogo.js CHANGED
@@ -12,11 +12,6 @@ const Logo_1 = require("./Logo");
12
12
  const Logo = (0, mobx_react_1.observer)(function ({ session, }) {
13
13
  const { configuration } = session;
14
14
  const logoPath = (0, configuration_1.readConfObject)(configuration, 'logoPath');
15
- if (!(logoPath === null || logoPath === void 0 ? void 0 : logoPath.uri)) {
16
- return react_1.default.createElement(Logo_1.LogoFull, { variant: "white" });
17
- }
18
- else {
19
- return react_1.default.createElement("img", { src: logoPath.uri, alt: "Custom logo" });
20
- }
15
+ return (logoPath === null || logoPath === void 0 ? void 0 : logoPath.uri) ? (react_1.default.createElement("img", { src: logoPath.uri, alt: "Custom logo" })) : (react_1.default.createElement(Logo_1.LogoFull, { variant: "white" }));
21
16
  });
22
17
  exports.default = Logo;
package/ui/ColorPicker.js CHANGED
@@ -90,7 +90,7 @@ function ColorPicker({ onChange, color, }) {
90
90
  const pal = event.target.value;
91
91
  setVal(pal);
92
92
  } }, palettes.map(p => (react_1.default.createElement(material_1.MenuItem, { value: p, key: p }, p)))),
93
- react_1.default.createElement("div", { className: classes.swatches }, presetColors.map((presetColor, idx) => (react_1.default.createElement("button", { key: presetColor + '-' + idx, className: classes.swatch, style: { background: presetColor }, onClick: () => handleChange(presetColor) })))),
93
+ react_1.default.createElement("div", { className: classes.swatches }, presetColors.map((presetColor, idx) => (react_1.default.createElement("button", { key: `${presetColor}-${idx}`, className: classes.swatch, style: { background: presetColor }, onClick: () => handleChange(presetColor) })))),
94
94
  react_1.default.createElement(material_1.TextField, { helperText: 'Manually set color (hex, rgb, or css color name)', value: text, onChange: event => handleChange(event.target.value) }))));
95
95
  }
96
96
  exports.ColorPicker = ColorPicker;
package/ui/Dialog.js CHANGED
@@ -32,7 +32,7 @@ function JBrowseDialog(props) {
32
32
  react_1.default.createElement(material_1.DialogTitle, null,
33
33
  title,
34
34
  onClose ? (react_1.default.createElement(material_1.IconButton, { className: classes.closeButton, onClick: () => {
35
- // @ts-ignore
35
+ // @ts-expect-error
36
36
  onClose();
37
37
  } },
38
38
  react_1.default.createElement(Close_1.default, null))) : null),
@@ -77,13 +77,13 @@ const DrawerHeader = (0, mobx_react_1.observer)(({ session, setToolbarHeight, })
77
77
  return HeadingComponent ? (react_1.default.createElement(HeadingComponent, { model: widget })) : (react_1.default.createElement(material_1.Typography, { variant: "h6", color: "inherit" }, heading));
78
78
  }, onChange: e => {
79
79
  const w = session.activeWidgets.get(e.target.value);
80
- if (!w) {
81
- session.notify(`Widget not found ${e.target.value}`, 'warning');
80
+ if (w) {
81
+ session.showWidget(w);
82
82
  }
83
83
  else {
84
- session.showWidget(w);
84
+ session.notify(`Widget not found ${e.target.value}`, 'warning');
85
85
  }
86
- } }, Array.from(activeWidgets.values()).map(widget => {
86
+ } }, [...activeWidgets.values()].map(widget => {
87
87
  const widgetType = pluginManager.getWidgetType(widget.type);
88
88
  const { HeadingComponent, heading } = widgetType;
89
89
  return (react_1.default.createElement(material_1.MenuItem, { "data-testid": `widget-drawer-selects-item-${widget.type}`, key: widget.id, value: widget.id },
@@ -59,7 +59,7 @@ const EditableTypography = react_1.default.forwardRef((props, ref) => {
59
59
  }, [blur, inputNode]);
60
60
  // possibly tss-react does not understand the passing of props to
61
61
  // useStyles, but it appears to work
62
- // @ts-ignore
62
+ // @ts-expect-error
63
63
  const { classes } = useStyles(props, { props });
64
64
  const theme = (0, material_1.useTheme)();
65
65
  const clientWidth = sizerNode === null || sizerNode === void 0 ? void 0 : sizerNode.clientWidth;
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { FileLocation, AbstractRootModel } from '../../util/types';
3
- declare const FileSelector: (props: {
3
+ declare const _default: (props: {
4
4
  location?: FileLocation | undefined;
5
5
  setLocation: (param: FileLocation) => void;
6
6
  setName?: ((str: string) => void) | undefined;
@@ -8,4 +8,4 @@ declare const FileSelector: (props: {
8
8
  description?: string | undefined;
9
9
  rootModel?: AbstractRootModel | undefined;
10
10
  }) => JSX.Element;
11
- export default FileSelector;
11
+ export default _default;
@@ -42,46 +42,45 @@ function ToggleButtonWithTooltip(props) {
42
42
  }
43
43
  function shorten(str, len) {
44
44
  if (typeof str === 'string' && str.length > len) {
45
- return `${str.substring(0, len)}…`;
45
+ return `${str.slice(0, Math.max(0, len))}…`;
46
46
  }
47
47
  return str;
48
48
  }
49
- const FileSelector = (0, mobx_react_1.observer)((props) => {
49
+ exports.default = (0, mobx_react_1.observer)(function (props) {
50
50
  const { location, name, description, rootModel, setLocation } = props;
51
51
  const fileOrUrl = !location || (0, types_1.isUriLocation)(location) ? 'url' : 'file';
52
52
  const [toggleButtonValue, setToggleButtonValue] = (0, react_1.useState)(location && 'internetAccountId' in location && location.internetAccountId
53
53
  ? location.internetAccountId
54
54
  : fileOrUrl);
55
- const accts = (0, types_1.isAppRootModel)(rootModel)
56
- ? rootModel.internetAccounts.slice()
57
- : [];
55
+ const accts = (0, types_1.isAppRootModel)(rootModel) ? [...rootModel.internetAccounts] : [];
58
56
  const numShown = 2;
59
57
  const [shownAccts, setShownAccts] = (0, react_1.useState)(accts.slice(0, numShown));
60
58
  const [hiddenAccts, setHiddenAccts] = (0, react_1.useState)(accts.slice(numShown));
61
59
  const [anchorEl, setAnchorEl] = (0, react_1.useState)(null);
62
- const selectedAcct = accts.find(ia => ia.internetAccountId === toggleButtonValue);
63
- const setLocationWithAccount = (location) => {
60
+ const selectedAcct = accts.find(i => i.internetAccountId === toggleButtonValue);
61
+ const setLocationWithAcct = (0, react_1.useCallback)((location) => {
64
62
  setLocation({
65
63
  ...location,
66
- internetAccountId: selectedAcct
67
- ? selectedAcct.internetAccountId
68
- : undefined,
64
+ ...((0, types_1.isUriLocation)(location)
65
+ ? { internetAccountId: selectedAcct === null || selectedAcct === void 0 ? void 0 : selectedAcct.internetAccountId }
66
+ : {}),
69
67
  });
70
- };
71
- // if you swap account selection after inputting url
72
- if (location &&
73
- selectedAcct &&
74
- (0, types_1.isUriLocation)(location) &&
75
- location.internetAccountId !== selectedAcct.internetAccountId) {
76
- setLocationWithAccount(location);
77
- }
78
- let locationInput = (react_1.default.createElement(UrlChooser_1.default, { ...props, setLocation: setLocationWithAccount, label: selectedAcct === null || selectedAcct === void 0 ? void 0 : selectedAcct.selectorLabel }));
68
+ }, [setLocation, selectedAcct]);
69
+ (0, react_1.useEffect)(() => {
70
+ // if you swap account selection after inputting url
71
+ if (selectedAcct &&
72
+ (0, types_1.isUriLocation)(location) &&
73
+ location.internetAccountId !== selectedAcct.internetAccountId) {
74
+ setLocationWithAcct(location);
75
+ }
76
+ }, [location, selectedAcct, setLocationWithAcct]);
77
+ let locationInput = (react_1.default.createElement(UrlChooser_1.default, { ...props, setLocation: setLocationWithAcct, label: selectedAcct === null || selectedAcct === void 0 ? void 0 : selectedAcct.selectorLabel }));
79
78
  if (toggleButtonValue === 'file') {
80
79
  locationInput = react_1.default.createElement(LocalFileChooser_1.default, { ...props });
81
80
  }
82
81
  if (selectedAcct === null || selectedAcct === void 0 ? void 0 : selectedAcct.SelectorComponent) {
83
82
  const { SelectorComponent } = selectedAcct;
84
- locationInput = (react_1.default.createElement(SelectorComponent, { ...props, setLocation: setLocationWithAccount }));
83
+ locationInput = (react_1.default.createElement(SelectorComponent, { ...props, setLocation: setLocationWithAcct }));
85
84
  }
86
85
  return (react_1.default.createElement(react_1.default.Fragment, null,
87
86
  react_1.default.createElement(material_1.Box, { display: "flex" },
@@ -93,7 +92,7 @@ const FileSelector = (0, mobx_react_1.observer)((props) => {
93
92
  setToggleButtonValue(newState);
94
93
  }
95
94
  if ((0, types_1.isUriLocation)(location)) {
96
- setLocationWithAccount(location);
95
+ setLocationWithAcct(location);
97
96
  }
98
97
  }, "aria-label": "file, url, or account picker" },
99
98
  new URLSearchParams(window.location.search).get('adminKey') ? null : (react_1.default.createElement(material_1.ToggleButton, { value: "file", "aria-label": "local file" }, "File")),
@@ -101,23 +100,14 @@ const FileSelector = (0, mobx_react_1.observer)((props) => {
101
100
  shownAccts.map(({ internetAccountId, toggleContents, name }) => (react_1.default.createElement(ToggleButtonWithTooltip, { key: internetAccountId, value: internetAccountId, "aria-label": name, title: name }, typeof toggleContents === 'string'
102
101
  ? shorten(toggleContents, 5)
103
102
  : toggleContents || shorten(name, 5)))),
104
- hiddenAccts.length ? (
105
- // @ts-ignore
103
+ hiddenAccts.length > 0 ? (
104
+ // @ts-expect-error
106
105
  react_1.default.createElement(material_1.ToggleButton, { onClick: event => setAnchorEl(event.target), selected: false },
107
106
  "More",
108
107
  react_1.default.createElement(ArrowDropDown_1.default, null))) : null),
109
- react_1.default.createElement(material_1.Menu, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: () => setAnchorEl(null), anchorOrigin: {
110
- vertical: 'bottom',
111
- horizontal: 'center',
112
- }, transformOrigin: {
113
- vertical: 'top',
114
- horizontal: 'center',
115
- } }, hiddenAccts === null || hiddenAccts === void 0 ? void 0 : hiddenAccts.map((acct, idx) => (react_1.default.createElement(material_1.MenuItem, { key: acct.internetAccountId, value: acct.internetAccountId, onClick: () => {
108
+ react_1.default.createElement(material_1.Menu, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: () => setAnchorEl(null), anchorOrigin: { vertical: 'bottom', horizontal: 'center' }, transformOrigin: { vertical: 'top', horizontal: 'center' } }, hiddenAccts === null || hiddenAccts === void 0 ? void 0 : hiddenAccts.map((acct, idx) => (react_1.default.createElement(material_1.MenuItem, { key: acct.internetAccountId, value: acct.internetAccountId, onClick: () => {
116
109
  const prev = shownAccts[shownAccts.length - 1];
117
- setShownAccts([
118
- ...shownAccts.slice(0, shownAccts.length - 1),
119
- acct,
120
- ]);
110
+ setShownAccts([...shownAccts.slice(0, -1), acct]);
121
111
  setHiddenAccts([
122
112
  prev,
123
113
  ...hiddenAccts.slice(0, idx),
@@ -129,4 +119,3 @@ const FileSelector = (0, mobx_react_1.observer)((props) => {
129
119
  locationInput,
130
120
  react_1.default.createElement(material_1.FormHelperText, null, description)));
131
121
  });
132
- exports.default = FileSelector;
@@ -1,2 +1 @@
1
- import FileSelector from './FileSelector';
2
- export default FileSelector;
1
+ export { default } from './FileSelector';
@@ -3,5 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- const FileSelector_1 = __importDefault(require("./FileSelector"));
7
- exports.default = FileSelector_1.default;
6
+ exports.default = void 0;
7
+ var FileSelector_1 = require("./FileSelector");
8
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(FileSelector_1).default; } });
@@ -16,16 +16,16 @@ const useStyles = (0, mui_1.makeStyles)()({
16
16
  textAlign: 'left',
17
17
  animation: `${(0, tss_react_1.keyframes) `
18
18
  0% {
19
- content: '...';
19
+ content: '';
20
20
  }
21
21
  25% {
22
- content: '';
22
+ content: '.';
23
23
  }
24
24
  50% {
25
- content: '.';
25
+ content: '..';
26
26
  }
27
27
  75% {
28
- content: '..';
28
+ content: '...';
29
29
  }
30
30
  `} 1.2s infinite ease-in-out`,
31
31
  },
package/ui/Menu.js CHANGED
@@ -69,26 +69,32 @@ function MenuItemEndDecoration(props) {
69
69
  ({ checked, disabled } = props);
70
70
  }
71
71
  let icon;
72
- if (type === 'subMenu') {
73
- icon = react_1.default.createElement(ArrowRight_1.default, { color: "action" });
74
- }
75
- else if (type === 'checkbox') {
76
- if (checked) {
77
- const color = disabled ? 'inherit' : undefined;
78
- icon = react_1.default.createElement(CheckBox_1.default, { color: color });
79
- }
80
- else {
81
- icon = react_1.default.createElement(CheckBoxOutlineBlank_1.default, { color: "action" });
72
+ switch (type) {
73
+ case 'subMenu': {
74
+ icon = react_1.default.createElement(ArrowRight_1.default, { color: "action" });
75
+ break;
82
76
  }
83
- }
84
- else if (type === 'radio') {
85
- if (checked) {
86
- const color = disabled ? 'inherit' : undefined;
87
- icon = react_1.default.createElement(RadioButtonChecked_1.default, { color: color });
77
+ case 'checkbox': {
78
+ if (checked) {
79
+ const color = disabled ? 'inherit' : undefined;
80
+ icon = react_1.default.createElement(CheckBox_1.default, { color: color });
81
+ }
82
+ else {
83
+ icon = react_1.default.createElement(CheckBoxOutlineBlank_1.default, { color: "action" });
84
+ }
85
+ break;
88
86
  }
89
- else {
90
- icon = react_1.default.createElement(RadioButtonUnchecked_1.default, { color: "action" });
87
+ case 'radio': {
88
+ if (checked) {
89
+ const color = disabled ? 'inherit' : undefined;
90
+ icon = react_1.default.createElement(RadioButtonChecked_1.default, { color: color });
91
+ }
92
+ else {
93
+ icon = react_1.default.createElement(RadioButtonUnchecked_1.default, { color: "action" });
94
+ }
95
+ break;
91
96
  }
97
+ // No default
92
98
  }
93
99
  return react_1.default.createElement("div", { className: classes.menuItemEndDecoration }, icon);
94
100
  }
@@ -208,21 +214,28 @@ const MenuPage = react_1.default.forwardRef((props, ref) => {
208
214
  setOpenSubMenuIdx(undefined);
209
215
  }
210
216
  }, onKeyDown: e => {
211
- if (e.key === 'ArrowLeft' || e.key === 'Escape') {
212
- onClose && onClose(e, 'escapeKeyDown');
213
- }
214
- else if (e.key === 'ArrowUp') {
215
- setSelectedMenuItemIdx(findPreviousValidIdx(menuItems, idx));
216
- }
217
- else if (e.key === 'ArrowDown') {
218
- const a = findNextValidIdx(menuItems, idx);
219
- setSelectedMenuItemIdx(a);
220
- }
221
- else if ('subMenu' in menuItem) {
222
- if (e.key === 'ArrowRight' || e.key === 'Enter') {
223
- setSubMenuAnchorEl(e.currentTarget);
224
- setOpenSubMenuIdx(idx);
225
- setIsSubMenuOpen(true);
217
+ switch (e.key) {
218
+ case 'ArrowLeft':
219
+ case 'Escape': {
220
+ onClose && onClose(e, 'escapeKeyDown');
221
+ break;
222
+ }
223
+ case 'ArrowUp': {
224
+ setSelectedMenuItemIdx(findPreviousValidIdx(menuItems, idx));
225
+ break;
226
+ }
227
+ case 'ArrowDown': {
228
+ const a = findNextValidIdx(menuItems, idx);
229
+ setSelectedMenuItemIdx(a);
230
+ break;
231
+ }
232
+ default: {
233
+ if ('subMenu' in menuItem &&
234
+ (e.key === 'ArrowRight' || e.key === 'Enter')) {
235
+ setSubMenuAnchorEl(e.currentTarget);
236
+ setOpenSubMenuIdx(idx);
237
+ setIsSubMenuOpen(true);
238
+ }
226
239
  }
227
240
  }
228
241
  }, disabled: Boolean(menuItem.disabled) },
package/ui/ResizeBar.js CHANGED
@@ -82,7 +82,12 @@ function Tick({ left, scrollLeft, idx, onDrag, }) {
82
82
  function ResizeBar({ widths, setWidths, checkbox, scrollLeft = 0, }) {
83
83
  const { classes } = useStyles();
84
84
  const offsets = [];
85
- widths.reduce((a, b, i) => (offsets[i] = a + b), checkbox ? 52 : 0);
85
+ let init = checkbox ? 52 : 0;
86
+ for (let i = 0; i < widths.length; i++) {
87
+ const width = widths[i];
88
+ offsets[i] = width + init;
89
+ init += width;
90
+ }
86
91
  const onDrag = (0, react_1.useCallback)((distance, idx) => {
87
92
  const newWidths = [...widths];
88
93
  // mui doesn't allow columns smaller than 50
@@ -72,12 +72,9 @@ function ResizeHandle({ onDrag, vertical = false, flexbox = false, className: or
72
72
  }, [mouseDragging, onDrag, vertical]);
73
73
  let className;
74
74
  if (flexbox) {
75
- if (vertical) {
76
- className = classes.flexbox_verticalHandle;
77
- }
78
- else {
79
- className = classes.flexbox_horizontalHandle;
80
- }
75
+ className = vertical
76
+ ? classes.flexbox_verticalHandle
77
+ : classes.flexbox_horizontalHandle;
81
78
  }
82
79
  else if (vertical) {
83
80
  className = classes.verticalHandle;
@@ -75,7 +75,7 @@ const ViewContainer = (0, mobx_react_1.observer)(function ({ view, onClose, onMi
75
75
  const [ref, { width }] = (0, react_use_measure_1.default)();
76
76
  (0, react_1.useEffect)(() => {
77
77
  if (width && (0, mobx_state_tree_1.isAlive)(view)) {
78
- view.setWidth(width - parseInt(padWidth, 10) * 2);
78
+ view.setWidth(width - Number.parseInt(padWidth, 10) * 2);
79
79
  }
80
80
  }, [padWidth, view, width]);
81
81
  const scrollRef = (0, react_1.useRef)(null);
@@ -91,11 +91,9 @@ const ViewContainer = (0, mobx_react_1.observer)(function ({ view, onClose, onMi
91
91
  react_1.default.createElement(ViewMenu_1.default, { model: view, IconProps: { className: classes.icon } }),
92
92
  react_1.default.createElement("div", { className: classes.grow }),
93
93
  react_1.default.createElement(material_1.Tooltip, { title: "Rename view", arrow: true },
94
- react_1.default.createElement(EditableTypography_1.default, { value: (view.displayName ||
95
- (
96
- // @ts-ignore
97
- (_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) ||
98
- 'Untitled view') + (view.minimized ? ' (minimized)' : ''), setValue: val => view.setDisplayName(val), variant: "body2", classes: {
94
+ react_1.default.createElement(EditableTypography_1.default, { value: view.displayName ||
95
+ // @ts-expect-error
96
+ `${((_a = view.assemblyNames) === null || _a === void 0 ? void 0 : _a.join(',')) || 'Untitled view'}${view.minimized ? ' (minimized)' : ''}`, setValue: val => view.setDisplayName(val), variant: "body2", classes: {
99
97
  input: classes.input,
100
98
  inputBase: classes.inputBase,
101
99
  inputRoot: classes.inputRoot,
package/ui/theme.js CHANGED
@@ -25,7 +25,7 @@ function stockTheme() {
25
25
  bases: {
26
26
  A: refTheme.palette.augmentColor({ color: colors_1.green }),
27
27
  C: refTheme.palette.augmentColor({ color: colors_1.blue }),
28
- G: refTheme.palette.augmentColor({ color: colors_1.amber }),
28
+ G: refTheme.palette.augmentColor({ color: colors_1.orange }),
29
29
  T: refTheme.palette.augmentColor({ color: colors_1.red }),
30
30
  },
31
31
  },
@@ -70,7 +70,7 @@ function getDarkStockTheme() {
70
70
  bases: {
71
71
  A: refTheme.palette.augmentColor({ color: colors_1.green }),
72
72
  C: refTheme.palette.augmentColor({ color: colors_1.blue }),
73
- G: refTheme.palette.augmentColor({ color: colors_1.amber }),
73
+ G: refTheme.palette.augmentColor({ color: colors_1.orange }),
74
74
  T: refTheme.palette.augmentColor({ color: colors_1.red }),
75
75
  },
76
76
  },
@@ -103,7 +103,7 @@ function getDarkMinimalTheme() {
103
103
  bases: {
104
104
  A: refTheme.palette.augmentColor({ color: colors_1.green }),
105
105
  C: refTheme.palette.augmentColor({ color: colors_1.blue }),
106
- G: refTheme.palette.augmentColor({ color: colors_1.amber }),
106
+ G: refTheme.palette.augmentColor({ color: colors_1.orange }),
107
107
  T: refTheme.palette.augmentColor({ color: colors_1.red }),
108
108
  },
109
109
  },
@@ -122,7 +122,7 @@ function getMinimalTheme() {
122
122
  bases: {
123
123
  A: refTheme.palette.augmentColor({ color: colors_1.green }),
124
124
  C: refTheme.palette.augmentColor({ color: colors_1.blue }),
125
- G: refTheme.palette.augmentColor({ color: colors_1.amber }),
125
+ G: refTheme.palette.augmentColor({ color: colors_1.orange }),
126
126
  T: refTheme.palette.augmentColor({ color: colors_1.red }),
127
127
  },
128
128
  },
@@ -226,7 +226,7 @@ function createDefaultProps(theme) {
226
226
  },
227
227
  styleOverrides: {
228
228
  secondary: {
229
- // @ts-ignore
229
+ // @ts-expect-error
230
230
  backgroundColor: (_b = (_a = theme === null || theme === void 0 ? void 0 : theme.palette) === null || _a === void 0 ? void 0 : _a.quaternary) === null || _b === void 0 ? void 0 : _b.main,
231
231
  },
232
232
  },
@@ -348,11 +348,11 @@ function createDefaultProps(theme) {
348
348
  MuiAccordionSummary: {
349
349
  styleOverrides: {
350
350
  root: {
351
- // @ts-ignore
351
+ // @ts-expect-error
352
352
  backgroundColor: (_d = (_c = theme === null || theme === void 0 ? void 0 : theme.palette) === null || _c === void 0 ? void 0 : _c.tertiary) === null || _d === void 0 ? void 0 : _d.main,
353
353
  },
354
354
  content: {
355
- // @ts-ignore
355
+ // @ts-expect-error
356
356
  color: (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.palette) === null || _e === void 0 ? void 0 : _e.tertiary) === null || _f === void 0 ? void 0 : _f.contrastText,
357
357
  },
358
358
  },
@@ -70,7 +70,7 @@ function pxToBp(self, px) {
70
70
  if (bp < 0) {
71
71
  const r = displayedRegions[0];
72
72
  const snap = (0, mobx_state_tree_1.getSnapshot)(r);
73
- // @ts-ignore
73
+ // @ts-expect-error
74
74
  return {
75
75
  // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
76
76
  ...snap,
@@ -88,7 +88,7 @@ function pxToBp(self, px) {
88
88
  const offset = bp - bpSoFar;
89
89
  if (len + bpSoFar > bp && bpSoFar <= bp) {
90
90
  const snap = (0, mobx_state_tree_1.getSnapshot)(r);
91
- // @ts-ignore
91
+ // @ts-expect-error
92
92
  return {
93
93
  // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
94
94
  ...snap,
@@ -108,12 +108,12 @@ function pxToBp(self, px) {
108
108
  bpSoFar += len;
109
109
  }
110
110
  }
111
- if (bp >= bpSoFar && displayedRegions.length) {
111
+ if (bp >= bpSoFar && displayedRegions.length > 0) {
112
112
  const r = displayedRegions[displayedRegions.length - 1];
113
113
  const len = r.end - r.start;
114
114
  const offset = bp - bpSoFar + len;
115
115
  const snap = (0, mobx_state_tree_1.getSnapshot)(r);
116
- // @ts-ignore
116
+ // @ts-expect-error
117
117
  return {
118
118
  // xref https://github.com/mobxjs/mobx-state-tree/issues/1524 for Omit
119
119
  ...snap,
@@ -147,11 +147,12 @@ function bpToPx({ refName, coord, regionNumber, self, }) {
147
147
  for (; i < displayedRegions.length; i++) {
148
148
  const r = displayedRegions[i];
149
149
  const len = r.end - r.start;
150
- if (refName === r.refName && coord >= r.start && coord <= r.end) {
151
- if (regionNumber ? regionNumber === i : true) {
152
- bpSoFar += r.reversed ? r.end - coord : coord - r.start;
153
- break;
154
- }
150
+ if (refName === r.refName &&
151
+ coord >= r.start &&
152
+ coord <= r.end &&
153
+ (regionNumber ? regionNumber === i : true)) {
154
+ bpSoFar += r.reversed ? r.end - coord : coord - r.start;
155
+ break;
155
156
  }
156
157
  // add the interRegionPaddingWidth if the boundary is in the screen e.g. in
157
158
  // a static block
@@ -185,11 +186,12 @@ function bpToPxMap({ refName, coord, regionNumber, self, }) {
185
186
  for (; i < displayedRegions.length; i++) {
186
187
  const r = displayedRegions[i];
187
188
  const len = r.end - r.start;
188
- if (refName === r.refName && coord >= r.start && coord <= r.end) {
189
- if (regionNumber !== undefined ? regionNumber === i : true) {
190
- bpSoFar += r.reversed ? r.end - coord : coord - r.start;
191
- break;
192
- }
189
+ if (refName === r.refName &&
190
+ coord >= r.start &&
191
+ coord <= r.end &&
192
+ (regionNumber === undefined ? true : regionNumber === i)) {
193
+ bpSoFar += r.reversed ? r.end - coord : coord - r.start;
194
+ break;
193
195
  }
194
196
  // add the interRegionPaddingWidth if the boundary is in the screen e.g. in
195
197
  // a static block
@@ -119,7 +119,7 @@ declare const Base1DView: import("mobx-state-tree").IModelType<{
119
119
  /**
120
120
  * #action
121
121
  */
122
- zoomTo(newBpPerPx: number, offset?: number): number;
122
+ zoomTo(bpPerPx: number, offset?: number): number;
123
123
  /**
124
124
  * #action
125
125
  */
@@ -180,15 +180,16 @@ const Base1DView = mobx_state_tree_1.types
180
180
  /**
181
181
  * #action
182
182
  */
183
- zoomTo(newBpPerPx, offset = self.width / 2) {
184
- const bpPerPx = newBpPerPx;
185
- if (bpPerPx === self.bpPerPx) {
186
- return self.bpPerPx;
187
- }
183
+ zoomTo(bpPerPx, offset = self.width / 2) {
184
+ const newBpPerPx = (0, index_1.clamp)(bpPerPx, 'minBpPerPx' in self ? self.minBpPerPx : 0, 'maxBpPerPx' in self ? self.maxBpPerPx : Infinity);
188
185
  const oldBpPerPx = self.bpPerPx;
189
- self.bpPerPx = bpPerPx;
190
- // tweak the offset so that the center of the view remains at the same coordinate
191
- self.offsetPx = (0, index_1.clamp)(Math.round(((self.offsetPx + offset) * oldBpPerPx) / bpPerPx - offset), self.minOffset, self.maxOffset);
186
+ if (Math.abs(oldBpPerPx - newBpPerPx) < 0.000001) {
187
+ return oldBpPerPx;
188
+ }
189
+ self.bpPerPx = newBpPerPx;
190
+ // tweak the offset so that the center of the view remains at the same
191
+ // coordinate
192
+ self.offsetPx = (0, index_1.clamp)(Math.round(((self.offsetPx + offset) * oldBpPerPx) / newBpPerPx - offset), self.minOffset, self.maxOffset);
192
193
  return self.bpPerPx;
193
194
  },
194
195
  /**
package/util/aborting.js CHANGED
@@ -75,6 +75,6 @@ function isAbortException(exception) {
75
75
  // Error: aborted
76
76
  // AbortError: aborted
77
77
  // AbortError: The user aborted a request.
78
- !!exception.message.match(/\b(aborted|AbortError)\b/i)));
78
+ !!/\b(aborted|aborterror)\b/i.test(exception.message)));
79
79
  }
80
80
  exports.isAbortException = isAbortException;
package/util/analytics.js CHANGED
@@ -83,7 +83,7 @@ async function writeGAAnalytics(rootModel, initialTimestamp) {
83
83
  analyticsScript += `ga('jbrowseTracker.send', 'pageview',${JSON.stringify(gaData)});`;
84
84
  const analyticsScriptNode = document.createElement('script');
85
85
  analyticsScriptNode.innerHTML = analyticsScript;
86
- document.getElementsByTagName('head')[0].appendChild(analyticsScriptNode);
86
+ document.getElementsByTagName('head')[0].append(analyticsScriptNode);
87
87
  }
88
88
  exports.writeGAAnalytics = writeGAAnalytics;
89
89
  function doAnalytics(rootModel, initialTimestamp, initialSessionQuery) {
@@ -6,13 +6,11 @@ class BlockSet {
6
6
  this.blocks = blocks;
7
7
  }
8
8
  push(block) {
9
- if (block instanceof ElidedBlock) {
10
- if (this.blocks.length) {
11
- const lastBlock = this.blocks[this.blocks.length - 1];
12
- if (lastBlock instanceof ElidedBlock) {
13
- lastBlock.push(block);
14
- return;
15
- }
9
+ if (block instanceof ElidedBlock && this.blocks.length > 0) {
10
+ const lastBlock = this.blocks[this.blocks.length - 1];
11
+ if (lastBlock instanceof ElidedBlock) {
12
+ lastBlock.push(block);
13
+ return;
16
14
  }
17
15
  }
18
16
  this.blocks.push(block);
@@ -24,21 +22,23 @@ class BlockSet {
24
22
  return this.blocks.map(block => block.toRegion());
25
23
  }
26
24
  map(func, thisarg) {
25
+ // eslint-disable-next-line unicorn/no-array-method-this-argument
27
26
  return this.blocks.map(func, thisarg);
28
27
  }
29
28
  forEach(func, thisarg) {
29
+ // eslint-disable-next-line unicorn/no-array-method-this-argument
30
30
  return this.blocks.forEach(func, thisarg);
31
31
  }
32
32
  get length() {
33
33
  return this.blocks.length;
34
34
  }
35
35
  get totalWidthPx() {
36
- return this.blocks.length
36
+ return this.blocks.length > 0
37
37
  ? this.blocks.map(blocks => blocks.widthPx).reduce((a, b) => a + b)
38
38
  : 0;
39
39
  }
40
40
  get totalWidthPxWithoutBorders() {
41
- return this.blocks.length
41
+ return this.blocks.length > 0
42
42
  ? this.blocks
43
43
  .filter(block => block.variant !== 'boundary')
44
44
  .map(blocks => blocks.widthPx)
@@ -46,7 +46,7 @@ class BlockSet {
46
46
  : 0;
47
47
  }
48
48
  get offsetPx() {
49
- return this.blocks.length ? this.blocks[0].offsetPx : 0;
49
+ return this.blocks.length > 0 ? this.blocks[0].offsetPx : 0;
50
50
  }
51
51
  get contentBlocks() {
52
52
  return this.blocks.filter(block => block instanceof ContentBlock);