@datagrok/sequence-translator 1.0.16 → 1.0.17

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.
Files changed (34) hide show
  1. package/detectors.js +0 -28
  2. package/dist/package-test.js +3830 -3738
  3. package/dist/package.js +3826 -3734
  4. package/package.json +3 -1
  5. package/setup-unlink-clean.sh +21 -0
  6. package/src/autostart/calculations.ts +2 -2
  7. package/src/autostart/registration.ts +102 -37
  8. package/src/{axolabs/define-pattern.ts → axolabs-tab/axolabs-tab.ts} +2 -2
  9. package/src/axolabs-tab/define-pattern.ts +874 -0
  10. package/src/{axolabs → axolabs-tab}/draw-svg.ts +1 -1
  11. package/src/{axolabs → axolabs-tab}/helpers.ts +2 -2
  12. package/src/{autostart → hardcode-to-be-eliminated}/ICDs.ts +0 -0
  13. package/src/{autostart → hardcode-to-be-eliminated}/IDPs.ts +0 -0
  14. package/src/{structures-works → hardcode-to-be-eliminated}/const.ts +0 -0
  15. package/src/{axolabs → hardcode-to-be-eliminated}/constants.ts +0 -0
  16. package/src/{structures-works → hardcode-to-be-eliminated}/converters.ts +1 -1
  17. package/src/{structures-works → hardcode-to-be-eliminated}/map.ts +2 -2
  18. package/src/{autostart → hardcode-to-be-eliminated}/salts.ts +0 -0
  19. package/src/{autostart → hardcode-to-be-eliminated}/sources.ts +0 -0
  20. package/src/{autostart → hardcode-to-be-eliminated}/users.ts +0 -0
  21. package/src/{main/main-view.ts → main-tab/main-tab.ts} +27 -79
  22. package/src/package.ts +40 -23
  23. package/src/sdf-tab/sdf-tab.ts +163 -0
  24. package/src/{structures-works → sdf-tab}/sequence-codes-tools.ts +8 -5
  25. package/src/tests/smiles-tests.ts +2 -2
  26. package/src/utils/const.ts +0 -0
  27. package/src/{helpers.ts → utils/helpers.ts} +3 -3
  28. package/src/utils/sdf-add-columns.ts +3 -3
  29. package/src/utils/sdf-save-table.ts +4 -4
  30. package/src/utils/structures-works/draw-molecule.ts +84 -0
  31. package/src/{structures-works → utils/structures-works}/from-monomers.ts +15 -16
  32. package/src/{structures-works → utils/structures-works}/mol-transformations.ts +34 -52
  33. package/{test-SequenceTranslator-6288c2fbe346-cce4ac1d.html → test-SequenceTranslator-6288c2fbe346-695b7b55.html} +10 -10
  34. package/src/structures-works/save-sense-antisense.ts +0 -91
@@ -1,4 +1,4 @@
1
- import {NUCLEOTIDES} from '../structures-works/map';
1
+ import {NUCLEOTIDES} from '../hardcode-to-be-eliminated/map';
2
2
  import {isOverhang, svg, textWidth, countOverhangsOnTheRightEdge, baseColor, textInsideCircle,
3
3
  fontColorVisibleOnBackground, isOneDigitNumber} from './helpers';
4
4
 
@@ -1,5 +1,5 @@
1
- import {AXOLABS_MAP} from './constants';
2
- import {NUCLEOTIDES} from '../structures-works/map';
1
+ import {AXOLABS_MAP} from '../hardcode-to-be-eliminated/constants';
2
+ import {NUCLEOTIDES} from '../hardcode-to-be-eliminated/map';
3
3
 
4
4
  export function isOverhang(modification: string): boolean {
5
5
  return modification.slice(-3) == '(o)';
@@ -1,7 +1,7 @@
1
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
+ import {sortByStringLengthInDescendingOrder} from '../utils/helpers';
5
5
  //name: gcrsToLcms
6
6
  //input: string nucleotides {semType: GCRS}
7
7
  //output: string result {semType: LCMS}
@@ -1,6 +1,6 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
- import {getAllCodesOfSynthesizer} from './sequence-codes-tools';
3
- import {differenceOfTwoArrays} from '../helpers';
2
+ import {getAllCodesOfSynthesizer} from '../sdf-tab/sequence-codes-tools';
3
+ import {differenceOfTwoArrays} from '../utils/helpers';
4
4
 
5
5
  export const DELIMITER = ';';
6
6
  export const NUCLEOTIDES = ['A', 'G', 'C', 'U', 'T'];
@@ -3,24 +3,29 @@ import * as ui from 'datagrok-api/ui';
3
3
  import * as DG from 'datagrok-api/dg';
4
4
 
5
5
  import * as rxjs from 'rxjs';
6
- import {convertSequence, undefinedInputSequence, isValidSequence} from '../structures-works/sequence-codes-tools';
7
- import {map} from '../structures-works/map';
8
- import {MODIFICATIONS} from '../structures-works/const';
9
- import {sequenceToSmiles, sequenceToMolV3000} from '../structures-works/from-monomers';
10
6
  import $ from 'cash-dom';
11
- import {download} from '../helpers';
12
- import {extractAtomDataV3000} from '../structures-works/mol-transformations';
13
- import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
7
+
8
+ import {convertSequence, undefinedInputSequence, isValidSequence} from '../sdf-tab/sequence-codes-tools';
9
+
10
+ // todo: elminate completely
11
+ import {map} from '../hardcode-to-be-eliminated/map';
12
+ import {MODIFICATIONS} from '../hardcode-to-be-eliminated/const';
13
+
14
+ // todo: unify with lib bio monomers works
15
+ import {sequenceToSmiles, sequenceToMolV3000} from '../utils/structures-works/from-monomers';
16
+ import {drawMolecule} from '../utils/structures-works/draw-molecule';
17
+
18
+ import {download} from '../utils/helpers';
14
19
 
15
20
  const defaultInput = 'fAmCmGmAmCpsmU'; // todo: capitalize constants
16
21
  const sequenceWasCopied = 'Copied'; // todo: wrap hardcoded literals into constants
17
22
  const tooltipSequence = 'Copy sequence';
18
23
 
19
- export async function mainView(onSequenceChanged: (seq: string) => void): Promise<HTMLDivElement> {
24
+ export async function getMainTab(onSequenceChanged: (seq: string) => void): Promise<HTMLDivElement> {
20
25
  const onInput: rxjs.Subject<string> = new rxjs.Subject<string>();
21
26
 
22
27
  async function updateTableAndMolecule(sequence: string, inputFormat: string): Promise<void> {
23
- moleculeSvgDiv.innerHTML = '';
28
+ moleculeImgDiv.innerHTML = '';
24
29
  outputTableDiv.innerHTML = '';
25
30
  const pi = DG.TaskBarProgressIndicator.create('Rendering table and molecule...');
26
31
 
@@ -56,77 +61,20 @@ export async function mainView(onSequenceChanged: (seq: string) => void): Promis
56
61
  ui.div([
57
62
  DG.HtmlTable.create(tableRows, (item: { key: string; value: string; }) =>
58
63
  [item.key, item.value], ['Code', 'Sequence']).root,
59
- ]),
64
+ ])
60
65
  );
61
66
 
62
- if (outputSequenceObj.type != undefinedInputSequence && outputSequenceObj.Error != undefinedInputSequence) {
67
+ if (outputSequenceObj.type !== undefinedInputSequence && outputSequenceObj.Error !== undefinedInputSequence) {
63
68
  const formCanvasWidth = 500;
64
69
  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
- }
115
- });
116
- $(formCanvas).on('mouseover', () => $(formCanvas).css('cursor', 'zoom-in'));
117
- $(formCanvas).on('mouseout', () => $(formCanvas).css('cursor', 'default'));
118
- const mol = sequenceToMolV3000(inputSequenceField.value.replace(/\s/g, ''), false, true,
119
- output.synthesizer![0]);
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);
128
- } else
129
- moleculeSvgDiv.innerHTML = '';
70
+ const molfile = sequenceToMolV3000(
71
+ inputSequenceField.value.replace(/\s/g, ''), false, true,
72
+ output.synthesizer![0]
73
+ );
74
+ await drawMolecule(moleculeImgDiv, formCanvasWidth, formCanvasHeight, molfile);
75
+ } else {
76
+ moleculeImgDiv.innerHTML = '';
77
+ }
130
78
  } finally {
131
79
  pi.close();
132
80
  }
@@ -136,7 +84,7 @@ export async function mainView(onSequenceChanged: (seq: string) => void): Promis
136
84
  inputFormatChoiceInput.onInput((format: string) => {
137
85
  updateTableAndMolecule(inputSequenceField.value.replace(/\s/g, ''), format);
138
86
  });
139
- const moleculeSvgDiv = ui.block([]);
87
+ const moleculeImgDiv = ui.block([]);
140
88
  const outputTableDiv = ui.div([]);
141
89
  const inputSequenceField = ui.textInput('', defaultInput, (sequence: string) => {
142
90
  // Send event to DG.debounce()
@@ -228,7 +176,7 @@ export async function mainView(onSequenceChanged: (seq: string) => void): Promis
228
176
  const topPanel = [
229
177
  downloadMolFileIcon,
230
178
  copySmilesIcon,
231
- switchInput.root,
179
+ switchInput.root, // todo: remove from top panel
232
180
  ];
233
181
 
234
182
  const v = grok.shell.v;
@@ -253,7 +201,7 @@ export async function mainView(onSequenceChanged: (seq: string) => void): Promis
253
201
  ui.h1('Output'),
254
202
  outputTableDiv,
255
203
  ]),
256
- moleculeSvgDiv,
204
+ moleculeImgDiv,
257
205
  ], 'sequence'),
258
206
  ]),
259
207
  codesTablesDiv,
package/src/package.ts CHANGED
@@ -1,13 +1,25 @@
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
+
4
5
  import {autostartOligoSdFileSubscription} from './autostart/registration';
5
- import {defineAxolabsPattern} from './axolabs/define-pattern';
6
- import {saveSenseAntiSense} from './structures-works/save-sense-antisense';
7
- import {mainView} from './main/main-view';
8
- import {IMonomerLib, MonomerWorks, readLibrary} from '@datagrok-libraries/bio';
9
6
  import {OligoSdFileApp} from './apps/oligo-sd-file-app';
10
7
 
8
+ // three tabs of the app's view
9
+ import {getMainTab} from './main-tab/main-tab';
10
+ import {getAxolabsTab} from './axolabs-tab/axolabs-tab';
11
+ import {getSdfTab} from './sdf-tab/sdf-tab';
12
+
13
+ const MAIN = 'MAIN';
14
+ const AXOLABS = 'AXOLABS';
15
+ const SDF = 'SDF';
16
+
17
+ const SEQUENCE_TRANSLATOR = 'Sequence Translator';
18
+ const DEFAULT_SEQUENCE = 'fAmCmGmAmCpsmU';
19
+ const DEFAULT_LIB_FILENAME = 'helmLib.json';
20
+
21
+ import {IMonomerLib, MonomerWorks, readLibrary} from '@datagrok-libraries/bio';
22
+
11
23
  export const _package = new DG.Package();
12
24
 
13
25
  const LIB_PATH = 'System:AppData/SequenceTranslator';
@@ -26,9 +38,9 @@ export function getMonomerLib() {
26
38
  //name: Sequence Translator
27
39
  //tags: app
28
40
  export async function sequenceTranslator(): Promise<void> {
29
- monomerLib = await readLibrary(LIB_PATH, 'helmLib.json');
41
+ monomerLib = await readLibrary(LIB_PATH, DEFAULT_LIB_FILENAME);
30
42
 
31
- if (monomerWorks == null)
43
+ if (monomerWorks === null)
32
44
  monomerWorks = new MonomerWorks(monomerLib);
33
45
 
34
46
  const windows = grok.shell.windows;
@@ -36,22 +48,25 @@ export async function sequenceTranslator(): Promise<void> {
36
48
  windows.showToolbox = false;
37
49
  windows.showHelp = false;
38
50
 
39
- let urlParams: URLSearchParams = new URLSearchParams(window.location.search);
40
- let mainSeq: string = 'fAmCmGmAmCpsmU';
41
- const v = grok.shell.newView('Sequence Translator', []);
42
- v.box = true;
43
- const tc = ui.tabControl({
44
- 'MAIN': await mainView((seq) => {
51
+ let urlParams = new URLSearchParams(window.location.search);
52
+
53
+ let mainSeq: string = DEFAULT_SEQUENCE;
54
+ const view = grok.shell.newView(SEQUENCE_TRANSLATOR, []);
55
+ view.box = true;
56
+
57
+ const tabControl = ui.tabControl({
58
+ [MAIN]: await getMainTab((seq) => {
45
59
  mainSeq = seq;
46
60
  urlParams = new URLSearchParams();
47
61
  urlParams.set('seq', mainSeq);
48
62
  updatePath();
49
63
  }),
50
- 'AXOLABS': defineAxolabsPattern(),
51
- 'SDF': saveSenseAntiSense(),
64
+ [AXOLABS]: getAxolabsTab(),
65
+ [SDF]: getSdfTab(),
52
66
  });
53
- tc.onTabChanged.subscribe((value) => {
54
- if (tc.currentPane.name != 'MAIN')
67
+
68
+ tabControl.onTabChanged.subscribe(() => {
69
+ if (tabControl.currentPane.name !== MAIN)
55
70
  urlParams.delete('seq');
56
71
  else
57
72
  urlParams.set('seq', mainSeq);
@@ -61,26 +76,28 @@ export async function sequenceTranslator(): Promise<void> {
61
76
  function updatePath() {
62
77
  const urlParamsTxt: string = Object.entries(urlParams)
63
78
  .map(([key, value]) => `${key}=${encodeURIComponent(value)}`).join('&');
64
- v.path = '/apps/SequenceTranslator/SequenceTranslator' + `/${tc.currentPane.name}/?${urlParamsTxt}`;
79
+ view.path = '/apps/SequenceTranslator/SequenceTranslator' + `/${tabControl.currentPane.name}/?${urlParamsTxt}`;
65
80
  }
66
81
 
67
82
  const pathParts: string[] = window.location.pathname.split('/');
68
83
  if (pathParts.length >= 5) {
69
84
  const tabName: string = pathParts[5];
70
- tc.currentPane = tc.getPane(tabName);
85
+ tabControl.currentPane = tabControl.getPane(tabName);
71
86
  }
72
87
 
73
- v.append(tc);
74
- console.debug('SequenceTranslator: app sequenceTranslator() ' + `v.path='${v.path}', v.basePath='${v.basePath}'.`);
88
+ view.append(tabControl);
89
+ // console.debug('SequenceTranslator: app sequenceTranslator() ' + `view.path='${view.path}', view.basePath='${view.basePath}'.`);
75
90
  }
76
91
 
77
92
  //tags: autostart
78
- autostartOligoSdFileSubscription();
93
+ export async function autostartST() {
94
+ autostartOligoSdFileSubscription();
95
+ };
79
96
 
80
97
  //name: oligoSdFileApp
81
98
  //description: Test/demo app for oligoSdFile
82
99
  export async function oligoSdFileApp() {
83
- console.debug('SequenceTranslator: package.ts oligoSdFileApp()');
100
+ // console.debug('SequenceTranslator: package.ts oligoSdFileApp()');
84
101
 
85
102
  const pi = DG.TaskBarProgressIndicator.create('open oligoSdFile app');
86
103
  try {
@@ -92,4 +109,4 @@ export async function oligoSdFileApp() {
92
109
  } finally {
93
110
  pi.close();
94
111
  }
95
- }
112
+ }
@@ -0,0 +1,163 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+ import * as rxjs from 'rxjs';
5
+ import {errorToConsole} from '@datagrok-libraries/utils/src/to-console';
6
+
7
+ import $ from 'cash-dom';
8
+
9
+ import {download} from '../utils/helpers';
10
+
11
+ import {sequenceToMolV3000} from '../utils/structures-works/from-monomers';
12
+ import {linkStrandsV3000} from '../utils/structures-works/mol-transformations';
13
+ import {getFormat} from './sequence-codes-tools';
14
+
15
+ import {drawMolecule} from '../utils/structures-works/draw-molecule';
16
+
17
+ function getMolfileForImg(
18
+ ss: string, as: string,
19
+ as2: string | null = null,
20
+ invertSS: boolean, invertAS: boolean, invertAS2: boolean,
21
+ useChiral: boolean
22
+ ): string {
23
+ const formatAs = getFormat(as);
24
+ const formatSs = getFormat(ss);
25
+ let formatAs2: string | null = null;
26
+ let molAS2: string | null = null;
27
+
28
+ let molSS = '';
29
+ let molAS = '';
30
+ try {
31
+ // a workaround to get the SS depicted in case AS is empty
32
+ molSS = sequenceToMolV3000(ss, invertSS, false, formatSs!);
33
+ molAS = sequenceToMolV3000(as, invertAS, false, formatAs!);
34
+ } catch (err) {
35
+ const errStr = errorToConsole(err);
36
+ console.error(errStr);
37
+ }
38
+
39
+ if (as2 !== null && as2 !== '') {
40
+ formatAs2 = getFormat(as2!);
41
+ molAS2 = sequenceToMolV3000(as2, invertAS2!, false, formatAs2!);
42
+ }
43
+
44
+ const antiStrands = molAS2 === null ? [molAS] : [molAS, molAS2];
45
+ const resultingMolfile = linkStrandsV3000({senseStrands: [molSS], antiStrands: antiStrands}, useChiral);
46
+ return resultingMolfile;
47
+ }
48
+
49
+ export function saveSdf(as: string, ss: string,
50
+ oneEntity: boolean, useChiral: boolean,
51
+ invertSS: boolean, invertAS: boolean,
52
+ as2: string | null = null, invertAS2: boolean | null
53
+ ): void {
54
+ const formatAs = getFormat(as);
55
+ const formatSs = getFormat(ss);
56
+ let formatAs2: string | null = null;
57
+ let molAS2: string | null = null;
58
+
59
+ const molSS = sequenceToMolV3000(ss, invertSS, false, formatSs!);
60
+ const molAS = sequenceToMolV3000(as, invertAS, false, formatAs!);
61
+
62
+ if (as2 !== null && as2 !== '') {
63
+ formatAs2 = getFormat(as2!);
64
+ molAS2 = sequenceToMolV3000(as2, invertAS2!, false, formatAs2!);
65
+ }
66
+
67
+ let result: string;
68
+ if (oneEntity) {
69
+ const antiStrands = molAS2 === null ? [molAS] : [molAS, molAS2];
70
+ result = linkStrandsV3000({senseStrands: [molSS], antiStrands: antiStrands}, useChiral) + '\n$$$$\n';
71
+ } else {
72
+ result =
73
+ molSS + '\n' +
74
+ `> <Sequence>\nSense Strand\n$$$$\n` +
75
+ molAS + '\n' +
76
+ `> <Sequence>\nAnti Sense\n$$$$\n`;
77
+
78
+ if (molAS2) {
79
+ result += molAS2+ '\n' +
80
+ `> <Sequence>\nAnti Sense 2\n$$$$\n`;
81
+ }
82
+ }
83
+
84
+ // construct date-time in the form yyyy-mm-dd_hh-mm-ss
85
+ const date = new Date();
86
+ function pad(x: number): string {
87
+ return (x >= 10) ? x.toString() : '0' + x.toString();
88
+ }
89
+ const dateString: string = date.getFullYear() + '-' + pad(date.getMonth() + 1) +
90
+ '-' + pad(date.getDate()) + '_' + pad(date.getHours()) + '-' +
91
+ pad(date.getMinutes()) + '-' + pad(date.getSeconds());
92
+
93
+ download(`SequenceTranslator-${dateString}.sdf`, encodeURIComponent(result));
94
+ }
95
+
96
+ /** UI of the SDF tab on the application's view */
97
+ export function getSdfTab(): HTMLDivElement {
98
+ const onInput: rxjs.Subject<string> = new rxjs.Subject<string>();
99
+
100
+ // inputs
101
+ const inputColHeader = ui.h1('Sequences');
102
+ const ssInput = ui.textInput('Sense Strand', '', () => { onInput.next(); });
103
+ ssInput.root.style.color = 'red';
104
+ const asInput = ui.textInput('Anti Sense', '', () => { onInput.next(); });
105
+ const as2Input = ui.textInput('Anti Sense 2', '', () => { onInput.next(); });
106
+ const saveEntity = ui.boolInput('Save as one entity', true);
107
+ const useChiralInput = ui.boolInput('Use chiral', true);
108
+
109
+ // default values
110
+ const straight = '5 prime -> 3 prime';
111
+ const inverse = '3 prime -> 5 prime';
112
+ let invertSS = false;
113
+ let invertAS = false;
114
+ const invertAS2 = false;
115
+
116
+ // choice inputs
117
+ const ssDirection = ui.choiceInput('SS direction', straight, [straight, inverse]);
118
+ ssDirection.onChanged(() => { invertSS = ssDirection.value === inverse; });
119
+ const asDirection = ui.choiceInput('AS direction', straight, [straight, inverse]);
120
+ asDirection.onChanged(() => { invertAS = asDirection.value === inverse; });
121
+ const as2Direction = ui.choiceInput('AS 2 direction', straight, [straight, inverse]);
122
+ as2Direction.onChanged(() => { invertAS = asDirection.value === inverse; });
123
+
124
+ // molecule image
125
+ const moleculeImgDiv = ui.block([]);
126
+ DG.debounce<string>(onInput, 300).subscribe(async () => {
127
+ let molfile = '';
128
+ try {
129
+ molfile = getMolfileForImg(
130
+ ssInput.value, asInput.value, as2Input.value, invertSS, invertAS, invertAS2, useChiralInput.value!
131
+ );
132
+ } catch (err) {
133
+ const errStr = errorToConsole(err);
134
+ console.error(errStr);
135
+ }
136
+ // todo: calculate relative numbers
137
+ const canvasWidth = 500;
138
+ const canvasHeight = 170;
139
+ // todo: remove div with image if molfile empty
140
+ await drawMolecule(moleculeImgDiv, canvasWidth, canvasHeight, molfile);
141
+ });
142
+
143
+ const saveButton = ui.buttonsInput([
144
+ ui.bigButton('Save SDF', () =>
145
+ saveSdf(
146
+ asInput.value, ssInput.value, saveEntity.value!,
147
+ useChiralInput.value!, invertSS, invertAS, as2Input.value, invertAS2)
148
+ )
149
+ ]);
150
+ //@ts-ignore
151
+ // the above line is recommended by Dmitry because saveButton has wrong return
152
+ // type
153
+ const form1 = ui.form([inputColHeader, ssInput, asInput, as2Input, saveButton]);
154
+ form1.className = 'ui-form ui-form-wide';
155
+ const form2 = ui.form([ssDirection, asDirection, as2Direction, saveEntity, useChiralInput]);
156
+ form2.className = 'ui-form ui-form-wide';
157
+
158
+ const body = ui.divV([ui.divH([ui.block([form1]), form2]), moleculeImgDiv]);
159
+ $(form1).find('textarea').css('flex-grow', '1');
160
+ $(form1).find('label').css('max-width', '140px');
161
+
162
+ return body;
163
+ }
@@ -1,12 +1,15 @@
1
-
2
- import {map, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS, DELIMITER, gcrsCodesWithoutSmiles, NUCLEOTIDES} from './map';
3
- import {sortByStringLengthInDescendingOrder} from '../helpers';
4
- import {asoGapmersNucleotidesToBioSpring, asoGapmersNucleotidesToGcrs,
1
+ import {
2
+ map, SYNTHESIZERS, TECHNOLOGIES, MODIFICATIONS, DELIMITER, gcrsCodesWithoutSmiles, NUCLEOTIDES
3
+ } from '../hardcode-to-be-eliminated/map';
4
+ import {sortByStringLengthInDescendingOrder} from '../utils/helpers';
5
+ import {
6
+ asoGapmersNucleotidesToBioSpring, asoGapmersNucleotidesToGcrs,
5
7
  asoGapmersBioSpringToNucleotides, asoGapmersBioSpringToGcrs, gcrsToMermade12, siRnaNucleotideToBioSpringSenseStrand,
6
8
  siRnaNucleotideToAxolabsSenseStrand, siRnaNucleotidesToGcrs, siRnaBioSpringToNucleotides,
7
9
  siRnaBioSpringToAxolabs, siRnaBioSpringToGcrs, siRnaAxolabsToNucleotides,
8
10
  siRnaAxolabsToBioSpring, siRnaAxolabsToGcrs, siRnaGcrsToNucleotides,
9
- siRnaGcrsToBioSpring, siRnaGcrsToAxolabs, gcrsToNucleotides, gcrsToLcms} from './converters';
11
+ siRnaGcrsToBioSpring, siRnaGcrsToAxolabs, gcrsToNucleotides, gcrsToLcms
12
+ } from '../hardcode-to-be-eliminated/converters';
10
13
 
11
14
  const noTranslationTableAvailable = 'No translation table available';
12
15
  export const undefinedInputSequence = 'Type of input sequence is undefined';
@@ -1,6 +1,6 @@
1
1
  import {category, expect, test} from '@datagrok-libraries/utils/src/test';
2
- import {sequenceToSmiles} from '../structures-works/from-monomers';
3
- import {SYNTHESIZERS} from '../structures-works/map';
2
+ import {sequenceToSmiles} from '../utils/structures-works/from-monomers';
3
+ import {SYNTHESIZERS} from '../hardcode-to-be-eliminated/map';
4
4
 
5
5
  category('sequence-translator', () => {
6
6
  // test('AGGTCCTCTTGACTTAGGCC', async () => {
File without changes
@@ -1,9 +1,9 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
 
3
3
  export function sortByStringLengthInDescendingOrder(array: string[]): string[] {
4
- return array.sort(function(a, b) {return b.length - a.length;});
4
+ return array.sort(function(a, b) { return b.length - a.length; });
5
5
  }
6
-
6
+
7
7
  export function stringify(items: string[]): string {
8
8
  return '["' + items.join('", "') + '"]';
9
9
  }
@@ -17,7 +17,7 @@ export function download(name: string, href: string): void {
17
17
 
18
18
  export function removeEmptyRows(t: DG.DataFrame, colToCheck: DG.Column): DG.DataFrame {
19
19
  for (let i = t.rowCount - 1; i > -1; i--) {
20
- if (colToCheck.getString(i) == '')
20
+ if (colToCheck.getString(i) === '')
21
21
  t.rows.removeAt(i, 1, false);
22
22
  }
23
23
  return t;
@@ -1,11 +1,11 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import {COL_NAMES, GENERATED_COL_NAMES, SEQUENCE_TYPES} from '../autostart/constants';
3
3
  import * as grok from 'datagrok-api/grok';
4
- import {removeEmptyRows} from '../helpers';
4
+ import {removeEmptyRows} from '../utils/helpers';
5
5
  import {parseStrandsFromDuplexCell, parseStrandsFromTriplexOrDimerCell} from './parse';
6
- import {isValidSequence} from '../structures-works/sequence-codes-tools';
6
+ import {isValidSequence} from '../sdf-tab/sequence-codes-tools';
7
7
  import {batchMolWeight, molecularWeight, saltMass, saltMolWeigth} from '../autostart/calculations';
8
- import {weightsObj} from '../structures-works/map';
8
+ import {weightsObj} from '../hardcode-to-be-eliminated/map';
9
9
 
10
10
  export class SdfColumnsExistsError extends Error {
11
11
  constructor(message: string) {
@@ -1,11 +1,11 @@
1
1
  import * as DG from 'datagrok-api/dg';
2
2
  import {COL_NAMES, GENERATED_COL_NAMES, SEQUENCE_TYPES} from '../autostart/constants';
3
- import {differenceOfTwoArrays, download} from '../helpers';
3
+ import {differenceOfTwoArrays, download} from '../utils/helpers';
4
4
  import * as grok from 'datagrok-api/grok';
5
- import {SYNTHESIZERS} from '../structures-works/map';
6
- import {sequenceToMolV3000} from '../structures-works/from-monomers';
5
+ import {SYNTHESIZERS} from '../hardcode-to-be-eliminated/map';
6
+ import {sequenceToMolV3000} from '../utils/structures-works/from-monomers';
7
7
  import {parseStrandsFromDuplexCell, parseStrandsFromTriplexOrDimerCell} from './parse';
8
- import {linkStrandsV3000} from '../structures-works/mol-transformations';
8
+ import {linkStrandsV3000} from '../utils/structures-works/mol-transformations';
9
9
 
10
10
  export async function sdfSaveTable(table: DG.DataFrame, onError: (rowI: number, err: any) => void) {
11
11
  if (GENERATED_COL_NAMES.some((colName) => !table.columns.contains(colName))) {