@datagrok/sequence-translator 1.0.14 → 1.0.16
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/.eslintrc.json +16 -3
- package/dist/package-test.js +715 -316
- package/dist/package.js +684 -301
- package/package.json +25 -22
- package/scripts/build-monomer-lib.py +52 -14
- package/src/apps/oligo-sd-file-app.ts +58 -0
- package/src/autostart/calculations.ts +9 -6
- package/src/autostart/constants.ts +0 -12
- package/src/autostart/registration.ts +121 -149
- package/src/axolabs/constants.ts +4 -4
- package/src/main/main-view.ts +90 -49
- package/src/package.ts +52 -5
- package/src/structures-works/const.ts +3 -16
- package/src/structures-works/converters.ts +28 -26
- package/src/structures-works/mol-transformations.ts +73 -75
- package/src/utils/parse.ts +27 -0
- package/src/utils/sdf-add-columns.ts +118 -0
- package/src/utils/sdf-save-table.ts +56 -0
- package/{test-SequenceTranslator-e8c06047b7e7-eb4db608.html → test-SequenceTranslator-6288c2fbe346-cce4ac1d.html} +6 -6
package/src/axolabs/constants.ts
CHANGED
|
@@ -44,22 +44,22 @@ export const AXOLABS_MAP:
|
|
|
44
44
|
color: 'rgb(255,192,0)',
|
|
45
45
|
},
|
|
46
46
|
'A': {
|
|
47
|
-
fullName: '
|
|
47
|
+
fullName: 'Adenosine',
|
|
48
48
|
symbols: ['a', 'a', 'a', 'a'],
|
|
49
49
|
color: RNA_COLOR,
|
|
50
50
|
},
|
|
51
51
|
'C': {
|
|
52
|
-
fullName: '
|
|
52
|
+
fullName: 'Cytidine',
|
|
53
53
|
symbols: ['c', 'c', 'c', 'c'],
|
|
54
54
|
color: RNA_COLOR,
|
|
55
55
|
},
|
|
56
56
|
'G': {
|
|
57
|
-
fullName: '
|
|
57
|
+
fullName: 'Guanosine',
|
|
58
58
|
symbols: ['g', 'g', 'g', 'g'],
|
|
59
59
|
color: RNA_COLOR,
|
|
60
60
|
},
|
|
61
61
|
'U': {
|
|
62
|
-
fullName: '
|
|
62
|
+
fullName: 'Uridine',
|
|
63
63
|
symbols: ['u', 'u', 'u', 'u'],
|
|
64
64
|
color: RNA_COLOR,
|
|
65
65
|
},
|
package/src/main/main-view.ts
CHANGED
|
@@ -1,35 +1,28 @@
|
|
|
1
1
|
import * as grok from 'datagrok-api/grok';
|
|
2
2
|
import * as ui from 'datagrok-api/ui';
|
|
3
3
|
import * as DG from 'datagrok-api/dg';
|
|
4
|
+
|
|
5
|
+
import * as rxjs from 'rxjs';
|
|
4
6
|
import {convertSequence, undefinedInputSequence, isValidSequence} from '../structures-works/sequence-codes-tools';
|
|
5
7
|
import {map} from '../structures-works/map';
|
|
6
8
|
import {MODIFICATIONS} from '../structures-works/const';
|
|
7
9
|
import {sequenceToSmiles, sequenceToMolV3000} from '../structures-works/from-monomers';
|
|
8
10
|
import $ from 'cash-dom';
|
|
9
11
|
import {download} from '../helpers';
|
|
12
|
+
import {extractAtomDataV3000} from '../structures-works/mol-transformations';
|
|
13
|
+
import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
|
|
10
14
|
|
|
11
15
|
const defaultInput = 'fAmCmGmAmCpsmU'; // todo: capitalize constants
|
|
12
16
|
const sequenceWasCopied = 'Copied'; // todo: wrap hardcoded literals into constants
|
|
13
17
|
const tooltipSequence = 'Copy sequence';
|
|
14
18
|
|
|
15
|
-
export async function mainView(): Promise<HTMLDivElement> {
|
|
16
|
-
const
|
|
19
|
+
export async function mainView(onSequenceChanged: (seq: string) => void): Promise<HTMLDivElement> {
|
|
20
|
+
const onInput: rxjs.Subject<string> = new rxjs.Subject<string>();
|
|
21
|
+
|
|
17
22
|
async function updateTableAndMolecule(sequence: string, inputFormat: string): Promise<void> {
|
|
18
23
|
moleculeSvgDiv.innerHTML = '';
|
|
19
24
|
outputTableDiv.innerHTML = '';
|
|
20
25
|
const pi = DG.TaskBarProgressIndicator.create('Rendering table and molecule...');
|
|
21
|
-
let errorsExist = false;
|
|
22
|
-
|
|
23
|
-
// external helm-like monomers library
|
|
24
|
-
const fileExists = await grok.dapi.files.exists(monomersLibAddress);
|
|
25
|
-
if (!fileExists) {
|
|
26
|
-
// todo: improve behaviour in this case
|
|
27
|
-
grok.shell.warning('Please, provide the file with monomers library as System:AppData/SequenceTranslator/helmLib.json');
|
|
28
|
-
pi.close();
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const monomersLib = await grok.dapi.files.readAsText(monomersLibAddress);
|
|
33
26
|
|
|
34
27
|
try {
|
|
35
28
|
sequence = sequence.replace(/\s/g, '');
|
|
@@ -46,16 +39,16 @@ export async function mainView(): Promise<HTMLDivElement> {
|
|
|
46
39
|
tableRows.push({
|
|
47
40
|
'key': key,
|
|
48
41
|
'value': ('indexOfFirstNotValidChar' in outputSequenceObj) ?
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
ui.divH([
|
|
43
|
+
ui.divText(sequence.slice(0, indexOfFirstNotValidChar), {style: {color: 'grey'}}),
|
|
44
|
+
ui.tooltip.bind(
|
|
45
|
+
ui.divText(sequence.slice(indexOfFirstNotValidChar), {style: {color: 'red'}}),
|
|
46
|
+
'Expected format: ' + JSON.parse(outputSequenceObj.indexOfFirstNotValidChar!).synthesizer +
|
|
47
|
+
'. See tables with valid codes on the right',
|
|
48
|
+
),
|
|
49
|
+
]) : //@ts-ignore
|
|
50
|
+
ui.link(outputSequenceObj[key], () => navigator.clipboard.writeText(outputSequenceObj[key])
|
|
51
|
+
.then(() => grok.shell.info(sequenceWasCopied)), tooltipSequence, ''),
|
|
59
52
|
});
|
|
60
53
|
}
|
|
61
54
|
|
|
@@ -67,27 +60,71 @@ export async function mainView(): Promise<HTMLDivElement> {
|
|
|
67
60
|
);
|
|
68
61
|
|
|
69
62
|
if (outputSequenceObj.type != undefinedInputSequence && outputSequenceObj.Error != undefinedInputSequence) {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
63
|
+
const formCanvasWidth = 500;
|
|
64
|
+
const formCanvasHeight = 170;
|
|
65
|
+
const formCanvas = ui.canvas(
|
|
66
|
+
formCanvasWidth * window.devicePixelRatio, formCanvasHeight * window.devicePixelRatio);
|
|
67
|
+
formCanvas.style.width = `${formCanvasWidth}px`;
|
|
68
|
+
formCanvas.style.height = `${formCanvasHeight}px`;
|
|
69
|
+
|
|
70
|
+
formCanvas.addEventListener('click', async () => {
|
|
71
|
+
try {
|
|
72
|
+
const mol = sequenceToMolV3000(
|
|
73
|
+
inputSequenceField.value.replace(/\s/g, ''), false, true,
|
|
74
|
+
output.synthesizer![0],
|
|
75
|
+
);
|
|
76
|
+
console.log(mol);
|
|
77
|
+
|
|
78
|
+
const addDiv = ui.div([], {style: {overflowX: 'scroll'}});
|
|
79
|
+
|
|
80
|
+
// addDiv size required, but now available before dialog show()
|
|
81
|
+
const coordinates = extractAtomDataV3000(mol);
|
|
82
|
+
const cw: number = $(window).width() * 0.80; // addDiv.clientWidth
|
|
83
|
+
const ch: number = $(window).height() * 0.70; // addDiv.clientHeight
|
|
84
|
+
const molWidth: number = Math.max(...coordinates.x) - Math.min(...coordinates.x);
|
|
85
|
+
const molHeight: number = Math.max(...coordinates.y) - Math.min(...coordinates.y);
|
|
86
|
+
|
|
87
|
+
const wR: number = cw / molWidth;
|
|
88
|
+
const hR: number = ch / molHeight;
|
|
89
|
+
const r: number = hR; // Math.max(wR, hR);
|
|
90
|
+
const dlgCanvasWidth = r * molWidth;
|
|
91
|
+
const dlgCanvasHeight = r * molHeight;
|
|
92
|
+
|
|
93
|
+
const dlgCanvas = ui.canvas(dlgCanvasWidth * window.devicePixelRatio, dlgCanvasHeight * window.devicePixelRatio);
|
|
94
|
+
dlgCanvas.style.width = `${dlgCanvasWidth}px`;
|
|
95
|
+
dlgCanvas.style.height = `${dlgCanvasHeight}px`;
|
|
96
|
+
|
|
97
|
+
// // @ts-ignore
|
|
98
|
+
// OCL.StructureView.drawMolecule(dlgCanvas, OCL.Molecule.fromMolfile(mol), {suppressChiralText: true});
|
|
99
|
+
// await grok.chem.canvasMol(0, 0, dlgCanvas.width, dlgCanvas.height, dlgCanvas, mol, null,
|
|
100
|
+
// {setNewCoords: false, normalizeDepiction: false, straightenDepiction: false});
|
|
101
|
+
await grok.functions.call('Chem:canvasMol', {
|
|
102
|
+
x: 0, y: 0, w: dlgCanvas.width, h: dlgCanvas.height, canvas: dlgCanvas,
|
|
103
|
+
molString: mol, scaffoldMolString: '',
|
|
104
|
+
options: {normalizeDepiction: false, straightenDepiction: false}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
addDiv.appendChild(dlgCanvas);
|
|
108
|
+
ui.dialog('Molecule: ' + inputSequenceField.value)
|
|
109
|
+
.add(addDiv)
|
|
110
|
+
.showModal(true);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
const errStr = errorToConsole(err);
|
|
113
|
+
console.error(errStr);
|
|
114
|
+
}
|
|
83
115
|
});
|
|
84
|
-
$(
|
|
85
|
-
$(
|
|
116
|
+
$(formCanvas).on('mouseover', () => $(formCanvas).css('cursor', 'zoom-in'));
|
|
117
|
+
$(formCanvas).on('mouseout', () => $(formCanvas).css('cursor', 'default'));
|
|
86
118
|
const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true,
|
|
87
119
|
output.synthesizer![0]);
|
|
88
|
-
// @ts-ignore
|
|
89
|
-
OCL.StructureView.drawMolecule(
|
|
90
|
-
|
|
120
|
+
// // @ts-ignore
|
|
121
|
+
// OCL.StructureView.drawMolecule(formCanvas, OCL.Molecule.fromMolfile(mol), {suppressChiralText: true});
|
|
122
|
+
await grok.functions.call('Chem:canvasMol', {
|
|
123
|
+
x: 0, y: 0, w: formCanvas.width, h: formCanvas.height, canvas: formCanvas,
|
|
124
|
+
molString: mol, scaffoldMolString: '',
|
|
125
|
+
options: {normalizeDepiction: false, straightenDepiction: false}
|
|
126
|
+
});
|
|
127
|
+
moleculeSvgDiv.append(formCanvas);
|
|
91
128
|
} else
|
|
92
129
|
moleculeSvgDiv.innerHTML = '';
|
|
93
130
|
} finally {
|
|
@@ -102,7 +139,13 @@ export async function mainView(): Promise<HTMLDivElement> {
|
|
|
102
139
|
const moleculeSvgDiv = ui.block([]);
|
|
103
140
|
const outputTableDiv = ui.div([]);
|
|
104
141
|
const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => {
|
|
142
|
+
// Send event to DG.debounce()
|
|
143
|
+
onInput.next(sequence);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
DG.debounce<string>(onInput, 300).subscribe((sequence) => {
|
|
105
147
|
updateTableAndMolecule(sequence, inputFormatChoiceInput.value!);
|
|
148
|
+
onSequenceChanged(sequence);
|
|
106
149
|
});
|
|
107
150
|
|
|
108
151
|
const asoGapmersGrid = DG.Viewer.grid(
|
|
@@ -139,9 +182,9 @@ export async function mainView(): Promise<HTMLDivElement> {
|
|
|
139
182
|
);
|
|
140
183
|
|
|
141
184
|
const overhangModificationsGrid = DG.Viewer.grid(
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
185
|
+
DG.DataFrame.fromColumns([
|
|
186
|
+
DG.Column.fromStrings('Name', Object.keys(MODIFICATIONS)),
|
|
187
|
+
])!, {showRowHeader: false, showCellTooltip: false, allowEdit: false},
|
|
145
188
|
);
|
|
146
189
|
updateTableAndMolecule(defaultInput, inputFormatChoiceInput.value!);
|
|
147
190
|
|
|
@@ -171,7 +214,6 @@ export async function mainView(): Promise<HTMLDivElement> {
|
|
|
171
214
|
|
|
172
215
|
const downloadMolFileIcon = ui.iconFA('download', async () => {
|
|
173
216
|
const clearSequence = inputSequenceField.value.replace(/\s/g, '');
|
|
174
|
-
const monomersLib = await grok.dapi.files.readAsText(monomersLibAddress);
|
|
175
217
|
const result = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, false,
|
|
176
218
|
inputFormatChoiceInput.value!);
|
|
177
219
|
download(clearSequence + '.mol', encodeURIComponent(result));
|
|
@@ -203,9 +245,8 @@ export async function mainView(): Promise<HTMLDivElement> {
|
|
|
203
245
|
appMainDescription,
|
|
204
246
|
ui.div([
|
|
205
247
|
ui.h1('Input sequence'),
|
|
206
|
-
ui.div([
|
|
207
|
-
|
|
208
|
-
], 'input-base'),
|
|
248
|
+
ui.div([], 'input-base'),
|
|
249
|
+
inputSequenceField.root,
|
|
209
250
|
], 'inputSequence'),
|
|
210
251
|
ui.div([inputFormatChoiceInput], {style: {padding: '5px 0'}}),
|
|
211
252
|
ui.block([
|
package/src/package.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {defineAxolabsPattern} from './axolabs/define-pattern';
|
|
|
6
6
|
import {saveSenseAntiSense} from './structures-works/save-sense-antisense';
|
|
7
7
|
import {mainView} from './main/main-view';
|
|
8
8
|
import {IMonomerLib, MonomerWorks, readLibrary} from '@datagrok-libraries/bio';
|
|
9
|
+
import {OligoSdFileApp} from './apps/oligo-sd-file-app';
|
|
9
10
|
|
|
10
11
|
export const _package = new DG.Package();
|
|
11
12
|
|
|
@@ -16,11 +17,11 @@ export let monomerWorks: MonomerWorks | null = null;
|
|
|
16
17
|
|
|
17
18
|
export function getMonomerWorks() {
|
|
18
19
|
return monomerWorks;
|
|
19
|
-
}
|
|
20
|
+
}
|
|
20
21
|
|
|
21
22
|
export function getMonomerLib() {
|
|
22
23
|
return monomerLib;
|
|
23
|
-
}
|
|
24
|
+
}
|
|
24
25
|
|
|
25
26
|
//name: Sequence Translator
|
|
26
27
|
//tags: app
|
|
@@ -35,14 +36,60 @@ export async function sequenceTranslator(): Promise<void> {
|
|
|
35
36
|
windows.showToolbox = false;
|
|
36
37
|
windows.showHelp = false;
|
|
37
38
|
|
|
39
|
+
let urlParams: URLSearchParams = new URLSearchParams(window.location.search);
|
|
40
|
+
let mainSeq: string = 'fAmCmGmAmCpsmU';
|
|
38
41
|
const v = grok.shell.newView('Sequence Translator', []);
|
|
39
42
|
v.box = true;
|
|
40
|
-
|
|
41
|
-
'MAIN': await mainView()
|
|
43
|
+
const tc = ui.tabControl({
|
|
44
|
+
'MAIN': await mainView((seq) => {
|
|
45
|
+
mainSeq = seq;
|
|
46
|
+
urlParams = new URLSearchParams();
|
|
47
|
+
urlParams.set('seq', mainSeq);
|
|
48
|
+
updatePath();
|
|
49
|
+
}),
|
|
42
50
|
'AXOLABS': defineAxolabsPattern(),
|
|
43
51
|
'SDF': saveSenseAntiSense(),
|
|
44
|
-
})
|
|
52
|
+
});
|
|
53
|
+
tc.onTabChanged.subscribe((value) => {
|
|
54
|
+
if (tc.currentPane.name != 'MAIN')
|
|
55
|
+
urlParams.delete('seq');
|
|
56
|
+
else
|
|
57
|
+
urlParams.set('seq', mainSeq);
|
|
58
|
+
updatePath();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
function updatePath() {
|
|
62
|
+
const urlParamsTxt: string = Object.entries(urlParams)
|
|
63
|
+
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');
|
|
64
|
+
v.path = '/apps/SequenceTranslator/SequenceTranslator' + `/${tc.currentPane.name}/?${urlParamsTxt}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const pathParts: string[] = window.location.pathname.split('/');
|
|
68
|
+
if (pathParts.length >= 5) {
|
|
69
|
+
const tabName: string = pathParts[5];
|
|
70
|
+
tc.currentPane = tc.getPane(tabName);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
v.append(tc);
|
|
74
|
+
console.debug('SequenceTranslator: app sequenceTranslator() ' + `v.path='${v.path}', v.basePath='${v.basePath}'.`);
|
|
45
75
|
}
|
|
46
76
|
|
|
47
77
|
//tags: autostart
|
|
48
78
|
autostartOligoSdFileSubscription();
|
|
79
|
+
|
|
80
|
+
//name: oligoSdFileApp
|
|
81
|
+
//description: Test/demo app for oligoSdFile
|
|
82
|
+
export async function oligoSdFileApp() {
|
|
83
|
+
console.debug('SequenceTranslator: package.ts oligoSdFileApp()');
|
|
84
|
+
|
|
85
|
+
const pi = DG.TaskBarProgressIndicator.create('open oligoSdFile app');
|
|
86
|
+
try {
|
|
87
|
+
grok.shell.windows.showProperties = false;
|
|
88
|
+
grok.shell.windows.showHelp = false;
|
|
89
|
+
|
|
90
|
+
const app = new OligoSdFileApp();
|
|
91
|
+
await app.init();
|
|
92
|
+
} finally {
|
|
93
|
+
pi.close();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
left: 'O[C@@H]1C[C@@H]O[C@H]1CO',
|
|
5
|
-
right: 'O[C@@H]1C[C@@H]O[C@H]1CO',
|
|
6
|
-
},
|
|
7
|
-
'(GalNAc-2-JNJ)': {
|
|
8
|
-
molecularWeight: 1273.3,
|
|
9
|
-
left: 'C(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)' +
|
|
10
|
-
'(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)' +
|
|
11
|
-
'(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)NC(=O)CCCC(=O)NCC(O)CO',
|
|
12
|
-
right: 'OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)' +
|
|
13
|
-
'(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)'+
|
|
14
|
-
'(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)',
|
|
15
|
-
},
|
|
16
|
-
};
|
|
1
|
+
import * as map from './map';
|
|
2
|
+
|
|
3
|
+
export const MODIFICATIONS = map.MODIFICATIONS;
|
|
17
4
|
|
|
18
5
|
export const standardPhosphateLinkSmiles = 'OP(=O)(O)O';
|
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import {lcmsToGcrs} from './map';
|
|
1
|
+
import {lcmsToGcrs, MODIFICATIONS} from './map';
|
|
2
2
|
import * as DG from 'datagrok-api/dg';
|
|
3
3
|
import {DELIMITER} from './map';
|
|
4
|
+
import {sortByStringLengthInDescendingOrder} from '../helpers';
|
|
4
5
|
//name: gcrsToLcms
|
|
5
6
|
//input: string nucleotides {semType: GCRS}
|
|
6
7
|
//output: string result {semType: LCMS}
|
|
7
8
|
export function gcrsToLcms(sequence: string): string {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+
try {
|
|
10
|
+
const df = DG.DataFrame.fromCsv(lcmsToGcrs);
|
|
11
|
+
const arr1: string[] = df.getCol('GCRS').toList();
|
|
12
|
+
const arr2: string[] = df.getCol('LCMS').toList();
|
|
13
|
+
const obj: { [i: string]: string } = {};
|
|
14
|
+
arr1.forEach((element, index) => obj[element] = arr2[index]);
|
|
15
|
+
obj[DELIMITER] = DELIMITER;
|
|
16
|
+
const codes = arr1
|
|
17
|
+
.concat(DELIMITER)
|
|
18
|
+
.concat(Object.keys(MODIFICATIONS));
|
|
19
|
+
const sortedCodes = sortByStringLengthInDescendingOrder(codes);
|
|
20
|
+
let i = 0;
|
|
21
|
+
let r1 = '';
|
|
22
|
+
while (i < sequence.length) {
|
|
23
|
+
const matchedCode = sortedCodes.find((c) => c == sequence.slice(i, i + c.length))!;
|
|
24
|
+
r1 += obj[sequence.slice(i, i + matchedCode.length)];
|
|
25
|
+
i += matchedCode.length;
|
|
26
|
+
}
|
|
27
|
+
while (r1.indexOf('//') != -1)
|
|
28
|
+
r1 = r1.replace('//', '/');
|
|
29
|
+
return r1;
|
|
30
|
+
} catch {
|
|
31
|
+
return '<error>';
|
|
27
32
|
}
|
|
28
|
-
while (r1.indexOf('//') != -1)
|
|
29
|
-
r1 = r1.replace('//', '/');
|
|
30
|
-
return r1;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
//name: asoGapmersNucleotidesToBioSpring
|
|
@@ -35,9 +37,9 @@ export function gcrsToLcms(sequence: string): string {
|
|
|
35
37
|
//output: string result {semType: BioSpring / Gapmers}
|
|
36
38
|
export function asoGapmersNucleotidesToBioSpring(nucleotides: string): string {
|
|
37
39
|
let count: number = -1;
|
|
38
|
-
const objForEdges: {[index: string]: string} = {
|
|
40
|
+
const objForEdges: { [index: string]: string } = {
|
|
39
41
|
'(invabasic)': '(invabasic)', '(GalNAc-2-JNJ)': '(GalNAc-2-JNJ)', 'T': '5*', 'A': '6*', 'C': '7*', 'G': '8*'};
|
|
40
|
-
const objForCenter: {[index: string]: string} = {
|
|
42
|
+
const objForCenter: { [index: string]: string } = {
|
|
41
43
|
'(invabasic)': '(invabasic)', '(GalNAc-2-JNJ)': '(GalNAc-2-JNJ)', 'T': 'T*', 'A': 'A*', 'C': '9*', 'G': 'G*'};
|
|
42
44
|
return nucleotides.replace(/(\(invabasic\)|\(GalNAc-2-JNJ\)|A|T|C|G)/g, function(x: string) {
|
|
43
45
|
count++;
|
|
@@ -51,7 +53,7 @@ export function asoGapmersNucleotidesToBioSpring(nucleotides: string): string {
|
|
|
51
53
|
//output: string result {semType: GCRS / Gapmers}
|
|
52
54
|
export function asoGapmersNucleotidesToGcrs(nucleotides: string): string {
|
|
53
55
|
let count: number = -1;
|
|
54
|
-
const objForEdges: {[index: string]: string} = {
|
|
56
|
+
const objForEdges: { [index: string]: string } = {
|
|
55
57
|
'(invabasic)': '(invabasic)', '(GalNAc-2-JNJ)': '(GalNAc-2-JNJ)', 'T': 'moeUnps',
|
|
56
58
|
'A': 'moeAnps', 'C': 'moe5mCnps', 'G': 'moeGnps'};
|
|
57
59
|
const objForCenter: {[index: string]: string} = {'(invabasic)': '(invabasic)', '(GalNAc-2-JNJ)': '(GalNAc-2-JNJ)',
|