@datagrok/sequence-translator 1.0.4 → 1.0.5

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/src/package.ts CHANGED
@@ -1,27 +1,13 @@
1
- /* Do not change these import lines. Datagrok will import API library in exactly the same manner */
2
1
  import * as grok from 'datagrok-api/grok';
3
2
  import * as ui from 'datagrok-api/ui';
4
3
  import * as DG from 'datagrok-api/dg';
5
- import $ from 'cash-dom';
6
- import {defineAxolabsPattern} from './defineAxolabsPattern';
4
+ import {autostartOligoSdFileSubscription} from './autostart/registration';
5
+ import {defineAxolabsPattern} from './axolabs/define-pattern';
7
6
  import {saveSenseAntiSense} from './structures-works/save-sense-antisense';
8
- import {sequenceToSmiles, sequenceToMolV3000} from './structures-works/from-monomers';
9
- import {convertSequence, undefinedInputSequence, isValidSequence, getFormat} from
10
- './structures-works/sequence-codes-tools';
11
- import {map, COL_NAMES, MODIFICATIONS} from './structures-works/map';
12
- import {siRnaAxolabsToGcrs, gcrsToNucleotides, asoGapmersBioSpringToGcrs, gcrsToMermade12,
13
- } from './structures-works/converters';
14
- import {SALTS_CSV} from './salts';
15
- import {USERS_CSV} from './users';
16
- import {ICDS} from './ICDs';
17
- import {SOURCES} from './sources';
18
- import {IDPS} from './IDPs';
7
+ import {mainView} from './main/main-view';
19
8
 
20
9
  export const _package = new DG.Package();
21
10
 
22
- const defaultInput = 'fAmCmGmAmCpsmU';
23
- const sequenceWasCopied = 'Copied';
24
- const tooltipSequence = 'Copy sequence';
25
11
 
26
12
  //name: Sequence Translator
27
13
  //tags: app
@@ -31,400 +17,15 @@ export function sequenceTranslator(): void {
31
17
  windows.showToolbox = false;
32
18
  windows.showHelp = false;
33
19
 
34
- function updateTableAndMolecule(sequence: string, inputFormat: string, isSet: boolean): void {
35
- moleculeSvgDiv.innerHTML = '';
36
- outputTableDiv.innerHTML = '';
37
- const pi = DG.TaskBarProgressIndicator.create('Rendering table and molecule...');
38
- let errorsExist = false;
39
- try {
40
- sequence = sequence.replace(/\s/g, '');
41
- const output = isValidSequence(sequence, null);
42
- if (isSet)
43
- output.synthesizer = [inputFormat];
44
- inputFormatChoiceInput.value = output.synthesizer![0];
45
- const outputSequenceObj = convertSequence(sequence, output);
46
- const tableRows = [];
47
-
48
- for (const key of Object.keys(outputSequenceObj).slice(1)) {
49
- const indexOfFirstNotValidChar = ('indexOfFirstNotValidChar' in outputSequenceObj) ?
50
- JSON.parse(outputSequenceObj.indexOfFirstNotValidChar!).indexOfFirstNotValidChar :
51
- -1;
52
- if ('indexOfFirstNotValidChar' in outputSequenceObj) {
53
- const indexOfFirstNotValidChar = ('indexOfFirstNotValidChar' in outputSequenceObj) ?
54
- JSON.parse(outputSequenceObj.indexOfFirstNotValidChar!).indexOfFirstNotValidChar :
55
- -1;
56
- if (indexOfFirstNotValidChar != -1)
57
- errorsExist = true;
58
- }
59
-
60
- tableRows.push({
61
- 'key': key,
62
- 'value': ('indexOfFirstNotValidChar' in outputSequenceObj) ?
63
- ui.divH([
64
- ui.divText(sequence.slice(0, indexOfFirstNotValidChar), {style: {color: 'grey'}}),
65
- ui.tooltip.bind(
66
- ui.divText(sequence.slice(indexOfFirstNotValidChar), {style: {color: 'red'}}),
67
- 'Expected format: ' + JSON.parse(outputSequenceObj.indexOfFirstNotValidChar!).synthesizer +
68
- '. See tables with valid codes on the right',
69
- ),
70
- ]) : //@ts-ignore
71
- ui.link(outputSequenceObj[key], () => navigator.clipboard.writeText(outputSequenceObj[key])
72
- .then(() => grok.shell.info(sequenceWasCopied)), tooltipSequence, ''),
73
- });
74
- }
75
-
76
- if (errorsExist) {
77
- const synthesizer = JSON.parse(outputSequenceObj.indexOfFirstNotValidChar!).synthesizer.slice(0, -6);
78
- asoGapmersGrid.onCellPrepare(function(gc) {
79
- gc.style.backColor = (gc.gridColumn.name == synthesizer) ? 0xFFF00000 : 0xFFFFFFFF;
80
- });
81
- omeAndFluoroGrid.onCellPrepare(function(gc) {
82
- gc.style.backColor = (gc.gridColumn.name == synthesizer) ? 0xFFF00000 : 0xFFFFFFFF;
83
- });
84
- switchInput.enabled = true;
85
- } else {
86
- asoGapmersGrid.onCellPrepare(function(gc) {gc.style.backColor = 0xFFFFFFFF;});
87
- omeAndFluoroGrid.onCellPrepare(function(gc) {gc.style.backColor = 0xFFFFFFFF;});
88
- }
89
-
90
- outputTableDiv.append(
91
- ui.div([
92
- DG.HtmlTable.create(tableRows, (item: { key: string; value: string; }) =>
93
- [item.key, item.value], ['Code', 'Sequence']).root,
94
- ]),
95
- );
96
-
97
- if (outputSequenceObj.type != undefinedInputSequence && outputSequenceObj.Error != undefinedInputSequence) {
98
- const canvas = ui.canvas(300, 170);
99
- canvas.addEventListener('click', () => {
100
- const canv = ui.canvas($(window).width(), $(window).height());
101
- const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true,
102
- output.synthesizer![0]);
103
- // @ts-ignore
104
- OCL.StructureView.drawMolecule(canv, OCL.Molecule.fromMolfile(mol), {suppressChiralText: true});
105
- ui.dialog('Molecule: ' + inputSequenceField.value)
106
- .add(canv)
107
- .showModal(true);
108
- });
109
- $(canvas).on('mouseover', () => $(canvas).css('cursor', 'zoom-in'));
110
- $(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));
111
- const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true,
112
- output.synthesizer![0]);
113
- // @ts-ignore
114
- OCL.StructureView.drawMolecule(canvas, OCL.Molecule.fromMolfile(mol), {suppressChiralText: true});
115
- moleculeSvgDiv.append(canvas);
116
- } else
117
- moleculeSvgDiv.innerHTML = '';
118
- } finally {
119
- pi.close();
120
- }
121
- }
122
-
123
- const inputFormatChoiceInput = ui.choiceInput(
124
- 'Input format: ', 'Janssen GCRS Codes', Object.keys(map), (format: string) => {
125
- updateTableAndMolecule(inputSequenceField.value.replace(/\s/g, ''), format, true);
126
- });
127
- const moleculeSvgDiv = ui.block([]);
128
- const outputTableDiv = ui.div([]);
129
- const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => updateTableAndMolecule(sequence,
130
- inputFormatChoiceInput.value!, false));
131
-
132
- const asoDf = DG.DataFrame.fromObjects([
133
- {'Name': '2\'MOE-5Me-rU', 'BioSpring': '5', 'Janssen GCRS': 'moeT'},
134
- {'Name': '2\'MOE-rA', 'BioSpring': '6', 'Janssen GCRS': 'moeA'},
135
- {'Name': '2\'MOE-5Me-rC', 'BioSpring': '7', 'Janssen GCRS': 'moe5mC'},
136
- {'Name': '2\'MOE-rG', 'BioSpring': '8', 'Janssen GCRS': 'moeG'},
137
- {'Name': '5-Methyl-dC', 'BioSpring': '9', 'Janssen GCRS': '5mC'},
138
- {'Name': 'ps linkage', 'BioSpring': '*', 'Janssen GCRS': 'ps'},
139
- {'Name': 'dA', 'BioSpring': 'A', 'Janssen GCRS': 'A, dA'},
140
- {'Name': 'dC', 'BioSpring': 'C', 'Janssen GCRS': 'C, dC'},
141
- {'Name': 'dG', 'BioSpring': 'G', 'Janssen GCRS': 'G, dG'},
142
- {'Name': 'dT', 'BioSpring': 'T', 'Janssen GCRS': 'T, dT'},
143
- {'Name': 'rA', 'BioSpring': '', 'Janssen GCRS': 'rA'},
144
- {'Name': 'rC', 'BioSpring': '', 'Janssen GCRS': 'rC'},
145
- {'Name': 'rG', 'BioSpring': '', 'Janssen GCRS': 'rG'},
146
- {'Name': 'rU', 'BioSpring': '', 'Janssen GCRS': 'rU'},
147
- ])!;
148
- const asoGapmersGrid = DG.Viewer.grid(asoDf, {showRowHeader: false, showCellTooltip: false});
149
-
150
- asoDf.onCurrentCellChanged.subscribe((_) => {
151
- navigator.clipboard.writeText(asoDf.currentCell.value).then(() => grok.shell.info('Copied'));
152
- });
153
-
154
- const omeAndFluoroGrid = DG.Viewer.grid(
155
- DG.DataFrame.fromObjects([
156
- {'Name': '2\'-fluoro-U', 'BioSpring': '1', 'Axolabs': 'Uf', 'Janssen GCRS': 'fU'},
157
- {'Name': '2\'-fluoro-A', 'BioSpring': '2', 'Axolabs': 'Af', 'Janssen GCRS': 'fA'},
158
- {'Name': '2\'-fluoro-C', 'BioSpring': '3', 'Axolabs': 'Cf', 'Janssen GCRS': 'fC'},
159
- {'Name': '2\'-fluoro-G', 'BioSpring': '4', 'Axolabs': 'Gf', 'Janssen GCRS': 'fG'},
160
- {'Name': '2\'OMe-rU', 'BioSpring': '5', 'Axolabs': 'u', 'Janssen GCRS': 'mU'},
161
- {'Name': '2\'OMe-rA', 'BioSpring': '6', 'Axolabs': 'a', 'Janssen GCRS': 'mA'},
162
- {'Name': '2\'OMe-rC', 'BioSpring': '7', 'Axolabs': 'c', 'Janssen GCRS': 'mC'},
163
- {'Name': '2\'OMe-rG', 'BioSpring': '8', 'Axolabs': 'g', 'Janssen GCRS': 'mG'},
164
- {'Name': 'ps linkage', 'BioSpring': '*', 'Axolabs': 's', 'Janssen GCRS': 'ps'},
165
- ])!, {showRowHeader: false, showCellTooltip: false},
166
- );
167
-
168
- const overhangModificationsGrid = DG.Viewer.grid(
169
- DG.DataFrame.fromColumns([
170
- DG.Column.fromStrings('Name', Object.keys(MODIFICATIONS)),
171
- ])!, {showRowHeader: false, showCellTooltip: false},
172
- );
173
- updateTableAndMolecule(defaultInput, inputFormatChoiceInput.value!, true);
174
-
175
- const appMainDescription = ui.info([
176
- ui.divText('How to convert one sequence:', {style: {'font-weight': 'bolder'}}),
177
- ui.divText('Paste sequence into the text field below'),
178
- ui.divText('\n How to convert many sequences:', {style: {'font-weight': 'bolder'}}),
179
- ui.divText('1. Drag & drop an Excel or CSV file with sequences into Datagrok'),
180
- ui.divText('2. Right-click on the column header, then see the \'Convert\' menu'),
181
- ui.divText('This will add the result column to the right of the table'),
182
- ], 'Convert oligonucleotide sequences between Nucleotides, BioSpring, Axolabs, Mermade 12 and GCRS representations.');
183
-
184
- const codesTablesDiv = ui.splitV([
185
- ui.box(ui.h2('ASO Gapmers'), {style: {maxHeight: '40px'}}),
186
- asoGapmersGrid.root,
187
- ui.box(ui.h2('2\'-OMe and 2\'-F siRNA'), {style: {maxHeight: '40px'}}),
188
- omeAndFluoroGrid.root,
189
- ui.box(ui.h2('Overhang modifications'), {style: {maxHeight: '40px'}}),
190
- overhangModificationsGrid.root,
191
- ], {style: {maxWidth: '350px'}});
192
-
193
- const tabControl = ui.tabControl({
194
- 'MAIN': ui.box(
195
- ui.splitH([
196
- ui.splitV([
197
- ui.panel([
198
- appMainDescription,
199
- ui.div([
200
- ui.h1('Input sequence'),
201
- ui.div([
202
- inputSequenceField.root,
203
- ], 'input-base'),
204
- ], 'inputSequence'),
205
- ui.div([inputFormatChoiceInput], {style: {padding: '5px 0'}}),
206
- ui.block([
207
- ui.h1('Output'),
208
- outputTableDiv,
209
- ]),
210
- moleculeSvgDiv,
211
- ], 'sequence'),
212
- ]),
213
- codesTablesDiv,
214
- ], {style: {height: '100%', width: '100%'}}),
215
- ),
216
- 'AXOLABS': defineAxolabsPattern(),
217
- 'SDF': saveSenseAntiSense(),
218
- });
219
-
220
- $(codesTablesDiv).hide();
221
-
222
- const v = grok.shell.newView('Sequence Translator', [tabControl]);
20
+ const v = grok.shell.newView('Sequence Translator', [
21
+ ui.tabControl({
22
+ 'MAIN': mainView(),
23
+ 'AXOLABS': defineAxolabsPattern(),
24
+ 'SDF': saveSenseAntiSense(),
25
+ }),
26
+ ]);
223
27
  v.box = true;
224
-
225
- const switchInput = ui.switchInput('Codes', false, (v: boolean) => (v) ?
226
- $(codesTablesDiv).show() :
227
- $(codesTablesDiv).hide(),
228
- );
229
-
230
- const topPanel = [
231
- ui.iconFA('download', () => {
232
- const result = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, false,
233
- inputFormatChoiceInput.value!);
234
- const element = document.createElement('a');
235
- element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result));
236
- element.setAttribute('download', inputSequenceField.value.replace(/\s/g, '') + '.mol');
237
- element.click();
238
- }, 'Save .mol file'),
239
- ui.iconFA('copy', () => {
240
- navigator.clipboard.writeText(
241
- sequenceToSmiles(inputSequenceField.value.replace(/\s/g, ''), false, inputFormatChoiceInput.value!))
242
- .then(() => grok.shell.info(sequenceWasCopied));
243
- }, 'Copy SMILES'),
244
- switchInput.root,
245
- ];
246
-
247
- tabControl.onTabChanged.subscribe((_) =>
248
- v.setRibbonPanels([(tabControl.currentPane.name == 'MAIN') ? topPanel : []]));
249
- v.setRibbonPanels([topPanel]);
250
- }
251
-
252
- async function saveTableAsSdFile(table: DG.DataFrame) {
253
- if (!table.columns.contains('Compound Name')) {
254
- grok.shell.warning(
255
- 'File saved without columns \'' +
256
- [COL_NAMES.COMPOUND_NAME, COL_NAMES.COMPOUND_COMMENTS, COL_NAMES.CPD_MW,
257
- COL_NAMES.SALT_MASS, COL_NAMES.BATCH_MW].join('\', \''),
258
- );
259
- }
260
- const structureColumn = table.col(COL_NAMES.SEQUENCE)!;
261
- const typeColumn = table.col(COL_NAMES.TYPE)!;
262
- let result = '';
263
- for (let i = 0; i < table.rowCount; i++) {
264
- const format = getFormat(structureColumn.get(i));
265
- result += (typeColumn.get(i) == 'SS') ?
266
- sequenceToMolV3000(structureColumn.get(i), false, true, format!) + '\n' + `> <Sequence>\nSense Strand\n\n` :
267
- sequenceToMolV3000(structureColumn.get(i), true, true, format!) + '\n' + `> <Sequence>\nAnti Sense\n\n`;
268
- for (const col of table.columns) {
269
- if (col.name != COL_NAMES.SEQUENCE)
270
- result += `> <${col.name}>\n${col.get(i)}\n\n`;
271
- }
272
- result += '$$$$\n\n';
273
- }
274
- const element = document.createElement('a');
275
- element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(result));
276
- element.setAttribute('download', table.name + '.sdf');
277
- element.click();
278
- }
279
-
280
- const weightsObj: {[code: string]: number} = {};
281
- for (const synthesizer of Object.keys(map)) {
282
- for (const technology of Object.keys(map[synthesizer])) {
283
- for (const code of Object.keys(map[synthesizer][technology]))
284
- weightsObj[code] ?? map[synthesizer][technology][code].weight;
285
- }
286
- }
287
- for (const [key, value] of Object.entries(MODIFICATIONS))
288
- weightsObj[key] = value.molecularWeight;
289
-
290
- function sortByStringLengthInDescendingOrder(array: string[]): string[] {
291
- return array.sort(function(a, b) {return b.length - a.length;});
292
- }
293
-
294
- function stringifyItems(items: string[]): string {
295
- return '["' + items.join('", "') + '"]';
296
- }
297
-
298
- function molecularWeight(sequence: string, weightsObj: {[index: string]: number}): number {
299
- const codes = sortByStringLengthInDescendingOrder(Object.keys(weightsObj)).concat(Object.keys(MODIFICATIONS));
300
- let weight = 0;
301
- let i = 0;
302
- while (i < sequence.length) {
303
- const matchedCode = codes.find((s) => s == sequence.slice(i, i + s.length))!;
304
- weight += weightsObj[sequence.slice(i, i + matchedCode.length)];
305
- i += matchedCode!.length;
306
- }
307
- return weight - 61.97;
308
28
  }
309
29
 
310
30
  //tags: autostart
311
- export function autostartOligoSdFileSubscription() {
312
- grok.events.onViewAdded.subscribe((v: any) => {
313
- if (v.type == 'TableView') {
314
- if (v.dataFrame.columns.contains(COL_NAMES.TYPE))
315
- oligoSdFile(v.dataFrame);
316
- grok.events.onContextMenu.subscribe((args) => {
317
- const seqCol = args.args.context.table.currentCol;
318
- if (DG.Detector.sampleCategories(seqCol, (s) => /^[fsACGUacgu]{6,}$/.test(s))) {
319
- args.args.menu.item('Convert Axolabs to GCRS', () => {
320
- args.args.context.table.columns.addNewString(seqCol.name + ' to GCRS').init((i: number) => {
321
- return siRnaAxolabsToGcrs(seqCol.get(i));
322
- });
323
- });
324
- } else if (DG.Detector.sampleCategories(seqCol, (s) => /^[fmpsACGU]{6,}$/.test(s)) ||
325
- DG.Detector.sampleCategories(seqCol, (s) => /^(?=.*moe)(?=.*5mC)(?=.*ps){6,}/.test(s))) {
326
- args.args.menu.item('Convert GCRS to raw', () => {
327
- args.args.context.table.columns.addNewString(seqCol.name + ' to raw').init((i: number) => {
328
- return gcrsToNucleotides(seqCol.get(i));
329
- });
330
- });
331
- args.args.menu.item('Convert GCRS to MM12', () => {
332
- args.args.context.table.columns.addNewString(seqCol.name + ' to MM12').init((i: number) => {
333
- return gcrsToMermade12(seqCol.get(i));
334
- });
335
- });
336
- } else if (DG.Detector.sampleCategories(seqCol, (s) => /^[*56789ATGC]{6,}$/.test(s))) {
337
- args.args.menu.item('Convert Biospring to GCRS', () => {
338
- const seqCol = args.args.context.table.currentCol;
339
- args.args.context.table.columns.addNewString(seqCol.name + ' to GCRS').init((i: number) => {
340
- return asoGapmersBioSpringToGcrs(seqCol.get(i));
341
- });
342
- });
343
- } else if (DG.Detector.sampleCategories(seqCol, (s) => /^[*1-8]{6,}$/.test(s))) {
344
- args.args.menu.item('Convert Biospring to GCRS', () => {
345
- args.args.context.table.columns.addNewString(seqCol.name + ' to GCRS').init((i: number) => {
346
- return siRnaAxolabsToGcrs(seqCol.get(i));
347
- });
348
- });
349
- }
350
- });
351
- }
352
- });
353
- }
354
-
355
- export function oligoSdFile(table: DG.DataFrame) {
356
- const saltsDf = DG.DataFrame.fromCsv(SALTS_CSV);
357
- const usersDf = DG.DataFrame.fromCsv(USERS_CSV);
358
- const sourcesDf = DG.DataFrame.fromCsv(SOURCES);
359
- const icdsDf = DG.DataFrame.fromCsv(ICDS);
360
- const idpsDf = DG.DataFrame.fromCsv(IDPS);
361
-
362
- function addColumns(t: DG.DataFrame, saltsDf: DG.DataFrame) {
363
- if (t.columns.contains(COL_NAMES.COMPOUND_NAME))
364
- return grok.shell.error('Columns already exist!');
365
-
366
- const sequence = t.col(COL_NAMES.SEQUENCE)!;
367
- const salt = t.col(COL_NAMES.SALT)!;
368
- const equivalents = t.col(COL_NAMES.EQUIVALENTS)!;
369
-
370
- t.columns.addNewString(COL_NAMES.COMPOUND_NAME).init((i: number) => sequence.get(i));
371
- t.columns.addNewString(COL_NAMES.COMPOUND_COMMENTS).init((i: number) => (i > 0 && i % 2 == 0) ?
372
- sequence.getString(i) + '; duplex of SS: ' + sequence.getString(i - 2) + ' and AS: ' + sequence.getString(i - 1) :
373
- sequence.getString(i),
374
- );
375
- const molWeightCol = saltsDf.col('MOLWEIGHT')!;
376
- const saltNamesList = saltsDf.col('DISPLAY')!.toList();
377
- t.columns.addNewFloat(COL_NAMES.CPD_MW)
378
- .init((i: number) => molecularWeight(sequence.get(i), weightsObj));
379
- t.columns.addNewFloat(COL_NAMES.SALT_MASS).init((i: number) => {
380
- const saltRowIndex = saltNamesList.indexOf(salt.get(i));
381
- const mw = molWeightCol.get(saltRowIndex);
382
- return mw * equivalents.get(i);
383
- });
384
- t.columns.addNewCalculated(COL_NAMES.BATCH_MW,
385
- '${' + COL_NAMES.CPD_MW + '} + ${' + COL_NAMES.SALT_MASS + '}', DG.COLUMN_TYPE.FLOAT, false,
386
- );
387
-
388
- addColumnsPressed = true;
389
- return newDf = t;
390
- }
391
-
392
- let newDf: DG.DataFrame;
393
- let addColumnsPressed = false;
394
-
395
- const d = ui.div([
396
- ui.icons.edit(() => {
397
- d.innerHTML = '';
398
- if (table.col(COL_NAMES.IDP)!.type != DG.COLUMN_TYPE.STRING)
399
- table.changeColumnType(COL_NAMES.IDP, DG.COLUMN_TYPE.STRING);
400
- d.append(
401
- ui.link('Add Columns', () => {
402
- addColumns(table, saltsDf);
403
- grok.shell.tableView(table.name).grid.columns.setOrder(Object.values(COL_NAMES));
404
- }, 'Add columns: \'' + [COL_NAMES.COMPOUND_NAME, COL_NAMES.COMPOUND_COMMENTS, COL_NAMES.CPD_MW,
405
- COL_NAMES.SALT_MASS, COL_NAMES.BATCH_MW].join('\', \''), ''),
406
- ui.button('Save SD file', () => saveTableAsSdFile(addColumnsPressed ? newDf : table)),
407
- );
408
-
409
- const view = grok.shell.getTableView(table.name);
410
-
411
- view.table!.col(COL_NAMES.TYPE)!.setTag(DG.TAGS.CHOICES, '["AS", "SS", "Duplex"]');
412
- view.table!.col(COL_NAMES.OWNER)!.setTag(DG.TAGS.CHOICES, stringifyItems(usersDf.columns.byIndex(0).toList()));
413
- view.table!.col(COL_NAMES.SALT)!.setTag(DG.TAGS.CHOICES, stringifyItems(saltsDf.columns.byIndex(0).toList()));
414
- view.table!.col(COL_NAMES.SOURCE)!.setTag(DG.TAGS.CHOICES, stringifyItems(sourcesDf.columns.byIndex(0).toList()));
415
- view.table!.col(COL_NAMES.ICD)!.setTag(DG.TAGS.CHOICES, stringifyItems(icdsDf.columns.byIndex(0).toList()));
416
- view.table!.col(COL_NAMES.IDP)!.setTag(DG.TAGS.CHOICES, stringifyItems(idpsDf.columns.byIndex(0).toList()));
417
-
418
- grok.events.onContextMenu.subscribe((args) => {
419
- if ([COL_NAMES.TYPE, COL_NAMES.OWNER, COL_NAMES.SALT, COL_NAMES.SOURCE, COL_NAMES.ICD, COL_NAMES.IDP]
420
- .includes(args.args.context.table.currentCol.name)) {
421
- args.args.menu.item('Fill Column With Value', () => {
422
- const v = args.args.context.table.currentCell.value;
423
- args.args.context.table.currentCell.column.init(v);
424
- });
425
- }
426
- });
427
- }),
428
- ]);
429
- grok.shell.v.setRibbonPanels([[d]]);
430
- }
31
+ autostartOligoSdFileSubscription();
@@ -15,7 +15,10 @@ export function gcrsToLcms(sequence: string): string {
15
15
  arr1[i] = arr1[i].replace(')', '\\)');
16
16
  }
17
17
  const regExp = new RegExp('(' + arr1.join('|') + ')', 'g');
18
- return sequence.replace(regExp, function(code) {return obj[code];});
18
+ let r1 = sequence.replace(regExp, function(code) {return obj[code];});
19
+ r1 = r1.replace('//', '/');
20
+ r1 = r1.replace('//', '/');
21
+ return r1.replace('//', '/');
19
22
  }
20
23
 
21
24
  //name: asoGapmersNucleotidesToBioSpring
@@ -1,4 +1,4 @@
1
- import {map, stadardPhosphateLinkSmiles, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS} from './map';
1
+ import {map, stadardPhosphateLinkSmiles, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS, delimiter} from './map';
2
2
  import {isValidSequence} from './sequence-codes-tools';
3
3
  import {getNucleotidesMol} from './mol-transformations';
4
4
 
@@ -12,7 +12,7 @@ export function sequenceToMolV3000(sequence: string, inverted: boolean = false,
12
12
  const links = ['s', 'ps', '*'];
13
13
  const includesStandardLinkAlready = ['e', 'h', /*'g',*/ 'f', 'i', 'l', 'k', 'j'];
14
14
  const dropdowns = Object.keys(MODIFICATIONS);
15
- codes = codes.concat(dropdowns);
15
+ codes = codes.concat(dropdowns).concat(delimiter);
16
16
  while (i < sequence.length) {
17
17
  const code = codes.find((s: string) => s == sequence.slice(i, i + s.length))!;
18
18
  i += code.length;
@@ -48,7 +48,7 @@ export function sequenceToSmiles(sequence: string, inverted: boolean = false, fo
48
48
  const links = ['s', 'ps', '*'];
49
49
  const includesStandardLinkAlready = ['e', 'h', /*'g',*/ 'f', 'i', 'l', 'k', 'j'];
50
50
  const dropdowns = Object.keys(MODIFICATIONS);
51
- codes = codes.concat(dropdowns);
51
+ codes = codes.concat(dropdowns).concat(delimiter);
52
52
  while (i < sequence.length) {
53
53
  const code = codes.find((s: string) => s == sequence.slice(i, i + s.length))!;
54
54
  i += code.length;
@@ -98,6 +98,7 @@ function getObjectWithCodesAndSmiles(sequence: string, format: string) {
98
98
  obj[code] = map[format][technology][code].SMILES;
99
99
  }
100
100
  }
101
+ obj[delimiter] = '';
101
102
  // TODO: create object based from synthesizer type to avoid key(codes) duplicates
102
103
  const output = isValidSequence(sequence, format);
103
104
  if (output.synthesizer!.includes(SYNTHESIZERS.MERMADE_12))
@@ -1,6 +1,7 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import {getAllCodesOfSynthesizer} from './sequence-codes-tools';
3
3
 
4
+ export const delimiter = ';';
4
5
  export const SYNTHESIZERS = {
5
6
  RAW_NUCLEOTIDES: 'Raw Nucleotides',
6
7
  BIOSPRING: 'BioSpring Codes',
@@ -242,12 +242,14 @@ export function linkV3000(molBlocks: string[], twoChains: boolean = false, oclRe
242
242
  macroMolBlock += 'M V30 BEGIN BOND\n';
243
243
  macroMolBlock += bondBlock;
244
244
  macroMolBlock += 'M V30 END BOND\n';
245
- macroMolBlock += 'M V30 BEGIN COLLECTION\n';
246
- macroMolBlock += collectionBlock;
247
- macroMolBlock += 'M V30 END COLLECTION\n';
245
+ //macroMolBlock += 'M V30 BEGIN COLLECTION\n';
246
+ //macroMolBlock += collectionBlock;
247
+ //macroMolBlock += 'M V30 END COLLECTION\n';
248
248
  macroMolBlock += 'M V30 END CTAB\n';
249
249
  macroMolBlock += 'M END\n';
250
250
 
251
+ macroMolBlock = macroMolBlock.replaceAll('CFG=1', '').replaceAll('CFG=2', '').replaceAll('CFG=3', '').replaceAll('CFG=4', '');
252
+
251
253
  return macroMolBlock;
252
254
  }
253
255
 
@@ -1,5 +1,5 @@
1
1
 
2
- import {map, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS} from './map';
2
+ import {map, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS, delimiter} from './map';
3
3
  import {asoGapmersNucleotidesToBioSpring, asoGapmersNucleotidesToGcrs,
4
4
  asoGapmersBioSpringToNucleotides, asoGapmersBioSpringToGcrs, asoGapmersGcrsToNucleotides,
5
5
  asoGapmersGcrsToBioSpring, gcrsToMermade12, siRnaNucleotideToBioSpringSenseStrand,
@@ -167,35 +167,35 @@ export function isValidSequence(sequence: string, format: string | null): {
167
167
  // .show();
168
168
  // } else if (possibleTechnologies.length == 0)
169
169
  if (possibleTechnologies.length == 0)
170
- return {indexOfFirstNotValidChar: 0, synthesizer: null, technology: null};
170
+ return {indexOfFirstNotValidChar: 0, synthesizer: [possibleSynthesizers[3]], technology: null};
171
171
 
172
172
  outputIndex = 0;
173
173
 
174
- possibleTechnologies.forEach((technology: string) => {
175
- const codes = Object.keys(map[possibleSynthesizers[0]][technology]);
176
- while (outputIndex < sequence.length) {
177
- const matchedCode = codes.find((c) => c == sequence.slice(outputIndex, outputIndex + c.length));
174
+ // possibleTechnologies.forEach((technology: string) => {
175
+ // const codes = Object.keys(map[possibleSynthesizers[0]][technology]);
176
+ // while (outputIndex < sequence.length) {
177
+ // const matchedCode = codes.find((c) => c == sequence.slice(outputIndex, outputIndex + c.length));
178
178
 
179
- if (matchedCode == null)
180
- break;
179
+ // if (matchedCode == null)
180
+ // break;
181
181
 
182
- if ( // for mistake pattern 'rAA'
183
- outputIndex > 1 &&
184
- nucleotides.includes(sequence[outputIndex]) &&
185
- firstUniqueCharacters.includes(sequence[outputIndex - 2])
186
- ) break;
182
+ // if ( // for mistake pattern 'rAA'
183
+ // outputIndex > 1 &&
184
+ // nucleotides.includes(sequence[outputIndex]) &&
185
+ // firstUniqueCharacters.includes(sequence[outputIndex - 2])
186
+ // ) break;
187
187
 
188
- if ( // for mistake pattern 'ArA'
189
- firstUniqueCharacters.includes(sequence[outputIndex + 1]) &&
190
- nucleotides.includes(sequence[outputIndex])
191
- ) {
192
- outputIndex++;
193
- break;
194
- }
188
+ // if ( // for mistake pattern 'ArA'
189
+ // firstUniqueCharacters.includes(sequence[outputIndex + 1]) &&
190
+ // nucleotides.includes(sequence[outputIndex])
191
+ // ) {
192
+ // outputIndex++;
193
+ // break;
194
+ // }
195
195
 
196
- outputIndex += matchedCode.length;
197
- }
198
- });
196
+ // outputIndex += matchedCode.length;
197
+ // }
198
+ // });
199
199
 
200
200
  return {
201
201
  indexOfFirstNotValidChar: indexOfFirstNotValidChar,
@@ -208,7 +208,7 @@ export function getAllCodesOfSynthesizer(synthesizer: string): string[] {
208
208
  let codes: string[] = [];
209
209
  for (const technology of Object.keys(map[synthesizer]))
210
210
  codes = codes.concat(Object.keys(map[synthesizer][technology]));
211
- return codes.concat(Object.keys(MODIFICATIONS)).concat(',');
211
+ return codes.concat(Object.keys(MODIFICATIONS)).concat(delimiter);
212
212
  }
213
213
 
214
214
  function getListOfPossibleSynthesizersByFirstMatchedCode(sequence: string): string[] {
@@ -1,4 +1,4 @@
1
- <html><head><meta charset="utf-8"/><title>SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=4f0c8bae6479. Commit 18ff1615.</title><style type="text/css">html,
1
+ <html><head><meta charset="utf-8"/><title>SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=4f0c8bae6479. Commit 6545fe31.</title><style type="text/css">html,
2
2
  body {
3
3
  font-family: Arial, Helvetica, sans-serif;
4
4
  font-size: 1rem;
@@ -229,7 +229,7 @@ header {
229
229
  font-size: 1rem;
230
230
  padding: 0 0.5rem;
231
231
  }
232
- </style></head><body><div id="jesthtml-content"><header><h1 id="title">SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=4f0c8bae6479. Commit 18ff1615.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-07-31 10:41:01</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts</div><div class="suite-time warn">38.415s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">22.634s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: Test result : SequenceTranslator.sequence-translator.AGGTCCTCTTGACTTAGGCC : Expected "OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1O", got "OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1O"
232
+ </style></head><body><div id="jesthtml-content"><header><h1 id="title">SequenceTranslator Test Report. Datagrok version datagrok/datagrok:latest SHA=4f0c8bae6479. Commit 6545fe31.</h1></header><div id="metadata-container"><div id="timestamp">Started: 2022-08-05 06:35:31</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed summary-empty">0 passed</div><div class="summary-failed">1 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><div class="suite-info"><div class="suite-path">/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts</div><div class="suite-time warn">44.417s</div></div><div class="suite-tests"><div class="test-result failed"><div class="test-info"><div class="test-suitename"> </div><div class="test-title">TEST</div><div class="test-status">failed</div><div class="test-duration">22.692s</div></div><div class="failureMessages"> <pre class="failureMsg">Error: Test result : SequenceTranslator.sequence-translator.AGGTCCTCTTGACTTAGGCC : Expected "OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1O", got "OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=C(C)C(=O)NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=CN=C(N)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C=CC(N)=NC2(=O))C[C@@H]1O"
233
233
  Test result : SequenceTranslator.sequence-translator.invabasic/galnac1 : Expected "O[C@@H]1C[C@@H]O[C@H]1COP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)", got "O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)OP(=O)(O)O"
234
234
  Test result : SequenceTranslator.sequence-translator.invabasic/galnac2 : Expected "O[C@@H]1C[C@@H]O[C@H]1COP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)", got "O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)OP(=O)(O)O"
235
235
  Test result : SequenceTranslator.sequence-translator.invabasic/galnac3 : Expected "O[C@@H]1C[C@@H]O[C@H]1COP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(S)O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)", got "O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OP(=O)(S)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(O)OC[C@H]1O[C@@H](N2C3N=C(N)NC(=O)C=3N=C2)[C@H](OC)[C@@H]1OP(=O)(S)O[C@@H]1C[C@@H]O[C@H]1COP(=O)(O)OCC(O)CNC(=O)CCCC(=O)NC(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)(COCCC(=O)NCCCNC(=O)CCCCOC2OC(CO)C(O)C(O)C2NC(=O)C)OP(=O)(O)O"
@@ -248,20 +248,20 @@ Test result : SequenceTranslator.sequence-translator.(invabasic)susguuUfgCfCfUfa
248
248
 
249
249
  at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:67:20
250
250
  at Generator.next (&lt;anonymous&gt;)
251
- at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:24:58)
251
+ at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:28:58)
252
252
  at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre></div></div></div><div class="suite-consolelog"><div class="suite-consolelog-header">Console Log</div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at Object.&lt;anonymous&gt; (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/test-node.ts:62:11)
253
253
  at Generator.next (&lt;anonymous&gt;)
254
- at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/test-node.ts:24:58)
254
+ at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/test-node.ts:28:58)
255
255
  at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Using web root: http://localhost:8080</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:40:11
256
256
  at Generator.next (&lt;anonymous&gt;)
257
- at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:27:71
257
+ at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:31:71
258
258
  at new Promise (&lt;anonymous&gt;)
259
- at Object.&lt;anonymous&gt;.__awaiter (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:23:12)
259
+ at Object.&lt;anonymous&gt;.__awaiter (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:27:12)
260
260
  at Object.&lt;anonymous&gt; (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:38:23)
261
261
  at Promise.then.completed (/home/runner/work/public/public/packages/SequenceTranslator/node_modules/jest-circus/build/utils.js:391:28)
262
262
  at new Promise (&lt;anonymous&gt;)</pre><pre class="suite-consolelog-item-message">Testing SequenceTranslator package</pre></div><div class="suite-consolelog-item"><pre class="suite-consolelog-item-origin"> at /home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:65:11
263
263
  at Generator.next (&lt;anonymous&gt;)
264
- at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:24:58)
264
+ at fulfilled (/home/runner/work/public/public/packages/SequenceTranslator/src/__jest__/remote.test.ts:28:58)
265
265
  at processTicksAndRejections (internal/process/task_queues.js:97:5)</pre><pre class="suite-consolelog-item-message">Test result : SequenceTranslator.sequence-translator.usCfCfUfGfAf : OK
266
266
  Test result : SequenceTranslator.sequence-translator.usAfsusgsgsg : OK
267
267
  Test result : SequenceTranslator.sequence-translator.UfUfUfsCfsuacg : OK