@datagrok/bio 2.12.12 → 2.12.13

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/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "Aleksandr Tanas",
6
6
  "email": "atanas@datagrok.ai"
7
7
  },
8
- "version": "2.12.12",
8
+ "version": "2.12.13",
9
9
  "description": "Bioinformatics support (import/export of sequences, conversion, visualization, analysis). [See more](https://github.com/datagrok-ai/public/blob/master/packages/Bio/README.md) for details.",
10
10
  "repository": {
11
11
  "type": "git",
@@ -34,12 +34,12 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@biowasm/aioli": "^3.1.0",
37
- "@datagrok-libraries/bio": "^5.40.6",
38
- "@datagrok-libraries/chem-meta": "^1.2.4",
37
+ "@datagrok-libraries/bio": "^5.40.8",
38
+ "@datagrok-libraries/chem-meta": "^1.2.5",
39
+ "@datagrok-libraries/math": "^1.1.1",
39
40
  "@datagrok-libraries/ml": "^6.6.0",
40
41
  "@datagrok-libraries/tutorials": "^1.3.12",
41
42
  "@datagrok-libraries/utils": "^4.2.0",
42
- "@datagrok-libraries/math": "^1.1.1",
43
43
  "@webgpu/types": "^0.1.40",
44
44
  "ajv": "^8.12.0",
45
45
  "ajv-errors": "^3.0.0",
@@ -103,7 +103,8 @@
103
103
  "All users"
104
104
  ],
105
105
  "sources": [
106
- "css/helm.css"
106
+ "css/helm.css",
107
+ "common/openchemlib-full.js"
107
108
  ],
108
109
  "category": "Bioinformatics",
109
110
  "meta": {
@@ -1,7 +1,11 @@
1
1
  import * as grok from 'datagrok-api/grok';
2
2
  import * as DG from 'datagrok-api/dg';
3
+ import * as ui from 'datagrok-api/ui';
3
4
 
4
- import {category, expect, test, delay} from '@datagrok-libraries/utils/src/test';
5
+ import $ from 'cash-dom';
6
+ import {fromEvent} from 'rxjs';
7
+
8
+ import {category, expect, test, delay, testEvent} from '@datagrok-libraries/utils/src/test';
5
9
  import {ALIGNMENT, ALPHABET, NOTATION, TAGS as bioTAGS} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
10
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
7
11
 
@@ -12,6 +16,8 @@ import {multipleSequenceAlignmentUI} from '../utils/multiple-sequence-alignment-
12
16
  import {awaitGrid} from './utils';
13
17
  import * as C from '../utils/constants';
14
18
 
19
+ import {_package} from '../package-test';
20
+
15
21
  category('renderers', () => {
16
22
  test('long sequence performance ', async () => {
17
23
  await performanceTest(generateLongSequence, 'Long sequences');
@@ -48,6 +54,10 @@ category('renderers', () => {
48
54
  await _selectRendererBySemType();
49
55
  });
50
56
 
57
+ test('scatterPlotTooltip', async () => {
58
+ await _testScatterPlotTooltip();
59
+ });
60
+
51
61
  async function _rendererMacromoleculeFasta() {
52
62
  const csv: string = await grok.dapi.files.readAsText('System:AppData/Bio/samples/FASTA.csv');
53
63
  const df: DG.DataFrame = DG.DataFrame.fromCsv(csv);
@@ -197,4 +207,40 @@ category('renderers', () => {
197
207
  `view renderer has set to '${renderer}' instead of correct 'MacromoleculeDifference'.`);
198
208
  }
199
209
  }
210
+
211
+ const seqCoordsCsv = `seq,x,y
212
+ ACGGTGTCGT,0,0
213
+ CGGTATCCCT,1,0
214
+ CTCGGCATGC,2,0
215
+ `;
216
+
217
+ async function _testScatterPlotTooltip(): Promise<void> {
218
+ const df = DG.DataFrame.fromCsv(seqCoordsCsv);
219
+ df.currentRowIdx = 0;
220
+ const view = grok.shell.addTableView(df);
221
+ const sp: DG.ScatterPlotViewer = df.plot.scatter({x: 'x', y: 'y'});
222
+ view.dockManager.dock(sp, DG.DOCK_TYPE.RIGHT, null);
223
+ await Promise.all([
224
+ testEvent(sp.onAfterDrawScene, () => {}, () => { sp.invalidateCanvas(); }, 1000),
225
+ awaitGrid(view.grid, 500)
226
+ ]);
227
+
228
+ const spBcr = sp.root.getBoundingClientRect();
229
+ const wp = sp.worldToScreen(1, 0);
230
+ const ev = new MouseEvent('mousemove', {
231
+ cancelable: true, bubbles: true, view: window, button: 0,
232
+ clientX: spBcr.left + wp.x, clientY: spBcr.top + wp.y
233
+ });
234
+ const spCanvas = $(sp.root).find('canvas').get()[0] as HTMLCanvasElement;
235
+ await testEvent(fromEvent(spCanvas, 'mousemove'), () => {
236
+ _package.logger.debug(`Test: event, currentRowIdx=${df.currentRowIdx}`);
237
+ expect($(ui.tooltip.root).find('div table.d4-row-tooltip-table tr td canvas').length, 1);
238
+ expect(sp.hitTest(wp.x, wp.y), 1);
239
+ }, () => {
240
+ spCanvas.dispatchEvent(ev);
241
+ }, 500);
242
+ // TODO: Any error occurred become 'Cannot read properties of null (reading 'get$columns')' because of scatter plot
243
+ //await testEvent(sp.onAfterDrawScene, () => {}, () => { sp.invalidateCanvas(); }, 200);
244
+ await awaitGrid(view.grid, 500);
245
+ }
200
246
  });
@@ -59,6 +59,31 @@ export function processSequence(subParts: string[]): [string[], boolean] {
59
59
  return [text, simplified];
60
60
  }
61
61
 
62
+ type RendererGridCellTemp = {
63
+ [mmcrTemps.monomerPlacer]: MonomerPlacer
64
+ }
65
+
66
+ function getRendererFridCellTempTemp(gridCell: DG.GridCell): RendererGridCellTemp {
67
+ /** Primarily store/get MonomerPlacer at GridColumn, fallback at (Table) Column for scatter plot tooltip */
68
+ let temp: RendererGridCellTemp | null = null;
69
+
70
+ let gridCol: DG.GridColumn | null = null;
71
+ try { gridCol = gridCell.gridColumn; } catch { gridCol = null; }
72
+ temp = gridCol && gridCol.dart ? gridCol.temp as RendererGridCellTemp : null;
73
+
74
+ if (!temp) {
75
+ let tableCol: DG.Column | null = null;
76
+ try { tableCol = gridCell.cell.column; } catch { tableCol = null; }
77
+ if (!tableCol) {
78
+ const k = 42;
79
+ }
80
+ temp = tableCol ? tableCol.temp as RendererGridCellTemp : null;
81
+ }
82
+ if (temp === null)
83
+ throw new Error(`Monomer placer store (GridColumn or Column) not found.`);
84
+ return temp;
85
+ }
86
+
62
87
  export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
63
88
  private padding: number = 5;
64
89
 
@@ -82,7 +107,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
82
107
 
83
108
  const tableCol: DG.Column = gridCell.cell.column;
84
109
  //const tableColTemp: TempType = tableCol.temp;
85
- const seqColTemp: MonomerPlacer = gridCell.gridColumn.temp[mmcrTemps.monomerPlacer];
110
+ const seqColTemp: MonomerPlacer = getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer];
86
111
  if (!seqColTemp) return; // Can do nothing without precalculated data
87
112
 
88
113
  const gridCellBounds: DG.Rect = gridCell.bounds;
@@ -165,7 +190,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
165
190
  (!isNaN(tagMaxMonomerLength) ? tagMaxMonomerLength : _package.properties?.MaxMonomerLength) ?? 4;
166
191
  }
167
192
 
168
- let seqColTemp: MonomerPlacer = gridCell.gridColumn.temp[mmcrTemps.monomerPlacer];
193
+ let seqColTemp: MonomerPlacer = getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer];
169
194
  if (!seqColTemp) {
170
195
  seqColTemp = new MonomerPlacer(grid, tableCol,
171
196
  () => {
@@ -192,7 +217,7 @@ export class MacromoleculeSequenceCellRenderer extends DG.GridCellRenderer {
192
217
  const _maxIndex = maxLengthWords.length;
193
218
 
194
219
  // Store updated seqColTemp to the col temp
195
- if (seqColTemp.updated) gridCell.gridColumn.temp[mmcrTemps.monomerPlacer] = seqColTemp;
220
+ if (seqColTemp.updated) getRendererFridCellTempTemp(gridCell)[mmcrTemps.monomerPlacer] = seqColTemp;
196
221
 
197
222
  g.save();
198
223
  try {
@@ -1,29 +1,4 @@
1
1
  export const HELM_ITEM_SEPARATOR = '|';
2
2
  export const HELM_SECTION_SEPARATOR = '$';
3
- export const HYDROGEN_SYMBOL = 'H';
4
- export const R_GROUP_ELEMENT_SYMBOL = 'R#';
5
-
6
- export const enum V2K_CONST {
7
- MAX_ATOM_COUNT = 999,
8
- RGP_LINE_START = 'M RGP',
9
- ATOM_ALIAS_LINE_START = 'A ',
10
- }
11
-
12
- export const enum V3K_CONST {
13
- HEADER = `
14
- RDKit 2D
15
-
16
- 0 0 0 0 0 0 0 0 0 0999 V3000`,
17
- BEGIN_CTAB = 'M V30 BEGIN CTAB',
18
- COUNTS_LINE_START = 'M V30 COUNTS ',
19
- COUNTS_LINE_END = ' 0 0 0',
20
- BEGIN_ATOM_BLOCK = 'M V30 BEGIN ATOM',
21
- END_ATOM_BLOCK = 'M V30 END ATOM',
22
- BEGIN_BOND_BLOCK = 'M V30 BEGIN BOND',
23
- END_BOND_BLOCK = 'M V30 END BOND',
24
- BEGIN_COLLECTION_BLOCK = 'M V30 BEGIN COLLECTION',
25
- END_COLLECTION_BLOCK = 'M V30 END COLLECTION',
26
- END_CTAB = 'M V30 END CTAB',
27
- END = 'M END\n',
28
- }
29
3
 
4
+ export const HYDROGEN_SYMBOL = 'H';
@@ -1,4 +1,4 @@
1
- import {R_GROUP_ELEMENT_SYMBOL} from './const';
1
+ import {R_GROUP_ELEMENT_SYMBOL} from '@datagrok-libraries/chem-meta/src/formats/molfile-const';
2
2
 
3
3
  export abstract class MolfileAtoms {
4
4
  protected coordinates: {x: number, y: number}[] = [];
@@ -1,5 +1,5 @@
1
1
  import {RDModule} from '@datagrok-libraries/chem-meta/src/rdkit-api';
2
- import {V2K_CONST, V3K_CONST} from './const';
2
+ import {V3K_CONST} from '@datagrok-libraries/chem-meta/src/formats/molfile-const';
3
3
  import {Helm} from './helm';
4
4
  import {MonomerWrapper} from './monomer-wrapper';
5
5
 
@@ -44,7 +44,6 @@ export class Polymer {
44
44
  }
45
45
 
46
46
  compileToMolfile(): string {
47
- const molfileHeader = '\nDatagrok\n';
48
47
  const atomLines: string[] = [];
49
48
  const bondLines: string[] = [];
50
49
 
@@ -73,8 +72,8 @@ export class Polymer {
73
72
  }
74
73
 
75
74
  private getV3KHeader(atomCount: number, bondCount: number): string {
76
- const countsLine = `${V3K_CONST.COUNTS_LINE_START}${atomCount} ${bondCount}${V3K_CONST.COUNTS_LINE_END}`;
77
- return `${V3K_CONST.HEADER}\n${V3K_CONST.BEGIN_CTAB}\n${countsLine}`;
75
+ const countsLine = `${V3K_CONST.COUNTS_LINE_START}${atomCount} ${bondCount}${V3K_CONST.COUNTS_LINE_DUMMY_END}`;
76
+ return `${V3K_CONST.DUMMY_HEADER}\n${V3K_CONST.BEGIN_CTAB}\n${countsLine}`;
78
77
  }
79
78
 
80
79
  private getV3KAtomBlock(atomLines: string[]): string {
@@ -1,9 +1,5 @@
1
1
  import {HELM_REQUIRED_FIELD} from '@datagrok-libraries/bio/src/utils/const';
2
2
 
3
- export const enum HELM_WRAPPER {
4
- LEFT = 'PEPTIDE1{',
5
- RIGHT = '}$$$$',
6
- }
7
3
  export const ALL_MONOMERS = '<All>';
8
4
 
9
5
  export const enum TRANSFORMATION_TYPE {
@@ -6,12 +6,15 @@ import {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';
6
6
  import {SeqHandler} from '@datagrok-libraries/bio/src/utils/seq-handler';
7
7
  import {ALIGNMENT, ALPHABET} from '@datagrok-libraries/bio/src/utils/macromolecule';
8
8
 
9
- import {HELM_WRAPPER} from './const';
10
9
  import {getMolColumnFromHelm} from '../helm-to-molfile/utils';
11
10
 
12
11
  export const RULES_PATH = 'System:AppData/Bio/polytool-rules/';
13
12
  export const RULES_STORAGE_NAME = 'Polytool';
14
13
 
14
+ const enum HELM_WRAPPER {
15
+ LEFT = 'PEPTIDE1{',
16
+ RIGHT = '}$$$$',
17
+ }
15
18
 
16
19
  type ConnectionData = {
17
20
  allPos1: number[],
@@ -43,19 +46,8 @@ class TransformationCommon {
43
46
  this.helmColumn = helmColumn;
44
47
  }
45
48
 
46
- protected hasTerminals(helm: string): boolean {
47
- let isLinkable = false;
48
- if (helm.includes('(1)'))
49
- isLinkable = true;
50
- if (helm.includes('(2)'))
51
- isLinkable = true;
52
-
53
- return isLinkable;
54
- }
55
-
56
- protected getLinkedPositions(helm: string, rules: Rule[]): [number, number][] {
57
- const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
58
- const monomers = seq.split('.').map((m) => { return m.replace('[', '').replace(']', ''); });
49
+ protected getLinkedPositions(monomers: string[], rules: Rule[]): [number, number][] {
50
+ const monomersNames = monomers.map((m) => { return m.replace('[', '').replace(']', ''); });
59
51
  const result: [number, number][] = new Array<[number, number]>(rules.length);
60
52
 
61
53
  for (let i = 0; i < rules.length; i++) {
@@ -65,14 +57,14 @@ class TransformationCommon {
65
57
  let firstEntryIndex = -1;
66
58
  let secondEntryIndex = -1;
67
59
  const add = `(${rules[i].code})`;
68
- for (let j = 0; j < monomers.length; j++) {
69
- if (monomers[j].includes(add)) {
60
+ for (let j = 0; j < monomersNames.length; j++) {
61
+ if (monomersNames[j].includes(add)) {
70
62
  if (firstFound) {
71
- if (firstIsFirst && monomers[j] == rules[i].secondMonomer + add) {
63
+ if (firstIsFirst && monomersNames[j] == rules[i].secondMonomer + add) {
72
64
  secondFound = true;
73
65
  secondEntryIndex = j;
74
66
  break;
75
- } else if (!firstIsFirst && monomers[j] == rules[i].firstMonomer + add) {
67
+ } else if (!firstIsFirst && monomersNames[j] == rules[i].firstMonomer + add) {
76
68
  secondFound = true;
77
69
  secondEntryIndex = j;
78
70
  break;
@@ -83,11 +75,11 @@ class TransformationCommon {
83
75
  // secondFound = true;
84
76
  // break;
85
77
  } else {
86
- if (monomers[j] == rules[i].firstMonomer + add) {
78
+ if (monomersNames[j] == rules[i].firstMonomer + add) {
87
79
  firstFound = true;
88
80
  firstIsFirst = true;
89
81
  firstEntryIndex = j;
90
- } else if (monomers[j] == rules[i].secondMonomer + add) {
82
+ } else if (monomersNames[j] == rules[i].secondMonomer + add) {
91
83
  firstFound = true;
92
84
  firstIsFirst = false;
93
85
  firstEntryIndex = j;
@@ -141,22 +133,42 @@ class TransformationCommon {
141
133
  return rules;
142
134
  }
143
135
 
144
- protected getTransformedHelm(helm: string, rules: Rule[]): string {
145
- const ruleCount = rules.length;
146
- const positions = this.getLinkedPositions(helm, rules);
136
+ protected getDimeric(helm: string): [string[], [number, number][]] {
137
+ const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
138
+ const monomers = seq.split('.');
139
+ const duplicates: [number, number][] = [];
140
+
141
+ for (let i = 0; i < monomers.length; i++) {
142
+ if (monomers[i].includes('(#2)')) {
143
+ monomers[i] = monomers[i].replace('(#2)', '');
144
+ const duplicateStart = i + 1;
145
+ let duplicateFinish = 0;
146
+ for (let j = duplicateStart + 1; j < monomers.length; j++) {
147
+ if (monomers[j].includes('}')) {
148
+ duplicateFinish = j; break;
149
+ }
150
+ }
151
+ monomers[duplicateStart] = monomers[duplicateStart].replace('{', '');
152
+ monomers[duplicateFinish] = monomers[duplicateFinish].replace('}', '');
153
+ duplicates.push([duplicateStart, duplicateFinish]);
154
+ }
155
+ }
147
156
 
157
+ return [monomers, duplicates];
158
+ }
159
+
160
+ protected getAllCycles(rules: Rule[], monomers: string [], positions: [number, number][]) :
161
+ [string [], number [], number [], number [], number []] {
148
162
  const allPos1: number [] = [];
149
163
  const allPos2: number [] = [];
150
164
  const allAttaches1: number [] = [];
151
165
  const allAttaches2: number [] = [];
166
+ const ruleCount = rules.length;
152
167
 
153
168
  for (let i = 0; i < ruleCount; i++) {
154
169
  if (positions[i][0] == -1)
155
170
  continue;
156
171
 
157
- //helm = helm.replaceAll(`(${i + 1})`, '');
158
- const seq = helm.replace(HELM_WRAPPER.LEFT, '').replace(HELM_WRAPPER.RIGHT, '');
159
- const monomers = seq.split('.');
160
172
  const firstMonomer = monomers[positions[i][0]].replace('[', '').replace(']', '');
161
173
  const secondMonomer = monomers[positions[i][1]].replace('[', '').replace(']', '');
162
174
 
@@ -167,31 +179,97 @@ class TransformationCommon {
167
179
  allPos2.push(positions[i][1] + 1);
168
180
  allAttaches1.push(rules[i].firstR);
169
181
  allAttaches2.push(rules[i].secondR);
182
+ }
170
183
 
171
- helm = HELM_WRAPPER.LEFT;
172
- for (let i = 0; i < monomers.length; i++) {
173
- if (i != monomers.length - 1)
174
- helm = helm + monomers[i] + '.';
175
- else
176
- helm = helm + monomers[i];
177
- }
178
- helm = helm + HELM_WRAPPER.RIGHT;
184
+ return [monomers, allPos1, allPos2, allAttaches1, allAttaches2];
185
+ }
186
+
187
+ protected getHelmCycle(source: ConnectionData, polFirst: number, poSecond: number): string {
188
+ let cycled = '';
189
+
190
+ for (let i = 0; i < source.allPos1.length; i++) {
191
+ if (i == 0)
192
+ cycled += `PEPTIDE${polFirst},PEPTIDE${poSecond},`;
193
+ else
194
+ cycled += `|PEPTIDE${polFirst},PEPTIDE${poSecond},`;
195
+ cycled += `${source.allPos1[i]}:R${source.allAttaches1[i]}-${source.allPos2[i]}:R${source.allAttaches2[i]}`;
179
196
  }
197
+ return cycled;
198
+ }
199
+
200
+ //"PEPTIDE1{[(#2)Succ].[{R].F.[Dab(2)].T.G.H.F.G.A.A.Y.P.[E(2)].[NH2}]}$$$$"
201
+ protected getTransformedHelm(helm: string, rules: Rule[]): string {
202
+ const [monomers, duplicates] = this.getDimeric(helm);
203
+ const positions = this.getLinkedPositions(monomers, rules);
204
+ const [monomersCycled, allPos1, allPos2, allAttaches1, allAttaches2] =
205
+ this.getAllCycles(rules, monomers, positions);
206
+
207
+ helm = 'PEPTIDE1{';
208
+ for (let i = 0; i < monomersCycled.length; i++)
209
+ helm += i != monomersCycled.length - 1 ? monomersCycled[i] + '.' : monomersCycled[i];
210
+
211
+ helm += '}';
212
+
213
+ const dimerCodes = new Array<string>(duplicates.length);
214
+ const cycleCodes = new Array<string>(duplicates.length);
215
+ for (let i = 0; i < duplicates.length; i++) {
216
+ let helmAdd = `|PEPTIDE${i + 2}{`;
217
+ const lengthAdd = duplicates[i][1] - duplicates[i][0];
218
+ //const monomersAdd = new Array<string>(lengthAdd);
219
+ const allPosAdd1: number [] = [];
220
+ const allPosAdd2: number [] = [];
221
+ const allAttachesAdd1: number [] = [];
222
+ const allAttachesAdd2: number [] = [];
223
+
224
+ for (let j = 0; j <= lengthAdd; j ++) {
225
+ const index = j + duplicates[i][0];
226
+ helmAdd += j != lengthAdd ? monomersCycled[index] + '.' : monomersCycled[index];
227
+ }
228
+
229
+ helmAdd += '}';
230
+
231
+ for (let j = 0; j < allPos1.length; j++) {
232
+ if (allPos1[j] - 1 >= duplicates[i][0] && allPos1[j] - 1 <= duplicates[i][1]) {
233
+ allPosAdd1.push(allPos1[j] - duplicates[i][0]);
234
+ allPosAdd2.push(allPos2[j] - duplicates[i][0]);
235
+ allAttachesAdd1.push(allAttaches1[j]);
236
+ allAttachesAdd2.push(allAttaches1[j]);
237
+ }
238
+ }
180
239
 
240
+ const addCyclysation = this.getHelmCycle({
241
+ allPos1: allPosAdd1,
242
+ allPos2: allPosAdd2,
243
+ allAttaches1: allAttachesAdd1,
244
+ allAttaches2: allAttachesAdd2}, i + 2, i + 2);
245
+
246
+ dimerCodes[i] = helmAdd;
247
+ cycleCodes[i] = this.getHelmCycle({
248
+ allPos1: [duplicates[i][0]],
249
+ allPos2: [1],
250
+ allAttaches1: [1],
251
+ allAttaches2: [1]}, 1, i + 2);
252
+ cycleCodes.push(addCyclysation);
253
+ }
181
254
 
182
- const cycledHelm = getHelmCycle(helm, {allPos1, allPos2, allAttaches1, allAttaches2});
255
+ for (let i = 0; i < dimerCodes.length; i++)
256
+ helm += dimerCodes[i];
183
257
 
184
- return cycledHelm;
258
+ helm += '$';
259
+ const mainCyclysation = this.getHelmCycle({allPos1, allPos2, allAttaches1, allAttaches2}, 1, 1);
260
+ helm += mainCyclysation;
261
+ for (let i = 0; i < cycleCodes.length; i++) {
262
+ helm += '|';
263
+ helm += cycleCodes[i];
264
+ }
265
+ helm += '$$$';
266
+ return helm;
185
267
  }
186
268
 
187
269
  transform(rulesTables: DG.DataFrame[]): string[] {
188
270
  const rules = this.getRules(rulesTables);
189
271
  const resultList = this.helmColumn.toList().map((helm: string) => {
190
- if (this.hasTerminals(helm))
191
- return this.getTransformedHelm(helm, rules);
192
-
193
- console.log(helm);
194
- return helm;
272
+ return this.getTransformedHelm(helm, rules);
195
273
  });
196
274
  return resultList;
197
275
  }
@@ -205,21 +283,6 @@ class PolymerTransformation {
205
283
  }
206
284
  }
207
285
 
208
- function getHelmCycle(helm: string, source: ConnectionData): string {
209
- let cycled = helm.replace(HELM_WRAPPER.RIGHT, '}$');
210
-
211
- for (let i = 0; i < source.allPos1.length; i++) {
212
- if (i == 0)
213
- cycled += 'PEPTIDE1,PEPTIDE1,';
214
- else
215
- cycled += '|PEPTIDE1,PEPTIDE1,';
216
- cycled += `${source.allPos1[i]}:R${source.allAttaches1[i]}-${source.allPos2[i]}:R${source.allAttaches2[i]}`;
217
- }
218
-
219
- cycled += '$$$';
220
- return cycled;
221
- }
222
-
223
286
  export async function addTransformedColumn(
224
287
  molColumn: DG.Column<string>, addHelm: boolean, ruleFiles: string[], chiralityEngine?: boolean
225
288
  ): Promise<void> {
package/webpack.config.js CHANGED
@@ -2,11 +2,12 @@ const path = require('path');
2
2
  const FuncGeneratorPlugin = require('datagrok-tools/plugins/func-gen-plugin');
3
3
  const packageName = path.parse(require('./package.json').name).name.toLowerCase().replace(/-/g, '');
4
4
 
5
+ const mode = 'development';
5
6
  module.exports = {
6
7
  cache: {
7
8
  type: 'filesystem',
8
9
  },
9
- mode: 'development',
10
+ mode: mode,
10
11
  entry: {
11
12
  package: ['./src/package.ts'],
12
13
  test: {
@@ -29,12 +30,12 @@ module.exports = {
29
30
  plugins: [
30
31
  new FuncGeneratorPlugin({outputPath: './src/package.g.ts'}),
31
32
  ],
32
- devtool: 'source-map',
33
+ devtool: mode === 'development' ? 'source-map' : 'inline-source-map',
33
34
  externals: {
34
35
  'datagrok-api/dg': 'DG',
35
36
  'datagrok-api/grok': 'grok',
36
37
  'datagrok-api/ui': 'ui',
37
- 'openchemlib/full.js': 'OCL',
38
+ 'openchemlib/full': 'OCL',
38
39
  'rxjs': 'rxjs',
39
40
  'rxjs/operators': 'rxjs.operators',
40
41
  'cash-dom': '$',