@jbrowse/core 2.11.1 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.js +17 -26
- package/BaseFeatureWidget/BaseFeatureDetail/index.js +1 -3
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.js +24 -85
- package/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.js +2 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.d.ts +3 -4
- package/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.js +55 -24
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.d.ts +9 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.js +69 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceFeatureMenu.d.ts +9 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceFeatureMenu.js +126 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.d.ts +6 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.js +68 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SettingsDialog.js +19 -10
- package/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +47 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/model.js +83 -9
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDNASequence.d.ts +3 -1
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDNASequence.js +76 -19
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDSSequence.d.ts +5 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDSSequence.js +12 -3
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/GenomicSequence.d.ts +7 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/GenomicSequence.js +51 -5
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/ProteinSequence.d.ts +5 -2
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/ProteinSequence.js +12 -3
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/SequenceDisplay.d.ts +11 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/SequenceDisplay.js +30 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/util.d.ts +11 -0
- package/BaseFeatureWidget/SequenceFeatureDetails/util.js +43 -1
- package/BaseFeatureWidget/stateModelFactory.d.ts +32 -2
- package/PluginManager.d.ts +2 -11
- package/ReExports/modules.d.ts +2 -11
- package/configuration/util.js +4 -11
- package/package.json +5 -3
- package/pluggableElementTypes/models/BaseDisplayModel.d.ts +3 -3
- package/pluggableElementTypes/models/BaseDisplayModel.js +3 -3
- package/pluggableElementTypes/renderers/util/serializableFilterChain.js +4 -1
- package/rpc/methods/util.d.ts +3 -2
- package/rpc/methods/util.js +0 -7
- package/stories/JBrowseCore.stories.d.ts +5 -0
- package/stories/JBrowseCore.stories.js +10 -0
- package/stories/examples/WithSequencePanel.d.ts +7 -0
- package/stories/examples/WithSequencePanel.js +43 -0
- package/stories/examples/index.d.ts +1 -0
- package/stories/examples/index.js +17 -0
- package/stories/examples/util.d.ts +33 -0
- package/stories/examples/util.js +235 -0
- package/tsconfig.build.tsbuildinfo +1 -1
- package/ui/Dialog.js +2 -1
- package/ui/ErrorMessageStackTraceDialog.js +13 -8
- package/util/Base1DUtils.d.ts +1 -1
- package/util/Base1DUtils.js +3 -7
- package/util/Base1DViewModel.d.ts +5 -16
- package/util/Base1DViewModel.js +6 -12
- package/util/blockTypes.d.ts +4 -0
- package/util/blockTypes.js +14 -3
- package/util/calculateDynamicBlocks.js +2 -3
- package/util/index.d.ts +1 -1
- package/util/range.d.ts +1 -1
- package/util/tracks.d.ts +3 -2
- package/util/tracks.js +10 -6
- package/util/types/index.d.ts +4 -1
- package/ui/ResizeBar.d.ts +0 -7
- package/ui/ResizeBar.js +0 -80
- package/ui/useResizeBar.d.ts +0 -5
- package/ui/useResizeBar.js +0 -22
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const material_1 = require("@mui/material");
|
|
8
|
+
const mobx_react_1 = require("mobx-react");
|
|
9
|
+
const mui_1 = require("tss-react/mui");
|
|
10
|
+
const useStyles = (0, mui_1.makeStyles)()({
|
|
11
|
+
formControl: {
|
|
12
|
+
margin: 0,
|
|
13
|
+
marginLeft: 4,
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
const SequenceTypeSelector = (0, mobx_react_1.observer)(function ({ model, }) {
|
|
17
|
+
const { classes } = useStyles();
|
|
18
|
+
const { intronBp, upDownBp, mode, hasCDS, hasExonOrCDS } = model;
|
|
19
|
+
return (react_1.default.createElement(material_1.FormControl, { className: classes.formControl },
|
|
20
|
+
react_1.default.createElement(material_1.Select, { size: "small", value: mode, onChange: event => model.setMode(event.target.value) }, Object.entries({
|
|
21
|
+
...(hasCDS
|
|
22
|
+
? {
|
|
23
|
+
cds: 'CDS',
|
|
24
|
+
}
|
|
25
|
+
: {}),
|
|
26
|
+
...(hasCDS
|
|
27
|
+
? {
|
|
28
|
+
protein: 'Protein',
|
|
29
|
+
}
|
|
30
|
+
: {}),
|
|
31
|
+
...(hasExonOrCDS
|
|
32
|
+
? {
|
|
33
|
+
cdna: 'cDNA',
|
|
34
|
+
}
|
|
35
|
+
: {}),
|
|
36
|
+
...(hasExonOrCDS
|
|
37
|
+
? {
|
|
38
|
+
gene: `Genomic w/ full introns`,
|
|
39
|
+
}
|
|
40
|
+
: {}),
|
|
41
|
+
...(hasExonOrCDS
|
|
42
|
+
? {
|
|
43
|
+
gene_updownstream: `Genomic w/ full introns +/- ${upDownBp}bp up+down stream`,
|
|
44
|
+
}
|
|
45
|
+
: {}),
|
|
46
|
+
...(hasExonOrCDS
|
|
47
|
+
? {
|
|
48
|
+
gene_collapsed_intron: `Genomic w/ ${intronBp}bp intron`,
|
|
49
|
+
}
|
|
50
|
+
: {}),
|
|
51
|
+
...(hasExonOrCDS
|
|
52
|
+
? {
|
|
53
|
+
gene_updownstream_collapsed_intron: `Genomic w/ ${intronBp}bp intron +/- ${upDownBp}bp up+down stream `,
|
|
54
|
+
}
|
|
55
|
+
: {}),
|
|
56
|
+
...(!hasExonOrCDS
|
|
57
|
+
? {
|
|
58
|
+
genomic: 'Genomic',
|
|
59
|
+
}
|
|
60
|
+
: {}),
|
|
61
|
+
...(!hasExonOrCDS
|
|
62
|
+
? {
|
|
63
|
+
genomic_sequence_updownstream: `Genomic +/- ${upDownBp}bp up+down stream`,
|
|
64
|
+
}
|
|
65
|
+
: {}),
|
|
66
|
+
}).map(([key, val]) => (react_1.default.createElement(material_1.MenuItem, { key: key, value: key }, val))))));
|
|
67
|
+
});
|
|
68
|
+
exports.default = SequenceTypeSelector;
|
|
@@ -36,25 +36,34 @@ const useStyles = (0, mui_1.makeStyles)()(theme => ({
|
|
|
36
36
|
dialogContent: {
|
|
37
37
|
width: '80em',
|
|
38
38
|
},
|
|
39
|
+
root: {
|
|
40
|
+
padding: 4,
|
|
41
|
+
},
|
|
39
42
|
}));
|
|
43
|
+
function TextField2(props) {
|
|
44
|
+
return (react_1.default.createElement("div", null,
|
|
45
|
+
react_1.default.createElement(material_1.TextField, { ...props })));
|
|
46
|
+
}
|
|
47
|
+
function FormControl2({ children }) {
|
|
48
|
+
return (react_1.default.createElement("div", null,
|
|
49
|
+
react_1.default.createElement(material_1.FormControl, null, children)));
|
|
50
|
+
}
|
|
40
51
|
const SequenceFeatureSettingsDialog = (0, mobx_react_1.observer)(function ({ handleClose, model, }) {
|
|
41
52
|
const { classes } = useStyles();
|
|
53
|
+
const { upperCaseCDS } = model;
|
|
42
54
|
const [intronBp, setIntronBp] = (0, react_1.useState)(`${model.intronBp}`);
|
|
43
55
|
const [upDownBp, setUpDownBp] = (0, react_1.useState)(`${model.upDownBp}`);
|
|
44
56
|
const intronBpValid = !Number.isNaN(+intronBp);
|
|
45
57
|
const upDownBpValid = !Number.isNaN(+upDownBp);
|
|
46
58
|
return (react_1.default.createElement(ui_1.Dialog, { maxWidth: "xl", open: true, onClose: () => handleClose(), title: "Feature sequence settings" },
|
|
47
59
|
react_1.default.createElement(material_1.DialogContent, { className: classes.dialogContent },
|
|
48
|
-
react_1.default.createElement("
|
|
49
|
-
|
|
50
|
-
react_1.default.createElement(
|
|
51
|
-
react_1.default.createElement(material_1.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
react_1.default.createElement(material_1.
|
|
55
|
-
react_1.default.createElement(material_1.RadioGroup, { value: model.upperCaseCDS ? 'cds' : 'unchanged', onChange: e => model.setUpperCaseCDS(e.target.value === 'cds') },
|
|
56
|
-
react_1.default.createElement(material_1.FormControlLabel, { value: "cds", control: react_1.default.createElement(material_1.Radio, null), label: "Capitalize CDS and lower case everything else" }),
|
|
57
|
-
react_1.default.createElement(material_1.FormControlLabel, { value: "unchanged", control: react_1.default.createElement(material_1.Radio, null), label: "Capitalization from reference genome sequence" }))))),
|
|
60
|
+
react_1.default.createElement(TextField2, { label: "Number of intronic bases around splice site to display", className: classes.formElt, value: intronBp, helperText: !intronBpValid ? 'Not a number' : '', error: !intronBpValid, onChange: event => setIntronBp(event.target.value) }),
|
|
61
|
+
react_1.default.createElement(TextField2, { label: "Number of bases up/down stream of feature to display", className: classes.formElt, value: upDownBp, helperText: !upDownBpValid ? 'Not a number' : '', error: !upDownBpValid, onChange: event => setUpDownBp(event.target.value) }),
|
|
62
|
+
react_1.default.createElement(FormControl2, null,
|
|
63
|
+
react_1.default.createElement(material_1.FormLabel, null, "Sequence capitalization"),
|
|
64
|
+
react_1.default.createElement(material_1.RadioGroup, { value: upperCaseCDS ? 'cds' : 'unchanged', onChange: e => model.setUpperCaseCDS(e.target.value === 'cds') },
|
|
65
|
+
react_1.default.createElement(material_1.FormControlLabel, { value: "cds", control: react_1.default.createElement(material_1.Radio, { className: classes.root, size: "small" }), label: "Capitalize CDS and lower case everything else" }),
|
|
66
|
+
react_1.default.createElement(material_1.FormControlLabel, { value: "unchanged", control: react_1.default.createElement(material_1.Radio, { className: classes.root, size: "small" }), label: "Capitalization from reference genome sequence" })))),
|
|
58
67
|
react_1.default.createElement(material_1.DialogActions, null,
|
|
59
68
|
react_1.default.createElement(material_1.Button, { onClick: () => {
|
|
60
69
|
model.setIntronBp(+intronBp);
|
|
@@ -1,12 +1,59 @@
|
|
|
1
1
|
import { Instance } from 'mobx-state-tree';
|
|
2
|
+
import { SimpleFeatureSerialized } from '../../util';
|
|
2
3
|
export declare function SequenceFeatureDetailsF(): import("mobx-state-tree").IModelType<{}, {
|
|
4
|
+
showCoordinatesSetting: string;
|
|
3
5
|
intronBp: number;
|
|
4
6
|
upDownBp: number;
|
|
5
7
|
upperCaseCDS: boolean;
|
|
8
|
+
charactersPerRow: number;
|
|
9
|
+
feature: SimpleFeatureSerialized | undefined;
|
|
10
|
+
mode: string;
|
|
6
11
|
} & {
|
|
12
|
+
/**
|
|
13
|
+
* #action
|
|
14
|
+
*/
|
|
15
|
+
setFeature(f: SimpleFeatureSerialized): void;
|
|
16
|
+
/**
|
|
17
|
+
* #action
|
|
18
|
+
*/
|
|
7
19
|
setUpDownBp(f: number): void;
|
|
20
|
+
/**
|
|
21
|
+
* #action
|
|
22
|
+
*/
|
|
8
23
|
setIntronBp(f: number): void;
|
|
24
|
+
/**
|
|
25
|
+
* #action
|
|
26
|
+
*/
|
|
9
27
|
setUpperCaseCDS(f: boolean): void;
|
|
28
|
+
/**
|
|
29
|
+
* #action
|
|
30
|
+
*/
|
|
31
|
+
setShowCoordinates(f: 'none' | 'relative' | 'genomic'): void;
|
|
32
|
+
/**
|
|
33
|
+
* #action
|
|
34
|
+
*/
|
|
35
|
+
setMode(mode: string): void;
|
|
36
|
+
} & {
|
|
37
|
+
/**
|
|
38
|
+
* #getter
|
|
39
|
+
*/
|
|
40
|
+
readonly showCoordinates: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* #getter
|
|
43
|
+
*/
|
|
44
|
+
readonly showGenomicCoordsOption: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* #getter
|
|
47
|
+
*/
|
|
48
|
+
readonly hasCDS: boolean | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* #getter
|
|
51
|
+
*/
|
|
52
|
+
readonly hasExon: boolean | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* #getter
|
|
55
|
+
*/
|
|
56
|
+
readonly hasExonOrCDS: boolean | undefined;
|
|
10
57
|
} & {
|
|
11
58
|
afterAttach(): void;
|
|
12
59
|
}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>;
|
|
@@ -5,27 +5,97 @@ const mobx_state_tree_1 = require("mobx-state-tree");
|
|
|
5
5
|
const mobx_1 = require("mobx");
|
|
6
6
|
// locals
|
|
7
7
|
const util_1 = require("../../util");
|
|
8
|
+
function localStorageGetNumber(key, defaultVal) {
|
|
9
|
+
var _a;
|
|
10
|
+
return +((_a = (0, util_1.localStorageGetItem)(key)) !== null && _a !== void 0 ? _a : defaultVal);
|
|
11
|
+
}
|
|
8
12
|
function SequenceFeatureDetailsF() {
|
|
9
13
|
return mobx_state_tree_1.types
|
|
10
|
-
.model('SequenceFeatureDetails'
|
|
11
|
-
.volatile(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
.model('SequenceFeatureDetails')
|
|
15
|
+
.volatile(() => ({
|
|
16
|
+
showCoordinatesSetting: (0, util_1.localStorageGetItem)('sequenceFeatureDetails-showCoordinatesSetting') ||
|
|
17
|
+
'none',
|
|
18
|
+
intronBp: localStorageGetNumber('sequenceFeatureDetails-intronBp', 10),
|
|
19
|
+
upDownBp: localStorageGetNumber('sequenceFeatureDetails-upDownBp', 100),
|
|
20
|
+
upperCaseCDS: Boolean(JSON.parse((0, util_1.localStorageGetItem)('sequenceFeatureDetails-upperCaseCDS') || 'true')),
|
|
21
|
+
charactersPerRow: 100,
|
|
22
|
+
feature: undefined,
|
|
23
|
+
mode: '',
|
|
24
|
+
}))
|
|
19
25
|
.actions(self => ({
|
|
26
|
+
/**
|
|
27
|
+
* #action
|
|
28
|
+
*/
|
|
29
|
+
setFeature(f) {
|
|
30
|
+
self.feature = f;
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* #action
|
|
34
|
+
*/
|
|
20
35
|
setUpDownBp(f) {
|
|
21
36
|
self.upDownBp = f;
|
|
22
37
|
},
|
|
38
|
+
/**
|
|
39
|
+
* #action
|
|
40
|
+
*/
|
|
23
41
|
setIntronBp(f) {
|
|
24
42
|
self.intronBp = f;
|
|
25
43
|
},
|
|
44
|
+
/**
|
|
45
|
+
* #action
|
|
46
|
+
*/
|
|
26
47
|
setUpperCaseCDS(f) {
|
|
27
48
|
self.upperCaseCDS = f;
|
|
28
49
|
},
|
|
50
|
+
/**
|
|
51
|
+
* #action
|
|
52
|
+
*/
|
|
53
|
+
setShowCoordinates(f) {
|
|
54
|
+
self.showCoordinatesSetting = f;
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* #action
|
|
58
|
+
*/
|
|
59
|
+
setMode(mode) {
|
|
60
|
+
self.mode = mode;
|
|
61
|
+
},
|
|
62
|
+
}))
|
|
63
|
+
.views(self => ({
|
|
64
|
+
/**
|
|
65
|
+
* #getter
|
|
66
|
+
*/
|
|
67
|
+
get showCoordinates() {
|
|
68
|
+
return self.showCoordinatesSetting !== 'none';
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* #getter
|
|
72
|
+
*/
|
|
73
|
+
get showGenomicCoordsOption() {
|
|
74
|
+
return (self.mode === 'gene' ||
|
|
75
|
+
self.mode === 'gene_updownstream' ||
|
|
76
|
+
self.mode === 'genomic' ||
|
|
77
|
+
self.mode === 'genomic_sequence_updownstream');
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* #getter
|
|
81
|
+
*/
|
|
82
|
+
get hasCDS() {
|
|
83
|
+
var _a, _b;
|
|
84
|
+
return (_b = (_a = self.feature) === null || _a === void 0 ? void 0 : _a.subfeatures) === null || _b === void 0 ? void 0 : _b.some(sub => sub.type === 'CDS');
|
|
85
|
+
},
|
|
86
|
+
/**
|
|
87
|
+
* #getter
|
|
88
|
+
*/
|
|
89
|
+
get hasExon() {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
return (_b = (_a = self.feature) === null || _a === void 0 ? void 0 : _a.subfeatures) === null || _b === void 0 ? void 0 : _b.some(sub => sub.type === 'exon');
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* #getter
|
|
95
|
+
*/
|
|
96
|
+
get hasExonOrCDS() {
|
|
97
|
+
return this.hasExon || this.hasCDS;
|
|
98
|
+
},
|
|
29
99
|
}))
|
|
30
100
|
.actions(self => ({
|
|
31
101
|
afterAttach() {
|
|
@@ -33,6 +103,10 @@ function SequenceFeatureDetailsF() {
|
|
|
33
103
|
(0, util_1.localStorageSetItem)('sequenceFeatureDetails-upDownBp', JSON.stringify(self.upDownBp));
|
|
34
104
|
(0, util_1.localStorageSetItem)('sequenceFeatureDetails-intronBp', JSON.stringify(self.intronBp));
|
|
35
105
|
(0, util_1.localStorageSetItem)('sequenceFeatureDetails-upperCaseCDS', JSON.stringify(self.upperCaseCDS));
|
|
106
|
+
(0, util_1.localStorageSetItem)('sequenceFeatureDetails-showCoordinatesSetting', self.showCoordinatesSetting);
|
|
107
|
+
}));
|
|
108
|
+
(0, mobx_state_tree_1.addDisposer)(self, (0, mobx_1.autorun)(() => {
|
|
109
|
+
self.setMode(self.hasCDS ? 'cds' : self.hasExon ? 'cdna' : 'genomic');
|
|
36
110
|
}));
|
|
37
111
|
},
|
|
38
112
|
}));
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Feat } from '../../util';
|
|
3
3
|
import { SequenceFeatureDetailsModel } from '../model';
|
|
4
|
-
|
|
4
|
+
import { SimpleFeatureSerialized } from '../../../util';
|
|
5
|
+
declare const CDNASequence: ({ utr, cds, exons, sequence, upstream, downstream, feature, includeIntrons, collapseIntron, model, }: {
|
|
5
6
|
utr: Feat[];
|
|
6
7
|
cds: Feat[];
|
|
7
8
|
exons: Feat[];
|
|
8
9
|
sequence: string;
|
|
9
10
|
upstream?: string;
|
|
10
11
|
downstream?: string;
|
|
12
|
+
feature: SimpleFeatureSerialized;
|
|
11
13
|
includeIntrons?: boolean;
|
|
12
14
|
collapseIntron?: boolean;
|
|
13
15
|
model: SequenceFeatureDetailsModel;
|
|
@@ -6,29 +6,86 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
7
|
const mobx_react_1 = require("mobx-react");
|
|
8
8
|
const util_1 = require("../util");
|
|
9
|
-
const
|
|
10
|
-
|
|
9
|
+
const SequenceDisplay_1 = __importDefault(require("./SequenceDisplay"));
|
|
10
|
+
const CDNASequence = (0, mobx_react_1.observer)(function ({ utr, cds, exons, sequence, upstream, downstream, feature, includeIntrons, collapseIntron, model, }) {
|
|
11
|
+
var _a;
|
|
12
|
+
const { upperCaseCDS, intronBp, charactersPerRow, showCoordinates, showCoordinatesSetting, } = model;
|
|
11
13
|
const hasCds = cds.length > 0;
|
|
12
14
|
const chunks = (cds.length ? [...cds, ...utr].sort((a, b) => a.start - b.start) : exons).filter(f => f.start !== f.end);
|
|
13
15
|
const toLower = (s) => (upperCaseCDS ? s.toLowerCase() : s);
|
|
14
16
|
const toUpper = (s) => (upperCaseCDS ? s.toUpperCase() : s);
|
|
17
|
+
const strand = feature.strand === -1 ? -1 : 1;
|
|
18
|
+
const fullGenomicCoordinates = showCoordinatesSetting === 'genomic' && includeIntrons && !collapseIntron;
|
|
19
|
+
const mult = fullGenomicCoordinates ? strand : 1;
|
|
20
|
+
let coordStart = fullGenomicCoordinates
|
|
21
|
+
? strand > 0
|
|
22
|
+
? feature.start + 1 - ((upstream === null || upstream === void 0 ? void 0 : upstream.length) || 0)
|
|
23
|
+
: feature.end + ((upstream === null || upstream === void 0 ? void 0 : upstream.length) || 0)
|
|
24
|
+
: 0;
|
|
25
|
+
let currStart = 0;
|
|
26
|
+
let currRemainder = 0;
|
|
27
|
+
let upstreamChunk = null;
|
|
28
|
+
if (upstream) {
|
|
29
|
+
const { segments, remainder } = (0, util_1.splitString)({
|
|
30
|
+
str: toLower(upstream),
|
|
31
|
+
charactersPerRow,
|
|
32
|
+
showCoordinates,
|
|
33
|
+
});
|
|
34
|
+
upstreamChunk = (react_1.default.createElement(SequenceDisplay_1.default, { model: model, color: util_1.updownstreamColor, strand: mult, start: currStart, coordStart: coordStart, chunks: segments }));
|
|
35
|
+
currRemainder = remainder;
|
|
36
|
+
currStart = currStart + upstream.length * mult;
|
|
37
|
+
coordStart = coordStart + upstream.length * mult;
|
|
38
|
+
}
|
|
39
|
+
const middleChunks = [];
|
|
40
|
+
for (let idx = 0; idx < chunks.length; idx++) {
|
|
41
|
+
const chunk = chunks[idx];
|
|
42
|
+
const intron = sequence.slice(chunk.end, (_a = chunks[idx + 1]) === null || _a === void 0 ? void 0 : _a.start);
|
|
43
|
+
const s = sequence.slice(chunk.start, chunk.end);
|
|
44
|
+
const { segments, remainder } = (0, util_1.splitString)({
|
|
45
|
+
str: hasCds
|
|
46
|
+
? chunk.type === 'CDS'
|
|
47
|
+
? toUpper(s)
|
|
48
|
+
: toLower(s)
|
|
49
|
+
: toUpper(s),
|
|
50
|
+
charactersPerRow,
|
|
51
|
+
currRemainder,
|
|
52
|
+
showCoordinates,
|
|
53
|
+
});
|
|
54
|
+
middleChunks.push(react_1.default.createElement(SequenceDisplay_1.default, { key: JSON.stringify(chunk) + '-mid', model: model, color: chunk.type === 'CDS' ? util_1.cdsColor : util_1.utrColor, strand: mult, start: currStart, coordStart: coordStart, chunks: segments }));
|
|
55
|
+
currRemainder = remainder;
|
|
56
|
+
currStart = currStart + s.length * mult;
|
|
57
|
+
coordStart = coordStart + s.length * mult;
|
|
58
|
+
if (intron && includeIntrons && idx < chunks.length - 1) {
|
|
59
|
+
const str = toLower(collapseIntron && intron.length > intronBp * 2
|
|
60
|
+
? `${intron.slice(0, intronBp)}...${intron.slice(-intronBp)}`
|
|
61
|
+
: intron);
|
|
62
|
+
const { segments, remainder } = (0, util_1.splitString)({
|
|
63
|
+
str,
|
|
64
|
+
charactersPerRow,
|
|
65
|
+
currRemainder,
|
|
66
|
+
showCoordinates,
|
|
67
|
+
});
|
|
68
|
+
if (segments.length) {
|
|
69
|
+
middleChunks.push(react_1.default.createElement(SequenceDisplay_1.default, { key: JSON.stringify(chunk) + '-intron', model: model, strand: mult, coordStart: coordStart, start: currStart, chunks: segments }));
|
|
70
|
+
currRemainder = remainder;
|
|
71
|
+
currStart = currStart + str.length * mult;
|
|
72
|
+
coordStart = coordStart + str.length * mult;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
let downstreamChunk = null;
|
|
77
|
+
if (downstream) {
|
|
78
|
+
const { segments } = (0, util_1.splitString)({
|
|
79
|
+
str: toLower(downstream),
|
|
80
|
+
charactersPerRow,
|
|
81
|
+
currRemainder,
|
|
82
|
+
showCoordinates,
|
|
83
|
+
});
|
|
84
|
+
downstreamChunk = (react_1.default.createElement(SequenceDisplay_1.default, { start: currStart, model: model, strand: mult, chunks: segments, coordStart: coordStart, color: util_1.updownstreamColor }));
|
|
85
|
+
}
|
|
15
86
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const intron = sequence.slice(chunk.end, (_a = chunks[idx + 1]) === null || _a === void 0 ? void 0 : _a.start);
|
|
20
|
-
return (react_1.default.createElement(react_1.default.Fragment, { key: JSON.stringify(chunk) },
|
|
21
|
-
react_1.default.createElement("span", { style: {
|
|
22
|
-
background: chunk.type === 'CDS' ? util_1.cdsColor : util_1.utrColor,
|
|
23
|
-
} }, hasCds
|
|
24
|
-
? chunk.type === 'CDS'
|
|
25
|
-
? toUpper(sequence.slice(chunk.start, chunk.end))
|
|
26
|
-
: toLower(sequence.slice(chunk.start, chunk.end))
|
|
27
|
-
: toUpper(sequence.slice(chunk.start, chunk.end))),
|
|
28
|
-
includeIntrons && idx < chunks.length - 1 ? (react_1.default.createElement("span", { style: { background: util_1.intronColor } }, toLower(collapseIntron && intron.length > intronBp * 2
|
|
29
|
-
? `${intron.slice(0, intronBp)}...${intron.slice(-intronBp)}`
|
|
30
|
-
: intron))) : null));
|
|
31
|
-
}),
|
|
32
|
-
downstream ? (react_1.default.createElement("span", { style: { background: util_1.updownstreamColor } }, toLower(downstream))) : null));
|
|
87
|
+
upstreamChunk,
|
|
88
|
+
middleChunks,
|
|
89
|
+
downstreamChunk));
|
|
33
90
|
});
|
|
34
91
|
exports.default = CDNASequence;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Feat } from '../../util';
|
|
3
|
-
|
|
3
|
+
import { SequenceFeatureDetailsModel } from '../model';
|
|
4
|
+
declare const CDSSequence: ({ cds, sequence, model, }: {
|
|
4
5
|
cds: Feat[];
|
|
5
6
|
sequence: string;
|
|
6
|
-
|
|
7
|
+
model: SequenceFeatureDetailsModel;
|
|
8
|
+
}) => React.JSX.Element;
|
|
9
|
+
export default CDSSequence;
|
|
@@ -4,9 +4,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const mobx_react_1 = require("mobx-react");
|
|
8
|
+
// locals
|
|
7
9
|
const util_1 = require("../util");
|
|
8
10
|
const util_2 = require("../../util");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
11
|
+
const SequenceDisplay_1 = __importDefault(require("./SequenceDisplay"));
|
|
12
|
+
const CDSSequence = (0, mobx_react_1.observer)(function ({ cds, sequence, model, }) {
|
|
13
|
+
const { charactersPerRow, showCoordinates } = model;
|
|
14
|
+
const { segments } = (0, util_1.splitString)({
|
|
15
|
+
str: (0, util_2.stitch)(cds, sequence),
|
|
16
|
+
charactersPerRow,
|
|
17
|
+
showCoordinates,
|
|
18
|
+
});
|
|
19
|
+
return (react_1.default.createElement(SequenceDisplay_1.default, { model: model, color: util_1.cdsColor, chunks: segments, start: 0 }));
|
|
20
|
+
});
|
|
12
21
|
exports.default = CDSSequence;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
2
|
+
import { SequenceFeatureDetailsModel } from '../model';
|
|
3
|
+
import { SimpleFeatureSerialized } from '../../../util';
|
|
4
|
+
declare const GenomicSequence: ({ sequence, upstream, feature, downstream, model, }: {
|
|
3
5
|
sequence: string;
|
|
6
|
+
feature: SimpleFeatureSerialized;
|
|
4
7
|
upstream?: string;
|
|
5
8
|
downstream?: string;
|
|
6
|
-
|
|
9
|
+
model: SequenceFeatureDetailsModel;
|
|
10
|
+
}) => React.JSX.Element;
|
|
11
|
+
export default GenomicSequence;
|
|
@@ -4,11 +4,57 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const mobx_react_1 = require("mobx-react");
|
|
8
|
+
// locals
|
|
7
9
|
const util_1 = require("../util");
|
|
8
|
-
|
|
10
|
+
const SequenceDisplay_1 = __importDefault(require("./SequenceDisplay"));
|
|
11
|
+
const GenomicSequence = (0, mobx_react_1.observer)(function ({ sequence, upstream, feature, downstream, model, }) {
|
|
12
|
+
const { charactersPerRow, showCoordinatesSetting, showCoordinates } = model;
|
|
13
|
+
let currStart = 0;
|
|
14
|
+
let upstreamChunk = null;
|
|
15
|
+
let currRemainder = 0;
|
|
16
|
+
const strand = feature.strand === -1 ? -1 : 1;
|
|
17
|
+
const fullGenomicCoordinates = showCoordinatesSetting === 'genomic';
|
|
18
|
+
const mult = fullGenomicCoordinates ? strand : 1;
|
|
19
|
+
let coordStart = fullGenomicCoordinates
|
|
20
|
+
? strand > 0
|
|
21
|
+
? feature.start + 1 - ((upstream === null || upstream === void 0 ? void 0 : upstream.length) || 0)
|
|
22
|
+
: feature.end + ((upstream === null || upstream === void 0 ? void 0 : upstream.length) || 0)
|
|
23
|
+
: 0;
|
|
24
|
+
if (upstream) {
|
|
25
|
+
const { segments, remainder } = (0, util_1.splitString)({
|
|
26
|
+
str: upstream,
|
|
27
|
+
charactersPerRow,
|
|
28
|
+
showCoordinates,
|
|
29
|
+
});
|
|
30
|
+
upstreamChunk = (react_1.default.createElement(SequenceDisplay_1.default, { model: model, color: util_1.updownstreamColor, start: currStart, coordStart: coordStart, chunks: segments }));
|
|
31
|
+
currRemainder = remainder;
|
|
32
|
+
currStart = currStart + upstream.length * mult;
|
|
33
|
+
coordStart = coordStart + upstream.length * mult;
|
|
34
|
+
}
|
|
35
|
+
const { segments, remainder } = (0, util_1.splitString)({
|
|
36
|
+
str: sequence,
|
|
37
|
+
charactersPerRow,
|
|
38
|
+
showCoordinates,
|
|
39
|
+
currRemainder,
|
|
40
|
+
});
|
|
41
|
+
const middleChunk = (react_1.default.createElement(SequenceDisplay_1.default, { model: model, color: util_1.genomeColor, start: currStart, coordStart: coordStart, chunks: segments }));
|
|
42
|
+
currRemainder = remainder;
|
|
43
|
+
currStart += sequence.length * mult;
|
|
44
|
+
coordStart = coordStart + sequence.length * mult;
|
|
45
|
+
let downstreamChunk = null;
|
|
46
|
+
if (downstream) {
|
|
47
|
+
const { segments } = (0, util_1.splitString)({
|
|
48
|
+
str: downstream,
|
|
49
|
+
charactersPerRow,
|
|
50
|
+
currRemainder,
|
|
51
|
+
showCoordinates,
|
|
52
|
+
});
|
|
53
|
+
downstreamChunk = (react_1.default.createElement(SequenceDisplay_1.default, { start: currStart, model: model, chunks: segments, coordStart: coordStart, color: util_1.updownstreamColor }));
|
|
54
|
+
}
|
|
9
55
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
56
|
+
upstreamChunk,
|
|
57
|
+
middleChunk,
|
|
58
|
+
downstreamChunk));
|
|
59
|
+
});
|
|
14
60
|
exports.default = GenomicSequence;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Feat } from '../../util';
|
|
3
|
-
|
|
3
|
+
import { SequenceFeatureDetailsModel } from '../model';
|
|
4
|
+
declare const ProteinSequence: ({ cds, sequence, codonTable, model, }: {
|
|
4
5
|
cds: Feat[];
|
|
5
6
|
sequence: string;
|
|
6
7
|
codonTable: Record<string, string>;
|
|
7
|
-
|
|
8
|
+
model: SequenceFeatureDetailsModel;
|
|
9
|
+
}) => React.JSX.Element;
|
|
10
|
+
export default ProteinSequence;
|
|
@@ -4,15 +4,24 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const mobx_react_1 = require("mobx-react");
|
|
8
|
+
// locals
|
|
7
9
|
const util_1 = require("../../util");
|
|
8
10
|
const util_2 = require("../util");
|
|
9
|
-
|
|
11
|
+
const SequenceDisplay_1 = __importDefault(require("./SequenceDisplay"));
|
|
12
|
+
const ProteinSequence = (0, mobx_react_1.observer)(function ({ cds, sequence, codonTable, model, }) {
|
|
13
|
+
const { charactersPerRow, showCoordinates } = model;
|
|
10
14
|
const str = (0, util_1.stitch)(cds, sequence);
|
|
11
15
|
let protein = '';
|
|
12
16
|
for (let i = 0; i < str.length; i += 3) {
|
|
13
17
|
// use & symbol for undefined codon, or partial slice
|
|
14
18
|
protein += codonTable[str.slice(i, i + 3)] || '&';
|
|
15
19
|
}
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
const { segments } = (0, util_2.splitString)({
|
|
21
|
+
str: protein,
|
|
22
|
+
charactersPerRow,
|
|
23
|
+
showCoordinates,
|
|
24
|
+
});
|
|
25
|
+
return (react_1.default.createElement(SequenceDisplay_1.default, { model: model, color: util_2.proteinColor, chunks: segments, start: 0 }));
|
|
26
|
+
});
|
|
18
27
|
exports.default = ProteinSequence;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SequenceFeatureDetailsModel } from '../model';
|
|
3
|
+
declare const SequenceDisplay: ({ chunks, start, color, strand, coordStart, model, }: {
|
|
4
|
+
chunks: string[];
|
|
5
|
+
start: number;
|
|
6
|
+
coordStart?: number;
|
|
7
|
+
strand?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
model: SequenceFeatureDetailsModel;
|
|
10
|
+
}) => React.JSX.Element[];
|
|
11
|
+
export default SequenceDisplay;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const react_1 = __importDefault(require("react"));
|
|
7
|
+
const mobx_react_1 = require("mobx-react");
|
|
8
|
+
const SequenceDisplay = (0, mobx_react_1.observer)(function ({ chunks, start, color, strand = 1, coordStart = start, model, }) {
|
|
9
|
+
const { charactersPerRow, showCoordinates } = model;
|
|
10
|
+
return chunks.map((chunk, idx) => {
|
|
11
|
+
var _a;
|
|
12
|
+
const f = coordStart - (start % charactersPerRow);
|
|
13
|
+
const prefix = (idx == 0 && start % charactersPerRow == 0) || idx > 0
|
|
14
|
+
? `${f + idx * strand * charactersPerRow}`.padStart(4) + ' '
|
|
15
|
+
: '';
|
|
16
|
+
const postfix = idx === chunks.length - 1 &&
|
|
17
|
+
(((_a = chunks.at(-1)) === null || _a === void 0 ? void 0 : _a.replaceAll(' ', '').length) || 0) +
|
|
18
|
+
(idx === 0 ? start % charactersPerRow : 0) !==
|
|
19
|
+
charactersPerRow
|
|
20
|
+
? null
|
|
21
|
+
: showCoordinates
|
|
22
|
+
? ' \n'
|
|
23
|
+
: '';
|
|
24
|
+
return (react_1.default.createElement(react_1.default.Fragment, { key: `${chunk}-${idx}` },
|
|
25
|
+
showCoordinates ? prefix : null,
|
|
26
|
+
react_1.default.createElement("span", { style: { background: color } }, chunk),
|
|
27
|
+
postfix));
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
exports.default = SequenceDisplay;
|
|
@@ -4,3 +4,14 @@ export declare const proteinColor = "rgb(220,160,220)";
|
|
|
4
4
|
export declare const cdsColor = "rgb(220,220,180)";
|
|
5
5
|
export declare const updownstreamColor = "rgba(250,200,200)";
|
|
6
6
|
export declare const genomeColor = "rgb(200,280,200)";
|
|
7
|
+
export declare function splitString({ str, charactersPerRow, showCoordinates, currRemainder, splitSize, }: {
|
|
8
|
+
str: string;
|
|
9
|
+
charactersPerRow: number;
|
|
10
|
+
showCoordinates: boolean;
|
|
11
|
+
currRemainder?: number;
|
|
12
|
+
splitStart?: number;
|
|
13
|
+
splitSize?: number;
|
|
14
|
+
}): {
|
|
15
|
+
segments: any[];
|
|
16
|
+
remainder: number;
|
|
17
|
+
};
|