@datagrok/helm 2.0.2 → 2.0.3

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.
@@ -15,6 +15,9 @@
15
15
  <script type="text/javascript">
16
16
  dojo.ready(function () {
17
17
  var jsd = new JSDraw("Div2", { width: 800, height: 400, skin: "w8", viewonly: true });
18
+ var mol = jsd.getMolfile();
19
+ var m = new JSDraw2.Mol();
20
+ console.log(JSDraw2.FormulaParser.getAtomStats(m.setMolfile(mol)));
18
21
  });
19
22
  </script>
20
23
  </body>
package/package.json CHANGED
@@ -1,17 +1,19 @@
1
1
  {
2
2
  "name": "@datagrok/helm",
3
- "beta": false,
4
3
  "friendlyName": "Helm",
5
- "version": "2.0.2",
4
+ "version": "2.0.3",
5
+ "author": {
6
+ "name": "Oleksandra Serhiienko",
7
+ "email": "oserhiienko@datagrok.ai"
8
+ },
6
9
  "description": "",
7
10
  "dependencies": {
8
- "datagrok-api": "^1.5.0",
9
- "cash-dom": "latest",
10
- "dayjs": "latest",
11
- "@datagrok-libraries/utils": "^1.4.0",
12
- "@datagrok-libraries/bio": "^3.0.1",
13
- "ts-loader": "^9.2.5",
14
- "typescript": "^4.4.2"
11
+ "datagrok-api": "^1.6.0",
12
+ "cash-dom": "^8.1.1",
13
+ "dayjs": "^1.10.6",
14
+ "@datagrok-libraries/utils": "^1.6.2",
15
+ "@datagrok-libraries/bio": "^3.1.1"
16
+
15
17
  },
16
18
  "sources": [
17
19
  "css/helm.css",
@@ -21,21 +23,24 @@
21
23
  "helm/JSDraw/Pistoia.HELM-uncompressed.js"
22
24
  ],
23
25
  "devDependencies": {
24
- "@typescript-eslint/eslint-plugin": "latest",
25
- "@typescript-eslint/parser": "latest",
26
- "eslint": "latest",
27
- "eslint-config-google": "latest",
28
- "ts-loader": "latest",
29
- "typescript": "latest",
30
- "webpack": "latest",
31
- "webpack-cli": "latest",
32
26
  "@types/jest": "^27.0.0",
33
27
  "jest": "^27.0.0",
34
- "jest-html-reporter": "^3.5.0",
28
+ "jest-html-reporter": "^3.6.0",
29
+ "path": "^0.12.7",
35
30
  "puppeteer": "^13.7.0",
36
31
  "ts-jest": "^27.0.0",
32
+ "ts-loader": "^9.2.6",
33
+ "typescript": "^4.4.4",
34
+ "webpack": "^5.59.1",
35
+ "webpack-cli": "^4.9.1",
36
+ "@typescript-eslint/eslint-plugin": "^5.11.0",
37
+ "@typescript-eslint/parser": "^5.11.0",
38
+ "eslint": "^8.18.0",
39
+ "eslint-config-google": "^0.14.0",
37
40
  "@types/js-yaml": "^4.0.5",
38
- "@types/node-fetch": "^2.6.1"
41
+ "js-yaml": "^4.1.0",
42
+ "@types/node-fetch": "^2.6.2",
43
+ "node-fetch": "^2.6.7"
39
44
  },
40
45
  "scripts": {
41
46
  "link-all": "npm link datagrok-api @datagrok-libraries/utils @datagrok-libraries/bio",
@@ -51,7 +56,7 @@
51
56
  "release-helm-public": "grok publish public --release",
52
57
  "lint": "eslint \"./src/**/*.ts\"",
53
58
  "lint-fix": "eslint \"./src/**/*.ts\" --fix",
54
- "test": "set HOST=dev && jest",
59
+ "test": "jest",
55
60
  "test-dev": "set HOST=dev && jest",
56
61
  "test-local": "set HOST=localhost && jest"
57
62
  },
@@ -5,7 +5,7 @@
5
5
  import * as utils from './test-node';
6
6
  import puppeteer from 'puppeteer';
7
7
 
8
- const P_START_TIMEOUT: number = 100000;
8
+ const P_START_TIMEOUT: number = 3600000;
9
9
  let browser: puppeteer.Browser;
10
10
  let page: puppeteer.Page;
11
11
 
@@ -51,10 +51,10 @@ it('TEST', async () => {
51
51
  let failReport = '';
52
52
  for (let i = 0; i < df.rowCount; i++) {
53
53
  if (cStatus.get(i)) {
54
- passReport += `Test result : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
54
+ passReport += `Test result : Success : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
55
55
  } else {
56
56
  failed = true;
57
- failReport += `Test result : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
57
+ failReport += `Test result : Failed : ${targetPackage}.${cCat.get(i)}.${cName.get(i)} : ${cMessage.get(i)}\n`;
58
58
  }
59
59
  }
60
60
  resolve({failReport, passReport, failed});
@@ -65,4 +65,4 @@ it('TEST', async () => {
65
65
  console.log(r.passReport);
66
66
  // @ts-ignore
67
67
  expect(r.failed).checkOutput(false, r.failReport);
68
- }, 100000);
68
+ }, 3600000);
@@ -66,6 +66,7 @@ export async function getBrowserPage(puppeteer: any): Promise<{browser: any, pag
66
66
  });
67
67
 
68
68
  let page = await browser.newPage();
69
+ await page.setDefaultNavigationTimeout(0);
69
70
  await page.goto(`${url}/oauth/`);
70
71
  await page.setCookie({name: 'auth', value: token});
71
72
  await page.evaluate((token: any) => {
@@ -73,8 +74,8 @@ export async function getBrowserPage(puppeteer: any): Promise<{browser: any, pag
73
74
  }, token);
74
75
  await page.goto(url);
75
76
  try {
76
- await page.waitForSelector('.grok-preloader');
77
- await page.waitForFunction(() => document.querySelector('.grok-preloader') == null, {timeout: 100000});
77
+ await page.waitForSelector('.grok-preloader', { timeout: 1800000 });
78
+ await page.waitForFunction(() => document.querySelector('.grok-preloader') == null, {timeout: 3600000});
78
79
  } catch (error) {
79
80
  throw error;
80
81
  }
@@ -11,7 +11,6 @@ export {tests};
11
11
  //input: string category {optional: true}
12
12
  //input: string test {optional: true}
13
13
  //output: dataframe result
14
- //top-menu: Tools | Dev | JS API Tests
15
14
  export async function test(category: string, test: string): Promise<DG.DataFrame> {
16
15
  const data = await runTests({category, test});
17
16
  return DG.DataFrame.fromObjects(data)!;
package/src/package.ts CHANGED
@@ -2,17 +2,15 @@
2
2
  import * as grok from 'datagrok-api/grok';
3
3
  import * as ui from 'datagrok-api/ui';
4
4
  import * as DG from 'datagrok-api/dg';
5
- //import {lru} from '../../Bio/src/utils/cell-renderer';
6
5
  import {NotationConverter} from '@datagrok-libraries/bio/src/utils/notation-converter';
7
- import {NOTATION} from '@datagrok-libraries/bio/src/utils/units-handler';
8
- import {WebLogo} from '@datagrok-libraries/bio/src/viewers/web-logo';
9
6
  import {createJsonMonomerLibFromSdf} from './utils';
10
7
  import {MONOMER_MANAGER_MAP, RGROUPS, RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from './constants';
11
- //import {ConverterFunc, DfReaderFunc} from '../../Bio/src/tests/types';
8
+ import {printLeftOrCentered} from '@datagrok-libraries/bio/src/utils/cell-renderer';
12
9
 
13
10
  export const _package = new DG.Package();
14
11
 
15
12
  const lru = new DG.LruCache<any, any>();
13
+ const molfiles = new DG.LruCache<any, any>();
16
14
  const STORAGE_NAME = 'Libraries';
17
15
  let i = 0;
18
16
  const LIB_PATH = 'libraries/';
@@ -25,22 +23,24 @@ export async function initHelm(): Promise<void> {
25
23
  await monomerManager(await grok.dapi.userDataStorage.getValue(STORAGE_NAME, j.toString(), true));
26
24
  }
27
25
  grid.invalidate();
26
+
27
+ return new Promise((resolve, reject) => {
28
+ // @ts-ignore
29
+ dojo.ready(function() { resolve(null); });
30
+ });
28
31
  }
29
32
 
30
- //name: initHelp
31
- export function initHelp() {
32
- return;
33
+ //name: helmCellRenderer
34
+ //tags: cellRenderer
35
+ //meta.cellType: helm
36
+ //meta.columnTags: units=helm
37
+ //output: grid_cell_renderer result
38
+ export function helmCellRenderer(): HelmCellRenderer {
39
+ return new HelmCellRenderer();
33
40
  }
34
41
 
35
- //name: getLru
36
- export async function getLru() {
37
- return await grok.functions.call('Bio:Lru');
38
- }
39
42
 
40
- //tags: cellEditor
41
- //description: Macromolecule
42
- //input: grid_cell cell
43
- export function editMoleculeCell(cell: DG.GridCell): void {
43
+ export function webEditor(value: string) {
44
44
  let view = ui.div();
45
45
  org.helm.webeditor.MolViewer.molscale = 0.8;
46
46
  let app = new scil.helm.App(view, {
@@ -65,55 +65,72 @@ export function editMoleculeCell(cell: DG.GridCell): void {
65
65
  scil.apply(app.properties.parent.style, s);
66
66
  app.structureview.resize(sizes.rightwidth, sizes.bottomheight + app.toolbarheight);
67
67
  app.mex.resize(sizes.topheight - 80);
68
- if (cell.gridColumn.column.tags[DG.TAGS.UNITS] === 'HELM') {
69
- setTimeout(function() {
70
- app.canvas.helm.setSequence(cell.cell.value, 'HELM');
71
- }, 200);
72
- //@ts-ignore
73
- ui.dialog({showHeader: false, showFooter: true})
74
- .add(view)
75
- .onOK(() => {
76
- const val = app.canvas.getHelm(true).replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
77
- cell.cell.value = val;
78
- }).show({modal: true, fullScreen: true});
79
- } else if (cell.gridColumn.column.tags[DG.TAGS.UNITS] === 'fasta:SEQ:PT') {
80
- const converter = new NotationConverter(cell.gridColumn.column);
81
- const resStr = converter.convertStringToHelm(cell.cell.value, '-');
82
- setTimeout(function() {
83
- app.canvas.helm.setSequence(resStr, 'HELM');
84
- }, 200);
85
- //@ts-ignore
86
- ui.dialog({showHeader: false, showFooter: true})
87
- .add(view)
88
- .onOK(() => {
89
- cell.cell.value;
90
- }).show({modal: true, fullScreen: true});
68
+ setTimeout(function() {
69
+ app.canvas.helm.setSequence(value, 'HELM');
70
+ }, 200);
71
+ //@ts-ignore
72
+ ui.dialog({showHeader: false, showFooter: true})
73
+ .add(view)
74
+ .onOK(() => {
75
+ const val = app.canvas.getHelm(true).replace(/<\/span>/g, '').replace(/<span style='background:#bbf;'>/g, '');
76
+ value = val;
77
+ }).show({modal: true, fullScreen: true});
78
+ }
79
+
80
+
81
+ //tags: cellEditor
82
+ //description: Macromolecule
83
+ //input: grid_cell cell
84
+ export function editMoleculeCell(cell: DG.GridCell): void {
85
+ if (cell.gridColumn.column.tags[DG.TAGS.UNITS] === 'helm') {
86
+ let grid = grok.shell.tv.grid;
87
+ webEditor(cell.cell.value);
88
+ grid.invalidate();
91
89
  }
92
90
  }
93
91
 
94
- //name: Details
92
+ //name: Open Helm Web Editor
93
+ //description: Adds editor
94
+ //meta.action: Open Helm Web Editor
95
+ //input: string mol { semType: Macromolecule }
96
+ export function openEditor(mol: string): void {
97
+ let df = grok.shell.tv.grid.dataFrame;
98
+ let converter = new NotationConverter(df.columns.bySemType('Macromolecule'));
99
+ const resStr = converter.convertStringToHelm(mol, '/');
100
+ webEditor(resStr);
101
+ }
102
+
103
+ //name: Properties
95
104
  //tags: panel, widgets
96
105
  //input: string helmString {semType: Macromolecule}
97
106
  //output: widget result
98
- export async function detailsPanel(helmString: string) {
99
- const lru = await getLru();
107
+ export async function propertiesPanel(helmString: string) {
108
+ //const lru = await getLru();
100
109
  const result = lru.get(helmString).split(',');
101
110
  return new DG.Widget(
102
111
  ui.tableFromMap({
103
112
  'formula': result[0].replace(/<sub>/g, '').replace(/<\/sub>/g, ''),
104
113
  'molecular weight': result[1],
105
114
  'extinction coefficient': result[2],
106
- 'molfile': result[3],
107
- 'fasta': ui.wait(async () => ui.divText(await helmToFasta(helmString))),
115
+ /*'fasta': ui.wait(async () => ui.divText(await helmToFasta(helmString))),
108
116
  'rna analogue sequence': ui.wait(async () => ui.divText(await helmToRNA(helmString))),
109
117
  'smiles': ui.wait(async () => ui.divText(await helmToSmiles(helmString))),
110
- //'peptide analogue sequence': ui.wait(async () => ui.divText(await helmToPeptide(helmString))),
118
+ //'peptide analogue sequence': ui.wait(async () => ui.divText(await helmToPeptide(helmString))),*/
111
119
  })
112
120
  );
113
121
  }
114
122
 
123
+ //name: Molfile
124
+ //tags: panel, widgets
125
+ //input: string helmString {semType: Macromolecule}
126
+ //output: widget result
127
+ export async function molfilePanel(helmString: string) {
128
+ return ui.textInput('', await getMolfile(helmString));
129
+ }
130
+
115
131
 
116
- async function loadDialog() {
132
+ //name: loadDialog
133
+ export async function loadDialog() {
117
134
  let res = (await _package.files.list(`${LIB_PATH}`, false, '')).map(it => it.fileName);
118
135
  let FilesList = await ui.choiceInput('Monomer Libraries', ' ', res);
119
136
  let grid = grok.shell.tv.grid;
@@ -159,7 +176,7 @@ export async function libraryPanel(helmColumn: DG.Column) {
159
176
  }
160
177
 
161
178
  //name: manageFiles
162
- function manageFiles() {
179
+ export async function manageFiles() {
163
180
  const a = ui.dialog({title: 'Manage files'})
164
181
  //@ts-ignore
165
182
  .add(ui.fileBrowser({path: 'System:AppData/Helm/libraries'}).root)
@@ -167,6 +184,8 @@ function manageFiles() {
167
184
  .show();
168
185
  }
169
186
 
187
+
188
+
170
189
  async function accessServer(url: string, key: string) {
171
190
  const params: RequestInit = {
172
191
  method: 'GET',
@@ -238,12 +257,22 @@ function getRS(smiles: string) {
238
257
  return res;
239
258
  }
240
259
 
241
- async function monomerManager(value: string) {
260
+ //name: monomerManager
261
+ //input: string value
262
+ export async function monomerManager(value: string) {
242
263
  let df: any[];
264
+ let file;
265
+ let dfSdf;
243
266
  if (value.endsWith('.sdf')) {
244
- const file = await _package.files.readAsBytes(`${LIB_PATH}${value}`);
245
- const dfSdf = await grok.functions.call('Chem:importSdf', {bytes: file});
246
- df = createJsonMonomerLibFromSdf(dfSdf[0]);
267
+ const funcList: DG.Func[] = DG.Func.find({package: 'Chem', name: 'importSdf'});
268
+ console.debug(`Helm: initHelm() funcList.length = ${funcList.length}`);
269
+ if (funcList.length === 1) {
270
+ file = await _package.files.readAsBytes(`${LIB_PATH}${value}`);
271
+ dfSdf = await grok.functions.call('Chem:importSdf', {bytes: file});
272
+ df = createJsonMonomerLibFromSdf(dfSdf[0]);
273
+ } else {
274
+ grok.shell.warning("Chem package is not installed");
275
+ }
247
276
  } else {
248
277
  const file = await _package.files.readAsText(`${LIB_PATH}${value}`);
249
278
  df = JSON.parse(file);
@@ -275,28 +304,161 @@ export function helmColumnToSmiles(helmColumn: DG.Column) {
275
304
  //todo: add column with smiles to col.dataFrame.
276
305
  }
277
306
 
307
+ //name: getMolfile
308
+ //input: string helmString {semType: Macromolecule}
309
+ export async function getMolfile(helmString) {
310
+ return molfiles.get(helmString);
311
+ }
312
+
313
+ function split(s: string, sep: string) {
314
+ var ret = [];
315
+ var frag = "";
316
+ var parentheses = 0;
317
+ var bracket = 0;
318
+ var braces = 0;
319
+ var quote = 0;
320
+ for (var i = 0; i < s.length; ++i) {
321
+ var c = s.substring(i, i + 1);
322
+ if (c == sep && bracket == 0 && parentheses == 0 && braces == 0 && quote == 0) {
323
+ ret.push(frag);
324
+ frag = "";
325
+ }
326
+ else {
327
+ frag += c;
328
+ if (quote > 0) {
329
+ if (c == '\\' && i + 1 < s.length) {
330
+ ++i;
331
+ var c2 = s.substring(i, i + 1);
332
+ frag += c2;
333
+ c += c2;
334
+ }
335
+ }
336
+ if (c == '\"') {
337
+ if (!(i > 0 && s.substring(i - 1, i) == '\\'))
338
+ quote = quote == 0 ? 1 : 0;
339
+ }
340
+ else if (c == '[')
341
+ ++bracket;
342
+ else if (c == ']')
343
+ --bracket;
344
+ else if (c == '(')
345
+ ++parentheses;
346
+ else if (c == ')')
347
+ --parentheses;
348
+ else if (c == '{')
349
+ ++braces;
350
+ else if (c == '}')
351
+ --braces;
352
+ }
353
+ }
354
+ ret.push(frag);
355
+ return ret;
356
+ }
357
+
358
+ function detachAnnotation(s: string) {
359
+ var ret = _detachAppendix(s, '\"');
360
+ if (ret.tag != null)
361
+ return ret;
362
+
363
+ var r = _detachAppendix(s, '\'');
364
+ return { tag: ret.tag, repeat: r.tag, str: r.str };
365
+ }
366
+
367
+ function _detachAppendix(s: string, c: string) {
368
+ var tag = null;
369
+ //@ts-ignore
370
+ if (scil.Utils.endswith(s, c)) {
371
+ var p = s.length - 1;
372
+ while (p > 0) {
373
+ p = s.lastIndexOf(c, p - 1);
374
+ if (p <= 0 || s.substring(p - 1, p) != '\\')
375
+ break;
376
+ }
377
+
378
+ if (p > 0 && p < s.length - 1) {
379
+ tag = s.substring(p + 1, s.length - 1);
380
+ s = s.substring(0, p);
381
+ }
382
+ }
383
+ if (tag != null)
384
+ tag = tag.replace(new RegExp("\\" + c, "g"), c);
385
+ return { tag: unescape(tag), str: s };
386
+ }
387
+
388
+ function unescape(s: string) {
389
+ //@ts-ignore
390
+ if (scil.Utils.isNullOrEmpty(s))
391
+ return s;
392
+
393
+ return s.replace(/[\\]./g, function (m) {
394
+ switch (m) {
395
+ case "\\r":
396
+ return "\r";
397
+ case "\\n":
398
+ return "\n";
399
+ case "\\t":
400
+ return "\t";
401
+ default:
402
+ return m.substring(1);
403
+ }
404
+ });
405
+ }
406
+
407
+ function parseHelm(s: string) {
408
+ var sections = split(s, '$');
409
+ s = sections[0];
410
+ var monomers = [];
411
+ //@ts-ignore
412
+ if (!scil.Utils.isNullOrEmpty(s)) {
413
+ var seqs = split(s, '|');
414
+ for (var i = 0; i < seqs.length; ++i) {
415
+ var e = detachAnnotation(seqs[i]);
416
+ s = e.str;
417
+
418
+ var p = s.indexOf("{");
419
+
420
+ s = s.substring(p + 1);
421
+ p = s.indexOf('}');
422
+ s = s.substring(0, p);
423
+
424
+ var ss = split(s, '.');
425
+ for (var monomer of ss) {
426
+ if (monomer.includes('(') && monomer.includes(')')) {
427
+ var elements = monomer.replace(/[()]/g, "").split("");
428
+ for (var el of elements) {
429
+ monomers.push(el);
430
+ }
431
+ } else {
432
+ monomers.push(monomer);
433
+ }
434
+ }
435
+ }
436
+ }
437
+ return monomers;
438
+ }
439
+
278
440
  //name: findMonomers
279
- //input: string helmString { semType: Macromolecule }
280
- export async function findMonomers(helmString: string) {
441
+ //input: string helmString
442
+ export function findMonomers(helmString: string) {
443
+ //@ts-ignore
281
444
  const types = Object.keys(org.helm.webeditor.monomerTypeList());
282
- const monomers = [];
283
- const monomerNames = [];
284
- for (let i = 0; i < types.length; i++) {
285
- // Synonym to overcome eslint error
286
- const GetMonomerSet = scil.helm.Monomers.getMonomerSet;
287
- monomers.push(new GetMonomerSet(types[i]));
288
- Object.keys(monomers[i]).forEach((k) => {
289
- monomerNames.push(monomers[i][k].id);
445
+ const monomers: any = [];
446
+ const monomer_names: any = [];
447
+ for (var i = 0; i < types.length; i++) {
448
+ //@ts-ignore
449
+ monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));
450
+ Object.keys(monomers[i]).forEach(k => {
451
+ monomer_names.push(monomers[i][k].id);
290
452
  });
291
453
  }
292
- const splitString = WebLogo.splitterAsHelm(helmString);
293
- return new Set(splitString.filter((val) => !monomerNames.includes(val)));
454
+ const split_string = parseHelm(helmString);
455
+ return new Set(split_string.filter(val => !monomer_names.includes(val)));
294
456
  }
295
457
 
296
458
  class HelmCellRenderer extends DG.GridCellRenderer {
297
- get name() { return 'macromolecule'; }
459
+ get name() { return 'helm'; }
298
460
 
299
- get cellType() { return 'macromolecule'; }
461
+ get cellType() { return 'helm'; }
300
462
 
301
463
  get defaultWidth(): number | null { return 400; }
302
464
 
@@ -305,18 +467,49 @@ class HelmCellRenderer extends DG.GridCellRenderer {
305
467
  render(g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
306
468
  gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
307
469
  ) {
308
- const host = ui.div([], {style: {width: `${w}px`, height: `${h}px`}});
309
- host.setAttribute('dataformat', 'helm');
310
- host.setAttribute('data', gridCell.cell.value);
311
-
312
- gridCell.element = host;
313
- const canvas = new JSDraw2.Editor(host, {width: w, height: h, skin: 'w8', viewonly: true});
314
- const formula = canvas.getFormula(true);
315
- const molWeight = Math.round(canvas.getMolWeight() * 100) / 100;
316
- const coef = Math.round(canvas.getExtinctionCoefficient(true) * 100) / 100;
317
- const molfile = canvas.getMolfile();
318
- const result = formula + ', ' + molWeight + ', ' + coef + ', ' + molfile;
319
- lru.set(gridCell.cell.value, result);
470
+ const grid = gridCell.gridRow !== -1 ? gridCell.grid : undefined;
471
+ const undefinedColor = 'rgb(100,100,100)';
472
+ const grayColor = '#808080';
473
+ const monomers = findMonomers(gridCell.cell.value);
474
+ if (monomers.size == 0) {
475
+ const host = ui.div([], {style: {width: `${w}px`, height: `${h}px`}});
476
+ host.setAttribute('dataformat', 'helm');
477
+ host.setAttribute('data', gridCell.cell.value);
478
+ gridCell.element = host;
479
+ //@ts-ignore
480
+ const canvas = new JSDraw2.Editor(host, {width: w, height: h, skin: 'w8', viewonly: true});
481
+ const formula = canvas.getFormula(true);
482
+ if (!formula) {
483
+ gridCell.element = ui.divText(gridCell.cell.value, {style: {color: 'red'}});
484
+ }
485
+ const molWeight = Math.round(canvas.getMolWeight() * 100) / 100;
486
+ const coef = Math.round(canvas.getExtinctionCoefficient(true) * 100) / 100;
487
+ const molfile = canvas.getMolfile();
488
+ const result = formula + ', ' + molWeight + ', ' + coef;
489
+ lru.set(gridCell.cell.value, result);
490
+ molfiles.set(gridCell.cell.value, molfile);
491
+ return;
492
+ }
493
+ if (monomers.size > 0) {
494
+ w = grid ? Math.min(grid.canvas.width - x, w) : g.canvas.width - x;
495
+ g.save();
496
+ g.beginPath();
497
+ g.rect(x, y, w, h);
498
+ g.clip();
499
+ g.font = '12px monospace';
500
+ g.textBaseline = 'top';
501
+ let x1 = x;
502
+ const s: string = gridCell.cell.value ?? '';
503
+ let subParts: string[] = parseHelm(s);
504
+ subParts.forEach((amino, index) => {
505
+ let color = monomers.has(amino) ? 'red' : grayColor;
506
+ g.fillStyle = undefinedColor;
507
+ let last = index === subParts.length - 1;
508
+ x1 = printLeftOrCentered(x1, y, w, h, g, amino, color, 0, true, 1.0, '/', last);
509
+ });
510
+ g.restore();
511
+ return;
512
+ }
320
513
  }
321
514
  }
322
515
 
@@ -1,13 +1,13 @@
1
- import {before, category, expect, test} from '@datagrok-libraries/utils/src/test';
2
- import {helmToFasta, helmToPeptide, helmToRNA} from '../package';
1
+ import {after, before, category, delay, expect, test} from '@datagrok-libraries/utils/src/test';
2
+ //import {findMonomers, helmToFasta, helmToPeptide, helmToRNA, initHelm} from '../package';
3
3
  import {_package} from '../package-test';
4
+ import {loadDialog, manageFiles, monomerManager} from '../package';
4
5
  import * as DG from 'datagrok-api/dg';
5
6
  import * as grok from 'datagrok-api/grok';
6
7
 
7
8
 
8
9
  category('Helm', () => {
9
-
10
- // These tests require webservice that is not present on test stand
10
+ //These tests require webservice that is not present on test stand
11
11
  // test('helmToFasta', async () => {
12
12
  // expect(await helmToFasta('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), '>RNA1UTGCA');
13
13
  // expect(await helmToFasta('RNA1{P.R(U).P.R(T)}$$$$'), '>RNA1UT');
@@ -45,4 +45,32 @@ category('Helm', () => {
45
45
  // await grok.data.detectSemanticTypes(df);
46
46
  // expect(col.tags[DG.TAGS.UNITS], 'HELM');
47
47
  // });
48
+
49
+
50
+ test('manageFiles', async () => {
51
+ return await manageFiles();
52
+ });
53
+
54
+ test('loadDialog', async() => {
55
+ return await grok.functions.call('Helm:loadDialog');
56
+ });
57
+
58
+ test('monomerManager', async() => {
59
+ await grok.functions.call('Helm:monomerManager', {value: 'HELMCoreLibrary.json'});
60
+ const checkName = '2-Chloroadenine';
61
+ let flag = false;
62
+ const types = Object.keys(org.helm.webeditor.monomerTypeList());
63
+ const monomers: any = [];
64
+ for (var i = 0; i < types.length; i++) {
65
+ //@ts-ignore
66
+ monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));
67
+ Object.keys(monomers[i]).forEach(k => {
68
+ if (monomers[i][k].n == checkName){
69
+ flag = true;
70
+ }
71
+ });
72
+ }
73
+ expect(flag, true);
74
+ });
75
+
48
76
  });