@datagrok/sequence-translator 1.2.5 → 1.2.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"package.js","mappings":"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","sources":["webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/chemical-table-parser-base.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler-base.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/const.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/utils.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-v3k-handler.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/utils/src/test.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/utils/src/to-console.js","webpack://sequencetranslator/./src/view/style/colored-text-input.css","webpack://sequencetranslator/./src/view/style/structure-app.css","webpack://sequencetranslator/./src/view/style/translator-app.css","webpack://sequencetranslator/./node_modules/css-loader/dist/runtime/api.js","webpack://sequencetranslator/./node_modules/css-loader/dist/runtime/sourceMaps.js","webpack://sequencetranslator/./node_modules/save-svg-as-png/lib/saveSvgAsPng.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/insertBySelector.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/insertStyleElement.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/styleDomAPI.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/styleTagTransform.js","webpack://sequencetranslator/./src/model/const.ts","webpack://sequencetranslator/./src/model/data-loading-utils/const.ts","webpack://sequencetranslator/./src/model/data-loading-utils/json-loader.ts","webpack://sequencetranslator/./src/model/helpers.ts","webpack://sequencetranslator/./src/model/monomer-lib/lib-wrapper.ts","webpack://sequencetranslator/./src/model/parsing-validation/sequence-validator.ts","webpack://sequencetranslator/./src/model/structure-app/const.ts","webpack://sequencetranslator/./src/model/structure-app/mol-transformations.ts","webpack://sequencetranslator/./src/model/translator-app/const.ts","webpack://sequencetranslator/./src/model/translator-app/conversion-utils.ts","webpack://sequencetranslator/./src/model/parsing-validation/format-handler.ts","webpack://sequencetranslator/./src/model/translator-app/format-converter.ts","webpack://sequencetranslator/external var \"ui\"","webpack://sequencetranslator/external var \"rxjs\"","webpack://sequencetranslator/./src/view/style/translator-app.css?3282","webpack://sequencetranslator/./src/model/parsing-validation/format-detector.ts","webpack://sequencetranslator/external var \"$\"","webpack://sequencetranslator/./src/view/utils/colored-input/input-painters.ts","webpack://sequencetranslator/./src/view/style/colored-text-input.css?0e07","webpack://sequencetranslator/./src/view/utils/colored-input/colored-text-input.ts","webpack://sequencetranslator/./src/model/structure-app/monomer-code-parser.ts","webpack://sequencetranslator/./src/model/structure-app/sequence-to-molfile.ts","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/formats/molfile-v2k-const.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-v2k-handler.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler.js","webpack://sequencetranslator/./src/view/utils/molecule-img.ts","webpack://sequencetranslator/./src/view/apps/oligo-translator.ts","webpack://sequencetranslator/./src/view/style/structure-app.css?9992","webpack://sequencetranslator/./src/model/structure-app/oligo-structure.ts","webpack://sequencetranslator/./src/view/apps/oligo-structure.ts","webpack://sequencetranslator/./src/model/pattern-app/const.ts","webpack://sequencetranslator/./src/model/pattern-app/helpers.ts","webpack://sequencetranslator/./src/model/pattern-app/oligo-pattern.ts","webpack://sequencetranslator/./src/model/pattern-app/draw-svg.ts","webpack://sequencetranslator/./src/view/apps/oligo-pattern.ts","webpack://sequencetranslator/./src/view/utils/draw-molecule.ts","webpack://sequencetranslator/./src/view/monomer-lib-viewer/viewer.ts","webpack://sequencetranslator/./src/view/app-ui.ts","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/consts.js","webpack://sequencetranslator/external var \"wu\"","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/types.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/seq-palettes.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/aminoacids.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/nucleotides.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/unknown.js","webpack://sequencetranslator/./node_modules/fastest-levenshtein/esm/mod.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/macromolecule-distance-functions.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/utils/units-handler.js","webpack://sequencetranslator/./src/plugins/mermade.ts","webpack://sequencetranslator/./src/package.ts","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/monomer-works/monomer-utils.js","webpack://sequencetranslator/./src/demo/demo-st-ui.ts","webpack://sequencetranslator/./src/view/const/oligo-translator.ts","webpack://sequencetranslator/./src/view/const/ui.ts","webpack://sequencetranslator/external var \"DG\"","webpack://sequencetranslator/external var \"grok\"","webpack://sequencetranslator/webpack/bootstrap","webpack://sequencetranslator/webpack/runtime/compat get default export","webpack://sequencetranslator/webpack/runtime/define property getters","webpack://sequencetranslator/webpack/runtime/hasOwnProperty shorthand","webpack://sequencetranslator/webpack/runtime/make namespace object","webpack://sequencetranslator/webpack/runtime/nonce","webpack://sequencetranslator/webpack/startup"],"sourcesContent":["/** Base for Molfile or Mol2 parser/handler */\nexport class ChemicalTableParserBase {\n constructor(fileContent) {\n this.init(fileContent);\n }\n ;\n init(fileContent) {\n this.fileContent = fileContent.replace(/\\r/g, '');\n this._atomCount = undefined;\n this._atomTypes = undefined;\n this._bondCount = undefined;\n this._bondTypes = undefined;\n this.xyzAtomCoordinates = undefined;\n this._pairsOfBondedAtoms = undefined;\n }\n /** Total number of atoms in a molecule */\n get atomCount() {\n if (this._atomCount === undefined)\n this.setAtomAndBondCounts();\n return this._atomCount;\n }\n /** Number of bonds in a molecule */\n get bondCount() {\n if (this._bondCount === undefined)\n this.setAtomAndBondCounts();\n return this._bondCount;\n }\n /** X coordinates of all atoms in a molecule */\n get x() {\n var _a;\n (_a = this.xyzAtomCoordinates) !== null && _a !== void 0 ? _a : (this.xyzAtomCoordinates = this.parseAtomCoordinates());\n return this.xyzAtomCoordinates.x;\n }\n ;\n /** Y coordinates of all atoms in a molecule */\n get y() {\n var _a;\n (_a = this.xyzAtomCoordinates) !== null && _a !== void 0 ? _a : (this.xyzAtomCoordinates = this.parseAtomCoordinates());\n return this.xyzAtomCoordinates.y;\n }\n ;\n /** Z coordinates of all atoms in a molecule */\n get z() {\n var _a;\n (_a = this.xyzAtomCoordinates) !== null && _a !== void 0 ? _a : (this.xyzAtomCoordinates = this.parseAtomCoordinates());\n return this.xyzAtomCoordinates.z;\n }\n ;\n get atomTypes() {\n var _a;\n (_a = this._atomTypes) !== null && _a !== void 0 ? _a : (this._atomTypes = this.parseAtomTypes());\n return this._atomTypes;\n }\n get pairsOfBondedAtoms() {\n var _a;\n (_a = this._pairsOfBondedAtoms) !== null && _a !== void 0 ? _a : (this._pairsOfBondedAtoms = this.parseBondedAtomPairs());\n return this._pairsOfBondedAtoms;\n }\n get bondTypes() {\n var _a;\n (_a = this._bondTypes) !== null && _a !== void 0 ? _a : (this._bondTypes = this.parseBondTypes());\n return this._bondTypes;\n }\n setAtomAndBondCounts() {\n const { atomCount, bondCount } = this.parseAtomAndBondCounts();\n this._atomCount = atomCount;\n this._bondCount = bondCount;\n }\n getNextColumnIdx(idx) {\n // skip non-whitespace, if necessary\n while (!this.isWhitespace(idx))\n ++idx;\n // skip whitespace\n while (this.isWhitespace(idx))\n ++idx;\n return idx;\n }\n shiftIdxToSpecifiedColumn(lineStartIdx, columnNumber) {\n let idx = lineStartIdx;\n const numberOfJumps = this.isWhitespace(idx) ? columnNumber : columnNumber - 1;\n for (let i = 0; i < numberOfJumps; i++)\n idx = this.getNextColumnIdx(idx);\n return idx;\n }\n parseAtomTypes() {\n const atomCount = this.atomCount;\n const atomTypes = new Array(atomCount);\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < atomCount; i++) {\n idx = this.shiftIdxToAtomType(idx);\n atomTypes[i] = this.parseAtomType(idx);\n idx = this.getNextLineIdx(idx);\n }\n return atomTypes;\n }\n ;\n parseAtomCoordinates() {\n const x = new Float32Array(this.atomCount);\n const y = new Float32Array(this.atomCount);\n const z = new Float32Array(this.atomCount);\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < this.atomCount; i++) {\n idx = this.shiftIdxToXColumn(idx);\n for (const item of [x, y, z]) {\n item[i] = this.parseFloatValue(idx);\n idx = this.getNextColumnIdx(idx);\n }\n idx = this.getNextLineIdx(idx);\n }\n return { x: x, y: y, z: z };\n }\n parseBondedAtomPairs() {\n const bondedAtomPairs = new Array(this.bondCount);\n let idx = this.getBondBlockIdx();\n for (let i = 0; i < this.bondCount; i++) {\n idx = this.shiftIdxToBondedAtomsPair(idx);\n const pair = new Uint16Array(2);\n pair[0] = this.parseIntValue(idx);\n idx = this.getNextColumnIdx(idx);\n pair[1] = this.parseIntValue(idx);\n bondedAtomPairs[i] = pair;\n idx = this.getNextLineIdx(idx);\n }\n return bondedAtomPairs;\n }\n parseBondTypes() {\n const bondCount = this.bondCount;\n const bondTypes = new Uint16Array(bondCount);\n let idx = this.getBondBlockIdx();\n for (let i = 0; i < bondCount; i++) {\n idx = this.shiftIdxToBondType(idx);\n bondTypes[i] = this.parseIntValue(idx);\n idx = this.getNextLineIdx(idx);\n }\n return bondTypes;\n }\n ;\n isWhitespace(idx) {\n const symbol = this.fileContent[idx];\n return symbol === ' ' || symbol === '\\t';\n }\n getNextLineIdx(idx) {\n if (this.fileContent[idx] !== '\\n')\n return this.fileContent.indexOf('\\n', idx) + 1;\n else\n return idx + 1;\n }\n parseFloatValue(idxOfNumber) {\n return this.parseNumericValue(parseFloat, idxOfNumber);\n }\n parseIntValue(idxOfNumber) {\n return this.parseNumericValue(parseInt, idxOfNumber);\n }\n parseNumericValue(parserFunction, idxOfNumber) {\n let end = idxOfNumber + 1;\n while (!this.isWhitespace(end))\n ++end;\n const value = parserFunction(this.fileContent.substring(idxOfNumber, end));\n return value;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlbWljYWwtdGFibGUtcGFyc2VyLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjaGVtaWNhbC10YWJsZS1wYXJzZXItYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQSw4Q0FBOEM7QUFDOUMsTUFBTSxPQUFnQix1QkFBdUI7SUFDM0MsWUFBWSxXQUFtQjtRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFBQSxDQUFDO0lBVVEsSUFBSSxDQUFDLFdBQW1CO1FBQ2hDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztRQUNwQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCwwQ0FBMEM7SUFDMUMsSUFBSSxTQUFTO1FBQ1gsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVM7WUFDL0IsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUIsT0FBTyxJQUFJLENBQUMsVUFBVyxDQUFDO0lBQzFCLENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsSUFBSSxTQUFTO1FBQ1gsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVM7WUFDL0IsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUIsT0FBTyxJQUFJLENBQUMsVUFBVyxDQUFDO0lBQzFCLENBQUM7SUFFRCxnREFBZ0Q7SUFDaEQsSUFBSSxDQUFDOztRQUNILE1BQUEsSUFBSSxDQUFDLGtC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QVcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgQXRvbUFuZEJvbmRDb3VudHMgPSB7XG4gIGF0b21Db3VudDogbnVtYmVyLFxuICBib25kQ291bnQ6IG51bWJlclxufVxuXG50eXBlIENvb3JkaW5hdGVBcnJheXMgPSB7XG4gIHg6IEZsb2F0MzJBcnJheSxcbiAgeTogRmxvYXQzMkFycmF5LFxuICB6OiBGbG9hdDMyQXJyYXksXG59XG5cbi8qKiBCYXNlIGZvciBNb2xmaWxlIG9yIE1vbDIgcGFyc2VyL2hhbmRsZXIgKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDaGVtaWNhbFRhYmxlUGFyc2VyQmFzZSB7XG4gIGNvbnN0cnVjdG9yKGZpbGVDb250ZW50OiBzdHJpbmcpIHtcbiAgICB0aGlzLmluaXQoZmlsZUNvbnRlbnQpO1xuICB9O1xuXG4gIHByb3RlY3RlZCBmaWxlQ29udGVudCE6IHN0cmluZztcbiAgcHJvdGVjdGVkIF9hdG9tQ291bnQ/OiBudW1iZXI7XG4gIHByb3RlY3RlZCBfYm9uZENvdW50PzogbnVtYmVyO1xuICBwcm90ZWN0ZWQgeHl6QXRvbUNvb3JkaW5hdGVzPzogQ29vcmRpbmF0ZUFycmF5cztcbiAgcHJvdGVjdGVkIF9hdG9tVHlwZXM/OiBzdHJpbmdbXTtcbiAgcHJvdGVjdGVkIF9wYWlyc09mQm9uZGVkQXRvbXM/OiBVaW50MTZBcnJheVtdO1xuICBwcm90ZWN0ZWQgX2JvbmRUeXBlcz86IFVpbnQxNkFycmF5O1xuXG4gIHByb3RlY3RlZCBpbml0KGZpbGVDb250ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZpbGVDb250ZW50ID0gZmlsZUNvbnRlbnQucmVwbGFjZSgvXFxyL2csICcnKTtcbiAgICB0aGlzLl9hdG9tQ291bnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fYXRvbVR5cGVzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2JvbmRDb3VudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9ib25kVHlwZXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy54eXpBdG9tQ29vcmRpbmF0ZXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcGFpcnNPZkJvbmRlZEF0b21zID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqIFRvdGFsIG51bWJlciBvZiBhdG9tcyBpbiBhIG1vbGVjdWxlICovXG4gIGdldCBhdG9tQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fYXRvbUNvdW50ID09PSB1bmRlZmluZWQpXG4gICAgICB0aGlzLnNldEF0b21BbmRCb25kQ291bnRzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2F0b21Db3VudCE7XG4gIH1cblxuICAvKiogTnVtYmVyIG9mIGJvbmRzIGluIGEgbW9sZWN1bGUgICovXG4gIGdldCBib25kQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fYm9uZENvdW50ID09PSB1bmRlZmluZWQpXG4gICAgICB0aGlzLnNldEF0b21BbmRCb25kQ291bnRzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2JvbmRDb3VudCE7XG4gIH1cblxuICAvKiogWCBjb29yZGluYXRlcyBvZiBhbGwgYXRvbXMgaW4gYSBtb2xlY3VsZSAgKi9cbiAgZ2V0IHgoKTogRmxvYXQzMkFycmF5IHtcbiAgICB0aGlzLnh5ekF0b21Db29yZGluYXRlcyA/Pz0gdGhpcy5wYXJzZUF0b21Db29yZGluYXRlcygpO1xuICAgIHJldHVybiB0aGlzLnh5ekF0b21Db29yZGluYXRlcy54O1xuICB9O1xuXG4gIC8qKiBZIGNvb3JkaW5hdGVzIG9mIGFsbCBhdG9tcyBpbiBhIG1vbGVjdWxlICAqL1xuICBnZXQgeSgpOiBGbG9hdDMyQXJyYXkge1xuICAgIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzID8/PSB0aGlzLnBhcnNlQXRvbUNvb3JkaW5hdGVzKCk7XG4gICAgcmV0dXJuIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzIS55O1xuICB9O1xuXG4gIC8qKiBaIGNvb3JkaW5hdGVzIG9mIGFsbCBhdG9tcyBpbiBhIG1vbGVjdWxlICAqL1xuICBnZXQgeigpOiBGbG9hdDMyQXJyYXkge1xuICAgIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzID8/PSB0aGlzLnBhcnNlQXRvbUNvb3JkaW5hdGVzKCk7XG4gICAgcmV0dXJuIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzIS56O1xuICB9O1xuXG4gIGdldCBhdG9tVHlwZXMoKTogc3RyaW5nW10ge1xuICAgIHRoaXMuX2F0b21UeXBlcyA/Pz0gdGhpcy5wYXJzZUF0b21UeXBlcygpO1xuICAgIHJldHVybiB0aGlzLl9hdG9tVHlwZXM7XG4gIH1cblxuICBnZXQgcGFpcnNPZkJvbmRlZEF0b21zKCk6IFVpbnQxNkFycmF5W10ge1xuICAgIHRoaXMuX3BhaXJzT2ZCb25kZWRBdG9tcyA/Pz0gdGhpcy5wYXJzZUJvbmRlZEF0b21QYWlycygpO1xuICAgIHJldHVybiB0aGlzLl9wYWlyc09mQm9uZGVkQXRvbXMhO1xuICB9XG5cbiAgZ2V0IGJvbmRUeXBlcygpOiBVaW50MTZBcnJheSB7XG4gICAgdGhpcy5fYm9uZFR5cGVzID8/PSB0aGlzLnBhcnNlQm9uZFR5cGVzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2JvbmRUeXBlcyE7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcGFyc2VBdG9tQW5kQm9uZENvdW50cygpOiBBdG9tQW5kQm9uZENvdW50cztcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldENvdW50c0xpbmVJZHgoKTogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0QXRvbUJsb2NrSWR4KCk6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldEJvbmRCbG9ja0lkeCgpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzaGlmdElkeFRvWENvbHVtbihsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNoaWZ0SWR4VG9BdG9tVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNoaWZ0SWR4VG9Cb25kZWRBdG9tc1BhaXIobGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzaGlmdElkeFRvQm9uZFR5cGUobGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUF0b21UeXBlKGlkeDogbnVtYmVyKTogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCBzZXRBdG9tQW5kQm9uZENvdW50cygpOiB2b2lkIHtcbiAgICBjb25zdCB7YXRvbUNvdW50LCBib25kQ291bnR9ID0gdGhpcy5wYXJzZUF0b21BbmRCb25kQ291bnRzKCk7XG4gICAgdGhpcy5fYXRvbUNvdW50ID0gYXRvbUNvdW50O1xuICAgIHRoaXMuX2JvbmRDb3VudCA9IGJvbmRDb3VudDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXROZXh0Q29sdW1uSWR4KGlkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAvLyBza2lwIG5vbi13aGl0ZXNwYWNlLCBpZiBuZWNlc3NhcnlcbiAgICB3aGlsZSAoIXRoaXMuaXNXaGl0ZXNwYWNlKGlkeCkpXG4gICAgICArK2lkeDtcbiAgICAvLyBza2lwIHdoaXRlc3BhY2VcbiAgICB3aGlsZSAodGhpcy5pc1doaXRlc3BhY2UoaWR4KSlcbiAgICAgICsraWR4O1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHg6IG51bWJlciwgY29sdW1uTnVtYmVyOiBudW1iZXIpIHtcbiAgICBsZXQgaWR4ID0gbGluZVN0YXJ0SWR4O1xuICAgIGNvbnN0IG51bWJlck9mSnVtcHMgPSB0aGlzLmlzV2hpdGVzcGFjZShpZHgpID8gY29sdW1uTnVtYmVyIDogY29sdW1uTnVtYmVyIC0gMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mSnVtcHM7IGkrKylcbiAgICAgIGlkeCA9IHRoaXMuZ2V0TmV4dENvbHVtbklkeChpZHgpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgcGFyc2VBdG9tVHlwZXMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGF0b21Db3VudCA9IHRoaXMuYXRvbUNvdW50O1xuICAgIGNvbnN0IGF0b21UeXBlcyA9IG5ldyBBcnJheTxzdHJpbmc+KGF0b21Db3VudCk7XG4gICAgbGV0IGlkeCA9IHRoaXMuZ2V0QXRvbUJsb2NrSWR4KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdG9tQ291bnQ7IGkrKykge1xuICAgICAgaWR4ID0gdGhpcy5zaGlmdElkeFRvQXRvbVR5cGUoaWR4KTtcbiAgICAgIGF0b21UeXBlc1tpXSA9IHRoaXMucGFyc2VBdG9tVHlwZShpZHgpO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4gYXRvbVR5cGVzO1xuICB9O1xuXG4gIHByb3RlY3RlZCBwYXJzZUF0b21Db29yZGluYXRlcygpOiBDb29yZGluYXRlQXJyYXlzIHtcbiAgICBjb25zdCB4ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmF0b21Db3VudCk7XG4gICAgY29uc3QgeSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5hdG9tQ291bnQpO1xuICAgIGNvbnN0IHogPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXRvbUNvdW50KTtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRBdG9tQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYXRvbUNvdW50OyBpKyspIHtcbiAgICAgIGlkeCA9IHRoaXMuc2hpZnRJZHhUb1hDb2x1bW4oaWR4KTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBbeCwgeSwgel0pIHtcbiAgICAgICAgaXRlbVtpXSA9IHRoaXMucGFyc2VGbG9hdFZhbHVlKGlkeCk7XG4gICAgICAgIGlkeCA9IHRoaXMuZ2V0TmV4dENvbHVtbklkeChpZHgpO1xuICAgICAgfVxuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4ge3g6IHgsIHk6IHksIHo6IHp9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlQm9uZGVkQXRvbVBhaXJzKCk6IFVpbnQxNkFycmF5W10ge1xuICAgIGNvbnN0IGJvbmRlZEF0b21QYWlycyA9IG5ldyBBcnJheTxVaW50MTZBcnJheT4odGhpcy5ib25kQ291bnQpO1xuICAgIGxldCBpZHggPSB0aGlzLmdldEJvbmRCbG9ja0lkeCgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib25kQ291bnQ7IGkrKykge1xuICAgICAgaWR4ID0gdGhpcy5zaGlmdElkeFRvQm9uZGVkQXRvbXNQYWlyKGlkeCk7XG4gICAgICBjb25zdCBwYWlyID0gbmV3IFVpbnQxNkFycmF5KDIpO1xuICAgICAgcGFpclswXSA9IHRoaXMucGFyc2VJbnRWYWx1ZShpZHgpO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0Q29sdW1uSWR4KGlkeCk7XG4gICAgICBwYWlyWzFdID0gdGhpcy5wYXJzZUludFZhbHVlKGlkeCk7XG4gICAgICBib25kZWRBdG9tUGFpcnNbaV0gPSBwYWlyO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4gYm9uZGVkQXRvbVBhaXJzO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlQm9uZFR5cGVzKCk6IFVpbnQxNkFycmF5IHtcbiAgICBjb25zdCBib25kQ291bnQgPSB0aGlzLmJvbmRDb3VudDtcbiAgICBjb25zdCBib25kVHlwZXMgPSBuZXcgVWludDE2QXJyYXkoYm9uZENvdW50KTtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRCb25kQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJvbmRDb3VudDsgaSsrKSB7XG4gICAgICBpZHggPSB0aGlzLnNoaWZ0SWR4VG9Cb25kVHlwZShpZHgpO1xuICAgICAgYm9uZFR5cGVzW2ldID0gdGhpcy5wYXJzZUludFZhbHVlKGlkeCk7XG4gICAgICBpZHggPSB0aGlzLmdldE5leHRMaW5lSWR4KGlkeCk7XG4gICAgfVxuICAgIHJldHVybiBib25kVHlwZXM7XG4gIH07XG5cbiAgcHJvdGVjdGVkIGlzV2hpdGVzcGFjZShpZHg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN5bWJvbCA9IHRoaXMuZmlsZUNvbnRlbnRbaWR4XTtcbiAgICByZXR1cm4gc3ltYm9sID09PSAnICcgfHwgc3ltYm9sID09PSAnXFx0JztcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXROZXh0TGluZUlkeChpZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZmlsZUNvbnRlbnRbaWR4XSAhPT0gJ1xcbicpXG4gICAgICByZXR1cm4gdGhpcy5maWxlQ29udGVudC5pbmRleE9mKCdcXG4nLCBpZHgpICsgMTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gaWR4ICsgMTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUZsb2F0VmFsdWUoaWR4T2ZOdW1iZXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VOdW1lcmljVmFsdWUocGFyc2VGbG9hdCwgaWR4T2ZOdW1iZXIpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlSW50VmFsdWUoaWR4T2ZOdW1iZXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VOdW1lcmljVmFsdWUocGFyc2VJbnQsIGlkeE9mTnVtYmVyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZU51bWVyaWNWYWx1ZShcbiAgICBwYXJzZXJGdW5jdGlvbjogKHN0cjogc3RyaW5nKSA9PiBudW1iZXIsXG4gICAgaWR4T2ZOdW1iZXI6IG51bWJlclxuICApOiBudW1iZXIge1xuICAgIGxldCBlbmQgPSBpZHhPZk51bWJlciArIDE7XG4gICAgd2hpbGUgKCF0aGlzLmlzV2hpdGVzcGFjZShlbmQpKVxuICAgICAgKytlbmQ7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZXJGdW5jdGlvbih0aGlzLmZpbGVDb250ZW50LnN1YnN0cmluZyhpZHhPZk51bWJlciwgZW5kKSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG4iXX0=","import { ChemicalTableParserBase } from './chemical-table-parser-base';\nimport { ASTERISK, D_QUOTE, L, R, S_QUOTE } from './const';\nimport { isAlpha } from './utils';\nexport class MolfileHandlerBase extends ChemicalTableParserBase {\n constructor(molfile) {\n super(molfile);\n this.init(molfile);\n }\n init(molfile) {\n super.init(molfile);\n }\n parseAtomType(idx) {\n let begin = idx;\n let end = begin;\n if (this.isQuote(begin)) {\n end = this.getNextIdenticalChar(begin);\n begin++;\n }\n else {\n end = this.fileContent.indexOf(' ', end);\n }\n return this.fileContent.substring(begin, end);\n }\n isQuote(idx) {\n const letter = this.fileContent[idx].charCodeAt(0);\n return letter === S_QUOTE || letter === D_QUOTE;\n }\n getNextIdenticalChar(idx) {\n const sym = this.fileContent[idx];\n return sym ? this.fileContent.indexOf(sym, idx + 1) : -1;\n }\n isQuery() {\n return this.isQueryOrFragment((char, idx) => {\n return char === S_QUOTE || char === D_QUOTE ||\n (char === L && !isAlpha(this.fileContent.charCodeAt(idx + 1)));\n });\n }\n ;\n isFragment() {\n return this.isQueryOrFragment((char) => {\n return char === R || char === ASTERISK;\n });\n }\n ;\n isQueryOrFragment(condition) {\n const atomCount = this.atomCount;\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < atomCount; i++) {\n idx = this.shiftIdxToAtomType(idx);\n const char = this.fileContent.charCodeAt(idx);\n if (condition(char, idx))\n return true;\n idx = this.getNextLineIdx(idx);\n }\n return false;\n }\n ;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS1oYW5kbGVyLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtb2xmaWxlLWhhbmRsZXItYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQW9CLE1BQU0sOEJBQThCLENBQUM7QUFDeEYsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVsQyxNQUFNLE9BQWdCLGtCQUFtQixTQUFRLHVCQUF1QjtJQUN0RSxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRVMsSUFBSSxDQUFDLE9BQWU7UUFDNUIsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN0QixDQUFDO0lBV1MsYUFBYSxDQUFDLEdBQVc7UUFDakMsSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDO1FBQ2hCLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQztRQUNoQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDdkIsR0FBRyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QyxLQUFLLEVBQUUsQ0FBQztTQUNUO2FBQU07WUFDTCxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVTLE9BQU8sQ0FBQyxHQUFXO1FBQzNCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sTUFBTSxLQUFLLE9BQU8sSUFBSSxNQUFNLEtBQUssT0FBTyxDQUFDO0lBQ2xELENBQUM7SUFFUyxvQkFBb0IsQ0FBQyxHQUFXO1FBQ3hDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFTSxPQUFPO1FBQ1osT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxJQUFZLEVBQUUsR0FBVyxFQUFFLEVBQUU7WUFDMUQsT0FBTyxJQUFJLEtBQUssT0FBTyxJQUFJLElBQUksS0FBSyxPQUFPO2dCQUMzQyxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNoRSxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQSxDQUFDO0lBRUssVUFBVTtRQUNmLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsSUFBWSxFQUFFLEVBQUU7WUFDN0MsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxRQUFRLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBQUEsQ0FBQztJQUVRLGlCQUFpQixDQUFDLFNBQWlEO1FBQzNFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ2pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbEMsR0FBRyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNuQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM5QyxJQUFJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO2dCQUN0QixPQUFPLElBQUksQ0FBQztZQUNkLEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2hDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQUEsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGVtaWNhbFRhYmxlUGFyc2VyQmFzZSwgQXRvbUFuZEJvbmRDb3VudHN9IGZyb20gJy4vY2hlbWljYWwtdGFibGUtcGFyc2VyLWJhc2UnO1xuaW1wb3J0IHsgQVNURVJJU0ssIERfUVVPVEUsIEwsIFIsIFNfUVVPVEUgfSBmcm9tICcuL2NvbnN0JztcbmltcG9ydCB7IGlzQWxwaGEgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE1vbGZpbGVIYW5kbGVyQmFzZSBleHRlbmRzIENoZW1pY2FsVGFibGVQYXJzZXJCYXNlIHtcbiAgY29uc3RydWN0b3IobW9sZmlsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobW9sZmlsZSk7XG4gICAgdGhpcy5pbml0KG1vbGZpbGUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGluaXQobW9sZmlsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIuaW5pdChtb2xmaWxlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUF0b21BbmRCb25kQ291bnRzKCk6IEF0b21BbmRCb25kQ291bnRzO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0Q291bnRzTGluZUlkeCgpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRBdG9tQmxvY2tJZHgoKTogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3Qgc2hpZnRJZHhUb1hDb2x1bW4obGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzaGlmdElkeFRvQXRvbVR5cGUobGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRCb25kQmxvY2tJZHgoKTogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3Qgc2hpZnRJZHhUb0JvbmRlZEF0b21zUGFpcihsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNoaWZ0SWR4VG9Cb25kVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcblxuICBwcm90ZWN0ZWQgcGFyc2VBdG9tVHlwZShpZHg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgbGV0IGJlZ2luID0gaWR4O1xuICAgIGxldCBlbmQgPSBiZWdpbjtcbiAgICBpZiAodGhpcy5pc1F1b3RlKGJlZ2luKSkge1xuICAgICAgZW5kID0gdGhpcy5nZXROZXh0SWRlbnRpY2FsQ2hhcihiZWdpbik7XG4gICAgICBiZWdpbisrO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmQgPSB0aGlzLmZpbGVDb250ZW50LmluZGV4T2YoJyAnLCBlbmQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5maWxlQ29udGVudC5zdWJzdHJpbmcoYmVnaW4sIGVuZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNRdW90ZShpZHg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGxldHRlciA9IHRoaXMuZmlsZUNvbnRlbnRbaWR4XS5jaGFyQ29kZUF0KDApO1xuICAgIHJldHVybiBsZXR0ZXIgPT09IFNfUVVPVEUgfHwgbGV0dGVyID09PSBEX1FVT1RFO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldE5leHRJZGVudGljYWxDaGFyKGlkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBzeW0gPSB0aGlzLmZpbGVDb250ZW50W2lkeF07XG4gICAgcmV0dXJuIHN5bSA/IHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZihzeW0sIGlkeCArIDEpIDogLTE7XG4gIH1cblxuICBwdWJsaWMgaXNRdWVyeSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc1F1ZXJ5T3JGcmFnbWVudCgoY2hhcjogbnVtYmVyLCBpZHg6IG51bWJlcikgPT4ge1xuICAgICAgcmV0dXJuIGNoYXIgPT09IFNfUVVPVEUgfHwgY2hhciA9PT0gRF9RVU9URSB8fFxuICAgICAgKGNoYXIgPT09IEwgJiYgIWlzQWxwaGEodGhpcy5maWxlQ29udGVudC5jaGFyQ29kZUF0KGlkeCArIDEpKSlcbiAgICB9KVxuICB9O1xuXG4gIHB1YmxpYyBpc0ZyYWdtZW50KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzUXVlcnlPckZyYWdtZW50KChjaGFyOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBjaGFyID09PSBSIHx8IGNoYXIgPT09IEFTVEVSSVNLO1xuICAgIH0pXG4gIH07XG5cbiAgcHJvdGVjdGVkIGlzUXVlcnlPckZyYWdtZW50KGNvbmRpdGlvbjogKGNoYXI6IG51bWJlciwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICBjb25zdCBhdG9tQ291bnQgPSB0aGlzLmF0b21Db3VudDtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRBdG9tQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0b21Db3VudDsgaSsrKSB7XG4gICAgICBpZHggPSB0aGlzLnNoaWZ0SWR4VG9BdG9tVHlwZShpZHgpO1xuICAgICAgY29uc3QgY2hhciA9IHRoaXMuZmlsZUNvbnRlbnQuY2hhckNvZGVBdChpZHgpO1xuICAgICAgaWYgKGNvbmRpdGlvbihjaGFyLCBpZHgpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGlkeCA9IHRoaXMuZ2V0TmV4dExpbmVJZHgoaWR4KTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xufVxuIl19","export const R = 82;\nexport const L = 76;\nexport const D_QUOTE = 34;\nexport const S_QUOTE = 39;\nexport const ASTERISK = 42;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb25zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3BCLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDcEIsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUMxQixNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBQzFCLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgUiA9IDgyO1xuZXhwb3J0IGNvbnN0IEwgPSA3NjtcbmV4cG9ydCBjb25zdCBEX1FVT1RFID0gMzQ7XG5leHBvcnQgY29uc3QgU19RVU9URSA9IDM5O1xuZXhwb3J0IGNvbnN0IEFTVEVSSVNLID0gNDI7XG4iXX0=","export function isAlpha(charCode) {\n return (charCode > 64 && charCode < 91) ||\n (charCode > 96 && charCode < 123);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLFVBQVUsT0FBTyxDQUFDLFFBQWdCO0lBQ3BDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsRUFBRSxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDbkMsQ0FBQyxRQUFRLEdBQUcsRUFBRSxJQUFJLFFBQVEsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIGlzQWxwaGEoY2hhckNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoY2hhckNvZGUgPiA2NCAmJiBjaGFyQ29kZSA8IDkxKSB8fFxuICAgICAgICAoY2hhckNvZGUgPiA5NiAmJiBjaGFyQ29kZSA8IDEyMyk7XG59XG4iXX0=","import { MolfileHandlerBase } from './molfile-handler-base';\nexport class MolfileV3KHandler extends MolfileHandlerBase {\n constructor(molfile) {\n super(molfile);\n this.init(molfile);\n }\n shiftIdxToAtomType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 4 /* V3K_CONST.ATOM_TYPE_COL */);\n }\n getCountsLineIdx() {\n return this.fileContent.indexOf(\"M V30 COUNTS \" /* V3K_CONST.BEGIN_COUNTS_LINE */);\n }\n getAtomBlockIdx() {\n let idx = this.fileContent.indexOf(\"M V30 BEGIN ATOM\" /* V3K_CONST.BEGIN_ATOM_BLOCK */);\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n shiftIdxToXColumn(lineStartIdx) {\n let idx = this.shiftIdxToAtomType(lineStartIdx);\n if (this.isQuote(idx)) {\n idx = this.getNextIdenticalChar(idx);\n idx = this.getNextColumnIdx(idx);\n return idx;\n }\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 5 /* V3K_CONST.X_COL */);\n }\n shiftIdxToBondedAtomsPair(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 5 /* V3K_CONST.FIRST_BONDED_ATOM_COL */);\n }\n shiftIdxToBondType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 4 /* V3K_CONST.BOND_TYPE_COL */);\n }\n getBondBlockIdx() {\n return this.getNextLineIdx(this.fileContent.indexOf(\"M V30 BEGIN BOND\" /* V3K_CONST.BEGIN_BOND_BLOCK */));\n }\n static validate(molfile) {\n return (molfile.indexOf(\"V3000\" /* V3K_CONST.HEADER */) !== -1 &&\n molfile.indexOf(\"M END\" /* V3K_CONST.END */) !== -1);\n }\n parseAtomAndBondCounts() {\n // parse atom count\n let begin = this.fileContent.indexOf(\"M V30 COUNTS \" /* V3K_CONST.BEGIN_COUNTS_LINE */) + 14 /* V3K_CONST.COUNTS_SHIFT */;\n let end = this.fileContent.indexOf(' ', begin + 1);\n const numOfAtoms = parseInt(this.fileContent.substring(begin, end));\n // parse bond count\n begin = end + 1;\n end = this.fileContent.indexOf(' ', begin + 1);\n const numOfBonds = parseInt(this.fileContent.substring(begin, end));\n return { atomCount: numOfAtoms, bondCount: numOfBonds };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS12M2staGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1vbGZpbGUtdjNrLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFLMUQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLGtCQUFrQjtJQUN2RCxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxrQ0FBMEIsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZ0JBQWdCO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLG9EQUE2QixDQUFDO0lBQy9ELENBQUM7SUFFUyxlQUFlO1FBQ3ZCLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxzREFBNEIsQ0FBQztRQUMvRCxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFUyxpQkFBaUIsQ0FBQyxZQUFvQjtRQUM5QyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3JCLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckMsR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqQyxPQUFPLEdBQUcsQ0FBQztTQUNaO1FBQ0QsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSwwQkFBa0IsQ0FBQztJQUN2RSxDQUFDO0lBRVMseUJBQXlCLENBQUMsWUFBb0I7UUFDdEQsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSwwQ0FBa0MsQ0FBQztJQUN2RixDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxrQ0FBMEIsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZUFBZTtRQUN2QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLHNEQUE0QixDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVNLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBZTtRQUNwQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sZ0NBQWtCLEtBQUssQ0FBQyxDQUFDO1lBQ2hELE9BQU8sQ0FBQyxPQUFPLDhCQUFlLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRVMsc0JBQXNCO1FBQzlCLG1CQUFtQjtRQUNuQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sb0RBQTZCLGtDQUF5QixDQUFDO1FBQzNGLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXBFLG1CQUFtQjtRQUNuQixLQUFLLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNoQixHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMvQyxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFcEUsT0FBTyxFQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBQyxDQUFDO0lBQ3hELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QXRvbUFuZEJvbmRDb3VudHN9IGZyb20gJy4vY2hlbWljYWwtdGFibGUtcGFyc2VyLWJhc2UnO1xuaW1wb3J0IHtNb2xmaWxlSGFuZGxlckJhc2V9IGZyb20gJy4vbW9sZmlsZS1oYW5kbGVyLWJhc2UnO1xuaW1wb3J0IHtWM0tfQ09OU1R9IGZyb20gJy4uL2Zvcm1hdHMvbW9sZmlsZS12M2stY29uc3QnO1xuaW1wb3J0IHsgTCwgUiB9IGZyb20gJy4vY29uc3QnO1xuaW1wb3J0IHsgaXNBbHBoYSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgTW9sZmlsZVYzS0hhbmRsZXIgZXh0ZW5kcyBNb2xmaWxlSGFuZGxlckJhc2Uge1xuICBjb25zdHJ1Y3Rvcihtb2xmaWxlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtb2xmaWxlKTtcbiAgICB0aGlzLmluaXQobW9sZmlsZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb0F0b21UeXBlKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULkFUT01fVFlQRV9DT0wpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldENvdW50c0xpbmVJZHgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5maWxlQ29udGVudC5pbmRleE9mKFYzS19DT05TVC5CRUdJTl9DT1VOVFNfTElORSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0QXRvbUJsb2NrSWR4KCk6IG51bWJlciB7XG4gICAgbGV0IGlkeCA9IHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZihWM0tfQ09OU1QuQkVHSU5fQVRPTV9CTE9DSyk7XG4gICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb1hDb2x1bW4obGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBpZHggPSB0aGlzLnNoaWZ0SWR4VG9BdG9tVHlwZShsaW5lU3RhcnRJZHgpO1xuICAgIGlmICh0aGlzLmlzUXVvdGUoaWR4KSkge1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0SWRlbnRpY2FsQ2hhcihpZHgpO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0Q29sdW1uSWR4KGlkeCk7XG4gICAgICByZXR1cm4gaWR4O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULlhfQ09MKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaGlmdElkeFRvQm9uZGVkQXRvbXNQYWlyKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULkZJUlNUX0JPTkRFRF9BVE9NX0NPTCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb0JvbmRUeXBlKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULkJPTkRfVFlQRV9DT0wpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEJvbmRCbG9ja0lkeCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmdldE5leHRMaW5lSWR4KHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZihWM0tfQ09OU1QuQkVHSU5fQk9ORF9CTE9DSykpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyB2YWxpZGF0ZShtb2xmaWxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKG1vbGZpbGUuaW5kZXhPZihWM0tfQ09OU1QuSEVBREVSKSAhPT0gLTEgJiZcbiAgICBtb2xmaWxlLmluZGV4T2YoVjNLX0NPTlNULkVORCkgIT09IC0xKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUF0b21BbmRCb25kQ291bnRzKCk6IEF0b21BbmRCb25kQ291bnRzIHtcbiAgICAvLyBwYXJzZSBhdG9tIGNvdW50XG4gICAgbGV0IGJlZ2luID0gdGhpcy5maWxlQ29udGVudC5pbmRleE9mKFYzS19DT05TVC5CRUdJTl9DT1VOVFNfTElORSkgKyBWM0tfQ09OU1QuQ09VTlRTX1NISUZUO1xuICAgIGxldCBlbmQgPSB0aGlzLmZpbGVDb250ZW50LmluZGV4T2YoJyAnLCBiZWdpbiArIDEpO1xuICAgIGNvbnN0IG51bU9mQXRvbXMgPSBwYXJzZUludCh0aGlzLmZpbGVDb250ZW50LnN1YnN0cmluZyhiZWdpbiwgZW5kKSk7XG5cbiAgICAvLyBwYXJzZSBib25kIGNvdW50XG4gICAgYmVnaW4gPSBlbmQgKyAxO1xuICAgIGVuZCA9IHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZignICcsIGJlZ2luICsgMSk7XG4gICAgY29uc3QgbnVtT2ZCb25kcyA9IHBhcnNlSW50KHRoaXMuZmlsZUNvbnRlbnQuc3Vic3RyaW5nKGJlZ2luLCBlbmQpKTtcblxuICAgIHJldHVybiB7YXRvbUNvdW50OiBudW1PZkF0b21zLCBib25kQ291bnQ6IG51bU9mQm9uZHN9O1xuICB9XG59XG4iXX0=","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nimport * as grok from 'datagrok-api/grok';\nimport * as DG from 'datagrok-api/dg';\nexport const tests = {};\nexport let currentCategory;\nexport var assure;\n(function (assure) {\n function notNull(value, name) {\n if (value == null)\n throw new Error(`${name == null ? 'Value' : name} not defined`);\n }\n assure.notNull = notNull;\n})(assure || (assure = {}));\nexport class TestContext {\n constructor(catchUnhandled, report) {\n this.catchUnhandled = true;\n this.report = false;\n if (catchUnhandled !== undefined)\n this.catchUnhandled = catchUnhandled;\n if (report !== undefined)\n this.report = report;\n }\n ;\n}\nexport class Test {\n constructor(category, name, test, options) {\n var _a;\n this.category = category;\n this.name = name;\n options !== null && options !== void 0 ? options : (options = {});\n (_a = options.timeout) !== null && _a !== void 0 ? _a : (options.timeout = 30000);\n this.options = options;\n this.test = () => __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n let result = '';\n try {\n result = yield test();\n }\n catch (e) {\n reject(e);\n }\n resolve(result);\n }));\n });\n }\n}\nexport function testEvent(event, handler, trigger, ms = 0) {\n return __awaiter(this, void 0, void 0, function* () {\n let sub;\n return new Promise((resolve, reject) => {\n sub = event.subscribe((args) => {\n try {\n handler(args);\n }\n catch (e) {\n reject(e);\n }\n sub.unsubscribe();\n resolve('OK');\n });\n setTimeout(() => {\n sub.unsubscribe();\n // eslint-disable-next-line prefer-promise-reject-errors\n reject('timeout');\n }, ms);\n trigger();\n });\n });\n}\nexport function test(name, test, options) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n if (tests[currentCategory].tests == undefined)\n tests[currentCategory].tests = [];\n tests[currentCategory].tests.push(new Test(currentCategory, name, test, options));\n}\n/* Tests two objects for equality, throws an exception if they are not equal. */\nexport function expect(actual, expected) {\n if (actual !== expected)\n throw new Error(`Expected \"${expected}\", got \"${actual}\"`);\n}\nexport function expectFloat(actual, expected, tolerance = 0.001) {\n const areEqual = Math.abs(actual - expected) < tolerance;\n if (!areEqual)\n throw new Error(`Expected ${expected}, got ${actual} (tolerance = ${tolerance})`);\n}\nexport function expectObject(actual, expected) {\n for (const [expectedKey, expectedValue] of Object.entries(expected)) {\n if (!actual.hasOwnProperty(expectedKey))\n throw new Error(`Expected property \"${expectedKey}\" not found`);\n const actualValue = actual[expectedKey];\n if (actualValue instanceof Array && expectedValue instanceof Array)\n expectArray(actualValue, expectedValue);\n else if (actualValue instanceof Object && expectedValue instanceof Object)\n expectObject(actualValue, expectedValue);\n else if (Number.isFinite(actualValue) && Number.isFinite(expectedValue))\n expectFloat(actualValue, expectedValue);\n else if (actualValue != expectedValue)\n throw new Error(`Expected (${expectedValue}) for key '${expectedKey}', got (${actualValue})`);\n }\n}\nexport function expectArray(actual, expected) {\n const actualLength = actual.length;\n const expectedLength = expected.length;\n if (actualLength != expectedLength) {\n throw new Error(`Arrays are of different length: actual array length is ${actualLength} ` +\n `and expected array length is ${expectedLength}`);\n }\n for (let i = 0; i < actualLength; i++) {\n if (actual[i] instanceof Array && expected[i] instanceof Array)\n expectArray(actual[i], expected[i]);\n else if (actual[i] instanceof Object && expected[i] instanceof Object)\n expectObject(actual[i], expected[i]);\n else if (actual[i] != expected[i])\n throw new Error(`Expected ${expected[i]} at position ${i}, got ${actual[i]}`);\n }\n}\n/* Defines a test suite. */\nexport function category(category, tests) {\n currentCategory = category;\n tests();\n}\n/* Defines a function to be executed before the tests in this category are executed. */\nexport function before(before) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].before = before;\n}\n/* Defines a function to be executed after the tests in this category are executed. */\nexport function after(after) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].after = after;\n}\nexport function runTests(options) {\n var _a, _b, _c, _d;\n var _e;\n return __awaiter(this, void 0, void 0, function* () {\n const results = [];\n const packageName = (_b = (_a = grok.functions.getCurrentCall()) === null || _a === void 0 ? void 0 : _a.func) === null || _b === void 0 ? void 0 : _b.package;\n console.log(`Running tests`);\n options !== null && options !== void 0 ? options : (options = {});\n (_c = (_e = options).testContext) !== null && _c !== void 0 ? _c : (_e.testContext = new TestContext());\n grok.shell.lastError = '';\n for (const [key, value] of Object.entries(tests)) {\n if ((options === null || options === void 0 ? void 0 : options.category) != undefined) {\n if (!key.toLowerCase().startsWith(options === null || options === void 0 ? void 0 : options.category.toLowerCase()))\n continue;\n }\n console.log(`Started ${key} category`);\n try {\n if (value.before)\n yield value.before();\n }\n catch (x) {\n value.beforeStatus = x.toString();\n }\n const t = (_d = value.tests) !== null && _d !== void 0 ? _d : [];\n const res = [];\n for (let i = 0; i < t.length; i++)\n res.push(yield execTest(t[i], options === null || options === void 0 ? void 0 : options.test));\n const data = (yield Promise.all(res)).filter((d) => d.result != 'skipped');\n try {\n if (value.after)\n yield value.after();\n }\n catch (x) {\n value.afterStatus = x.toString();\n }\n if (value.afterStatus)\n data.push({ category: key, name: 'init', result: value.afterStatus, success: false, ms: 0, skipped: false });\n if (value.beforeStatus)\n data.push({ category: key, name: 'init', result: value.beforeStatus, success: false, ms: 0, skipped: false });\n results.push(...data);\n }\n if (options.testContext.catchUnhandled) {\n yield delay(1000);\n if (grok.shell.lastError.length > 0) {\n results.push({\n category: 'Unhandled exceptions',\n name: 'exceptions',\n result: grok.shell.lastError, success: false, ms: 0, skipped: false\n });\n }\n }\n if (options.testContext.report) {\n const logger = new DG.Logger();\n const successful = results.filter((r) => r.success).length;\n const skipped = results.filter((r) => r.skipped).length;\n const failed = results.filter((r) => !r.success);\n const description = 'Package @package tested: @successful successful, @skipped skipped, @failed failed tests';\n const params = {\n successful: successful,\n skipped: skipped,\n failed: failed.length,\n package: packageName\n };\n for (const r of failed)\n Object.assign(params, { [`${r.category} | ${r.name}`]: r.result });\n logger.log(description, params, 'package-tested');\n }\n return results;\n });\n}\nfunction execTest(t, predicate) {\n var _a, _b, _c;\n return __awaiter(this, void 0, void 0, function* () {\n let r;\n const filter = predicate != undefined && (!t.name.toLowerCase().startsWith(predicate.toLowerCase()));\n const skip = ((_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason) || filter;\n const skipReason = filter ? 'skipped' : (_b = t.options) === null || _b === void 0 ? void 0 : _b.skipReason;\n if (!skip)\n console.log(`Started ${t.category} ${t.name}`);\n const start = new Date();\n try {\n if (skip)\n r = { success: true, result: skipReason, ms: 0, skipped: true };\n else\n r = { success: true, result: (_c = yield t.test()) !== null && _c !== void 0 ? _c : 'OK', ms: 0, skipped: false };\n }\n catch (x) {\n r = { success: false, result: x.toString(), ms: 0, skipped: false };\n }\n const stop = new Date();\n // @ts-ignore\n r.ms = stop - start;\n if (!skip)\n console.log(`Finished ${t.category} ${t.name} for ${r.ms} ms`);\n r.category = t.category;\n r.name = t.name;\n return r;\n });\n}\n/* Waits [ms] milliseconds */\nexport function delay(ms) {\n return __awaiter(this, void 0, void 0, function* () {\n yield new Promise((r) => setTimeout(r, ms));\n });\n}\nexport function awaitCheck(checkHandler, error = 'Timeout exceeded', wait = 500) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n clearInterval(interval);\n reject(new Error(error));\n }, wait);\n // @ts-ignore\n const interval = setInterval(() => {\n if (checkHandler()) {\n clearInterval(interval);\n resolve();\n }\n }, 50);\n });\n });\n}\nexport function isDialogPresent(dialogTitle) {\n for (let i = 0; i < DG.Dialog.getOpenDialogs().length; i++) {\n if (DG.Dialog.getOpenDialogs()[i].title == dialogTitle)\n return true;\n }\n return false;\n}\nexport function testViewer(v, df, detectSemanticTypes = false) {\n return __awaiter(this, void 0, void 0, function* () {\n if (detectSemanticTypes)\n yield grok.data.detectSemanticTypes(df);\n const tv = grok.shell.addTableView(df);\n const viewerName = `[name=viewer-${v.replace(/\\s+/g, '-')} i]`;\n const selector = `${viewerName} canvas,${viewerName} svg,${viewerName} img,\n ${viewerName} input,${viewerName} h1,${viewerName} a`;\n const res = [];\n try {\n let viewer = tv.addViewer(v);\n yield awaitCheck(() => document.querySelector(selector) !== null, 'cannot load viewer', 3000);\n res.push(Array.from(tv.viewers).length);\n Array.from(df.row(0).cells).forEach((c) => c.value = null);\n df.rows.select((row) => row.idx > 1 && row.idx < 7);\n for (let i = 7; i < 12; i++)\n df.filter.set(i, false);\n df.currentRowIdx = 1;\n const props = viewer.getOptions(true).look;\n const newProps = {};\n Object.keys(props).filter((k) => typeof props[k] === 'boolean').forEach((k) => newProps[k] = !props[k]);\n viewer.setOptions(newProps);\n yield delay(250);\n const layout = tv.saveLayout();\n const oldProps = viewer.getOptions().look;\n tv.resetLayout();\n res.push(Array.from(tv.viewers).length);\n tv.loadLayout(layout);\n yield awaitCheck(() => document.querySelector(selector) !== null, 'cannot load viewer from layout', 3000);\n yield delay(250);\n res.push(Array.from(tv.viewers).length);\n viewer = Array.from(tv.viewers).find((v) => v.type !== 'Grid');\n expectArray(res, [2, 1, 2]);\n expect(JSON.stringify(viewer.getOptions().look), JSON.stringify(oldProps));\n }\n finally {\n tv.close();\n grok.shell.closeTable(df);\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSXRDLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FLZCxFQUFFLENBQUM7QUFFUCxNQUFNLENBQUMsSUFBSSxlQUF1QixDQUFDO0FBRW5DLE1BQU0sS0FBVyxNQUFNLENBTXRCO0FBTkQsV0FBaUIsTUFBTTtJQUVyQixTQUFnQixPQUFPLENBQUMsS0FBVSxFQUFFLElBQWE7UUFDL0MsSUFBSSxLQUFLLElBQUksSUFBSTtZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksY0FBYyxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUhlLGNBQU8sVUFHdEIsQ0FBQTtBQUNILENBQUMsRUFOZ0IsTUFBTSxLQUFOLE1BQU0sUUFNdEI7QUFRRCxNQUFNLE9BQU8sV0FBVztJQUl0QixZQUFZLGNBQXdCLEVBQUUsTUFBZ0I7UUFIdEQsbUJBQWMsR0FBRyxJQUFJLENBQUM7UUFDdEIsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUdiLElBQUksY0FBYyxLQUFLLFNBQVM7WUFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztRQUN2RSxJQUFJLE1BQU0sS0FBSyxTQUFTO1lBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDakQsQ0FBQztJQUFBLENBQUM7Q0FDSDtBQUVELE1BQU0sT0FBTyxJQUFJO0lBTWYsWUFBWSxRQUFnQixFQUFFLElBQVksRUFBRSxJQUF3QixFQUFFLE9BQXFCOztRQUN6RixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsSUFBSSxHQUFH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SyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUUsQ0FBQztZQUNoRSxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FDNUU7Z0JBQVM7WUFDUixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMzQjtJQUNILENBQUM7Q0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCBUaW1lb3V0ID0gTm9kZUpTLlRpbWVvdXQ7XG5cbmV4cG9ydCBjb25zdCB0ZXN0czoge1xuICBba2V5OiBzdHJpbmddOiB7XG4gICAgdGVzdHM/OiBUZXN0W10sIGJlZm9yZT86ICgpID0+IFByb21pc2U8dm9pZD4sIGFmdGVyPzogKCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgICBiZWZvcmVTdGF0dXM/OiBzdHJpbmcsIGFmdGVyU3RhdHVzPzogc3RyaW5nXG4gIH1cbn0gPSB7fTtcblxuZXhwb3J0IGxldCBjdXJyZW50Q2F0ZWdvcnk6IHN0cmluZztcblxuZXhwb3J0IG5hbWVzcGFjZSBhc3N1cmUge1xuXG4gIGV4cG9ydCBmdW5jdGlvbiBub3ROdWxsKHZhbHVlOiBhbnksIG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtuYW1lID09IG51bGwgPyAnVmFsdWUnIDogbmFtZX0gbm90IGRlZmluZWRgKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RPcHRpb25zIHtcbiAgdGltZW91dD86IG51bWJlcjtcbiAgdW5oYW5kbGVkRXhjZXB0aW9uVGltZW91dD86IG51bWJlcjtcbiAgc2tpcFJlYXNvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3RDb250ZXh0IHtcbiAgY2F0Y2hVbmhhbmRsZWQgPSB0cnVlO1xuICByZXBvcnQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihjYXRjaFVuaGFuZGxlZD86IGJvb2xlYW4sIHJlcG9ydD86IGJvb2xlYW4pIHtcbiAgICBpZiAoY2F0Y2hVbmhhbmRsZWQgIT09IHVuZGVmaW5lZCkgdGhpcy5jYXRjaFVuaGFuZGxlZCA9IGNhdGNoVW5oYW5kbGVkO1xuICAgIGlmIChyZXBvcnQgIT09IHVuZGVmaW5lZCkgdGhpcy5yZXBvcnQgPSByZXBvcnQ7XG4gIH07XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0IHtcbiAgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+O1xuICBuYW1lOiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIG9wdGlvbnM/OiBUZXN0T3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihjYXRlZ29yeTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHRlc3Q6ICgpID0+IFByb21pc2U8YW55Piwgb3B0aW9ucz86IFRlc3RPcHRpb25zKSB7XG4gICAgdGhpcy5jYXRlZ29yeSA9IGNhdGVnb3J5O1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgb3B0aW9ucyA/Pz0ge307XG4gICAgb3B0aW9ucy50aW1lb3V0ID8/PSAzMDAwMDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMudGVzdCA9IGFzeW5jICgpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9ICcnO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHRlc3QoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRlc3RFdmVudDxUPihldmVudDogT2JzZXJ2YWJsZTxUPixcbiAgaGFuZGxlcjogKGFyZ3M6IFQpID0+IHZvaWQsIHRyaWdnZXI6ICgpID0+IHZvaWQsIG1zOiBudW1iZXIgPSAwKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgbGV0IHN1YjogU3Vic2NyaXB0aW9uO1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHN1YiA9IGV2ZW50LnN1YnNjcmliZSgoYXJncykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlcihhcmdzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICByZXNvbHZlKCdPSycpO1xuICAgIH0pO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KCd0aW1lb3V0Jyk7XG4gICAgfSwgbXMpO1xuICAgIHRyaWdnZXIoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0KG5hbWU6IHN0cmluZywgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+LCBvcHRpb25zPzogVGVzdE9wdGlvbnMpOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPSBbXTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS50ZXN0cyEucHVzaChuZXcgVGVzdChjdXJyZW50Q2F0ZWdvcnksIG5hbWUsIHRlc3QsIG9wdGlvbnMpKTtcbn1cblxuLyogVGVzdHMgdHdvIG9iamVjdHMgZm9yIGVxdWFsaXR5LCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZXkgYXJlIG5vdCBlcXVhbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3QoYWN0dWFsOiBhbnksIGV4cGVjdGVkOiBhbnkpOiB2b2lkIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBcIiR7ZXhwZWN0ZWR9XCIsIGdvdCBcIiR7YWN0dWFsfVwiYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RGbG9hdChhY3R1YWw6IG51bWJlciwgZXhwZWN0ZWQ6IG51bWJlciwgdG9sZXJhbmNlID0gMC4wMDEpOiB2b2lkIHtcbiAgY29uc3QgYXJlRXF1YWwgPSBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPCB0b2xlcmFuY2U7XG4gIGlmICghYXJlRXF1YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSwgZ290ICR7YWN0dWFsfSAodG9sZXJhbmNlID0gJHt0b2xlcmFuY2V9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0T2JqZWN0KGFjdHVhbDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSwgZXhwZWN0ZWQ6IHsgW2tleTogc3RyaW5nXTogYW55IH0pIHtcbiAgZm9yIChjb25zdCBbZXhwZWN0ZWRLZXksIGV4cGVjdGVkVmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGV4cGVjdGVkKSkge1xuICAgIGlmICghYWN0dWFsLmhhc093blByb3BlcnR5KGV4cGVjdGVkS2V5KSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgcHJvcGVydHkgXCIke2V4cGVjdGVkS2V5fVwiIG5vdCBmb3VuZGApO1xuXG4gICAgY29uc3QgYWN0dWFsVmFsdWUgPSBhY3R1YWxbZXhwZWN0ZWRLZXldO1xuICAgIGlmIChhY3R1YWxWYWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIGV4cGVjdGVkVmFsdWUgaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgIGV4cGVjdEFycmF5KGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKTtcbiAgICBlbHNlIGlmIChhY3R1YWxWYWx1ZSBpbnN0YW5jZW9mIE9iamVjdCAmJiBleHBlY3RlZFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0KVxuICAgICAgZXhwZWN0T2JqZWN0KGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKTtcbiAgICBlbHNlIGlmIChOdW1iZXIuaXNGaW5pdGUoYWN0dWFsVmFsdWUpICYmIE51bWJlci5pc0Zpbml0ZShleHBlY3RlZFZhbHVlKSlcbiAgICAgIGV4cGVjdEZsb2F0KGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKTtcbiAgICBlbHNlIGlmIChhY3R1YWxWYWx1ZSAhPSBleHBlY3RlZFZhbHVlKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAoJHtleHBlY3RlZFZhbHVlfSkgZm9yIGtleSAnJHtleHBlY3RlZEtleX0nLCBnb3QgKCR7YWN0dWFsVmFsdWV9KWApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RBcnJheShhY3R1YWw6IEFycmF5TGlrZTxhbnk+LCBleHBlY3RlZDogQXJyYXlMaWtlPGFueT4pIHtcbiAgY29uc3QgYWN0dWFsTGVuZ3RoID0gYWN0dWFsLmxlbmd0aDtcbiAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7XG5cbiAgaWYgKGFjdHVhbExlbmd0aCAhPSBleHBlY3RlZExlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXJyYXlzIGFyZSBvZiBkaWZmZXJlbnQgbGVuZ3RoOiBhY3R1YWwgYXJyYXkgbGVuZ3RoIGlzICR7YWN0dWFsTGVuZ3RofSBgICtcbiAgICAgIGBhbmQgZXhwZWN0ZWQgYXJyYXkgbGVuZ3RoIGlzICR7ZXhwZWN0ZWRMZW5ndGh9YCk7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFjdHVhbExlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFjdHVhbFtpXSBpbnN0YW5jZW9mIEFycmF5ICYmIGV4cGVjdGVkW2ldIGluc3RhbmNlb2YgQXJyYXkpXG4gICAgICBleHBlY3RBcnJheShhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTtcbiAgICBlbHNlIGlmIChhY3R1YWxbaV0gaW5zdGFuY2VvZiBPYmplY3QgJiYgZXhwZWN0ZWRbaV0gaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgICBleHBlY3RPYmplY3QoYWN0dWFsW2ldLCBleHBlY3RlZFtpXSk7XG4gICAgZWxzZSBpZiAoYWN0dWFsW2ldICE9IGV4cGVjdGVkW2ldKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkW2ldfSBhdCBwb3NpdGlvbiAke2l9LCBnb3QgJHthY3R1YWxbaV19YCk7XG4gIH1cbn1cblxuLyogRGVmaW5lcyBhIHRlc3Qgc3VpdGUuICovXG5leHBvcnQgZnVuY3Rpb24gY2F0ZWdvcnkoY2F0ZWdvcnk6IHN0cmluZywgdGVzdHM6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgY3VycmVudENhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gIHRlc3RzKCk7XG59XG5cbi8qIERlZmluZXMgYSBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBiZWZvcmUgdGhlIHRlc3RzIGluIHRoaXMgY2F0ZWdvcnkgYXJlIGV4ZWN1dGVkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJlZm9yZShiZWZvcmU6ICgpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS5iZWZvcmUgPSBiZWZvcmU7XG59XG5cbi8qIERlZmluZXMgYSBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBhZnRlciB0aGUgdGVzdHMgaW4gdGhpcyBjYXRlZ29yeSBhcmUgZXhlY3V0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXIoYWZ0ZXI6ICgpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS5hZnRlciA9IGFmdGVyO1xufVxuXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5UZXN0cyhvcHRpb25zPzogeyBjYXRlZ29yeT86IHN0cmluZywgdGVzdD86IHN0cmluZywgdGVzdENvbnRleHQ/OiBUZXN0Q29udGV4dCB9KSB7XG4gIGNvbnN0IHJlc3VsdHM6IHsgY2F0ZWdvcnk/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIHN1Y2Nlc3M6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfVtdID0gW107XG4gIGNvbnN0IHBhY2thZ2VOYW1lID0gZ3Jvay5mdW5jdGlvbnMuZ2V0Q3VycmVudENhbGwoKT8uZnVuYz8ucGFja2FnZTtcbiAgY29uc29sZS5sb2coYFJ1bm5pbmcgdGVzdHNgKTtcbiAgb3B0aW9ucyA/Pz0ge307XG4gIG9wdGlvbnMhLnRlc3RDb250ZXh0ID8/PSBuZXcgVGVzdENvbnRleHQoKTtcbiAgZ3Jvay5zaGVsbC5sYXN0RXJyb3IgPSAnJztcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModGVzdHMpKSB7XG4gICAgaWYgKG9wdGlvbnM/LmNhdGVnb3J5ICE9IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCFrZXkudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKG9wdGlvbnM/LmNhdGVnb3J5LnRvTG93ZXJDYXNlKCkpKVxuICAgICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYFN0YXJ0ZWQgJHtrZXl9IGNhdGVnb3J5YCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh2YWx1ZS5iZWZvcmUpXG4gICAgICAgIGF3YWl0IHZhbHVlLmJlZm9yZSgpO1xuICAgIH0gY2F0Y2ggKHg6IGFueSkge1xuICAgICAgdmFsdWUuYmVmb3JlU3RhdHVzID0geC50b1N0cmluZygpO1xuICAgIH1cbiAgICBjb25zdCB0ID0gdmFsdWUudGVzdHMgPz8gW107XG4gICAgY29uc3QgcmVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0Lmxlbmd0aDsgaSsrKVxuICAgICAgcmVzLnB1c2goYXdhaXQgZXhlY1Rlc3QodFtpXSwgb3B0aW9ucz8udGVzdCkpO1xuXG4gICAgY29uc3QgZGF0YSA9IChhd2FpdCBQcm9taXNlLmFsbChyZXMpKS5maWx0ZXIoKGQpID0+IGQucmVzdWx0ICE9ICdza2lwcGVkJyk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh2YWx1ZS5hZnRlcilcbiAgICAgICAgYXdhaXQgdmFsdWUuYWZ0ZXIoKTtcbiAgICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICAgIHZhbHVlLmFmdGVyU3RhdHVzID0geC50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAodmFsdWUuYWZ0ZXJTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5hZnRlclN0YXR1cywgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZX0pO1xuICAgIGlmICh2YWx1ZS5iZWZvcmVTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5iZWZvcmVTdGF0dXMsIHN1Y2Nlc3M6IGZhbHNlLCBtczogMCwgc2tpcHBlZDogZmFsc2V9KTtcbiAgICByZXN1bHRzLnB1c2goLi4uZGF0YSk7XG4gIH1cbiAgaWYgKG9wdGlvbnMudGVzdENvbnRleHQuY2F0Y2hVbmhhbmRsZWQpIHtcbiAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICBpZiAoZ3Jvay5zaGVsbC5sYXN0RXJyb3IubGVuZ3RoID4gMCkge1xuICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdVbmhhbmRsZWQgZXhjZXB0aW9ucycsXG4gICAgICAgIG5hbWU6ICdleGNlcHRpb25zJyxcbiAgICAgICAgcmVzdWx0OiBncm9rLnNoZWxsLmxhc3RFcnJvciwgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGlmIChvcHRpb25zLnRlc3RDb250ZXh0LnJlcG9ydCkge1xuICAgIGNvbnN0IGxvZ2dlciA9IG5ldyBERy5Mb2dnZXIoKTtcbiAgICBjb25zdCBzdWNjZXNzZnVsID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+IHIuc3VjY2VzcykubGVuZ3RoO1xuICAgIGNvbnN0IHNraXBwZWQgPSByZXN1bHRzLmZpbHRlcigocikgPT4gci5za2lwcGVkKS5sZW5ndGg7XG4gICAgY29uc3QgZmFpbGVkID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+ICFyLnN1Y2Nlc3MpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJ1BhY2thZ2UgQHBhY2thZ2UgdGVzdGVkOiBAc3VjY2Vzc2Z1bCBzdWNjZXNzZnVsLCBAc2tpcHBlZCBza2lwcGVkLCBAZmFpbGVkIGZhaWxlZCB0ZXN0cyc7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgc3VjY2Vzc2Z1bDogc3VjY2Vzc2Z1bCxcbiAgICAgIHNraXBwZWQ6IHNraXBwZWQsXG4gICAgICBmYWlsZWQ6IGZhaWxlZC5sZW5ndGgsXG4gICAgICBwYWNrYWdlOiBwYWNrYWdlTmFtZVxuICAgIH07XG4gICAgZm9yIChjb25zdCByIG9mIGZhaWxlZCkgT2JqZWN0LmFzc2lnbihwYXJhbXMsIHtbYCR7ci5jYXRlZ29yeX0gfCAke3IubmFtZX1gXTogci5yZXN1bHR9KTtcbiAgICBsb2dnZXIubG9nKGRlc2NyaXB0aW9uLCBwYXJhbXMsICdwYWNrYWdlLXRlc3RlZCcpO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjVGVzdCh0OiBUZXN0LCBwcmVkaWNhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBsZXQgcjogeyBjYXRlZ29yeT86IHN0cmluZywgbmFtZT86IHN0cmluZywgc3VjY2VzczogYm9vbGVhbiwgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfTtcbiAgY29uc3QgZmlsdGVyID0gcHJlZGljYXRlICE9IHVuZGVmaW5lZCAmJiAoIXQubmFtZS50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgocHJlZGljYXRlLnRvTG93ZXJDYXNlKCkpKTtcbiAgY29uc3Qgc2tpcCA9IHQub3B0aW9ucz8uc2tpcFJlYXNvbiB8fCBmaWx0ZXI7XG4gIGNvbnN0IHNraXBSZWFzb24gPSBmaWx0ZXIgPyAnc2tpcHBlZCcgOiB0Lm9wdGlvbnM/LnNraXBSZWFzb247XG4gIGlmICghc2tpcClcbiAgICBjb25zb2xlLmxvZyhgU3RhcnRlZCAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfWApO1xuICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKCk7XG5cbiAgdHJ5IHtcbiAgICBpZiAoc2tpcClcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBza2lwUmVhc29uISwgbXM6IDAsIHNraXBwZWQ6IHRydWV9O1xuICAgIGVsc2VcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBhd2FpdCB0LnRlc3QoKSA/PyAnT0snLCBtczogMCwgc2tpcHBlZDogZmFsc2V9O1xuICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICByID0ge3N1Y2Nlc3M6IGZhbHNlLCByZXN1bHQ6IHgudG9TdHJpbmcoKSwgbXM6IDAsIHNraXBwZWQ6IGZhbHNlfTtcbiAgfVxuICBjb25zdCBzdG9wID0gbmV3IERhdGUoKTtcbiAgLy8gQHRzLWlnbm9yZVxuICByLm1zID0gc3RvcCAtIHN0YXJ0O1xuICBpZiAoIXNraXApXG4gICAgY29uc29sZS5sb2coYEZpbmlzaGVkICR7dC5jYXRlZ29yeX0gJHt0Lm5hbWV9IGZvciAke3IubXN9IG1zYCk7XG5cbiAgci5jYXRlZ29yeSA9IHQuY2F0ZWdvcnk7XG4gIHIubmFtZSA9IHQubmFtZTtcbiAgcmV0dXJuIHI7XG59XG5cbi8qIFdhaXRzIFttc10gbWlsbGlzZWNvbmRzICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsYXkobXM6IG51bWJlcikge1xuICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXdhaXRDaGVjayhjaGVja0hhbmRsZXI6ICgpID0+IGJvb2xlYW4sXG4gIGVycm9yOiBzdHJpbmcgPSAnVGltZW91dCBleGNlZWRlZCcsIHdhaXQ6IG51bWJlciA9IDUwMCk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGVycm9yKSk7XG4gICAgfSwgd2FpdCk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGludGVydmFsOiBUaW1lb3V0ID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgaWYgKGNoZWNrSGFuZGxlcigpKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSwgNTApO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGlhbG9nUHJlc2VudChkaWFsb2dUaXRsZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgREcuRGlhbG9nLmdldE9wZW5EaWFsb2dzKCkubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoREcuRGlhbG9nLmdldE9wZW5EaWFsb2dzKClbaV0udGl0bGUgPT0gZGlhbG9nVGl0bGUpXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0Vmlld2VyKHY6IHN0cmluZywgZGY6IERHLkRhdGFGcmFtZSwgZGV0ZWN0U2VtYW50aWNUeXBlczogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChkZXRlY3RTZW1hbnRpY1R5cGVzKSBhd2FpdCBncm9rLmRhdGEuZGV0ZWN0U2VtYW50aWNUeXBlcyhkZik7XG4gIGNvbnN0IHR2ID0gZ3Jvay5zaGVsbC5hZGRUYWJsZVZpZXcoZGYpO1xuICBjb25zdCB2aWV3ZXJOYW1lID0gYFtuYW1lPXZpZXdlci0ke3YucmVwbGFjZSgvXFxzKy9nLCAnLScpfSBpXWA7XG4gIGNvbnN0IHNlbGVjdG9yID0gYCR7dmlld2VyTmFtZX0gY2FudmFzLCR7dmlld2VyTmFtZX0gc3ZnLCR7dmlld2VyTmFtZX0gaW1nLFxuICAgICR7dmlld2VyTmFtZX0gaW5wdXQsJHt2aWV3ZXJOYW1lfSBoMSwke3ZpZXdlck5hbWV9IGFgO1xuICBjb25zdCByZXMgPSBbXTtcbiAgdHJ5IHtcbiAgICBsZXQgdmlld2VyID0gdHYuYWRkVmlld2VyKHYpO1xuICAgIGF3YWl0IGF3YWl0Q2hlY2soKCkgPT4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikgIT09IG51bGwsXG4gICAgICAnY2Fubm90IGxvYWQgdmlld2VyJywgMzAwMCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIEFycmF5LmZyb20oZGYucm93KDApLmNlbGxzKS5mb3JFYWNoKChjKSA9PiBjLnZhbHVlID0gbnVsbCk7XG4gICAgZGYucm93cy5zZWxlY3QoKHJvdykgPT4gcm93LmlkeCA+IDEgJiYgcm93LmlkeCA8IDcpO1xuICAgIGZvciAobGV0IGkgPSA3OyBpIDwgMTI7IGkrKykgZGYuZmlsdGVyLnNldChpLCBmYWxzZSk7XG4gICAgZGYuY3VycmVudFJvd0lkeCA9IDE7XG4gICAgY29uc3QgcHJvcHMgPSB2aWV3ZXIuZ2V0T3B0aW9ucyh0cnVlKS5sb29rO1xuICAgIGNvbnN0IG5ld1Byb3BzOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHByb3BzKS5maWx0ZXIoKGspID0+IHR5cGVvZiBwcm9wc1trXSA9PT0gJ2Jvb2xlYW4nKS5mb3JFYWNoKChrKSA9PiBuZXdQcm9wc1trXSA9ICFwcm9wc1trXSk7XG4gICAgdmlld2VyLnNldE9wdGlvbnMobmV3UHJvcHMpO1xuICAgIGF3YWl0IGRlbGF5KDI1MCk7XG4gICAgY29uc3QgbGF5b3V0ID0gdHYuc2F2ZUxheW91dCgpO1xuICAgIGNvbnN0IG9sZFByb3BzID0gdmlld2VyLmdldE9wdGlvbnMoKS5sb29rO1xuICAgIHR2LnJlc2V0TGF5b3V0KCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIHR2LmxvYWRMYXlvdXQobGF5b3V0KTtcbiAgICBhd2FpdCBhd2FpdENoZWNrKCgpID0+IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpICE9PSBudWxsLFxuICAgICAgJ2Nhbm5vdCBsb2FkIHZpZXdlciBmcm9tIGxheW91dCcsIDMwMDApO1xuICAgIGF3YWl0IGRlbGF5KDI1MCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIHZpZXdlciA9IEFycmF5LmZyb20odHYudmlld2VycykuZmluZCgodikgPT4gdi50eXBlICE9PSAnR3JpZCcpITtcbiAgICBleHBlY3RBcnJheShyZXMsIFsyLCAxLCAyXSk7XG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHZpZXdlci5nZXRPcHRpb25zKCkubG9vayksIEpTT04uc3RyaW5naWZ5KG9sZFByb3BzKSk7XG4gIH0gZmluYWxseSB7XG4gICAgdHYuY2xvc2UoKTtcbiAgICBncm9rLnNoZWxsLmNsb3NlVGFibGUoZGYpO1xuICB9XG59XG4iXX0=","export function errorToConsole(err) {\n var _a;\n if (typeof err === 'string' || err instanceof String) {\n return err;\n }\n else if ('$thrownJsError' in err) {\n return errorToConsole(err['$thrownJsError']);\n }\n else if (err instanceof Error) {\n return (_a = err.stack) !== null && _a !== void 0 ? _a : err.message;\n }\n else {\n return err.toString();\n }\n}\nexport function rectToConsole(rect) {\n return `(x=${rect.x}, y=${rect.y}, w=${rect.width}, h=${rect.height})`;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG8tY29uc29sZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRvLWNvbnNvbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFROztJQUNyQyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLFlBQVksTUFBTSxFQUFFO1FBQ3BELE9BQU8sR0FBYSxDQUFDO0tBQ3RCO1NBQU0sSUFBSSxnQkFBZ0IsSUFBSSxHQUFHLEVBQUU7UUFDbEMsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztLQUM5QztTQUFNLElBQUksR0FBRyxZQUFZLEtBQUssRUFBRTtRQUMvQixPQUFPLE1BQUMsR0FBYSxDQUFDLEtBQUssbUNBQUssR0FBYSxDQUFDLE9BQU8sQ0FBQztLQUN2RDtTQUFNO1FBQ0wsT0FBTyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7S0FDdkI7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFhO0lBQ3pDLE9BQU8sTUFBTSxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEtBQUssT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUM7QUFDekUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHVpIGZyb20gJ2RhdGFncm9rLWFwaS91aSc7XG5pbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGVycm9yVG9Db25zb2xlKGVycjogYW55KTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnIHx8IGVyciBpbnN0YW5jZW9mIFN0cmluZykge1xuICAgIHJldHVybiBlcnIgYXMgc3RyaW5nO1xuICB9IGVsc2UgaWYgKCckdGhyb3duSnNFcnJvcicgaW4gZXJyKSB7XG4gICAgcmV0dXJuIGVycm9yVG9Db25zb2xlKGVyclsnJHRocm93bkpzRXJyb3InXSk7XG4gIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4gKGVyciBhcyBFcnJvcikuc3RhY2sgPz8gKGVyciBhcyBFcnJvcikubWVzc2FnZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXJyLnRvU3RyaW5nKCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY3RUb0NvbnNvbGUocmVjdDogREcuUmVjdCk6IHN0cmluZyB7XG4gIHJldHVybiBgKHg9JHtyZWN0Lnh9LCB5PSR7cmVjdC55fSwgdz0ke3JlY3Qud2lkdGh9LCBoPSR7cmVjdC5oZWlnaHR9KWA7XG59XG4iXX0=","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".colored-text-input > textarea {\\n width: 100%;\\n -webkit-text-fill-color: transparent;\\n background-color: transparent;\\n position: relative;\\n z-index: 1;\\n resize: none;\\n height: 22px; /* Fine tuned value to avoid \\\"jumping\\\" of the textarea upon autoresize */\\n}\\n\\n.colored-text-input > div {\\n /* The values here are fine tuned to those of the ui.input textarea in order\\n * to achieve precise overlap */\\n overflow: auto;\\n position: absolute;\\n pointer-events: none;\\n cursor: text;\\n z-index: 0;\\n max-width: 100%;\\n padding: 2px;\\n line-height: normal;\\n font-family: 'Roboto Mono', 'Roboto Mono Local', monospace;\\n font-size: 12px;\\n color: transparent;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/view/style/colored-text-input.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,WAAW;EACX,oCAAoC;EACpC,6BAA6B;EAC7B,kBAAkB;EAClB,UAAU;EACV,YAAY;EACZ,YAAY,EAAE,wEAAwE;AACxF;;AAEA;EACE;iCAC+B;EAC/B,cAAc;EACd,kBAAkB;EAClB,oBAAoB;EACpB,YAAY;EACZ,UAAU;EACV,eAAe;EACf,YAAY;EACZ,mBAAmB;EACnB,0DAA0D;EAC1D,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACrB,qBAAqB;AACvB\",\"sourcesContent\":[\".colored-text-input > textarea {\\n width: 100%;\\n -webkit-text-fill-color: transparent;\\n background-color: transparent;\\n position: relative;\\n z-index: 1;\\n resize: none;\\n height: 22px; /* Fine tuned value to avoid \\\"jumping\\\" of the textarea upon autoresize */\\n}\\n\\n.colored-text-input > div {\\n /* The values here are fine tuned to those of the ui.input textarea in order\\n * to achieve precise overlap */\\n overflow: auto;\\n position: absolute;\\n pointer-events: none;\\n cursor: text;\\n z-index: 0;\\n max-width: 100%;\\n padding: 2px;\\n line-height: normal;\\n font-family: 'Roboto Mono', 'Roboto Mono Local', monospace;\\n font-size: 12px;\\n color: transparent;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n\\n.st-structure-body {\\n padding-right: 20px;\\n}\\n\\n.st-structure-input-form {\\n text-align: right;\\n vertical-align: top;\\n min-width: 95px;\\n}\\n\\n.st-structure-direction-choice label {\\n min-width: 100px;\\n float: right;\\n}\\n\\n.st-structure-direction-choice div {\\n justify-content: right;\\n}\\n\\n.st-structure-text-input-td { /* Style for td containing textarea */\\n width: 100%;\\n}\\n\\n.st-structure-mol-img {\\n margin-right: 30px;\\n float: right;\\n}\\n\\n.st-structure-bool-button-block {\\n justify-content: right;\\n margin-bottom: 10px;\\n}\\n\\n.st-structure-bottom {\\n flex-direction: row-reverse;\\n padding-top: 20px;\\n}\\n\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/view/style/structure-app.css\"],\"names\":[],\"mappings\":\"AAAA,gGAAgG;;AAEhG;EACE,mBAAmB;AACrB;;AAEA;EACE,iBAAiB;EACjB,mBAAmB;EACnB,eAAe;AACjB;;AAEA;EACE,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,sBAAsB;AACxB;;AAEA,8BAA8B,qCAAqC;EACjE,WAAW;AACb;;AAEA;EACE,kBAAkB;EAClB,YAAY;AACd;;AAEA;EACE,sBAAsB;EACtB,mBAAmB;AACrB;;AAEA;EACE,2BAA2B;EAC3B,iBAAiB;AACnB\",\"sourcesContent\":[\"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n\\n.st-structure-body {\\n padding-right: 20px;\\n}\\n\\n.st-structure-input-form {\\n text-align: right;\\n vertical-align: top;\\n min-width: 95px;\\n}\\n\\n.st-structure-direction-choice label {\\n min-width: 100px;\\n float: right;\\n}\\n\\n.st-structure-direction-choice div {\\n justify-content: right;\\n}\\n\\n.st-structure-text-input-td { /* Style for td containing textarea */\\n width: 100%;\\n}\\n\\n.st-structure-mol-img {\\n margin-right: 30px;\\n float: right;\\n}\\n\\n.st-structure-bool-button-block {\\n justify-content: right;\\n margin-bottom: 10px;\\n}\\n\\n.st-structure-bottom {\\n flex-direction: row-reverse;\\n padding-top: 20px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n.st-translator-input-table {\\n /* width: 100%; */\\n margin-right: 20px;\\n}\\n\\n.st-translator-input-table td:has(textarea) {\\n width: 100%;\\n}\\n\\n.st-translator-input-table td:has(select) {\\n min-width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table {\\n margin-top: 20px;\\n margin-right: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.st-translator-output-table table {\\n width: 100%;\\n table-layout: fixed;\\n}\\n\\n/* .st-translator-output-table table tbody tr td { */\\n/* max-width: 20%; */\\n/* } */\\n\\n.st-translator-output-table td {\\n padding-top: 6px;\\n padding-bottom: 6px;\\n}\\n.st-translator-output-table tr:nth-child(even) {\\n background-color: var(--grey-1);\\n}\\n\\n.st-translator-output-table td:nth-child(odd) {\\n width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table td a {\\n overflow-wrap: break-word;\\n}\\n\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/view/style/translator-app.css\"],\"names\":[],\"mappings\":\"AAAA,gGAAgG;AAChG;EACE,iBAAiB;EACjB,kBAAkB;AACpB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,mBAAmB;AACrB;;AAEA;EACE,WAAW;EACX,mBAAmB;AACrB;;AAEA,oDAAoD;AACpD,sBAAsB;AACtB,MAAM;;AAEN;EACE,gBAAgB;EAChB,mBAAmB;AACrB;AACA;EACE,+BAA+B;AACjC;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,yBAAyB;AAC3B\",\"sourcesContent\":[\"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n.st-translator-input-table {\\n /* width: 100%; */\\n margin-right: 20px;\\n}\\n\\n.st-translator-input-table td:has(textarea) {\\n width: 100%;\\n}\\n\\n.st-translator-input-table td:has(select) {\\n min-width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table {\\n margin-top: 20px;\\n margin-right: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.st-translator-output-table table {\\n width: 100%;\\n table-layout: fixed;\\n}\\n\\n/* .st-translator-output-table table tbody tr td { */\\n/* max-width: 20%; */\\n/* } */\\n\\n.st-translator-output-table td {\\n padding-top: 6px;\\n padding-bottom: 6px;\\n}\\n.st-translator-output-table tr:nth-child(even) {\\n background-color: var(--grey-1);\\n}\\n\\n.st-translator-output-table td:nth-child(odd) {\\n width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table td a {\\n overflow-wrap: break-word;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","'use strict';\n\n(function () {\n var out$ = typeof exports != 'undefined' && exports || typeof define != 'undefined' && {} || this || window;\n if (typeof define !== 'undefined') define('save-svg-as-png', [], function () {\n return out$;\n });\n out$.default = out$;\n\n var xmlNs = 'http://www.w3.org/2000/xmlns/';\n var xhtmlNs = 'http://www.w3.org/1999/xhtml';\n var svgNs = 'http://www.w3.org/2000/svg';\n var doctype = '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" [<!ENTITY nbsp \"&#160;\">]>';\n var urlRegex = /url\\([\"']?(.+?)[\"']?\\)/;\n var fontFormats = {\n woff2: 'font/woff2',\n woff: 'font/woff',\n otf: 'application/x-font-opentype',\n ttf: 'application/x-font-ttf',\n eot: 'application/vnd.ms-fontobject',\n sfnt: 'application/font-sfnt',\n svg: 'image/svg+xml'\n };\n\n var isElement = function isElement(obj) {\n return obj instanceof HTMLElement || obj instanceof SVGElement;\n };\n var requireDomNode = function requireDomNode(el) {\n if (!isElement(el)) throw new Error('an HTMLElement or SVGElement is required; got ' + el);\n };\n var requireDomNodePromise = function requireDomNodePromise(el) {\n return new Promise(function (resolve, reject) {\n if (isElement(el)) resolve(el);else reject(new Error('an HTMLElement or SVGElement is required; got ' + el));\n });\n };\n var isExternal = function isExternal(url) {\n return url && url.lastIndexOf('http', 0) === 0 && url.lastIndexOf(window.location.host) === -1;\n };\n\n var getFontMimeTypeFromUrl = function getFontMimeTypeFromUrl(fontUrl) {\n var formats = Object.keys(fontFormats).filter(function (extension) {\n return fontUrl.indexOf('.' + extension) > 0;\n }).map(function (extension) {\n return fontFormats[extension];\n });\n if (formats) return formats[0];\n console.error('Unknown font format for ' + fontUrl + '. Fonts may not be working correctly.');\n return 'application/octet-stream';\n };\n\n var arrayBufferToBase64 = function arrayBufferToBase64(buffer) {\n var binary = '';\n var bytes = new Uint8Array(buffer);\n for (var i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }return window.btoa(binary);\n };\n\n var getDimension = function getDimension(el, clone, dim) {\n var v = el.viewBox && el.viewBox.baseVal && el.viewBox.baseVal[dim] || clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim)) || el.getBoundingClientRect()[dim] || parseInt(clone.style[dim]) || parseInt(window.getComputedStyle(el).getPropertyValue(dim));\n return typeof v === 'undefined' || v === null || isNaN(parseFloat(v)) ? 0 : v;\n };\n\n var getDimensions = function getDimensions(el, clone, width, height) {\n if (el.tagName === 'svg') return {\n width: width || getDimension(el, clone, 'width'),\n height: height || getDimension(el, clone, 'height')\n };else if (el.getBBox) {\n var _el$getBBox = el.getBBox(),\n x = _el$getBBox.x,\n y = _el$getBBox.y,\n _width = _el$getBBox.width,\n _height = _el$getBBox.height;\n\n return {\n width: x + _width,\n height: y + _height\n };\n }\n };\n\n var reEncode = function reEncode(data) {\n return decodeURIComponent(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, function (match, p1) {\n var c = String.fromCharCode('0x' + p1);\n return c === '%' ? '%25' : c;\n }));\n };\n\n var uriToBlob = function uriToBlob(uri) {\n var byteString = window.atob(uri.split(',')[1]);\n var mimeString = uri.split(',')[0].split(':')[1].split(';')[0];\n var buffer = new ArrayBuffer(byteString.length);\n var intArray = new Uint8Array(buffer);\n for (var i = 0; i < byteString.length; i++) {\n intArray[i] = byteString.charCodeAt(i);\n }\n return new Blob([buffer], { type: mimeString });\n };\n\n var query = function query(el, selector) {\n if (!selector) return;\n try {\n return el.querySelector(selector) || el.parentNode && el.parentNode.querySelector(selector);\n } catch (err) {\n console.warn('Invalid CSS selector \"' + selector + '\"', err);\n }\n };\n\n var detectCssFont = function detectCssFont(rule, href) {\n // Match CSS font-face rules to external links.\n // @font-face {\n // src: local('Abel'), url(https://fonts.gstatic.com/s/abel/v6/UzN-iejR1VoXU2Oc-7LsbvesZW2xOQ-xsNqO47m55DA.woff2);\n // }\n var match = rule.cssText.match(urlRegex);\n var url = match && match[1] || '';\n if (!url || url.match(/^data:/) || url === 'about:blank') return;\n var fullUrl = url.startsWith('../') ? href + '/../' + url : url.startsWith('./') ? href + '/.' + url : url;\n return {\n text: rule.cssText,\n format: getFontMimeTypeFromUrl(fullUrl),\n url: fullUrl\n };\n };\n\n var inlineImages = function inlineImages(el) {\n return Promise.all(Array.from(el.querySelectorAll('image')).map(function (image) {\n var href = image.getAttributeNS('http://www.w3.org/1999/xlink', 'href') || image.getAttribute('href');\n if (!href) return Promise.resolve(null);\n if (isExternal(href)) {\n href += (href.indexOf('?') === -1 ? '?' : '&') + 't=' + new Date().valueOf();\n }\n return new Promise(function (resolve, reject) {\n var canvas = document.createElement('canvas');\n var img = new Image();\n img.crossOrigin = 'anonymous';\n img.src = href;\n img.onerror = function () {\n return reject(new Error('Could not load ' + href));\n };\n img.onload = function () {\n canvas.width = img.width;\n canvas.height = img.height;\n canvas.getContext('2d').drawImage(img, 0, 0);\n image.setAttributeNS('http://www.w3.org/1999/xlink', 'href', canvas.toDataURL('image/png'));\n resolve(true);\n };\n });\n }));\n };\n\n var cachedFonts = {};\n var inlineFonts = function inlineFonts(fonts) {\n return Promise.all(fonts.map(function (font) {\n return new Promise(function (resolve, reject) {\n if (cachedFonts[font.url]) return resolve(cachedFonts[font.url]);\n\n var req = new XMLHttpRequest();\n req.addEventListener('load', function () {\n // TODO: it may also be worth it to wait until fonts are fully loaded before\n // attempting to rasterize them. (e.g. use https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet)\n var fontInBase64 = arrayBufferToBase64(req.response);\n var fontUri = font.text.replace(urlRegex, 'url(\"data:' + font.format + ';base64,' + fontInBase64 + '\")') + '\\n';\n cachedFonts[font.url] = fontUri;\n resolve(fontUri);\n });\n req.addEventListener('error', function (e) {\n console.warn('Failed to load font from: ' + font.url, e);\n cachedFonts[font.url] = null;\n resolve(null);\n });\n req.addEventListener('abort', function (e) {\n console.warn('Aborted loading font from: ' + font.url, e);\n resolve(null);\n });\n req.open('GET', font.url);\n req.responseType = 'arraybuffer';\n req.send();\n });\n })).then(function (fontCss) {\n return fontCss.filter(function (x) {\n return x;\n }).join('');\n });\n };\n\n var cachedRules = null;\n var styleSheetRules = function styleSheetRules() {\n if (cachedRules) return cachedRules;\n return cachedRules = Array.from(document.styleSheets).map(function (sheet) {\n try {\n return { rules: sheet.cssRules, href: sheet.href };\n } catch (e) {\n console.warn('Stylesheet could not be loaded: ' + sheet.href, e);\n return {};\n }\n });\n };\n\n var inlineCss = function inlineCss(el, options) {\n var _ref = options || {},\n selectorRemap = _ref.selectorRemap,\n modifyStyle = _ref.modifyStyle,\n modifyCss = _ref.modifyCss,\n fonts = _ref.fonts,\n excludeUnusedCss = _ref.excludeUnusedCss;\n\n var generateCss = modifyCss || function (selector, properties) {\n var sel = selectorRemap ? selectorRemap(selector) : selector;\n var props = modifyStyle ? modifyStyle(properties) : properties;\n return sel + '{' + props + '}\\n';\n };\n var css = [];\n var detectFonts = typeof fonts === 'undefined';\n var fontList = fonts || [];\n styleSheetRules().forEach(function (_ref2) {\n var rules = _ref2.rules,\n href = _ref2.href;\n\n if (!rules) return;\n Array.from(rules).forEach(function (rule) {\n if (typeof rule.style != 'undefined') {\n if (query(el, rule.selectorText)) css.push(generateCss(rule.selectorText, rule.style.cssText));else if (detectFonts && rule.cssText.match(/^@font-face/)) {\n var font = detectCssFont(rule, href);\n if (font) fontList.push(font);\n } else if (!excludeUnusedCss) {\n css.push(rule.cssText);\n }\n }\n });\n });\n\n return inlineFonts(fontList).then(function (fontCss) {\n return css.join('\\n') + fontCss;\n });\n };\n\n var downloadOptions = function downloadOptions() {\n if (!navigator.msSaveOrOpenBlob && !('download' in document.createElement('a'))) {\n return { popup: window.open() };\n }\n };\n\n out$.prepareSvg = function (el, options, done) {\n requireDomNode(el);\n\n var _ref3 = options || {},\n _ref3$left = _ref3.left,\n left = _ref3$left === undefined ? 0 : _ref3$left,\n _ref3$top = _ref3.top,\n top = _ref3$top === undefined ? 0 : _ref3$top,\n w = _ref3.width,\n h = _ref3.height,\n _ref3$scale = _ref3.scale,\n scale = _ref3$scale === undefined ? 1 : _ref3$scale,\n _ref3$responsive = _ref3.responsive,\n responsive = _ref3$responsive === undefined ? false : _ref3$responsive,\n _ref3$excludeCss = _ref3.excludeCss,\n excludeCss = _ref3$excludeCss === undefined ? false : _ref3$excludeCss;\n\n return inlineImages(el).then(function () {\n var clone = el.cloneNode(true);\n clone.style.backgroundColor = (options || {}).backgroundColor || el.style.backgroundColor;\n\n var _getDimensions = getDimensions(el, clone, w, h),\n width = _getDimensions.width,\n height = _getDimensions.height;\n\n if (el.tagName !== 'svg') {\n if (el.getBBox) {\n if (clone.getAttribute('transform') != null) {\n clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\\(.*?\\)/, ''));\n }\n var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.appendChild(clone);\n clone = svg;\n } else {\n console.error('Attempted to render non-SVG element', el);\n return;\n }\n }\n\n clone.setAttribute('version', '1.1');\n clone.setAttribute('viewBox', [left, top, width, height].join(' '));\n if (!clone.getAttribute('xmlns')) clone.setAttributeNS(xmlNs, 'xmlns', svgNs);\n if (!clone.getAttribute('xmlns:xlink')) clone.setAttributeNS(xmlNs, 'xmlns:xlink', 'http://www.w3.org/1999/xlink');\n\n if (responsive) {\n clone.removeAttribute('width');\n clone.removeAttribute('height');\n clone.setAttribute('preserveAspectRatio', 'xMinYMin meet');\n } else {\n clone.setAttribute('width', width * scale);\n clone.setAttribute('height', height * scale);\n }\n\n Array.from(clone.querySelectorAll('foreignObject > *')).forEach(function (foreignObject) {\n foreignObject.setAttributeNS(xmlNs, 'xmlns', foreignObject.tagName === 'svg' ? svgNs : xhtmlNs);\n });\n\n if (excludeCss) {\n var outer = document.createElement('div');\n outer.appendChild(clone);\n var src = outer.innerHTML;\n if (typeof done === 'function') done(src, width, height);else return { src: src, width: width, height: height };\n } else {\n return inlineCss(el, options).then(function (css) {\n var style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = '<![CDATA[\\n' + css + '\\n]]>';\n\n var defs = document.createElement('defs');\n defs.appendChild(style);\n clone.insertBefore(defs, clone.firstChild);\n\n var outer = document.createElement('div');\n outer.appendChild(clone);\n var src = outer.innerHTML.replace(/NS\\d+:href/gi, 'xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href');\n\n if (typeof done === 'function') done(src, width, height);else return { src: src, width: width, height: height };\n });\n }\n });\n };\n\n out$.svgAsDataUri = function (el, options, done) {\n requireDomNode(el);\n return out$.prepareSvg(el, options).then(function (_ref4) {\n var src = _ref4.src,\n width = _ref4.width,\n height = _ref4.height;\n\n var svgXml = 'data:image/svg+xml;base64,' + window.btoa(reEncode(doctype + src));\n if (typeof done === 'function') {\n done(svgXml, width, height);\n }\n return svgXml;\n });\n };\n\n out$.svgAsPngUri = function (el, options, done) {\n requireDomNode(el);\n\n var _ref5 = options || {},\n _ref5$encoderType = _ref5.encoderType,\n encoderType = _ref5$encoderType === undefined ? 'image/png' : _ref5$encoderType,\n _ref5$encoderOptions = _ref5.encoderOptions,\n encoderOptions = _ref5$encoderOptions === undefined ? 0.8 : _ref5$encoderOptions,\n canvg = _ref5.canvg;\n\n var convertToPng = function convertToPng(_ref6) {\n var src = _ref6.src,\n width = _ref6.width,\n height = _ref6.height;\n\n var canvas = document.createElement('canvas');\n var context = canvas.getContext('2d');\n var pixelRatio = window.devicePixelRatio || 1;\n\n canvas.width = width * pixelRatio;\n canvas.height = height * pixelRatio;\n canvas.style.width = canvas.width + 'px';\n canvas.style.height = canvas.height + 'px';\n context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n\n if (canvg) canvg(canvas, src);else context.drawImage(src, 0, 0);\n\n var png = void 0;\n try {\n png = canvas.toDataURL(encoderType, encoderOptions);\n } catch (e) {\n if (typeof SecurityError !== 'undefined' && e instanceof SecurityError || e.name === 'SecurityError') {\n console.error('Rendered SVG images cannot be downloaded in this browser.');\n return;\n } else throw e;\n }\n if (typeof done === 'function') done(png, canvas.width, canvas.height);\n return Promise.resolve(png);\n };\n\n if (canvg) return out$.prepareSvg(el, options).then(convertToPng);else return out$.svgAsDataUri(el, options).then(function (uri) {\n return new Promise(function (resolve, reject) {\n var image = new Image();\n image.onload = function () {\n return resolve(convertToPng({\n src: image,\n width: image.width,\n height: image.height\n }));\n };\n image.onerror = function () {\n reject('There was an error loading the data URI as an image on the following SVG\\n' + window.atob(uri.slice(26)) + 'Open the following link to see browser\\'s diagnosis\\n' + uri);\n };\n image.src = uri;\n });\n });\n };\n\n out$.download = function (name, uri, options) {\n if (navigator.msSaveOrOpenBlob) navigator.msSaveOrOpenBlob(uriToBlob(uri), name);else {\n var saveLink = document.createElement('a');\n if ('download' in saveLink) {\n saveLink.download = name;\n saveLink.style.display = 'none';\n document.body.appendChild(saveLink);\n try {\n var blob = uriToBlob(uri);\n var url = URL.createObjectURL(blob);\n saveLink.href = url;\n saveLink.onclick = function () {\n return requestAnimationFrame(function () {\n return URL.revokeObjectURL(url);\n });\n };\n } catch (e) {\n console.error(e);\n console.warn('Error while getting object URL. Falling back to string URL.');\n saveLink.href = uri;\n }\n saveLink.click();\n document.body.removeChild(saveLink);\n } else if (options && options.popup) {\n options.popup.document.title = name;\n options.popup.location.replace(uri);\n }\n }\n };\n\n out$.saveSvg = function (el, name, options) {\n var downloadOpts = downloadOptions(); // don't inline, can't be async\n return requireDomNodePromise(el).then(function (el) {\n return out$.svgAsDataUri(el, options || {});\n }).then(function (uri) {\n return out$.download(name, uri, downloadOpts);\n });\n };\n\n out$.saveSvgAsPng = function (el, name, options) {\n var downloadOpts = downloadOptions(); // don't inline, can't be async\n return requireDomNodePromise(el).then(function (el) {\n return out$.svgAsPngUri(el, options || {});\n }).then(function (uri) {\n return out$.download(name, uri, downloadOpts);\n });\n };\n})();","\"use strict\";\n\nvar stylesInDOM = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n\n return updater;\n}\n\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n\n stylesInDOM.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};","\"use strict\";\n\nvar memo = {};\n/* istanbul ignore next */\n\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n}\n/* istanbul ignore next */\n\n\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n}\n\nmodule.exports = insertBySelector;","\"use strict\";\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\n\nmodule.exports = insertStyleElement;","\"use strict\";\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = typeof __webpack_nonce__ !== \"undefined\" ? __webpack_nonce__ : null;\n\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\n\nmodule.exports = setAttributesWithoutAttributes;","\"use strict\";\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n\n var needLayer = typeof obj.layer !== \"undefined\";\n\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n\n css += obj.css;\n\n if (needLayer) {\n css += \"}\";\n }\n\n if (obj.media) {\n css += \"}\";\n }\n\n if (obj.supports) {\n css += \"}\";\n }\n\n var sourceMap = obj.sourceMap;\n\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n options.styleTagTransform(css, styleElement, options.options);\n}\n\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n\n styleElement.parentNode.removeChild(styleElement);\n}\n/* istanbul ignore next */\n\n\nfunction domAPI(options) {\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\n\nmodule.exports = domAPI;","\"use strict\";\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n\n styleElement.appendChild(document.createTextNode(css));\n }\n}\n\nmodule.exports = styleTagTransform;","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nexport const NUCLEOTIDES = ['A', 'G', 'C', 'U', 'T'];\n\nexport const TECHNOLOGIES = {\n DNA: 'DNA',\n RNA: 'RNA',\n ASO_GAPMERS: 'ASOGapmers',\n SI_RNA: 'siRNA',\n};\n\nexport enum DEFAULT_FORMATS {\n HELM = 'HELM',\n AXOLABS = 'Axolabs',\n}\n","export const LIB_PATH = 'System:AppData/SequenceTranslator';\nexport const DEFAULT_LIB_FILENAME = 'monomer-lib.json';\n\nexport const APP_PATH = 'System:AppData/SequenceTranslator';\nexport const AXOLABS_STYLE_FILENAME = 'axolabs-style.json';\nexport const CODES_TO_HELM_DICT_FILENAME = 'formats-to-helm.json';\nexport const CODES_TO_SYMBOLS_FILENAME = 'codes-to-symbols.json';\nexport const MONOMERS_WITH_PHOSPHATE_LINKERS = 'linkers.json';\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {APP_PATH, AXOLABS_STYLE_FILENAME, CODES_TO_HELM_DICT_FILENAME, CODES_TO_SYMBOLS_FILENAME, MONOMERS_WITH_PHOSPHATE_LINKERS} from './const';\nimport {AxolabsStyle, FormatToHELMDict, CodeToSymbol} from './types';\n\nconst fileSource = new DG.FileSource(APP_PATH);\n\nexport let axolabsStyleMap: AxolabsStyle;\nexport let codesToHelmDictionary: FormatToHELMDict;\nexport let codesToSymbolsDictionary: CodeToSymbol;\nexport let monomersWithPhosphateLinkers: {[key: string]: string[]};\n\nexport async function getJsonData(): Promise<void> {\n const data = [axolabsStyleMap, codesToHelmDictionary, codesToSymbolsDictionary, monomersWithPhosphateLinkers];\n\n if (data.every((item) => item !== undefined))\n return;\n\n axolabsStyleMap = await parse(AXOLABS_STYLE_FILENAME);\n codesToHelmDictionary = await parse(CODES_TO_HELM_DICT_FILENAME);\n codesToSymbolsDictionary = await parse(CODES_TO_SYMBOLS_FILENAME);\n monomersWithPhosphateLinkers = await parse(MONOMERS_WITH_PHOSPHATE_LINKERS);\n}\n\nasync function parse(path: string): Promise<any> {\n let parsedJson: string;\n try {\n parsedJson = JSON.parse(await fileSource.readAsText(path))\n } catch (err: any) {\n const errMsg: string = err.hasOwnProperty('message') ? err.message : err.toString();\n throw new Error(`Error loading json from ${path}:` + errMsg);\n }\n return parsedJson;\n}\n\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nexport function sortByReverseLength(array: string[]): string[] {\n return array.sort((a, b) => b.length - a.length);\n}\n\nexport function download(name: string, href: string): void {\n const element = document.createElement('a');\n element.setAttribute('href', 'data:text/plain;charset=utf-8,' + href);\n element.setAttribute('download', name);\n element.click();\n}\n\nexport async function tryCatch<T>(func: () => Promise<T>, finallyFunc?: () => any, callbackName: string = 'Oligo app'): Promise<T> {\n try {\n return await func();\n } catch (err: any) {\n const errMsg: string = err.hasOwnProperty('message') ? err.message : err.toString();\n grok.shell.error(`${callbackName} error: ` + errMsg);\n throw err;\n } finally {\n if (finallyFunc)\n finallyFunc();\n }\n};\n\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_package} from '../../package';\nimport {DEFAULT_FORMATS} from '../const';\n\nimport {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';\n\nimport {HELM_REQUIRED_FIELDS as REQ, HELM_OPTIONAL_FIELDS as OPT} from '@datagrok-libraries/bio/src/utils/const';\nimport {META_FIELDS as MET} from './const';\nimport {codesToSymbolsDictionary} from '../../model/data-loading-utils/json-loader';\n\nexport class MonomerLibWrapper {\n private constructor() {\n const lib = _package.monomerLib;\n if (lib === null)\n throw new Error('SequenceTranslator: monomer library is null');\n this.lib = lib!;\n this.allMonomers = this.getAllMonomers();\n }\n\n private lib: IMonomerLib;\n private static instance?: MonomerLibWrapper;\n private allMonomers: Monomer[];\n\n private formatMonomerForViewer(sourceObj: Monomer): {[key: string]: string} {\n const formattedObject: {[key: string]: string} = {};\n formattedObject[REQ.NAME] = sourceObj[REQ.SYMBOL];\n formattedObject[REQ.SYMBOL] = sourceObj[REQ.SYMBOL];\n formattedObject[REQ.MOLFILE] = sourceObj[REQ.MOLFILE];\n const formats = this.getAllFormats();\n formats.forEach((format) => {\n if (format === DEFAULT_FORMATS.HELM)\n return;\n const map = codesToSymbolsDictionary[format];\n const codes = Object.keys(map).filter((code) => map[code] === sourceObj.symbol);\n formattedObject[format] = codes.join(', ');\n })\n\n return formattedObject;\n }\n\n private getAllMonomers(): Monomer[] {\n const polymerTypes = this.lib.getPolymerTypes();\n let result: Monomer[] = [];\n for (const polymerType of polymerTypes) {\n const monomerSymbols = this.lib.getMonomerSymbolsByType(polymerType);\n const monomersByType: Monomer[] = monomerSymbols\n .map((monomerSymbol) => this.lib.getMonomer(polymerType, monomerSymbol))\n .filter((monomer): monomer is Monomer => monomer !== null);\n result = result.concat(monomersByType);\n }\n return result;\n }\n\n private getMonomer(monomerSymbol: string): Monomer {\n const monomer = this.lib.getMonomer('RNA', monomerSymbol);\n if (monomer === undefined)\n throw new Error(`SequenceTranslator: no monomer with symbol ${monomerSymbol}`);\n return monomer!;\n }\n\n static getInstance(): MonomerLibWrapper {\n if (MonomerLibWrapper.instance === undefined)\n MonomerLibWrapper.instance = new MonomerLibWrapper();\n return MonomerLibWrapper.instance!;\n }\n\n getMolfileBySymbol(monomerSymbol: string): string {\n const monomer = this.getMonomer(monomerSymbol);\n return monomer.molfile;\n }\n\n getNaturalAnalogBySymbol(monomerSymbol: string): string {\n const monomer = this.getMonomer(monomerSymbol);\n const naturalAnalog = monomer.naturalAnalog;\n if (!naturalAnalog)\n throw new Error(`ST: no natural analog for ${monomerSymbol}`);\n return naturalAnalog!;\n }\n\n // todo: a better criterion\n isModification(monomerSymbol: string): boolean {\n const molfile = this.getMolfileBySymbol(monomerSymbol);\n return (molfile.includes('MODIFICATION')) ? true : false;\n }\n\n getCodeToSymbolMap(format: string): Map<string, string> {\n return new Map<string, string>(Object.entries(codesToSymbolsDictionary[format]));\n }\n\n getCodesByFormat(format: string): string[] {\n return Object.keys(codesToSymbolsDictionary[format]);\n }\n\n getAllFormats(): string[] {\n return Object.keys(codesToSymbolsDictionary);\n }\n\n getTableForViewer(): DG.DataFrame {\n const formattedObjects = this.allMonomers.map((monomer) => this.formatMonomerForViewer(monomer));\n const df = DG.DataFrame.fromObjects(formattedObjects)!;\n return df;\n }\n\n getCodesToWeightsMap(): Map<string, number> {\n const codesToWeightsMap = new Map<string, number>();\n Object.entries(codesToSymbolsDictionary).forEach(([_, dict]) => {\n Object.entries(dict).forEach(([code, monomerSymbol]) => {\n const monomer = this.getMonomer(monomerSymbol);\n const weight = monomer[OPT.META]?.[MET.MOLWEIGHT];\n codesToWeightsMap.set(code, weight);\n });\n });\n return codesToWeightsMap;\n }\n}\n","import {NUCLEOTIDES} from '../const';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\nimport {sortByReverseLength} from '../helpers';\nimport {DEFAULT_FORMATS} from '../const';\n\nexport class SequenceValidator {\n constructor(private sequence: string) {\n this.libWrapper = MonomerLibWrapper.getInstance();\n };\n private libWrapper: MonomerLibWrapper;\n\n getInvalidCodeIndex(format: string): number {\n if (format === DEFAULT_FORMATS.HELM)\n return this.sequence.length;\n const firstUniqueCharacters = ['r', 'd']; // what for?\n const codes = sortByReverseLength(\n this.libWrapper.getCodesByFormat(format)\n );\n let indexOfFirstInvalidChar = 0;\n while (indexOfFirstInvalidChar < this.sequence.length) {\n const matchedCode = codes.find((code) => {\n const subSequence = this.sequence.substring(indexOfFirstInvalidChar, indexOfFirstInvalidChar + code.length);\n return code === subSequence;\n });\n\n if (!matchedCode) break;\n\n // todo: refactor the vague condition\n if ( // for mistake pattern 'rAA'\n indexOfFirstInvalidChar > 1 &&\n NUCLEOTIDES.includes(this.sequence[indexOfFirstInvalidChar]) &&\n firstUniqueCharacters.includes(this.sequence[indexOfFirstInvalidChar - 2])\n ) break;\n\n if ( // for mistake pattern 'ArA'\n firstUniqueCharacters.includes(this.sequence[indexOfFirstInvalidChar + 1]) &&\n NUCLEOTIDES.includes(this.sequence[indexOfFirstInvalidChar])\n ) {\n indexOfFirstInvalidChar++;\n break;\n }\n indexOfFirstInvalidChar += matchedCode.length;\n }\n if (indexOfFirstInvalidChar === this.sequence.length)\n indexOfFirstInvalidChar = -1\n return indexOfFirstInvalidChar;\n }\n\n isValidSequence(format: string): boolean {\n return this.getInvalidCodeIndex(format) === -1;\n }\n}\n","export const PHOSPHATE_SYMBOL = 'p';\n","export function getNucleotidesMol(codes: string[]) {\n const molBlocks: string[] = [];\n\n for (let i = 0; i < codes.length - 1; i++) {\n if (codes[i].includes('MODIFICATION')) {\n if (i === 0)\n molBlocks.push(reflect(codes[i]));\n else\n molBlocks.push(codes[i]);\n } else {\n molBlocks.push(rotateNucleotidesV3000(codes[i]));\n }\n }\n\n return linkV3000(molBlocks);\n}\n\nexport function linkStrandsV3000(\n strands: { senseStrands: string[], antiStrands: string[] }, useChirality: boolean = true\n): string {\n let macroMolBlock = '\\nDatagrok macromolecule handler\\n\\n';\n macroMolBlock += ' 0 0 0 0 0 0 999 V3000\\n';\n macroMolBlock += 'M V30 BEGIN CTAB\\n';\n let atomBlock = '';\n let bondBlock = '';\n let collectionBlock = '';\n const collection: number [] = [];\n let natom = 0;\n let nbond = 0;\n let xShift = 0;\n\n if (strands.antiStrands.length > 0) {\n for (let i = 0; i < strands.antiStrands.length; i++)\n strands.antiStrands[i] = invertNucleotidesV3000(strands.antiStrands[i]);\n }\n\n let inverted = false;\n const molBlocks = strands.senseStrands.concat(strands.antiStrands);\n /** Minimal value of AS and AS2 shift */\n let ssYShift = 0;\n\n for (let i = 0; i < molBlocks.length; i++) {\n molBlocks[i] = molBlocks[i].replaceAll('(-\\nM V30 ', '(')\n .replaceAll('-\\nM V30 ', '').replaceAll(' )', ')');\n const numbers = extractAtomsBondsNumbersV3000(molBlocks[i]);\n const coordinates = extractAtomDataV3000(molBlocks[i]);\n\n if (i >= strands.senseStrands.length) {\n if (inverted === false) {\n // AS strand\n inverted = true;\n xShift = 0;\n }\n } else {\n // SS strands\n ssYShift = Math.min(ssYShift, Math.min(\n ...coordinates.y.filter((item) => item < 0)\n ));\n }\n\n if (inverted) {\n const xShiftRight = Math.min(...coordinates.x) - xShift;\n const yShift = Math.max(...coordinates.y) + 5;\n for (let j = 0; j < coordinates.x.length; j++)\n coordinates.x[j] -= xShiftRight;\n for (let j = 0; j < coordinates.y.length; j++)\n coordinates.y[j] -= yShift - ssYShift;\n }\n\n let indexAtoms = molBlocks[i].indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n indexAtoms = molBlocks[i].indexOf('\\n', indexAtoms);\n let index = indexAtoms;\n let indexEnd = indexAtoms;\n\n for (let j = 0; j < numbers.natom; j++) {\n // if (coordinates.atomIndex[j] !== 1 || i === 0 || twoChains) {\n //rewrite atom number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite coordinates\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n\n const totalShift = true ? 0 : xShift - coordinates.x[0];\n let coordinate = true ?\n Math.round(10000 * coordinates.x[j]) / 10000 :\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)) + totalShift)) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n coordinate = true ?\n Math.round(10000 * coordinates.y[j]) / 10000 :\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)))) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexAtomsEnd = molBlocks[i].indexOf('M V30 END ATOM');\n atomBlock += molBlocks[i].substring(indexAtoms + 1, indexAtomsEnd);\n\n let indexBonds = molBlocks[i].indexOf('M V30 BEGIN BOND'); // V3000 index for bonds\n indexBonds = molBlocks[i].indexOf('\\n', indexBonds);\n index = indexBonds;\n indexEnd = indexBonds;\n\n for (let j = 0; j < numbers.nbond; j++) {\n //rewrite bond number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const bondNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + nbond;\n molBlocks[i] = molBlocks[i].slice(0, index) + bondNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite atom pair in bond\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = Math.min(molBlocks[i].indexOf('\\n', index), molBlocks[i].indexOf(' ', index));\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexBondEnd = molBlocks[i].indexOf('M V30 END BOND');\n bondBlock += molBlocks[i].substring(indexBonds + 1, indexBondEnd);\n\n let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections\n\n while (indexCollection !== -1) {\n indexCollection += 28;\n const collectionEnd = molBlocks[i].indexOf(')', indexCollection);\n const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);\n collectionEntries.forEach((e) => {\n collection.push(parseInt(e) + natom);\n });\n indexCollection = collectionEnd;\n indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);\n }\n\n natom += true ? numbers.natom : numbers.natom - 1;\n nbond += numbers.nbond;\n xShift += Math.max(...coordinates.x) + 5;//twoChains ? 0 : coordinates.x[numbers.natom - 1] - coordinates.x[0];\n }\n\n const entries = 4;\n const collNumber = Math.ceil(collection.length / entries);\n\n collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\\n';\n for (let i = 0; i < collNumber; i++) {\n collectionBlock += 'M V30 ';\n const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;\n for (let j = 0; j < entriesCurrent; j++) {\n collectionBlock += (j + 1 === entriesCurrent) ?\n (i === collNumber - 1 ? collection[entries * i + j] + ')\\n' : collection[entries * i + j] + ' -\\n') :\n collection[entries * i + j] + ' ';\n }\n }\n\n //generate file\n true ? natom : natom++;\n macroMolBlock += 'M V30 COUNTS ' + natom + ' ' + nbond + ' 0 0 0\\n';\n macroMolBlock += 'M V30 BEGIN ATOM\\n';\n macroMolBlock += atomBlock;\n macroMolBlock += 'M V30 END ATOM\\n';\n macroMolBlock += 'M V30 BEGIN BOND\\n';\n macroMolBlock += bondBlock;\n macroMolBlock += 'M V30 END BOND\\n';\n if (useChirality && collection.length > 0) {\n macroMolBlock += 'M V30 BEGIN COLLECTION\\n';\n macroMolBlock += collectionBlock;\n macroMolBlock += 'M V30 END COLLECTION\\n';\n } else {\n macroMolBlock = macroMolBlock.replace(/ CFG=\\d/g, ' ');\n }\n\n macroMolBlock += 'M V30 END CTAB\\n';\n macroMolBlock += 'M END';\n\n return macroMolBlock;\n}\n\nexport function linkV3000(molBlocks: string[], useChirality: boolean = true): string {\n let macroMolBlock = '\\nDatagrok macromolecule handler\\n\\n';\n macroMolBlock += ' 0 0 0 0 0 0 999 V3000\\n';\n macroMolBlock += 'M V30 BEGIN CTAB\\n';\n let atomBlock = '';\n let bondBlock = '';\n let collectionBlock = '';\n const collection: number [] = [];\n let natom = 0;\n let nbond = 0;\n let xShift = 0;\n\n for (let i = 0; i < molBlocks.length; i++) {\n const isBoundary = molBlocks[i].includes('MODIFICATION') && i === 0;\n let specLength = 0;\n if (isBoundary) {\n const coordinates = extractAtomDataV3000(molBlocks[i]);\n specLength = coordinates.atomIndex.length;\n }\n\n\n molBlocks[i] = molBlocks[i].replaceAll('(-\\nM V30 ', '(')\n .replaceAll('-\\nM V30 ', '').replaceAll(' )', ')');\n const numbers = extractAtomsBondsNumbersV3000(molBlocks[i]);\n const coordinates = extractAtomDataV3000(molBlocks[i]);\n\n let indexAtoms = molBlocks[i].indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n indexAtoms = molBlocks[i].indexOf('\\n', indexAtoms);\n let index = indexAtoms;\n let indexEnd = indexAtoms;\n\n for (let j = 0; j < numbers.natom; j++) {\n if (coordinates.atomIndex[j] !== 1 || i === 0) {\n //rewrite atom number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite coordinates\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n\n const totalShift = xShift - coordinates.x[0];\n let coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)) + totalShift)) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)))) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n } else {\n index = molBlocks[i].indexOf('M V30', index) - 1;\n indexEnd = molBlocks[i].indexOf('\\n', index + 1);\n molBlocks[i] = molBlocks[i].slice(0, index) + molBlocks[i].slice(indexEnd);\n }\n }\n\n const indexAtomsEnd = molBlocks[i].indexOf('M V30 END ATOM');\n atomBlock += molBlocks[i].substring(indexAtoms + 1, indexAtomsEnd);\n\n let indexBonds = molBlocks[i].indexOf('M V30 BEGIN BOND'); // V3000 index for bonds\n indexBonds = molBlocks[i].indexOf('\\n', indexBonds);\n index = indexBonds;\n indexEnd = indexBonds;\n\n for (let j = 0; j < numbers.nbond; j++) {\n //rewrite bond number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const bondNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + nbond;\n molBlocks[i] = molBlocks[i].slice(0, index) + bondNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite atom pair in bond\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = Math.min(molBlocks[i].indexOf('\\n', index), molBlocks[i].indexOf(' ', index));\n atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexBondEnd = molBlocks[i].indexOf('M V30 END BOND');\n bondBlock += molBlocks[i].substring(indexBonds + 1, indexBondEnd);\n\n let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections\n\n while (indexCollection !== -1) {\n indexCollection += 28;\n const collectionEnd = molBlocks[i].indexOf(')', indexCollection);\n const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);\n collectionEntries.forEach((e) => {\n collection.push(parseInt(e) + natom);\n });\n indexCollection = collectionEnd;\n indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);\n }\n\n natom += numbers.natom - 1;\n nbond += numbers.nbond;\n if (isBoundary)\n xShift += Math.max(...coordinates.x);\n else\n xShift += coordinates.x[numbers.natom - 1] - coordinates.x[0];\n }\n\n const entries = 4;\n const collNumber = Math.ceil(collection.length / entries);\n\n collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\\n';\n for (let i = 0; i < collNumber; i++) {\n collectionBlock += 'M V30 ';\n const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;\n for (let j = 0; j < entriesCurrent; j++) {\n collectionBlock += (j + 1 === entriesCurrent) ?\n (i === collNumber - 1 ? collection[entries * i + j] + ')\\n' : collection[entries * i + j] + ' -\\n') :\n collection[entries * i + j] + ' ';\n }\n }\n //}\n\n //generate file\n natom++;\n macroMolBlock += 'M V30 COUNTS ' + natom + ' ' + nbond + ' 0 0 0\\n';\n macroMolBlock += 'M V30 BEGIN ATOM\\n';\n macroMolBlock += atomBlock;\n macroMolBlock += 'M V30 END ATOM\\n';\n macroMolBlock += 'M V30 BEGIN BOND\\n';\n macroMolBlock += bondBlock;\n macroMolBlock += 'M V30 END BOND\\n';\n if (useChirality && collection.length > 0) {\n macroMolBlock += 'M V30 BEGIN COLLECTION\\n';\n macroMolBlock += collectionBlock;\n macroMolBlock += 'M V30 END COLLECTION\\n';\n } else { macroMolBlock = macroMolBlock.replace(/ CFG=\\d/g, ' '); }\n\n macroMolBlock += 'M V30 END CTAB\\n';\n macroMolBlock += 'M END';\n\n return macroMolBlock;\n}\n\nfunction rotateNucleotidesV3000(molBlock: string): string {\n const coordinates = extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n //fix 5 prime if inadequate\n if (natom > 8)\n fix5Prime(coordinates, indexFivePrime, indexThreePrime);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n let angle = 0;\n if (coordinates.x[indexFivePrime] === 0) {\n angle = coordinates.y[indexFivePrime] > coordinates.y[indexThreePrime] ? Math.PI / 2 : 3 * Math.PI / 2;\n } else if (coordinates.y[indexFivePrime] === 0) {\n angle = coordinates.x[indexFivePrime] > coordinates.x[indexThreePrime] ? Math.PI : 0;\n } else {\n const derivative = coordinates.y[indexFivePrime] / coordinates.x[indexFivePrime];\n angle = derivative > 0 ?\n (coordinates.x[indexFivePrime] > 0 ? Math.PI - Math.atan(derivative) : Math.PI * 2 - Math.atan(derivative)) :\n (coordinates.x[indexFivePrime] > 0 ? -Math.PI - Math.atan(derivative) : Math.atan(derivative));\n }\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n for (let i = 0; i < natom; i++) {\n const xAdd = coordinates.x[i];\n coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;\n coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;\n }\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n}\n\nfunction reflect(molBlock: string): string {\n const coordinates = extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n //place to center\n for (let i = 0; i < natom; i++)\n coordinates.x[i] = -coordinates.x[i];\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n}\n\n\nfunction invertNucleotidesV3000(molBlock: string) {\n const coordinates = extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const xCenter = (Math.max(...coordinates.x) + Math.min(...coordinates.x)) / 2;\n const yCenter = (Math.max(...coordinates.y) + Math.min(...coordinates.y)) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n const angle = Math.PI;\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n for (let i = 0; i < natom; i++) {\n const xAdd = coordinates.x[i];\n coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;\n coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;\n }\n\n //place back\n const yShift = Math.max(...coordinates.y);\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] += xCenter;\n coordinates.y[i] -= yShift;\n }\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n}\n\nfunction fix5Prime(coordinates: { atomIndex: number[], atomType: string[], x: number[], y: number[] },\n indexFivePrime: number, indexThreePrime: number) {\n const indexFivePrimeNeighbour = indexFivePrime + 1;\n const xShift = coordinates.x[indexFivePrimeNeighbour];\n const yShift = coordinates.y[indexFivePrimeNeighbour];\n const base3PrimeX = coordinates.x[indexThreePrime] - xShift;\n const base3PrimeY = coordinates.y[indexThreePrime] - yShift;\n const base5PrimeX = coordinates.x[indexFivePrime] - xShift;\n const base5PrimeY = coordinates.y[indexFivePrime] - yShift;\n\n const rotated5PrimeX = base5PrimeX * Math.cos(Math.PI * 2 / 3) - base5PrimeY * Math.sin(Math.PI * 2 / 3);\n const rotated5PrimeY = base5PrimeX * Math.sin(Math.PI * 2 / 3) + base5PrimeY * Math.cos(Math.PI * 2 / 3);\n\n const dx = base5PrimeX - base3PrimeX;\n const dy = base5PrimeY - base3PrimeY;\n const dxRotated = rotated5PrimeX - base3PrimeX;\n const dyRotated = rotated5PrimeY - base3PrimeY;\n\n if (Math.sqrt(dyRotated * dyRotated + dxRotated * dxRotated) >= Math.sqrt(dy * dy + dx * dx)) {\n coordinates.x[indexFivePrime] = rotated5PrimeX + xShift;\n coordinates.y[indexFivePrime] = rotated5PrimeY + yShift;\n }\n}\n\nfunction extractAtomsBondsNumbersV3000(molBlock: string): { natom: number, nbond: number } {\n molBlock = molBlock.replaceAll('\\r', ''); //equalize old and new sdf standards\n let index = molBlock.indexOf('COUNTS') + 7; // V3000 index for atoms and bonds number\n let indexEnd = molBlock.indexOf(' ', index);\n\n const atomsNumber = parseInt(molBlock.substring(index, indexEnd));\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n const bondsNumber = parseInt(molBlock.substring(index, indexEnd));\n\n return {natom: atomsNumber, nbond: bondsNumber};\n}\n\nexport function extractAtomDataV3000(molBlock: string) {\n const numbers = extractAtomsBondsNumbersV3000(molBlock);\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n\n const indexes: number[] = Array(numbers.natom);\n const types: string[] = Array(numbers.natom);\n const x: number[] = Array(numbers.natom);\n const y: number[] = Array(numbers.natom);\n\n for (let i = 0; i < numbers.natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n indexEnd = molBlock.indexOf(' ', index);\n indexes[i] = parseInt(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n types[i] = molBlock.substring(index, indexEnd);\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n x[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n y[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return {atomIndex: indexes, atomType: types, x: x, y: y};\n}\n","export const GROUP_TYPE = {\n NUCLEOSIDE: 'nucleoside',\n LINKAGE: 'phosphateBackbone',\n} as const;\n\nexport const PHOSPHATE_SYMBOL = 'p';\n\nexport const UNKNOWN_SYMBOL = '<?>';\n","import {DEFAULT_FORMATS, NUCLEOTIDES} from '../const';\nimport {UNKNOWN_SYMBOL} from './const';\nimport {FormatConverter} from './format-converter';\nimport {codesToHelmDictionary} from '../data-loading-utils/json-loader';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\n\nexport function getTranslatedSequences(sequence: string, indexOfFirstInvalidChar: number, sourceFormat: string): {[key: string]: string} {\n const supportedFormats = Object.keys(codesToHelmDictionary).concat([DEFAULT_FORMATS.HELM]) as string[];\n\n if (!sequence || (indexOfFirstInvalidChar !== -1 && sourceFormat !== DEFAULT_FORMATS.HELM))\n return {};\n\n if (!supportedFormats.includes(sourceFormat))\n throw new Error(`${sourceFormat} format is not supported by SequenceTranslator`)\n\n const outputFormats = supportedFormats.filter((el) => el != sourceFormat)\n .sort((a, b) => a.localeCompare(b));\n const converter = new FormatConverter(sequence, sourceFormat);\n const result = Object.fromEntries(\n outputFormats.map((format) => {\n let translation;\n try {\n translation = converter.convertTo(format);\n } catch {\n translation = null;\n }\n return [format, translation];\n }).filter(([format, translation]) => translation)\n )\n const helm = (sourceFormat === DEFAULT_FORMATS.HELM) ? sequence : result[DEFAULT_FORMATS.HELM];\n const nucleotides = getNucleotidesSequence(helm, MonomerLibWrapper.getInstance());\n if (nucleotides)\n result['Nucleotides'] = nucleotides;\n return result;\n}\n\nexport function getNucleotidesSequence(helmString: string, monomerLib: MonomerLibWrapper): string | null {\n const re = new RegExp('\\\\([^()]*\\\\)', 'g');\n const branches = helmString.match(re);\n if (!branches)\n return null;\n const nucleotides = branches!.map((branch) => {\n const stripped = branch.replace(/[\\[\\]()]/g, '');\n if (NUCLEOTIDES.includes(stripped))\n return stripped;\n return monomerLib.getNaturalAnalogBySymbol(stripped);\n }).map((el) => el ? el : UNKNOWN_SYMBOL).join('');\n return nucleotides;\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {codesToHelmDictionary} from '../data-loading-utils/json-loader';\nimport {CodesInfo} from '../data-loading-utils/types';\nimport {DEFAULT_FORMATS} from '../const';\nimport {GROUP_TYPE, PHOSPHATE_SYMBOL} from '../translator-app/const';\n\nconst inverseLengthComparator = (a: string, b: string) => b.length - a.length;\n\nexport class FormatHandler {\n constructor() {\n this.formats = this.getFormats();\n }\n\n /** Includes all formats except HELM (the \"default\" one) */\n private formats: string[];\n\n /** All format names except HELM (the \"default\" one) */\n getFormatNames(): string[] {\n return this.formats.sort();\n };\n\n getCodesByFormat(format: string): string[] {\n this.validateFormat(format);\n\n if (this.isHelm(format))\n throw new Error(`Codes cannot be obtained for HELM`);\n return this.getFormatCodes(format);\n }\n\n getHelmToFormatDict(format: string): {[key: string]: string} {\n this.validateFormat(format);\n\n const codesInfoObject = codesToHelmDictionary[format] as CodesInfo;\n const dict = getHelmToCodeDict(codesInfoObject);\n return dict;\n }\n\n getFormatToHelmDict(format: string): {[key: string]: string} {\n this.validateFormat(format);\n\n const codesInfoObject = codesToHelmDictionary[format] as CodesInfo;\n const dict = Object.assign({}, ...Object.values(codesInfoObject)) as {[code: string]: string};\n return dict;\n }\n\n /** Get helm codes for the specified format */\n getTargetFormatHelmCodes(format: string): string[] {\n this.validateFormat(format);\n\n const dict = this.getHelmToFormatDict(format);\n const helmCodes = Object.keys(dict).sort(inverseLengthComparator);\n return helmCodes;\n }\n\n getTargetFormatHelmCodesRegExp(format: string): RegExp {\n this.validateFormat(format);\n\n const helmCodes = this.getTargetFormatHelmCodes(format);\n const helmRegExp = new RegExp(getRegExpPattern(helmCodes) + '|.', 'g');\n return helmRegExp;\n }\n\n getFormatRegExp(format: string): RegExp {\n this.validateFormat(format);\n\n if (this.isHelm(format))\n throw new Error(`Helm RegExp can be built for non-HELM target formats`);\n return this.getNonHelmFormatRegExp(format);\n }\n\n getPhosphateHelmCodesRegExp(format: string): RegExp {\n this.validateFormat(format);\n\n const codesInfoObject = codesToHelmDictionary[format] as CodesInfo;\n const phosphateHELMCodes = Array.from(\n new Set(Object.values(codesInfoObject[GROUP_TYPE.LINKAGE]))\n ).sort(inverseLengthComparator);\n const phosphateHELMPattern = getRegExpPattern(phosphateHELMCodes);\n const phosphateRegExp = new RegExp(`${PHOSPHATE_SYMBOL}\\.(${phosphateHELMPattern})`, 'g');\n return phosphateRegExp;\n }\n\n isValidFormat(format: string): boolean {\n return this.formats.includes(format);\n }\n\n private getFormats(): string[] {\n return Object.keys(codesToHelmDictionary);\n }\n\n private validateFormat(format: string) {\n if (!this.isValidFormat(format))\n throw new Error(`Invalid format: ${format}`);\n }\n\n private isHelm(format: string): boolean {\n return format === DEFAULT_FORMATS.HELM;\n }\n\n private getFormatCodes(format: string): string[] {\n const dict = this.getFormatToHelmDict(format);\n const formatCodes = Object.keys(dict).sort(inverseLengthComparator);\n return formatCodes;\n }\n \n private getNonHelmFormatRegExp(format: string): RegExp {\n const formatCodes = this.getCodesByFormat(format);\n const formatRegExp = new RegExp(getRegExpPattern(formatCodes) + '|\\\\([^()]*\\\\)|.', 'g'); // the added group before '|.' is to avoid mismatch inside parenths\n return formatRegExp;\n }\n}\n\nexport function getRegExpPattern(arr: string[]): string {\n const negativeLookBehind = '(?<!\\\\([^()]*)'; // not '(' followed by non-parenths\n const negativeLookAhead = '(?![^()]*\\\\))'; // not ')' preceded by non-parenths\n const escaped = arr.map((key) => key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .map((key) => {\n if (!key.includes('(') && !key.includes(')'))\n return `${negativeLookBehind}${key}${negativeLookAhead}`;\n return key;\n });\n const result = escaped.join('|');\n return result;\n}\n\nfunction getHelmToCodeDict(infoObj: CodesInfo) {\n const result: {[key: string]: string | string[]} = {};\n Object.values(infoObj).forEach((obj: {[code: string]: string}) => {\n Object.entries(obj).forEach(([code, helm]) => {\n const key = helm.replace(/\\)p/g, ')').replace(/\\]p/g, ']');\n if (result[key] === undefined) {\n result[key] = [code];\n } else {\n (result[key] as string[]).push(code);\n }\n })\n });\n Object.entries(result).forEach(([key, value]) => {\n const sorted = (value as string[]).sort(inverseLengthComparator);\n result[key] = sorted[0] as string;\n })\n return result as {[key: string]: string};\n}\n","import * as DG from 'datagrok-api/dg';\nimport {DEFAULT_FORMATS} from '../const';\nimport {PHOSPHATE_SYMBOL, UNKNOWN_SYMBOL} from './const';\nimport {FormatHandler, getRegExpPattern} from '../parsing-validation/format-handler';\n\nconst HELM_WRAPPER = {\n LEFT: 'RNA1{',\n RIGHT: '}$$$$',\n};\n\nexport class FormatConverter {\n constructor(private readonly sequence: string, private readonly sourceFormat: string) { };\n\n private formats = new FormatHandler();\n\n convertTo(targetFormat: string): string {\n const formats = this.formats.getFormatNames();\n\n if (this.sourceFormat === DEFAULT_FORMATS.HELM && formats.includes(targetFormat))\n return this.helmToFormat(this.sequence, targetFormat);\n else if (formats.includes(this.sourceFormat) && targetFormat === DEFAULT_FORMATS.HELM)\n return this.formatToHelm(this.sequence, this.sourceFormat);\n else if ([this.sourceFormat, targetFormat].every((el) => formats.includes(el))) {\n const helm = this.formatToHelm(this.sequence, this.sourceFormat);\n return this.helmToFormat(helm, targetFormat);\n }\n else {\n throw new Error (`ST: unsupported translation direction ${this.sourceFormat} -> ${targetFormat}`);\n }\n }\n\n private helmToFormat(helmSequence: string, targetFormat: string): string {\n const wrapperRegExp = new RegExp(getRegExpPattern(Object.values(HELM_WRAPPER)), 'g')\n let result = helmSequence.replace(wrapperRegExp, '');\n\n const dict = this.formats.getHelmToFormatDict(targetFormat);\n const helmCodes = this.formats.getTargetFormatHelmCodes(targetFormat);\n const helmRegExp = this.formats.getTargetFormatHelmCodesRegExp(targetFormat);\n\n result = result.replace(helmRegExp, (match) => {\n return helmCodes.includes(match) ? dict[match] :\n (match === 'p' || match === '.') ? match : '?';\n }).replace(/\\?+/g, UNKNOWN_SYMBOL).replace(/p\\.|\\./g, '');\n result = result.replace(/<empty>/g, '');\n // remove double slash in LCMS codes\n result = result.replace(/\\/\\//g, '/');\n return result;\n }\n\n private formatToHelm(sequence: string, sourceFormat: string): string {\n const dict = this.formats.getFormatToHelmDict(sourceFormat);\n const formatCodes = this.formats.getCodesByFormat(sourceFormat);\n const formatRegExp = this.formats.getFormatRegExp(sourceFormat);\n const phosphateRegExp = this.formats.getPhosphateHelmCodesRegExp(sourceFormat);\n\n let helm = sequence.replace(formatRegExp, (match) => {\n const result = formatCodes.includes(match) ? dict[match] + '.' : '?';\n return result;\n });\n helm = helm.replace(/\\?+/g, `${UNKNOWN_SYMBOL}.`);\n helm = helm.slice(0, -1); // strip last dot\n if (helm[helm.length - 1] === PHOSPHATE_SYMBOL)\n helm = helm.slice(0, -1);\n helm = helm.replace(phosphateRegExp, (match, group) => group);\n helm = helm.replace(/<empty>/g, '');\n return `${HELM_WRAPPER.LEFT + helm + HELM_WRAPPER.RIGHT}`;\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = ui;","const __WEBPACK_NAMESPACE_OBJECT__ = rxjs;","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./translator-app.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./translator-app.css\";\n export default content && content.locals ? content.locals : undefined;\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {sortByReverseLength} from '../helpers';\nimport {DEFAULT_FORMATS} from '../const';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\nimport {codesToHelmDictionary} from '../data-loading-utils/json-loader';\nimport {SequenceValidator} from './sequence-validator';\n\nexport class FormatDetector {\n constructor (private sequence: string) {\n this.libWrapper = MonomerLibWrapper.getInstance();\n this.formats = Object.keys(codesToHelmDictionary);\n };\n\n private libWrapper: MonomerLibWrapper;\n private formats: string[];\n\n getFormat(): string | null {\n // todo: reliable criterion\n if (this.sequence.startsWith('RNA'))\n return DEFAULT_FORMATS.HELM;\n const possibleFormats = this.getListOfPossibleSynthesizersByFirstMatchedCode();\n if (possibleFormats.length === 0)\n return null;\n\n const validator = new SequenceValidator(this.sequence);\n const outputIndices = Array(possibleFormats.length).fill(0);\n for (let i = 0; i < possibleFormats.length; ++i) {\n const format = possibleFormats[i];\n outputIndices[i] = validator.getInvalidCodeIndex(format);\n }\n const formatIdx = (outputIndices.some((idx) => idx === -1)) ? -1 : Math.max(...outputIndices);\n return possibleFormats[outputIndices.indexOf(formatIdx)];\n }\n\n // todo: rename\n private getListOfPossibleSynthesizersByFirstMatchedCode(): string[] {\n const sequence = this.sequence;\n let synthesizers: string[] = [];\n for (const format of this.formats) {\n let codes = sortByReverseLength(this.libWrapper.getCodesByFormat(format));\n let start = 0;\n for (let i = 0; i < sequence.length; i++) {\n if (sequence[i] === ')' && i !== sequence.length - 1) {\n start = i + 1;\n break;\n }\n }\n if (codes.some((s: string) => s === sequence.slice(start, start + s.length)))\n synthesizers.push(format);\n }\n return synthesizers;\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = $;","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {SequenceValidator} from '../../../model/parsing-validation/sequence-validator';\nimport {FormatDetector} from '../../../model/parsing-validation/format-detector';\n\nimport $ from 'cash-dom';\n\n/** Set different colors for letters, can be upgraded to color various monomers */\nexport function demoPainter(input: string): HTMLSpanElement[] {\n const colors = ['red', 'blueviolet', 'chartreuse',\n 'aquamarine', 'darkcyan', 'gold', 'green', 'aqua', 'orange',\n 'blue'];\n const spans: HTMLSpanElement[] = [];\n for (let i = 0; i < input.length; ++i) {\n const span = ui.span([input.charAt(i)]);\n // $(span).css('-webkit-text-fill-color', colors.at(Math.round(Math.random() * colors.length))!);\n $(span).css('-webkit-text-fill-color', colors[i % colors.length]!);\n spans.push(span);\n }\n return spans;\n}\n\n// todo: port to another place\nexport function highlightInvalidSubsequence(input: string): HTMLSpanElement[] {\n // validate sequence\n let cutoff = 0;\n const format = (new FormatDetector(input)).getFormat();\n if (format !== null)\n cutoff = (new SequenceValidator(input)).getInvalidCodeIndex(format!);\n const isValid = cutoff < 0 || input === '';\n const greyTextSpan = ui.span([]);\n $(greyTextSpan).css('-webkit-text-fill-color', 'var(--grey-6)');\n const redTextSpan = ui.span([]);\n $(redTextSpan).css('-webkit-text-fill-color', 'red');\n\n if (!isValid) {\n greyTextSpan.innerHTML = input.slice(0, cutoff);\n redTextSpan.innerHTML = input.slice(cutoff);\n } else { greyTextSpan.innerHTML = input; }\n return [greyTextSpan, redTextSpan];\n};\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./colored-text-input.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./colored-text-input.css\";\n export default content && content.locals ? content.locals : undefined;\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\n// external modules dependencies\nimport $ from 'cash-dom';\n\n// inner dependencies\nimport '../../style/colored-text-input.css';\n\n\n/** Class for colorizing input in the textarea of DG.InputBase. */\nexport class ColoredTextInput {\n constructor(\n private textInputBase: DG.InputBase<string>,\n /** Divide input value into an array of spans, each with its own text color, use -webkit-text-fill-color. */\n private painter: (str: string) => HTMLSpanElement[],\n /** Resize, no scrolls */\n resizeable: boolean = true\n ) {\n $(this.root).addClass('colored-text-input');\n if (resizeable) {\n // make input field automatically resizeable\n this.textInputBase.onChanged(\n () => {\n // necessary for the field to be squeezable, not only expandable\n $(this.textArea).css('height', 0);\n $(this.textArea).css('height', (this.textArea!.scrollHeight) + 'px');\n }\n );\n }\n this.highlights = ui.div([]);\n this.root.appendChild(this.highlights);\n this.colorize();\n\n this.textInputBase.onChanged(() => this.colorize());\n }\n\n private highlights: HTMLDivElement;\n\n get textArea() {\n return this.textInputBase.root.getElementsByTagName('textarea').item(0);\n };\n\n get inputBase() {\n return this.textInputBase;\n }\n\n get root() { return this.textInputBase.root; };\n\n private colorize() {\n const spans = this.painter(this.textInputBase.value);\n this.highlights.innerHTML = '';\n spans.forEach((span: HTMLSpanElement) => this.highlights.appendChild(span));\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {PHOSPHATE_SYMBOL} from './const';\nimport {sortByReverseLength} from '../helpers';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\nimport {monomersWithPhosphateLinkers} from '../data-loading-utils/json-loader';\n\n/** Wrapper for parsing a strand and getting a sequence of monomer IDs (with\n * omitted linkers, if needed) */\nexport class MonomerSequenceParser {\n constructor(\n private sequence: string, \n // todo: remove from the list of parameters\n private codeMap: Map<string, string>\n ) {\n }\n\n /** Get sequence of parsed monomer symbols, which are unique short names for\n * the monomers within the Monomer Library */\n parseSequence(): string[] {\n const parsedRawCodes = this.parseRawSequence();\n return this.addLinkers(parsedRawCodes);\n }\n\n private addLinkers(parsedRawCodes: string[]) {\n const monomerSymbolSequence: string[] = [];\n parsedRawCodes.forEach((code, i) => {\n const monomerSymbol = this.getSymbolForCode(code);\n if (i > 0 && monomerHasLeftPhosphateLinker(monomerSymbol))\n monomerSymbolSequence.pop();\n\n monomerSymbolSequence.push(monomerSymbol);\n\n const isPhosphate = monomerIsPhosphateLinker(monomerSymbol);\n const lastMonomer = i === parsedRawCodes.length - 1;\n const nextMonomerIsPhosphate = (i + 1 < parsedRawCodes.length && monomerIsPhosphateLinker(this.getSymbolForCode(parsedRawCodes[i + 1])));\n\n // todo: refactor as molfile-specific\n if (!isPhosphate && !monomerHasRightPhosphateLinker(monomerSymbol) && !nextMonomerIsPhosphate && !lastMonomer) {\n monomerSymbolSequence.push(PHOSPHATE_SYMBOL);\n }\n });\n return monomerSymbolSequence;\n }\n\n private getSymbolForCode(code: string): string {\n let monomerSymbol = this.codeMap.get(code);\n // todo: remove as a legacy workaround, codeMap must contain all the\n // symbols, and symbols are not codes\n monomerSymbol ??= code;\n return monomerSymbol;\n }\n\n private parseRawSequence(): string[] {\n const allCodesOfFormat = this.getAllCodesOfFormat();\n const parsedCodes = [];\n let i = 0;\n while (i < this.sequence.length) {\n const code = allCodesOfFormat.find(\n (s: string) => s === this.sequence.substring(i, i + s.length)\n )!;\n parsedCodes.push(code);\n i += code.length;\n }\n return parsedCodes;\n }\n\n // todo: port to monomer handler\n private getAllCodesOfFormat(): string[] {\n let allCodesInTheFormat = Array.from(this.codeMap.keys());\n return sortByReverseLength(allCodesInTheFormat);\n }\n}\n\n// todo: to be eliminated after full helm support\nfunction monomerHasLeftPhosphateLinker(monomerSymbol: string): boolean {\n return monomersWithPhosphateLinkers['left'].includes(monomerSymbol);\n}\n\nfunction monomerHasRightPhosphateLinker(monomerSymbol: string): boolean {\n return monomersWithPhosphateLinkers['right'].includes(monomerSymbol);\n}\n\nfunction monomerIsPhosphateLinker(monomerSymbol: string): boolean {\n return monomersWithPhosphateLinkers['phosphate'].includes(monomerSymbol);\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {MonomerSequenceParser} from './monomer-code-parser';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\n\nexport class SequenceToMolfileConverter {\n constructor(\n sequence: string, private invert: boolean = false, format: string\n ) {\n this.lib = MonomerLibWrapper.getInstance();\n const codeToSymbolMap = this.lib.getCodeToSymbolMap(format);\n this.parser = new MonomerSequenceParser(sequence, codeToSymbolMap);\n }\n\n private parser: MonomerSequenceParser;\n private lib: MonomerLibWrapper;\n\n convert(): string {\n const parsedSequence = this.parser.parseSequence();\n const monomerMolfiles: string[] = [];\n parsedSequence.forEach((monomerSymbol, idx) => {\n const monomerMolfile = this.getMonomerMolfile(monomerSymbol, idx);\n monomerMolfiles.push(monomerMolfile);\n })\n let molfile = this.getPolymerMolfile(monomerMolfiles);\n if (this.invert) {\n molfile = this.reflect(molfile);\n molfile = this.invertBondConfiguration(molfile);\n }\n return molfile;\n }\n\n private invertBondConfiguration(molfile: string): string {\n const beginIdx = molfile.indexOf('M V30 BEGIN BOND');\n const endIdx = molfile.indexOf('M V30 END BOND');\n let bondBlock = molfile.substring(beginIdx, endIdx);\n bondBlock = bondBlock.replace(\n /(CFG=)([13])/g,\n (match, group1, group2) => (group2 === '1') ? `${group1}3` : (group2 === '3') ? `${group1}1` : match\n );\n const result = molfile.substring(0, beginIdx) + bondBlock + molfile.substring(endIdx);\n return result;\n }\n\n private getMonomerMolfile(monomerSymbol: string, idx: number): string {\n const molBlock = this.lib.getMolfileBySymbol(monomerSymbol);\n if (this.lib.isModification(monomerSymbol))\n return (idx === 0) ? this.reflect(molBlock) : molBlock;\n else\n return this.rotateNucleotidesV3000(molBlock);\n }\n\n private getPolymerMolfile(monomerMolfiles: string[]) {\n return this.linkV3000(monomerMolfiles);\n }\n\n private reflect(molBlock: string): string {\n const coordinates = this.extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n //place to center\n for (let i = 0; i < natom; i++)\n coordinates.x[i] = -coordinates.x[i];\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n }\n\n private extractAtomDataV3000(molBlock: string) {\n const numbers = this.extractAtomsBondsNumbersV3000(molBlock);\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n\n const indexes: number[] = Array(numbers.natom);\n const types: string[] = Array(numbers.natom);\n const x: number[] = Array(numbers.natom);\n const y: number[] = Array(numbers.natom);\n\n for (let i = 0; i < numbers.natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n indexEnd = molBlock.indexOf(' ', index);\n indexes[i] = parseInt(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n types[i] = molBlock.substring(index, indexEnd);\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n x[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n y[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return {atomIndex: indexes, atomType: types, x: x, y: y};\n }\n\n private extractAtomsBondsNumbersV3000(molBlock: string): { natom: number, nbond: number } {\n molBlock = molBlock.replaceAll('\\r', ''); //equalize old and new sdf standards\n let index = molBlock.indexOf('COUNTS') + 7; // V3000 index for atoms and bonds number\n let indexEnd = molBlock.indexOf(' ', index);\n\n const atomsNumber = parseInt(molBlock.substring(index, indexEnd));\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n const bondsNumber = parseInt(molBlock.substring(index, indexEnd));\n\n return {natom: atomsNumber, nbond: bondsNumber};\n }\n\n private rotateNucleotidesV3000(molBlock: string): string {\n const coordinates = this.extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n //fix 5 prime if inadequate\n if (natom > 8)\n this.fix5Prime(coordinates, indexFivePrime, indexThreePrime);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n let angle = 0;\n if (coordinates.x[indexFivePrime] === 0) {\n angle = coordinates.y[indexFivePrime] > coordinates.y[indexThreePrime] ? Math.PI / 2 : 3 * Math.PI / 2;\n } else if (coordinates.y[indexFivePrime] === 0) {\n angle = coordinates.x[indexFivePrime] > coordinates.x[indexThreePrime] ? Math.PI : 0;\n } else {\n const derivative = coordinates.y[indexFivePrime] / coordinates.x[indexFivePrime];\n angle = derivative > 0 ?\n (coordinates.x[indexFivePrime] > 0 ? Math.PI - Math.atan(derivative) : Math.PI * 2 - Math.atan(derivative)) :\n (coordinates.x[indexFivePrime] > 0 ? -Math.PI - Math.atan(derivative) : Math.atan(derivative));\n }\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n for (let i = 0; i < natom; i++) {\n const xAdd = coordinates.x[i];\n coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;\n coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;\n }\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n }\n\n\n private linkV3000(molBlocks: string[], useChirality: boolean = true): string {\n let macroMolBlock = '\\nDatagrok macromolecule handler\\n\\n';\n macroMolBlock += ' 0 0 0 0 0 0 999 V3000\\n';\n macroMolBlock += 'M V30 BEGIN CTAB\\n';\n let atomBlock = '';\n let bondBlock = '';\n let collectionBlock = '';\n const collection: number [] = [];\n let natom = 0;\n let nbond = 0;\n let xShift = 0;\n\n for (let i = 0; i < molBlocks.length; i++) {\n const isBoundary = molBlocks[i].includes('MODIFICATION') && i === 0;\n let specLength = 0;\n if (isBoundary) {\n const coordinates = this.extractAtomDataV3000(molBlocks[i]);\n specLength = coordinates.atomIndex.length;\n }\n\n\n molBlocks[i] = molBlocks[i].replaceAll('(-\\nM V30 ', '(')\n .replaceAll('-\\nM V30 ', '').replaceAll(' )', ')');\n const numbers = this.extractAtomsBondsNumbersV3000(molBlocks[i]);\n const coordinates = this.extractAtomDataV3000(molBlocks[i]);\n\n let indexAtoms = molBlocks[i].indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n indexAtoms = molBlocks[i].indexOf('\\n', indexAtoms);\n let index = indexAtoms;\n let indexEnd = indexAtoms;\n\n for (let j = 0; j < numbers.natom; j++) {\n if (coordinates.atomIndex[j] !== 1 || i === 0) {\n //rewrite atom number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite coordinates\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n\n const totalShift = xShift - coordinates.x[0];\n let coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)) + totalShift)) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)))) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n } else {\n index = molBlocks[i].indexOf('M V30', index) - 1;\n indexEnd = molBlocks[i].indexOf('\\n', index + 1);\n molBlocks[i] = molBlocks[i].slice(0, index) + molBlocks[i].slice(indexEnd);\n }\n }\n\n const indexAtomsEnd = molBlocks[i].indexOf('M V30 END ATOM');\n atomBlock += molBlocks[i].substring(indexAtoms + 1, indexAtomsEnd);\n\n let indexBonds = molBlocks[i].indexOf('M V30 BEGIN BOND'); // V3000 index for bonds\n indexBonds = molBlocks[i].indexOf('\\n', indexBonds);\n index = indexBonds;\n indexEnd = indexBonds;\n\n for (let j = 0; j < numbers.nbond; j++) {\n //rewrite bond number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const bondNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + nbond;\n molBlocks[i] = molBlocks[i].slice(0, index) + bondNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite atom pair in bond\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = Math.min(molBlocks[i].indexOf('\\n', index), molBlocks[i].indexOf(' ', index));\n atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexBondEnd = molBlocks[i].indexOf('M V30 END BOND');\n bondBlock += molBlocks[i].substring(indexBonds + 1, indexBondEnd);\n\n let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections\n\n while (indexCollection !== -1) {\n indexCollection += 28;\n const collectionEnd = molBlocks[i].indexOf(')', indexCollection);\n const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);\n collectionEntries.forEach((e) => {\n collection.push(parseInt(e) + natom);\n });\n indexCollection = collectionEnd;\n indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);\n }\n\n natom += numbers.natom - 1;\n nbond += numbers.nbond;\n if (isBoundary)\n xShift += Math.max(...coordinates.x);\n else\n xShift += coordinates.x[numbers.natom - 1] - coordinates.x[0];\n }\n\n const entries = 4;\n const collNumber = Math.ceil(collection.length / entries);\n\n collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\\n';\n for (let i = 0; i < collNumber; i++) {\n collectionBlock += 'M V30 ';\n const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;\n for (let j = 0; j < entriesCurrent; j++) {\n collectionBlock += (j + 1 === entriesCurrent) ?\n (i === collNumber - 1 ? collection[entries * i + j] + ')\\n' : collection[entries * i + j] + ' -\\n') :\n collection[entries * i + j] + ' ';\n }\n }\n\n //generate file\n natom++;\n macroMolBlock += 'M V30 COUNTS ' + natom + ' ' + nbond + ' 0 0 0\\n';\n macroMolBlock += 'M V30 BEGIN ATOM\\n';\n macroMolBlock += atomBlock;\n macroMolBlock += 'M V30 END ATOM\\n';\n macroMolBlock += 'M V30 BEGIN BOND\\n';\n macroMolBlock += bondBlock;\n macroMolBlock += 'M V30 END BOND\\n';\n if (useChirality && collection.length > 0) {\n macroMolBlock += 'M V30 BEGIN COLLECTION\\n';\n macroMolBlock += collectionBlock;\n macroMolBlock += 'M V30 END COLLECTION\\n';\n } else { macroMolBlock = macroMolBlock.replace(/ CFG=\\d/g, ' '); }\n\n macroMolBlock += 'M V30 END CTAB\\n';\n macroMolBlock += 'M END';\n\n return macroMolBlock;\n }\n\n private fix5Prime(coordinates: { atomIndex: number[], atomType: string[], x: number[], y: number[] },\n indexFivePrime: number, indexThreePrime: number) {\n const indexFivePrimeNeighbour = indexFivePrime + 1;\n const xShift = coordinates.x[indexFivePrimeNeighbour];\n const yShift = coordinates.y[indexFivePrimeNeighbour];\n const base3PrimeX = coordinates.x[indexThreePrime] - xShift;\n const base3PrimeY = coordinates.y[indexThreePrime] - yShift;\n const base5PrimeX = coordinates.x[indexFivePrime] - xShift;\n const base5PrimeY = coordinates.y[indexFivePrime] - yShift;\n\n const rotated5PrimeX = base5PrimeX * Math.cos(Math.PI * 2 / 3) - base5PrimeY * Math.sin(Math.PI * 2 / 3);\n const rotated5PrimeY = base5PrimeX * Math.sin(Math.PI * 2 / 3) + base5PrimeY * Math.cos(Math.PI * 2 / 3);\n\n const dx = base5PrimeX - base3PrimeX;\n const dy = base5PrimeY - base3PrimeY;\n const dxRotated = rotated5PrimeX - base3PrimeX;\n const dyRotated = rotated5PrimeY - base3PrimeY;\n\n if (Math.sqrt(dyRotated * dyRotated + dxRotated * dxRotated) >= Math.sqrt(dy * dy + dx * dx)) {\n coordinates.x[indexFivePrime] = rotated5PrimeX + xShift;\n coordinates.y[indexFivePrime] = rotated5PrimeY + yShift;\n }\n }\n}\n","/** Constants related to the structure of Molfile V2K */\nexport var V2K_CONST;\n(function (V2K_CONST) {\n V2K_CONST[\"HEADER\"] = \"V2000\";\n V2K_CONST[V2K_CONST[\"NUM_OF_HEADER_LINES\"] = 3] = \"NUM_OF_HEADER_LINES\";\n V2K_CONST[V2K_CONST[\"NUM_OF_COUNTS_DIGITS\"] = 3] = \"NUM_OF_COUNTS_DIGITS\";\n V2K_CONST[V2K_CONST[\"ATOM_TYPE_COL\"] = 4] = \"ATOM_TYPE_COL\";\n V2K_CONST[V2K_CONST[\"FIRST_BONDED_ATOM_COL\"] = 1] = \"FIRST_BONDED_ATOM_COL\";\n V2K_CONST[V2K_CONST[\"BOND_TYPE_COL\"] = 3] = \"BOND_TYPE_COL\";\n V2K_CONST[V2K_CONST[\"RGP_SHIFT\"] = 8] = \"RGP_SHIFT\";\n V2K_CONST[\"RGP_LINE\"] = \"M RGP\";\n V2K_CONST[\"A_LINE\"] = \"A \";\n V2K_CONST[\"END\"] = \"M END\";\n})(V2K_CONST || (V2K_CONST = {}));\nexport const MALFORMED_MOL_V2000 = `\nMalformed\n\n 0 0 0 0 0 0 0 0 0 0999 V2000\nM END`;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS12MmstY29uc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtb2xmaWxlLXYyay1jb25zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3REFBd0Q7QUFDeEQsTUFBTSxDQUFOLElBQVksU0FlWDtBQWZELFdBQVksU0FBUztJQUNuQiw2QkFBZ0IsQ0FBQTtJQUNoQix1RUFBdUIsQ0FBQTtJQUV2Qix5RUFBd0IsQ0FBQTtJQUN4QiwyREFBaUIsQ0FBQTtJQUNqQiwyRUFBeUIsQ0FBQTtJQUN6QiwyREFBaUIsQ0FBQTtJQUdqQixtREFBYSxDQUFBO0lBQ2IsZ0NBQW1CLENBQUE7SUFDbkIsMkJBQWMsQ0FBQTtJQUVkLDJCQUFjLENBQUE7QUFDaEIsQ0FBQyxFQWZXLFNBQVMsS0FBVCxTQUFTLFFBZXBCO0FBRUQsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUc7Ozs7T0FJNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBDb25zdGFudHMgcmVsYXRlZCB0byB0aGUgc3RydWN0dXJlIG9mIE1vbGZpbGUgVjJLICovXG5leHBvcnQgZW51bSBWMktfQ09OU1Qge1xuICBIRUFERVIgPSAnVjIwMDAnLFxuICBOVU1fT0ZfSEVBREVSX0xJTkVTID0gMyxcblxuICBOVU1fT0ZfQ09VTlRTX0RJR0lUUyA9IDMsXG4gIEFUT01fVFlQRV9DT0wgPSA0LFxuICBGSVJTVF9CT05ERURfQVRPTV9DT0wgPSAxLFxuICBCT05EX1RZUEVfQ09MID0gMyxcblxuXG4gIFJHUF9TSElGVCA9IDgsXG4gIFJHUF9MSU5FID0gJ00gIFJHUCcsXG4gIEFfTElORSA9ICdBICAnLFxuXG4gIEVORCA9ICdNICBFTkQnLFxufVxuXG5leHBvcnQgY29uc3QgTUFMRk9STUVEX01PTF9WMjAwMCA9IGBcbk1hbGZvcm1lZFxuXG4gIDAgIDAgIDAgIDAgIDAgIDAgIDAgIDAgIDAgIDA5OTkgVjIwMDBcbk0gIEVORGA7XG4iXX0=","import { MolfileHandlerBase } from './molfile-handler-base';\nimport { V2K_CONST } from '../formats/molfile-v2k-const';\nexport class MolfileV2KHandler extends MolfileHandlerBase {\n constructor(molfile) {\n super(molfile);\n }\n static validate(molfile) {\n return (molfile.indexOf(V2K_CONST.HEADER) !== -1 &&\n molfile.indexOf(V2K_CONST.END) !== -1);\n }\n shiftIdxToAtomType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, V2K_CONST.ATOM_TYPE_COL);\n }\n getCountsLineIdx() {\n let idx = 0;\n for (let i = 0; i < V2K_CONST.NUM_OF_HEADER_LINES; ++i)\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n getAtomBlockIdx() {\n let idx = this.getCountsLineIdx();\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n shiftIdxToXColumn(lineStartIdx) {\n return this.getNextColumnIdx(lineStartIdx);\n }\n shiftIdxToBondedAtomsPair(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, V2K_CONST.FIRST_BONDED_ATOM_COL);\n }\n shiftIdxToBondType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, V2K_CONST.BOND_TYPE_COL);\n }\n getBondBlockIdx() {\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < this.atomCount; i++)\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n parseAtomAndBondCounts() {\n let begin = this.getCountsLineIdx();\n let end = begin + V2K_CONST.NUM_OF_COUNTS_DIGITS;\n const atomCount = parseInt(this.fileContent.substring(begin, end));\n begin = end;\n end += V2K_CONST.NUM_OF_COUNTS_DIGITS;\n const bondCount = parseInt(this.fileContent.substring(begin, end));\n return { atomCount: atomCount, bondCount: bondCount };\n }\n ;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS12MmstaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1vbGZpbGUtdjJrLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBSXZELE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxrQkFBa0I7SUFDdkQsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQixDQUFDO0lBRU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFlO1FBQ3BDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZ0JBQWdCO1FBQ3hCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxDQUFDO1lBQ3BELEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVTLGVBQWU7UUFDdkIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDbEMsR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRVMsaUJBQWlCLENBQUMsWUFBb0I7UUFDOUMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVTLHlCQUF5QixDQUFDLFlBQW9CO1FBQ3RELE9BQU8sSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZUFBZTtRQUN2QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDakMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFO1lBQ3JDLEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVTLHNCQUFzQjtRQUM5QixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNwQyxJQUFJLEdBQUcsR0FBRyxLQUFLLEdBQUcsU0FBUyxDQUFDLG9CQUFvQixDQUFDO1FBQ2pELE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuRSxLQUFLLEdBQUcsR0FBRyxDQUFDO1FBQ1osR0FBRyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQztRQUN0QyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkUsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBQyxDQUFDO0lBQ3RELENBQUM7SUFBQSxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0F0b21BbmRCb25kQ291bnRzfSBmcm9tICcuL2NoZW1pY2FsLXRhYmxlLXBhcnNlci1iYXNlJztcbmltcG9ydCB7TW9sZmlsZUhhbmRsZXJCYXNlfSBmcm9tICcuL21vbGZpbGUtaGFuZGxlci1iYXNlJztcbmltcG9ydCB7VjJLX0NPTlNUfSBmcm9tICcuLi9mb3JtYXRzL21vbGZpbGUtdjJrLWNvbnN0JztcbmltcG9ydCB7IEwsIFIgfSBmcm9tICcuL2NvbnN0JztcbmltcG9ydCB7IGlzQWxwaGEgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGNsYXNzIE1vbGZpbGVWMktIYW5kbGVyIGV4dGVuZHMgTW9sZmlsZUhhbmRsZXJCYXNlIHtcbiAgY29uc3RydWN0b3IobW9sZmlsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobW9sZmlsZSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHZhbGlkYXRlKG1vbGZpbGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAobW9sZmlsZS5pbmRleE9mKFYyS19DT05TVC5IRUFERVIpICE9PSAtMSAmJlxuICAgIG1vbGZpbGUuaW5kZXhPZihWMktfQ09OU1QuRU5EKSAhPT0gLTEpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNoaWZ0SWR4VG9BdG9tVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHgsIFYyS19DT05TVC5BVE9NX1RZUEVfQ09MKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRDb3VudHNMaW5lSWR4KCk6IG51bWJlciB7XG4gICAgbGV0IGlkeCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBWMktfQ09OU1QuTlVNX09GX0hFQURFUl9MSU5FUzsgKytpKVxuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0QXRvbUJsb2NrSWR4KCk6IG51bWJlciB7XG4gICAgbGV0IGlkeCA9IHRoaXMuZ2V0Q291bnRzTGluZUlkeCgpO1xuICAgIGlkeCA9IHRoaXMuZ2V0TmV4dExpbmVJZHgoaWR4KTtcbiAgICByZXR1cm4gaWR4O1xuICB9XG5cbiAgcHJvdGVjdGVkIHNoaWZ0SWR4VG9YQ29sdW1uKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nZXROZXh0Q29sdW1uSWR4KGxpbmVTdGFydElkeCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb0JvbmRlZEF0b21zUGFpcihsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHgsIFYyS19DT05TVC5GSVJTVF9CT05ERURfQVRPTV9DT0wpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNoaWZ0SWR4VG9Cb25kVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHgsIFYyS19DT05TVC5CT05EX1RZUEVfQ09MKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRCb25kQmxvY2tJZHgoKTogbnVtYmVyIHtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRBdG9tQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYXRvbUNvdW50OyBpKyspXG4gICAgICBpZHggPSB0aGlzLmdldE5leHRMaW5lSWR4KGlkeCk7XG4gICAgcmV0dXJuIGlkeDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUF0b21BbmRCb25kQ291bnRzKCk6IEF0b21BbmRCb25kQ291bnRzIHtcbiAgICBsZXQgYmVnaW4gPSB0aGlzLmdldENvdW50c0xpbmVJZHgoKTtcbiAgICBsZXQgZW5kID0gYmVnaW4gKyBWMktfQ09OU1QuTlVNX09GX0NPVU5UU19ESUdJVFM7XG4gICAgY29uc3QgYXRvbUNvdW50ID0gcGFyc2VJbnQodGhpcy5maWxlQ29udGVudC5zdWJzdHJpbmcoYmVnaW4sIGVuZCkpO1xuICAgIGJlZ2luID0gZW5kO1xuICAgIGVuZCArPSBWMktfQ09OU1QuTlVNX09GX0NPVU5UU19ESUdJVFM7XG4gICAgY29uc3QgYm9uZENvdW50ID0gcGFyc2VJbnQodGhpcy5maWxlQ29udGVudC5zdWJzdHJpbmcoYmVnaW4sIGVuZCkpO1xuICAgIHJldHVybiB7YXRvbUNvdW50OiBhdG9tQ291bnQsIGJvbmRDb3VudDogYm9uZENvdW50fTtcbiAgfTtcbn1cbiJdfQ==","import { MolfileV2KHandler } from './molfile-v2k-handler';\nimport { MolfileV3KHandler } from './molfile-v3k-handler';\n/** Defines the proper handler based on the molfile type */\nexport class MolfileHandler {\n constructor() { }\n static getInstance(molfile) {\n if (MolfileV2KHandler.validate(molfile))\n return new MolfileV2KHandler(molfile);\n else if (MolfileV3KHandler.validate(molfile))\n return new MolfileV3KHandler(molfile);\n else\n throw new Error('Malformed molfile');\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibW9sZmlsZS1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBRXhELDREQUE0RDtBQUM1RCxNQUFNLE9BQU8sY0FBYztJQUN6QixnQkFBdUIsQ0FBQztJQUV4QixNQUFNLENBQUMsV0FBVyxDQUFDLE9BQWU7UUFDaEMsSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1lBQ3JDLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUNuQyxJQUFJLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7WUFDMUMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDOztZQUV0QyxNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDekMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtNb2xmaWxlSGFuZGxlckJhc2V9IGZyb20gJy4vbW9sZmlsZS1oYW5kbGVyLWJhc2UnO1xuaW1wb3J0IHtNb2xmaWxlVjJLSGFuZGxlcn0gZnJvbSAnLi9tb2xmaWxlLXYyay1oYW5kbGVyJztcbmltcG9ydCB7TW9sZmlsZVYzS0hhbmRsZXJ9IGZyb20gJy4vbW9sZmlsZS12M2staGFuZGxlcic7XG5cbi8qKiBEZWZpbmVzIHRoZSBwcm9wZXIgaGFuZGxlciBiYXNlZCBvbiB0aGUgbW9sZmlsZSB0eXBlICAqL1xuZXhwb3J0IGNsYXNzIE1vbGZpbGVIYW5kbGVyIHtcbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgc3RhdGljIGdldEluc3RhbmNlKG1vbGZpbGU6IHN0cmluZyk6IE1vbGZpbGVIYW5kbGVyQmFzZSB7XG4gICAgaWYgKE1vbGZpbGVWMktIYW5kbGVyLnZhbGlkYXRlKG1vbGZpbGUpKVxuICAgICAgcmV0dXJuIG5ldyBNb2xmaWxlVjJLSGFuZGxlcihtb2xmaWxlKTtcbiAgICBlbHNlIGlmIChNb2xmaWxlVjNLSGFuZGxlci52YWxpZGF0ZShtb2xmaWxlKSlcbiAgICAgIHJldHVybiBuZXcgTW9sZmlsZVYzS0hhbmRsZXIobW9sZmlsZSk7XG4gICAgZWxzZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYWxmb3JtZWQgbW9sZmlsZScpO1xuICB9XG59XG4iXX0=","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {MolfileHandler} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler';\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport $ from 'cash-dom';\n\nconst InvalidMolfileError = class extends Error {\n constructor(message: string) { super(message); }\n};\n\nexport class MoleculeImage {\n constructor(molblok: string) {\n this.molblock = molblok;\n }\n\n private _validMolBlock: string;\n get molblock(): string { return this._validMolBlock; }\n\n set molblock(value: string) {\n if (value === '') {\n this._validMolBlock = value;\n return;\n }\n\n try {\n this.validateMolBlock(value);\n } catch (error) {\n if (error instanceof InvalidMolfileError)\n value = '';\n const errorMessage = errorToConsole(error);\n console.error(errorMessage);\n }\n this._validMolBlock = value;\n }\n\n private validateMolBlock(molblock: string): void {\n // todo: add a sound criterion\n if (molblock === '')\n throw new InvalidMolfileError('MoleculeImage: invalid molblock');\n }\n\n private async drawMolBlockOnCanvas(canvas: HTMLCanvasElement): Promise<void> {\n try {\n await grok.functions.call('Chem:canvasMol', {\n x: 0, y: 0, w: canvas.width, h: canvas.height, canvas: canvas,\n molString: this.molblock, scaffoldMolString: '',\n options: {normalizeDepiction: false, straightenDepiction: false}\n });\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n };\n\n private getMoleculeDimensions(): {height: number, width: number} {\n const molData = MolfileHandler.getInstance(this.molblock);\n const width: number = Math.max(...molData.x) - Math.min(...molData.x);\n const height: number = Math.max(...molData.y) - Math.min(...molData.y);\n return {height: height, width: width};\n }\n\n private async zoomIn(): Promise<void> {\n const dialog = ui.dialog({title: 'Molecule', showFooter:false});\n const dialogDivStyle = {\n overflowX: 'scroll',\n };\n\n const height = $(window).height() * 0.7;\n const molDimensions = this.getMoleculeDimensions();\n\n const zoomRatio = height / molDimensions.height;\n\n const dialogCanvasHeight = height;\n const dialogCanvasWidth = molDimensions.width * zoomRatio;\n\n const dialogCanvas = ui.canvas(dialogCanvasWidth, dialogCanvasHeight);\n await this.drawMolBlockOnCanvas(dialogCanvas);\n \n const dialogDiv = ui.block([dialogCanvas], {style: dialogDivStyle});\n dialog.add(dialogDiv).showModal(true);\n\n $(dialog.root).find('.d4-dialog-contents').removeClass('ui-form');\n $(dialog.root).find('.d4-dialog-contents').removeClass('ui-panel');\n $(dialog.root).find('.d4-dialog-contents').addClass('ui-box');\n $(dialog.root).find('.d4-dialog-contents').css('padding', '0');\n }\n\n public async drawMolecule(\n moleculeImgDiv: HTMLDivElement,\n canvasWidth: number, canvasHeight: number\n ): Promise<void> {\n moleculeImgDiv.innerHTML = '';\n\n const canvas = ui.canvas(canvasWidth * window.devicePixelRatio, canvasHeight * window.devicePixelRatio);\n\n // Draw zoomed-out molecule\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n canvas.style.cursor = 'zoom-in';\n /*\n canvas.style.borderStyle = 'solid';\n canvas.style.borderRadius = '1px';\n canvas.style.borderColor = 'var(--grey-2)';\n canvas.style.borderWidth = 'thin';\n */\n this.drawMolBlockOnCanvas(canvas);\n\n // Dialog with zoomed-in molecule\n canvas.addEventListener('click', async () => {\n await this.zoomIn();\n });\n //$(canvas).on('click', async () => { await this.zoomIn(); });\n //$(canvas).on('mouseover', () => $(canvas).css('cursor', 'grab')); // for some reason 'zoom-in' value wouldn't work\n //$(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));\n\n moleculeImgDiv.append(ui.tooltip.bind(canvas,'Click to zoom'));\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport * as rxjs from 'rxjs';\nimport '../style/translator-app.css';\n\nimport {highlightInvalidSubsequence} from '../utils/colored-input/input-painters';\nimport {ColoredTextInput} from '../utils/colored-input/colored-text-input';\nimport {SequenceToMolfileConverter} from '../../model/structure-app/sequence-to-molfile';\nimport {getTranslatedSequences} from '../../model/translator-app/conversion-utils';\nimport {MoleculeImage} from '../utils/molecule-img';\nimport {download} from '../../model/helpers';\nimport {SEQUENCE_COPIED_MSG, SEQ_TOOLTIP_MSG} from '../const/oligo-translator';\nimport {DEFAULT_AXOLABS_INPUT} from '../const/ui';\nimport {FormatDetector} from '../../model/parsing-validation/format-detector';\nimport {SequenceValidator} from '../../model/parsing-validation/sequence-validator';\nimport {FormatConverter} from '../../model/translator-app/format-converter';\nimport {codesToHelmDictionary} from '../../model/data-loading-utils/json-loader';\nimport {DEFAULT_FORMATS} from '../../model/const';\n\nexport class TranslatorLayoutHandler {\n constructor() {\n const INPUT_FORMATS = Object.keys(codesToHelmDictionary).concat(DEFAULT_FORMATS.HELM);\n this.moleculeImgDiv = ui.div([]);\n this.moleculeImgDiv.className = 'mol-host';\n this.moleculeImgDiv.style.border = '1px solid var(--grey-2)';\n this.moleculeImgDiv.style.borderRadius = '1px';\n this.moleculeImgDiv.style.marginTop = '12px';\n\n this.outputTableDiv = ui.div([]);\n this.formatChoiceInput = ui.choiceInput('', DEFAULT_FORMATS.HELM, INPUT_FORMATS, async () => {\n this.format = this.formatChoiceInput.value;\n this.updateTable();\n await this.updateMolImg();\n });\n this.sequenceInputBase = ui.textInput('', DEFAULT_AXOLABS_INPUT,\n () => { this.onInput.next(); });\n\n this.init();\n\n DG.debounce<string>(this.onInput, 300).subscribe(async () => {\n this.init();\n this.formatChoiceInput.value = this.format;\n this.updateTable();\n await this.updateMolImg();\n });\n }\n\n // todo: reduce # of state vars by further refactoring legacy code\n private onInput = new rxjs.Subject<string>();\n private moleculeImgDiv: HTMLDivElement;\n private outputTableDiv: HTMLDivElement;\n private formatChoiceInput: DG.InputBase;\n private sequenceInputBase: DG.InputBase;\n private molfile: string;\n public sequence: string;\n private format: string | null;\n\n async getHtmlElement(): Promise<HTMLDivElement> {\n const sequenceColoredInput = new ColoredTextInput(this.sequenceInputBase, highlightInvalidSubsequence);\n\n const downloadMolfileButton = ui.button(\n 'Get SDF',\n () => { this.saveMolfile(); },\n 'Save structure as SDF');\n\n const copySmilesButton = ui.button(\n 'Copy SMILES',\n () => { this.copySmiles(); },\n 'Copy SMILES for the sequence');\n\n const formatChoiceInput = ui.div([this.formatChoiceInput]);\n\n const clearButton = ui.button(\n ui.icons.delete(() => { sequenceColoredInput.inputBase.value = '' }),\n () => {}\n );\n ui.tooltip.bind(clearButton, 'Clear input');\n\n const inputTableRow = {\n format: formatChoiceInput,\n textInput: sequenceColoredInput.root,\n clearBtn: clearButton\n };\n const upperBlock = ui.table(\n [inputTableRow], (item) => [item.format, item.textInput, item.clearBtn]\n );\n upperBlock.classList.add('st-translator-input-table');\n\n const outputTable = ui.block([\n this.outputTableDiv,\n downloadMolfileButton,\n copySmilesButton,\n ]);\n\n const mainTabBody = ui.box(\n ui.panel([\n upperBlock,\n outputTable,\n ui.block([ui.box(this.moleculeImgDiv)])\n ]),\n );\n\n this.formatChoiceInput.value = this.format;\n this.updateTable();\n await this.updateMolImg();\n return mainTabBody;\n }\n\n private saveMolfile(): void {\n const result = (new SequenceToMolfileConverter(this.sequence, false,\n this.formatChoiceInput.value!)).convert() + '\\n$$$$';\n download(this.sequence + '.sdf', encodeURIComponent(result));\n }\n\n private copySmiles(): void {\n const smiles = DG.chem.convert(this.molfile, DG.chem.Notation.MolBlock, DG.chem.Notation.Smiles);\n navigator.clipboard.writeText(smiles).then(\n () => grok.shell.info(SEQUENCE_COPIED_MSG)\n );\n }\n\n private updateTable(): void {\n this.outputTableDiv.innerHTML = '';\n // todo: does not detect correctly (U-A)(U-A)\n const indexOfInvalidChar = (!this.format) ? 0 : (new SequenceValidator(this.sequence)).getInvalidCodeIndex(this.format!);\n const translatedSequences = getTranslatedSequences(this.sequence, indexOfInvalidChar, this.format!);\n const tableRows = [];\n\n for (const key of Object.keys(translatedSequences)) {\n const sequence = ('indexOfFirstInvalidChar' in translatedSequences) ?\n ui.divH([]) :\n ui.link(\n translatedSequences[key],\n () => navigator.clipboard.writeText(translatedSequences[key])\n .then(() => grok.shell.info(SEQUENCE_COPIED_MSG)),\n SEQ_TOOLTIP_MSG, ''\n );\n tableRows.push({\n format: key,\n sequence: sequence,\n });\n }\n const outputTable = ui.table(tableRows, (item) => [item.format, item.sequence], ['FORMAT', 'SEQUENCE']);\n\n this.outputTableDiv.append(outputTable);\n this.outputTableDiv.classList.add('st-translator-output-table');\n }\n\n private async updateMolImg(): Promise<void> {\n const canvasWidth = 500;\n const canvasHeight = 170;\n const molImgObj = new MoleculeImage(this.molfile);\n await molImgObj.drawMolecule(this.moleculeImgDiv, canvasWidth, canvasHeight);\n // should the canvas be returned from the above function?\n }\n\n // todo: sort mehtods\n private init(): void {\n this.sequence = this.getFormattedSequence();\n\n this.format = (new FormatDetector(this.sequence)).getFormat();\n\n // warning: getMolfile relies on 'this.format', so the order is important\n this.molfile = this.getMolfile();\n }\n\n private getFormattedSequence(): string {\n return this.sequenceInputBase.value.replace(/\\s/g, '');\n }\n\n private getMolfile(): string {\n if (!this.format)\n return '';\n if (this.format === DEFAULT_FORMATS.HELM) {\n const axolabs = (new FormatConverter(this.sequence, this.format).convertTo(DEFAULT_FORMATS.AXOLABS));\n return (new SequenceToMolfileConverter(axolabs, false, DEFAULT_FORMATS.AXOLABS).convert());\n }\n const molfile = (new SequenceToMolfileConverter(this.sequence, false, this.format)).convert();\n return molfile;\n }\n}\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./structure-app.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./structure-app.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport {download} from '../helpers';\nimport {SequenceToMolfileConverter} from './sequence-to-molfile';\nimport {linkStrandsV3000} from './mol-transformations';\nimport {DEFAULT_FORMATS} from '../const';\nimport {FormatDetector} from '../parsing-validation/format-detector';\n\nexport type StrandData = {\n strand: string,\n invert: boolean\n}\n\n/** Get a molfile for a single strand */\nexport function getMolfileForStrand(strand: string, invert: boolean): string {\n if (strand === '')\n return '';\n const format = (new FormatDetector(strand)).getFormat();\n if (!format)\n return '';\n let molfile = '';\n try {\n molfile = (new SequenceToMolfileConverter(strand, invert, format)).convert();\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n return molfile;\n}\n\n/** Get molfile for single strand or linked strands */\nexport function getLinkedMolfile(\n ss: StrandData, as: StrandData, as2: StrandData, useChiral: boolean\n): string {\n const nonEmptyStrands = [ss, as, as2].filter((item) => item.strand !== '');\n if (nonEmptyStrands.length === 1) {\n return getMolfileForStrand(nonEmptyStrands[0].strand, nonEmptyStrands[0].invert);\n } else {\n const ssMol = getMolfileForStrand(ss.strand, ss.invert);\n const asMol = getMolfileForStrand(as.strand, as.invert);\n const as2Mol = getMolfileForStrand(as2.strand, as2.invert);\n\n // select only the non-empty anti-strands\n const antiStrands = [asMol, as2Mol].filter((item) => item !== '');\n const resultingMolfile = linkStrandsV3000({senseStrands: [ssMol], antiStrands: antiStrands}, useChiral);\n\n return resultingMolfile;\n }\n}\n\n/** Save sdf in case ss and as (and optionally as2) strands entered */\nexport function saveSdf(\n ss: StrandData, as: StrandData, as2: StrandData, useChiral: boolean,\n oneEntity: boolean\n): void {\n const nonEmptyStrands = [ss.strand, as.strand, as2.strand].filter((item) => item !== '');\n if (\n nonEmptyStrands.length === 0 ||\n nonEmptyStrands.length === 1 && ss.strand === ''\n ) {\n grok.shell.warning('Enter SS and optionally AS/AS2 to save SDF');\n } else {\n let result: string;\n if (oneEntity) {\n result = getLinkedMolfile(ss, as, as2, useChiral) + '\\n$$$$\\n';\n } else {\n const ssMol = getMolfileForStrand(ss.strand, ss.invert);\n const asMol = getMolfileForStrand(as.strand, as.invert);\n const as2Mol = getMolfileForStrand(as2.strand, as2.invert);\n result = ssMol + '\\n' +\n `> <Sequence>\\nSense Strand\\n$$$$\\n`;\n if (asMol) {\n result += asMol + '\\n' +\n `> <Sequence>\\nAnti Sense\\n$$$$\\n`;\n }\n if (as2Mol) {\n result += as2Mol + '\\n' +\n `> <Sequence>\\nAnti Sense 2\\n$$$$\\n`;\n }\n }\n\n // construct date-time in the form yyyy-mm-dd_hh-mm-ss\n const date = new Date();\n function pad(x: number): string {\n return (x >= 10) ? x.toString() : '0' + x.toString();\n }\n const dateString: string = date.getFullYear() + '-' + pad(date.getMonth() + 1) +\n '-' + pad(date.getDate()) + '_' + pad(date.getHours()) + '-' +\n pad(date.getMinutes()) + '-' + pad(date.getSeconds());\n\n download(`SequenceTranslator-${dateString}.sdf`, encodeURIComponent(result));\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport * as rxjs from 'rxjs';\nimport '../style/structure-app.css';\nimport $ from 'cash-dom';\n\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport {highlightInvalidSubsequence} from '../utils/colored-input/input-painters';\nimport {getLinkedMolfile, saveSdf} from '../../model/structure-app/oligo-structure';\nimport {ColoredTextInput} from '../utils/colored-input/colored-text-input';\nimport {MoleculeImage} from '../utils/molecule-img';\nimport {StrandData} from '../../model/structure-app/oligo-structure';\n\nconst enum DIRECTION {\n STRAIGHT = '5′ → 3′',\n INVERSE = '3′ → 5′',\n};\nconst STRANDS = ['ss', 'as', 'as2'] as const;\n\nexport class StructureLayoutHandler {\n constructor() {\n this.onInput = new rxjs.Subject<string>();\n this.onInvalidInput = new rxjs.Subject<string>();\n this.inputBase = Object.fromEntries(\n STRANDS.map(\n (key) => [key, ui.textInput('', '', () => { this.onInput.next(); })]\n )\n );\n this.useChiralInput = ui.boolInput('Use chiral', true);\n this.saveAllStrandsInput = ui.boolInput('Save as one entity', true);\n ui.tooltip.bind(this.saveAllStrandsInput.root, 'Save SDF with all strands in one molfile');\n this.directionInversion = Object.fromEntries(\n STRANDS.map((key) => [key, false])\n );\n this.moleculeImgDiv = ui.block([]);\n $(this.moleculeImgDiv).addClass('st-structure-mol-img');\n\n DG.debounce<string>(this.onInput, 300).subscribe(async () => {\n await this.updateMoleculeImg();\n });\n\n DG.debounce<string>(this.onInvalidInput, 1000).subscribe(async () => {\n grok.shell.warning('Insert Sense strand');\n });\n }\n\n private onInput: rxjs.Subject<string>;\n private onInvalidInput: rxjs.Subject<string>;\n private useChiralInput: DG.InputBase<boolean | null>;\n private saveAllStrandsInput: DG.InputBase<boolean | null>;\n private inputBase: {[key: string]: DG.InputBase<string>};\n private directionInversion: {[key: string]: boolean};\n private moleculeImgDiv: HTMLDivElement;\n\n async getHtmlDivElement(): Promise<HTMLDivElement> {\n const tableLayout = this.getTableInput();\n const boolInputsAndButton = this.getBoolInputsAndButton();\n await this.updateMoleculeImg();\n const bottomDiv = ui.divH([boolInputsAndButton, this.moleculeImgDiv]);\n $(bottomDiv).addClass('st-structure-bottom');\n\n const layout = ui.divV([tableLayout, bottomDiv]);\n $(layout).addClass('st-structure-body');\n\n return layout;\n }\n\n private getBoolInputsAndButton(): HTMLDivElement {\n const saveButton = ui.buttonsInput([\n ui.bigButton('Save SDF', () => {\n const strandData = this.getStrandData();\n saveSdf(strandData.ss, strandData.as, strandData.as2,\n this.useChiralInput.value!, this.saveAllStrandsInput.value!);\n })\n ]);\n\n const boolInputsAndButtonArray = [this.saveAllStrandsInput.root, this.useChiralInput.root, saveButton];\n const boolInputsAndButton = ui.divV(boolInputsAndButtonArray);\n for (const item of boolInputsAndButtonArray)\n $(item).addClass('st-structure-bool-button-block');\n return boolInputsAndButton;\n }\n\n private getTableInput(): HTMLTableElement {\n const coloredInput = Object.fromEntries(\n STRANDS.map(\n (key) => [key, new ColoredTextInput(this.inputBase[key], highlightInvalidSubsequence)]\n )\n );\n\n const directionChoiceInput = Object.fromEntries(\n STRANDS.map(\n (key, idx) => {\n const selected = (idx === 0) ? DIRECTION.STRAIGHT : DIRECTION.INVERSE;\n return [key, ui.choiceInput(\n `${key.toUpperCase()} direction`, selected, [DIRECTION.STRAIGHT, DIRECTION.INVERSE]\n )]\n }\n )\n );\n\n STRANDS.forEach((strand, idx) => {\n directionChoiceInput[strand].onChanged(() => {\n let value = directionChoiceInput[strand].value === DIRECTION.INVERSE;\n // warning: the next line is necessary until the legacy notion of direction used in the molfile generation gets fixed\n if (idx > 0) { value = !value; }\n this.directionInversion[strand] = value;\n this.onInput.next();\n });\n });\n\n const labelNames = ['Sense Strand', 'Anti Sense', 'Anti Sense 2'];\n const labelNameMap = new Map(STRANDS.map(\n (key, index) => [key, labelNames[index]]\n ));\n const label = Object.fromEntries(\n STRANDS.map(\n (key) => [key, ui.label(labelNameMap.get(key)!)]\n )\n );\n\n const clearBlock = Object.fromEntries(\n STRANDS.map(\n (key) => {\n const clearIcon = ui.icons.delete(() => { coloredInput[key].inputBase.value = '' });\n const clearButton = ui.button(clearIcon, () => {});\n ui.tooltip.bind(clearButton, `Clear ${key.toUpperCase()}`);\n return [key, clearIcon];\n }\n ));\n\n const tableRows = STRANDS.map((strand) => {\n return {\n label: label[strand],\n textInput: coloredInput[strand].root,\n clear: clearBlock[strand],\n choiceInput: directionChoiceInput[strand].root,\n };\n });\n const tableLayout = ui.table(\n tableRows, (item) => [item.label, item.textInput, item.clear, item.choiceInput]);\n $(tableLayout).css('margin-top', '10px');\n\n for (const strand of STRANDS) {\n let element = label[strand].parentElement!;\n element.classList.add('st-structure-input-form');\n // the following line is necessary because otherwise overridden by\n // d4-item-table class\n $(element).css('padding-top', '3px');\n\n element = directionChoiceInput[strand].root.parentElement!;\n element.classList.add('st-structure-input-form', 'st-structure-direction-choice');\n\n element = this.inputBase[strand].root.parentElement!;\n element.classList.add('st-structure-text-input-td');\n }\n return tableLayout;\n }\n\n private getStrandData() {\n return Object.fromEntries(\n STRANDS.map((strand, idx) => {\n let invert = this.directionInversion[strand];\n return [strand, {\n strand: this.inputBase[strand].value.replace(/\\s*/g, ''),\n invert: invert\n }]\n })\n );\n }\n\n private getMolfile(ss: StrandData, as: StrandData, as2: StrandData): string {\n // if (ss.strand === '' && (as.strand !== '' || as2.strand !== '')) {\n // this.onInvalidInput.next();\n // return '';\n // }\n\n return getLinkedMolfile(ss, as, as2, this.useChiralInput.value!);\n }\n\n private async updateMoleculeImg(): Promise<void> {\n let molfile = '';\n try {\n const strandData = this.getStrandData();\n if (Object.values(strandData).some((data) => data.strand !== ''))\n molfile = this.getMolfile(strandData.ss, strandData.as, strandData.as2);\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n // todo: calculate relative numbers\n const canvasWidth = 650;\n const canvasHeight = 150;\n const molImgObj = new MoleculeImage(molfile);\n await molImgObj.drawMolecule(this.moleculeImgDiv, canvasWidth, canvasHeight);\n // should the canvas be returned from the above function?\n $(this.moleculeImgDiv).find('canvas').css('float', 'inherit');\n }\n}\n","export const DEFAULT_PTO: boolean = true;\nexport const DEFAULT_SEQUENCE_LENGTH: number = 23;\nexport const MAX_SEQUENCE_LENGTH: number = 35;\nexport const USER_STORAGE_KEY: string = 'SequenceTranslator';\nexport const EXAMPLE_MIN_WIDTH: string = '400px';\n\nexport const enum JSON_FIELD {\n SS_BASES = 'ssBases',\n AS_BASES = 'asBases',\n SS_PTO = 'ssPtoLinkages',\n AS_PTO = 'asPtoLinkages',\n SS_3 = 'ssThreeModification',\n SS_5 = 'ssFiveModification',\n AS_3 = 'asThreeModification',\n AS_5 = 'asFiveModification',\n COMMENT = 'comment',\n};\n\nexport const SS = 'SS' as const;\nexport const AS = 'AS' as const;\nexport const STRANDS = [SS, AS];\nexport const STRAND_NAME = {\n [SS]: 'Sense strand',\n [AS]: 'Anti sense',\n}\n\nexport const THREE_PRIME = 'THREE_PRIME' as const;\nexport const FIVE_PRIME = 'FIVE_PRIME' as const;\nexport const TERMINAL_KEYS = [THREE_PRIME, FIVE_PRIME];\nexport const TERMINAL = {\n [THREE_PRIME]: 3,\n [FIVE_PRIME]: 5,\n}\n","import {NUCLEOTIDES} from '../const';\nimport {axolabsStyleMap} from '../data-loading-utils/json-loader';\n\nexport function isOverhang(modification: string): boolean {\n return modification.slice(-3) === '(o)';\n}\n\nexport function isOneDigitNumber(n: number): boolean {\n return n < 10;\n}\n\n// https://uxdesign.cc/star-rating-make-svg-great-again-d4ce4731347e\nexport function getPointsToDrawStar(centerX: number, centerY: number): string {\n const innerCirclePoints = 5; // a 5 point star\n const innerRadius = 15 / innerCirclePoints;\n const innerOuterRadiusRatio = 2; // outter circle is x2 the inner\n const outerRadius = innerRadius * innerOuterRadiusRatio;\n const angle = Math.PI / innerCirclePoints;\n const angleOffsetToCenterStar = 60;\n const totalNumberOfPoints = innerCirclePoints * 2; // 10 in a 5-points star\n\n let points = '';\n for (let i = 0; i < totalNumberOfPoints; i++) {\n const r = (i % 2 === 0) ? outerRadius : innerRadius;\n const currentX = centerX + Math.cos(i * angle + angleOffsetToCenterStar) * r;\n const currentY = centerY + Math.sin(i * angle + angleOffsetToCenterStar) * r;\n points += `${currentX},${currentY} `;\n }\n return points;\n}\n\nexport function countOverhangsOnTheRightEdge(modifications: string[]): number {\n let i = 0;\n while (i < modifications.length && isOverhang(modifications[i]))\n i++;\n return (i === modifications.length - 1) ? 0 : i;\n}\n\nexport function textWidth(text: string, font: number): number {\n const context = document.createElement('canvas').getContext('2d');\n // @ts-ignore\n context.font = String(font);\n // @ts-ignore\n return 2 * context.measureText(text).width;\n}\n\nexport function textInsideCircle(bases: string[], index: number): string {\n return (isOverhang(bases[index]) || !NUCLEOTIDES.includes(bases[index])) ? '' : bases[index];\n}\n\nexport function fontColorVisibleOnBackground(base: string): string {\n const AXOLABS_MAP = axolabsStyleMap;\n const rgbIntList = AXOLABS_MAP[base].color.match(/\\d+/g)!.map((e) => Number(e));\n return (rgbIntList[0] * 0.299 + rgbIntList[1] * 0.587 + rgbIntList[2] * 0.114) > 186 ? '#33333' : '#ffffff';\n}\n\nexport function baseColor(base: string): string {\n const AXOLABS_MAP = axolabsStyleMap;\n return AXOLABS_MAP[base].color;\n}\n\nexport const svg = {\n xmlns: 'http://www.w3.org/2000/svg',\n render: function(width: number, height: number): Element {\n const e = document.createElementNS(this.xmlns, 'svg');\n e.setAttribute('id', 'mySvg');\n e.setAttribute('width', String(width));\n e.setAttribute('height', String(height));\n return e;\n },\n circle: function(x: number, y: number, radius: number, color: string): Element {\n const e = document.createElementNS(this.xmlns, 'circle');\n e.setAttribute('cx', String(x));\n e.setAttribute('cy', String(y));\n e.setAttribute('r', String(radius));\n e.setAttribute('fill', color);\n return e;\n },\n text: function(text: string, x: number, y: number, fontSize: number, color: string): Element {\n const e = document.createElementNS(this.xmlns, 'text');\n e.setAttribute('x', String(x));\n e.setAttribute('y', String(y));\n e.setAttribute('font-size', String(fontSize));\n e.setAttribute('font-weight', 'normal');\n e.setAttribute('font-family', 'Arial');\n e.setAttribute('fill', color);\n e.innerHTML = text;\n return e;\n },\n star: function(x: number, y: number, fill: string): Element {\n const e = document.createElementNS(this.xmlns, 'polygon');\n e.setAttribute('points', getPointsToDrawStar(x, y));\n e.setAttribute('fill', fill);\n return e;\n },\n};\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n// @ts-ignore\nimport * as svg from 'save-svg-as-png';\nimport $ from 'cash-dom';\n\nimport {isOverhang} from './helpers';\nimport {axolabsStyleMap} from '../data-loading-utils/json-loader';\n\nexport function generateExample(sequenceLength: number, sequenceBasis: string): string {\n const AXOLABS_MAP = axolabsStyleMap;\n const uniqueSymbols = AXOLABS_MAP[sequenceBasis].symbols.join('');\n return uniqueSymbols.repeat(Math.floor(sequenceLength / 4)) + uniqueSymbols.slice(0, sequenceLength % 4);\n}\n\nexport function findDuplicates(data: Int32Array | Float32Array | Float64Array | Uint32Array): number[] {\n return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));\n}\n\nexport async function isCurrentUserCreatedThisPattern(patternName: string): Promise<boolean> {\n return await grok.dapi.users.current().then((user) => {\n const [firstName, lastName] = getUserName(patternName);\n return (user.firstName !== firstName || user.lastName !== lastName);\n });\n}\n\nexport function getShortName(patternName: string): string {\n let first = patternName.length + 1;\n for (let i = 0; i < patternName.length; i++) {\n if (patternName[i] === '(') {\n first = i;\n break;\n }\n }\n return patternName.slice(0, first - 1);\n}\n\nfunction getUserName(patternName: string): string[] {\n let first = -1;\n for (let i = 0; i < patternName.length; i++) {\n if (patternName[i] === '(') {\n first = i;\n break;\n }\n }\n return (first === -1) ? ['', ''] : patternName.slice(first + 9, patternName.length - 1).split(' ').slice(1);\n}\n\nexport function translateSequence(\n sequence: string,\n bases: DG.InputBase[],\n ptoLinkages: DG.InputBase[],\n startModification: DG.InputBase,\n endModification: DG.InputBase,\n firstPtoExist: boolean): string {\n let i: number = -1;\n let mainSequence = sequence.replace(/[AUGC]/g, function(x: string) {\n i++;\n const AXOLABS_MAP = axolabsStyleMap;\n\n const baseChoices: string[] = Object.keys(AXOLABS_MAP);\n // const defaultBase: string = baseChoices[0];\n const indexOfSymbol = AXOLABS_MAP['RNA']['symbols'].indexOf(x);\n let symbol = AXOLABS_MAP[bases[i].value]['symbols'][indexOfSymbol];\n if (isOverhang(bases[i].value)) {\n if (i < sequence.length / 2 && !isOverhang(bases[i + 1].value))\n symbol = symbol + x + 'f';\n else if (i > sequence.length / 2 && !isOverhang(bases[i - 1].value))\n symbol = x + 'f' + symbol;\n }\n return (ptoLinkages[i].value) ? symbol + 's' : symbol;\n });\n if (mainSequence.slice(0, 5).split('mU').length === 3)\n mainSequence = '(uu)' + mainSequence.slice(4);\n if (mainSequence.slice(mainSequence.length - 7).split('mU').length === 3)\n mainSequence = mainSequence.slice(0, mainSequence.length - 4) + '(uu)';\n return startModification.value + (firstPtoExist ? 's' : '') + mainSequence + endModification.value;\n}\n\nexport function addColumnWithIds(tableName: string, columnName: string, patternName: string) {\n const nameOfNewColumn = 'ID ' + patternName;\n const columns = grok.shell.table(tableName).columns;\n if (columns.contains(nameOfNewColumn))\n columns.remove(nameOfNewColumn);\n const columnWithIds = columns.byName(columnName);\n return columns.addNewString(nameOfNewColumn).init((i: number) => {\n return (columnWithIds.getString(i) === '') ? '' : columnWithIds.get(i) + '_' + patternName;\n });\n}\n\nexport function addColumnWithTranslatedSequences(\n tableName: string,\n columnName: string,\n bases: DG.InputBase[],\n ptoLinkages: DG.InputBase[],\n startModification: DG.InputBase,\n endModification: DG.InputBase,\n firstPtoExist: boolean) {\n const nameOfNewColumn = 'Axolabs ' + columnName;\n const columns = grok.shell.table(tableName).columns;\n if (columns.contains(nameOfNewColumn))\n columns.remove(nameOfNewColumn);\n const columnWithInputSequences = columns.byName(columnName);\n return columns.addNewString(nameOfNewColumn).init((i: number) => {\n return columnWithInputSequences.getString(i) === '' ?\n '' :\n translateSequence(columnWithInputSequences.getString(i), bases, ptoLinkages, startModification, endModification,\n firstPtoExist);\n });\n}\n","import {NUCLEOTIDES} from '../const';\nimport {isOverhang, svg, textWidth, countOverhangsOnTheRightEdge, baseColor, textInsideCircle,\n fontColorVisibleOnBackground, isOneDigitNumber} from './helpers';\n\nconst BASE_RADIUS = 15;\nconst BASE_DIAMETER = 2 * BASE_RADIUS;\nconst shiftToAlignTwoDigitNumberNearCircle = -10;\nconst shiftToAlignOneDigitNumberNearCircle = -5;\nconst LEGEND_RADIUS = 6;\nconst PS_LINKAGE_RADIUS = 5;\nconst BASE_FONT_SIZE = 17;\nconst LEGEND_FONT_SIZE = 14;\nconst PS_LINKAGE_COLOR = 'red';\nconst FONT_COLOR = 'var(--grey-6)';\nconst TITLE_FONT_COLOR = 'black';\nconst MODIFICATIONS_COLOR = 'red';\nconst SS_LEFT_TEXT = 'SS: 5\\'';\nconst AS_LEFT_TEXT = 'AS: 3\\'';\nconst SS_RIGHT_TEXT = '3\\'';\nconst AS_RIGHT_TEXT = '5\\'';\n\nconst WIDTH_OF_LEFT_TEXT = Math.max(\n textWidth(SS_LEFT_TEXT, BASE_FONT_SIZE),\n textWidth(AS_LEFT_TEXT, BASE_FONT_SIZE),\n);\n\nconst WIDTH_OF_RIGHT_TEXT = Math.max(\n textWidth(SS_RIGHT_TEXT, BASE_FONT_SIZE),\n textWidth(AS_RIGHT_TEXT, BASE_FONT_SIZE),\n);\n\nconst X = {\n TITLE: BASE_RADIUS, // Math.round(width / 4),\n LEFT_TEXTS: 0,\n};\nconst X_OF_LEFT_MODIFICATIONS = X.LEFT_TEXTS + WIDTH_OF_LEFT_TEXT - 5;\n\nconst Y = {\n TITLE: BASE_RADIUS,\n SS_INDICES: 2 * BASE_RADIUS,\n SS_CIRCLES: 3.5 * BASE_RADIUS,\n SS_TEXTS: 4 * BASE_RADIUS,\n AS_CIRCLES: 6.5 * BASE_RADIUS,\n AS_TEXTS: 7 * BASE_RADIUS,\n AS_INDICES: 8.5 * BASE_RADIUS,\n comment: (asExists: boolean) => (asExists) ? 11 * BASE_RADIUS : 8.5 * BASE_RADIUS,\n circlesInLegends: (asExists: boolean) => (asExists) ? 9.5 * BASE_RADIUS : 6 * BASE_RADIUS,\n textLegend: (asExists: boolean) => (asExists) ? 10 * BASE_RADIUS - 3 : Y.AS_CIRCLES - 3,\n svgHeight: (asExists: boolean) => (asExists) ? 11 * BASE_RADIUS : 9 * BASE_RADIUS,\n};\n\nexport function drawAxolabsPattern(\n patternName: string, asExists: boolean, ssBases: string[],\n asBases: string[], ssPtoStatuses: boolean[], asPtoStatuses: boolean[],\n ss3Modification: string, ss5Modification: string,\n as3Modification: string, as5Modification: string, comment: string,\n enumerateModifications: string[],\n): Element {\n function equidistantXForLegend(index: number): number {\n return Math.round((index + startFrom) * width / (uniqueBases.length + startFrom) + LEGEND_RADIUS);\n }\n\n function xOfBaseCircles(index: number, rightOverhangs: number): number {\n return widthOfRightModification +\n (resultingNumberOfNucleotidesInStrands - index + rightOverhangs + 1) * BASE_DIAMETER;\n }\n\n function shiftToAlignNumberNearCircle(bases: string[], generalIndex: number, nucleotideIndex: number): number {\n return (isOneDigitNumber(nucleotideIndex) || NUCLEOTIDES.includes(bases[generalIndex])) ?\n shiftToAlignOneDigitNumberNearCircle : shiftToAlignTwoDigitNumberNearCircle;\n }\n\n ssBases = ssBases.reverse();\n ssPtoStatuses = ssPtoStatuses.reverse();\n\n const ssRightOverhangs = countOverhangsOnTheRightEdge(ssBases);\n const asRightOverhangs = countOverhangsOnTheRightEdge(asBases);\n\n const resultingNumberOfNucleotidesInStrands = Math.max(\n ssBases.length - ssRightOverhangs,\n asBases.length - asRightOverhangs,\n );\n\n const widthOfRightOverhangs = Math.max(ssRightOverhangs, asRightOverhangs);\n const widthOfBases = BASE_DIAMETER * (resultingNumberOfNucleotidesInStrands + widthOfRightOverhangs);\n\n const widthOfLeftModification = Math.max(\n textWidth(ss3Modification, BASE_FONT_SIZE),\n textWidth(as5Modification, BASE_FONT_SIZE),\n );\n\n const widthOfRightModification = Math.max(\n textWidth(ss5Modification, BASE_FONT_SIZE),\n textWidth(as3Modification, BASE_FONT_SIZE),\n );\n\n const uniqueBases = asExists ?\n [...new Set(ssBases.concat(asBases))] :\n [...new Set(ssBases)];\n\n const isPtoExist = asExists ?\n ssPtoStatuses.concat(asPtoStatuses).includes(true) :\n ssPtoStatuses.includes(true);\n\n const startFrom = isPtoExist ? 1 : 0;\n\n const xOfSsRightModifications = ssRightOverhangs * BASE_DIAMETER + xOfBaseCircles(-0.5, 0);\n const xOfAsRightModifications = asRightOverhangs * BASE_DIAMETER + xOfBaseCircles(-0.5, 0);\n\n const xOfRightTexts = Math.max(xOfSsRightModifications, xOfAsRightModifications) + widthOfLeftModification +\n BASE_DIAMETER * widthOfRightOverhangs;\n\n const width = WIDTH_OF_LEFT_TEXT + widthOfLeftModification + widthOfBases + widthOfRightModification +\n WIDTH_OF_RIGHT_TEXT + BASE_DIAMETER;\n const image = svg.render(width, Y.svgHeight(asExists));\n\n image.append(\n svg.text(SS_LEFT_TEXT, X.LEFT_TEXTS, Y.SS_TEXTS, BASE_FONT_SIZE, FONT_COLOR),\n asExists ? svg.text(AS_LEFT_TEXT, X.LEFT_TEXTS, Y.AS_TEXTS, BASE_FONT_SIZE, FONT_COLOR) : '',\n svg.text(SS_RIGHT_TEXT, xOfRightTexts, Y.SS_TEXTS, BASE_FONT_SIZE, FONT_COLOR),\n asExists ? svg.text(AS_RIGHT_TEXT, xOfRightTexts, Y.AS_TEXTS, BASE_FONT_SIZE, FONT_COLOR) : '',\n svg.text(ss5Modification, X_OF_LEFT_MODIFICATIONS, Y.SS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR),\n asExists ? svg.text(as3Modification, X_OF_LEFT_MODIFICATIONS, Y.AS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR) : '',\n svg.text(ss3Modification, xOfSsRightModifications, Y.SS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR),\n asExists ? svg.text(as5Modification, xOfAsRightModifications, Y.AS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR) : '',\n svg.text(comment, X.LEFT_TEXTS, Y.comment(asExists), LEGEND_FONT_SIZE, FONT_COLOR),\n isPtoExist ? svg.star(BASE_RADIUS, Y.circlesInLegends(asExists), PS_LINKAGE_COLOR) : '',\n isPtoExist ? svg.text('ps linkage', 2 * BASE_RADIUS - 8, Y.textLegend(asExists), LEGEND_FONT_SIZE, FONT_COLOR) : '',\n );\n\n const numberOfSsNucleotides = ssBases.filter((value) => !isOverhang(value)).length;\n let nucleotideCounter = numberOfSsNucleotides;\n for (let i = ssBases.length - 1; i > -1; i--) {\n const xOfNumbers = xOfBaseCircles(i, ssRightOverhangs) +\n shiftToAlignNumberNearCircle(ssBases, ssBases.length - i, numberOfSsNucleotides - nucleotideCounter);\n if (!isOverhang(ssBases[i]))\n nucleotideCounter--;\n const n = (!isOverhang(ssBases[i]) && enumerateModifications.includes(ssBases[i])) ?\n String(numberOfSsNucleotides - nucleotideCounter) : '';\n image.append(\n svg.text(n, xOfNumbers, Y.SS_INDICES, LEGEND_FONT_SIZE, FONT_COLOR),\n svg.circle(xOfBaseCircles(i, ssRightOverhangs), Y.SS_CIRCLES, BASE_RADIUS, baseColor(ssBases[i])),\n svg.text(textInsideCircle(ssBases, i), xOfNumbers, Y.SS_TEXTS, BASE_FONT_SIZE,\n fontColorVisibleOnBackground(ssBases[i])),\n ssPtoStatuses[i] ?\n svg.star(xOfBaseCircles(i, ssRightOverhangs) + BASE_RADIUS, Y.SS_TEXTS + PS_LINKAGE_RADIUS, PS_LINKAGE_COLOR) :\n '',\n );\n }\n image.append(\n ssPtoStatuses[ssBases.length] ?\n svg.star(xOfBaseCircles(ssBases.length, ssRightOverhangs) +\n BASE_RADIUS, Y.SS_TEXTS + PS_LINKAGE_RADIUS, PS_LINKAGE_COLOR) : '',\n );\n\n const numberOfAsNucleotides = asBases.filter((value) => !isOverhang(value)).length;\n if (asExists) {\n let nucleotideCounter = numberOfAsNucleotides;\n for (let i = asBases.length - 1; i > -1; i--) {\n if (!isOverhang(asBases[i]))\n nucleotideCounter--;\n const xOfNumbers = xOfBaseCircles(i, asRightOverhangs) +\n shiftToAlignNumberNearCircle(asBases, i, nucleotideCounter + 1);\n const n = (!isOverhang(asBases[i]) && enumerateModifications.includes(asBases[i])) ?\n String(nucleotideCounter + 1) : '';\n image.append(\n svg.text(n, xOfNumbers, Y.AS_INDICES, LEGEND_FONT_SIZE, FONT_COLOR),\n svg.circle(xOfBaseCircles(i, asRightOverhangs), Y.AS_CIRCLES, BASE_RADIUS, baseColor(asBases[i])),\n svg.text(textInsideCircle(asBases, i),\n xOfBaseCircles(i, asRightOverhangs) + shiftToAlignNumberNearCircle(asBases, i, nucleotideCounter + 1),\n Y.AS_TEXTS, BASE_FONT_SIZE, fontColorVisibleOnBackground(asBases[i])),\n asPtoStatuses[i] ? svg.star(xOfBaseCircles(i, asRightOverhangs) +\n BASE_RADIUS, Y.AS_TEXTS + PS_LINKAGE_RADIUS, PS_LINKAGE_COLOR) : '',\n );\n }\n image.append(\n asPtoStatuses[asBases.length] ?\n svg.star(xOfBaseCircles(asBases.length, asRightOverhangs) + BASE_RADIUS, Y.AS_TEXTS + PS_LINKAGE_RADIUS,\n PS_LINKAGE_COLOR) : '',\n );\n }\n\n const title = `${patternName} for ${numberOfSsNucleotides}${(asExists ? `/${numberOfAsNucleotides}` : '')}mer`;\n image.append(svg.text(title, X.TITLE, Y.TITLE, BASE_FONT_SIZE, TITLE_FONT_COLOR));\n for (let i = 0; i < uniqueBases.length; i++) {\n image.append(\n svg.circle(equidistantXForLegend(i), Y.circlesInLegends(asExists), LEGEND_RADIUS, baseColor(uniqueBases[i])),\n svg.text(uniqueBases[i], equidistantXForLegend(i) + LEGEND_RADIUS + 4, Y.textLegend(asExists), LEGEND_FONT_SIZE,\n FONT_COLOR),\n );\n }\n return image;\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {axolabsStyleMap} from '../../model/data-loading-utils/json-loader';\nimport {\n DEFAULT_PTO, DEFAULT_SEQUENCE_LENGTH, MAX_SEQUENCE_LENGTH, USER_STORAGE_KEY, SS, AS, STRAND_NAME, STRANDS, TERMINAL, TERMINAL_KEYS, THREE_PRIME, FIVE_PRIME, JSON_FIELD as FIELD\n} from '../../model/pattern-app/const';\nimport {isOverhang} from '../../model/pattern-app/helpers';\nimport {generateExample, translateSequence, getShortName, isCurrentUserCreatedThisPattern, findDuplicates, addColumnWithIds, addColumnWithTranslatedSequences} from '../../model//pattern-app/oligo-pattern';\nimport {drawAxolabsPattern} from '../../model/pattern-app/draw-svg';\n// todo: remove ts-ignore\n//@ts-ignore\nimport * as svg from 'save-svg-as-png';\nimport $ from 'cash-dom';\n\ntype BooleanInput = DG.InputBase<boolean | null>;\ntype StringInput = DG.InputBase<string | null>;\n\nexport class PatternLayoutHandler {\n get htmlDivElement() {\n function updateModification(strand: string) {\n modificationItems[strand].innerHTML = '';\n ptoLinkages[strand] = ptoLinkages[strand].concat(Array(maxStrandLength[strand] - baseInputsObject[strand].length).fill(fullyPto));\n baseInputsObject[strand] = baseInputsObject[strand].concat(Array(maxStrandLength[strand] - baseInputsObject[strand].length).fill(sequenceBase));\n let nucleotideCounter = 0;\n for (let i = 0; i < strandLengthInput[strand].value!; i++) {\n ptoLinkages[strand][i] = ui.boolInput('', ptoLinkages[strand][i].value!, () => {\n updateSvgScheme();\n updateOutputExamples();\n });\n baseInputsObject[strand][i] = ui.choiceInput('', baseInputsObject[strand][i].value, baseChoices, (v: string) => {\n if (!enumerateModifications.includes(v)) {\n enumerateModifications.push(v);\n isEnumerateModificationsDiv.append(\n ui.divText('', {style: {width: '25px'}}),\n ui.boolInput(v, true, (boolV: boolean) => {\n if (boolV) {\n if (!enumerateModifications.includes(v))\n enumerateModifications.push(v);\n } else {\n const index = enumerateModifications.indexOf(v, 0);\n if (index > -1)\n enumerateModifications.splice(index, 1);\n }\n updateSvgScheme();\n }).root,\n );\n }\n updateModification(AS);\n updateSvgScheme();\n updateOutputExamples();\n });\n $(baseInputsObject[strand][i].root).addClass('st-pattern-choice-input');\n if (!isOverhang(baseInputsObject[strand][i].value!))\n nucleotideCounter++;\n\n modificationItems[strand].append(\n ui.divH([\n ui.div([ui.label(isOverhang(baseInputsObject[strand][i].value!) ? '' : String(nucleotideCounter))],\n {style: {width: '20px'}})!,\n ui.block75([baseInputsObject[strand][i].root])!,\n ui.div([ptoLinkages[strand][i]])!,\n ], {style: {alignItems: 'center'}}),\n );\n }\n }\n\n function updateUiForNewSequenceLength() {\n if (Object.values(strandLengthInput).every((input) => input.value! < MAX_SEQUENCE_LENGTH)) {\n STRANDS.forEach((strand) => {\n if (strandLengthInput[strand].value! > maxStrandLength[strand])\n maxStrandLength[strand] = strandLengthInput[strand].value!;\n updateModification(strand);\n })\n\n updateSvgScheme();\n updateInputExamples();\n updateOutputExamples();\n } else {\n ui.dialog('Out of range')\n .add(ui.divText('Sequence length should be less than ' +\n MAX_SEQUENCE_LENGTH.toString() + ' due to UI constrains.'))\n .onOK(()=> {Object.values(strandLengthInput).every((input)=> input.value = 34)})\n .onCancel(()=> {Object.values(strandLengthInput).every((input)=> input.value = 34)})\n .showModal(false);\n }\n }\n\n // todo: unify with updateBases\n function updatePto(newPtoValue: boolean): void {\n STRANDS.forEach((strand) => {\n for (let i = 0; i < ptoLinkages[strand].length; i++)\n ptoLinkages[strand][i].value = newPtoValue;\n })\n updateSvgScheme();\n }\n\n function updateBases(newBasisValue: string): void {\n STRANDS.forEach((strand) => {\n for (let i = 0; i < baseInputsObject[strand].length; i++)\n baseInputsObject[strand][i].value = newBasisValue;\n })\n updateSvgScheme();\n }\n\n function updateInputExamples() {\n STRANDS.forEach((s) => {\n if (strandColumnInput[s].value === '')\n inputExample[s].value = generateExample(strandLengthInput[s].value!, sequenceBase.value!);\n });\n }\n\n function updateOutputExamples() {\n const conditions = [true, createAsStrand.value];\n STRANDS.forEach((strand, i) => {\n if (conditions[i]) {\n outputExample[strand].value = translateSequence(inputExample[strand].value, baseInputsObject[strand], ptoLinkages[strand], terminalModification[strand][FIVE_PRIME], terminalModification[strand][THREE_PRIME], firstPto[strand].value!);\n }\n })\n }\n\n function updateSvgScheme() {\n svgDiv.innerHTML = '';\n svgDiv.append(\n ui.span([\n\n // todo: refactor the funciton, reduce # of args\n drawAxolabsPattern(\n getShortName(saveAs.value),\n createAsStrand.value!,\n\n baseInputsObject[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value!),\n baseInputsObject[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value!),\n\n [firstPto[SS].value!].concat(ptoLinkages[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value!)),\n [firstPto[AS].value!].concat(ptoLinkages[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value!)),\n\n terminalModification[SS][THREE_PRIME].value,\n terminalModification[SS][FIVE_PRIME].value,\n\n terminalModification[AS][THREE_PRIME].value,\n terminalModification[AS][FIVE_PRIME].value,\n\n comment.value,\n enumerateModifications,\n ),\n ]),\n );\n }\n\n // todo: rename\n function detectDefaultBasis(array: string[]) {\n const modeMap: {[index: string]: number} = {};\n let maxEl = array[0];\n let maxCount = 1;\n for (let i = 0; i < array.length; i++) {\n const el = array[i];\n if (modeMap[el] === null)\n modeMap[el] = 1;\n else\n modeMap[el]++;\n if (modeMap[el] > maxCount) {\n maxEl = el;\n maxCount = modeMap[el];\n }\n }\n return maxEl;\n }\n\n async function parsePatternAndUpdateUi(newName: string) {\n const pi = DG.TaskBarProgressIndicator.create('Loading pattern...');\n await grok.dapi.userDataStorage.get(USER_STORAGE_KEY, false).then((entities) => {\n const obj = JSON.parse(entities[newName]);\n sequenceBase.value = detectDefaultBasis(obj[FIELD.AS_BASES].concat(obj[FIELD.SS_BASES]));\n createAsStrand.value = (obj[FIELD.AS_BASES].length > 0);\n saveAs.value = newName;\n\n let fields = [FIELD.SS_BASES, FIELD.AS_BASES];\n STRANDS.forEach((strand, i) => {\n baseInputsObject[strand] = [];\n const field = fields[i];\n for (let j = 0; j < obj[field].length; j++)\n baseInputsObject[strand].push(ui.choiceInput('', obj[field][j], baseChoices));\n })\n\n fields = [FIELD.SS_PTO, FIELD.AS_PTO];\n STRANDS.forEach((s, i) => {\n const field = fields[i];\n firstPto[s].value = obj[field][0];\n ptoLinkages[s] = [];\n for (let j = 1; j < obj[field].length; j++)\n ptoLinkages[s].push(ui.boolInput('', obj[field][j]));\n });\n\n fields = [FIELD.SS_BASES, FIELD.AS_BASES];\n STRANDS.forEach((strand, i) => {\n strandLengthInput[strand].value = obj[fields[i]].length;\n })\n\n const field = [[FIELD.SS_3, FIELD.SS_5], [FIELD.AS_3, FIELD.AS_5]];\n STRANDS.forEach((strand, i) => {\n TERMINAL_KEYS.forEach((terminal, j) => {\n terminalModification[strand][terminal].value = obj[field[i][j]];\n })\n })\n comment.value = obj[FIELD.COMMENT];\n });\n pi.close();\n }\n\n function allColumnValuesOfEqualLength(colName: string): boolean {\n const col = tableInput.value!.getCol(colName);\n let allLengthsAreTheSame = true;\n for (let i = 1; i < col.length; i++) {\n if (col.get(i - 1).length !== col.get(i).length && col.get(i).length !== 0) {\n allLengthsAreTheSame = false;\n break;\n }\n }\n if (!allLengthsAreTheSame) {\n const dialog = ui.dialog('Sequences lengths mismatch');\n $(dialog.getButton('OK')).hide();\n dialog\n .add(ui.divText('The sequence length should match the number of Raw sequences in the input file'))\n .add(ui.divText('\\'ADD COLUMN\\' to see sequences lengths'))\n .addButton('ADD COLUMN', () => {\n tableInput.value!.columns.addNewInt('Sequences lengths in ' + colName).init((j: number) => col.get(j).length);\n grok.shell.info('Column with lengths added to \\'' + tableInput.value!.name + '\\'');\n dialog.close();\n grok.shell.v = grok.shell.getTableView(tableInput.value!.name);\n })\n .show();\n }\n if (col.get(0).length !== strandLengthInput[SS].value) {\n const d = ui.dialog('Length was updated by value to from imported file');\n d.add(ui.divText('Latest modifications may not take effect during translation'))\n .onOK(() => grok.shell.info('Lengths changed')).show();\n }\n return allLengthsAreTheSame;\n }\n\n async function getCurrentUserName(): Promise<string> {\n return await grok.dapi.users.current().then((user) => {\n return ' (created by ' + user.friendlyName + ')';\n });\n }\n\n async function postPatternToUserStorage() {\n const currUserName = await getCurrentUserName();\n saveAs.value = (saveAs.stringValue.includes('(created by ')) ?\n getShortName(saveAs.value) + currUserName :\n saveAs.stringValue + currUserName;\n return grok.dapi.userDataStorage.postValue(\n USER_STORAGE_KEY,\n saveAs.value,\n JSON.stringify({\n [FIELD.SS_BASES]: baseInputsObject[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value),\n [FIELD.AS_BASES]: baseInputsObject[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value),\n [FIELD.SS_PTO]: [firstPto[SS].value].concat(ptoLinkages[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value)),\n [FIELD.AS_PTO]: [firstPto[AS].value].concat(ptoLinkages[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value)),\n [FIELD.SS_3]: terminalModification[SS][THREE_PRIME].value,\n [FIELD.SS_5]:terminalModification[SS][FIVE_PRIME].value,\n [FIELD.AS_3]: terminalModification[AS][THREE_PRIME].value,\n [FIELD.AS_5]: terminalModification[AS][FIVE_PRIME].value,\n [FIELD.COMMENT]: comment.value,\n }),\n false,\n ).then(() => grok.shell.info('Pattern \\'' + saveAs.value + '\\' was successfully uploaded!'));\n }\n\n async function updatePatternsList() {\n grok.dapi.userDataStorage.get(USER_STORAGE_KEY, false).then(async (entities) => {\n const lstMy: string[] = [];\n const lstOthers: string[] = [];\n\n // TODO: display short name, but use long for querying userdataStorage\n for (const ent of Object.keys(entities)) {\n if (await isCurrentUserCreatedThisPattern(ent))\n lstOthers.push(ent);\n else\n lstMy.push(ent);//getShortName(ent));\n }\n\n let loadPattern = ui.choiceInput('Load pattern', '', lstMy, (v: string) => parsePatternAndUpdateUi(v));\n\n const currentUserName = (await grok.dapi.users.current()).friendlyName;\n const otherUsers = 'Other users';\n\n const patternListChoiceInput = ui.choiceInput('', currentUserName, [currentUserName, otherUsers], (v: string) => {\n const currentList = v === currentUserName ? lstMy : lstOthers;\n loadPattern = ui.choiceInput('Load pattern', '', currentList, (v: string) => parsePatternAndUpdateUi(v));\n\n loadPattern.root.append(patternListChoiceInput.input);\n loadPattern.root.append(loadPattern.input);\n // @ts-ignore\n loadPattern.input.style.maxWidth = '120px';\n loadPattern.input.style.marginLeft = '12px';\n loadPattern.setTooltip('Apply Existing Pattern');\n\n loadPatternDiv.innerHTML = '';\n loadPatternDiv.append(loadPattern.root);\n loadPattern.root.append(\n ui.div([\n ui.button(ui.iconFA('trash-alt', () => {}), async () => {\n if (loadPattern.value === null)\n grok.shell.warning('Choose pattern to delete');\n else if (await isCurrentUserCreatedThisPattern(saveAs.value))\n grok.shell.warning('Cannot delete pattern, created by other user');\n else {\n await grok.dapi.userDataStorage.remove(USER_STORAGE_KEY, loadPattern.value, false)\n .then(() => grok.shell.info('Pattern \\'' + loadPattern.value + '\\' deleted'));\n }\n await updatePatternsList();\n }),\n ], 'ui-input-options'),\n );\n });\n patternListChoiceInput.input.style.maxWidth = '142px';\n loadPattern.root.append(patternListChoiceInput.input);\n loadPattern.root.append(loadPattern.input);\n // @ts-ignore\n loadPattern.input.style.maxWidth = '100px';\n loadPattern.setTooltip('Apply Existing Pattern');\n\n loadPatternDiv.innerHTML = '';\n loadPatternDiv.append(loadPattern.root);\n loadPattern.root.append(\n ui.div([\n ui.button(ui.iconFA('trash-alt', () => {}), async () => {\n if (loadPattern.value === null)\n grok.shell.warning('Choose pattern to delete');\n else if (await isCurrentUserCreatedThisPattern(saveAs.value))\n grok.shell.warning('Cannot delete pattern, created by other user');\n else {\n await grok.dapi.userDataStorage.remove(USER_STORAGE_KEY, loadPattern.value, false)\n .then(() => grok.shell.info('Pattern \\'' + loadPattern.value + '\\' deleted'));\n }\n await updatePatternsList();\n }),\n ], 'ui-input-options'),\n );\n });\n }\n\n async function savePattern() {\n await grok.dapi.userDataStorage.get(USER_STORAGE_KEY, false)\n .then((entities) => {\n if (Object.keys(entities).includes(saveAs.value)) {\n const dialog = ui.dialog('Pattern already exists');\n $(dialog.getButton('OK')).hide();\n dialog\n .add(ui.divText('Pattern name \\'' + saveAs.value + '\\' already exists.'))\n .add(ui.divText('Replace pattern?'))\n .addButton('YES', async () => {\n await grok.dapi.userDataStorage.remove(USER_STORAGE_KEY, saveAs.value, false)\n .then(() => postPatternToUserStorage());\n dialog.close();\n })\n .show();\n } else\n postPatternToUserStorage();\n });\n await updatePatternsList();\n }\n\n function validateStrandColumn(colName: string, strand: string): void {\n const allLengthsAreTheSame: boolean = allColumnValuesOfEqualLength(colName);\n const firstSequence = tableInput.value!.getCol(colName).get(0);\n if (allLengthsAreTheSame && firstSequence.length !== strandLengthInput[strand].value)\n strandLengthInput[strand].value = tableInput.value!.getCol(colName).get(0).length;\n inputExample[strand].value = firstSequence;\n }\n\n function validateIdsColumn(colName: string) {\n const col = tableInput.value!.getCol(colName);\n if (col.type !== DG.TYPE.INT)\n grok.shell.error('Column should contain integers only');\n //@ts-ignore\n else if (col.categories.filter((e) => e !== '').length < col.toList().filter((e) => e !== '').length) {\n const duplicates = findDuplicates(col.getRawData());\n ui.dialog('Non-unique IDs')\n .add(ui.divText('Press \\'OK\\' to select rows with non-unique values'))\n .onOK(() => {\n const selection = tableInput.value!.selection;\n selection.init((i: number) => duplicates.indexOf(col.get(i)) > -1);\n grok.shell.v = grok.shell.getTableView(tableInput.value!.name);\n grok.shell.info('Rows are selected in table \\'' + tableInput.value!.name + '\\'');\n })\n .show();\n }\n }\n\n const baseChoices: string[] = Object.keys(axolabsStyleMap);\n const defaultBase: string = baseChoices[0];\n const enumerateModifications = [defaultBase];\n const sequenceBase = ui.choiceInput('Sequence basis', defaultBase, baseChoices, (v: string) => {\n updateBases(v);\n updateOutputExamples();\n });\n const fullyPto = ui.boolInput('Fully PTO', DEFAULT_PTO, (v: boolean) => {\n STRANDS.forEach((s) => { firstPto[s].value = v; })\n updatePto(v);\n updateOutputExamples();\n });\n fullyPto.captionLabel.classList.add('ui-label-right');\n fullyPto.captionLabel.style.textAlign = 'left';\n fullyPto.captionLabel.style.maxWidth = '100px';\n fullyPto.captionLabel.style.maxWidth = '100px';\n fullyPto.captionLabel.style.minWidth = '40px';\n fullyPto.captionLabel.style.width = 'auto';\n\n const maxStrandLength = Object.fromEntries(STRANDS.map(\n (strand) => [strand, DEFAULT_SEQUENCE_LENGTH]\n ));\n // todo: remove vague legacy 'items' from name\n const modificationItems = Object.fromEntries(STRANDS.map(\n (strand) => [strand, ui.div([])]\n ));\n const ptoLinkages = Object.fromEntries(STRANDS.map(\n (strand) => [strand, Array<BooleanInput>(DEFAULT_SEQUENCE_LENGTH)\n .fill(ui.boolInput('', DEFAULT_PTO))]\n ));\n const baseInputsObject = Object.fromEntries(STRANDS.map(\n (strand) => {\n const choiceInputs = Array<StringInput>(DEFAULT_SEQUENCE_LENGTH)\n .fill(ui.choiceInput('', defaultBase, baseChoices));\n return [strand, choiceInputs];\n }\n ));\n const strandLengthInput = Object.fromEntries(STRANDS.map(\n (strand) => {\n const input = ui.intInput(`${STRAND_NAME[strand]} length`, DEFAULT_SEQUENCE_LENGTH, () => updateUiForNewSequenceLength());\n input.setTooltip(`Length of ${STRAND_NAME[strand].toLowerCase()}, including overhangs`);\n return [strand, input];\n }));\n const strandVar = Object.fromEntries(STRANDS.map((strand) => [strand, '']));\n const inputExample = Object.fromEntries(STRANDS.map(\n (strand) => [strand, ui.textInput(\n ``, generateExample(strandLengthInput[strand].value!, sequenceBase.value!))\n ]));\n\n const strandColumnInput = Object.fromEntries(STRANDS.map((strand) => {\n const input = ui.choiceInput(`${STRAND_NAME[strand]} column`, '', [], (colName: string) => {\n validateStrandColumn(colName, strand);\n strandVar[strand] = colName;\n });\n return [strand, input];\n }));\n\n const firstPto = Object.fromEntries(STRANDS.map((strand) => {\n const input = ui.boolInput(`First ${strand} PTO`, fullyPto.value!, () => updateSvgScheme());\n input.setTooltip(`ps linkage before first nucleotide of ${STRAND_NAME[strand].toLowerCase()}`);\n\n input.captionLabel.classList.add('ui-label-right');\n input.captionLabel.style.textAlign = 'left';\n input.captionLabel.style.maxWidth = '100px';\n input.captionLabel.style.minWidth = '40px';\n input.captionLabel.style.width = 'auto';\n\n return [strand, input];\n }));\n\n const terminalModification = Object.fromEntries(STRANDS.map((strand) => {\n const inputs = Object.fromEntries(TERMINAL_KEYS.map((key) => {\n const input = ui.stringInput(`${strand} ${TERMINAL[key]}\\' Modification`, '', () => {\n updateSvgScheme();\n updateOutputExamples();\n });\n input.setTooltip(`Additional ${strand} ${TERMINAL[key]}\\' Modification`);\n return [key, input];\n }));\n return [strand, inputs];\n }));\n\n const outputExample = Object.fromEntries(STRANDS.map((strand) => {\n const input = ui.textInput('', translateSequence(\n inputExample[strand].value, baseInputsObject[strand], ptoLinkages[strand], terminalModification[strand][THREE_PRIME],terminalModification[strand][FIVE_PRIME], firstPto[strand].value!\n ));\n input.input.style.minWidth = 'none';\n input.input.style.flexGrow = '1';\n $(input.root.lastChild).css('height', 'auto');\n return [strand, input];\n }));\n\n const modificationSection = Object.fromEntries(STRANDS.map((strand) => {\n const panel = ui.block([\n ui.h1(`${STRAND_NAME[strand]}`),\n ui.divH([\n ui.div([ui.divText('#')], {style: {width: '20px'}})!,\n ui.block75([ui.divText('Modification')])!,\n ui.div([ui.divText('PTO')])!,\n ]),\n modificationItems[strand],\n ], {style: {paddingTop: '12px'}});\n return [strand, panel];\n }));\n\n STRANDS.forEach((s) => {\n \n inputExample[s].input.style.resize = 'none';\n outputExample[s].input.style.resize = 'none';\n inputExample[s].input.style.minWidth = 'none';\n inputExample[s].input.style.flexGrow = '1';\n outputExample[s].input.style.minWidth = 'none';\n outputExample[s].input.style.flexGrow = '1';\n let options = ui.div([\n ui.button(ui.iconFA('copy', () => {}), () => {\n navigator.clipboard.writeText(outputExample[s].value).then(() =>\n grok.shell.info('Sequence was copied to clipboard'));\n }),\n ], 'ui-input-options');\n options.style.height = 'inherit';\n outputExample[s].root.append(\n options\n );\n })\n\n // const inputIdColumnDiv = ui.div([]);\n const svgDiv = ui.div([]);\n const asExampleDiv = ui.div([], 'ui-form ui-form-wide');\n const loadPatternDiv = ui.div([]);\n const asModificationDiv = ui.form([]);\n const isEnumerateModificationsDiv = ui.divH([\n ui.boolInput(defaultBase, true, (v: boolean) => {\n if (v) {\n if (!enumerateModifications.includes(defaultBase))\n enumerateModifications.push(defaultBase);\n } else {\n const index = enumerateModifications.indexOf(defaultBase, 0);\n if (index > -1)\n enumerateModifications.splice(index, 1);\n }\n updateSvgScheme();\n updateOutputExamples();\n }).root,\n ]);\n\n const asLengthDiv = ui.div([strandLengthInput[AS].root]);\n\n function getTableInput(tableList: DG.DataFrame[]): DG.InputBase {\n const tableInput = ui.tableInput('Tables', tableList[0], tableList, () => {\n const table = tableInput.value;\n if (table === null) {\n console.warn('Table is null');\n return;\n }\n const tableName = table!.name;\n if (!grok.shell.tableNames.includes(tableName)) {\n const view = grok.shell.v;\n grok.shell.addTableView(table!);\n grok.shell.v = view;\n }\n const columnNames = table.columns.names();\n\n STRANDS.forEach((strand) => {\n const defaultColumn = columnNames[0];\n validateStrandColumn(defaultColumn, strand);\n strandVar[strand] = defaultColumn;\n const input = ui.choiceInput(`${STRAND_NAME[strand]} column`, defaultColumn, columnNames, (colName: string) => {\n validateStrandColumn(colName, strand);\n strandVar[strand] = colName;\n console.log(`clicked ${strand} var:`, strandVar[strand]);\n });\n $(strandColumnInput[strand].root).replaceWith(input.root);\n })\n\n idVar = columnNames[0];\n // todo: unify with inputStrandColumn\n const idInput = ui.choiceInput('ID column', columnNames[0], columnNames, (colName: string) => {\n validateIdsColumn(colName);\n idVar = colName;\n });\n $(inputIdColumn.root).replaceWith(idInput.root);\n });\n return tableInput;\n }\n\n const tableInput = getTableInput([]);\n\n // todo: unify with strandVar\n let idVar = '';\n const inputIdColumn = ui.choiceInput('ID column', '', [], (colName: string) => {\n validateIdsColumn(colName);\n idVar = colName;\n });\n // inputIdColumnDiv.append(inputIdColumn.root);\n\n updatePatternsList();\n\n const createAsStrand = ui.boolInput('Anti sense strand', true, (v: boolean) => {\n modificationSection[AS].hidden = !v;\n strandColumnInput[AS].root.hidden = !v;\n asLengthDiv.hidden = !v;\n asModificationDiv.hidden = !v;\n asExampleDiv.hidden = !v;\n firstPto[AS].root.hidden = !v;\n updateSvgScheme();\n });\n createAsStrand.setTooltip('Create antisense strand sections on SVG and table to the right');\n\n const saveAs = ui.textInput('Save as', 'Pattern name', () => updateSvgScheme());\n saveAs.setTooltip('Name Of New Pattern');\n\n\n TERMINAL_KEYS.forEach((terminal) => {\n asModificationDiv.append(terminalModification[AS][terminal].root);\n })\n\n const comment = ui.textInput('Comment', '', () => updateSvgScheme());\n\n const savePatternButton = ui.bigButton('Save', () => {\n if (saveAs.value !== '')\n savePattern().then(() => grok.shell.info('Pattern saved'));\n else {\n const name = ui.stringInput('Enter name', '');\n ui.dialog('Pattern Name')\n .add(name.root)\n .onOK(() => {\n saveAs.value = name.value;\n savePattern().then(() => grok.shell.info('Pattern saved'));\n })\n .show();\n }\n });\n saveAs.addOptions(savePatternButton);\n\n const convertSequenceButton = ui.bigButton('Convert', () => {\n const condition = [true, createAsStrand.value];\n console.log(`strand vars:`, Object.values(strandVar));\n if (STRANDS.some((s, i) => condition[i] && strandVar[s] === ''))\n grok.shell.info('Please select table and columns on which to apply pattern');\n else if (STRANDS.some((s) => strandLengthInput[s].value !== inputExample[s].value.length)) {\n const dialog = ui.dialog('Length Mismatch');\n $(dialog.getButton('OK')).hide();\n dialog\n .add(ui.divText('Length of sequences in columns doesn\\'t match entered length. Update length value?'))\n .addButton('YES', () => {\n STRANDS.forEach((s) => {\n strandLengthInput[s].value = tableInput.value!.getCol(strandColumnInput[s].value!).getString(0).length;\n })\n dialog.close();\n })\n .show();\n } else {\n if (idVar !== '')\n addColumnWithIds(tableInput.value!.name, idVar, getShortName(saveAs.value));\n const condition = [true, createAsStrand.value];\n STRANDS.forEach((strand, i) => {\n if (condition[i])\n addColumnWithTranslatedSequences(\n tableInput.value!.name, strandVar[strand], baseInputsObject[strand], ptoLinkages[strand],\n terminalModification[strand][FIVE_PRIME], terminalModification[strand][THREE_PRIME], firstPto[strand].value!);\n })\n grok.shell.v = grok.shell.getTableView(tableInput.value!.name);\n grok.shell.info(((createAsStrand.value) ? 'Columns were' : 'Column was') +\n ' added to table \\'' + tableInput.value!.name + '\\'');\n updateOutputExamples();\n }\n });\n\n asExampleDiv.append(inputExample[AS].root);\n asExampleDiv.append(outputExample[AS].root);\n\n updateUiForNewSequenceLength();\n\n const exampleSection = ui.div([\n ui.h1('Conversion preview'),\n inputExample[SS].root,\n outputExample[SS].root,\n asExampleDiv,\n ], 'ui-form ui-form-wide');\n\n const inputsSection = ui.block50([\n ui.h1('Convert options'),\n tableInput.root,\n strandColumnInput[SS].root,\n strandColumnInput[AS].root,\n inputIdColumn.root,\n ui.buttonsInput([\n convertSequenceButton,\n ]),\n ]);\n inputsSection.classList.add('ui-form');\n\n const downloadButton = ui.link('Download', () => svg.saveSvgAsPng(document.getElementById('mySvg'), saveAs.value,\n {backgroundColor: 'white'}), 'Download pattern as PNG image', '');\n \n const editPattern = ui.link('Edit pattern', ()=>{\n ui.dialog('Edit pattern')\n .add(ui.divV([\n ui.h1('PTO'),\n ui.divH([\n fullyPto.root,\n firstPto[SS].root,\n firstPto[AS].root,\n ], {style:{gap:'12px'}})\n ]))\n .add(ui.divH([\n modificationSection[SS],\n modificationSection[AS],\n ], {style:{gap:'24px'}}))\n .onOK(()=>{grok.shell.info('Saved')})\n .show()\n }, 'Edit pattern', ''); \n\n strandLengthInput[SS].addCaption('Length');\n\n return ui.splitH([\n ui.box(\n ui.div([\n ui.h1('Pattern'),\n createAsStrand.root,\n strandLengthInput[SS],\n strandLengthInput[AS],\n sequenceBase.root,\n comment.root,\n loadPatternDiv,\n saveAs.root,\n ui.h1('Convert'),\n tableInput.root,\n strandColumnInput[SS],\n strandColumnInput[AS],\n inputIdColumn.root,\n ui.buttonsInput([\n convertSequenceButton,\n ]),\n ], 'ui-form')\n , {style:{maxWidth:'450px'}}),\n ui.panel([\n svgDiv,\n isEnumerateModificationsDiv,\n ui.divH([\n downloadButton,\n editPattern\n ], {style:{gap:'12px', marginTop:'12px'}}),\n ui.divH([\n ui.divV([\n ui.h1('Sense strand'),\n inputExample[SS].root,\n outputExample[SS].root,\n ], 'ui-block'),\n ui.divV([\n ui.h1('Anti sense'),\n inputExample[AS],\n outputExample[AS]\n ], 'ui-block'),\n ], {style:{gap:'24px', marginTop:'24px'}}),\n ui.h1('Additional modifications'),\n ui.form([\n terminalModification[SS][FIVE_PRIME],\n terminalModification[SS][THREE_PRIME],\n ]),\n asModificationDiv,\n ], {style: {overflowX: 'scroll', padding:'12px 24px'}})\n ], {}, true)\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport $ from 'cash-dom';\n\nimport {extractAtomDataV3000} from '../../model/structure-app/mol-transformations';\n\n/** Draw molecule on the canvas and append it to the specified div, with the\n * option of zoom-in */\nexport async function drawMolecule(\n moleculeImgDiv: HTMLDivElement,\n canvasWidth: number, canvasHeight: number,\n molfile: string\n): Promise<void> {\n // clear div's content if any\n moleculeImgDiv.innerHTML = '';\n\n if (molfile !== '') {\n const canvas = ui.canvas(canvasWidth * window.devicePixelRatio, canvasHeight * window.devicePixelRatio);\n\n // Draw zoomed-out molecule\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n canvas.style.borderStyle = 'solid';\n canvas.style.borderColor = 'var(--grey-3)';\n canvas.style.borderWidth = 'thin';\n drawMolfileOnCanvas(canvas, molfile);\n\n // Dialog with zoomed-in molecule\n $(canvas).on('click', async () => { await drawZoomedInMolecule(molfile); });\n $(canvas).on('mouseover', () => $(canvas).css('cursor', 'grab')); // for some reason 'zoom-in' value wouldn't work\n $(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));\n\n moleculeImgDiv.append(canvas);\n }\n}\n\n\nexport async function drawZoomedInMolecule(molfile: string): Promise<void> {\n try {\n const dialogDivStyle = {\n overflowX: 'scroll',\n };\n const dialogDiv = ui.div([], {style: dialogDivStyle});\n\n // dialogDiv size required, but now available before dialog show()\n const atomCoordinates = extractAtomDataV3000(molfile);\n // const cw: number = $(window).width() * 0.80; // dialogDiv.clientWidth\n const clientHeight: number = $(window).height() * 0.70; // dialogDiv.clientHeight\n const molWidth: number = Math.max(...atomCoordinates.x) - Math.min(...atomCoordinates.x);\n const molHeight: number = Math.max(...atomCoordinates.y) - Math.min(...atomCoordinates.y);\n\n // const wR: number = cw / molWidth;\n const hR: number = clientHeight / molHeight;\n const r: number = hR; // Math.max(wR, hR);\n const dialogCanvasWidth = r * molWidth;\n const dialogCanvasHeight = r * molHeight;\n\n const dialogCanvas = ui.canvas(\n dialogCanvasWidth * window.devicePixelRatio, dialogCanvasHeight * window.devicePixelRatio\n );\n dialogCanvas.style.width = `${dialogCanvasWidth}px`;\n dialogCanvas.style.height = `${dialogCanvasHeight}px`;\n await drawMolfileOnCanvas(dialogCanvas, molfile);\n\n dialogDiv.appendChild(dialogCanvas);\n ui.dialog('Molecule')\n .add(dialogDiv)\n .showModal(true);\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n};\n\n\nexport async function drawMolfileOnCanvas(canvas: HTMLCanvasElement, molfile: string): Promise<void> {\n await grok.functions.call('Chem:canvasMol', {\n x: 0, y: 0, w: canvas.width, h: canvas.height, canvas: canvas,\n molString: molfile, scaffoldMolString: '',\n options: {normalizeDepiction: false, straightenDepiction: false}\n });\n};\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {drawZoomedInMolecule} from '../utils/draw-molecule';\nimport {MonomerLibWrapper} from '../../model/monomer-lib/lib-wrapper';\n\nexport class MonomerLibViewer {\n static async view(): Promise<void> {\n const table = MonomerLibWrapper.getInstance().getTableForViewer();\n table.name = 'Monomer Library';\n const view = grok.shell.addTableView(table);\n view.grid.props.allowEdit = false;\n const onDoubleClick = view.grid.onCellDoubleClick;\n onDoubleClick.subscribe(async (gridCell: DG.GridCell) => {\n const molfile = gridCell.cell.value;\n if (gridCell.tableColumn?.semType === 'Molecule')\n await drawZoomedInMolecule(molfile);\n });\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {TAB, APP} from './const/ui';\nimport {TranslatorLayoutHandler} from './apps/oligo-translator';\nimport {StructureLayoutHandler} from './apps/oligo-structure';\nimport {PatternLayoutHandler} from './apps/oligo-pattern';\nimport {MonomerLibViewer} from './monomer-lib-viewer/viewer';\nimport {_package} from '../package';\nimport {tryCatch} from '../model/helpers';\n\ntype ViewFactories = {[name: string]: () => DG.View};\n\nexport abstract class AppUIBase {\n constructor(protected appName: string, protected parentAppName?: string) { }\n abstract addView(): Promise<void>;\n\n async createAppLayout(): Promise<void> {\n const pi: DG.TaskBarProgressIndicator = DG.TaskBarProgressIndicator.create(`Loading ${this.appName}...`);\n\n let currentView = grok.shell.v?.root;\n if (currentView)\n ui.setUpdateIndicator(currentView, true);\n\n await tryCatch(async () => {\n await this.addView();\n }, () => pi.close());\n\n if (currentView)\n ui.setUpdateIndicator(currentView, false);\n }\n}\n\nabstract class SimpleAppUIBase extends AppUIBase {\n constructor(appName: string) {\n super(appName);\n this.view = DG.View.create();\n this.setupView();\n }\n\n protected view: DG.View;\n async addView(): Promise<void> {\n await this.initView();\n const name = this.parentAppName ? this.parentAppName + '/' + this.appName : this.appName;\n this.view.path = `/apps/${_package.name}/${name.replace(/\\s/g, '')}/`;\n grok.shell.addView(this.view);\n }\n\n protected abstract getHtml(): Promise<HTMLDivElement>;\n async initView(): Promise<void> {\n const html = await this.getHtml();\n this.view.append(html);\n }\n\n protected setupView(): void {\n this.view.box = true;\n this.view.name = this.appName;\n\n const windows = grok.shell.windows;\n windows.showProperties = false;\n windows.showToolbox = false;\n windows.showHelp = false;\n }\n\n getView(): DG.View {\n return this.view;\n }\n}\n\nexport class CombinedAppUI extends AppUIBase {\n constructor(externalViewFactories: ViewFactories) {\n super(APP.COMBINED)\n this.externalViewFactories = externalViewFactories;\n const factories = this.getViewFactories();\n this.multiView = new DG.MultiView({viewFactories: factories}); \n }\n\n private multiView: DG.MultiView;\n private externalViewFactories?: ViewFactories;\n\n private getViewFactories(): ViewFactories {\n function viewFactory(uiConstructor: new (view: DG.View) => SimpleAppUIBase): () => DG.View {\n const view = DG.View.create();\n const translateUI = new uiConstructor(view);\n // intentonally don't await for the promise\n translateUI.initView();\n return () => translateUI.getView();\n }\n\n let result: {[key: string]: () => DG.View } = {\n [TAB.TRANSLATOR]: viewFactory(OligoTranslatorUI),\n [TAB.PATTERN]: viewFactory(OligoPatternUI),\n [TAB.STRUCTRE]: viewFactory(OligoStructureUI),\n }\n\n if (this.externalViewFactories)\n result = Object.assign({}, result, this.externalViewFactories);\n\n return result\n }\n\n private getPath(): string {\n let name = this.multiView.tabs.currentPane.name;\n name = name.charAt(0).toUpperCase() + name.substring(1).toLowerCase();\n const path = `/apps/${_package.name}/OligoToolkit/${name}`;\n return path;\n }\n\n private setUrl(): void {\n this.multiView.path = this.getPath();\n }\n\n async addView(): Promise<void> {\n this.multiView.tabs.onTabChanged.subscribe(() => this.setUrl());\n this.setUrl();\n grok.shell.addView(this.multiView);\n }\n}\n\n/** For plugins from external packages */\nexport class ExternalPluginUI extends SimpleAppUIBase {\n constructor(viewName: string, layout: HTMLDivElement) {\n super(viewName);\n this.layout = layout;\n }\n private layout: HTMLDivElement;\n\n protected getHtml(): Promise<HTMLDivElement> {\n return Promise.resolve(this.layout);\n }\n}\n\nexport class AppUIFactory {\n private constructor() {}\n\n static getUI(appName: string): SimpleAppUIBase {\n switch (appName) {\n case APP.TRANSLATOR:\n return new OligoTranslatorUI();\n case APP.PATTERN:\n return new OligoPatternUI();\n case APP.STRUCTRE:\n return new OligoStructureUI();\n default:\n throw new Error(`Unknown app name: ${appName}`);\n }\n }\n}\n\nclass OligoTranslatorUI extends SimpleAppUIBase {\n constructor() {\n super(APP.TRANSLATOR);\n\n const viewMonomerLibIcon = ui.iconFA('book', MonomerLibViewer.view, 'View monomer library');\n this.topPanel = [\n viewMonomerLibIcon,\n ];\n this.view.setRibbonPanels([this.topPanel]);\n this.ui = new TranslatorLayoutHandler();\n }\n\n private readonly topPanel: HTMLElement[];\n private readonly ui: TranslatorLayoutHandler;\n\n protected getHtml(): Promise<HTMLDivElement> {\n return this.ui.getHtmlElement();\n };\n}\n\nclass OligoPatternUI extends SimpleAppUIBase {\n constructor() {\n super(APP.PATTERN);\n this.ui = new PatternLayoutHandler();\n }\n private readonly ui: PatternLayoutHandler;\n protected getHtml(): Promise<HTMLDivElement> {\n return Promise.resolve(this.ui.htmlDivElement);\n }\n}\n\nclass OligoStructureUI extends SimpleAppUIBase {\n constructor() {\n super(APP.STRUCTRE)\n this.ui = new StructureLayoutHandler();\n }\n private readonly ui: StructureLayoutHandler;\n\n protected getHtml(): Promise<HTMLDivElement> {\n return this.ui.getHtmlDivElement();\n }\n}\n","import { CandidateType } from './types';\n/** enum type to simplify setting \"user-friendly\" notation if necessary */\nexport var NOTATION;\n(function (NOTATION) {\n NOTATION[\"FASTA\"] = \"fasta\";\n NOTATION[\"SEPARATOR\"] = \"separator\";\n NOTATION[\"HELM\"] = \"helm\";\n})(NOTATION || (NOTATION = {}));\nexport const positionSeparator = ', ';\nexport const monomerRe = /(?:\\[([A-Za-z0-9_\\-,()]+)\\])|([A-Za-z\\-])/g;\nexport const Alphabets = new class {\n constructor() {\n this.fasta = {\n peptide: new Set([\n 'G', 'L', 'Y', 'S', 'E', 'Q', 'D', 'N', 'F', 'A',\n 'K', 'R', 'H', 'C', 'V', 'P', 'W', 'I', 'M', 'T',\n ]),\n dna: new Set(['A', 'C', 'G', 'T']),\n rna: new Set(['A', 'C', 'G', 'U']),\n };\n }\n}();\nexport const candidateAlphabets = [\n new CandidateType(\"PT\" /* ALPHABET.PT */, Alphabets.fasta.peptide, 0.50),\n new CandidateType(\"DNA\" /* ALPHABET.DNA */, Alphabets.fasta.dna, 0.55),\n new CandidateType(\"RNA\" /* ALPHABET.RNA */, Alphabets.fasta.rna, 0.55),\n];\n//# sourceMappingURL=consts.js.map","const __WEBPACK_NAMESPACE_OBJECT__ = wu;","/** Alphabet candidate type */\nexport class CandidateType {\n constructor(name, alphabet, cutoff) {\n this.name = name;\n this.alphabet = alphabet;\n this.cutoff = cutoff;\n }\n}\n/** Alphabet candidate similarity type */\nexport class CandidateSimType extends CandidateType {\n constructor(candidate, freq, similarity) {\n super(candidate.name, candidate.alphabet, candidate.cutoff);\n this.freq = freq;\n this.similarity = similarity;\n }\n}\n//# sourceMappingURL=types.js.map","/**\n * Denotes a vector of floating poit values.\n *\n * @export\n * @class Vector\n * @extends {Float32Array}\n */\nexport class Vector extends Float32Array {\n}\n/**\n * Denotes a two-dimensional matrix.\n *\n * @export\n * @class Matrix\n * @extends {Array<Vector>}\n */\nexport class Matrix extends Array {\n}\n/**\n * Denotes cartesian coordinates.\n *\n * @export\n * @class Coordinates\n * @extends {Matrix}\n */\nexport class Coordinates extends Matrix {\n}\n/**\n * Denotes an array of arbitrary-typed vectors.\n *\n * @export\n * @class Vectors\n * @extends {Array<any>}\n */\nexport class Vectors extends Array {\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcbiJdfQ==","export class SeqPaletteBase {\n static makePalette(dt, simplified = false, PaletteType = SeqPaletteBase) {\n const palette = {};\n dt.forEach((cp) => {\n const objList = cp[0];\n const colour = cp[1];\n objList.forEach((obj, ind) => {\n palette[obj] = this.colourPalette[colour][simplified ? 0 : ind];\n });\n });\n return new PaletteType(palette);\n }\n constructor(palette) {\n this._palette = palette;\n }\n get(m) {\n return this._palette[m];\n }\n}\nSeqPaletteBase.undefinedColor = 'rgb(100,100,100)';\n/** Palette with shades of primary colors */\nSeqPaletteBase.colourPalette = {\n 'orange': ['rgb(255,187,120)', 'rgb(245,167,100)', 'rgb(235,137,70)', 'rgb(205, 111, 71)'],\n 'all_green': ['rgb(44,160,44)', 'rgb(74,160,74)', 'rgb(23,103,57)', 'rgb(30,110,96)', 'rgb(60,131,95)',\n 'rgb(24,110,79)', 'rgb(152,223,138)', 'rgb(182, 223, 138)', 'rgb(152, 193, 138)'],\n 'all_blue': ['rgb(31,119,180)', 'rgb(23,190,207)', 'rgb(122, 102, 189)', 'rgb(158,218,229)', 'rgb(141, 124, 217)',\n 'rgb(31, 120, 150)'],\n 'magenta': ['rgb(162,106,192)', 'rgb(197,165,224)', 'rgb(208,113,218)'],\n 'red': ['rgb(214,39,40)', 'rgb(255,152,150)'],\n 'st_blue': ['rgb(23,190,207)', 'rgb(158,218,229)', 'rgb(31,119,180)'],\n 'dark_blue': ['rgb(31,119,180)', 'rgb(31, 120, 150)'],\n 'light_blue': ['rgb(23,190,207)', 'rgb(158,218,229)', 'rgb(108, 218, 229)', 'rgb(23,190,227)'],\n 'lilac_blue': ['rgb(124,102,211)', 'rgb(149,134,217)', 'rgb(97, 81, 150)'],\n 'dark_green': ['rgb(23,103,57)', 'rgb(30,110,96)', 'rgb(60,131,95)', 'rgb(24,110,79)'],\n 'green': ['rgb(44,160,44)', 'rgb(74,160,74)'],\n 'light_green': ['rgb(152,223,138)', 'rgb(182, 223, 138)', 'rgb(152, 193, 138)'],\n 'st_green': ['rgb(44,160,44)', 'rgb(152,223,138)', 'rgb(39, 174, 96)', 'rgb(74,160,74)'],\n 'pink': ['rgb(247,182,210)'],\n 'brown': ['rgb(140,86,75)', 'rgb(102, 62, 54)'],\n 'gray': ['rgb(127,127,127)', 'rgb(199,199,199)', 'rgb(196,156,148)', 'rgb(222, 222, 180)'],\n 'yellow': ['rgb(188,189,34)'],\n 'white': ['rgb(230,230,230)'],\n};\n//# sourceMappingURL=seq-palettes.js.map","import { SeqPaletteBase } from './seq-palettes';\nexport class AminoacidsPalettes extends SeqPaletteBase {\n static get Lesk() {\n if (this.lesk === void 0) {\n this.lesk = this.makePalette([\n [['G', 'A', 'S', 'T'], 'orange'],\n [['C', 'V', 'I', 'L', 'P', 'F', 'Y', 'M', 'W'], 'all_green'],\n [['N', 'Q', 'H'], 'magenta'],\n [['D', 'E'], 'red'],\n [['K', 'R'], 'all_blue'],\n ], false, AminoacidsPalettes);\n }\n return this.lesk;\n }\n static get GrokGroups() {\n if (this.grokGroups === void 0) {\n this.grokGroups = this.makePalette([\n [['C', 'U'], 'yellow'],\n [['G', 'P'], 'red'],\n [['A', 'V', 'I', 'L', 'M', 'F', 'Y', 'W'], 'all_green'],\n [['R', 'H', 'K'], 'light_blue'],\n [['D', 'E'], 'dark_blue'],\n [['S', 'T', 'N', 'Q'], 'orange'],\n ], false, AminoacidsPalettes);\n }\n return this.grokGroups;\n }\n static get RasMol() {\n if (this.rasMol === void 0) {\n this.rasMol = new AminoacidsPalettes({\n // http://acces.ens-lyon.fr/biotic/rastop/help/colour.htm\n 'D': '#E60A0A',\n 'E': '#E60A0A',\n 'C': '#E6E600',\n 'M': '#E6E600',\n 'K': '#145AFF',\n 'R': '#145AFF',\n 'S': '#FA9600',\n 'T': '#FA9600',\n 'F': '#3232AA',\n 'Y': '#3232AA',\n 'N': '#00DCDC',\n 'Q': '#00DCDC',\n 'G': '#EBEBEB',\n 'L': '#0F820F',\n 'V': '#0F820F',\n 'I': '#0F820F',\n 'A': '#C8C8C8',\n 'W': '#B45AB4',\n 'H': '#8282D2',\n 'P': '#DC9682',\n 'others': '#BEA06E',\n });\n }\n return this.rasMol;\n }\n get(m) {\n const resM = m in AminoacidsPalettes.aaSynonyms ? AminoacidsPalettes.aaSynonyms[m] : m;\n const res = super.get(resM);\n return res;\n }\n}\n/** Only some of the synonyms. These were obtained from the clustered oligopeptide dataset. */\nAminoacidsPalettes.aaSynonyms = {\n 'MeNle': 'L',\n 'MeA': 'A',\n 'MeG': 'G',\n 'MeF': 'F',\n};\nexport class Aminoacids {\n static getPalette(scheme = 'grok') {\n switch (scheme) {\n case 'grok':\n return AminoacidsPalettes.GrokGroups;\n case 'lesk':\n return AminoacidsPalettes.Lesk;\n default:\n throw new Error(`ChemPalette: scheme \\`${scheme}\\` does not exist`);\n }\n }\n /**\n * Returns divided amino acid with its content in the bracket, if the content is number, then its omitted\n *\n * @param {string} c raw amino\n * @return {[string, string]} outer and inner content\n */\n static getInnerOuter(c) {\n let isInner = 0;\n let inner = '';\n let outer = '';\n for (const char of c) {\n if (char == '(')\n isInner++;\n else if (char == ')')\n isInner--;\n else if (isInner)\n inner += char;\n else\n outer += char;\n }\n return !isNaN(parseInt(inner)) ? [outer, ''] : [outer, inner];\n }\n static getColorAAPivot(monomer = '', scheme = 'grok') {\n //const chemPaletteInstance = AAPalettes.GrokGroups();\n const chemPaletteInstance = this.getPalette(scheme);\n let [outerMonomer, innerMonomer] = this.getInnerOuter(monomer);\n outerMonomer = (outerMonomer.length > 6 ? `${outerMonomer.slice(0, 3)}...` : outerMonomer);\n innerMonomer = (innerMonomer.length > 6 ? `${innerMonomer.slice(0, 3)}...` : innerMonomer);\n if (monomer.length == 1 || monomer[1] == '(') {\n const amino = monomer[0]?.toUpperCase();\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 1] :\n [this.undefinedColor, outerMonomer, innerMonomer, 1];\n }\n if (monomer[0] == 'd' && monomer[1] in chemPaletteInstance) {\n if (monomer.length == 2 || monomer[2] == '(') {\n const amino = monomer[1]?.toUpperCase();\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 2] :\n [this.undefinedColor, outerMonomer, innerMonomer, 2];\n }\n }\n if (monomer.substring(0, 3) in this.AAFullNames) {\n if (monomer.length == 3 || monomer[3] == '(') {\n const amino = this.AAFullNames[monomer.substring(0, 3)];\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 3] :\n [this.undefinedColor, outerMonomer, innerMonomer, 3];\n }\n }\n if (monomer[0]?.toLowerCase() == monomer[0]) {\n if (monomer.substring(1, 3) in this.AAFullNames) {\n if (monomer.length == 4 || monomer[4] == '(') {\n const amino = this.AAFullNames[monomer.substring(1, 3)];\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 4] :\n [this.undefinedColor, outerMonomer, innerMonomer, 4];\n }\n }\n }\n return [this.undefinedColor, outerMonomer, innerMonomer, 0];\n }\n}\nAminoacids.SemType = 'Aminoacids';\nAminoacids.SemTypeMultipleAlignment = 'AminoacidsMultipleAlignment';\nAminoacids.undefinedColor = 'rgb(100,100,100)';\nAminoacids.Names = {\n 'G': 'Glycine',\n 'L': 'Leucine',\n 'Y': 'Tyrosine',\n 'S': 'Serine',\n 'E': 'Glutamic acid',\n 'Q': 'Glutamine',\n 'D': 'Aspartic acid',\n 'N': 'Asparagine',\n 'F': 'Phenylalanine',\n 'A': 'Alanine',\n 'K': 'Lysine',\n 'R': 'Arginine',\n 'H': 'Histidine',\n 'C': 'Cysteine',\n 'V': 'Valine',\n 'P': 'Proline',\n 'W': 'Tryptophan',\n 'I': 'Isoleucine',\n 'M': 'Methionine',\n 'T': 'Threonine',\n};\nAminoacids.AASmiles = {\n 'G': 'NCC(=O)O',\n 'L': 'N[C@H](CC(C)C)C(=O)O',\n 'Y': 'NC(CC1=CC=C(O)C=C1)C(=O)O',\n 'S': 'NC(CO)C(=O)O',\n 'E': 'N[C@@H](CCC(O)=O)C(=O)O',\n 'Q': 'N[C@@H](CCC(N)=O)C(=O)O',\n 'D': 'N[C@@H](CC(O)=O)C(=O)O',\n 'N': 'N[C@@H](CC(N)=O)C(=O)O',\n 'F': 'NC(CC1=CC=CC=C1)C(=O)O',\n 'A': 'N[C@H](C)C(=O)O',\n 'K': 'NC(CCCCN)C(=O)O',\n 'R': 'N[C@H](CCCNC(=N)C)C(=O)O',\n 'H': 'NC(CC1=CN=C[N]1)C(=O)O',\n 'C': 'N[C@@H](CS)C(=O)O',\n 'V': 'NC(C(C)C)C(=O)O',\n 'P': 'N(CCC1)C1C(=O)O',\n 'W': 'N[C@@H](Cc1c2ccccc2n([H])c1)C(=O)O',\n 'I': 'N[C@H]([C@H](C)CC)C(=O)O',\n 'M': 'NC(CCSC)C(=O)O',\n 'T': 'NC(C(O)C)C(=O)O',\n};\nAminoacids.AASmilesTruncated = {\n 'G': '*C*',\n 'L': 'CC(C)C[C@H](*)*',\n 'Y': 'C1=CC(=CC=C1CC(*)*)O',\n 'S': 'OCC(*)C*',\n 'E': '*[C@@H](CCC(O)=O)*',\n 'Q': '*N[C@@H](CCC(N)=O)*',\n 'D': '*[C@@H](CC(O)=O)*',\n 'N': '*[C@@H](CC(N)=O)*',\n 'F': 'C1=CC=C(C=C1)CC(*)*',\n 'A': 'C[C@H](*)*',\n 'K': 'C(CCN)CC(*)*',\n 'R': '*[C@H](CCCNC(=N)C)*',\n 'H': 'C1=C(NC=N1)CC(*)*',\n 'C': 'C([C@@H](*)*)S',\n 'V': 'CC(C)C(*)*',\n 'P': 'C1CCN(*)C1*',\n 'W': '*[C@@H](Cc1c2ccccc2n([H])c1)*',\n 'I': 'CC[C@H](C)[C@H](*)*',\n 'M': 'CSCCC(*)*',\n 'T': 'CC(O)C(*)*',\n};\n/** TODO: Full?\n */\nAminoacids.AAFullNames = {\n 'Ala': 'A',\n 'Arg': 'R',\n 'Asn': 'N',\n 'Asp': 'D',\n 'Cys': 'C',\n 'Gln': 'Q',\n 'Glu': 'E',\n 'Gly': 'G',\n 'His': 'H',\n 'Ile': 'I',\n 'Leu': 'L',\n 'Lys': 'K',\n 'Met': 'M',\n 'Phe': 'F',\n 'Pro': 'P',\n 'Ser': 'S',\n 'Thr': 'T',\n 'Trp': 'W',\n 'Tyr': 'Y',\n 'Val': 'V',\n};\n//# sourceMappingURL=aminoacids.js.map","import { SeqPaletteBase } from './seq-palettes';\nexport class NucleotidesPalettes extends SeqPaletteBase {\n static get Chromatogram() {\n if (this.chromatogram === void 0) {\n this.chromatogram = new NucleotidesPalettes({\n 'A': 'green',\n 'C': 'blue',\n 'G': 'black',\n 'T': 'red',\n 'U': 'red',\n 'others': 'gray',\n });\n }\n return this.chromatogram;\n }\n}\nexport class Nucleotides {\n}\nNucleotides.SemType = 'Nucleotides';\nNucleotides.SemTypeMultipleAlignment = 'NucleotidesMultipleAlignment';\nNucleotides.Names = {\n 'A': 'Adenine',\n 'C': 'Cytosine',\n 'G': 'Guanine',\n 'T': 'Thymine',\n 'U': 'Uracil',\n};\n//# sourceMappingURL=nucleotides.js.map","import * as DG from 'datagrok-api/dg';\n/** makes the color less white, makes the transparency effect always perceptible\n * @param {string} color x coordinate.\n * */\nfunction correctColor(color) {\n if (color == null)\n return 'rgb(100,100,100)';\n const dgColor = DG.Color.fromHtml(color);\n const g = DG.Color.g(dgColor);\n const r = DG.Color.r(dgColor);\n const b = DG.Color.b(dgColor);\n // calculate euclidean distance to white\n const distToBlack = Math.sqrt(Math.pow(0 - r, 2) + Math.pow(0 - g, 2) + Math.pow(0 - b, 2));\n // normalize vector r g b\n const normR = r / distToBlack;\n const normG = g / distToBlack;\n const normB = b / distToBlack;\n if (distToBlack > 210) {\n return `rgb(${normR * 210},${normG * 210},${normB * 210})`;\n }\n return DG.Color.toRgb(dgColor);\n}\nexport class StringUtils {\n static hashCode(s) {\n let hash = 0;\n if (s.length === 0)\n return hash;\n for (let i = 0; i < s.length; i++) {\n const chr = s.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n }\n}\nimport { SeqPaletteBase } from './seq-palettes';\nexport class UnknownSeqPalette {\n}\nexport class GrayAllPalette extends UnknownSeqPalette {\n get(m) {\n return '#666666';\n }\n}\nexport class UnknownColorPalette extends UnknownSeqPalette {\n static buildPalette() {\n const res = [].concat(...Object.values(SeqPaletteBase.colourPalette));\n return res;\n }\n get(m) {\n const hash = StringUtils.hashCode(m);\n const pI = hash % UnknownColorPalette.palette.length;\n return correctColor(UnknownColorPalette.palette[pI]);\n }\n}\nUnknownColorPalette.palette = UnknownColorPalette.buildPalette();\nexport class UnknownSeqPalettes extends SeqPaletteBase {\n static get Gray() {\n if (this.gray === void 0)\n this.gray = new GrayAllPalette();\n return this.gray;\n }\n static get Color() {\n if (this.color === void 0)\n this.color = new UnknownColorPalette();\n return this.color;\n }\n}\n//# sourceMappingURL=unknown.js.map","const peq = new Uint32Array(0x10000);\nconst myers_32 = (a, b) => {\n const n = a.length;\n const m = b.length;\n const lst = 1 << (n - 1);\n let pv = -1;\n let mv = 0;\n let sc = n;\n let i = n;\n while (i--) {\n peq[a.charCodeAt(i)] |= 1 << i;\n }\n for (i = 0; i < m; i++) {\n let eq = peq[b.charCodeAt(i)];\n const xv = eq | mv;\n eq |= ((eq & pv) + pv) ^ pv;\n mv |= ~(eq | pv);\n pv &= eq;\n if (mv & lst) {\n sc++;\n }\n if (pv & lst) {\n sc--;\n }\n mv = (mv << 1) | 1;\n pv = (pv << 1) | ~(xv | mv);\n mv &= xv;\n }\n i = n;\n while (i--) {\n peq[a.charCodeAt(i)] = 0;\n }\n return sc;\n};\nconst myers_x = (b, a) => {\n const n = a.length;\n const m = b.length;\n const mhc = [];\n const phc = [];\n const hsize = Math.ceil(n / 32);\n const vsize = Math.ceil(m / 32);\n for (let i = 0; i < hsize; i++) {\n phc[i] = -1;\n mhc[i] = 0;\n }\n let j = 0;\n for (; j < vsize - 1; j++) {\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n }\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m - start) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n let score = m;\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n score += (ph >>> (m - 1)) & 1;\n score -= (mh >>> (m - 1)) & 1;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n return score;\n};\nconst distance = (a, b) => {\n if (a.length < b.length) {\n const tmp = b;\n b = a;\n a = tmp;\n }\n if (b.length === 0) {\n return a.length;\n }\n if (a.length <= 32) {\n return myers_32(a, b);\n }\n return myers_x(a, b);\n};\nconst closest = (str, arr) => {\n let min_distance = Infinity;\n let min_index = 0;\n for (let i = 0; i < arr.length; i++) {\n const dist = distance(str, arr[i]);\n if (dist < min_distance) {\n min_distance = dist;\n min_index = i;\n }\n }\n return arr[min_index];\n};\nexport { closest, distance };\n","import { hamming } from './hamming';\nimport { levenstein } from './levenstein';\nimport { needlemanWunch } from './needleman-wunsch';\n/** Enum containing currently supported macromolecule distance functions\n * Hamming distance will be used if the sequences are already aligned\n * Needleman distance will be used for protein sequences with known BLOSUM62 matrix\n * Levenshtein distance will be used for nucleotide sequences as for them substitution matrix is same as identity matrix\n */\nexport var MmDistanceFunctionsNames;\n(function (MmDistanceFunctionsNames) {\n MmDistanceFunctionsNames[\"HAMMING\"] = \"Hamming\";\n MmDistanceFunctionsNames[\"LEVENSHTEIN\"] = \"Levenshtein\";\n MmDistanceFunctionsNames[\"NEEDLEMANN_WUNSCH\"] = \"Needlemann-Wunsch\";\n})(MmDistanceFunctionsNames || (MmDistanceFunctionsNames = {}));\n;\nexport const mmDistanceFunctions = {\n [MmDistanceFunctionsNames.HAMMING]: hamming,\n [MmDistanceFunctionsNames.LEVENSHTEIN]: levenstein,\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: needlemanWunch\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBR2xEOzs7O0dBSUc7QUFDSCxNQUFNLENBQU4sSUFBWSx3QkFJWDtBQUpELFdBQVksd0JBQXdCO0lBQ2hDLCtDQUFtQixDQUFBO0lBQ25CLHVEQUEyQixDQUFBO0lBQzNCLG1FQUF1QyxDQUFBO0FBQzNDLENBQUMsRUFKVyx3QkFBd0IsS0FBeEIsd0JBQXdCLFFBSW5DO0FBQUEsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUE4RTtJQUM1RyxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU87SUFDM0MsQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxVQUFVO0lBQ2xELENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsRUFBRSxjQUFjO0NBQzdELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhbW1pbmd9IGZyb20gJy4vaGFtbWluZyc7XG5pbXBvcnQge2xldmVuc3RlaW59IGZyb20gJy4vbGV2ZW5zdGVpbic7XG5pbXBvcnQge25lZWRsZW1hbld1bmNofSBmcm9tICcuL25lZWRsZW1hbi13dW5zY2gnO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuLyoqIEVudW0gY29udGFpbmluZyBjdXJyZW50bHkgc3VwcG9ydGVkIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2UgZnVuY3Rpb25zXG4gKiBIYW1taW5nIGRpc3RhbmNlIHdpbGwgYmUgdXNlZCBpZiB0aGUgc2VxdWVuY2VzIGFyZSBhbHJlYWR5IGFsaWduZWRcbiAqIE5lZWRsZW1hbiBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgZm9yIHByb3RlaW4gc2VxdWVuY2VzIHdpdGgga25vd24gQkxPU1VNNjIgbWF0cml4XG4gKiBMZXZlbnNodGVpbiBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgZm9yIG51Y2xlb3RpZGUgc2VxdWVuY2VzIGFzIGZvciB0aGVtIHN1YnN0aXR1dGlvbiBtYXRyaXggaXMgc2FtZSBhcyBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGVudW0gTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzIHtcbiAgICBIQU1NSU5HID0gJ0hhbW1pbmcnLFxuICAgIExFVkVOU0hURUlOID0gJ0xldmVuc2h0ZWluJyxcbiAgICBORUVETEVNQU5OX1dVTlNDSCA9ICdOZWVkbGVtYW5uLVd1bnNjaCdcbn07XG5cbmV4cG9ydCBjb25zdCBtbURpc3RhbmNlRnVuY3Rpb25zOiBSZWNvcmQ8TW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLCAodmFsdWU/OiBhbnkpID0+IG1tRGlzdGFuY2VGdW5jdGlvblR5cGU+ID0ge1xuICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddOiBoYW1taW5nLFxuICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkxFVkVOU0hURUlOXTogbGV2ZW5zdGVpbixcbiAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF06IG5lZWRsZW1hbld1bmNoXG59O1xuIl19","import * as DG from 'datagrok-api/dg';\nimport wu from 'wu';\nimport { NOTATION, candidateAlphabets, positionSeparator } from './macromolecule';\nimport { detectAlphabet, getSplitterForColumn, getSplitterWithSeparator, splitterAsFasta, splitterAsFastaSimple, splitterAsHelm } from './macromolecule/utils';\nimport { mmDistanceFunctions, MmDistanceFunctionsNames } from '@datagrok-libraries/ml/src/macromolecule-distance-functions';\nimport { getMonomerLibHelper } from '../monomer-works/monomer-utils';\nexport const Tags = new class {\n constructor() {\n /** Column's temp slot name for a UnitsHandler object */\n this.uhTemp = `units-handler.${DG.SEMTYPE.MACROMOLECULE}`;\n }\n}();\nexport const GapSymbols = {\n [NOTATION.FASTA]: '-',\n [NOTATION.SEPARATOR]: '',\n [NOTATION.HELM]: '*',\n};\n/** Class for handling notation units in Macromolecule columns and\n * conversion of notation systems in Macromolecule columns\n */\nexport class UnitsHandler {\n static setUnitsToFastaColumn(uh) {\n if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.getTag(DG.TAGS.UNITS) !== NOTATION.FASTA)\n throw new Error(`The column of notation '${NOTATION.FASTA}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);\n uh.column.setTag(DG.TAGS.UNITS, NOTATION.FASTA);\n UnitsHandler.setTags(uh);\n }\n static setUnitsToSeparatorColumn(uh, separator) {\n if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.getTag(DG.TAGS.UNITS) !== NOTATION.SEPARATOR)\n throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);\n if (!separator)\n throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must have the separator tag.`);\n uh.column.setTag(DG.TAGS.UNITS, NOTATION.SEPARATOR);\n uh.column.setTag(\"separator\" /* TAGS.separator */, separator);\n UnitsHandler.setTags(uh);\n }\n static setUnitsToHelmColumn(uh) {\n if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE)\n throw new Error(`The column of notation '${NOTATION.HELM}' must be '${DG.SEMTYPE.MACROMOLECULE}'`);\n uh.column.setTag(DG.TAGS.UNITS, NOTATION.HELM);\n UnitsHandler.setTags(uh);\n }\n /** From detectMacromolecule */\n static setTags(uh) {\n const units = uh.column.getTag(DG.TAGS.UNITS);\n const stats = uh.stats;\n const alphabetIsMultichar = Object.keys(stats.freq).some((m) => m.length > 1);\n if ([NOTATION.FASTA, NOTATION.SEPARATOR].includes(units)) {\n // Empty monomer alphabet is not allowed\n if (Object.keys(stats.freq).length === 0)\n throw new Error('Alphabet is empty');\n const aligned = stats.sameLength ? \"SEQ.MSA\" /* ALIGNMENT.SEQ_MSA */ : \"SEQ\" /* ALIGNMENT.SEQ */;\n uh.column.setTag(\"aligned\" /* TAGS.aligned */, aligned);\n const alphabet = detectAlphabet(stats.freq, candidateAlphabets);\n uh.column.setTag(\"alphabet\" /* TAGS.alphabet */, alphabet);\n if (alphabet === \"UN\" /* ALPHABET.UN */) {\n const alphabetSize = Object.keys(stats.freq).length;\n const alphabetIsMultichar = Object.keys(stats.freq).some((m) => m.length > 1);\n uh.column.setTag(\".alphabetSize\" /* TAGS.alphabetSize */, alphabetSize.toString());\n uh.column.setTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */, alphabetIsMultichar ? 'true' : 'false');\n }\n }\n }\n get column() { return this._column; }\n get units() { return this._units; }\n get notation() { return this._notation; }\n get defaultGapSymbol() { return this._defaultGapSymbol; }\n get separator() {\n const separator = this.column.getTag(\"separator\" /* TAGS.separator */) ?? undefined;\n if (this.notation === NOTATION.SEPARATOR && separator === undefined)\n throw new Error(`Separator is mandatory for column '${this.column.name}' of notation '${this.notation}'.`);\n return separator;\n }\n get aligned() {\n const aligned = this.column.getTag(\"aligned\" /* TAGS.aligned */);\n // TAGS.aligned is mandatory for columns of NOTATION.FASTA and NOTATION.SEPARATOR\n if (!aligned && (this.isFasta() || this.isSeparator()))\n throw new Error('Tag aligned not set');\n return aligned;\n }\n /** Alphabet name (upper case) */\n get alphabet() {\n const alphabet = this.column.getTag(\"alphabet\" /* TAGS.alphabet */);\n // TAGS.alphabet is mandatory for columns of NOTATION.FASTA and NOTATION.SEPARATOR\n if (!alphabet && (this.isFasta() || this.isSeparator()))\n throw new Error('Tag alphabet not set');\n return alphabet;\n }\n get helmCompatible() {\n return this.column.getTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */);\n }\n getAlphabetSize() {\n if (this.notation == NOTATION.HELM || this.alphabet == \"UN\" /* ALPHABET.UN */) {\n const alphabetSizeStr = this.column.getTag(\".alphabetSize\" /* TAGS.alphabetSize */);\n let alphabetSize;\n if (alphabetSizeStr)\n alphabetSize = parseInt(alphabetSizeStr);\n else {\n // calculate alphabetSize on demand\n const stats = this.stats;\n alphabetSize = Object.keys(stats.freq).length;\n }\n return alphabetSize;\n }\n else {\n switch (this.alphabet) {\n case \"PT\" /* ALPHABET.PT */:\n return 20;\n case \"DNA\" /* ALPHABET.DNA */:\n case \"RNA\" /* ALPHABET.RNA */:\n return 4;\n case 'NT':\n console.warn(`Unexpected alphabet 'NT'.`);\n return 4;\n default:\n throw new Error(`Unexpected alphabet '${this.alphabet}'.`);\n }\n }\n }\n getAlphabetIsMultichar() {\n if (this.notation === NOTATION.HELM)\n return true;\n else if (this.alphabet !== \"UN\" /* ALPHABET.UN */)\n return false;\n else\n return this.column.getTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */) === 'true';\n }\n /** */\n get splitted() {\n if (this._splitted === null) {\n const splitter = this.getSplitter();\n const colLength = this._column.length;\n this._splitted = new Array(colLength);\n const catIdxList = this._column.getRawData();\n const catList = this._column.categories;\n for (let rowI = 0; rowI < colLength; rowI++) {\n const seq = catList[catIdxList[rowI]];\n this._splitted[rowI] = splitter(seq);\n }\n }\n return this._splitted;\n }\n get stats() {\n if (this._stats === null) {\n const freq = {};\n let sameLength = true;\n let firstLength = null;\n for (const mSeq of this.splitted) {\n if (firstLength == null)\n firstLength = mSeq.length;\n else if (mSeq.length !== firstLength)\n sameLength = false;\n for (const m of mSeq) {\n if (!(m in freq))\n freq[m] = 0;\n freq[m] += 1;\n }\n }\n this._stats = { freq: freq, sameLength: sameLength };\n }\n return this._stats;\n }\n get maxLength() {\n if (this._maxLength === null)\n this._maxLength = Math.max(...this.splitted.map((seqS) => seqS.length));\n return this._maxLength;\n }\n get posList() {\n if (this._posList === null) {\n const posListTxt = this.column.getTag(\".positionNames\" /* TAGS.positionNames */);\n this._posList = posListTxt ? posListTxt.split(positionSeparator).map((p) => p.trim()) :\n wu.count(1).take(this.maxLength).map((pos) => pos.toString()).toArray();\n }\n return this._posList;\n }\n isFasta() { return this.notation === NOTATION.FASTA; }\n isSeparator() { return this.notation === NOTATION.SEPARATOR; }\n isHelm() { return this.notation === NOTATION.HELM; }\n isRna() { return this.alphabet === \"RNA\" /* ALPHABET.RNA */; }\n isDna() { return this.alphabet === \"DNA\" /* ALPHABET.DNA */; }\n isPeptide() { return this.alphabet === \"PT\" /* ALPHABET.PT */; }\n isMsa() { return this.aligned ? this.aligned.toUpperCase().includes('MSA') : false; }\n isHelmCompatible() { return this.helmCompatible === 'true'; }\n isGap(m) {\n return !m || (this.units === NOTATION.FASTA && m === GapSymbols[NOTATION.FASTA]) ||\n (this.units === NOTATION.HELM && m === GapSymbols[NOTATION.HELM]);\n }\n /** Associate notation types with the corresponding units */\n /**\n * @return {NOTATION} Notation associated with the units type\n */\n getNotation() {\n if (this.units.toLowerCase().startsWith(NOTATION.FASTA))\n return NOTATION.FASTA;\n else if (this.units.toLowerCase().startsWith(NOTATION.SEPARATOR))\n return NOTATION.SEPARATOR;\n else if (this.units.toLowerCase().startsWith(NOTATION.HELM))\n return NOTATION.HELM;\n else\n throw new Error(`Column '${this.column.name}' has unexpected notation '${this.units}'.`);\n }\n /**\n * Get the wrapper strings for HELM, depending on the type of the\n * macromolecule (peptide, DNA, RNA)\n *\n * @return {string[]} Array of wrappers\n */\n getHelmWrappers() {\n const prefix = (this.isDna()) ? 'DNA1{' :\n (this.isRna() || this.isHelmCompatible()) ? 'RNA1{' : 'PEPTIDE1{';\n const postfix = '}$$$$';\n const leftWrapper = (this.isDna()) ? 'D(' :\n (this.isRna()) ? 'R(' : ''; // no wrapper for peptides\n const rightWrapper = (this.isDna() || this.isRna()) ? ')P' : ''; // no wrapper for peptides\n return [prefix, leftWrapper, rightWrapper, postfix];\n }\n /**\n * Create a new empty column of the specified notation type and the same\n * length as column\n *\n * @param {NOTATION} tgtNotation\n * @return {DG.Column}\n */\n getNewColumn(tgtNotation, tgtSeparator) {\n const col = this.column;\n const len = col.length;\n const name = tgtNotation.toLowerCase() + '(' + col.name + ')';\n const newColName = col.dataFrame.columns.getUnusedName(name);\n const newColumn = DG.Column.fromList('string', newColName, new Array(len).fill(''));\n newColumn.semType = DG.SEMTYPE.MACROMOLECULE;\n newColumn.setTag(DG.TAGS.UNITS, tgtNotation);\n if (tgtNotation === NOTATION.SEPARATOR) {\n if (!tgtSeparator)\n throw new Error(`Notation \\'${NOTATION.SEPARATOR}\\' requires separator value.`);\n newColumn.setTag(\"separator\" /* TAGS.separator */, tgtSeparator);\n }\n newColumn.setTag(DG.TAGS.CELL_RENDERER, 'Macromolecule'); // cell.renderer\n const srcAligned = col.getTag(\"aligned\" /* TAGS.aligned */);\n if (srcAligned)\n newColumn.setTag(\"aligned\" /* TAGS.aligned */, srcAligned);\n const srcAlphabet = col.getTag(\"alphabet\" /* TAGS.alphabet */);\n if (srcAlphabet != null)\n newColumn.setTag(\"alphabet\" /* TAGS.alphabet */, srcAlphabet);\n let srcAlphabetSize = col.getTag(\".alphabetSize\" /* TAGS.alphabetSize */);\n if (srcAlphabet != null && srcAlphabetSize)\n newColumn.setTag(\".alphabetSize\" /* TAGS.alphabetSize */, srcAlphabetSize);\n const srcAlphabetIsMultichar = col.getTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */);\n if (srcAlphabet != null && srcAlphabetIsMultichar !== undefined)\n newColumn.setTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */, srcAlphabetIsMultichar);\n if (tgtNotation == NOTATION.HELM) {\n srcAlphabetSize = this.getAlphabetSize().toString();\n newColumn.setTag(\".alphabetSize\" /* TAGS.alphabetSize */, srcAlphabetSize);\n }\n return newColumn;\n }\n /**\n * Create a new empty column using templateCol as a template\n *\n * @param {DG.Column} templateCol the properties and units of this column are used as a\n * template to build the new one\n * @return {DG.Column}\n */\n static getNewColumn(templateCol) {\n const col = UnitsHandler.getOrCreate(templateCol);\n const targetNotation = col.notation;\n return col.getNewColumn(targetNotation);\n }\n /**\n * A helper function checking the validity of the 'units' string\n *\n * @param {string} units the string to be validated\n * @return {boolean}\n */\n static unitsStringIsValid(units) {\n units = units.toLowerCase();\n const prefixes = [NOTATION.FASTA, NOTATION.SEPARATOR, NOTATION.HELM];\n const postfixes = ['rna', 'dna', 'pt'];\n const prefixCriterion = prefixes.some((p) => units.startsWith(p.toLowerCase()));\n return prefixCriterion;\n }\n /**\n * Construct a new column of semantic type MACROMOLECULE from the list of\n * specified parameters\n *\n * @param {number} len the length of the new column\n * @param {string} name the name of the new column\n * @param {string} units the units of the new column\n * @return {DG.Column}\n */\n static getNewColumnFromParams(len, name, units) {\n // WARNING: in this implementation is is impossible to verify the uniqueness\n // of the new column's name\n // TODO: verify the validity of units parameter\n if (!UnitsHandler.unitsStringIsValid(units))\n throw new Error('Invalid format of \\'units\\' parameter');\n const newColumn = DG.Column.fromList('string', name, new Array(len).fill(''));\n newColumn.semType = DG.SEMTYPE.MACROMOLECULE;\n newColumn.setTag(DG.TAGS.UNITS, units);\n return newColumn;\n }\n /** Gets function to split seq value to monomers */\n getSplitter(limit) {\n if (this.units.toLowerCase().startsWith(NOTATION.FASTA)) {\n const alphabet = this.column.getTag(\"alphabet\" /* TAGS.alphabet */);\n if (alphabet !== null && !this.getAlphabetIsMultichar())\n return splitterAsFastaSimple;\n else\n return splitterAsFasta;\n }\n else if (this.units.toLowerCase().startsWith(NOTATION.SEPARATOR))\n return getSplitterWithSeparator(this.separator, limit);\n else if (this.units.toLowerCase().startsWith(NOTATION.HELM))\n return splitterAsHelm;\n else\n throw new Error(`Unexpected units ${this.units} .`);\n // TODO: Splitter for HELM\n }\n getDistanceFunctionName() {\n // TODO add support for helm and separator notation\n if (!this.isFasta())\n throw new Error('Only FASTA notation is supported');\n if (this.isMsa())\n return MmDistanceFunctionsNames.HAMMING;\n switch (this.alphabet) {\n // As DNA and RNA scoring matrices are same as identity matrices(mostly),\n // we can use very fast and optimized Levenshtein distance library\n case \"DNA\" /* ALPHABET.DNA */:\n case \"RNA\" /* ALPHABET.RNA */:\n return MmDistanceFunctionsNames.LEVENSHTEIN;\n case \"PT\" /* ALPHABET.PT */:\n return MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH;\n // For default case, let's use Levenshtein distance\n default:\n return MmDistanceFunctionsNames.LEVENSHTEIN;\n }\n }\n getDistanceFunction() {\n return mmDistanceFunctions[this.getDistanceFunctionName()]();\n }\n // checks if the separator notation is compatible with helm library\n async checkHelmCompatibility() {\n // check first for the column tag to avoid extra processing\n if (this.column.tags.has(\".isHelmCompatible\" /* TAGS.isHelmCompatible */))\n return this.column.getTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */) === 'true';\n // get the monolmer lib and check against the column\n const monomerLibHelper = await getMonomerLibHelper();\n const bioLib = monomerLibHelper.getBioLib();\n // retrieve peptides\n const peptides = bioLib.getMonomerSymbolsByType(\"PEPTIDE\" /* HELM_POLYMER_TYPE.PEPTIDE */.toString());\n // convert the peptides list to a set for faster lookup\n const peptidesSet = new Set(peptides);\n // get splitter for given separator and check if all monomers are in the lib\n const splitterFunc = getSplitterWithSeparator(this.separator);\n // iterate over the columns, split them and check if all monomers are in the lib\n //TODO maybe add missing threshhold so that if there are not too many missing monomers\n // the column is still considered helm compatible\n for (const row of this.column.categories) {\n const monomers = splitterFunc(row);\n for (const monomer of monomers) {\n if (!peptidesSet.has(monomer)) {\n this.column.setTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */, 'false');\n return false;\n }\n }\n }\n this.column.setTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */, 'true');\n return true;\n }\n // -- Notation Converter --\n get splitter() {\n if (this._splitter === null)\n this._splitter = getSplitterForColumn(this.column);\n return this._splitter;\n }\n toFasta(targetNotation) { return targetNotation === NOTATION.FASTA; }\n toSeparator(targetNotation) { return targetNotation === NOTATION.SEPARATOR; }\n toHelm(targetNotation) { return targetNotation === NOTATION.HELM; }\n /**\n * Convert HELM string to FASTA/SEPARATOR\n *\n * @param {string} helmPolymer A string to be converted\n * @param {string} tgtNotation Target notation: FASTA or SEPARATOR\n * @param {string} tgtSeparator Optional target separator (for HELM ->\n * @param {string | null} tgtGapSymbol Optional target gap symbol\n * SEPARATOR)\n * @return {string} Converted string\n */\n convertHelmToFastaSeparator(helmPolymer, tgtNotation, tgtSeparator, tgtGapSymbol) {\n if (!tgtGapSymbol) {\n tgtGapSymbol = (this.toFasta(tgtNotation)) ?\n GapSymbols[NOTATION.FASTA] :\n GapSymbols[NOTATION.SEPARATOR];\n }\n if (!tgtSeparator)\n tgtSeparator = (this.toFasta(tgtNotation)) ? '' : this.separator;\n const helmWrappersRe = /(R\\(|D\\(|\\)|P)/g;\n const isNucleotide = helmPolymer.startsWith('DNA') || helmPolymer.startsWith('RNA');\n // items can be monomers or helms\n const helmItemsArray = this.splitter(helmPolymer);\n const tgtMonomersArray = [];\n for (let i = 0; i < helmItemsArray.length; i++) {\n let item = helmItemsArray[i];\n if (isNucleotide)\n item = item.replace(helmWrappersRe, '');\n if (item === GapSymbols[NOTATION.HELM])\n tgtMonomersArray.push(tgtGapSymbol);\n else if (this.toFasta(tgtNotation) && item.length > 1) {\n // the case of a multi-character monomer converted to FASTA\n const monomer = '[' + item + ']';\n tgtMonomersArray.push(monomer);\n }\n else\n tgtMonomersArray.push(item);\n }\n return tgtMonomersArray.join(tgtSeparator);\n }\n /** Dispatcher method for notation conversion\n *\n * @param {NOTATION} tgtNotation Notation we want to convert to\n * @param {string | null} tgtSeparator Possible separator\n * @return {DG.Column} Converted column\n */\n convert(tgtNotation, tgtSeparator) {\n const convert = this.getConverter(tgtNotation, tgtSeparator);\n const newColumn = this.getNewColumn(tgtNotation, tgtSeparator);\n // assign the values to the newly created empty column\n newColumn.init((rowI) => { return convert(this.column.get(rowI)); });\n // newColumn.setTag(DG.TAGS.UNITS, NOTATION.SEPARATOR);\n return newColumn;\n }\n /**\n * @param name\n * @param startIdx Start position index of the region (0-based)\n * @param endIdx End position index of the region (0-based, inclusive)\n */\n getRegion(startIdx, endIdx, name) {\n const regCol = this.getNewColumn(this.notation, this.separator);\n regCol.name = name;\n const maxLength = Math.max(...this.splitted.map((seqS) => seqS.length));\n const startIdxVal = startIdx ?? 0;\n const endIdxVal = endIdx ?? this.maxLength - 1;\n const join = this.getJoiner();\n const regLength = endIdxVal - startIdxVal + 1;\n regCol.init((rowI) => {\n const seqS = this.splitted[rowI];\n // Custom slicing instead of array method to maintain gaps\n const regMList = new Array(regLength);\n for (let regJPos = 0; regJPos < regLength; ++regJPos) {\n const seqJPos = startIdxVal + regJPos;\n regMList[regJPos] = seqJPos < seqS.length ? seqS[seqJPos] : GapSymbols[this.notation];\n }\n return join(regMList);\n });\n const getRegionOfPositionNames = (str) => {\n const srcPosList = str.split(',').map((p) => p.trim());\n const regPosList = new Array(regLength);\n for (let regJPos = 0; regJPos < regLength; ++regJPos) {\n const srcJPos = startIdxVal + regJPos;\n regPosList[regJPos] = srcJPos < srcPosList.length ? srcPosList[srcJPos] : '?';\n }\n return regPosList.join(positionSeparator);\n };\n const srcPositionNamesStr = this.column.getTag(\".positionNames\" /* TAGS.positionNames */);\n if (srcPositionNamesStr)\n regCol.setTag(\".positionNames\" /* TAGS.positionNames */, getRegionOfPositionNames(srcPositionNamesStr));\n const srcPositionLabelsStr = this.column.getTag(\".positionLabels\" /* TAGS.positionLabels */);\n if (srcPositionLabelsStr)\n regCol.setTag(\".positionLabels\" /* TAGS.positionLabels */, getRegionOfPositionNames(srcPositionLabelsStr));\n return regCol;\n }\n getJoiner() {\n const srcUh = this;\n if (this.notation === NOTATION.FASTA)\n return function (srcS) { return joinToFasta(srcUh, srcS); };\n else if (this.notation === NOTATION.SEPARATOR)\n return function (srcS) { return joinToSeparator(srcUh, srcS, srcUh.separator); };\n else if (this.notation === NOTATION.HELM) {\n const isDnaOrRna = srcUh.alphabet === \"DNA\" /* ALPHABET.DNA */ || srcUh.alphabet === \"RNA\" /* ALPHABET.RNA */;\n return function (srcS) { return joinToHelm(srcUh, srcS, isDnaOrRna); };\n }\n else\n throw new Error();\n }\n getConverter(tgtUnits, tgtSeparator = undefined) {\n if (tgtUnits === NOTATION.SEPARATOR && !tgtSeparator)\n throw new Error(`Target separator is not specified for target units '${NOTATION.SEPARATOR}'.`);\n const srcUh = this;\n if (tgtUnits === NOTATION.FASTA)\n return function (src) { return convertToFasta(srcUh, src); };\n if (tgtUnits === NOTATION.HELM)\n return function (src) { return convertToHelm(srcUh, src); };\n else if (tgtUnits === NOTATION.SEPARATOR)\n return function (src) { return convertToSeparator(srcUh, src, tgtSeparator); };\n else\n throw new Error();\n }\n constructor(col) {\n this._splitter = null;\n this._splitted = null;\n this._stats = null;\n this._maxLength = null;\n this._posList = null;\n if (col.type != DG.TYPE.STRING)\n throw new Error(`Unexpected column type '${col.type}', must be '${DG.TYPE.STRING}'.`);\n this._column = col;\n const units = this._column.getTag(DG.TAGS.UNITS);\n if (units !== null && units !== undefined)\n this._units = units;\n else\n throw new Error('Units are not specified in column');\n this._notation = this.getNotation();\n this._defaultGapSymbol = (this.isFasta()) ? GapSymbols[NOTATION.FASTA] :\n (this.isHelm()) ? GapSymbols[NOTATION.HELM] :\n GapSymbols[NOTATION.SEPARATOR];\n if (!this.column.tags.has(\"aligned\" /* TAGS.aligned */) || !this.column.tags.has(\"alphabet\" /* TAGS.alphabet */) ||\n (!this.column.tags.has(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */) && !this.isHelm() && this.alphabet === \"UN\" /* ALPHABET.UN */)) {\n // The following detectors and setters are to be called because the column is likely\n // as the UnitsHandler constructor was called on the column.\n if (this.isFasta())\n UnitsHandler.setUnitsToFastaColumn(this);\n else if (this.isSeparator()) {\n const separator = col.getTag(\"separator\" /* TAGS.separator */);\n UnitsHandler.setUnitsToSeparatorColumn(this, separator);\n }\n else if (this.isHelm())\n UnitsHandler.setUnitsToHelmColumn(this);\n else\n throw new Error(`Unexpected units '${this.column.getTag(DG.TAGS.UNITS)}'.`);\n }\n // if (!this.column.tags.has(TAGS.alphabetSize)) {\n // if (this.isHelm())\n // throw new Error(`For column '${this.column.name}' of notation '${this.notation}' ` +\n // `tag '${TAGS.alphabetSize}' is mandatory.`);\n // else if (['UN'].includes(this.alphabet))\n // throw new Error(`For column '${this.column.name}' of alphabet '${this.alphabet}' ` +\n // `tag '${TAGS.alphabetSize}' is mandatory.`);\n // }\n if (!this.column.tags.has(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */)) {\n if (this.isHelm())\n this.column.setTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */, 'true');\n else if (['UN'].includes(this.alphabet)) {\n throw new Error(`For column '${this.column.name}' of alphabet '${this.alphabet}' ` +\n `tag '${\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */}' is mandatory.`);\n }\n }\n }\n /** Gets a column's UnitsHandler object from temp slot or creates a new and stores it to the temp slot. */\n static getOrCreate(col) {\n if (!(Tags.uhTemp in col.temp))\n col.temp[Tags.uhTemp] = new UnitsHandler(col);\n return col.temp[Tags.uhTemp];\n }\n}\nconst helmWrappersRe = /[RD]\\((\\w)\\)P?/g;\nfunction joinToFasta(srcUh, seqS) {\n const resMList = new Array(seqS.length);\n for (const [srcM, mI] of wu.enumerate(seqS)) {\n let m = srcM;\n if (srcUh.isHelm())\n m = srcM.replace(helmWrappersRe, '$1');\n if (srcUh.isGap(m))\n m = GapSymbols[NOTATION.FASTA];\n else if (m.length > 1)\n m = '[' + seqS[mI] + ']';\n resMList[mI] = m;\n }\n return resMList.join('');\n}\nfunction convertToFasta(srcUh, src) {\n const srcMList = srcUh.isHelm() ? splitterAsHelmNucl(srcUh, src) : srcUh.getSplitter()(src);\n return joinToFasta(srcUh, srcMList);\n}\nfunction joinToSeparator(srcUh, seqS, tgtSeparator) {\n const resMList = new Array(seqS.length);\n for (const [srcM, mI] of wu.enumerate(seqS)) {\n let m = srcM;\n if (srcUh.isGap(m))\n m = GapSymbols[NOTATION.SEPARATOR];\n resMList[mI] = m;\n }\n return resMList.map((m) => m ?? '').join(tgtSeparator);\n}\nfunction convertToSeparator(srcUh, src, tgtSeparator) {\n const srcMList = srcUh.isHelm() ? splitterAsHelmNucl(srcUh, src) : srcUh.getSplitter()(src);\n return joinToSeparator(srcUh, srcMList, tgtSeparator);\n}\nfunction joinToHelm(srcUh, seqS, isDnaOrRna) {\n const [prefix, leftWrapper, rightWrapper, postfix] = srcUh.getHelmWrappers();\n const resMList = wu(seqS).map((srcM) => {\n let m = srcM;\n if (srcUh.isGap(m))\n m = GapSymbols[NOTATION.HELM];\n else if (isDnaOrRna)\n m = m.replace(helmWrappersRe, '$1');\n else\n m = srcM.length == 1 ? `${leftWrapper}${srcM}${rightWrapper}` : `${leftWrapper}[${srcM}]${rightWrapper}`;\n return m;\n }).toArray();\n return `${prefix}${resMList.join('.')}${postfix}`;\n}\nfunction convertToHelm(srcUh, src) {\n const isDnaOrRna = src.startsWith('DNA') || src.startsWith('RNA');\n const srcS = srcUh.getSplitter()(src);\n return joinToHelm(srcUh, srcS, isDnaOrRna);\n}\n/** Splits Helm sequence adjusting nucleotides to single char symbols. (!) Removes lone phosphorus. */\nfunction splitterAsHelmNucl(srcUh, src) {\n const srcMList = srcUh.getSplitter()(src);\n const tgtMList = new Array(srcMList.length);\n const isDna = src.startsWith('DNA');\n const isRna = src.startsWith('RNA');\n for (const [srcM, mI] of wu.enumerate(srcMList)) {\n let m = srcM;\n if (isDna || isRna) {\n m = m.replace(helmWrappersRe, '$1');\n m = m === 'P' ? null : m;\n }\n tgtMList[mI] = m;\n }\n return tgtMList.filter((m) => m !== null);\n}\n//# sourceMappingURL=units-handler.js.map","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {ExternalPluginUI} from '../view/app-ui';\nimport {ColoredTextInput} from '../view/utils/colored-input/colored-text-input';\nimport {highlightInvalidSubsequence} from '../view/utils/colored-input/input-painters';\nimport {codesToSymbolsDictionary} from '../model/data-loading-utils/json-loader';\nimport {MERMADE} from './const';\n\nexport async function getExternalAppViewFactories(): Promise<{[name: string]: () => DG.View} | undefined> {\n const externalPluginData = {\n [MERMADE.FUNCTION_NAME]: {\n tabName: MERMADE.TAB_NAME,\n parameters: getMerMadeParameters()\n },\n }\n\n const result: {[tabName: string]: () => DG.View} = {};\n\n for (const [pluginName, data] of Object.entries(externalPluginData)) {\n let div: HTMLDivElement;\n try {\n div = await grok.functions.call(pluginName, data.parameters);\n const pluginUI = new ExternalPluginUI(data.tabName, div);\n\n // intentonally don't await for the promise\n pluginUI.initView();\n\n result[data.tabName] = () => pluginUI.getView();\n } catch (err) {\n console.warn(`Plugin ${pluginName} not loaded, reason:`, err)\n continue;\n }\n }\n return result;\n}\n\nfunction getMerMadeParameters(): {[name: string]: any} {\n const base = ui.textInput('', '');\n const input = new ColoredTextInput(base, highlightInvalidSubsequence);\n\n return {\n coloredInput: input,\n codes: codesToSymbolsDictionary\n }\n}\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {AppUIFactory, CombinedAppUI} from './view/app-ui';\nimport {tryCatch} from './model/helpers';\nimport {LIB_PATH, DEFAULT_LIB_FILENAME} from './model/data-loading-utils/const';\nimport {IMonomerLib} from '@datagrok-libraries/bio/src/types';\nimport {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';\nimport {getJsonData} from './model/data-loading-utils/json-loader';\nimport {SequenceToMolfileConverter} from './model/structure-app/sequence-to-molfile';\nimport {linkStrandsV3000} from './model/structure-app/mol-transformations';\nimport {MonomerLibWrapper} from './model/monomer-lib/lib-wrapper';\nimport {FormatDetector} from './model/parsing-validation/format-detector';\nimport {SequenceValidator} from './model/parsing-validation/sequence-validator';\nimport {demoOligoTranslatorUI, demoOligoPatternUI, demoOligoStructureUI} from './demo/demo-st-ui';\nimport {FormatConverter} from './model/translator-app/format-converter';\nimport {APP} from './view/const/ui';\nimport {getExternalAppViewFactories} from './plugins/mermade';\n\nclass StPackage extends DG.Package {\n private _monomerLib?: IMonomerLib;\n\n get monomerLib(): IMonomerLib {\n if (!this._monomerLib)\n throw new Error ('Monomer lib not loaded')\n return this._monomerLib!;\n }\n\n public async initMonomerLib(): Promise<void> {\n if (this._monomerLib !== undefined)\n return;\n\n const pi: DG.TaskBarProgressIndicator = DG.TaskBarProgressIndicator.create(\n `Initializing ${APP.COMBINED} monomer library ...`);\n await tryCatch(async () => {\n const libHelper: IMonomerLibHelper = await getMonomerLibHelper();\n this._monomerLib = await libHelper.readLibrary(LIB_PATH, DEFAULT_LIB_FILENAME);\n }, () => pi.close());\n }\n}\n\nexport const _package: StPackage = new StPackage();\n\nasync function buildLayout(appName: string): Promise<void> {\n await initSequenceTranslatorLibData();\n const appUI = AppUIFactory.getUI(appName);\n await appUI.createAppLayout();\n}\n\n\n//name: Oligo Toolkit\n//meta.icon: img/icons/toolkit.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoToolkitApp(): Promise<void> {\n await initSequenceTranslatorLibData();\n const externalViewFactories = await getExternalAppViewFactories();\n if (!externalViewFactories)\n throw new Error('External app view factories not loaded');\n const appUI = new CombinedAppUI(externalViewFactories!);\n await appUI.createAppLayout();\n}\n\n//name: Oligo Translator\n//meta.icon: img/icons/translator.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoTranslatorApp(): Promise<void> {\n await buildLayout(APP.TRANSLATOR);\n}\n\n//name: Oligo Pattern\n//meta.icon: img/icons/pattern.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoPatternApp(): Promise<void> {\n await buildLayout(APP.PATTERN);\n}\n\n//name: Oligo Structure\n//meta.icon: img/icons/structure.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoStructureApp(): Promise<void> {\n await buildLayout(APP.STRUCTRE);\n}\n\n//name: initSequenceTranslatorLibData\nexport async function initSequenceTranslatorLibData(): Promise<void> {\n await getJsonData();\n await _package.initMonomerLib();\n}\n\n//name: getCodeToWeightsMap\n//output: object result\nexport function getCodeToWeightsMap(): {[key: string]: number} {\n const map = MonomerLibWrapper.getInstance().getCodesToWeightsMap();\n return Object.fromEntries(map);\n}\n\n//name: validateSequence\n//input: string sequence\n//output: bool result\nexport function validateSequence(sequence: string): boolean {\n const validator = new SequenceValidator(sequence);\n const format = (new FormatDetector(sequence).getFormat());\n return (format === null) ? false : validator.isValidSequence(format!);\n}\n\n//name: validateSequence\n//input: string sequence\n//input: bool invert\n//output: string result\nexport function getMolfileFromGcrsSequence(sequence: string, invert: boolean): string {\n return (new SequenceToMolfileConverter(sequence, invert, 'GCRS')).convert();\n}\n\n//name: linkStrands\n//input: object strands\n//output: string result\nexport function linkStrands(strands: { senseStrands: string[], antiStrands: string[] }): string {\n return linkStrandsV3000(strands, true);\n}\n\n//name: demoOligoTranslator\n//meta.demoPath: Bioinformatics | Oligo Toolkit | Translator\n//description: Translate oligonucleotide sequences across various formats accepted by different synthesizers\n//meta.path: /apps/Tutorials/Demo/Bioinformatics/Oligonucleotide%20Sequence:%20Translate\nexport async function demoTranslateSequence(): Promise<void> {\n await demoOligoTranslatorUI();\n}\n\n//name: demoOligoPattern\n//meta.demoPath: Bioinformatics | Oligo Toolkit | Pattern\n//description: Design a modification pattern for an oligonucleotide sequence\n//meta.path:%20/apps/Tutorials/Demo/Bioinformatics/Oligonucleotide%20Sequence:%20Visualize%20duplex\nexport async function demoOligoPattern(): Promise<void> {\n await demoOligoPatternUI();\n}\n\n//name: demoOligoStructure\n//meta.demoPath: Bioinformatics | Oligo Toolkit | Structure\n//description: Visualize duplex and save SDF\n//meta.path:%20/apps/Tutorials/Demo/Bioinformatics/Oligonucleotide%20Sequence:%20Visualize%20duplex\nexport async function demoOligoStructure(): Promise<void> {\n await demoOligoStructureUI();\n}\n\n//name: translateOligonucleotideSequence\n//input: string sequence\n//input: string sourceFormat\n//input: string targetFormat\n//output: string result\nexport async function translateOligonucleotideSequence(sequence: string, sourceFormat: string, targetFormat: string): Promise<string> {\n await initSequenceTranslatorLibData();\n return (new FormatConverter(sequence, sourceFormat)).convertTo(targetFormat);\n}\n","// import * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport * as grok from 'datagrok-api/grok';\nimport { HELM_CORE_FIELDS, jsonSdfMonomerLibDict, MONOMER_ENCODE_MAX, MONOMER_ENCODE_MIN, SDF_MONOMER_NAME } from '../utils/const';\nimport { UnitsHandler } from '../utils/units-handler';\nimport { splitAlignedSequences } from '../utils/splitter';\nexport function encodeMonomers(col) {\n let encodeSymbol = MONOMER_ENCODE_MIN;\n const monomerSymbolDict = {};\n const uh = UnitsHandler.getOrCreate(col);\n const splitterFunc = uh.getSplitter();\n const encodedStringArray = [];\n for (let i = 0; i < col.length; ++i) {\n let encodedMonomerStr = '';\n const monomers = splitterFunc(col.get(i));\n for (const m of monomers) {\n if (!monomerSymbolDict[m]) {\n if (encodeSymbol > MONOMER_ENCODE_MAX) {\n grok.shell.error(`Not enough symbols to encode monomers`);\n return null;\n }\n monomerSymbolDict[m] = encodeSymbol;\n encodeSymbol++;\n }\n encodedMonomerStr += String.fromCodePoint(monomerSymbolDict[m]);\n }\n encodedStringArray.push(encodedMonomerStr);\n }\n return DG.Column.fromStrings('encodedMolecules', encodedStringArray);\n}\nexport function getMolfilesFromSeq(col, monomersLibObject) {\n const uh = UnitsHandler.getOrCreate(col);\n const splitter = uh.getSplitter();\n const monomersDict = createMomomersMolDict(monomersLibObject);\n const molFiles = [];\n for (let i = 0; i < col.length; ++i) {\n const macroMolecule = col.get(i);\n const monomers = splitter(macroMolecule);\n const molFilesForSeq = [];\n for (let j = 0; j < monomers.length; ++j) {\n if (monomers[j]) {\n if (!monomersDict[monomers[j]]) {\n grok.shell.warning(`Monomer ${monomers[j]} is missing in HELM library. Structure cannot be created`);\n return null;\n }\n // what is the reason of double conversion?\n molFilesForSeq.push(JSON.parse(JSON.stringify(monomersDict[monomers[j]])));\n }\n }\n molFiles.push(molFilesForSeq);\n }\n return molFiles;\n}\nexport function getMolfilesFromSingleSeq(cell, monomersLibObject) {\n const uh = UnitsHandler.getOrCreate(cell.column);\n const splitterFunc = uh.getSplitter();\n const monomersDict = createMomomersMolDict(monomersLibObject);\n const molFiles = [];\n const macroMolecule = cell.value;\n const monomers = splitterFunc(macroMolecule);\n const molFilesForSeq = [];\n for (let j = 0; j < monomers.length; ++j) {\n if (monomers[j]) {\n if (!monomersDict[monomers[j]]) {\n grok.shell.warning(`Monomer ${monomers[j]} is missing in HELM library. Structure cannot be created`);\n return null;\n }\n molFilesForSeq.push(JSON.parse(JSON.stringify(monomersDict[monomers[j]])));\n }\n }\n molFiles.push(molFilesForSeq);\n return molFiles;\n}\nexport function createMomomersMolDict(lib) {\n const dict = {};\n lib.forEach((it) => {\n if (it['polymerType'] === 'PEPTIDE') {\n const monomerObject = {};\n HELM_CORE_FIELDS.forEach((field) => {\n monomerObject[field] = it[field];\n });\n dict[it[\"symbol\" /* HELM_FIELDS.SYMBOL */]] = monomerObject;\n }\n });\n return dict;\n}\nexport function createJsonMonomerLibFromSdf(table) {\n const resultLib = [];\n for (let i = 0; i < table.rowCount; i++) {\n const monomer = {};\n Object.keys(jsonSdfMonomerLibDict).forEach((key) => {\n if (key === \"symbol\" /* HELM_FIELDS.SYMBOL */) {\n const monomerSymbol = table.get(jsonSdfMonomerLibDict[key], i);\n monomer[key] = monomerSymbol === '.' ? table.get(SDF_MONOMER_NAME, i) : monomerSymbol;\n }\n else if (key === \"rgroups\" /* HELM_FIELDS.RGROUPS */) {\n const rgroups = table.get(jsonSdfMonomerLibDict[key], i).split('\\n');\n const jsonRgroups = [];\n rgroups.forEach((g) => {\n const rgroup = {};\n const altAtom = g.substring(g.lastIndexOf(']') + 1);\n const radicalNum = g.match(/\\[R(\\d+)\\]/)[1];\n rgroup[\"capGroupSmiles\" /* HELM_RGROUP_FIELDS.CAP_GROUP_SMILES */] = altAtom === 'H' ? `[*:${radicalNum}][H]` : `O[*:${radicalNum}]`;\n rgroup[\"alternateId\" /* HELM_RGROUP_FIELDS.ALTERNATE_ID */] = altAtom === 'H' ? `R${radicalNum}-H` : `R${radicalNum}-OH`;\n rgroup[\"capGroupName\" /* HELM_RGROUP_FIELDS.CAP_GROUP_NAME */] = altAtom === 'H' ? `H` : `OH`;\n rgroup[\"label\" /* HELM_RGROUP_FIELDS.LABEL */] = `R${radicalNum}`;\n jsonRgroups.push(rgroup);\n });\n monomer[key] = jsonRgroups;\n }\n else {\n if (jsonSdfMonomerLibDict[key])\n monomer[key] = table.get(jsonSdfMonomerLibDict[key], i);\n }\n });\n resultLib.push(monomer);\n }\n return resultLib;\n}\nexport async function getMonomerLibHelper() {\n const funcList = DG.Func.find({ package: 'Bio', name: 'getMonomerLibHelper' });\n if (funcList.length === 0)\n throw new Error('Package \"Bio\" must be installed for MonomerLibHelper.');\n const res = (await funcList[0].prepare().call()).getOutputParamValue();\n return res;\n}\nexport async function sequenceChemSimilarity(positionColumns, referenceSequence) {\n if (positionColumns instanceof DG.Column)\n positionColumns = splitAlignedSequences(positionColumns).columns.toList();\n const libHelper = await getMonomerLibHelper();\n const monomerLib = libHelper.getBioLib();\n // const smilesCols: DG.Column<string>[] = new Array(monomerCols.length);\n const rawCols = new Array(positionColumns.length);\n const rowCount = positionColumns[0].length;\n const totalSimilarity = new Float32Array(rowCount);\n // Calculate base similarity\n for (let position = 0; position < positionColumns.length; ++position) {\n const referenceMonomer = referenceSequence[position];\n const referenceMol = monomerLib.getMonomer('PEPTIDE', referenceMonomer)?.smiles ?? '';\n const monomerCol = positionColumns[position];\n const monomerColData = monomerCol.getRawData();\n const monomerColCategories = monomerCol.categories;\n const emptyCategoryIdx = monomerColCategories.indexOf('');\n rawCols[position] = { categories: monomerColCategories, data: monomerColData, emptyIndex: emptyCategoryIdx };\n if (typeof referenceMonomer === 'undefined')\n continue;\n // Calculating similarity for \n const molCol = DG.Column.fromStrings('smiles', monomerColCategories.map((cat) => monomerLib.getMonomer('PEPTIDE', cat)?.smiles ?? ''));\n const _df = DG.DataFrame.fromColumns([molCol]); // getSimilarities expects that column is in dataframe\n const similarityCol = (await grok.chem.getSimilarities(molCol, referenceMol));\n const similarityColData = similarityCol.getRawData();\n for (let rowIdx = 0; rowIdx < rowCount; ++rowIdx) {\n const monomerCategoryIdx = monomerColData[rowIdx];\n totalSimilarity[rowIdx] += referenceMonomer !== '' && monomerCategoryIdx !== emptyCategoryIdx ?\n similarityColData[monomerCategoryIdx] :\n referenceMonomer === '' && monomerCategoryIdx === emptyCategoryIdx ? 1 : 0;\n }\n }\n for (let similarityIndex = 0; similarityIndex < totalSimilarity.length; ++similarityIndex) {\n let updatedSimilarity = totalSimilarity[similarityIndex] / referenceSequence.length;\n for (let position = 0; position < positionColumns.length; ++position) {\n const currentRawCol = rawCols[position];\n if ((position >= referenceSequence.length && currentRawCol.data[similarityIndex] !== currentRawCol.emptyIndex) ||\n (currentRawCol.data[similarityIndex] === currentRawCol.emptyIndex && position < referenceSequence.length)) {\n updatedSimilarity = DG.FLOAT_NULL;\n break;\n }\n }\n totalSimilarity[similarityIndex] = updatedSimilarity;\n }\n const similarityCol = DG.Column.fromFloat32Array('Similarity', totalSimilarity);\n return similarityCol;\n}\n//# sourceMappingURL=monomer-utils.js.map","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {delay} from '@datagrok-libraries/utils/src/test';\nimport {getJsonData} from '../model/data-loading-utils/json-loader';\nimport {_package, oligoTranslatorApp, oligoPatternApp, oligoStructureApp} from '../package';\nimport {tryCatch} from '../model/helpers';\n\nexport async function demoOligoTranslatorUI() {\n await tryCatch(async () => oligoTranslatorApp());\n}\n\nexport async function demoOligoPatternUI() {\n await tryCatch(async () => {\n async function emulateUserInput(value: string, idx: number, idxUpdate: (idx: number) => number): Promise<void> {\n await delay(3000);\n\n // warning: this redefinition is necessary because\n // the ids of the elements can dynamically change\n const choiceInputs: NodeListOf<HTMLSelectElement> = document.querySelectorAll('.st-pattern-choice-input > select');\n len = choiceInputs.length;\n const selectElement = choiceInputs[idxUpdate(idx)];\n selectElement.value = value;\n const event = new Event('input');\n selectElement.dispatchEvent(event);\n }\n\n await oligoPatternApp();\n\n let len: number;\n\n const ssNewValues = ['DNA', 'invAb', 'Z-New'];\n ssNewValues.forEach(async (value, idx) => {\n emulateUserInput(value, idx, (i) => 2 * i);\n });\n\n const asNewValues = ['2\\'-O-Methyl', '2\\'-Fluoro', '2\\'-O-MOE'];\n asNewValues.forEach(async (value, idx) => {\n emulateUserInput(value, idx, (i) => (len - 2 - 2 * i));\n });\n })\n}\n\nexport async function demoOligoStructureUI() {\n await tryCatch(async () => {\n async function setInputValue(idx: number, sequence: string): Promise<void> {\n await delay(500);\n const textInputs: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll('.colored-text-input > textarea');\n const textarea = textInputs[idx];\n textarea.value = sequence;\n const event = new Event('input');\n textarea.dispatchEvent(event);\n }\n await oligoStructureApp();\n const inputSequences = ['Afcgacsu', 'Afcgacsu', 'Afcgacsu'];\n inputSequences.forEach(async (sequence, idx) => {\n await setInputValue(idx, sequence);\n })\n });\n}\n","export const DEFAULT_INPUT = 'fAmCmGmAmCpsmU';\nexport const SEQUENCE_COPIED_MSG = 'Copied';\nexport const SEQ_TOOLTIP_MSG = 'Copy sequence';\n","export const enum TAB {\n TRANSLATOR = 'TRANSLATOR',\n PATTERN = 'PATTERN',\n STRUCTRE = 'STRUCTURE'\n}\n\nexport const enum APP {\n COMBINED = 'Oligo Toolkit',\n TRANSLATOR = 'Oligo Translator',\n PATTERN = 'Oligo Pattern',\n STRUCTRE = 'Oligo Structure',\n}\n\nexport const DEFAULT_AXOLABS_INPUT = 'Afcgacsu';\n","module.exports = DG;","module.exports = grok;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(593);\n"],"names":["ChemicalTableParserBase","constructor","fileContent","this","init","replace","_atomCount","undefined","_atomTypes","_bondCount","_bondTypes","xyzAtomCoordinates","_pairsOfBondedAtoms","atomCount","setAtomAndBondCounts","bondCount","x","_a","parseAtomCoordinates","y","z","atomTypes","parseAtomTypes","pairsOfBondedAtoms","parseBondedAtomPairs","bondTypes","parseBondTypes","parseAtomAndBondCounts","getNextColumnIdx","idx","isWhitespace","shiftIdxToSpecifiedColumn","lineStartIdx","columnNumber","numberOfJumps","i","Array","getAtomBlockIdx","shiftIdxToAtomType","parseAtomType","getNextLineIdx","Float32Array","shiftIdxToXColumn","item","parseFloatValue","bondedAtomPairs","getBondBlockIdx","shiftIdxToBondedAtomsPair","pair","Uint16Array","parseIntValue","shiftIdxToBondType","symbol","indexOf","idxOfNumber","parseNumericValue","parseFloat","parseInt","parserFunction","end","substring","MolfileHandlerBase","molfile","super","begin","isQuote","getNextIdenticalChar","letter","charCodeAt","sym","isQuery","isQueryOrFragment","char","charCode","isFragment","condition","MolfileV3KHandler","getCountsLineIdx","static","numOfAtoms","assure","delay","ms","thisArg","_arguments","generator","Promise","r","setTimeout","P","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","notNull","name","Error","errorToConsole","err","String","stack","message","toString","___CSS_LOADER_EXPORT___","push","module","id","exports","cssWithMappingToString","list","map","content","needLayer","concat","length","join","modules","media","dedupe","supports","layer","alreadyImportedModules","k","_k","cssMapping","btoa","base64","unescape","encodeURIComponent","JSON","stringify","data","sourceMapping","out$","window","default","xmlNs","svgNs","urlRegex","fontFormats","woff2","woff","otf","ttf","eot","sfnt","svg","isElement","obj","HTMLElement","SVGElement","requireDomNode","el","requireDomNodePromise","getDimension","clone","dim","v","viewBox","baseVal","getAttribute","match","getBoundingClientRect","style","getComputedStyle","getPropertyValue","isNaN","uriToBlob","uri","byteString","atob","split","mimeString","buffer","ArrayBuffer","intArray","Uint8Array","Blob","type","cachedFonts","cachedRules","inlineCss","options","_ref","selectorRemap","modifyStyle","modifyCss","fonts","excludeUnusedCss","generateCss","selector","properties","css","detectFonts","fontList","from","document","styleSheets","sheet","rules","cssRules","href","console","warn","forEach","_ref2","rule","querySelector","parentNode","query","selectorText","cssText","font","url","fontUrl","formats","fullUrl","startsWith","text","format","Object","keys","filter","extension","error","detectCssFont","all","req","XMLHttpRequest","addEventListener","fontInBase64","binary","bytes","byteLength","fromCharCode","arrayBufferToBase64","response","fontUri","open","responseType","send","fontCss","inlineFonts","downloadOptions","navigator","msSaveOrOpenBlob","createElement","popup","prepareSvg","_ref3","_ref3$left","left","_ref3$top","top","w","width","h","height","_ref3$scale","scale","_ref3$responsive","responsive","_ref3$excludeCss","excludeCss","querySelectorAll","image","getAttributeNS","lastIndexOf","location","host","Date","valueOf","canvas","img","Image","crossOrigin","src","onerror","onload","getContext","drawImage","setAttributeNS","toDataURL","inlineImages","cloneNode","backgroundColor","_getDimensions","tagName","getBBox","_el$getBBox","getDimensions","setAttribute","createElementNS","appendChild","removeAttribute","foreignObject","innerHTML","defs","insertBefore","firstChild","outer","svgAsDataUri","_ref4","svgXml","decodeURIComponent","p1","c","svgAsPngUri","_ref5","_ref5$encoderType","encoderType","_ref5$encoderOptions","encoderOptions","canvg","convertToPng","_ref6","context","pixelRatio","devicePixelRatio","setTransform","png","SecurityError","slice","download","saveLink","display","body","blob","URL","createObjectURL","onclick","requestAnimationFrame","revokeObjectURL","click","removeChild","title","saveSvg","downloadOpts","saveSvgAsPng","stylesInDOM","getIndexByIdentifier","identifier","modulesToDom","idCountMap","identifiers","base","count","indexByIdentifier","sourceMap","references","updater","addElementStyle","byIndex","splice","api","domAPI","update","newObj","remove","lastIdentifiers","newList","index","newLastIdentifiers","_i","_index","memo","insert","target","styleTarget","HTMLIFrameElement","contentDocument","head","getTarget","element","setAttributes","attributes","styleElement","nonce","insertStyleElement","styleTagTransform","removeStyleElement","styleSheet","createTextNode","NUCLEOTIDES","DEFAULT_FORMATS","LIB_PATH","DEFAULT_LIB_FILENAME","APP_PATH","AXOLABS_STYLE_FILENAME","CODES_TO_HELM_DICT_FILENAME","CODES_TO_SYMBOLS_FILENAME","MONOMERS_WITH_PHOSPHATE_LINKERS","fileSource","axolabsStyleMap","codesToHelmDictionary","codesToSymbolsDictionary","monomersWithPhosphateLinkers","async","getJsonData","every","parse","path","parsedJson","readAsText","errMsg","hasOwnProperty","sortByReverseLength","array","sort","a","b","tryCatch","func","finallyFunc","callbackName","MonomerLibWrapper","lib","_package","allMonomers","getAllMonomers","formatMonomerForViewer","sourceObj","formattedObject","getAllFormats","codes","code","polymerTypes","getPolymerTypes","polymerType","monomersByType","getMonomerSymbolsByType","monomerSymbol","getMonomer","monomer","instance","getMolfileBySymbol","getNaturalAnalogBySymbol","naturalAnalog","isModification","includes","getCodeToSymbolMap","Map","entries","getCodesByFormat","getTableForViewer","formattedObjects","getCodesToWeightsMap","codesToWeightsMap","_","dict","weight","set","SequenceValidator","sequence","libWrapper","getInvalidCodeIndex","firstUniqueCharacters","indexOfFirstInvalidChar","matchedCode","find","isValidSequence","PHOSPHATE_SYMBOL","linkStrandsV3000","strands","useChirality","macroMolBlock","atomBlock","bondBlock","collectionBlock","collection","natom","nbond","xShift","antiStrands","invertNucleotidesV3000","inverted","molBlocks","senseStrands","ssYShift","replaceAll","numbers","extractAtomsBondsNumbersV3000","coordinates","extractAtomDataV3000","Math","min","xShiftRight","yShift","max","j","indexAtoms","indexEnd","atomNumber","coordinate","round","indexAtomsEnd","indexBonds","bondNumber","indexBondEnd","indexCollection","collectionEnd","collNumber","ceil","entriesCurrent","molBlock","atomIndex","xCenter","yCenter","angle","PI","cos","sin","xAdd","atomsNumber","indexes","types","atomType","GROUP_TYPE","NUCLEOSIDE","LINKAGE","UNKNOWN_SYMBOL","getTranslatedSequences","sourceFormat","supportedFormats","outputFormats","localeCompare","converter","fromEntries","translation","convertTo","nucleotides","helmString","monomerLib","re","RegExp","branches","branch","stripped","getNucleotidesSequence","inverseLengthComparator","FormatHandler","getFormats","getFormatNames","validateFormat","isHelm","getFormatCodes","getHelmToFormatDict","infoObj","values","helm","key","sorted","getHelmToCodeDict","getFormatToHelmDict","codesInfoObject","assign","getTargetFormatHelmCodes","getTargetFormatHelmCodesRegExp","helmCodes","getRegExpPattern","getFormatRegExp","getNonHelmFormatRegExp","getPhosphateHelmCodesRegExp","phosphateHELMPattern","Set","isValidFormat","formatCodes","arr","HELM_WRAPPER","LEFT","RIGHT","FormatConverter","targetFormat","helmToFormat","formatToHelm","helmSequence","wrapperRegExp","helmRegExp","formatRegExp","phosphateRegExp","group","ui","rxjs","FormatDetector","getFormat","possibleFormats","getListOfPossibleSynthesizersByFirstMatchedCode","validator","outputIndices","fill","formatIdx","some","synthesizers","start","s","$","highlightInvalidSubsequence","input","cutoff","isValid","greyTextSpan","redTextSpan","ColoredTextInput","textInputBase","painter","resizeable","root","addClass","onChanged","textArea","highlights","colorize","getElementsByTagName","inputBase","spans","span","MonomerSequenceParser","codeMap","parseSequence","parsedRawCodes","parseRawSequence","addLinkers","monomerSymbolSequence","getSymbolForCode","monomerHasLeftPhosphateLinker","pop","isPhosphate","monomerIsPhosphateLinker","lastMonomer","nextMonomerIsPhosphate","monomerHasRightPhosphateLinker","get","allCodesOfFormat","getAllCodesOfFormat","parsedCodes","allCodesInTheFormat","SequenceToMolfileConverter","invert","codeToSymbolMap","parser","convert","parsedSequence","monomerMolfiles","monomerMolfile","getMonomerMolfile","getPolymerMolfile","reflect","invertBondConfiguration","beginIdx","endIdx","group1","group2","rotateNucleotidesV3000","linkV3000","indexFivePrime","indexThreePrime","fix5Prime","derivative","atan","isBoundary","specLength","totalShift","indexFivePrimeNeighbour","base3PrimeX","base3PrimeY","base5PrimeX","base5PrimeY","rotated5PrimeX","rotated5PrimeY","dx","dy","dxRotated","dyRotated","sqrt","V2K_CONST","MolfileV2KHandler","HEADER","END","ATOM_TYPE_COL","NUM_OF_HEADER_LINES","FIRST_BONDED_ATOM_COL","BOND_TYPE_COL","NUM_OF_COUNTS_DIGITS","MolfileHandler","validate","InvalidMolfileError","MoleculeImage","molblok","molblock","_validMolBlock","validateMolBlock","errorMessage","molString","scaffoldMolString","normalizeDepiction","straightenDepiction","errStr","getMoleculeDimensions","molData","getInstance","dialog","showFooter","molDimensions","zoomRatio","dialogCanvasHeight","dialogCanvasWidth","dialogCanvas","drawMolBlockOnCanvas","dialogDiv","overflowX","add","showModal","removeClass","moleculeImgDiv","canvasWidth","canvasHeight","cursor","zoomIn","append","TranslatorLayoutHandler","INPUT_FORMATS","className","border","borderRadius","marginTop","outputTableDiv","formatChoiceInput","updateTable","updateMolImg","sequenceInputBase","onInput","subscribe","sequenceColoredInput","downloadMolfileButton","saveMolfile","copySmilesButton","copySmiles","clearButton","inputTableRow","textInput","clearBtn","upperBlock","classList","outputTable","mainTabBody","smiles","clipboard","writeText","indexOfInvalidChar","translatedSequences","tableRows","molImgObj","drawMolecule","getFormattedSequence","getMolfile","axolabs","getMolfileForStrand","strand","getLinkedMolfile","ss","as","as2","useChiral","nonEmptyStrands","ssMol","STRANDS","StructureLayoutHandler","onInvalidInput","useChiralInput","saveAllStrandsInput","directionInversion","updateMoleculeImg","tableLayout","getTableInput","boolInputsAndButton","getBoolInputsAndButton","bottomDiv","layout","saveButton","strandData","getStrandData","oneEntity","asMol","as2Mol","date","pad","dateString","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","saveSdf","boolInputsAndButtonArray","coloredInput","directionChoiceInput","selected","toUpperCase","labelNames","labelNameMap","label","clearBlock","clearIcon","clear","choiceInput","parentElement","USER_STORAGE_KEY","SS","AS","STRAND_NAME","THREE_PRIME","FIVE_PRIME","TERMINAL_KEYS","TERMINAL","isOverhang","modification","countOverhangsOnTheRightEdge","modifications","textWidth","measureText","textInsideCircle","bases","fontColorVisibleOnBackground","rgbIntList","color","Number","baseColor","xmlns","render","circle","radius","fontSize","star","centerX","centerY","points","innerCirclePoints","innerRadius","getPointsToDrawStar","generateExample","sequenceLength","sequenceBasis","uniqueSymbols","symbols","repeat","floor","isCurrentUserCreatedThisPattern","patternName","user","firstName","lastName","first","getUserName","getShortName","translateSequence","ptoLinkages","startModification","endModification","firstPtoExist","mainSequence","AXOLABS_MAP","indexOfSymbol","BASE_RADIUS","BASE_DIAMETER","BASE_FONT_SIZE","PS_LINKAGE_COLOR","FONT_COLOR","MODIFICATIONS_COLOR","SS_LEFT_TEXT","AS_LEFT_TEXT","WIDTH_OF_LEFT_TEXT","WIDTH_OF_RIGHT_TEXT","X_OF_LEFT_MODIFICATIONS","Y","TITLE","SS_INDICES","SS_CIRCLES","SS_TEXTS","AS_CIRCLES","AS_TEXTS","AS_INDICES","comment","asExists","circlesInLegends","textLegend","svgHeight","drawAxolabsPattern","ssBases","asBases","ssPtoStatuses","asPtoStatuses","ss3Modification","ss5Modification","as3Modification","as5Modification","enumerateModifications","equidistantXForLegend","startFrom","uniqueBases","xOfBaseCircles","rightOverhangs","widthOfRightModification","resultingNumberOfNucleotidesInStrands","shiftToAlignNumberNearCircle","generalIndex","nucleotideIndex","reverse","ssRightOverhangs","asRightOverhangs","widthOfRightOverhangs","widthOfBases","widthOfLeftModification","isPtoExist","xOfSsRightModifications","xOfAsRightModifications","xOfRightTexts","numberOfSsNucleotides","nucleotideCounter","xOfNumbers","n","numberOfAsNucleotides","PatternLayoutHandler","htmlDivElement","updateModification","modificationItems","maxStrandLength","baseInputsObject","fullyPto","sequenceBase","strandLengthInput","updateSvgScheme","updateOutputExamples","baseChoices","isEnumerateModificationsDiv","boolV","alignItems","updateUiForNewSequenceLength","strandColumnInput","inputExample","onOK","onCancel","conditions","createAsStrand","outputExample","terminalModification","firstPto","svgDiv","saveAs","parsePatternAndUpdateUi","newName","pi","entities","modeMap","maxEl","maxCount","detectDefaultBasis","fields","field","terminal","close","postPatternToUserStorage","currUserName","friendlyName","getCurrentUserName","stringValue","updatePatternsList","lstMy","lstOthers","ent","loadPattern","currentUserName","patternListChoiceInput","currentList","maxWidth","marginLeft","setTooltip","loadPatternDiv","savePattern","getButton","hide","addButton","show","validateStrandColumn","colName","allLengthsAreTheSame","col","tableInput","getCol","columns","addNewInt","allColumnValuesOfEqualLength","firstSequence","validateIdsColumn","categories","toList","duplicates","getRawData","selection","defaultBase","newBasisValue","newPtoValue","captionLabel","textAlign","minWidth","toLowerCase","strandVar","inputs","flexGrow","lastChild","modificationSection","paddingTop","resize","asExampleDiv","asModificationDiv","asLengthDiv","tableList","table","tableName","view","columnNames","names","defaultColumn","log","replaceWith","idVar","idInput","inputIdColumn","hidden","savePatternButton","addOptions","convertSequenceButton","getString","columnName","nameOfNewColumn","contains","columnWithIds","byName","addNewString","addColumnWithIds","columnWithInputSequences","addColumnWithTranslatedSequences","downloadButton","getElementById","editPattern","gap","addCaption","padding","drawZoomedInMolecule","dialogDivStyle","atomCoordinates","clientHeight","molWidth","molHeight","hR","drawMolfileOnCanvas","MonomerLibViewer","grid","props","allowEdit","onCellDoubleClick","gridCell","cell","tableColumn","semType","AppUIBase","appName","parentAppName","currentView","addView","SimpleAppUIBase","setupView","initView","html","getHtml","box","windows","showProperties","showToolbox","showHelp","getView","CombinedAppUI","externalViewFactories","factories","getViewFactories","multiView","viewFactories","viewFactory","uiConstructor","translateUI","OligoTranslatorUI","OligoPatternUI","OligoStructureUI","getPath","tabs","currentPane","charAt","setUrl","onTabChanged","ExternalPluginUI","viewName","AppUIFactory","viewMonomerLibIcon","topPanel","setRibbonPanels","getHtmlElement","getHtmlDivElement","NOTATION","wu","CandidateType","alphabet","fasta","peptide","dna","rna","dt","simplified","PaletteType","palette","cp","objList","colour","ind","colourPalette","_palette","m","undefinedColor","Lesk","lesk","makePalette","GrokGroups","grokGroups","RasMol","rasMol","resM","aaSynonyms","Aminoacids","scheme","isInner","inner","chemPaletteInstance","getPalette","outerMonomer","innerMonomer","getInnerOuter","amino","AAFullNames","SemType","SemTypeMultipleAlignment","Names","AASmiles","AASmilesTruncated","Nucleotides","StringUtils","hash","UnknownSeqPalette","UnknownColorPalette","pI","hashCode","dgColor","g","distToBlack","pow","correctColor","buildPalette","Uint32Array","MmDistanceFunctionsNames","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","uhTemp","getMerMadeParameters","StPackage","_monomerLib","libHelper","funcList","package","prepare","call","getOutputParamValue","readLibrary","buildLayout","initSequenceTranslatorLibData","appUI","getUI","createAppLayout","oligoToolkitApp","externalPluginData","tabName","parameters","pluginName","div","pluginUI","getExternalAppViewFactories","oligoTranslatorApp","oligoPatternApp","oligoStructureApp","initMonomerLib","getCodeToWeightsMap","validateSequence","getMolfileFromGcrsSequence","linkStrands","demoTranslateSequence","demoOligoTranslatorUI","demoOligoPattern","emulateUserInput","idxUpdate","choiceInputs","len","selectElement","event","Event","dispatchEvent","demoOligoPatternUI","demoOligoStructure","textarea","setInputValue","demoOligoStructureUI","translateOligonucleotideSequence","SEQUENCE_COPIED_MSG","SEQ_TOOLTIP_MSG","DEFAULT_AXOLABS_INPUT","DG","grok","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","definition","o","defineProperty","enumerable","prop","prototype","Symbol","toStringTag","nc","__webpack_exports__"],"sourceRoot":""}
1
+ {"version":3,"file":"package.js","mappings":"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","sources":["webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/chemical-table-parser-base.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler-base.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/const.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/utils.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-v3k-handler.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/utils/src/test.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/utils/src/to-console.js","webpack://sequencetranslator/./src/view/style/colored-text-input.css","webpack://sequencetranslator/./src/view/style/structure-app.css","webpack://sequencetranslator/./src/view/style/translator-app.css","webpack://sequencetranslator/./node_modules/css-loader/dist/runtime/api.js","webpack://sequencetranslator/./node_modules/css-loader/dist/runtime/sourceMaps.js","webpack://sequencetranslator/./node_modules/save-svg-as-png/lib/saveSvgAsPng.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/insertBySelector.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/insertStyleElement.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/styleDomAPI.js","webpack://sequencetranslator/./node_modules/style-loader/dist/runtime/styleTagTransform.js","webpack://sequencetranslator/./src/model/const.ts","webpack://sequencetranslator/./src/model/data-loading-utils/const.ts","webpack://sequencetranslator/./src/model/data-loading-utils/json-loader.ts","webpack://sequencetranslator/./src/model/helpers.ts","webpack://sequencetranslator/./src/model/monomer-lib/lib-wrapper.ts","webpack://sequencetranslator/./src/model/parsing-validation/sequence-validator.ts","webpack://sequencetranslator/./src/model/structure-app/const.ts","webpack://sequencetranslator/./src/model/structure-app/mol-transformations.ts","webpack://sequencetranslator/./src/model/translator-app/const.ts","webpack://sequencetranslator/./src/model/translator-app/conversion-utils.ts","webpack://sequencetranslator/./src/model/parsing-validation/format-handler.ts","webpack://sequencetranslator/./src/model/translator-app/format-converter.ts","webpack://sequencetranslator/external var \"ui\"","webpack://sequencetranslator/external var \"rxjs\"","webpack://sequencetranslator/./src/view/style/translator-app.css?3282","webpack://sequencetranslator/./src/model/parsing-validation/format-detector.ts","webpack://sequencetranslator/external var \"$\"","webpack://sequencetranslator/./src/view/utils/colored-input/input-painters.ts","webpack://sequencetranslator/./src/view/style/colored-text-input.css?0e07","webpack://sequencetranslator/./src/view/utils/colored-input/colored-text-input.ts","webpack://sequencetranslator/./src/model/structure-app/monomer-code-parser.ts","webpack://sequencetranslator/./src/model/structure-app/sequence-to-molfile.ts","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/formats/molfile-v2k-const.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-v2k-handler.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler.js","webpack://sequencetranslator/./src/view/utils/molecule-img.ts","webpack://sequencetranslator/./src/view/apps/oligo-translator.ts","webpack://sequencetranslator/./src/view/style/structure-app.css?9992","webpack://sequencetranslator/./src/model/structure-app/oligo-structure.ts","webpack://sequencetranslator/./src/view/apps/oligo-structure.ts","webpack://sequencetranslator/./src/model/pattern-app/const.ts","webpack://sequencetranslator/./src/model/pattern-app/helpers.ts","webpack://sequencetranslator/./src/model/pattern-app/oligo-pattern.ts","webpack://sequencetranslator/./src/model/pattern-app/draw-svg.ts","webpack://sequencetranslator/./src/view/apps/oligo-pattern.ts","webpack://sequencetranslator/./src/view/utils/draw-molecule.ts","webpack://sequencetranslator/./src/view/monomer-lib-viewer/viewer.ts","webpack://sequencetranslator/./src/view/app-ui.ts","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/consts.js","webpack://sequencetranslator/external var \"wu\"","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/types.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/seq-palettes.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/aminoacids.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/nucleotides.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/unknown.js","webpack://sequencetranslator/./node_modules/fastest-levenshtein/esm/mod.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/macromolecule-distance-functions.js","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/utils/units-handler.js","webpack://sequencetranslator/./src/plugins/mermade.ts","webpack://sequencetranslator/./src/package.ts","webpack://sequencetranslator/./node_modules/@datagrok-libraries/bio/src/monomer-works/monomer-utils.js","webpack://sequencetranslator/./src/demo/demo-st-ui.ts","webpack://sequencetranslator/./src/view/const/oligo-translator.ts","webpack://sequencetranslator/./src/view/const/ui.ts","webpack://sequencetranslator/external var \"DG\"","webpack://sequencetranslator/external var \"grok\"","webpack://sequencetranslator/webpack/bootstrap","webpack://sequencetranslator/webpack/runtime/compat get default export","webpack://sequencetranslator/webpack/runtime/define property getters","webpack://sequencetranslator/webpack/runtime/hasOwnProperty shorthand","webpack://sequencetranslator/webpack/runtime/make namespace object","webpack://sequencetranslator/webpack/runtime/nonce","webpack://sequencetranslator/webpack/startup"],"sourcesContent":["/** Base for Molfile or Mol2 parser/handler */\nexport class ChemicalTableParserBase {\n constructor(fileContent) {\n this.init(fileContent);\n }\n ;\n init(fileContent) {\n this.fileContent = fileContent.replace(/\\r/g, '');\n this._atomCount = undefined;\n this._atomTypes = undefined;\n this._bondCount = undefined;\n this._bondTypes = undefined;\n this.xyzAtomCoordinates = undefined;\n this._pairsOfBondedAtoms = undefined;\n }\n /** Total number of atoms in a molecule */\n get atomCount() {\n if (this._atomCount === undefined)\n this.setAtomAndBondCounts();\n return this._atomCount;\n }\n /** Number of bonds in a molecule */\n get bondCount() {\n if (this._bondCount === undefined)\n this.setAtomAndBondCounts();\n return this._bondCount;\n }\n /** X coordinates of all atoms in a molecule */\n get x() {\n var _a;\n (_a = this.xyzAtomCoordinates) !== null && _a !== void 0 ? _a : (this.xyzAtomCoordinates = this.parseAtomCoordinates());\n return this.xyzAtomCoordinates.x;\n }\n ;\n /** Y coordinates of all atoms in a molecule */\n get y() {\n var _a;\n (_a = this.xyzAtomCoordinates) !== null && _a !== void 0 ? _a : (this.xyzAtomCoordinates = this.parseAtomCoordinates());\n return this.xyzAtomCoordinates.y;\n }\n ;\n /** Z coordinates of all atoms in a molecule */\n get z() {\n var _a;\n (_a = this.xyzAtomCoordinates) !== null && _a !== void 0 ? _a : (this.xyzAtomCoordinates = this.parseAtomCoordinates());\n return this.xyzAtomCoordinates.z;\n }\n ;\n get atomTypes() {\n var _a;\n (_a = this._atomTypes) !== null && _a !== void 0 ? _a : (this._atomTypes = this.parseAtomTypes());\n return this._atomTypes;\n }\n get pairsOfBondedAtoms() {\n var _a;\n (_a = this._pairsOfBondedAtoms) !== null && _a !== void 0 ? _a : (this._pairsOfBondedAtoms = this.parseBondedAtomPairs());\n return this._pairsOfBondedAtoms;\n }\n get bondTypes() {\n var _a;\n (_a = this._bondTypes) !== null && _a !== void 0 ? _a : (this._bondTypes = this.parseBondTypes());\n return this._bondTypes;\n }\n setAtomAndBondCounts() {\n const { atomCount, bondCount } = this.parseAtomAndBondCounts();\n this._atomCount = atomCount;\n this._bondCount = bondCount;\n }\n getNextColumnIdx(idx) {\n // skip non-whitespace, if necessary\n while (!this.isWhitespace(idx))\n ++idx;\n // skip whitespace\n while (this.isWhitespace(idx))\n ++idx;\n return idx;\n }\n shiftIdxToSpecifiedColumn(lineStartIdx, columnNumber) {\n let idx = lineStartIdx;\n const numberOfJumps = this.isWhitespace(idx) ? columnNumber : columnNumber - 1;\n for (let i = 0; i < numberOfJumps; i++)\n idx = this.getNextColumnIdx(idx);\n return idx;\n }\n parseAtomTypes() {\n const atomCount = this.atomCount;\n const atomTypes = new Array(atomCount);\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < atomCount; i++) {\n idx = this.shiftIdxToAtomType(idx);\n atomTypes[i] = this.parseAtomType(idx);\n idx = this.getNextLineIdx(idx);\n }\n return atomTypes;\n }\n ;\n parseAtomCoordinates() {\n const x = new Float32Array(this.atomCount);\n const y = new Float32Array(this.atomCount);\n const z = new Float32Array(this.atomCount);\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < this.atomCount; i++) {\n idx = this.shiftIdxToXColumn(idx);\n for (const item of [x, y, z]) {\n item[i] = this.parseFloatValue(idx);\n idx = this.getNextColumnIdx(idx);\n }\n idx = this.getNextLineIdx(idx);\n }\n return { x: x, y: y, z: z };\n }\n parseBondedAtomPairs() {\n const bondedAtomPairs = new Array(this.bondCount);\n let idx = this.getBondBlockIdx();\n for (let i = 0; i < this.bondCount; i++) {\n idx = this.shiftIdxToBondedAtomsPair(idx);\n const pair = new Uint16Array(2);\n pair[0] = this.parseIntValue(idx);\n idx = this.getNextColumnIdx(idx);\n pair[1] = this.parseIntValue(idx);\n bondedAtomPairs[i] = pair;\n idx = this.getNextLineIdx(idx);\n }\n return bondedAtomPairs;\n }\n parseBondTypes() {\n const bondCount = this.bondCount;\n const bondTypes = new Uint16Array(bondCount);\n let idx = this.getBondBlockIdx();\n for (let i = 0; i < bondCount; i++) {\n idx = this.shiftIdxToBondType(idx);\n bondTypes[i] = this.parseIntValue(idx);\n idx = this.getNextLineIdx(idx);\n }\n return bondTypes;\n }\n ;\n isWhitespace(idx) {\n const symbol = this.fileContent[idx];\n return symbol === ' ' || symbol === '\\t';\n }\n getNextLineIdx(idx) {\n if (this.fileContent[idx] !== '\\n')\n return this.fileContent.indexOf('\\n', idx) + 1;\n else\n return idx + 1;\n }\n parseFloatValue(idxOfNumber) {\n return this.parseNumericValue(parseFloat, idxOfNumber);\n }\n parseIntValue(idxOfNumber) {\n return this.parseNumericValue(parseInt, idxOfNumber);\n }\n parseNumericValue(parserFunction, idxOfNumber) {\n let end = idxOfNumber + 1;\n while (!this.isWhitespace(end))\n ++end;\n const value = parserFunction(this.fileContent.substring(idxOfNumber, end));\n return value;\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlbWljYWwtdGFibGUtcGFyc2VyLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjaGVtaWNhbC10YWJsZS1wYXJzZXItYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQSw4Q0FBOEM7QUFDOUMsTUFBTSxPQUFnQix1QkFBdUI7SUFDM0MsWUFBWSxXQUFtQjtRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFBQSxDQUFDO0lBVVEsSUFBSSxDQUFDLFdBQW1CO1FBQ2hDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDNUIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFNBQVMsQ0FBQztRQUNwQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCwwQ0FBMEM7SUFDMUMsSUFBSSxTQUFTO1FBQ1gsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVM7WUFDL0IsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUIsT0FBTyxJQUFJLENBQUMsVUFBVyxDQUFDO0lBQzFCLENBQUM7SUFFRCxxQ0FBcUM7SUFDckMsSUFBSSxTQUFTO1FBQ1gsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVM7WUFDL0IsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDOUIsT0FBTyxJQUFJLENBQUMsVUFBVyxDQUFDO0lBQzFCLENBQUM7SUFFRCxnREFBZ0Q7SUFDaEQsSUFBSSxDQUFDOztRQUNILE1BQUEsSUFBSSxDQUFDLGtC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QVcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgQXRvbUFuZEJvbmRDb3VudHMgPSB7XG4gIGF0b21Db3VudDogbnVtYmVyLFxuICBib25kQ291bnQ6IG51bWJlclxufVxuXG50eXBlIENvb3JkaW5hdGVBcnJheXMgPSB7XG4gIHg6IEZsb2F0MzJBcnJheSxcbiAgeTogRmxvYXQzMkFycmF5LFxuICB6OiBGbG9hdDMyQXJyYXksXG59XG5cbi8qKiBCYXNlIGZvciBNb2xmaWxlIG9yIE1vbDIgcGFyc2VyL2hhbmRsZXIgKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDaGVtaWNhbFRhYmxlUGFyc2VyQmFzZSB7XG4gIGNvbnN0cnVjdG9yKGZpbGVDb250ZW50OiBzdHJpbmcpIHtcbiAgICB0aGlzLmluaXQoZmlsZUNvbnRlbnQpO1xuICB9O1xuXG4gIHByb3RlY3RlZCBmaWxlQ29udGVudCE6IHN0cmluZztcbiAgcHJvdGVjdGVkIF9hdG9tQ291bnQ/OiBudW1iZXI7XG4gIHByb3RlY3RlZCBfYm9uZENvdW50PzogbnVtYmVyO1xuICBwcm90ZWN0ZWQgeHl6QXRvbUNvb3JkaW5hdGVzPzogQ29vcmRpbmF0ZUFycmF5cztcbiAgcHJvdGVjdGVkIF9hdG9tVHlwZXM/OiBzdHJpbmdbXTtcbiAgcHJvdGVjdGVkIF9wYWlyc09mQm9uZGVkQXRvbXM/OiBVaW50MTZBcnJheVtdO1xuICBwcm90ZWN0ZWQgX2JvbmRUeXBlcz86IFVpbnQxNkFycmF5O1xuXG4gIHByb3RlY3RlZCBpbml0KGZpbGVDb250ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmZpbGVDb250ZW50ID0gZmlsZUNvbnRlbnQucmVwbGFjZSgvXFxyL2csICcnKTtcbiAgICB0aGlzLl9hdG9tQ291bnQgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fYXRvbVR5cGVzID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuX2JvbmRDb3VudCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLl9ib25kVHlwZXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy54eXpBdG9tQ29vcmRpbmF0ZXMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcGFpcnNPZkJvbmRlZEF0b21zID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqIFRvdGFsIG51bWJlciBvZiBhdG9tcyBpbiBhIG1vbGVjdWxlICovXG4gIGdldCBhdG9tQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fYXRvbUNvdW50ID09PSB1bmRlZmluZWQpXG4gICAgICB0aGlzLnNldEF0b21BbmRCb25kQ291bnRzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2F0b21Db3VudCE7XG4gIH1cblxuICAvKiogTnVtYmVyIG9mIGJvbmRzIGluIGEgbW9sZWN1bGUgICovXG4gIGdldCBib25kQ291bnQoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5fYm9uZENvdW50ID09PSB1bmRlZmluZWQpXG4gICAgICB0aGlzLnNldEF0b21BbmRCb25kQ291bnRzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2JvbmRDb3VudCE7XG4gIH1cblxuICAvKiogWCBjb29yZGluYXRlcyBvZiBhbGwgYXRvbXMgaW4gYSBtb2xlY3VsZSAgKi9cbiAgZ2V0IHgoKTogRmxvYXQzMkFycmF5IHtcbiAgICB0aGlzLnh5ekF0b21Db29yZGluYXRlcyA/Pz0gdGhpcy5wYXJzZUF0b21Db29yZGluYXRlcygpO1xuICAgIHJldHVybiB0aGlzLnh5ekF0b21Db29yZGluYXRlcy54O1xuICB9O1xuXG4gIC8qKiBZIGNvb3JkaW5hdGVzIG9mIGFsbCBhdG9tcyBpbiBhIG1vbGVjdWxlICAqL1xuICBnZXQgeSgpOiBGbG9hdDMyQXJyYXkge1xuICAgIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzID8/PSB0aGlzLnBhcnNlQXRvbUNvb3JkaW5hdGVzKCk7XG4gICAgcmV0dXJuIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzIS55O1xuICB9O1xuXG4gIC8qKiBaIGNvb3JkaW5hdGVzIG9mIGFsbCBhdG9tcyBpbiBhIG1vbGVjdWxlICAqL1xuICBnZXQgeigpOiBGbG9hdDMyQXJyYXkge1xuICAgIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzID8/PSB0aGlzLnBhcnNlQXRvbUNvb3JkaW5hdGVzKCk7XG4gICAgcmV0dXJuIHRoaXMueHl6QXRvbUNvb3JkaW5hdGVzIS56O1xuICB9O1xuXG4gIGdldCBhdG9tVHlwZXMoKTogc3RyaW5nW10ge1xuICAgIHRoaXMuX2F0b21UeXBlcyA/Pz0gdGhpcy5wYXJzZUF0b21UeXBlcygpO1xuICAgIHJldHVybiB0aGlzLl9hdG9tVHlwZXM7XG4gIH1cblxuICBnZXQgcGFpcnNPZkJvbmRlZEF0b21zKCk6IFVpbnQxNkFycmF5W10ge1xuICAgIHRoaXMuX3BhaXJzT2ZCb25kZWRBdG9tcyA/Pz0gdGhpcy5wYXJzZUJvbmRlZEF0b21QYWlycygpO1xuICAgIHJldHVybiB0aGlzLl9wYWlyc09mQm9uZGVkQXRvbXMhO1xuICB9XG5cbiAgZ2V0IGJvbmRUeXBlcygpOiBVaW50MTZBcnJheSB7XG4gICAgdGhpcy5fYm9uZFR5cGVzID8/PSB0aGlzLnBhcnNlQm9uZFR5cGVzKCk7XG4gICAgcmV0dXJuIHRoaXMuX2JvbmRUeXBlcyE7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcGFyc2VBdG9tQW5kQm9uZENvdW50cygpOiBBdG9tQW5kQm9uZENvdW50cztcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldENvdW50c0xpbmVJZHgoKTogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0QXRvbUJsb2NrSWR4KCk6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldEJvbmRCbG9ja0lkeCgpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzaGlmdElkeFRvWENvbHVtbihsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNoaWZ0SWR4VG9BdG9tVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNoaWZ0SWR4VG9Cb25kZWRBdG9tc1BhaXIobGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzaGlmdElkeFRvQm9uZFR5cGUobGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUF0b21UeXBlKGlkeDogbnVtYmVyKTogc3RyaW5nO1xuXG4gIHByb3RlY3RlZCBzZXRBdG9tQW5kQm9uZENvdW50cygpOiB2b2lkIHtcbiAgICBjb25zdCB7YXRvbUNvdW50LCBib25kQ291bnR9ID0gdGhpcy5wYXJzZUF0b21BbmRCb25kQ291bnRzKCk7XG4gICAgdGhpcy5fYXRvbUNvdW50ID0gYXRvbUNvdW50O1xuICAgIHRoaXMuX2JvbmRDb3VudCA9IGJvbmRDb3VudDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXROZXh0Q29sdW1uSWR4KGlkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICAvLyBza2lwIG5vbi13aGl0ZXNwYWNlLCBpZiBuZWNlc3NhcnlcbiAgICB3aGlsZSAoIXRoaXMuaXNXaGl0ZXNwYWNlKGlkeCkpXG4gICAgICArK2lkeDtcbiAgICAvLyBza2lwIHdoaXRlc3BhY2VcbiAgICB3aGlsZSAodGhpcy5pc1doaXRlc3BhY2UoaWR4KSlcbiAgICAgICsraWR4O1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHg6IG51bWJlciwgY29sdW1uTnVtYmVyOiBudW1iZXIpIHtcbiAgICBsZXQgaWR4ID0gbGluZVN0YXJ0SWR4O1xuICAgIGNvbnN0IG51bWJlck9mSnVtcHMgPSB0aGlzLmlzV2hpdGVzcGFjZShpZHgpID8gY29sdW1uTnVtYmVyIDogY29sdW1uTnVtYmVyIC0gMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mSnVtcHM7IGkrKylcbiAgICAgIGlkeCA9IHRoaXMuZ2V0TmV4dENvbHVtbklkeChpZHgpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgcGFyc2VBdG9tVHlwZXMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGF0b21Db3VudCA9IHRoaXMuYXRvbUNvdW50O1xuICAgIGNvbnN0IGF0b21UeXBlcyA9IG5ldyBBcnJheTxzdHJpbmc+KGF0b21Db3VudCk7XG4gICAgbGV0IGlkeCA9IHRoaXMuZ2V0QXRvbUJsb2NrSWR4KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdG9tQ291bnQ7IGkrKykge1xuICAgICAgaWR4ID0gdGhpcy5zaGlmdElkeFRvQXRvbVR5cGUoaWR4KTtcbiAgICAgIGF0b21UeXBlc1tpXSA9IHRoaXMucGFyc2VBdG9tVHlwZShpZHgpO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4gYXRvbVR5cGVzO1xuICB9O1xuXG4gIHByb3RlY3RlZCBwYXJzZUF0b21Db29yZGluYXRlcygpOiBDb29yZGluYXRlQXJyYXlzIHtcbiAgICBjb25zdCB4ID0gbmV3IEZsb2F0MzJBcnJheSh0aGlzLmF0b21Db3VudCk7XG4gICAgY29uc3QgeSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5hdG9tQ291bnQpO1xuICAgIGNvbnN0IHogPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYXRvbUNvdW50KTtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRBdG9tQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYXRvbUNvdW50OyBpKyspIHtcbiAgICAgIGlkeCA9IHRoaXMuc2hpZnRJZHhUb1hDb2x1bW4oaWR4KTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBbeCwgeSwgel0pIHtcbiAgICAgICAgaXRlbVtpXSA9IHRoaXMucGFyc2VGbG9hdFZhbHVlKGlkeCk7XG4gICAgICAgIGlkeCA9IHRoaXMuZ2V0TmV4dENvbHVtbklkeChpZHgpO1xuICAgICAgfVxuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4ge3g6IHgsIHk6IHksIHo6IHp9O1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlQm9uZGVkQXRvbVBhaXJzKCk6IFVpbnQxNkFycmF5W10ge1xuICAgIGNvbnN0IGJvbmRlZEF0b21QYWlycyA9IG5ldyBBcnJheTxVaW50MTZBcnJheT4odGhpcy5ib25kQ291bnQpO1xuICAgIGxldCBpZHggPSB0aGlzLmdldEJvbmRCbG9ja0lkeCgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5ib25kQ291bnQ7IGkrKykge1xuICAgICAgaWR4ID0gdGhpcy5zaGlmdElkeFRvQm9uZGVkQXRvbXNQYWlyKGlkeCk7XG4gICAgICBjb25zdCBwYWlyID0gbmV3IFVpbnQxNkFycmF5KDIpO1xuICAgICAgcGFpclswXSA9IHRoaXMucGFyc2VJbnRWYWx1ZShpZHgpO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0Q29sdW1uSWR4KGlkeCk7XG4gICAgICBwYWlyWzFdID0gdGhpcy5wYXJzZUludFZhbHVlKGlkeCk7XG4gICAgICBib25kZWRBdG9tUGFpcnNbaV0gPSBwYWlyO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIH1cbiAgICByZXR1cm4gYm9uZGVkQXRvbVBhaXJzO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlQm9uZFR5cGVzKCk6IFVpbnQxNkFycmF5IHtcbiAgICBjb25zdCBib25kQ291bnQgPSB0aGlzLmJvbmRDb3VudDtcbiAgICBjb25zdCBib25kVHlwZXMgPSBuZXcgVWludDE2QXJyYXkoYm9uZENvdW50KTtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRCb25kQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJvbmRDb3VudDsgaSsrKSB7XG4gICAgICBpZHggPSB0aGlzLnNoaWZ0SWR4VG9Cb25kVHlwZShpZHgpO1xuICAgICAgYm9uZFR5cGVzW2ldID0gdGhpcy5wYXJzZUludFZhbHVlKGlkeCk7XG4gICAgICBpZHggPSB0aGlzLmdldE5leHRMaW5lSWR4KGlkeCk7XG4gICAgfVxuICAgIHJldHVybiBib25kVHlwZXM7XG4gIH07XG5cbiAgcHJvdGVjdGVkIGlzV2hpdGVzcGFjZShpZHg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN5bWJvbCA9IHRoaXMuZmlsZUNvbnRlbnRbaWR4XTtcbiAgICByZXR1cm4gc3ltYm9sID09PSAnICcgfHwgc3ltYm9sID09PSAnXFx0JztcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXROZXh0TGluZUlkeChpZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZmlsZUNvbnRlbnRbaWR4XSAhPT0gJ1xcbicpXG4gICAgICByZXR1cm4gdGhpcy5maWxlQ29udGVudC5pbmRleE9mKCdcXG4nLCBpZHgpICsgMTtcbiAgICBlbHNlXG4gICAgICByZXR1cm4gaWR4ICsgMTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUZsb2F0VmFsdWUoaWR4T2ZOdW1iZXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VOdW1lcmljVmFsdWUocGFyc2VGbG9hdCwgaWR4T2ZOdW1iZXIpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHBhcnNlSW50VmFsdWUoaWR4T2ZOdW1iZXI6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VOdW1lcmljVmFsdWUocGFyc2VJbnQsIGlkeE9mTnVtYmVyKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZU51bWVyaWNWYWx1ZShcbiAgICBwYXJzZXJGdW5jdGlvbjogKHN0cjogc3RyaW5nKSA9PiBudW1iZXIsXG4gICAgaWR4T2ZOdW1iZXI6IG51bWJlclxuICApOiBudW1iZXIge1xuICAgIGxldCBlbmQgPSBpZHhPZk51bWJlciArIDE7XG4gICAgd2hpbGUgKCF0aGlzLmlzV2hpdGVzcGFjZShlbmQpKVxuICAgICAgKytlbmQ7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZXJGdW5jdGlvbih0aGlzLmZpbGVDb250ZW50LnN1YnN0cmluZyhpZHhPZk51bWJlciwgZW5kKSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG4iXX0=","import { ChemicalTableParserBase } from './chemical-table-parser-base';\nimport { ASTERISK, D_QUOTE, L, R, S_QUOTE } from './const';\nimport { isAlpha } from './utils';\nexport class MolfileHandlerBase extends ChemicalTableParserBase {\n constructor(molfile) {\n super(molfile);\n this.init(molfile);\n }\n init(molfile) {\n super.init(molfile);\n }\n parseAtomType(idx) {\n let begin = idx;\n let end = begin;\n if (this.isQuote(begin)) {\n end = this.getNextIdenticalChar(begin);\n begin++;\n }\n else {\n end = this.fileContent.indexOf(' ', end);\n }\n return this.fileContent.substring(begin, end);\n }\n isQuote(idx) {\n const letter = this.fileContent[idx].charCodeAt(0);\n return letter === S_QUOTE || letter === D_QUOTE;\n }\n getNextIdenticalChar(idx) {\n const sym = this.fileContent[idx];\n return sym ? this.fileContent.indexOf(sym, idx + 1) : -1;\n }\n isQuery() {\n return this.isQueryOrFragment((char, idx) => {\n return char === S_QUOTE || char === D_QUOTE ||\n (char === L && !isAlpha(this.fileContent.charCodeAt(idx + 1)));\n });\n }\n ;\n isFragment() {\n return this.isQueryOrFragment((char) => {\n return char === R || char === ASTERISK;\n });\n }\n ;\n isQueryOrFragment(condition) {\n const atomCount = this.atomCount;\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < atomCount; i++) {\n idx = this.shiftIdxToAtomType(idx);\n const char = this.fileContent.charCodeAt(idx);\n if (condition(char, idx))\n return true;\n idx = this.getNextLineIdx(idx);\n }\n return false;\n }\n ;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS1oYW5kbGVyLWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtb2xmaWxlLWhhbmRsZXItYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQW9CLE1BQU0sOEJBQThCLENBQUM7QUFDeEYsT0FBTyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVsQyxNQUFNLE9BQWdCLGtCQUFtQixTQUFRLHVCQUF1QjtJQUN0RSxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRVMsSUFBSSxDQUFDLE9BQWU7UUFDNUIsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUN0QixDQUFDO0lBV1MsYUFBYSxDQUFDLEdBQVc7UUFDakMsSUFBSSxLQUFLLEdBQUcsR0FBRyxDQUFDO1FBQ2hCLElBQUksR0FBRyxHQUFHLEtBQUssQ0FBQztRQUNoQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDdkIsR0FBRyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2QyxLQUFLLEVBQUUsQ0FBQztTQUNUO2FBQU07WUFDTCxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQzFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVTLE9BQU8sQ0FBQyxHQUFXO1FBQzNCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sTUFBTSxLQUFLLE9BQU8sSUFBSSxNQUFNLEtBQUssT0FBTyxDQUFDO0lBQ2xELENBQUM7SUFFUyxvQkFBb0IsQ0FBQyxHQUFXO1FBQ3hDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFTSxPQUFPO1FBQ1osT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxJQUFZLEVBQUUsR0FBVyxFQUFFLEVBQUU7WUFDMUQsT0FBTyxJQUFJLEtBQUssT0FBTyxJQUFJLElBQUksS0FBSyxPQUFPO2dCQUMzQyxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNoRSxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQSxDQUFDO0lBRUssVUFBVTtRQUNmLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsSUFBWSxFQUFFLEVBQUU7WUFDN0MsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksS0FBSyxRQUFRLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBQUEsQ0FBQztJQUVRLGlCQUFpQixDQUFDLFNBQWlEO1FBQzNFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ2pDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDbEMsR0FBRyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNuQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM5QyxJQUFJLFNBQVMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO2dCQUN0QixPQUFPLElBQUksQ0FBQztZQUNkLEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ2hDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQUEsQ0FBQztDQUNIIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGVtaWNhbFRhYmxlUGFyc2VyQmFzZSwgQXRvbUFuZEJvbmRDb3VudHN9IGZyb20gJy4vY2hlbWljYWwtdGFibGUtcGFyc2VyLWJhc2UnO1xuaW1wb3J0IHsgQVNURVJJU0ssIERfUVVPVEUsIEwsIFIsIFNfUVVPVEUgfSBmcm9tICcuL2NvbnN0JztcbmltcG9ydCB7IGlzQWxwaGEgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIE1vbGZpbGVIYW5kbGVyQmFzZSBleHRlbmRzIENoZW1pY2FsVGFibGVQYXJzZXJCYXNlIHtcbiAgY29uc3RydWN0b3IobW9sZmlsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobW9sZmlsZSk7XG4gICAgdGhpcy5pbml0KG1vbGZpbGUpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGluaXQobW9sZmlsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIuaW5pdChtb2xmaWxlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBwYXJzZUF0b21BbmRCb25kQ291bnRzKCk6IEF0b21BbmRCb25kQ291bnRzO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0Q291bnRzTGluZUlkeCgpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRBdG9tQmxvY2tJZHgoKTogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3Qgc2hpZnRJZHhUb1hDb2x1bW4obGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBzaGlmdElkeFRvQXRvbVR5cGUobGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXI7XG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRCb25kQmxvY2tJZHgoKTogbnVtYmVyO1xuICBwcm90ZWN0ZWQgYWJzdHJhY3Qgc2hpZnRJZHhUb0JvbmRlZEF0b21zUGFpcihsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNoaWZ0SWR4VG9Cb25kVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlcjtcblxuICBwcm90ZWN0ZWQgcGFyc2VBdG9tVHlwZShpZHg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgbGV0IGJlZ2luID0gaWR4O1xuICAgIGxldCBlbmQgPSBiZWdpbjtcbiAgICBpZiAodGhpcy5pc1F1b3RlKGJlZ2luKSkge1xuICAgICAgZW5kID0gdGhpcy5nZXROZXh0SWRlbnRpY2FsQ2hhcihiZWdpbik7XG4gICAgICBiZWdpbisrO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbmQgPSB0aGlzLmZpbGVDb250ZW50LmluZGV4T2YoJyAnLCBlbmQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5maWxlQ29udGVudC5zdWJzdHJpbmcoYmVnaW4sIGVuZCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgaXNRdW90ZShpZHg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGxldHRlciA9IHRoaXMuZmlsZUNvbnRlbnRbaWR4XS5jaGFyQ29kZUF0KDApO1xuICAgIHJldHVybiBsZXR0ZXIgPT09IFNfUVVPVEUgfHwgbGV0dGVyID09PSBEX1FVT1RFO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldE5leHRJZGVudGljYWxDaGFyKGlkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBzeW0gPSB0aGlzLmZpbGVDb250ZW50W2lkeF07XG4gICAgcmV0dXJuIHN5bSA/IHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZihzeW0sIGlkeCArIDEpIDogLTE7XG4gIH1cblxuICBwdWJsaWMgaXNRdWVyeSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc1F1ZXJ5T3JGcmFnbWVudCgoY2hhcjogbnVtYmVyLCBpZHg6IG51bWJlcikgPT4ge1xuICAgICAgcmV0dXJuIGNoYXIgPT09IFNfUVVPVEUgfHwgY2hhciA9PT0gRF9RVU9URSB8fFxuICAgICAgKGNoYXIgPT09IEwgJiYgIWlzQWxwaGEodGhpcy5maWxlQ29udGVudC5jaGFyQ29kZUF0KGlkeCArIDEpKSlcbiAgICB9KVxuICB9O1xuXG4gIHB1YmxpYyBpc0ZyYWdtZW50KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmlzUXVlcnlPckZyYWdtZW50KChjaGFyOiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBjaGFyID09PSBSIHx8IGNoYXIgPT09IEFTVEVSSVNLO1xuICAgIH0pXG4gIH07XG5cbiAgcHJvdGVjdGVkIGlzUXVlcnlPckZyYWdtZW50KGNvbmRpdGlvbjogKGNoYXI6IG51bWJlciwgaWR4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgICBjb25zdCBhdG9tQ291bnQgPSB0aGlzLmF0b21Db3VudDtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRBdG9tQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0b21Db3VudDsgaSsrKSB7XG4gICAgICBpZHggPSB0aGlzLnNoaWZ0SWR4VG9BdG9tVHlwZShpZHgpO1xuICAgICAgY29uc3QgY2hhciA9IHRoaXMuZmlsZUNvbnRlbnQuY2hhckNvZGVBdChpZHgpO1xuICAgICAgaWYgKGNvbmRpdGlvbihjaGFyLCBpZHgpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIGlkeCA9IHRoaXMuZ2V0TmV4dExpbmVJZHgoaWR4KTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xufVxuIl19","export const R = 82;\nexport const L = 76;\nexport const D_QUOTE = 34;\nexport const S_QUOTE = 39;\nexport const ASTERISK = 42;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjb25zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3BCLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDcEIsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUMxQixNQUFNLENBQUMsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBQzFCLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgUiA9IDgyO1xuZXhwb3J0IGNvbnN0IEwgPSA3NjtcbmV4cG9ydCBjb25zdCBEX1FVT1RFID0gMzQ7XG5leHBvcnQgY29uc3QgU19RVU9URSA9IDM5O1xuZXhwb3J0IGNvbnN0IEFTVEVSSVNLID0gNDI7XG4iXX0=","export function isAlpha(charCode) {\n return (charCode > 64 && charCode < 91) ||\n (charCode > 96 && charCode < 123);\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ1dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLFVBQVUsT0FBTyxDQUFDLFFBQWdCO0lBQ3BDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsRUFBRSxJQUFJLFFBQVEsR0FBRyxFQUFFLENBQUM7UUFDbkMsQ0FBQyxRQUFRLEdBQUcsRUFBRSxJQUFJLFFBQVEsR0FBRyxHQUFHLENBQUMsQ0FBQztBQUMxQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGZ1bmN0aW9uIGlzQWxwaGEoY2hhckNvZGU6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoY2hhckNvZGUgPiA2NCAmJiBjaGFyQ29kZSA8IDkxKSB8fFxuICAgICAgICAoY2hhckNvZGUgPiA5NiAmJiBjaGFyQ29kZSA8IDEyMyk7XG59XG4iXX0=","import { MolfileHandlerBase } from './molfile-handler-base';\nexport class MolfileV3KHandler extends MolfileHandlerBase {\n constructor(molfile) {\n super(molfile);\n this.init(molfile);\n }\n shiftIdxToAtomType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 4 /* V3K_CONST.ATOM_TYPE_COL */);\n }\n getCountsLineIdx() {\n return this.fileContent.indexOf(\"M V30 COUNTS \" /* V3K_CONST.BEGIN_COUNTS_LINE */);\n }\n getAtomBlockIdx() {\n let idx = this.fileContent.indexOf(\"M V30 BEGIN ATOM\" /* V3K_CONST.BEGIN_ATOM_BLOCK */);\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n shiftIdxToXColumn(lineStartIdx) {\n let idx = this.shiftIdxToAtomType(lineStartIdx);\n if (this.isQuote(idx)) {\n idx = this.getNextIdenticalChar(idx);\n idx = this.getNextColumnIdx(idx);\n return idx;\n }\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 5 /* V3K_CONST.X_COL */);\n }\n shiftIdxToBondedAtomsPair(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 5 /* V3K_CONST.FIRST_BONDED_ATOM_COL */);\n }\n shiftIdxToBondType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, 4 /* V3K_CONST.BOND_TYPE_COL */);\n }\n getBondBlockIdx() {\n return this.getNextLineIdx(this.fileContent.indexOf(\"M V30 BEGIN BOND\" /* V3K_CONST.BEGIN_BOND_BLOCK */));\n }\n static validate(molfile) {\n return (molfile.indexOf(\"V3000\" /* V3K_CONST.HEADER */) !== -1 &&\n molfile.indexOf(\"M END\" /* V3K_CONST.END */) !== -1);\n }\n parseAtomAndBondCounts() {\n // parse atom count\n let begin = this.fileContent.indexOf(\"M V30 COUNTS \" /* V3K_CONST.BEGIN_COUNTS_LINE */) + 14 /* V3K_CONST.COUNTS_SHIFT */;\n let end = this.fileContent.indexOf(' ', begin + 1);\n const numOfAtoms = parseInt(this.fileContent.substring(begin, end));\n // parse bond count\n begin = end + 1;\n end = this.fileContent.indexOf(' ', begin + 1);\n const numOfBonds = parseInt(this.fileContent.substring(begin, end));\n return { atomCount: numOfAtoms, bondCount: numOfBonds };\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS12M2staGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1vbGZpbGUtdjNrLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFLMUQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLGtCQUFrQjtJQUN2RCxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxrQ0FBMEIsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZ0JBQWdCO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLG9EQUE2QixDQUFDO0lBQy9ELENBQUM7SUFFUyxlQUFlO1FBQ3ZCLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxzREFBNEIsQ0FBQztRQUMvRCxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFUyxpQkFBaUIsQ0FBQyxZQUFvQjtRQUM5QyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDaEQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3JCLEdBQUcsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckMsR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqQyxPQUFPLEdBQUcsQ0FBQztTQUNaO1FBQ0QsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSwwQkFBa0IsQ0FBQztJQUN2RSxDQUFDO0lBRVMseUJBQXlCLENBQUMsWUFBb0I7UUFDdEQsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSwwQ0FBa0MsQ0FBQztJQUN2RixDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxrQ0FBMEIsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZUFBZTtRQUN2QixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLHNEQUE0QixDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVNLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBZTtRQUNwQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sZ0NBQWtCLEtBQUssQ0FBQyxDQUFDO1lBQ2hELE9BQU8sQ0FBQyxPQUFPLDhCQUFlLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRVMsc0JBQXNCO1FBQzlCLG1CQUFtQjtRQUNuQixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sb0RBQTZCLGtDQUF5QixDQUFDO1FBQzNGLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkQsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXBFLG1CQUFtQjtRQUNuQixLQUFLLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNoQixHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMvQyxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFcEUsT0FBTyxFQUFDLFNBQVMsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBQyxDQUFDO0lBQ3hELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QXRvbUFuZEJvbmRDb3VudHN9IGZyb20gJy4vY2hlbWljYWwtdGFibGUtcGFyc2VyLWJhc2UnO1xuaW1wb3J0IHtNb2xmaWxlSGFuZGxlckJhc2V9IGZyb20gJy4vbW9sZmlsZS1oYW5kbGVyLWJhc2UnO1xuaW1wb3J0IHtWM0tfQ09OU1R9IGZyb20gJy4uL2Zvcm1hdHMvbW9sZmlsZS12M2stY29uc3QnO1xuaW1wb3J0IHsgTCwgUiB9IGZyb20gJy4vY29uc3QnO1xuaW1wb3J0IHsgaXNBbHBoYSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgY2xhc3MgTW9sZmlsZVYzS0hhbmRsZXIgZXh0ZW5kcyBNb2xmaWxlSGFuZGxlckJhc2Uge1xuICBjb25zdHJ1Y3Rvcihtb2xmaWxlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtb2xmaWxlKTtcbiAgICB0aGlzLmluaXQobW9sZmlsZSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb0F0b21UeXBlKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULkFUT01fVFlQRV9DT0wpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldENvdW50c0xpbmVJZHgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5maWxlQ29udGVudC5pbmRleE9mKFYzS19DT05TVC5CRUdJTl9DT1VOVFNfTElORSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0QXRvbUJsb2NrSWR4KCk6IG51bWJlciB7XG4gICAgbGV0IGlkeCA9IHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZihWM0tfQ09OU1QuQkVHSU5fQVRPTV9CTE9DSyk7XG4gICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb1hDb2x1bW4obGluZVN0YXJ0SWR4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBpZHggPSB0aGlzLnNoaWZ0SWR4VG9BdG9tVHlwZShsaW5lU3RhcnRJZHgpO1xuICAgIGlmICh0aGlzLmlzUXVvdGUoaWR4KSkge1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0SWRlbnRpY2FsQ2hhcihpZHgpO1xuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0Q29sdW1uSWR4KGlkeCk7XG4gICAgICByZXR1cm4gaWR4O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULlhfQ09MKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzaGlmdElkeFRvQm9uZGVkQXRvbXNQYWlyKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULkZJUlNUX0JPTkRFRF9BVE9NX0NPTCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb0JvbmRUeXBlKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5zaGlmdElkeFRvU3BlY2lmaWVkQ29sdW1uKGxpbmVTdGFydElkeCwgVjNLX0NPTlNULkJPTkRfVFlQRV9DT0wpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldEJvbmRCbG9ja0lkeCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmdldE5leHRMaW5lSWR4KHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZihWM0tfQ09OU1QuQkVHSU5fQk9ORF9CTE9DSykpO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyB2YWxpZGF0ZShtb2xmaWxlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKG1vbGZpbGUuaW5kZXhPZihWM0tfQ09OU1QuSEVBREVSKSAhPT0gLTEgJiZcbiAgICBtb2xmaWxlLmluZGV4T2YoVjNLX0NPTlNULkVORCkgIT09IC0xKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUF0b21BbmRCb25kQ291bnRzKCk6IEF0b21BbmRCb25kQ291bnRzIHtcbiAgICAvLyBwYXJzZSBhdG9tIGNvdW50XG4gICAgbGV0IGJlZ2luID0gdGhpcy5maWxlQ29udGVudC5pbmRleE9mKFYzS19DT05TVC5CRUdJTl9DT1VOVFNfTElORSkgKyBWM0tfQ09OU1QuQ09VTlRTX1NISUZUO1xuICAgIGxldCBlbmQgPSB0aGlzLmZpbGVDb250ZW50LmluZGV4T2YoJyAnLCBiZWdpbiArIDEpO1xuICAgIGNvbnN0IG51bU9mQXRvbXMgPSBwYXJzZUludCh0aGlzLmZpbGVDb250ZW50LnN1YnN0cmluZyhiZWdpbiwgZW5kKSk7XG5cbiAgICAvLyBwYXJzZSBib25kIGNvdW50XG4gICAgYmVnaW4gPSBlbmQgKyAxO1xuICAgIGVuZCA9IHRoaXMuZmlsZUNvbnRlbnQuaW5kZXhPZignICcsIGJlZ2luICsgMSk7XG4gICAgY29uc3QgbnVtT2ZCb25kcyA9IHBhcnNlSW50KHRoaXMuZmlsZUNvbnRlbnQuc3Vic3RyaW5nKGJlZ2luLCBlbmQpKTtcblxuICAgIHJldHVybiB7YXRvbUNvdW50OiBudW1PZkF0b21zLCBib25kQ291bnQ6IG51bU9mQm9uZHN9O1xuICB9XG59XG4iXX0=","var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nimport * as grok from 'datagrok-api/grok';\nimport * as DG from 'datagrok-api/dg';\nexport const tests = {};\nexport let currentCategory;\nexport var assure;\n(function (assure) {\n function notNull(value, name) {\n if (value == null)\n throw new Error(`${name == null ? 'Value' : name} not defined`);\n }\n assure.notNull = notNull;\n})(assure || (assure = {}));\nexport class TestContext {\n constructor(catchUnhandled, report) {\n this.catchUnhandled = true;\n this.report = false;\n if (catchUnhandled !== undefined)\n this.catchUnhandled = catchUnhandled;\n if (report !== undefined)\n this.report = report;\n }\n ;\n}\nexport class Test {\n constructor(category, name, test, options) {\n var _a;\n this.category = category;\n this.name = name;\n options !== null && options !== void 0 ? options : (options = {});\n (_a = options.timeout) !== null && _a !== void 0 ? _a : (options.timeout = 30000);\n this.options = options;\n this.test = () => __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {\n let result = '';\n try {\n result = yield test();\n }\n catch (e) {\n reject(e);\n }\n resolve(result);\n }));\n });\n }\n}\nexport function testEvent(event, handler, trigger, ms = 0) {\n return __awaiter(this, void 0, void 0, function* () {\n let sub;\n return new Promise((resolve, reject) => {\n sub = event.subscribe((args) => {\n try {\n handler(args);\n }\n catch (e) {\n reject(e);\n }\n sub.unsubscribe();\n resolve('OK');\n });\n setTimeout(() => {\n sub.unsubscribe();\n // eslint-disable-next-line prefer-promise-reject-errors\n reject('timeout');\n }, ms);\n trigger();\n });\n });\n}\nexport function test(name, test, options) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n if (tests[currentCategory].tests == undefined)\n tests[currentCategory].tests = [];\n tests[currentCategory].tests.push(new Test(currentCategory, name, test, options));\n}\n/* Tests two objects for equality, throws an exception if they are not equal. */\nexport function expect(actual, expected) {\n if (actual !== expected)\n throw new Error(`Expected \"${expected}\", got \"${actual}\"`);\n}\nexport function expectFloat(actual, expected, tolerance = 0.001) {\n const areEqual = Math.abs(actual - expected) < tolerance;\n if (!areEqual)\n throw new Error(`Expected ${expected}, got ${actual} (tolerance = ${tolerance})`);\n}\nexport function expectObject(actual, expected) {\n for (const [expectedKey, expectedValue] of Object.entries(expected)) {\n if (!actual.hasOwnProperty(expectedKey))\n throw new Error(`Expected property \"${expectedKey}\" not found`);\n const actualValue = actual[expectedKey];\n if (actualValue instanceof Array && expectedValue instanceof Array)\n expectArray(actualValue, expectedValue);\n else if (actualValue instanceof Object && expectedValue instanceof Object)\n expectObject(actualValue, expectedValue);\n else if (Number.isFinite(actualValue) && Number.isFinite(expectedValue))\n expectFloat(actualValue, expectedValue);\n else if (actualValue != expectedValue)\n throw new Error(`Expected (${expectedValue}) for key '${expectedKey}', got (${actualValue})`);\n }\n}\nexport function expectArray(actual, expected) {\n const actualLength = actual.length;\n const expectedLength = expected.length;\n if (actualLength != expectedLength) {\n throw new Error(`Arrays are of different length: actual array length is ${actualLength} ` +\n `and expected array length is ${expectedLength}`);\n }\n for (let i = 0; i < actualLength; i++) {\n if (actual[i] instanceof Array && expected[i] instanceof Array)\n expectArray(actual[i], expected[i]);\n else if (actual[i] instanceof Object && expected[i] instanceof Object)\n expectObject(actual[i], expected[i]);\n else if (actual[i] != expected[i])\n throw new Error(`Expected ${expected[i]} at position ${i}, got ${actual[i]}`);\n }\n}\n/* Defines a test suite. */\nexport function category(category, tests) {\n currentCategory = category;\n tests();\n}\n/* Defines a function to be executed before the tests in this category are executed. */\nexport function before(before) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].before = before;\n}\n/* Defines a function to be executed after the tests in this category are executed. */\nexport function after(after) {\n if (tests[currentCategory] == undefined)\n tests[currentCategory] = {};\n tests[currentCategory].after = after;\n}\nexport function runTests(options) {\n var _a, _b, _c, _d;\n var _e;\n return __awaiter(this, void 0, void 0, function* () {\n const results = [];\n const packageName = (_b = (_a = grok.functions.getCurrentCall()) === null || _a === void 0 ? void 0 : _a.func) === null || _b === void 0 ? void 0 : _b.package;\n console.log(`Running tests`);\n options !== null && options !== void 0 ? options : (options = {});\n (_c = (_e = options).testContext) !== null && _c !== void 0 ? _c : (_e.testContext = new TestContext());\n grok.shell.lastError = '';\n for (const [key, value] of Object.entries(tests)) {\n if ((options === null || options === void 0 ? void 0 : options.category) != undefined) {\n if (!key.toLowerCase().startsWith(options === null || options === void 0 ? void 0 : options.category.toLowerCase()))\n continue;\n }\n console.log(`Started ${key} category`);\n try {\n if (value.before)\n yield value.before();\n }\n catch (x) {\n value.beforeStatus = x.toString();\n }\n const t = (_d = value.tests) !== null && _d !== void 0 ? _d : [];\n const res = [];\n for (let i = 0; i < t.length; i++)\n res.push(yield execTest(t[i], options === null || options === void 0 ? void 0 : options.test));\n const data = (yield Promise.all(res)).filter((d) => d.result != 'skipped');\n try {\n if (value.after)\n yield value.after();\n }\n catch (x) {\n value.afterStatus = x.toString();\n }\n if (value.afterStatus)\n data.push({ category: key, name: 'init', result: value.afterStatus, success: false, ms: 0, skipped: false });\n if (value.beforeStatus)\n data.push({ category: key, name: 'init', result: value.beforeStatus, success: false, ms: 0, skipped: false });\n results.push(...data);\n }\n if (options.testContext.catchUnhandled) {\n yield delay(1000);\n if (grok.shell.lastError.length > 0) {\n results.push({\n category: 'Unhandled exceptions',\n name: 'exceptions',\n result: grok.shell.lastError, success: false, ms: 0, skipped: false\n });\n }\n }\n if (options.testContext.report) {\n const logger = new DG.Logger();\n const successful = results.filter((r) => r.success).length;\n const skipped = results.filter((r) => r.skipped).length;\n const failed = results.filter((r) => !r.success);\n const description = 'Package @package tested: @successful successful, @skipped skipped, @failed failed tests';\n const params = {\n successful: successful,\n skipped: skipped,\n failed: failed.length,\n package: packageName\n };\n for (const r of failed)\n Object.assign(params, { [`${r.category} | ${r.name}`]: r.result });\n logger.log(description, params, 'package-tested');\n }\n return results;\n });\n}\nfunction execTest(t, predicate) {\n var _a, _b, _c;\n return __awaiter(this, void 0, void 0, function* () {\n let r;\n const filter = predicate != undefined && (!t.name.toLowerCase().startsWith(predicate.toLowerCase()));\n const skip = ((_a = t.options) === null || _a === void 0 ? void 0 : _a.skipReason) || filter;\n const skipReason = filter ? 'skipped' : (_b = t.options) === null || _b === void 0 ? void 0 : _b.skipReason;\n if (!skip)\n console.log(`Started ${t.category} ${t.name}`);\n const start = new Date();\n try {\n if (skip)\n r = { success: true, result: skipReason, ms: 0, skipped: true };\n else\n r = { success: true, result: (_c = yield t.test()) !== null && _c !== void 0 ? _c : 'OK', ms: 0, skipped: false };\n }\n catch (x) {\n r = { success: false, result: x.toString(), ms: 0, skipped: false };\n }\n const stop = new Date();\n // @ts-ignore\n r.ms = stop - start;\n if (!skip)\n console.log(`Finished ${t.category} ${t.name} for ${r.ms} ms`);\n r.category = t.category;\n r.name = t.name;\n return r;\n });\n}\n/* Waits [ms] milliseconds */\nexport function delay(ms) {\n return __awaiter(this, void 0, void 0, function* () {\n yield new Promise((r) => setTimeout(r, ms));\n });\n}\nexport function awaitCheck(checkHandler, error = 'Timeout exceeded', wait = 500) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n clearInterval(interval);\n reject(new Error(error));\n }, wait);\n // @ts-ignore\n const interval = setInterval(() => {\n if (checkHandler()) {\n clearInterval(interval);\n resolve();\n }\n }, 50);\n });\n });\n}\nexport function isDialogPresent(dialogTitle) {\n for (let i = 0; i < DG.Dialog.getOpenDialogs().length; i++) {\n if (DG.Dialog.getOpenDialogs()[i].title == dialogTitle)\n return true;\n }\n return false;\n}\nexport function testViewer(v, df, detectSemanticTypes = false) {\n return __awaiter(this, void 0, void 0, function* () {\n if (detectSemanticTypes)\n yield grok.data.detectSemanticTypes(df);\n const tv = grok.shell.addTableView(df);\n const viewerName = `[name=viewer-${v.replace(/\\s+/g, '-')} i]`;\n const selector = `${viewerName} canvas,${viewerName} svg,${viewerName} img,\n ${viewerName} input,${viewerName} h1,${viewerName} a`;\n const res = [];\n try {\n let viewer = tv.addViewer(v);\n yield awaitCheck(() => document.querySelector(selector) !== null, 'cannot load viewer', 3000);\n res.push(Array.from(tv.viewers).length);\n Array.from(df.row(0).cells).forEach((c) => c.value = null);\n df.rows.select((row) => row.idx > 1 && row.idx < 7);\n for (let i = 7; i < 12; i++)\n df.filter.set(i, false);\n df.currentRowIdx = 1;\n const props = viewer.getOptions(true).look;\n const newProps = {};\n Object.keys(props).filter((k) => typeof props[k] === 'boolean').forEach((k) => newProps[k] = !props[k]);\n viewer.setOptions(newProps);\n yield delay(250);\n const layout = tv.saveLayout();\n const oldProps = viewer.getOptions().look;\n tv.resetLayout();\n res.push(Array.from(tv.viewers).length);\n tv.loadLayout(layout);\n yield awaitCheck(() => document.querySelector(selector) !== null, 'cannot load viewer from layout', 3000);\n yield delay(250);\n res.push(Array.from(tv.viewers).length);\n viewer = Array.from(tv.viewers).find((v) => v.type !== 'Grid');\n expectArray(res, [2, 1, 2]);\n expect(JSON.stringify(viewer.getOptions().look), JSON.stringify(oldProps));\n }\n finally {\n tv.close();\n grok.shell.closeTable(df);\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSXRDLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FLZCxFQUFFLENBQUM7QUFFUCxNQUFNLENBQUMsSUFBSSxlQUF1QixDQUFDO0FBRW5DLE1BQU0sS0FBVyxNQUFNLENBTXRCO0FBTkQsV0FBaUIsTUFBTTtJQUVyQixTQUFnQixPQUFPLENBQUMsS0FBVSxFQUFFLElBQWE7UUFDL0MsSUFBSSxLQUFLLElBQUksSUFBSTtZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksY0FBYyxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUhlLGNBQU8sVUFHdEIsQ0FBQTtBQUNILENBQUMsRUFOZ0IsTUFBTSxLQUFOLE1BQU0sUUFNdEI7QUFRRCxNQUFNLE9BQU8sV0FBVztJQUl0QixZQUFZLGNBQXdCLEVBQUUsTUFBZ0I7UUFIdEQsbUJBQWMsR0FBRyxJQUFJLENBQUM7UUFDdEIsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUdiLElBQUksY0FBYyxLQUFLLFNBQVM7WUFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztRQUN2RSxJQUFJLE1BQU0sS0FBSyxTQUFTO1lBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDakQsQ0FBQztJQUFBLENBQUM7Q0FDSDtBQUVELE1BQU0sT0FBTyxJQUFJO0lBTWYsWUFBWSxRQUFnQixFQUFFLElBQVksRUFBRSxJQUF3QixFQUFFLE9BQXFCOztRQUN6RixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsSUFBSSxHQUFH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SyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2pCLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUUsQ0FBQztZQUNoRSxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FDNUU7Z0JBQVM7WUFDUixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMzQjtJQUNILENBQUM7Q0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgREcgZnJvbSAnZGF0YWdyb2stYXBpL2RnJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCBUaW1lb3V0ID0gTm9kZUpTLlRpbWVvdXQ7XG5cbmV4cG9ydCBjb25zdCB0ZXN0czoge1xuICBba2V5OiBzdHJpbmddOiB7XG4gICAgdGVzdHM/OiBUZXN0W10sIGJlZm9yZT86ICgpID0+IFByb21pc2U8dm9pZD4sIGFmdGVyPzogKCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgICBiZWZvcmVTdGF0dXM/OiBzdHJpbmcsIGFmdGVyU3RhdHVzPzogc3RyaW5nXG4gIH1cbn0gPSB7fTtcblxuZXhwb3J0IGxldCBjdXJyZW50Q2F0ZWdvcnk6IHN0cmluZztcblxuZXhwb3J0IG5hbWVzcGFjZSBhc3N1cmUge1xuXG4gIGV4cG9ydCBmdW5jdGlvbiBub3ROdWxsKHZhbHVlOiBhbnksIG5hbWU/OiBzdHJpbmcpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtuYW1lID09IG51bGwgPyAnVmFsdWUnIDogbmFtZX0gbm90IGRlZmluZWRgKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RPcHRpb25zIHtcbiAgdGltZW91dD86IG51bWJlcjtcbiAgdW5oYW5kbGVkRXhjZXB0aW9uVGltZW91dD86IG51bWJlcjtcbiAgc2tpcFJlYXNvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3RDb250ZXh0IHtcbiAgY2F0Y2hVbmhhbmRsZWQgPSB0cnVlO1xuICByZXBvcnQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihjYXRjaFVuaGFuZGxlZD86IGJvb2xlYW4sIHJlcG9ydD86IGJvb2xlYW4pIHtcbiAgICBpZiAoY2F0Y2hVbmhhbmRsZWQgIT09IHVuZGVmaW5lZCkgdGhpcy5jYXRjaFVuaGFuZGxlZCA9IGNhdGNoVW5oYW5kbGVkO1xuICAgIGlmIChyZXBvcnQgIT09IHVuZGVmaW5lZCkgdGhpcy5yZXBvcnQgPSByZXBvcnQ7XG4gIH07XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0IHtcbiAgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+O1xuICBuYW1lOiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBzdHJpbmc7XG4gIG9wdGlvbnM/OiBUZXN0T3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihjYXRlZ29yeTogc3RyaW5nLCBuYW1lOiBzdHJpbmcsIHRlc3Q6ICgpID0+IFByb21pc2U8YW55Piwgb3B0aW9ucz86IFRlc3RPcHRpb25zKSB7XG4gICAgdGhpcy5jYXRlZ29yeSA9IGNhdGVnb3J5O1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgb3B0aW9ucyA/Pz0ge307XG4gICAgb3B0aW9ucy50aW1lb3V0ID8/PSAzMDAwMDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMudGVzdCA9IGFzeW5jICgpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGFzeW5jIChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9ICcnO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHRlc3QoKTtcbiAgICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRlc3RFdmVudDxUPihldmVudDogT2JzZXJ2YWJsZTxUPixcbiAgaGFuZGxlcjogKGFyZ3M6IFQpID0+IHZvaWQsIHRyaWdnZXI6ICgpID0+IHZvaWQsIG1zOiBudW1iZXIgPSAwKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgbGV0IHN1YjogU3Vic2NyaXB0aW9uO1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHN1YiA9IGV2ZW50LnN1YnNjcmliZSgoYXJncykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlcihhcmdzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICByZXNvbHZlKCdPSycpO1xuICAgIH0pO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KCd0aW1lb3V0Jyk7XG4gICAgfSwgbXMpO1xuICAgIHRyaWdnZXIoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0KG5hbWU6IHN0cmluZywgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+LCBvcHRpb25zPzogVGVzdE9wdGlvbnMpOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPSBbXTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS50ZXN0cyEucHVzaChuZXcgVGVzdChjdXJyZW50Q2F0ZWdvcnksIG5hbWUsIHRlc3QsIG9wdGlvbnMpKTtcbn1cblxuLyogVGVzdHMgdHdvIG9iamVjdHMgZm9yIGVxdWFsaXR5LCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZXkgYXJlIG5vdCBlcXVhbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3QoYWN0dWFsOiBhbnksIGV4cGVjdGVkOiBhbnkpOiB2b2lkIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBcIiR7ZXhwZWN0ZWR9XCIsIGdvdCBcIiR7YWN0dWFsfVwiYCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RGbG9hdChhY3R1YWw6IG51bWJlciwgZXhwZWN0ZWQ6IG51bWJlciwgdG9sZXJhbmNlID0gMC4wMDEpOiB2b2lkIHtcbiAgY29uc3QgYXJlRXF1YWwgPSBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPCB0b2xlcmFuY2U7XG4gIGlmICghYXJlRXF1YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSwgZ290ICR7YWN0dWFsfSAodG9sZXJhbmNlID0gJHt0b2xlcmFuY2V9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0T2JqZWN0KGFjdHVhbDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSwgZXhwZWN0ZWQ6IHsgW2tleTogc3RyaW5nXTogYW55IH0pIHtcbiAgZm9yIChjb25zdCBbZXhwZWN0ZWRLZXksIGV4cGVjdGVkVmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGV4cGVjdGVkKSkge1xuICAgIGlmICghYWN0dWFsLmhhc093blByb3BlcnR5KGV4cGVjdGVkS2V5KSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgcHJvcGVydHkgXCIke2V4cGVjdGVkS2V5fVwiIG5vdCBmb3VuZGApO1xuXG4gICAgY29uc3QgYWN0dWFsVmFsdWUgPSBhY3R1YWxbZXhwZWN0ZWRLZXldO1xuICAgIGlmIChhY3R1YWxWYWx1ZSBpbnN0YW5jZW9mIEFycmF5ICYmIGV4cGVjdGVkVmFsdWUgaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgIGV4cGVjdEFycmF5KGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKTtcbiAgICBlbHNlIGlmIChhY3R1YWxWYWx1ZSBpbnN0YW5jZW9mIE9iamVjdCAmJiBleHBlY3RlZFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0KVxuICAgICAgZXhwZWN0T2JqZWN0KGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKTtcbiAgICBlbHNlIGlmIChOdW1iZXIuaXNGaW5pdGUoYWN0dWFsVmFsdWUpICYmIE51bWJlci5pc0Zpbml0ZShleHBlY3RlZFZhbHVlKSlcbiAgICAgIGV4cGVjdEZsb2F0KGFjdHVhbFZhbHVlLCBleHBlY3RlZFZhbHVlKTtcbiAgICBlbHNlIGlmIChhY3R1YWxWYWx1ZSAhPSBleHBlY3RlZFZhbHVlKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAoJHtleHBlY3RlZFZhbHVlfSkgZm9yIGtleSAnJHtleHBlY3RlZEtleX0nLCBnb3QgKCR7YWN0dWFsVmFsdWV9KWApO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RBcnJheShhY3R1YWw6IEFycmF5TGlrZTxhbnk+LCBleHBlY3RlZDogQXJyYXlMaWtlPGFueT4pIHtcbiAgY29uc3QgYWN0dWFsTGVuZ3RoID0gYWN0dWFsLmxlbmd0aDtcbiAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7XG5cbiAgaWYgKGFjdHVhbExlbmd0aCAhPSBleHBlY3RlZExlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXJyYXlzIGFyZSBvZiBkaWZmZXJlbnQgbGVuZ3RoOiBhY3R1YWwgYXJyYXkgbGVuZ3RoIGlzICR7YWN0dWFsTGVuZ3RofSBgICtcbiAgICAgIGBhbmQgZXhwZWN0ZWQgYXJyYXkgbGVuZ3RoIGlzICR7ZXhwZWN0ZWRMZW5ndGh9YCk7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFjdHVhbExlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFjdHVhbFtpXSBpbnN0YW5jZW9mIEFycmF5ICYmIGV4cGVjdGVkW2ldIGluc3RhbmNlb2YgQXJyYXkpXG4gICAgICBleHBlY3RBcnJheShhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTtcbiAgICBlbHNlIGlmIChhY3R1YWxbaV0gaW5zdGFuY2VvZiBPYmplY3QgJiYgZXhwZWN0ZWRbaV0gaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgICBleHBlY3RPYmplY3QoYWN0dWFsW2ldLCBleHBlY3RlZFtpXSk7XG4gICAgZWxzZSBpZiAoYWN0dWFsW2ldICE9IGV4cGVjdGVkW2ldKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkW2ldfSBhdCBwb3NpdGlvbiAke2l9LCBnb3QgJHthY3R1YWxbaV19YCk7XG4gIH1cbn1cblxuLyogRGVmaW5lcyBhIHRlc3Qgc3VpdGUuICovXG5leHBvcnQgZnVuY3Rpb24gY2F0ZWdvcnkoY2F0ZWdvcnk6IHN0cmluZywgdGVzdHM6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgY3VycmVudENhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gIHRlc3RzKCk7XG59XG5cbi8qIERlZmluZXMgYSBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBiZWZvcmUgdGhlIHRlc3RzIGluIHRoaXMgY2F0ZWdvcnkgYXJlIGV4ZWN1dGVkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJlZm9yZShiZWZvcmU6ICgpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS5iZWZvcmUgPSBiZWZvcmU7XG59XG5cbi8qIERlZmluZXMgYSBmdW5jdGlvbiB0byBiZSBleGVjdXRlZCBhZnRlciB0aGUgdGVzdHMgaW4gdGhpcyBjYXRlZ29yeSBhcmUgZXhlY3V0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXIoYWZ0ZXI6ICgpID0+IFByb21pc2U8dm9pZD4pOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS5hZnRlciA9IGFmdGVyO1xufVxuXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5UZXN0cyhvcHRpb25zPzogeyBjYXRlZ29yeT86IHN0cmluZywgdGVzdD86IHN0cmluZywgdGVzdENvbnRleHQ/OiBUZXN0Q29udGV4dCB9KSB7XG4gIGNvbnN0IHJlc3VsdHM6IHsgY2F0ZWdvcnk/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIHN1Y2Nlc3M6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfVtdID0gW107XG4gIGNvbnN0IHBhY2thZ2VOYW1lID0gZ3Jvay5mdW5jdGlvbnMuZ2V0Q3VycmVudENhbGwoKT8uZnVuYz8ucGFja2FnZTtcbiAgY29uc29sZS5sb2coYFJ1bm5pbmcgdGVzdHNgKTtcbiAgb3B0aW9ucyA/Pz0ge307XG4gIG9wdGlvbnMhLnRlc3RDb250ZXh0ID8/PSBuZXcgVGVzdENvbnRleHQoKTtcbiAgZ3Jvay5zaGVsbC5sYXN0RXJyb3IgPSAnJztcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModGVzdHMpKSB7XG4gICAgaWYgKG9wdGlvbnM/LmNhdGVnb3J5ICE9IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCFrZXkudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKG9wdGlvbnM/LmNhdGVnb3J5LnRvTG93ZXJDYXNlKCkpKVxuICAgICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coYFN0YXJ0ZWQgJHtrZXl9IGNhdGVnb3J5YCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh2YWx1ZS5iZWZvcmUpXG4gICAgICAgIGF3YWl0IHZhbHVlLmJlZm9yZSgpO1xuICAgIH0gY2F0Y2ggKHg6IGFueSkge1xuICAgICAgdmFsdWUuYmVmb3JlU3RhdHVzID0geC50b1N0cmluZygpO1xuICAgIH1cbiAgICBjb25zdCB0ID0gdmFsdWUudGVzdHMgPz8gW107XG4gICAgY29uc3QgcmVzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0Lmxlbmd0aDsgaSsrKVxuICAgICAgcmVzLnB1c2goYXdhaXQgZXhlY1Rlc3QodFtpXSwgb3B0aW9ucz8udGVzdCkpO1xuXG4gICAgY29uc3QgZGF0YSA9IChhd2FpdCBQcm9taXNlLmFsbChyZXMpKS5maWx0ZXIoKGQpID0+IGQucmVzdWx0ICE9ICdza2lwcGVkJyk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh2YWx1ZS5hZnRlcilcbiAgICAgICAgYXdhaXQgdmFsdWUuYWZ0ZXIoKTtcbiAgICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICAgIHZhbHVlLmFmdGVyU3RhdHVzID0geC50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAodmFsdWUuYWZ0ZXJTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5hZnRlclN0YXR1cywgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZX0pO1xuICAgIGlmICh2YWx1ZS5iZWZvcmVTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5iZWZvcmVTdGF0dXMsIHN1Y2Nlc3M6IGZhbHNlLCBtczogMCwgc2tpcHBlZDogZmFsc2V9KTtcbiAgICByZXN1bHRzLnB1c2goLi4uZGF0YSk7XG4gIH1cbiAgaWYgKG9wdGlvbnMudGVzdENvbnRleHQuY2F0Y2hVbmhhbmRsZWQpIHtcbiAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICBpZiAoZ3Jvay5zaGVsbC5sYXN0RXJyb3IubGVuZ3RoID4gMCkge1xuICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdVbmhhbmRsZWQgZXhjZXB0aW9ucycsXG4gICAgICAgIG5hbWU6ICdleGNlcHRpb25zJyxcbiAgICAgICAgcmVzdWx0OiBncm9rLnNoZWxsLmxhc3RFcnJvciwgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGlmIChvcHRpb25zLnRlc3RDb250ZXh0LnJlcG9ydCkge1xuICAgIGNvbnN0IGxvZ2dlciA9IG5ldyBERy5Mb2dnZXIoKTtcbiAgICBjb25zdCBzdWNjZXNzZnVsID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+IHIuc3VjY2VzcykubGVuZ3RoO1xuICAgIGNvbnN0IHNraXBwZWQgPSByZXN1bHRzLmZpbHRlcigocikgPT4gci5za2lwcGVkKS5sZW5ndGg7XG4gICAgY29uc3QgZmFpbGVkID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+ICFyLnN1Y2Nlc3MpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJ1BhY2thZ2UgQHBhY2thZ2UgdGVzdGVkOiBAc3VjY2Vzc2Z1bCBzdWNjZXNzZnVsLCBAc2tpcHBlZCBza2lwcGVkLCBAZmFpbGVkIGZhaWxlZCB0ZXN0cyc7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgc3VjY2Vzc2Z1bDogc3VjY2Vzc2Z1bCxcbiAgICAgIHNraXBwZWQ6IHNraXBwZWQsXG4gICAgICBmYWlsZWQ6IGZhaWxlZC5sZW5ndGgsXG4gICAgICBwYWNrYWdlOiBwYWNrYWdlTmFtZVxuICAgIH07XG4gICAgZm9yIChjb25zdCByIG9mIGZhaWxlZCkgT2JqZWN0LmFzc2lnbihwYXJhbXMsIHtbYCR7ci5jYXRlZ29yeX0gfCAke3IubmFtZX1gXTogci5yZXN1bHR9KTtcbiAgICBsb2dnZXIubG9nKGRlc2NyaXB0aW9uLCBwYXJhbXMsICdwYWNrYWdlLXRlc3RlZCcpO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjVGVzdCh0OiBUZXN0LCBwcmVkaWNhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICBsZXQgcjogeyBjYXRlZ29yeT86IHN0cmluZywgbmFtZT86IHN0cmluZywgc3VjY2VzczogYm9vbGVhbiwgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfTtcbiAgY29uc3QgZmlsdGVyID0gcHJlZGljYXRlICE9IHVuZGVmaW5lZCAmJiAoIXQubmFtZS50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgocHJlZGljYXRlLnRvTG93ZXJDYXNlKCkpKTtcbiAgY29uc3Qgc2tpcCA9IHQub3B0aW9ucz8uc2tpcFJlYXNvbiB8fCBmaWx0ZXI7XG4gIGNvbnN0IHNraXBSZWFzb24gPSBmaWx0ZXIgPyAnc2tpcHBlZCcgOiB0Lm9wdGlvbnM/LnNraXBSZWFzb247XG4gIGlmICghc2tpcClcbiAgICBjb25zb2xlLmxvZyhgU3RhcnRlZCAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfWApO1xuICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKCk7XG5cbiAgdHJ5IHtcbiAgICBpZiAoc2tpcClcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBza2lwUmVhc29uISwgbXM6IDAsIHNraXBwZWQ6IHRydWV9O1xuICAgIGVsc2VcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBhd2FpdCB0LnRlc3QoKSA/PyAnT0snLCBtczogMCwgc2tpcHBlZDogZmFsc2V9O1xuICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICByID0ge3N1Y2Nlc3M6IGZhbHNlLCByZXN1bHQ6IHgudG9TdHJpbmcoKSwgbXM6IDAsIHNraXBwZWQ6IGZhbHNlfTtcbiAgfVxuICBjb25zdCBzdG9wID0gbmV3IERhdGUoKTtcbiAgLy8gQHRzLWlnbm9yZVxuICByLm1zID0gc3RvcCAtIHN0YXJ0O1xuICBpZiAoIXNraXApXG4gICAgY29uc29sZS5sb2coYEZpbmlzaGVkICR7dC5jYXRlZ29yeX0gJHt0Lm5hbWV9IGZvciAke3IubXN9IG1zYCk7XG5cbiAgci5jYXRlZ29yeSA9IHQuY2F0ZWdvcnk7XG4gIHIubmFtZSA9IHQubmFtZTtcbiAgcmV0dXJuIHI7XG59XG5cbi8qIFdhaXRzIFttc10gbWlsbGlzZWNvbmRzICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsYXkobXM6IG51bWJlcikge1xuICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBtcykpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXdhaXRDaGVjayhjaGVja0hhbmRsZXI6ICgpID0+IGJvb2xlYW4sXG4gIGVycm9yOiBzdHJpbmcgPSAnVGltZW91dCBleGNlZWRlZCcsIHdhaXQ6IG51bWJlciA9IDUwMCk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGVycm9yKSk7XG4gICAgfSwgd2FpdCk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGludGVydmFsOiBUaW1lb3V0ID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgaWYgKGNoZWNrSGFuZGxlcigpKSB7XG4gICAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWwpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSwgNTApO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzRGlhbG9nUHJlc2VudChkaWFsb2dUaXRsZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgREcuRGlhbG9nLmdldE9wZW5EaWFsb2dzKCkubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoREcuRGlhbG9nLmdldE9wZW5EaWFsb2dzKClbaV0udGl0bGUgPT0gZGlhbG9nVGl0bGUpXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0Vmlld2VyKHY6IHN0cmluZywgZGY6IERHLkRhdGFGcmFtZSwgZGV0ZWN0U2VtYW50aWNUeXBlczogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChkZXRlY3RTZW1hbnRpY1R5cGVzKSBhd2FpdCBncm9rLmRhdGEuZGV0ZWN0U2VtYW50aWNUeXBlcyhkZik7XG4gIGNvbnN0IHR2ID0gZ3Jvay5zaGVsbC5hZGRUYWJsZVZpZXcoZGYpO1xuICBjb25zdCB2aWV3ZXJOYW1lID0gYFtuYW1lPXZpZXdlci0ke3YucmVwbGFjZSgvXFxzKy9nLCAnLScpfSBpXWA7XG4gIGNvbnN0IHNlbGVjdG9yID0gYCR7dmlld2VyTmFtZX0gY2FudmFzLCR7dmlld2VyTmFtZX0gc3ZnLCR7dmlld2VyTmFtZX0gaW1nLFxuICAgICR7dmlld2VyTmFtZX0gaW5wdXQsJHt2aWV3ZXJOYW1lfSBoMSwke3ZpZXdlck5hbWV9IGFgO1xuICBjb25zdCByZXMgPSBbXTtcbiAgdHJ5IHtcbiAgICBsZXQgdmlld2VyID0gdHYuYWRkVmlld2VyKHYpO1xuICAgIGF3YWl0IGF3YWl0Q2hlY2soKCkgPT4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikgIT09IG51bGwsXG4gICAgICAnY2Fubm90IGxvYWQgdmlld2VyJywgMzAwMCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIEFycmF5LmZyb20oZGYucm93KDApLmNlbGxzKS5mb3JFYWNoKChjKSA9PiBjLnZhbHVlID0gbnVsbCk7XG4gICAgZGYucm93cy5zZWxlY3QoKHJvdykgPT4gcm93LmlkeCA+IDEgJiYgcm93LmlkeCA8IDcpO1xuICAgIGZvciAobGV0IGkgPSA3OyBpIDwgMTI7IGkrKykgZGYuZmlsdGVyLnNldChpLCBmYWxzZSk7XG4gICAgZGYuY3VycmVudFJvd0lkeCA9IDE7XG4gICAgY29uc3QgcHJvcHMgPSB2aWV3ZXIuZ2V0T3B0aW9ucyh0cnVlKS5sb29rO1xuICAgIGNvbnN0IG5ld1Byb3BzOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHByb3BzKS5maWx0ZXIoKGspID0+IHR5cGVvZiBwcm9wc1trXSA9PT0gJ2Jvb2xlYW4nKS5mb3JFYWNoKChrKSA9PiBuZXdQcm9wc1trXSA9ICFwcm9wc1trXSk7XG4gICAgdmlld2VyLnNldE9wdGlvbnMobmV3UHJvcHMpO1xuICAgIGF3YWl0IGRlbGF5KDI1MCk7XG4gICAgY29uc3QgbGF5b3V0ID0gdHYuc2F2ZUxheW91dCgpO1xuICAgIGNvbnN0IG9sZFByb3BzID0gdmlld2VyLmdldE9wdGlvbnMoKS5sb29rO1xuICAgIHR2LnJlc2V0TGF5b3V0KCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIHR2LmxvYWRMYXlvdXQobGF5b3V0KTtcbiAgICBhd2FpdCBhd2FpdENoZWNrKCgpID0+IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpICE9PSBudWxsLFxuICAgICAgJ2Nhbm5vdCBsb2FkIHZpZXdlciBmcm9tIGxheW91dCcsIDMwMDApO1xuICAgIGF3YWl0IGRlbGF5KDI1MCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIHZpZXdlciA9IEFycmF5LmZyb20odHYudmlld2VycykuZmluZCgodikgPT4gdi50eXBlICE9PSAnR3JpZCcpITtcbiAgICBleHBlY3RBcnJheShyZXMsIFsyLCAxLCAyXSk7XG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHZpZXdlci5nZXRPcHRpb25zKCkubG9vayksIEpTT04uc3RyaW5naWZ5KG9sZFByb3BzKSk7XG4gIH0gZmluYWxseSB7XG4gICAgdHYuY2xvc2UoKTtcbiAgICBncm9rLnNoZWxsLmNsb3NlVGFibGUoZGYpO1xuICB9XG59XG4iXX0=","export function errorToConsole(err) {\n var _a;\n if (typeof err === 'string' || err instanceof String) {\n return err;\n }\n else if ('$thrownJsError' in err) {\n return errorToConsole(err['$thrownJsError']);\n }\n else if (err instanceof Error) {\n return (_a = err.stack) !== null && _a !== void 0 ? _a : err.message;\n }\n else {\n return err.toString();\n }\n}\nexport function rectToConsole(rect) {\n return `(x=${rect.x}, y=${rect.y}, w=${rect.width}, h=${rect.height})`;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG8tY29uc29sZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRvLWNvbnNvbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBS0EsTUFBTSxVQUFVLGNBQWMsQ0FBQyxHQUFROztJQUNyQyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLFlBQVksTUFBTSxFQUFFO1FBQ3BELE9BQU8sR0FBYSxDQUFDO0tBQ3RCO1NBQU0sSUFBSSxnQkFBZ0IsSUFBSSxHQUFHLEVBQUU7UUFDbEMsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztLQUM5QztTQUFNLElBQUksR0FBRyxZQUFZLEtBQUssRUFBRTtRQUMvQixPQUFPLE1BQUMsR0FBYSxDQUFDLEtBQUssbUNBQUssR0FBYSxDQUFDLE9BQU8sQ0FBQztLQUN2RDtTQUFNO1FBQ0wsT0FBTyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7S0FDdkI7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFhO0lBQ3pDLE9BQU8sTUFBTSxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEtBQUssT0FBTyxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUM7QUFDekUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHVpIGZyb20gJ2RhdGFncm9rLWFwaS91aSc7XG5pbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGVycm9yVG9Db25zb2xlKGVycjogYW55KTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnIHx8IGVyciBpbnN0YW5jZW9mIFN0cmluZykge1xuICAgIHJldHVybiBlcnIgYXMgc3RyaW5nO1xuICB9IGVsc2UgaWYgKCckdGhyb3duSnNFcnJvcicgaW4gZXJyKSB7XG4gICAgcmV0dXJuIGVycm9yVG9Db25zb2xlKGVyclsnJHRocm93bkpzRXJyb3InXSk7XG4gIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4gKGVyciBhcyBFcnJvcikuc3RhY2sgPz8gKGVyciBhcyBFcnJvcikubWVzc2FnZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZXJyLnRvU3RyaW5nKCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlY3RUb0NvbnNvbGUocmVjdDogREcuUmVjdCk6IHN0cmluZyB7XG4gIHJldHVybiBgKHg9JHtyZWN0Lnh9LCB5PSR7cmVjdC55fSwgdz0ke3JlY3Qud2lkdGh9LCBoPSR7cmVjdC5oZWlnaHR9KWA7XG59XG4iXX0=","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".colored-text-input > textarea {\\n width: 100%;\\n -webkit-text-fill-color: transparent;\\n background-color: transparent;\\n position: relative;\\n z-index: 1;\\n resize: none;\\n height: 22px; /* Fine tuned value to avoid \\\"jumping\\\" of the textarea upon autoresize */\\n}\\n\\n.colored-text-input > div {\\n /* The values here are fine tuned to those of the ui.input textarea in order\\n * to achieve precise overlap */\\n overflow: auto;\\n position: absolute;\\n pointer-events: none;\\n cursor: text;\\n z-index: 0;\\n max-width: 100%;\\n padding: 2px;\\n line-height: normal;\\n font-family: 'Roboto Mono', 'Roboto Mono Local', monospace;\\n font-size: 12px;\\n color: transparent;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/view/style/colored-text-input.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,WAAW;EACX,oCAAoC;EACpC,6BAA6B;EAC7B,kBAAkB;EAClB,UAAU;EACV,YAAY;EACZ,YAAY,EAAE,wEAAwE;AACxF;;AAEA;EACE;iCAC+B;EAC/B,cAAc;EACd,kBAAkB;EAClB,oBAAoB;EACpB,YAAY;EACZ,UAAU;EACV,eAAe;EACf,YAAY;EACZ,mBAAmB;EACnB,0DAA0D;EAC1D,eAAe;EACf,kBAAkB;EAClB,qBAAqB;EACrB,qBAAqB;AACvB\",\"sourcesContent\":[\".colored-text-input > textarea {\\n width: 100%;\\n -webkit-text-fill-color: transparent;\\n background-color: transparent;\\n position: relative;\\n z-index: 1;\\n resize: none;\\n height: 22px; /* Fine tuned value to avoid \\\"jumping\\\" of the textarea upon autoresize */\\n}\\n\\n.colored-text-input > div {\\n /* The values here are fine tuned to those of the ui.input textarea in order\\n * to achieve precise overlap */\\n overflow: auto;\\n position: absolute;\\n pointer-events: none;\\n cursor: text;\\n z-index: 0;\\n max-width: 100%;\\n padding: 2px;\\n line-height: normal;\\n font-family: 'Roboto Mono', 'Roboto Mono Local', monospace;\\n font-size: 12px;\\n color: transparent;\\n white-space: pre-wrap;\\n word-wrap: break-word;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n\\n.st-structure-body {\\n padding-right: 20px;\\n}\\n\\n.st-structure-input-form {\\n text-align: right;\\n vertical-align: top;\\n min-width: 95px;\\n}\\n\\n.st-structure-direction-choice label {\\n min-width: 100px;\\n float: right;\\n}\\n\\n.st-structure-direction-choice div {\\n justify-content: right;\\n}\\n\\n.st-structure-text-input-td { /* Style for td containing textarea */\\n width: 100%;\\n}\\n\\n.st-structure-mol-img {\\n margin-right: 30px;\\n float: right;\\n}\\n\\n.st-structure-bool-button-block {\\n justify-content: right;\\n margin-bottom: 10px;\\n}\\n\\n.st-structure-bottom {\\n flex-direction: row-reverse;\\n padding-top: 20px;\\n}\\n\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/view/style/structure-app.css\"],\"names\":[],\"mappings\":\"AAAA,gGAAgG;;AAEhG;EACE,mBAAmB;AACrB;;AAEA;EACE,iBAAiB;EACjB,mBAAmB;EACnB,eAAe;AACjB;;AAEA;EACE,gBAAgB;EAChB,YAAY;AACd;;AAEA;EACE,sBAAsB;AACxB;;AAEA,8BAA8B,qCAAqC;EACjE,WAAW;AACb;;AAEA;EACE,kBAAkB;EAClB,YAAY;AACd;;AAEA;EACE,sBAAsB;EACtB,mBAAmB;AACrB;;AAEA;EACE,2BAA2B;EAC3B,iBAAiB;AACnB\",\"sourcesContent\":[\"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n\\n.st-structure-body {\\n padding-right: 20px;\\n}\\n\\n.st-structure-input-form {\\n text-align: right;\\n vertical-align: top;\\n min-width: 95px;\\n}\\n\\n.st-structure-direction-choice label {\\n min-width: 100px;\\n float: right;\\n}\\n\\n.st-structure-direction-choice div {\\n justify-content: right;\\n}\\n\\n.st-structure-text-input-td { /* Style for td containing textarea */\\n width: 100%;\\n}\\n\\n.st-structure-mol-img {\\n margin-right: 30px;\\n float: right;\\n}\\n\\n.st-structure-bool-button-block {\\n justify-content: right;\\n margin-bottom: 10px;\\n}\\n\\n.st-structure-bottom {\\n flex-direction: row-reverse;\\n padding-top: 20px;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n.st-translator-input-table {\\n /* width: 100%; */\\n margin-right: 20px;\\n}\\n\\n.st-translator-input-table td:has(textarea) {\\n width: 100%;\\n}\\n\\n.st-translator-input-table td:has(select) {\\n min-width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table {\\n margin-top: 20px;\\n margin-right: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.st-translator-output-table table {\\n width: 100%;\\n table-layout: fixed;\\n}\\n\\n/* .st-translator-output-table table tbody tr td { */\\n/* max-width: 20%; */\\n/* } */\\n\\n.st-translator-output-table td {\\n padding-top: 6px;\\n padding-bottom: 6px;\\n}\\n.st-translator-output-table tr:nth-child(even) {\\n background-color: var(--grey-1);\\n}\\n\\n.st-translator-output-table td:nth-child(odd) {\\n width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table td a {\\n overflow-wrap: break-word;\\n}\\n\", \"\",{\"version\":3,\"sources\":[\"webpack://./src/view/style/translator-app.css\"],\"names\":[],\"mappings\":\"AAAA,gGAAgG;AAChG;EACE,iBAAiB;EACjB,kBAAkB;AACpB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,mBAAmB;AACrB;;AAEA;EACE,WAAW;EACX,mBAAmB;AACrB;;AAEA,oDAAoD;AACpD,sBAAsB;AACtB,MAAM;;AAEN;EACE,gBAAgB;EAChB,mBAAmB;AACrB;AACA;EACE,+BAA+B;AACjC;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,yBAAyB;AAC3B\",\"sourcesContent\":[\"/* Naming convention: class names should begin with st and app name to avoid naming collitions */\\n.st-translator-input-table {\\n /* width: 100%; */\\n margin-right: 20px;\\n}\\n\\n.st-translator-input-table td:has(textarea) {\\n width: 100%;\\n}\\n\\n.st-translator-input-table td:has(select) {\\n min-width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table {\\n margin-top: 20px;\\n margin-right: 20px;\\n margin-bottom: 10px;\\n}\\n\\n.st-translator-output-table table {\\n width: 100%;\\n table-layout: fixed;\\n}\\n\\n/* .st-translator-output-table table tbody tr td { */\\n/* max-width: 20%; */\\n/* } */\\n\\n.st-translator-output-table td {\\n padding-top: 6px;\\n padding-bottom: 6px;\\n}\\n.st-translator-output-table tr:nth-child(even) {\\n background-color: var(--grey-1);\\n}\\n\\n.st-translator-output-table td:nth-child(odd) {\\n width: 120px;\\n vertical-align: top;\\n}\\n\\n.st-translator-output-table td a {\\n overflow-wrap: break-word;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","\"use strict\";\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};","\"use strict\";\n\nmodule.exports = function (item) {\n var content = item[1];\n var cssMapping = item[3];\n if (!cssMapping) {\n return content;\n }\n if (typeof btoa === \"function\") {\n var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(cssMapping))));\n var data = \"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(base64);\n var sourceMapping = \"/*# \".concat(data, \" */\");\n return [content].concat([sourceMapping]).join(\"\\n\");\n }\n return [content].join(\"\\n\");\n};","'use strict';\n\n(function () {\n var out$ = typeof exports != 'undefined' && exports || typeof define != 'undefined' && {} || this || window;\n if (typeof define !== 'undefined') define('save-svg-as-png', [], function () {\n return out$;\n });\n out$.default = out$;\n\n var xmlNs = 'http://www.w3.org/2000/xmlns/';\n var xhtmlNs = 'http://www.w3.org/1999/xhtml';\n var svgNs = 'http://www.w3.org/2000/svg';\n var doctype = '<?xml version=\"1.0\" standalone=\"no\"?><!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" [<!ENTITY nbsp \"&#160;\">]>';\n var urlRegex = /url\\([\"']?(.+?)[\"']?\\)/;\n var fontFormats = {\n woff2: 'font/woff2',\n woff: 'font/woff',\n otf: 'application/x-font-opentype',\n ttf: 'application/x-font-ttf',\n eot: 'application/vnd.ms-fontobject',\n sfnt: 'application/font-sfnt',\n svg: 'image/svg+xml'\n };\n\n var isElement = function isElement(obj) {\n return obj instanceof HTMLElement || obj instanceof SVGElement;\n };\n var requireDomNode = function requireDomNode(el) {\n if (!isElement(el)) throw new Error('an HTMLElement or SVGElement is required; got ' + el);\n };\n var requireDomNodePromise = function requireDomNodePromise(el) {\n return new Promise(function (resolve, reject) {\n if (isElement(el)) resolve(el);else reject(new Error('an HTMLElement or SVGElement is required; got ' + el));\n });\n };\n var isExternal = function isExternal(url) {\n return url && url.lastIndexOf('http', 0) === 0 && url.lastIndexOf(window.location.host) === -1;\n };\n\n var getFontMimeTypeFromUrl = function getFontMimeTypeFromUrl(fontUrl) {\n var formats = Object.keys(fontFormats).filter(function (extension) {\n return fontUrl.indexOf('.' + extension) > 0;\n }).map(function (extension) {\n return fontFormats[extension];\n });\n if (formats) return formats[0];\n console.error('Unknown font format for ' + fontUrl + '. Fonts may not be working correctly.');\n return 'application/octet-stream';\n };\n\n var arrayBufferToBase64 = function arrayBufferToBase64(buffer) {\n var binary = '';\n var bytes = new Uint8Array(buffer);\n for (var i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }return window.btoa(binary);\n };\n\n var getDimension = function getDimension(el, clone, dim) {\n var v = el.viewBox && el.viewBox.baseVal && el.viewBox.baseVal[dim] || clone.getAttribute(dim) !== null && !clone.getAttribute(dim).match(/%$/) && parseInt(clone.getAttribute(dim)) || el.getBoundingClientRect()[dim] || parseInt(clone.style[dim]) || parseInt(window.getComputedStyle(el).getPropertyValue(dim));\n return typeof v === 'undefined' || v === null || isNaN(parseFloat(v)) ? 0 : v;\n };\n\n var getDimensions = function getDimensions(el, clone, width, height) {\n if (el.tagName === 'svg') return {\n width: width || getDimension(el, clone, 'width'),\n height: height || getDimension(el, clone, 'height')\n };else if (el.getBBox) {\n var _el$getBBox = el.getBBox(),\n x = _el$getBBox.x,\n y = _el$getBBox.y,\n _width = _el$getBBox.width,\n _height = _el$getBBox.height;\n\n return {\n width: x + _width,\n height: y + _height\n };\n }\n };\n\n var reEncode = function reEncode(data) {\n return decodeURIComponent(encodeURIComponent(data).replace(/%([0-9A-F]{2})/g, function (match, p1) {\n var c = String.fromCharCode('0x' + p1);\n return c === '%' ? '%25' : c;\n }));\n };\n\n var uriToBlob = function uriToBlob(uri) {\n var byteString = window.atob(uri.split(',')[1]);\n var mimeString = uri.split(',')[0].split(':')[1].split(';')[0];\n var buffer = new ArrayBuffer(byteString.length);\n var intArray = new Uint8Array(buffer);\n for (var i = 0; i < byteString.length; i++) {\n intArray[i] = byteString.charCodeAt(i);\n }\n return new Blob([buffer], { type: mimeString });\n };\n\n var query = function query(el, selector) {\n if (!selector) return;\n try {\n return el.querySelector(selector) || el.parentNode && el.parentNode.querySelector(selector);\n } catch (err) {\n console.warn('Invalid CSS selector \"' + selector + '\"', err);\n }\n };\n\n var detectCssFont = function detectCssFont(rule, href) {\n // Match CSS font-face rules to external links.\n // @font-face {\n // src: local('Abel'), url(https://fonts.gstatic.com/s/abel/v6/UzN-iejR1VoXU2Oc-7LsbvesZW2xOQ-xsNqO47m55DA.woff2);\n // }\n var match = rule.cssText.match(urlRegex);\n var url = match && match[1] || '';\n if (!url || url.match(/^data:/) || url === 'about:blank') return;\n var fullUrl = url.startsWith('../') ? href + '/../' + url : url.startsWith('./') ? href + '/.' + url : url;\n return {\n text: rule.cssText,\n format: getFontMimeTypeFromUrl(fullUrl),\n url: fullUrl\n };\n };\n\n var inlineImages = function inlineImages(el) {\n return Promise.all(Array.from(el.querySelectorAll('image')).map(function (image) {\n var href = image.getAttributeNS('http://www.w3.org/1999/xlink', 'href') || image.getAttribute('href');\n if (!href) return Promise.resolve(null);\n if (isExternal(href)) {\n href += (href.indexOf('?') === -1 ? '?' : '&') + 't=' + new Date().valueOf();\n }\n return new Promise(function (resolve, reject) {\n var canvas = document.createElement('canvas');\n var img = new Image();\n img.crossOrigin = 'anonymous';\n img.src = href;\n img.onerror = function () {\n return reject(new Error('Could not load ' + href));\n };\n img.onload = function () {\n canvas.width = img.width;\n canvas.height = img.height;\n canvas.getContext('2d').drawImage(img, 0, 0);\n image.setAttributeNS('http://www.w3.org/1999/xlink', 'href', canvas.toDataURL('image/png'));\n resolve(true);\n };\n });\n }));\n };\n\n var cachedFonts = {};\n var inlineFonts = function inlineFonts(fonts) {\n return Promise.all(fonts.map(function (font) {\n return new Promise(function (resolve, reject) {\n if (cachedFonts[font.url]) return resolve(cachedFonts[font.url]);\n\n var req = new XMLHttpRequest();\n req.addEventListener('load', function () {\n // TODO: it may also be worth it to wait until fonts are fully loaded before\n // attempting to rasterize them. (e.g. use https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet)\n var fontInBase64 = arrayBufferToBase64(req.response);\n var fontUri = font.text.replace(urlRegex, 'url(\"data:' + font.format + ';base64,' + fontInBase64 + '\")') + '\\n';\n cachedFonts[font.url] = fontUri;\n resolve(fontUri);\n });\n req.addEventListener('error', function (e) {\n console.warn('Failed to load font from: ' + font.url, e);\n cachedFonts[font.url] = null;\n resolve(null);\n });\n req.addEventListener('abort', function (e) {\n console.warn('Aborted loading font from: ' + font.url, e);\n resolve(null);\n });\n req.open('GET', font.url);\n req.responseType = 'arraybuffer';\n req.send();\n });\n })).then(function (fontCss) {\n return fontCss.filter(function (x) {\n return x;\n }).join('');\n });\n };\n\n var cachedRules = null;\n var styleSheetRules = function styleSheetRules() {\n if (cachedRules) return cachedRules;\n return cachedRules = Array.from(document.styleSheets).map(function (sheet) {\n try {\n return { rules: sheet.cssRules, href: sheet.href };\n } catch (e) {\n console.warn('Stylesheet could not be loaded: ' + sheet.href, e);\n return {};\n }\n });\n };\n\n var inlineCss = function inlineCss(el, options) {\n var _ref = options || {},\n selectorRemap = _ref.selectorRemap,\n modifyStyle = _ref.modifyStyle,\n modifyCss = _ref.modifyCss,\n fonts = _ref.fonts,\n excludeUnusedCss = _ref.excludeUnusedCss;\n\n var generateCss = modifyCss || function (selector, properties) {\n var sel = selectorRemap ? selectorRemap(selector) : selector;\n var props = modifyStyle ? modifyStyle(properties) : properties;\n return sel + '{' + props + '}\\n';\n };\n var css = [];\n var detectFonts = typeof fonts === 'undefined';\n var fontList = fonts || [];\n styleSheetRules().forEach(function (_ref2) {\n var rules = _ref2.rules,\n href = _ref2.href;\n\n if (!rules) return;\n Array.from(rules).forEach(function (rule) {\n if (typeof rule.style != 'undefined') {\n if (query(el, rule.selectorText)) css.push(generateCss(rule.selectorText, rule.style.cssText));else if (detectFonts && rule.cssText.match(/^@font-face/)) {\n var font = detectCssFont(rule, href);\n if (font) fontList.push(font);\n } else if (!excludeUnusedCss) {\n css.push(rule.cssText);\n }\n }\n });\n });\n\n return inlineFonts(fontList).then(function (fontCss) {\n return css.join('\\n') + fontCss;\n });\n };\n\n var downloadOptions = function downloadOptions() {\n if (!navigator.msSaveOrOpenBlob && !('download' in document.createElement('a'))) {\n return { popup: window.open() };\n }\n };\n\n out$.prepareSvg = function (el, options, done) {\n requireDomNode(el);\n\n var _ref3 = options || {},\n _ref3$left = _ref3.left,\n left = _ref3$left === undefined ? 0 : _ref3$left,\n _ref3$top = _ref3.top,\n top = _ref3$top === undefined ? 0 : _ref3$top,\n w = _ref3.width,\n h = _ref3.height,\n _ref3$scale = _ref3.scale,\n scale = _ref3$scale === undefined ? 1 : _ref3$scale,\n _ref3$responsive = _ref3.responsive,\n responsive = _ref3$responsive === undefined ? false : _ref3$responsive,\n _ref3$excludeCss = _ref3.excludeCss,\n excludeCss = _ref3$excludeCss === undefined ? false : _ref3$excludeCss;\n\n return inlineImages(el).then(function () {\n var clone = el.cloneNode(true);\n clone.style.backgroundColor = (options || {}).backgroundColor || el.style.backgroundColor;\n\n var _getDimensions = getDimensions(el, clone, w, h),\n width = _getDimensions.width,\n height = _getDimensions.height;\n\n if (el.tagName !== 'svg') {\n if (el.getBBox) {\n if (clone.getAttribute('transform') != null) {\n clone.setAttribute('transform', clone.getAttribute('transform').replace(/translate\\(.*?\\)/, ''));\n }\n var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.appendChild(clone);\n clone = svg;\n } else {\n console.error('Attempted to render non-SVG element', el);\n return;\n }\n }\n\n clone.setAttribute('version', '1.1');\n clone.setAttribute('viewBox', [left, top, width, height].join(' '));\n if (!clone.getAttribute('xmlns')) clone.setAttributeNS(xmlNs, 'xmlns', svgNs);\n if (!clone.getAttribute('xmlns:xlink')) clone.setAttributeNS(xmlNs, 'xmlns:xlink', 'http://www.w3.org/1999/xlink');\n\n if (responsive) {\n clone.removeAttribute('width');\n clone.removeAttribute('height');\n clone.setAttribute('preserveAspectRatio', 'xMinYMin meet');\n } else {\n clone.setAttribute('width', width * scale);\n clone.setAttribute('height', height * scale);\n }\n\n Array.from(clone.querySelectorAll('foreignObject > *')).forEach(function (foreignObject) {\n foreignObject.setAttributeNS(xmlNs, 'xmlns', foreignObject.tagName === 'svg' ? svgNs : xhtmlNs);\n });\n\n if (excludeCss) {\n var outer = document.createElement('div');\n outer.appendChild(clone);\n var src = outer.innerHTML;\n if (typeof done === 'function') done(src, width, height);else return { src: src, width: width, height: height };\n } else {\n return inlineCss(el, options).then(function (css) {\n var style = document.createElement('style');\n style.setAttribute('type', 'text/css');\n style.innerHTML = '<![CDATA[\\n' + css + '\\n]]>';\n\n var defs = document.createElement('defs');\n defs.appendChild(style);\n clone.insertBefore(defs, clone.firstChild);\n\n var outer = document.createElement('div');\n outer.appendChild(clone);\n var src = outer.innerHTML.replace(/NS\\d+:href/gi, 'xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href');\n\n if (typeof done === 'function') done(src, width, height);else return { src: src, width: width, height: height };\n });\n }\n });\n };\n\n out$.svgAsDataUri = function (el, options, done) {\n requireDomNode(el);\n return out$.prepareSvg(el, options).then(function (_ref4) {\n var src = _ref4.src,\n width = _ref4.width,\n height = _ref4.height;\n\n var svgXml = 'data:image/svg+xml;base64,' + window.btoa(reEncode(doctype + src));\n if (typeof done === 'function') {\n done(svgXml, width, height);\n }\n return svgXml;\n });\n };\n\n out$.svgAsPngUri = function (el, options, done) {\n requireDomNode(el);\n\n var _ref5 = options || {},\n _ref5$encoderType = _ref5.encoderType,\n encoderType = _ref5$encoderType === undefined ? 'image/png' : _ref5$encoderType,\n _ref5$encoderOptions = _ref5.encoderOptions,\n encoderOptions = _ref5$encoderOptions === undefined ? 0.8 : _ref5$encoderOptions,\n canvg = _ref5.canvg;\n\n var convertToPng = function convertToPng(_ref6) {\n var src = _ref6.src,\n width = _ref6.width,\n height = _ref6.height;\n\n var canvas = document.createElement('canvas');\n var context = canvas.getContext('2d');\n var pixelRatio = window.devicePixelRatio || 1;\n\n canvas.width = width * pixelRatio;\n canvas.height = height * pixelRatio;\n canvas.style.width = canvas.width + 'px';\n canvas.style.height = canvas.height + 'px';\n context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);\n\n if (canvg) canvg(canvas, src);else context.drawImage(src, 0, 0);\n\n var png = void 0;\n try {\n png = canvas.toDataURL(encoderType, encoderOptions);\n } catch (e) {\n if (typeof SecurityError !== 'undefined' && e instanceof SecurityError || e.name === 'SecurityError') {\n console.error('Rendered SVG images cannot be downloaded in this browser.');\n return;\n } else throw e;\n }\n if (typeof done === 'function') done(png, canvas.width, canvas.height);\n return Promise.resolve(png);\n };\n\n if (canvg) return out$.prepareSvg(el, options).then(convertToPng);else return out$.svgAsDataUri(el, options).then(function (uri) {\n return new Promise(function (resolve, reject) {\n var image = new Image();\n image.onload = function () {\n return resolve(convertToPng({\n src: image,\n width: image.width,\n height: image.height\n }));\n };\n image.onerror = function () {\n reject('There was an error loading the data URI as an image on the following SVG\\n' + window.atob(uri.slice(26)) + 'Open the following link to see browser\\'s diagnosis\\n' + uri);\n };\n image.src = uri;\n });\n });\n };\n\n out$.download = function (name, uri, options) {\n if (navigator.msSaveOrOpenBlob) navigator.msSaveOrOpenBlob(uriToBlob(uri), name);else {\n var saveLink = document.createElement('a');\n if ('download' in saveLink) {\n saveLink.download = name;\n saveLink.style.display = 'none';\n document.body.appendChild(saveLink);\n try {\n var blob = uriToBlob(uri);\n var url = URL.createObjectURL(blob);\n saveLink.href = url;\n saveLink.onclick = function () {\n return requestAnimationFrame(function () {\n return URL.revokeObjectURL(url);\n });\n };\n } catch (e) {\n console.error(e);\n console.warn('Error while getting object URL. Falling back to string URL.');\n saveLink.href = uri;\n }\n saveLink.click();\n document.body.removeChild(saveLink);\n } else if (options && options.popup) {\n options.popup.document.title = name;\n options.popup.location.replace(uri);\n }\n }\n };\n\n out$.saveSvg = function (el, name, options) {\n var downloadOpts = downloadOptions(); // don't inline, can't be async\n return requireDomNodePromise(el).then(function (el) {\n return out$.svgAsDataUri(el, options || {});\n }).then(function (uri) {\n return out$.download(name, uri, downloadOpts);\n });\n };\n\n out$.saveSvgAsPng = function (el, name, options) {\n var downloadOpts = downloadOptions(); // don't inline, can't be async\n return requireDomNodePromise(el).then(function (el) {\n return out$.svgAsPngUri(el, options || {});\n }).then(function (uri) {\n return out$.download(name, uri, downloadOpts);\n });\n };\n})();","\"use strict\";\n\nvar stylesInDOM = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n\n return updater;\n}\n\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n\n stylesInDOM.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};","\"use strict\";\n\nvar memo = {};\n/* istanbul ignore next */\n\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n}\n/* istanbul ignore next */\n\n\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n}\n\nmodule.exports = insertBySelector;","\"use strict\";\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\n\nmodule.exports = insertStyleElement;","\"use strict\";\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = typeof __webpack_nonce__ !== \"undefined\" ? __webpack_nonce__ : null;\n\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\n\nmodule.exports = setAttributesWithoutAttributes;","\"use strict\";\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n\n var needLayer = typeof obj.layer !== \"undefined\";\n\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n\n css += obj.css;\n\n if (needLayer) {\n css += \"}\";\n }\n\n if (obj.media) {\n css += \"}\";\n }\n\n if (obj.supports) {\n css += \"}\";\n }\n\n var sourceMap = obj.sourceMap;\n\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n options.styleTagTransform(css, styleElement, options.options);\n}\n\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n\n styleElement.parentNode.removeChild(styleElement);\n}\n/* istanbul ignore next */\n\n\nfunction domAPI(options) {\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\n\nmodule.exports = domAPI;","\"use strict\";\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n\n styleElement.appendChild(document.createTextNode(css));\n }\n}\n\nmodule.exports = styleTagTransform;","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nexport const NUCLEOTIDES = ['A', 'G', 'C', 'U', 'T'];\n\nexport const TECHNOLOGIES = {\n DNA: 'DNA',\n RNA: 'RNA',\n ASO_GAPMERS: 'ASOGapmers',\n SI_RNA: 'siRNA',\n};\n\nexport enum DEFAULT_FORMATS {\n HELM = 'HELM',\n AXOLABS = 'Axolabs',\n}\n","export const LIB_PATH = 'System:AppData/SequenceTranslator';\nexport const DEFAULT_LIB_FILENAME = 'monomer-lib.json';\n\nexport const APP_PATH = 'System:AppData/SequenceTranslator';\nexport const AXOLABS_STYLE_FILENAME = 'axolabs-style.json';\nexport const CODES_TO_HELM_DICT_FILENAME = 'formats-to-helm.json';\nexport const CODES_TO_SYMBOLS_FILENAME = 'codes-to-symbols.json';\nexport const MONOMERS_WITH_PHOSPHATE_LINKERS = 'linkers.json';\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {APP_PATH, AXOLABS_STYLE_FILENAME, CODES_TO_HELM_DICT_FILENAME, CODES_TO_SYMBOLS_FILENAME, MONOMERS_WITH_PHOSPHATE_LINKERS} from './const';\nimport {AxolabsStyle, FormatToHELMDict, CodeToSymbol} from './types';\n\nconst fileSource = new DG.FileSource(APP_PATH);\n\nexport let axolabsStyleMap: AxolabsStyle;\nexport let codesToHelmDictionary: FormatToHELMDict;\nexport let codesToSymbolsDictionary: CodeToSymbol;\nexport let monomersWithPhosphateLinkers: {[key: string]: string[]};\n\nexport async function getJsonData(): Promise<void> {\n const data = [axolabsStyleMap, codesToHelmDictionary, codesToSymbolsDictionary, monomersWithPhosphateLinkers];\n\n if (data.every((item) => item !== undefined))\n return;\n\n axolabsStyleMap = await parse(AXOLABS_STYLE_FILENAME);\n codesToHelmDictionary = await parse(CODES_TO_HELM_DICT_FILENAME);\n codesToSymbolsDictionary = await parse(CODES_TO_SYMBOLS_FILENAME);\n monomersWithPhosphateLinkers = await parse(MONOMERS_WITH_PHOSPHATE_LINKERS);\n}\n\nasync function parse(path: string): Promise<any> {\n let parsedJson: string;\n try {\n parsedJson = JSON.parse(await fileSource.readAsText(path))\n } catch (err: any) {\n const errMsg: string = err.hasOwnProperty('message') ? err.message : err.toString();\n throw new Error(`Error loading json from ${path}:` + errMsg);\n }\n return parsedJson;\n}\n\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nexport function sortByReverseLength(array: string[]): string[] {\n return array.sort((a, b) => b.length - a.length);\n}\n\nexport function download(name: string, href: string): void {\n const element = document.createElement('a');\n element.setAttribute('href', 'data:text/plain;charset=utf-8,' + href);\n element.setAttribute('download', name);\n element.click();\n}\n\nexport async function tryCatch<T>(func: () => Promise<T>, finallyFunc?: () => any, callbackName: string = 'Oligo app'): Promise<T> {\n try {\n return await func();\n } catch (err: any) {\n const errMsg: string = err.hasOwnProperty('message') ? err.message : err.toString();\n grok.shell.error(`${callbackName} error: ` + errMsg);\n throw err;\n } finally {\n if (finallyFunc)\n finallyFunc();\n }\n};\n\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {_package} from '../../package';\nimport {DEFAULT_FORMATS} from '../const';\n\nimport {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';\n\nimport {HELM_REQUIRED_FIELDS as REQ, HELM_OPTIONAL_FIELDS as OPT} from '@datagrok-libraries/bio/src/utils/const';\nimport {META_FIELDS as MET} from './const';\nimport {codesToSymbolsDictionary} from '../../model/data-loading-utils/json-loader';\n\nexport class MonomerLibWrapper {\n private constructor() {\n const lib = _package.monomerLib;\n if (lib === null)\n throw new Error('SequenceTranslator: monomer library is null');\n this.lib = lib!;\n this.allMonomers = this.getAllMonomers();\n }\n\n private lib: IMonomerLib;\n private static instance?: MonomerLibWrapper;\n private allMonomers: Monomer[];\n\n private formatMonomerForViewer(sourceObj: Monomer): {[key: string]: string} {\n const formattedObject: {[key: string]: string} = {};\n formattedObject[REQ.NAME] = sourceObj[REQ.SYMBOL];\n formattedObject[REQ.SYMBOL] = sourceObj[REQ.SYMBOL];\n formattedObject[REQ.MOLFILE] = sourceObj[REQ.MOLFILE];\n const formats = this.getAllFormats();\n formats.forEach((format) => {\n if (format === DEFAULT_FORMATS.HELM)\n return;\n const map = codesToSymbolsDictionary[format];\n const codes = Object.keys(map).filter((code) => map[code] === sourceObj.symbol);\n formattedObject[format] = codes.join(', ');\n })\n\n return formattedObject;\n }\n\n private getAllMonomers(): Monomer[] {\n const polymerTypes = this.lib.getPolymerTypes();\n let result: Monomer[] = [];\n for (const polymerType of polymerTypes) {\n const monomerSymbols = this.lib.getMonomerSymbolsByType(polymerType);\n const monomersByType: Monomer[] = monomerSymbols\n .map((monomerSymbol) => this.lib.getMonomer(polymerType, monomerSymbol))\n .filter((monomer): monomer is Monomer => monomer !== null);\n result = result.concat(monomersByType);\n }\n return result;\n }\n\n private getMonomer(monomerSymbol: string): Monomer {\n const monomer = this.lib.getMonomer('RNA', monomerSymbol);\n if (monomer === undefined)\n throw new Error(`SequenceTranslator: no monomer with symbol ${monomerSymbol}`);\n return monomer!;\n }\n\n static getInstance(): MonomerLibWrapper {\n if (MonomerLibWrapper.instance === undefined)\n MonomerLibWrapper.instance = new MonomerLibWrapper();\n return MonomerLibWrapper.instance!;\n }\n\n getMolfileBySymbol(monomerSymbol: string): string {\n const monomer = this.getMonomer(monomerSymbol);\n return monomer.molfile;\n }\n\n getNaturalAnalogBySymbol(monomerSymbol: string): string {\n const monomer = this.getMonomer(monomerSymbol);\n const naturalAnalog = monomer.naturalAnalog;\n if (!naturalAnalog)\n throw new Error(`ST: no natural analog for ${monomerSymbol}`);\n return naturalAnalog!;\n }\n\n // todo: a better criterion\n isModification(monomerSymbol: string): boolean {\n const molfile = this.getMolfileBySymbol(monomerSymbol);\n return (molfile.includes('MODIFICATION')) ? true : false;\n }\n\n getCodeToSymbolMap(format: string): Map<string, string> {\n return new Map<string, string>(Object.entries(codesToSymbolsDictionary[format]));\n }\n\n getCodesByFormat(format: string): string[] {\n return Object.keys(codesToSymbolsDictionary[format]);\n }\n\n getAllFormats(): string[] {\n return Object.keys(codesToSymbolsDictionary);\n }\n\n getTableForViewer(): DG.DataFrame {\n const formattedObjects = this.allMonomers.map((monomer) => this.formatMonomerForViewer(monomer));\n const df = DG.DataFrame.fromObjects(formattedObjects)!;\n return df;\n }\n\n getCodesToWeightsMap(): Map<string, number> {\n const codesToWeightsMap = new Map<string, number>();\n Object.entries(codesToSymbolsDictionary).forEach(([_, dict]) => {\n Object.entries(dict).forEach(([code, monomerSymbol]) => {\n const monomer = this.getMonomer(monomerSymbol);\n const weight = monomer[OPT.META]?.[MET.MOLWEIGHT];\n codesToWeightsMap.set(code, weight);\n });\n });\n return codesToWeightsMap;\n }\n}\n","import {NUCLEOTIDES} from '../const';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\nimport {sortByReverseLength} from '../helpers';\nimport {DEFAULT_FORMATS} from '../const';\n\nexport class SequenceValidator {\n constructor(private sequence: string) {\n this.libWrapper = MonomerLibWrapper.getInstance();\n };\n private libWrapper: MonomerLibWrapper;\n\n getInvalidCodeIndex(format: string): number {\n if (format === DEFAULT_FORMATS.HELM)\n return this.sequence.length;\n const firstUniqueCharacters = ['r', 'd']; // what for?\n const codes = sortByReverseLength(\n this.libWrapper.getCodesByFormat(format)\n );\n let indexOfFirstInvalidChar = 0;\n while (indexOfFirstInvalidChar < this.sequence.length) {\n const matchedCode = codes.find((code) => {\n const subSequence = this.sequence.substring(indexOfFirstInvalidChar, indexOfFirstInvalidChar + code.length);\n return code === subSequence;\n });\n\n if (!matchedCode) break;\n\n // todo: refactor the vague condition\n if ( // for mistake pattern 'rAA'\n indexOfFirstInvalidChar > 1 &&\n NUCLEOTIDES.includes(this.sequence[indexOfFirstInvalidChar]) &&\n firstUniqueCharacters.includes(this.sequence[indexOfFirstInvalidChar - 2])\n ) break;\n\n if ( // for mistake pattern 'ArA'\n firstUniqueCharacters.includes(this.sequence[indexOfFirstInvalidChar + 1]) &&\n NUCLEOTIDES.includes(this.sequence[indexOfFirstInvalidChar])\n ) {\n indexOfFirstInvalidChar++;\n break;\n }\n indexOfFirstInvalidChar += matchedCode.length;\n }\n if (indexOfFirstInvalidChar === this.sequence.length)\n indexOfFirstInvalidChar = -1\n return indexOfFirstInvalidChar;\n }\n\n isValidSequence(format: string): boolean {\n return this.getInvalidCodeIndex(format) === -1;\n }\n}\n","export const PHOSPHATE_SYMBOL = 'p';\n","export function getNucleotidesMol(codes: string[]) {\n const molBlocks: string[] = [];\n\n for (let i = 0; i < codes.length - 1; i++) {\n if (codes[i].includes('MODIFICATION')) {\n if (i === 0)\n molBlocks.push(reflect(codes[i]));\n else\n molBlocks.push(codes[i]);\n } else {\n molBlocks.push(rotateNucleotidesV3000(codes[i]));\n }\n }\n\n return linkV3000(molBlocks);\n}\n\nexport function linkStrandsV3000(\n strands: { senseStrands: string[], antiStrands: string[] }, useChirality: boolean = true\n): string {\n let macroMolBlock = '\\n Datagrok macromolecule handler\\n\\n';\n macroMolBlock += ' 0 0 0 0 0 0 999 V3000\\n';\n macroMolBlock += 'M V30 BEGIN CTAB\\n';\n let atomBlock = '';\n let bondBlock = '';\n let collectionBlock = '';\n const collection: number [] = [];\n let natom = 0;\n let nbond = 0;\n let xShift = 0;\n\n if (strands.antiStrands.length > 0) {\n for (let i = 0; i < strands.antiStrands.length; i++)\n strands.antiStrands[i] = invertNucleotidesV3000(strands.antiStrands[i]);\n }\n\n let inverted = false;\n const molBlocks = strands.senseStrands.concat(strands.antiStrands);\n /** Minimal value of AS and AS2 shift */\n let ssYShift = 0;\n\n for (let i = 0; i < molBlocks.length; i++) {\n molBlocks[i] = molBlocks[i].replaceAll('(-\\nM V30 ', '(')\n .replaceAll('-\\nM V30 ', '').replaceAll(' )', ')');\n const numbers = extractAtomsBondsNumbersV3000(molBlocks[i]);\n const coordinates = extractAtomDataV3000(molBlocks[i]);\n\n if (i >= strands.senseStrands.length) {\n if (inverted === false) {\n // AS strand\n inverted = true;\n xShift = 0;\n }\n } else {\n // SS strands\n ssYShift = Math.min(ssYShift, Math.min(\n ...coordinates.y.filter((item) => item < 0)\n ));\n }\n\n if (inverted) {\n const xShiftRight = Math.min(...coordinates.x) - xShift;\n const yShift = Math.max(...coordinates.y) + 5;\n for (let j = 0; j < coordinates.x.length; j++)\n coordinates.x[j] -= xShiftRight;\n for (let j = 0; j < coordinates.y.length; j++)\n coordinates.y[j] -= yShift - ssYShift;\n }\n\n let indexAtoms = molBlocks[i].indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n indexAtoms = molBlocks[i].indexOf('\\n', indexAtoms);\n let index = indexAtoms;\n let indexEnd = indexAtoms;\n\n for (let j = 0; j < numbers.natom; j++) {\n // if (coordinates.atomIndex[j] !== 1 || i === 0 || twoChains) {\n //rewrite atom number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite coordinates\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n\n const totalShift = true ? 0 : xShift - coordinates.x[0];\n let coordinate = true ?\n Math.round(10000 * coordinates.x[j]) / 10000 :\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)) + totalShift)) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n coordinate = true ?\n Math.round(10000 * coordinates.y[j]) / 10000 :\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)))) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexAtomsEnd = molBlocks[i].indexOf('M V30 END ATOM');\n atomBlock += molBlocks[i].substring(indexAtoms + 1, indexAtomsEnd);\n\n let indexBonds = molBlocks[i].indexOf('M V30 BEGIN BOND'); // V3000 index for bonds\n indexBonds = molBlocks[i].indexOf('\\n', indexBonds);\n index = indexBonds;\n indexEnd = indexBonds;\n\n for (let j = 0; j < numbers.nbond; j++) {\n //rewrite bond number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const bondNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + nbond;\n molBlocks[i] = molBlocks[i].slice(0, index) + bondNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite atom pair in bond\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = Math.min(molBlocks[i].indexOf('\\n', index), molBlocks[i].indexOf(' ', index));\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexBondEnd = molBlocks[i].indexOf('M V30 END BOND');\n bondBlock += molBlocks[i].substring(indexBonds + 1, indexBondEnd);\n\n let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections\n\n while (indexCollection !== -1) {\n indexCollection += 28;\n const collectionEnd = molBlocks[i].indexOf(')', indexCollection);\n const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);\n collectionEntries.forEach((e) => {\n collection.push(parseInt(e) + natom);\n });\n indexCollection = collectionEnd;\n indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);\n }\n\n natom += true ? numbers.natom : numbers.natom - 1;\n nbond += numbers.nbond;\n xShift += Math.max(...coordinates.x) + 5;//twoChains ? 0 : coordinates.x[numbers.natom - 1] - coordinates.x[0];\n }\n\n const entries = 4;\n const collNumber = Math.ceil(collection.length / entries);\n\n collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\\n';\n for (let i = 0; i < collNumber; i++) {\n collectionBlock += 'M V30 ';\n const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;\n for (let j = 0; j < entriesCurrent; j++) {\n collectionBlock += (j + 1 === entriesCurrent) ?\n (i === collNumber - 1 ? collection[entries * i + j] + ')\\n' : collection[entries * i + j] + ' -\\n') :\n collection[entries * i + j] + ' ';\n }\n }\n\n //generate file\n true ? natom : natom++;\n macroMolBlock += 'M V30 COUNTS ' + natom + ' ' + nbond + ' 0 0 0\\n';\n macroMolBlock += 'M V30 BEGIN ATOM\\n';\n macroMolBlock += atomBlock;\n macroMolBlock += 'M V30 END ATOM\\n';\n macroMolBlock += 'M V30 BEGIN BOND\\n';\n macroMolBlock += bondBlock;\n macroMolBlock += 'M V30 END BOND\\n';\n if (useChirality && collection.length > 0) {\n macroMolBlock += 'M V30 BEGIN COLLECTION\\n';\n macroMolBlock += collectionBlock;\n macroMolBlock += 'M V30 END COLLECTION\\n';\n } else {\n macroMolBlock = macroMolBlock.replace(/ CFG=\\d/g, ' ');\n }\n\n macroMolBlock += 'M V30 END CTAB\\n';\n macroMolBlock += 'M END';\n\n return macroMolBlock;\n}\n\nexport function linkV3000(molBlocks: string[], useChirality: boolean = true): string {\n let macroMolBlock = '\\n Datagrok macromolecule handler\\n\\n';\n macroMolBlock += ' 0 0 0 0 0 0 999 V3000\\n';\n macroMolBlock += 'M V30 BEGIN CTAB\\n';\n let atomBlock = '';\n let bondBlock = '';\n let collectionBlock = '';\n const collection: number [] = [];\n let natom = 0;\n let nbond = 0;\n let xShift = 0;\n\n for (let i = 0; i < molBlocks.length; i++) {\n const isBoundary = molBlocks[i].includes('MODIFICATION') && i === 0;\n let specLength = 0;\n if (isBoundary) {\n const coordinates = extractAtomDataV3000(molBlocks[i]);\n specLength = coordinates.atomIndex.length;\n }\n\n\n molBlocks[i] = molBlocks[i].replaceAll('(-\\nM V30 ', '(')\n .replaceAll('-\\nM V30 ', '').replaceAll(' )', ')');\n const numbers = extractAtomsBondsNumbersV3000(molBlocks[i]);\n const coordinates = extractAtomDataV3000(molBlocks[i]);\n\n let indexAtoms = molBlocks[i].indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n indexAtoms = molBlocks[i].indexOf('\\n', indexAtoms);\n let index = indexAtoms;\n let indexEnd = indexAtoms;\n\n for (let j = 0; j < numbers.natom; j++) {\n if (coordinates.atomIndex[j] !== 1 || i === 0) {\n //rewrite atom number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite coordinates\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n\n const totalShift = xShift - coordinates.x[0];\n let coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)) + totalShift)) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)))) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n } else {\n index = molBlocks[i].indexOf('M V30', index) - 1;\n indexEnd = molBlocks[i].indexOf('\\n', index + 1);\n molBlocks[i] = molBlocks[i].slice(0, index) + molBlocks[i].slice(indexEnd);\n }\n }\n\n const indexAtomsEnd = molBlocks[i].indexOf('M V30 END ATOM');\n atomBlock += molBlocks[i].substring(indexAtoms + 1, indexAtomsEnd);\n\n let indexBonds = molBlocks[i].indexOf('M V30 BEGIN BOND'); // V3000 index for bonds\n indexBonds = molBlocks[i].indexOf('\\n', indexBonds);\n index = indexBonds;\n indexEnd = indexBonds;\n\n for (let j = 0; j < numbers.nbond; j++) {\n //rewrite bond number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const bondNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + nbond;\n molBlocks[i] = molBlocks[i].slice(0, index) + bondNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite atom pair in bond\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = Math.min(molBlocks[i].indexOf('\\n', index), molBlocks[i].indexOf(' ', index));\n atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexBondEnd = molBlocks[i].indexOf('M V30 END BOND');\n bondBlock += molBlocks[i].substring(indexBonds + 1, indexBondEnd);\n\n let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections\n\n while (indexCollection !== -1) {\n indexCollection += 28;\n const collectionEnd = molBlocks[i].indexOf(')', indexCollection);\n const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);\n collectionEntries.forEach((e) => {\n collection.push(parseInt(e) + natom);\n });\n indexCollection = collectionEnd;\n indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);\n }\n\n natom += numbers.natom - 1;\n nbond += numbers.nbond;\n if (isBoundary)\n xShift += Math.max(...coordinates.x);\n else\n xShift += coordinates.x[numbers.natom - 1] - coordinates.x[0];\n }\n\n const entries = 4;\n const collNumber = Math.ceil(collection.length / entries);\n\n collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\\n';\n for (let i = 0; i < collNumber; i++) {\n collectionBlock += 'M V30 ';\n const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;\n for (let j = 0; j < entriesCurrent; j++) {\n collectionBlock += (j + 1 === entriesCurrent) ?\n (i === collNumber - 1 ? collection[entries * i + j] + ')\\n' : collection[entries * i + j] + ' -\\n') :\n collection[entries * i + j] + ' ';\n }\n }\n //}\n\n //generate file\n natom++;\n macroMolBlock += 'M V30 COUNTS ' + natom + ' ' + nbond + ' 0 0 0\\n';\n macroMolBlock += 'M V30 BEGIN ATOM\\n';\n macroMolBlock += atomBlock;\n macroMolBlock += 'M V30 END ATOM\\n';\n macroMolBlock += 'M V30 BEGIN BOND\\n';\n macroMolBlock += bondBlock;\n macroMolBlock += 'M V30 END BOND\\n';\n if (useChirality && collection.length > 0) {\n macroMolBlock += 'M V30 BEGIN COLLECTION\\n';\n macroMolBlock += collectionBlock;\n macroMolBlock += 'M V30 END COLLECTION\\n';\n } else { macroMolBlock = macroMolBlock.replace(/ CFG=\\d/g, ' '); }\n\n macroMolBlock += 'M V30 END CTAB\\n';\n macroMolBlock += 'M END';\n\n return macroMolBlock;\n}\n\nfunction rotateNucleotidesV3000(molBlock: string): string {\n const coordinates = extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n //fix 5 prime if inadequate\n if (natom > 8)\n fix5Prime(coordinates, indexFivePrime, indexThreePrime);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n let angle = 0;\n if (coordinates.x[indexFivePrime] === 0) {\n angle = coordinates.y[indexFivePrime] > coordinates.y[indexThreePrime] ? Math.PI / 2 : 3 * Math.PI / 2;\n } else if (coordinates.y[indexFivePrime] === 0) {\n angle = coordinates.x[indexFivePrime] > coordinates.x[indexThreePrime] ? Math.PI : 0;\n } else {\n const derivative = coordinates.y[indexFivePrime] / coordinates.x[indexFivePrime];\n angle = derivative > 0 ?\n (coordinates.x[indexFivePrime] > 0 ? Math.PI - Math.atan(derivative) : Math.PI * 2 - Math.atan(derivative)) :\n (coordinates.x[indexFivePrime] > 0 ? -Math.PI - Math.atan(derivative) : Math.atan(derivative));\n }\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n for (let i = 0; i < natom; i++) {\n const xAdd = coordinates.x[i];\n coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;\n coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;\n }\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n}\n\nfunction reflect(molBlock: string): string {\n const coordinates = extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n //place to center\n for (let i = 0; i < natom; i++)\n coordinates.x[i] = -coordinates.x[i];\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n}\n\n\nfunction invertNucleotidesV3000(molBlock: string) {\n const coordinates = extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const xCenter = (Math.max(...coordinates.x) + Math.min(...coordinates.x)) / 2;\n const yCenter = (Math.max(...coordinates.y) + Math.min(...coordinates.y)) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n const angle = Math.PI;\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n for (let i = 0; i < natom; i++) {\n const xAdd = coordinates.x[i];\n coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;\n coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;\n }\n\n //place back\n const yShift = Math.max(...coordinates.y);\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] += xCenter;\n coordinates.y[i] -= yShift;\n }\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n}\n\nfunction fix5Prime(coordinates: { atomIndex: number[], atomType: string[], x: number[], y: number[] },\n indexFivePrime: number, indexThreePrime: number) {\n const indexFivePrimeNeighbour = indexFivePrime + 1;\n const xShift = coordinates.x[indexFivePrimeNeighbour];\n const yShift = coordinates.y[indexFivePrimeNeighbour];\n const base3PrimeX = coordinates.x[indexThreePrime] - xShift;\n const base3PrimeY = coordinates.y[indexThreePrime] - yShift;\n const base5PrimeX = coordinates.x[indexFivePrime] - xShift;\n const base5PrimeY = coordinates.y[indexFivePrime] - yShift;\n\n const rotated5PrimeX = base5PrimeX * Math.cos(Math.PI * 2 / 3) - base5PrimeY * Math.sin(Math.PI * 2 / 3);\n const rotated5PrimeY = base5PrimeX * Math.sin(Math.PI * 2 / 3) + base5PrimeY * Math.cos(Math.PI * 2 / 3);\n\n const dx = base5PrimeX - base3PrimeX;\n const dy = base5PrimeY - base3PrimeY;\n const dxRotated = rotated5PrimeX - base3PrimeX;\n const dyRotated = rotated5PrimeY - base3PrimeY;\n\n if (Math.sqrt(dyRotated * dyRotated + dxRotated * dxRotated) >= Math.sqrt(dy * dy + dx * dx)) {\n coordinates.x[indexFivePrime] = rotated5PrimeX + xShift;\n coordinates.y[indexFivePrime] = rotated5PrimeY + yShift;\n }\n}\n\nfunction extractAtomsBondsNumbersV3000(molBlock: string): { natom: number, nbond: number } {\n molBlock = molBlock.replaceAll('\\r', ''); //equalize old and new sdf standards\n let index = molBlock.indexOf('COUNTS') + 7; // V3000 index for atoms and bonds number\n let indexEnd = molBlock.indexOf(' ', index);\n\n const atomsNumber = parseInt(molBlock.substring(index, indexEnd));\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n const bondsNumber = parseInt(molBlock.substring(index, indexEnd));\n\n return {natom: atomsNumber, nbond: bondsNumber};\n}\n\nexport function extractAtomDataV3000(molBlock: string) {\n const numbers = extractAtomsBondsNumbersV3000(molBlock);\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n\n const indexes: number[] = Array(numbers.natom);\n const types: string[] = Array(numbers.natom);\n const x: number[] = Array(numbers.natom);\n const y: number[] = Array(numbers.natom);\n\n for (let i = 0; i < numbers.natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n indexEnd = molBlock.indexOf(' ', index);\n indexes[i] = parseInt(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n types[i] = molBlock.substring(index, indexEnd);\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n x[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n y[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return {atomIndex: indexes, atomType: types, x: x, y: y};\n}\n","export const GROUP_TYPE = {\n NUCLEOSIDE: 'nucleoside',\n LINKAGE: 'phosphateBackbone',\n} as const;\n\nexport const PHOSPHATE_SYMBOL = 'p';\n\nexport const UNKNOWN_SYMBOL = '<?>';\n","import {DEFAULT_FORMATS, NUCLEOTIDES} from '../const';\nimport {UNKNOWN_SYMBOL} from './const';\nimport {FormatConverter} from './format-converter';\nimport {codesToHelmDictionary} from '../data-loading-utils/json-loader';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\n\nexport function getTranslatedSequences(sequence: string, indexOfFirstInvalidChar: number, sourceFormat: string): {[key: string]: string} {\n const supportedFormats = Object.keys(codesToHelmDictionary).concat([DEFAULT_FORMATS.HELM]) as string[];\n\n if (!sequence || (indexOfFirstInvalidChar !== -1 && sourceFormat !== DEFAULT_FORMATS.HELM))\n return {};\n\n if (!supportedFormats.includes(sourceFormat))\n throw new Error(`${sourceFormat} format is not supported by SequenceTranslator`)\n\n const outputFormats = supportedFormats.filter((el) => el != sourceFormat)\n .sort((a, b) => a.localeCompare(b));\n const converter = new FormatConverter(sequence, sourceFormat);\n const result = Object.fromEntries(\n outputFormats.map((format) => {\n let translation;\n try {\n translation = converter.convertTo(format);\n } catch {\n translation = null;\n }\n return [format, translation];\n }).filter(([format, translation]) => translation)\n )\n const helm = (sourceFormat === DEFAULT_FORMATS.HELM) ? sequence : result[DEFAULT_FORMATS.HELM];\n const nucleotides = getNucleotidesSequence(helm, MonomerLibWrapper.getInstance());\n if (nucleotides)\n result['Nucleotides'] = nucleotides;\n return result;\n}\n\nexport function getNucleotidesSequence(helmString: string, monomerLib: MonomerLibWrapper): string | null {\n const re = new RegExp('\\\\([^()]*\\\\)', 'g');\n const branches = helmString.match(re);\n if (!branches)\n return null;\n const nucleotides = branches!.map((branch) => {\n const stripped = branch.replace(/[\\[\\]()]/g, '');\n if (NUCLEOTIDES.includes(stripped))\n return stripped;\n return monomerLib.getNaturalAnalogBySymbol(stripped);\n }).map((el) => el ? el : UNKNOWN_SYMBOL).join('');\n return nucleotides;\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {codesToHelmDictionary} from '../data-loading-utils/json-loader';\nimport {CodesInfo} from '../data-loading-utils/types';\nimport {DEFAULT_FORMATS} from '../const';\nimport {GROUP_TYPE, PHOSPHATE_SYMBOL} from '../translator-app/const';\n\nconst inverseLengthComparator = (a: string, b: string) => b.length - a.length;\n\nexport class FormatHandler {\n constructor() {\n this.formats = this.getFormats();\n }\n\n /** Includes all formats except HELM (the \"default\" one) */\n private formats: string[];\n\n /** All format names except HELM (the \"default\" one) */\n getFormatNames(): string[] {\n return this.formats.sort();\n };\n\n getCodesByFormat(format: string): string[] {\n this.validateFormat(format);\n\n if (this.isHelm(format))\n throw new Error(`Codes cannot be obtained for HELM`);\n return this.getFormatCodes(format);\n }\n\n getHelmToFormatDict(format: string): {[key: string]: string} {\n this.validateFormat(format);\n\n const codesInfoObject = codesToHelmDictionary[format] as CodesInfo;\n const dict = getHelmToCodeDict(codesInfoObject);\n return dict;\n }\n\n getFormatToHelmDict(format: string): {[key: string]: string} {\n this.validateFormat(format);\n\n const codesInfoObject = codesToHelmDictionary[format] as CodesInfo;\n const dict = Object.assign({}, ...Object.values(codesInfoObject)) as {[code: string]: string};\n return dict;\n }\n\n /** Get helm codes for the specified format */\n getTargetFormatHelmCodes(format: string): string[] {\n this.validateFormat(format);\n\n const dict = this.getHelmToFormatDict(format);\n const helmCodes = Object.keys(dict).sort(inverseLengthComparator);\n return helmCodes;\n }\n\n getTargetFormatHelmCodesRegExp(format: string): RegExp {\n this.validateFormat(format);\n\n const helmCodes = this.getTargetFormatHelmCodes(format);\n const helmRegExp = new RegExp(getRegExpPattern(helmCodes) + '|.', 'g');\n return helmRegExp;\n }\n\n getFormatRegExp(format: string): RegExp {\n this.validateFormat(format);\n\n if (this.isHelm(format))\n throw new Error(`Helm RegExp can be built for non-HELM target formats`);\n return this.getNonHelmFormatRegExp(format);\n }\n\n getPhosphateHelmCodesRegExp(format: string): RegExp {\n this.validateFormat(format);\n\n const codesInfoObject = codesToHelmDictionary[format] as CodesInfo;\n const phosphateHELMCodes = Array.from(\n new Set(Object.values(codesInfoObject[GROUP_TYPE.LINKAGE]))\n ).sort(inverseLengthComparator);\n const phosphateHELMPattern = getRegExpPattern(phosphateHELMCodes);\n const phosphateRegExp = new RegExp(`${PHOSPHATE_SYMBOL}\\.(${phosphateHELMPattern})`, 'g');\n return phosphateRegExp;\n }\n\n isValidFormat(format: string): boolean {\n return this.formats.includes(format);\n }\n\n private getFormats(): string[] {\n return Object.keys(codesToHelmDictionary);\n }\n\n private validateFormat(format: string) {\n if (!this.isValidFormat(format))\n throw new Error(`Invalid format: ${format}`);\n }\n\n private isHelm(format: string): boolean {\n return format === DEFAULT_FORMATS.HELM;\n }\n\n private getFormatCodes(format: string): string[] {\n const dict = this.getFormatToHelmDict(format);\n const formatCodes = Object.keys(dict).sort(inverseLengthComparator);\n return formatCodes;\n }\n \n private getNonHelmFormatRegExp(format: string): RegExp {\n const formatCodes = this.getCodesByFormat(format);\n const formatRegExp = new RegExp(getRegExpPattern(formatCodes) + '|\\\\([^()]*\\\\)|.', 'g'); // the added group before '|.' is to avoid mismatch inside parenths\n return formatRegExp;\n }\n}\n\nexport function getRegExpPattern(arr: string[]): string {\n const negativeLookBehind = '(?<!\\\\([^()]*)'; // not '(' followed by non-parenths\n const negativeLookAhead = '(?![^()]*\\\\))'; // not ')' preceded by non-parenths\n const escaped = arr.map((key) => key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n .map((key) => {\n if (!key.includes('(') && !key.includes(')'))\n return `${negativeLookBehind}${key}${negativeLookAhead}`;\n return key;\n });\n const result = escaped.join('|');\n return result;\n}\n\nfunction getHelmToCodeDict(infoObj: CodesInfo) {\n const result: {[key: string]: string | string[]} = {};\n Object.values(infoObj).forEach((obj: {[code: string]: string}) => {\n Object.entries(obj).forEach(([code, helm]) => {\n const key = helm.replace(/\\)p/g, ')').replace(/\\]p/g, ']');\n if (result[key] === undefined) {\n result[key] = [code];\n } else {\n (result[key] as string[]).push(code);\n }\n })\n });\n Object.entries(result).forEach(([key, value]) => {\n const sorted = (value as string[]).sort(inverseLengthComparator);\n result[key] = sorted[0] as string;\n })\n return result as {[key: string]: string};\n}\n","import * as DG from 'datagrok-api/dg';\nimport {DEFAULT_FORMATS} from '../const';\nimport {PHOSPHATE_SYMBOL, UNKNOWN_SYMBOL} from './const';\nimport {FormatHandler, getRegExpPattern} from '../parsing-validation/format-handler';\n\nconst HELM_WRAPPER = {\n LEFT: 'RNA1{',\n RIGHT: '}$$$$',\n};\n\nexport class FormatConverter {\n constructor(private readonly sequence: string, private readonly sourceFormat: string) { };\n\n private formats = new FormatHandler();\n\n convertTo(targetFormat: string): string {\n const formats = this.formats.getFormatNames();\n\n if (this.sourceFormat === DEFAULT_FORMATS.HELM && formats.includes(targetFormat))\n return this.helmToFormat(this.sequence, targetFormat);\n else if (formats.includes(this.sourceFormat) && targetFormat === DEFAULT_FORMATS.HELM)\n return this.formatToHelm(this.sequence, this.sourceFormat);\n else if ([this.sourceFormat, targetFormat].every((el) => formats.includes(el))) {\n const helm = this.formatToHelm(this.sequence, this.sourceFormat);\n return this.helmToFormat(helm, targetFormat);\n }\n else {\n throw new Error (`ST: unsupported translation direction ${this.sourceFormat} -> ${targetFormat}`);\n }\n }\n\n private helmToFormat(helmSequence: string, targetFormat: string): string {\n const wrapperRegExp = new RegExp(getRegExpPattern(Object.values(HELM_WRAPPER)), 'g')\n let result = helmSequence.replace(wrapperRegExp, '');\n\n const dict = this.formats.getHelmToFormatDict(targetFormat);\n const helmCodes = this.formats.getTargetFormatHelmCodes(targetFormat);\n const helmRegExp = this.formats.getTargetFormatHelmCodesRegExp(targetFormat);\n\n result = result.replace(helmRegExp, (match) => {\n return helmCodes.includes(match) ? dict[match] :\n (match === 'p' || match === '.') ? match : '?';\n }).replace(/\\?+/g, UNKNOWN_SYMBOL).replace(/p\\.|\\./g, '');\n result = result.replace(/<empty>/g, '');\n // remove double slash in LCMS codes\n result = result.replace(/\\/\\//g, '/');\n return result;\n }\n\n private formatToHelm(sequence: string, sourceFormat: string): string {\n const dict = this.formats.getFormatToHelmDict(sourceFormat);\n const formatCodes = this.formats.getCodesByFormat(sourceFormat);\n const formatRegExp = this.formats.getFormatRegExp(sourceFormat);\n const phosphateRegExp = this.formats.getPhosphateHelmCodesRegExp(sourceFormat);\n\n let helm = sequence.replace(formatRegExp, (match) => {\n const result = formatCodes.includes(match) ? dict[match] + '.' : '?';\n return result;\n });\n helm = helm.replace(/\\?+/g, `${UNKNOWN_SYMBOL}.`);\n helm = helm.slice(0, -1); // strip last dot\n if (helm[helm.length - 1] === PHOSPHATE_SYMBOL)\n helm = helm.slice(0, -1);\n helm = helm.replace(phosphateRegExp, (match, group) => group);\n helm = helm.replace(/<empty>/g, '');\n return `${HELM_WRAPPER.LEFT + helm + HELM_WRAPPER.RIGHT}`;\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = ui;","const __WEBPACK_NAMESPACE_OBJECT__ = rxjs;","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./translator-app.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./translator-app.css\";\n export default content && content.locals ? content.locals : undefined;\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {sortByReverseLength} from '../helpers';\nimport {DEFAULT_FORMATS} from '../const';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\nimport {codesToHelmDictionary} from '../data-loading-utils/json-loader';\nimport {SequenceValidator} from './sequence-validator';\n\nexport class FormatDetector {\n constructor (private sequence: string) {\n this.libWrapper = MonomerLibWrapper.getInstance();\n this.formats = Object.keys(codesToHelmDictionary);\n };\n\n private libWrapper: MonomerLibWrapper;\n private formats: string[];\n\n getFormat(): string | null {\n // todo: reliable criterion\n if (this.sequence.startsWith('RNA'))\n return DEFAULT_FORMATS.HELM;\n const possibleFormats = this.getListOfPossibleSynthesizersByFirstMatchedCode();\n if (possibleFormats.length === 0)\n return null;\n\n const validator = new SequenceValidator(this.sequence);\n const outputIndices = Array(possibleFormats.length).fill(0);\n for (let i = 0; i < possibleFormats.length; ++i) {\n const format = possibleFormats[i];\n outputIndices[i] = validator.getInvalidCodeIndex(format);\n }\n const formatIdx = (outputIndices.some((idx) => idx === -1)) ? -1 : Math.max(...outputIndices);\n return possibleFormats[outputIndices.indexOf(formatIdx)];\n }\n\n // todo: rename\n private getListOfPossibleSynthesizersByFirstMatchedCode(): string[] {\n const sequence = this.sequence;\n let synthesizers: string[] = [];\n for (const format of this.formats) {\n let codes = sortByReverseLength(this.libWrapper.getCodesByFormat(format));\n let start = 0;\n for (let i = 0; i < sequence.length; i++) {\n if (sequence[i] === ')' && i !== sequence.length - 1) {\n start = i + 1;\n break;\n }\n }\n if (codes.some((s: string) => s === sequence.slice(start, start + s.length)))\n synthesizers.push(format);\n }\n return synthesizers;\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = $;","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {SequenceValidator} from '../../../model/parsing-validation/sequence-validator';\nimport {FormatDetector} from '../../../model/parsing-validation/format-detector';\n\nimport $ from 'cash-dom';\n\n/** Set different colors for letters, can be upgraded to color various monomers */\nexport function demoPainter(input: string): HTMLSpanElement[] {\n const colors = ['red', 'blueviolet', 'chartreuse',\n 'aquamarine', 'darkcyan', 'gold', 'green', 'aqua', 'orange',\n 'blue'];\n const spans: HTMLSpanElement[] = [];\n for (let i = 0; i < input.length; ++i) {\n const span = ui.span([input.charAt(i)]);\n // $(span).css('-webkit-text-fill-color', colors.at(Math.round(Math.random() * colors.length))!);\n $(span).css('-webkit-text-fill-color', colors[i % colors.length]!);\n spans.push(span);\n }\n return spans;\n}\n\n// todo: port to another place\nexport function highlightInvalidSubsequence(input: string): HTMLSpanElement[] {\n // validate sequence\n let cutoff = 0;\n const format = (new FormatDetector(input)).getFormat();\n if (format !== null)\n cutoff = (new SequenceValidator(input)).getInvalidCodeIndex(format!);\n const isValid = cutoff < 0 || input === '';\n const greyTextSpan = ui.span([]);\n $(greyTextSpan).css('-webkit-text-fill-color', 'var(--grey-6)');\n const redTextSpan = ui.span([]);\n $(redTextSpan).css('-webkit-text-fill-color', 'red');\n\n if (!isValid) {\n greyTextSpan.innerHTML = input.slice(0, cutoff);\n redTextSpan.innerHTML = input.slice(cutoff);\n } else { greyTextSpan.innerHTML = input; }\n return [greyTextSpan, redTextSpan];\n};\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./colored-text-input.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./colored-text-input.css\";\n export default content && content.locals ? content.locals : undefined;\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\n// external modules dependencies\nimport $ from 'cash-dom';\n\n// inner dependencies\nimport '../../style/colored-text-input.css';\n\n\n/** Class for colorizing input in the textarea of DG.InputBase. */\nexport class ColoredTextInput {\n constructor(\n private textInputBase: DG.InputBase<string>,\n /** Divide input value into an array of spans, each with its own text color, use -webkit-text-fill-color. */\n private painter: (str: string) => HTMLSpanElement[],\n /** Resize, no scrolls */\n resizeable: boolean = true\n ) {\n $(this.root).addClass('colored-text-input');\n if (resizeable) {\n // make input field automatically resizeable\n this.textInputBase.onChanged(\n () => {\n // necessary for the field to be squeezable, not only expandable\n $(this.textArea).css('height', 0);\n $(this.textArea).css('height', (this.textArea!.scrollHeight) + 'px');\n }\n );\n }\n this.highlights = ui.div([]);\n this.root.appendChild(this.highlights);\n this.colorize();\n\n this.textInputBase.onChanged(() => this.colorize());\n }\n\n private highlights: HTMLDivElement;\n\n get textArea() {\n return this.textInputBase.root.getElementsByTagName('textarea').item(0);\n };\n\n get inputBase() {\n return this.textInputBase;\n }\n\n get root() { return this.textInputBase.root; };\n\n private colorize() {\n const spans = this.painter(this.textInputBase.value);\n this.highlights.innerHTML = '';\n spans.forEach((span: HTMLSpanElement) => this.highlights.appendChild(span));\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {PHOSPHATE_SYMBOL} from './const';\nimport {sortByReverseLength} from '../helpers';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\nimport {monomersWithPhosphateLinkers} from '../data-loading-utils/json-loader';\n\n/** Wrapper for parsing a strand and getting a sequence of monomer IDs (with\n * omitted linkers, if needed) */\nexport class MonomerSequenceParser {\n constructor(\n private sequence: string, \n // todo: remove from the list of parameters\n private codeMap: Map<string, string>\n ) {\n }\n\n /** Get sequence of parsed monomer symbols, which are unique short names for\n * the monomers within the Monomer Library */\n parseSequence(): string[] {\n const parsedRawCodes = this.parseRawSequence();\n return this.addLinkers(parsedRawCodes);\n }\n\n private addLinkers(parsedRawCodes: string[]) {\n const monomerSymbolSequence: string[] = [];\n parsedRawCodes.forEach((code, i) => {\n const monomerSymbol = this.getSymbolForCode(code);\n if (i > 0 && monomerHasLeftPhosphateLinker(monomerSymbol))\n monomerSymbolSequence.pop();\n\n monomerSymbolSequence.push(monomerSymbol);\n\n const isPhosphate = monomerIsPhosphateLinker(monomerSymbol);\n const lastMonomer = i === parsedRawCodes.length - 1;\n const nextMonomerIsPhosphate = (i + 1 < parsedRawCodes.length && monomerIsPhosphateLinker(this.getSymbolForCode(parsedRawCodes[i + 1])));\n\n // todo: refactor as molfile-specific\n if (!isPhosphate && !monomerHasRightPhosphateLinker(monomerSymbol) && !nextMonomerIsPhosphate && !lastMonomer) {\n monomerSymbolSequence.push(PHOSPHATE_SYMBOL);\n }\n });\n return monomerSymbolSequence;\n }\n\n private getSymbolForCode(code: string): string {\n let monomerSymbol = this.codeMap.get(code);\n // todo: remove as a legacy workaround, codeMap must contain all the\n // symbols, and symbols are not codes\n monomerSymbol ??= code;\n return monomerSymbol;\n }\n\n private parseRawSequence(): string[] {\n const allCodesOfFormat = this.getAllCodesOfFormat();\n const parsedCodes = [];\n let i = 0;\n while (i < this.sequence.length) {\n const code = allCodesOfFormat.find(\n (s: string) => s === this.sequence.substring(i, i + s.length)\n )!;\n parsedCodes.push(code);\n i += code.length;\n }\n return parsedCodes;\n }\n\n // todo: port to monomer handler\n private getAllCodesOfFormat(): string[] {\n let allCodesInTheFormat = Array.from(this.codeMap.keys());\n return sortByReverseLength(allCodesInTheFormat);\n }\n}\n\n// todo: to be eliminated after full helm support\nfunction monomerHasLeftPhosphateLinker(monomerSymbol: string): boolean {\n return monomersWithPhosphateLinkers['left'].includes(monomerSymbol);\n}\n\nfunction monomerHasRightPhosphateLinker(monomerSymbol: string): boolean {\n return monomersWithPhosphateLinkers['right'].includes(monomerSymbol);\n}\n\nfunction monomerIsPhosphateLinker(monomerSymbol: string): boolean {\n return monomersWithPhosphateLinkers['phosphate'].includes(monomerSymbol);\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {MonomerSequenceParser} from './monomer-code-parser';\nimport {MonomerLibWrapper} from '../monomer-lib/lib-wrapper';\n\nexport class SequenceToMolfileConverter {\n constructor(\n sequence: string, private invert: boolean = false, format: string\n ) {\n this.lib = MonomerLibWrapper.getInstance();\n const codeToSymbolMap = this.lib.getCodeToSymbolMap(format);\n this.parser = new MonomerSequenceParser(sequence, codeToSymbolMap);\n }\n\n private parser: MonomerSequenceParser;\n private lib: MonomerLibWrapper;\n\n convert(): string {\n const parsedSequence = this.parser.parseSequence();\n const monomerMolfiles: string[] = [];\n parsedSequence.forEach((monomerSymbol, idx) => {\n const monomerMolfile = this.getMonomerMolfile(monomerSymbol, idx);\n monomerMolfiles.push(monomerMolfile);\n })\n let molfile = this.getPolymerMolfile(monomerMolfiles);\n if (this.invert) {\n molfile = this.reflect(molfile);\n molfile = this.invertBondConfiguration(molfile);\n }\n return molfile;\n }\n\n private invertBondConfiguration(molfile: string): string {\n const beginIdx = molfile.indexOf('M V30 BEGIN BOND');\n const endIdx = molfile.indexOf('M V30 END BOND');\n let bondBlock = molfile.substring(beginIdx, endIdx);\n bondBlock = bondBlock.replace(\n /(CFG=)([13])/g,\n (match, group1, group2) => (group2 === '1') ? `${group1}3` : (group2 === '3') ? `${group1}1` : match\n );\n const result = molfile.substring(0, beginIdx) + bondBlock + molfile.substring(endIdx);\n return result;\n }\n\n private getMonomerMolfile(monomerSymbol: string, idx: number): string {\n const molBlock = this.lib.getMolfileBySymbol(monomerSymbol);\n if (this.lib.isModification(monomerSymbol))\n return (idx === 0) ? this.reflect(molBlock) : molBlock;\n else\n return this.rotateNucleotidesV3000(molBlock);\n }\n\n private getPolymerMolfile(monomerMolfiles: string[]) {\n return this.linkV3000(monomerMolfiles);\n }\n\n private reflect(molBlock: string): string {\n const coordinates = this.extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n //place to center\n for (let i = 0; i < natom; i++)\n coordinates.x[i] = -coordinates.x[i];\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n }\n\n private extractAtomDataV3000(molBlock: string) {\n const numbers = this.extractAtomsBondsNumbersV3000(molBlock);\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n\n const indexes: number[] = Array(numbers.natom);\n const types: string[] = Array(numbers.natom);\n const x: number[] = Array(numbers.natom);\n const y: number[] = Array(numbers.natom);\n\n for (let i = 0; i < numbers.natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n indexEnd = molBlock.indexOf(' ', index);\n indexes[i] = parseInt(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n types[i] = molBlock.substring(index, indexEnd);\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n x[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n y[i] = parseFloat(molBlock.substring(index, indexEnd));\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return {atomIndex: indexes, atomType: types, x: x, y: y};\n }\n\n private extractAtomsBondsNumbersV3000(molBlock: string): { natom: number, nbond: number } {\n molBlock = molBlock.replaceAll('\\r', ''); //equalize old and new sdf standards\n let index = molBlock.indexOf('COUNTS') + 7; // V3000 index for atoms and bonds number\n let indexEnd = molBlock.indexOf(' ', index);\n\n const atomsNumber = parseInt(molBlock.substring(index, indexEnd));\n index = indexEnd + 1;\n indexEnd = molBlock.indexOf(' ', index);\n const bondsNumber = parseInt(molBlock.substring(index, indexEnd));\n\n return {natom: atomsNumber, nbond: bondsNumber};\n }\n\n private rotateNucleotidesV3000(molBlock: string): string {\n const coordinates = this.extractAtomDataV3000(molBlock);\n const natom = coordinates.atomIndex.length;\n\n const indexFivePrime = coordinates.atomIndex.indexOf(1);\n const indexThreePrime = coordinates.atomIndex.indexOf(natom);\n\n //fix 5 prime if inadequate\n if (natom > 8)\n this.fix5Prime(coordinates, indexFivePrime, indexThreePrime);\n\n const xCenter = (coordinates.x[indexThreePrime] + coordinates.x[indexFivePrime]) / 2;\n const yCenter = (coordinates.y[indexThreePrime] + coordinates.y[indexFivePrime]) / 2;\n\n //place to center\n for (let i = 0; i < natom; i++) {\n coordinates.x[i] -= xCenter;\n coordinates.y[i] -= yCenter;\n }\n\n let angle = 0;\n if (coordinates.x[indexFivePrime] === 0) {\n angle = coordinates.y[indexFivePrime] > coordinates.y[indexThreePrime] ? Math.PI / 2 : 3 * Math.PI / 2;\n } else if (coordinates.y[indexFivePrime] === 0) {\n angle = coordinates.x[indexFivePrime] > coordinates.x[indexThreePrime] ? Math.PI : 0;\n } else {\n const derivative = coordinates.y[indexFivePrime] / coordinates.x[indexFivePrime];\n angle = derivative > 0 ?\n (coordinates.x[indexFivePrime] > 0 ? Math.PI - Math.atan(derivative) : Math.PI * 2 - Math.atan(derivative)) :\n (coordinates.x[indexFivePrime] > 0 ? -Math.PI - Math.atan(derivative) : Math.atan(derivative));\n }\n\n const cos = Math.cos(angle);\n const sin = Math.sin(angle);\n\n for (let i = 0; i < natom; i++) {\n const xAdd = coordinates.x[i];\n coordinates.x[i] = xAdd * cos - coordinates.y[i] * sin;\n coordinates.y[i] = xAdd * sin + coordinates.y[i] * cos;\n }\n\n //place to right\n const xShift = coordinates.x[indexFivePrime];\n for (let i = 0; i < natom; i++)\n coordinates.x[i] -= xShift;\n\n //rewrite molBlock\n let index = molBlock.indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n index = molBlock.indexOf('\\n', index);\n let indexEnd = index;\n for (let i = 0; i < natom; i++) {\n index = molBlock.indexOf('V30', index) + 4;\n index = molBlock.indexOf(' ', index) + 1;\n index = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', index) + 1;\n indexEnd = molBlock.indexOf(' ', indexEnd);\n\n molBlock = molBlock.slice(0, index) +\n coordinates.x[i] + ' ' + coordinates.y[i] +\n molBlock.slice(indexEnd);\n\n index = molBlock.indexOf('\\n', index) + 1;\n }\n\n return molBlock;\n }\n\n\n private linkV3000(molBlocks: string[], useChirality: boolean = true): string {\n let macroMolBlock = '\\n Datagrok macromolecule handler\\n\\n';\n macroMolBlock += ' 0 0 0 0 0 0 999 V3000\\n';\n macroMolBlock += 'M V30 BEGIN CTAB\\n';\n let atomBlock = '';\n let bondBlock = '';\n let collectionBlock = '';\n const collection: number [] = [];\n let natom = 0;\n let nbond = 0;\n let xShift = 0;\n\n for (let i = 0; i < molBlocks.length; i++) {\n const isBoundary = molBlocks[i].includes('MODIFICATION') && i === 0;\n let specLength = 0;\n if (isBoundary) {\n const coordinates = this.extractAtomDataV3000(molBlocks[i]);\n specLength = coordinates.atomIndex.length;\n }\n\n\n molBlocks[i] = molBlocks[i].replaceAll('(-\\nM V30 ', '(')\n .replaceAll('-\\nM V30 ', '').replaceAll(' )', ')');\n const numbers = this.extractAtomsBondsNumbersV3000(molBlocks[i]);\n const coordinates = this.extractAtomDataV3000(molBlocks[i]);\n\n let indexAtoms = molBlocks[i].indexOf('M V30 BEGIN ATOM'); // V3000 index for atoms coordinates\n indexAtoms = molBlocks[i].indexOf('\\n', indexAtoms);\n let index = indexAtoms;\n let indexEnd = indexAtoms;\n\n for (let j = 0; j < numbers.natom; j++) {\n if (coordinates.atomIndex[j] !== 1 || i === 0) {\n //rewrite atom number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite coordinates\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n\n const totalShift = xShift - coordinates.x[0];\n let coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)) + totalShift)) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n coordinate =\n Math.round(10000 * (parseFloat(molBlocks[i].substring(index, indexEnd)))) / 10000;\n molBlocks[i] = molBlocks[i].slice(0, index) + coordinate + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n } else {\n index = molBlocks[i].indexOf('M V30', index) - 1;\n indexEnd = molBlocks[i].indexOf('\\n', index + 1);\n molBlocks[i] = molBlocks[i].slice(0, index) + molBlocks[i].slice(indexEnd);\n }\n }\n\n const indexAtomsEnd = molBlocks[i].indexOf('M V30 END ATOM');\n atomBlock += molBlocks[i].substring(indexAtoms + 1, indexAtomsEnd);\n\n let indexBonds = molBlocks[i].indexOf('M V30 BEGIN BOND'); // V3000 index for bonds\n indexBonds = molBlocks[i].indexOf('\\n', indexBonds);\n index = indexBonds;\n indexEnd = indexBonds;\n\n for (let j = 0; j < numbers.nbond; j++) {\n //rewrite bond number\n index = molBlocks[i].indexOf('V30', index) + 4;\n indexEnd = molBlocks[i].indexOf(' ', index);\n const bondNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + nbond;\n molBlocks[i] = molBlocks[i].slice(0, index) + bondNumber + molBlocks[i].slice(indexEnd);\n\n //rewrite atom pair in bond\n index = molBlocks[i].indexOf(' ', index) + 1;\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = molBlocks[i].indexOf(' ', index);\n let atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n index = molBlocks[i].indexOf(' ', index) + 1;\n indexEnd = Math.min(molBlocks[i].indexOf('\\n', index), molBlocks[i].indexOf(' ', index));\n atomNumber = 0;\n if (isBoundary) {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd));\n if (atomNumber === 1)\n atomNumber = specLength;\n else if (atomNumber === specLength)\n atomNumber = 1;\n atomNumber += natom;\n } else {\n atomNumber = parseInt(molBlocks[i].substring(index, indexEnd)) + natom;\n }\n molBlocks[i] = molBlocks[i].slice(0, index) + atomNumber + molBlocks[i].slice(indexEnd);\n\n index = molBlocks[i].indexOf('\\n', index) + 1;\n }\n\n const indexBondEnd = molBlocks[i].indexOf('M V30 END BOND');\n bondBlock += molBlocks[i].substring(indexBonds + 1, indexBondEnd);\n\n let indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=('); // V3000 index for collections\n\n while (indexCollection !== -1) {\n indexCollection += 28;\n const collectionEnd = molBlocks[i].indexOf(')', indexCollection);\n const collectionEntries = molBlocks[i].substring(indexCollection, collectionEnd).split(' ').slice(1);\n collectionEntries.forEach((e) => {\n collection.push(parseInt(e) + natom);\n });\n indexCollection = collectionEnd;\n indexCollection = molBlocks[i].indexOf('M V30 MDLV30/STEABS ATOMS=(', indexCollection);\n }\n\n natom += numbers.natom - 1;\n nbond += numbers.nbond;\n if (isBoundary)\n xShift += Math.max(...coordinates.x);\n else\n xShift += coordinates.x[numbers.natom - 1] - coordinates.x[0];\n }\n\n const entries = 4;\n const collNumber = Math.ceil(collection.length / entries);\n\n collectionBlock += 'M V30 MDLV30/STEABS ATOMS=(' + collection.length + ' -\\n';\n for (let i = 0; i < collNumber; i++) {\n collectionBlock += 'M V30 ';\n const entriesCurrent = i + 1 === collNumber ? collection.length - (collNumber - 1) * entries : entries;\n for (let j = 0; j < entriesCurrent; j++) {\n collectionBlock += (j + 1 === entriesCurrent) ?\n (i === collNumber - 1 ? collection[entries * i + j] + ')\\n' : collection[entries * i + j] + ' -\\n') :\n collection[entries * i + j] + ' ';\n }\n }\n\n //generate file\n natom++;\n macroMolBlock += 'M V30 COUNTS ' + natom + ' ' + nbond + ' 0 0 0\\n';\n macroMolBlock += 'M V30 BEGIN ATOM\\n';\n macroMolBlock += atomBlock;\n macroMolBlock += 'M V30 END ATOM\\n';\n macroMolBlock += 'M V30 BEGIN BOND\\n';\n macroMolBlock += bondBlock;\n macroMolBlock += 'M V30 END BOND\\n';\n if (useChirality && collection.length > 0) {\n macroMolBlock += 'M V30 BEGIN COLLECTION\\n';\n macroMolBlock += collectionBlock;\n macroMolBlock += 'M V30 END COLLECTION\\n';\n } else { macroMolBlock = macroMolBlock.replace(/ CFG=\\d/g, ' '); }\n\n macroMolBlock += 'M V30 END CTAB\\n';\n macroMolBlock += 'M END';\n\n return macroMolBlock;\n }\n\n private fix5Prime(coordinates: { atomIndex: number[], atomType: string[], x: number[], y: number[] },\n indexFivePrime: number, indexThreePrime: number) {\n const indexFivePrimeNeighbour = indexFivePrime + 1;\n const xShift = coordinates.x[indexFivePrimeNeighbour];\n const yShift = coordinates.y[indexFivePrimeNeighbour];\n const base3PrimeX = coordinates.x[indexThreePrime] - xShift;\n const base3PrimeY = coordinates.y[indexThreePrime] - yShift;\n const base5PrimeX = coordinates.x[indexFivePrime] - xShift;\n const base5PrimeY = coordinates.y[indexFivePrime] - yShift;\n\n const rotated5PrimeX = base5PrimeX * Math.cos(Math.PI * 2 / 3) - base5PrimeY * Math.sin(Math.PI * 2 / 3);\n const rotated5PrimeY = base5PrimeX * Math.sin(Math.PI * 2 / 3) + base5PrimeY * Math.cos(Math.PI * 2 / 3);\n\n const dx = base5PrimeX - base3PrimeX;\n const dy = base5PrimeY - base3PrimeY;\n const dxRotated = rotated5PrimeX - base3PrimeX;\n const dyRotated = rotated5PrimeY - base3PrimeY;\n\n if (Math.sqrt(dyRotated * dyRotated + dxRotated * dxRotated) >= Math.sqrt(dy * dy + dx * dx)) {\n coordinates.x[indexFivePrime] = rotated5PrimeX + xShift;\n coordinates.y[indexFivePrime] = rotated5PrimeY + yShift;\n }\n }\n}\n","/** Constants related to the structure of Molfile V2K */\nexport var V2K_CONST;\n(function (V2K_CONST) {\n V2K_CONST[\"HEADER\"] = \"V2000\";\n V2K_CONST[V2K_CONST[\"NUM_OF_HEADER_LINES\"] = 3] = \"NUM_OF_HEADER_LINES\";\n V2K_CONST[V2K_CONST[\"NUM_OF_COUNTS_DIGITS\"] = 3] = \"NUM_OF_COUNTS_DIGITS\";\n V2K_CONST[V2K_CONST[\"ATOM_TYPE_COL\"] = 4] = \"ATOM_TYPE_COL\";\n V2K_CONST[V2K_CONST[\"FIRST_BONDED_ATOM_COL\"] = 1] = \"FIRST_BONDED_ATOM_COL\";\n V2K_CONST[V2K_CONST[\"BOND_TYPE_COL\"] = 3] = \"BOND_TYPE_COL\";\n V2K_CONST[V2K_CONST[\"RGP_SHIFT\"] = 8] = \"RGP_SHIFT\";\n V2K_CONST[\"RGP_LINE\"] = \"M RGP\";\n V2K_CONST[\"A_LINE\"] = \"A \";\n V2K_CONST[\"END\"] = \"M END\";\n})(V2K_CONST || (V2K_CONST = {}));\nexport const MALFORMED_MOL_V2000 = `\nMalformed\n\n 0 0 0 0 0 0 0 0 0 0999 V2000\nM END`;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS12MmstY29uc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtb2xmaWxlLXYyay1jb25zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx3REFBd0Q7QUFDeEQsTUFBTSxDQUFOLElBQVksU0FlWDtBQWZELFdBQVksU0FBUztJQUNuQiw2QkFBZ0IsQ0FBQTtJQUNoQix1RUFBdUIsQ0FBQTtJQUV2Qix5RUFBd0IsQ0FBQTtJQUN4QiwyREFBaUIsQ0FBQTtJQUNqQiwyRUFBeUIsQ0FBQTtJQUN6QiwyREFBaUIsQ0FBQTtJQUdqQixtREFBYSxDQUFBO0lBQ2IsZ0NBQW1CLENBQUE7SUFDbkIsMkJBQWMsQ0FBQTtJQUVkLDJCQUFjLENBQUE7QUFDaEIsQ0FBQyxFQWZXLFNBQVMsS0FBVCxTQUFTLFFBZXBCO0FBRUQsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUc7Ozs7T0FJNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBDb25zdGFudHMgcmVsYXRlZCB0byB0aGUgc3RydWN0dXJlIG9mIE1vbGZpbGUgVjJLICovXG5leHBvcnQgZW51bSBWMktfQ09OU1Qge1xuICBIRUFERVIgPSAnVjIwMDAnLFxuICBOVU1fT0ZfSEVBREVSX0xJTkVTID0gMyxcblxuICBOVU1fT0ZfQ09VTlRTX0RJR0lUUyA9IDMsXG4gIEFUT01fVFlQRV9DT0wgPSA0LFxuICBGSVJTVF9CT05ERURfQVRPTV9DT0wgPSAxLFxuICBCT05EX1RZUEVfQ09MID0gMyxcblxuXG4gIFJHUF9TSElGVCA9IDgsXG4gIFJHUF9MSU5FID0gJ00gIFJHUCcsXG4gIEFfTElORSA9ICdBICAnLFxuXG4gIEVORCA9ICdNICBFTkQnLFxufVxuXG5leHBvcnQgY29uc3QgTUFMRk9STUVEX01PTF9WMjAwMCA9IGBcbk1hbGZvcm1lZFxuXG4gIDAgIDAgIDAgIDAgIDAgIDAgIDAgIDAgIDAgIDA5OTkgVjIwMDBcbk0gIEVORGA7XG4iXX0=","import { MolfileHandlerBase } from './molfile-handler-base';\nimport { V2K_CONST } from '../formats/molfile-v2k-const';\nexport class MolfileV2KHandler extends MolfileHandlerBase {\n constructor(molfile) {\n super(molfile);\n }\n static validate(molfile) {\n return (molfile.indexOf(V2K_CONST.HEADER) !== -1 &&\n molfile.indexOf(V2K_CONST.END) !== -1);\n }\n shiftIdxToAtomType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, V2K_CONST.ATOM_TYPE_COL);\n }\n getCountsLineIdx() {\n let idx = 0;\n for (let i = 0; i < V2K_CONST.NUM_OF_HEADER_LINES; ++i)\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n getAtomBlockIdx() {\n let idx = this.getCountsLineIdx();\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n shiftIdxToXColumn(lineStartIdx) {\n return this.getNextColumnIdx(lineStartIdx);\n }\n shiftIdxToBondedAtomsPair(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, V2K_CONST.FIRST_BONDED_ATOM_COL);\n }\n shiftIdxToBondType(lineStartIdx) {\n return this.shiftIdxToSpecifiedColumn(lineStartIdx, V2K_CONST.BOND_TYPE_COL);\n }\n getBondBlockIdx() {\n let idx = this.getAtomBlockIdx();\n for (let i = 0; i < this.atomCount; i++)\n idx = this.getNextLineIdx(idx);\n return idx;\n }\n parseAtomAndBondCounts() {\n let begin = this.getCountsLineIdx();\n let end = begin + V2K_CONST.NUM_OF_COUNTS_DIGITS;\n const atomCount = parseInt(this.fileContent.substring(begin, end));\n begin = end;\n end += V2K_CONST.NUM_OF_COUNTS_DIGITS;\n const bondCount = parseInt(this.fileContent.substring(begin, end));\n return { atomCount: atomCount, bondCount: bondCount };\n }\n ;\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS12MmstaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1vbGZpbGUtdjJrLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLDhCQUE4QixDQUFDO0FBSXZELE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxrQkFBa0I7SUFDdkQsWUFBWSxPQUFlO1FBQ3pCLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqQixDQUFDO0lBRU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFlO1FBQ3BDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZ0JBQWdCO1FBQ3hCLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsRUFBRSxDQUFDO1lBQ3BELEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVTLGVBQWU7UUFDdkIsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDbEMsR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0IsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRVMsaUJBQWlCLENBQUMsWUFBb0I7UUFDOUMsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVTLHlCQUF5QixDQUFDLFlBQW9CO1FBQ3RELE9BQU8sSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUN2RixDQUFDO0lBRVMsa0JBQWtCLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxJQUFJLENBQUMseUJBQXlCLENBQUMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRVMsZUFBZTtRQUN2QixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDakMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFO1lBQ3JDLEdBQUcsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUVTLHNCQUFzQjtRQUM5QixJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNwQyxJQUFJLEdBQUcsR0FBRyxLQUFLLEdBQUcsU0FBUyxDQUFDLG9CQUFvQixDQUFDO1FBQ2pELE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuRSxLQUFLLEdBQUcsR0FBRyxDQUFDO1FBQ1osR0FBRyxJQUFJLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQztRQUN0QyxNQUFNLFNBQVMsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkUsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBQyxDQUFDO0lBQ3RELENBQUM7SUFBQSxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0F0b21BbmRCb25kQ291bnRzfSBmcm9tICcuL2NoZW1pY2FsLXRhYmxlLXBhcnNlci1iYXNlJztcbmltcG9ydCB7TW9sZmlsZUhhbmRsZXJCYXNlfSBmcm9tICcuL21vbGZpbGUtaGFuZGxlci1iYXNlJztcbmltcG9ydCB7VjJLX0NPTlNUfSBmcm9tICcuLi9mb3JtYXRzL21vbGZpbGUtdjJrLWNvbnN0JztcbmltcG9ydCB7IEwsIFIgfSBmcm9tICcuL2NvbnN0JztcbmltcG9ydCB7IGlzQWxwaGEgfSBmcm9tICcuL3V0aWxzJztcblxuZXhwb3J0IGNsYXNzIE1vbGZpbGVWMktIYW5kbGVyIGV4dGVuZHMgTW9sZmlsZUhhbmRsZXJCYXNlIHtcbiAgY29uc3RydWN0b3IobW9sZmlsZTogc3RyaW5nKSB7XG4gICAgc3VwZXIobW9sZmlsZSk7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHZhbGlkYXRlKG1vbGZpbGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAobW9sZmlsZS5pbmRleE9mKFYyS19DT05TVC5IRUFERVIpICE9PSAtMSAmJlxuICAgIG1vbGZpbGUuaW5kZXhPZihWMktfQ09OU1QuRU5EKSAhPT0gLTEpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNoaWZ0SWR4VG9BdG9tVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHgsIFYyS19DT05TVC5BVE9NX1RZUEVfQ09MKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRDb3VudHNMaW5lSWR4KCk6IG51bWJlciB7XG4gICAgbGV0IGlkeCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBWMktfQ09OU1QuTlVNX09GX0hFQURFUl9MSU5FUzsgKytpKVxuICAgICAgaWR4ID0gdGhpcy5nZXROZXh0TGluZUlkeChpZHgpO1xuICAgIHJldHVybiBpZHg7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0QXRvbUJsb2NrSWR4KCk6IG51bWJlciB7XG4gICAgbGV0IGlkeCA9IHRoaXMuZ2V0Q291bnRzTGluZUlkeCgpO1xuICAgIGlkeCA9IHRoaXMuZ2V0TmV4dExpbmVJZHgoaWR4KTtcbiAgICByZXR1cm4gaWR4O1xuICB9XG5cbiAgcHJvdGVjdGVkIHNoaWZ0SWR4VG9YQ29sdW1uKGxpbmVTdGFydElkeDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5nZXROZXh0Q29sdW1uSWR4KGxpbmVTdGFydElkeCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2hpZnRJZHhUb0JvbmRlZEF0b21zUGFpcihsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHgsIFYyS19DT05TVC5GSVJTVF9CT05ERURfQVRPTV9DT0wpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNoaWZ0SWR4VG9Cb25kVHlwZShsaW5lU3RhcnRJZHg6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuc2hpZnRJZHhUb1NwZWNpZmllZENvbHVtbihsaW5lU3RhcnRJZHgsIFYyS19DT05TVC5CT05EX1RZUEVfQ09MKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRCb25kQmxvY2tJZHgoKTogbnVtYmVyIHtcbiAgICBsZXQgaWR4ID0gdGhpcy5nZXRBdG9tQmxvY2tJZHgoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuYXRvbUNvdW50OyBpKyspXG4gICAgICBpZHggPSB0aGlzLmdldE5leHRMaW5lSWR4KGlkeCk7XG4gICAgcmV0dXJuIGlkeDtcbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZUF0b21BbmRCb25kQ291bnRzKCk6IEF0b21BbmRCb25kQ291bnRzIHtcbiAgICBsZXQgYmVnaW4gPSB0aGlzLmdldENvdW50c0xpbmVJZHgoKTtcbiAgICBsZXQgZW5kID0gYmVnaW4gKyBWMktfQ09OU1QuTlVNX09GX0NPVU5UU19ESUdJVFM7XG4gICAgY29uc3QgYXRvbUNvdW50ID0gcGFyc2VJbnQodGhpcy5maWxlQ29udGVudC5zdWJzdHJpbmcoYmVnaW4sIGVuZCkpO1xuICAgIGJlZ2luID0gZW5kO1xuICAgIGVuZCArPSBWMktfQ09OU1QuTlVNX09GX0NPVU5UU19ESUdJVFM7XG4gICAgY29uc3QgYm9uZENvdW50ID0gcGFyc2VJbnQodGhpcy5maWxlQ29udGVudC5zdWJzdHJpbmcoYmVnaW4sIGVuZCkpO1xuICAgIHJldHVybiB7YXRvbUNvdW50OiBhdG9tQ291bnQsIGJvbmRDb3VudDogYm9uZENvdW50fTtcbiAgfTtcbn1cbiJdfQ==","import { MolfileV2KHandler } from './molfile-v2k-handler';\nimport { MolfileV3KHandler } from './molfile-v3k-handler';\n/** Defines the proper handler based on the molfile type */\nexport class MolfileHandler {\n constructor() { }\n static getInstance(molfile) {\n if (MolfileV2KHandler.validate(molfile))\n return new MolfileV2KHandler(molfile);\n else if (MolfileV3KHandler.validate(molfile))\n return new MolfileV3KHandler(molfile);\n else\n throw new Error('Malformed molfile');\n }\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9sZmlsZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibW9sZmlsZS1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ3hELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBRXhELDREQUE0RDtBQUM1RCxNQUFNLE9BQU8sY0FBYztJQUN6QixnQkFBdUIsQ0FBQztJQUV4QixNQUFNLENBQUMsV0FBVyxDQUFDLE9BQWU7UUFDaEMsSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1lBQ3JDLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUNuQyxJQUFJLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7WUFDMUMsT0FBTyxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDOztZQUV0QyxNQUFNLElBQUksS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFDekMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtNb2xmaWxlSGFuZGxlckJhc2V9IGZyb20gJy4vbW9sZmlsZS1oYW5kbGVyLWJhc2UnO1xuaW1wb3J0IHtNb2xmaWxlVjJLSGFuZGxlcn0gZnJvbSAnLi9tb2xmaWxlLXYyay1oYW5kbGVyJztcbmltcG9ydCB7TW9sZmlsZVYzS0hhbmRsZXJ9IGZyb20gJy4vbW9sZmlsZS12M2staGFuZGxlcic7XG5cbi8qKiBEZWZpbmVzIHRoZSBwcm9wZXIgaGFuZGxlciBiYXNlZCBvbiB0aGUgbW9sZmlsZSB0eXBlICAqL1xuZXhwb3J0IGNsYXNzIE1vbGZpbGVIYW5kbGVyIHtcbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgc3RhdGljIGdldEluc3RhbmNlKG1vbGZpbGU6IHN0cmluZyk6IE1vbGZpbGVIYW5kbGVyQmFzZSB7XG4gICAgaWYgKE1vbGZpbGVWMktIYW5kbGVyLnZhbGlkYXRlKG1vbGZpbGUpKVxuICAgICAgcmV0dXJuIG5ldyBNb2xmaWxlVjJLSGFuZGxlcihtb2xmaWxlKTtcbiAgICBlbHNlIGlmIChNb2xmaWxlVjNLSGFuZGxlci52YWxpZGF0ZShtb2xmaWxlKSlcbiAgICAgIHJldHVybiBuZXcgTW9sZmlsZVYzS0hhbmRsZXIobW9sZmlsZSk7XG4gICAgZWxzZVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYWxmb3JtZWQgbW9sZmlsZScpO1xuICB9XG59XG4iXX0=","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {MolfileHandler} from '@datagrok-libraries/chem-meta/src/parsing-utils/molfile-handler';\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport $ from 'cash-dom';\n\nconst InvalidMolfileError = class extends Error {\n constructor(message: string) { super(message); }\n};\n\nexport class MoleculeImage {\n constructor(molblok: string) {\n this.molblock = molblok;\n }\n\n private _validMolBlock: string;\n get molblock(): string { return this._validMolBlock; }\n\n set molblock(value: string) {\n if (value === '') {\n this._validMolBlock = value;\n return;\n }\n\n try {\n this.validateMolBlock(value);\n } catch (error) {\n if (error instanceof InvalidMolfileError)\n value = '';\n const errorMessage = errorToConsole(error);\n console.error(errorMessage);\n }\n this._validMolBlock = value;\n }\n\n private validateMolBlock(molblock: string): void {\n // todo: add a sound criterion\n if (molblock === '')\n throw new InvalidMolfileError('MoleculeImage: invalid molblock');\n }\n\n private async drawMolBlockOnCanvas(canvas: HTMLCanvasElement): Promise<void> {\n try {\n await grok.functions.call('Chem:canvasMol', {\n x: 0, y: 0, w: canvas.width, h: canvas.height, canvas: canvas,\n molString: this.molblock, scaffoldMolString: '',\n options: {normalizeDepiction: false, straightenDepiction: false}\n });\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n };\n\n private getMoleculeDimensions(): {height: number, width: number} {\n const molData = MolfileHandler.getInstance(this.molblock);\n const width: number = Math.max(...molData.x) - Math.min(...molData.x);\n const height: number = Math.max(...molData.y) - Math.min(...molData.y);\n return {height: height, width: width};\n }\n\n private async zoomIn(): Promise<void> {\n const dialog = ui.dialog({title: 'Molecule', showFooter:false});\n const dialogDivStyle = {\n overflowX: 'scroll',\n };\n\n const height = $(window).height() * 0.7;\n const molDimensions = this.getMoleculeDimensions();\n\n const zoomRatio = height / molDimensions.height;\n\n const dialogCanvasHeight = height;\n const dialogCanvasWidth = molDimensions.width * zoomRatio;\n\n const dialogCanvas = ui.canvas(dialogCanvasWidth, dialogCanvasHeight);\n await this.drawMolBlockOnCanvas(dialogCanvas);\n \n const dialogDiv = ui.block([dialogCanvas], {style: dialogDivStyle});\n dialog.add(dialogDiv).showModal(true);\n\n $(dialog.root).find('.d4-dialog-contents').removeClass('ui-form');\n $(dialog.root).find('.d4-dialog-contents').removeClass('ui-panel');\n $(dialog.root).find('.d4-dialog-contents').addClass('ui-box');\n $(dialog.root).find('.d4-dialog-contents').css('padding', '0');\n }\n\n public async drawMolecule(\n moleculeImgDiv: HTMLDivElement,\n canvasWidth: number, canvasHeight: number\n ): Promise<void> {\n moleculeImgDiv.innerHTML = '';\n\n const canvas = ui.canvas(canvasWidth * window.devicePixelRatio, canvasHeight * window.devicePixelRatio);\n\n // Draw zoomed-out molecule\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n canvas.style.cursor = 'zoom-in';\n /*\n canvas.style.borderStyle = 'solid';\n canvas.style.borderRadius = '1px';\n canvas.style.borderColor = 'var(--grey-2)';\n canvas.style.borderWidth = 'thin';\n */\n this.drawMolBlockOnCanvas(canvas);\n\n // Dialog with zoomed-in molecule\n canvas.addEventListener('click', async () => {\n await this.zoomIn();\n });\n //$(canvas).on('click', async () => { await this.zoomIn(); });\n //$(canvas).on('mouseover', () => $(canvas).css('cursor', 'grab')); // for some reason 'zoom-in' value wouldn't work\n //$(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));\n\n moleculeImgDiv.append(ui.tooltip.bind(canvas,'Click to zoom'));\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport * as rxjs from 'rxjs';\nimport '../style/translator-app.css';\n\nimport {highlightInvalidSubsequence} from '../utils/colored-input/input-painters';\nimport {ColoredTextInput} from '../utils/colored-input/colored-text-input';\nimport {SequenceToMolfileConverter} from '../../model/structure-app/sequence-to-molfile';\nimport {getTranslatedSequences} from '../../model/translator-app/conversion-utils';\nimport {MoleculeImage} from '../utils/molecule-img';\nimport {download} from '../../model/helpers';\nimport {SEQUENCE_COPIED_MSG, SEQ_TOOLTIP_MSG} from '../const/oligo-translator';\nimport {DEFAULT_AXOLABS_INPUT} from '../const/ui';\nimport {FormatDetector} from '../../model/parsing-validation/format-detector';\nimport {SequenceValidator} from '../../model/parsing-validation/sequence-validator';\nimport {FormatConverter} from '../../model/translator-app/format-converter';\nimport {codesToHelmDictionary} from '../../model/data-loading-utils/json-loader';\nimport {DEFAULT_FORMATS} from '../../model/const';\n\nexport class TranslatorLayoutHandler {\n constructor() {\n const INPUT_FORMATS = Object.keys(codesToHelmDictionary).concat(DEFAULT_FORMATS.HELM);\n this.moleculeImgDiv = ui.div([]);\n this.moleculeImgDiv.className = 'mol-host';\n this.moleculeImgDiv.style.border = '1px solid var(--grey-2)';\n this.moleculeImgDiv.style.borderRadius = '1px';\n this.moleculeImgDiv.style.marginTop = '12px';\n\n this.outputTableDiv = ui.div([]);\n this.formatChoiceInput = ui.choiceInput('', DEFAULT_FORMATS.HELM, INPUT_FORMATS, async () => {\n this.format = this.formatChoiceInput.value;\n this.updateTable();\n await this.updateMolImg();\n });\n this.sequenceInputBase = ui.textInput('', DEFAULT_AXOLABS_INPUT,\n () => { this.onInput.next(); });\n\n this.init();\n\n DG.debounce<string>(this.onInput, 300).subscribe(async () => {\n this.init();\n this.formatChoiceInput.value = this.format;\n this.updateTable();\n await this.updateMolImg();\n });\n }\n\n // todo: reduce # of state vars by further refactoring legacy code\n private onInput = new rxjs.Subject<string>();\n private moleculeImgDiv: HTMLDivElement;\n private outputTableDiv: HTMLDivElement;\n private formatChoiceInput: DG.InputBase;\n private sequenceInputBase: DG.InputBase;\n private molfile: string;\n public sequence: string;\n private format: string | null;\n\n async getHtmlElement(): Promise<HTMLDivElement> {\n const sequenceColoredInput = new ColoredTextInput(this.sequenceInputBase, highlightInvalidSubsequence);\n\n const downloadMolfileButton = ui.button(\n 'Get SDF',\n () => { this.saveMolfile(); },\n 'Save structure as SDF');\n\n const copySmilesButton = ui.button(\n 'Copy SMILES',\n () => { this.copySmiles(); },\n 'Copy SMILES for the sequence');\n\n const formatChoiceInput = ui.div([this.formatChoiceInput]);\n\n const clearButton = ui.button(\n ui.icons.delete(() => { sequenceColoredInput.inputBase.value = '' }),\n () => {}\n );\n ui.tooltip.bind(clearButton, 'Clear input');\n\n const inputTableRow = {\n format: formatChoiceInput,\n textInput: sequenceColoredInput.root,\n clearBtn: clearButton\n };\n const upperBlock = ui.table(\n [inputTableRow], (item) => [item.format, item.textInput, item.clearBtn]\n );\n upperBlock.classList.add('st-translator-input-table');\n\n const outputTable = ui.block([\n this.outputTableDiv,\n downloadMolfileButton,\n copySmilesButton,\n ]);\n\n const mainTabBody = ui.box(\n ui.panel([\n upperBlock,\n outputTable,\n ui.block([ui.box(this.moleculeImgDiv)])\n ]),\n );\n\n this.formatChoiceInput.value = this.format;\n this.updateTable();\n await this.updateMolImg();\n return mainTabBody;\n }\n\n private saveMolfile(): void {\n const result = (new SequenceToMolfileConverter(this.sequence, false,\n this.formatChoiceInput.value!)).convert() + '\\n$$$$';\n download(this.sequence + '.sdf', encodeURIComponent(result));\n }\n\n private copySmiles(): void {\n const smiles = DG.chem.convert(this.molfile, DG.chem.Notation.MolBlock, DG.chem.Notation.Smiles);\n navigator.clipboard.writeText(smiles).then(\n () => grok.shell.info(SEQUENCE_COPIED_MSG)\n );\n }\n\n private updateTable(): void {\n this.outputTableDiv.innerHTML = '';\n // todo: does not detect correctly (U-A)(U-A)\n const indexOfInvalidChar = (!this.format) ? 0 : (new SequenceValidator(this.sequence)).getInvalidCodeIndex(this.format!);\n const translatedSequences = getTranslatedSequences(this.sequence, indexOfInvalidChar, this.format!);\n const tableRows = [];\n\n for (const key of Object.keys(translatedSequences)) {\n const sequence = ('indexOfFirstInvalidChar' in translatedSequences) ?\n ui.divH([]) :\n ui.link(\n translatedSequences[key],\n () => navigator.clipboard.writeText(translatedSequences[key])\n .then(() => grok.shell.info(SEQUENCE_COPIED_MSG)),\n SEQ_TOOLTIP_MSG, ''\n );\n tableRows.push({\n format: key,\n sequence: sequence,\n });\n }\n const outputTable = ui.table(tableRows, (item) => [item.format, item.sequence], ['FORMAT', 'SEQUENCE']);\n\n this.outputTableDiv.append(outputTable);\n this.outputTableDiv.classList.add('st-translator-output-table');\n }\n\n private async updateMolImg(): Promise<void> {\n const canvasWidth = 500;\n const canvasHeight = 170;\n const molImgObj = new MoleculeImage(this.molfile);\n await molImgObj.drawMolecule(this.moleculeImgDiv, canvasWidth, canvasHeight);\n // should the canvas be returned from the above function?\n }\n\n // todo: sort mehtods\n private init(): void {\n this.sequence = this.getFormattedSequence();\n\n this.format = (new FormatDetector(this.sequence)).getFormat();\n\n // warning: getMolfile relies on 'this.format', so the order is important\n this.molfile = this.getMolfile();\n }\n\n private getFormattedSequence(): string {\n return this.sequenceInputBase.value.replace(/\\s/g, '');\n }\n\n private getMolfile(): string {\n if (!this.format)\n return '';\n if (this.format === DEFAULT_FORMATS.HELM) {\n const axolabs = (new FormatConverter(this.sequence, this.format).convertTo(DEFAULT_FORMATS.AXOLABS));\n return (new SequenceToMolfileConverter(axolabs, false, DEFAULT_FORMATS.AXOLABS).convert());\n }\n const molfile = (new SequenceToMolfileConverter(this.sequence, false, this.format)).convert();\n return molfile;\n }\n}\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./structure-app.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\n\n options.insert = insertFn.bind(null, \"head\");\n \noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./structure-app.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport {download} from '../helpers';\nimport {SequenceToMolfileConverter} from './sequence-to-molfile';\nimport {linkStrandsV3000} from './mol-transformations';\nimport {DEFAULT_FORMATS} from '../const';\nimport {FormatDetector} from '../parsing-validation/format-detector';\n\nexport type StrandData = {\n strand: string,\n invert: boolean\n}\n\n/** Get a molfile for a single strand */\nexport function getMolfileForStrand(strand: string, invert: boolean): string {\n if (strand === '')\n return '';\n const format = (new FormatDetector(strand)).getFormat();\n if (!format)\n return '';\n let molfile = '';\n try {\n molfile = (new SequenceToMolfileConverter(strand, invert, format)).convert();\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n return molfile;\n}\n\n/** Get molfile for single strand or linked strands */\nexport function getLinkedMolfile(\n ss: StrandData, as: StrandData, as2: StrandData, useChiral: boolean\n): string {\n const nonEmptyStrands = [ss, as, as2].filter((item) => item.strand !== '');\n if (nonEmptyStrands.length === 1) {\n return getMolfileForStrand(nonEmptyStrands[0].strand, nonEmptyStrands[0].invert);\n } else {\n const ssMol = getMolfileForStrand(ss.strand, ss.invert);\n const asMol = getMolfileForStrand(as.strand, as.invert);\n const as2Mol = getMolfileForStrand(as2.strand, as2.invert);\n\n // select only the non-empty anti-strands\n const antiStrands = [asMol, as2Mol].filter((item) => item !== '');\n const resultingMolfile = linkStrandsV3000({senseStrands: [ssMol], antiStrands: antiStrands}, useChiral);\n\n return resultingMolfile;\n }\n}\n\n/** Save sdf in case ss and as (and optionally as2) strands entered */\nexport function saveSdf(\n ss: StrandData, as: StrandData, as2: StrandData, useChiral: boolean,\n oneEntity: boolean\n): void {\n const nonEmptyStrands = [ss.strand, as.strand, as2.strand].filter((item) => item !== '');\n if (\n nonEmptyStrands.length === 0 ||\n nonEmptyStrands.length === 1 && ss.strand === ''\n ) {\n grok.shell.warning('Enter SS and optionally AS/AS2 to save SDF');\n } else {\n let result: string;\n if (oneEntity) {\n result = getLinkedMolfile(ss, as, as2, useChiral) + '\\n$$$$\\n';\n } else {\n const ssMol = getMolfileForStrand(ss.strand, ss.invert);\n const asMol = getMolfileForStrand(as.strand, as.invert);\n const as2Mol = getMolfileForStrand(as2.strand, as2.invert);\n result = ssMol + '\\n' +\n `> <Sequence>\\nSense Strand\\n$$$$\\n`;\n if (asMol) {\n result += asMol + '\\n' +\n `> <Sequence>\\nAnti Sense\\n$$$$\\n`;\n }\n if (as2Mol) {\n result += as2Mol + '\\n' +\n `> <Sequence>\\nAnti Sense 2\\n$$$$\\n`;\n }\n }\n\n // construct date-time in the form yyyy-mm-dd_hh-mm-ss\n const date = new Date();\n function pad(x: number): string {\n return (x >= 10) ? x.toString() : '0' + x.toString();\n }\n const dateString: string = date.getFullYear() + '-' + pad(date.getMonth() + 1) +\n '-' + pad(date.getDate()) + '_' + pad(date.getHours()) + '-' +\n pad(date.getMinutes()) + '-' + pad(date.getSeconds());\n\n download(`SequenceTranslator-${dateString}.sdf`, encodeURIComponent(result));\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport * as rxjs from 'rxjs';\nimport '../style/structure-app.css';\nimport $ from 'cash-dom';\n\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport {highlightInvalidSubsequence} from '../utils/colored-input/input-painters';\nimport {getLinkedMolfile, saveSdf} from '../../model/structure-app/oligo-structure';\nimport {ColoredTextInput} from '../utils/colored-input/colored-text-input';\nimport {MoleculeImage} from '../utils/molecule-img';\nimport {StrandData} from '../../model/structure-app/oligo-structure';\n\nconst enum DIRECTION {\n STRAIGHT = '5′ → 3′',\n INVERSE = '3′ → 5′',\n};\nconst STRANDS = ['ss', 'as', 'as2'] as const;\n\nexport class StructureLayoutHandler {\n constructor() {\n this.onInput = new rxjs.Subject<string>();\n this.onInvalidInput = new rxjs.Subject<string>();\n this.inputBase = Object.fromEntries(\n STRANDS.map(\n (key) => [key, ui.textInput('', '', () => { this.onInput.next(); })]\n )\n );\n this.useChiralInput = ui.boolInput('Use chiral', true);\n this.saveAllStrandsInput = ui.boolInput('Save as one entity', true);\n ui.tooltip.bind(this.saveAllStrandsInput.root, 'Save SDF with all strands in one molfile');\n this.directionInversion = Object.fromEntries(\n STRANDS.map((key) => [key, false])\n );\n this.moleculeImgDiv = ui.block([]);\n $(this.moleculeImgDiv).addClass('st-structure-mol-img');\n\n DG.debounce<string>(this.onInput, 300).subscribe(async () => {\n await this.updateMoleculeImg();\n });\n\n DG.debounce<string>(this.onInvalidInput, 1000).subscribe(async () => {\n grok.shell.warning('Insert Sense strand');\n });\n }\n\n private onInput: rxjs.Subject<string>;\n private onInvalidInput: rxjs.Subject<string>;\n private useChiralInput: DG.InputBase<boolean | null>;\n private saveAllStrandsInput: DG.InputBase<boolean | null>;\n private inputBase: {[key: string]: DG.InputBase<string>};\n private directionInversion: {[key: string]: boolean};\n private moleculeImgDiv: HTMLDivElement;\n\n async getHtmlDivElement(): Promise<HTMLDivElement> {\n const tableLayout = this.getTableInput();\n const boolInputsAndButton = this.getBoolInputsAndButton();\n await this.updateMoleculeImg();\n const bottomDiv = ui.divH([boolInputsAndButton, this.moleculeImgDiv]);\n $(bottomDiv).addClass('st-structure-bottom');\n\n const layout = ui.divV([tableLayout, bottomDiv]);\n $(layout).addClass('st-structure-body');\n\n return layout;\n }\n\n private getBoolInputsAndButton(): HTMLDivElement {\n const saveButton = ui.buttonsInput([\n ui.bigButton('Save SDF', () => {\n const strandData = this.getStrandData();\n saveSdf(strandData.ss, strandData.as, strandData.as2,\n this.useChiralInput.value!, this.saveAllStrandsInput.value!);\n })\n ]);\n\n const boolInputsAndButtonArray = [this.saveAllStrandsInput.root, this.useChiralInput.root, saveButton];\n const boolInputsAndButton = ui.divV(boolInputsAndButtonArray);\n for (const item of boolInputsAndButtonArray)\n $(item).addClass('st-structure-bool-button-block');\n return boolInputsAndButton;\n }\n\n private getTableInput(): HTMLTableElement {\n const coloredInput = Object.fromEntries(\n STRANDS.map(\n (key) => [key, new ColoredTextInput(this.inputBase[key], highlightInvalidSubsequence)]\n )\n );\n\n const directionChoiceInput = Object.fromEntries(\n STRANDS.map(\n (key, idx) => {\n const selected = (idx === 0) ? DIRECTION.STRAIGHT : DIRECTION.INVERSE;\n return [key, ui.choiceInput(\n `${key.toUpperCase()} direction`, selected, [DIRECTION.STRAIGHT, DIRECTION.INVERSE]\n )]\n }\n )\n );\n\n STRANDS.forEach((strand, idx) => {\n directionChoiceInput[strand].onChanged(() => {\n let value = directionChoiceInput[strand].value === DIRECTION.INVERSE;\n // warning: the next line is necessary until the legacy notion of direction used in the molfile generation gets fixed\n if (idx > 0) { value = !value; }\n this.directionInversion[strand] = value;\n this.onInput.next();\n });\n });\n\n const labelNames = ['Sense Strand', 'Anti Sense', 'Anti Sense 2'];\n const labelNameMap = new Map(STRANDS.map(\n (key, index) => [key, labelNames[index]]\n ));\n const label = Object.fromEntries(\n STRANDS.map(\n (key) => [key, ui.label(labelNameMap.get(key)!)]\n )\n );\n\n const clearBlock = Object.fromEntries(\n STRANDS.map(\n (key) => {\n const clearIcon = ui.icons.delete(() => { coloredInput[key].inputBase.value = '' });\n const clearButton = ui.button(clearIcon, () => {});\n ui.tooltip.bind(clearButton, `Clear ${key.toUpperCase()}`);\n return [key, clearIcon];\n }\n ));\n\n const tableRows = STRANDS.map((strand) => {\n return {\n label: label[strand],\n textInput: coloredInput[strand].root,\n clear: clearBlock[strand],\n choiceInput: directionChoiceInput[strand].root,\n };\n });\n const tableLayout = ui.table(\n tableRows, (item) => [item.label, item.textInput, item.clear, item.choiceInput]);\n $(tableLayout).css('margin-top', '10px');\n\n for (const strand of STRANDS) {\n let element = label[strand].parentElement!;\n element.classList.add('st-structure-input-form');\n // the following line is necessary because otherwise overridden by\n // d4-item-table class\n $(element).css('padding-top', '3px');\n\n element = directionChoiceInput[strand].root.parentElement!;\n element.classList.add('st-structure-input-form', 'st-structure-direction-choice');\n\n element = this.inputBase[strand].root.parentElement!;\n element.classList.add('st-structure-text-input-td');\n }\n return tableLayout;\n }\n\n private getStrandData() {\n return Object.fromEntries(\n STRANDS.map((strand, idx) => {\n let invert = this.directionInversion[strand];\n return [strand, {\n strand: this.inputBase[strand].value.replace(/\\s*/g, ''),\n invert: invert\n }]\n })\n );\n }\n\n private getMolfile(ss: StrandData, as: StrandData, as2: StrandData): string {\n // if (ss.strand === '' && (as.strand !== '' || as2.strand !== '')) {\n // this.onInvalidInput.next();\n // return '';\n // }\n\n return getLinkedMolfile(ss, as, as2, this.useChiralInput.value!);\n }\n\n private async updateMoleculeImg(): Promise<void> {\n let molfile = '';\n try {\n const strandData = this.getStrandData();\n if (Object.values(strandData).some((data) => data.strand !== ''))\n molfile = this.getMolfile(strandData.ss, strandData.as, strandData.as2);\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n // todo: calculate relative numbers\n const canvasWidth = 650;\n const canvasHeight = 150;\n const molImgObj = new MoleculeImage(molfile);\n await molImgObj.drawMolecule(this.moleculeImgDiv, canvasWidth, canvasHeight);\n // should the canvas be returned from the above function?\n $(this.moleculeImgDiv).find('canvas').css('float', 'inherit');\n }\n}\n","export const DEFAULT_PTO: boolean = true;\nexport const DEFAULT_SEQUENCE_LENGTH: number = 23;\nexport const MAX_SEQUENCE_LENGTH: number = 35;\nexport const USER_STORAGE_KEY: string = 'SequenceTranslator';\nexport const EXAMPLE_MIN_WIDTH: string = '400px';\n\nexport const enum JSON_FIELD {\n SS_BASES = 'ssBases',\n AS_BASES = 'asBases',\n SS_PTO = 'ssPtoLinkages',\n AS_PTO = 'asPtoLinkages',\n SS_3 = 'ssThreeModification',\n SS_5 = 'ssFiveModification',\n AS_3 = 'asThreeModification',\n AS_5 = 'asFiveModification',\n COMMENT = 'comment',\n};\n\nexport const SS = 'SS' as const;\nexport const AS = 'AS' as const;\nexport const STRANDS = [SS, AS];\nexport const STRAND_NAME = {\n [SS]: 'Sense strand',\n [AS]: 'Anti sense',\n}\n\nexport const THREE_PRIME = 'THREE_PRIME' as const;\nexport const FIVE_PRIME = 'FIVE_PRIME' as const;\nexport const TERMINAL_KEYS = [THREE_PRIME, FIVE_PRIME];\nexport const TERMINAL = {\n [THREE_PRIME]: 3,\n [FIVE_PRIME]: 5,\n}\n","import {NUCLEOTIDES} from '../const';\nimport {axolabsStyleMap} from '../data-loading-utils/json-loader';\n\nexport function isOverhang(modification: string): boolean {\n return modification.slice(-3) === '(o)';\n}\n\nexport function isOneDigitNumber(n: number): boolean {\n return n < 10;\n}\n\n// https://uxdesign.cc/star-rating-make-svg-great-again-d4ce4731347e\nexport function getPointsToDrawStar(centerX: number, centerY: number): string {\n const innerCirclePoints = 5; // a 5 point star\n const innerRadius = 15 / innerCirclePoints;\n const innerOuterRadiusRatio = 2; // outter circle is x2 the inner\n const outerRadius = innerRadius * innerOuterRadiusRatio;\n const angle = Math.PI / innerCirclePoints;\n const angleOffsetToCenterStar = 60;\n const totalNumberOfPoints = innerCirclePoints * 2; // 10 in a 5-points star\n\n let points = '';\n for (let i = 0; i < totalNumberOfPoints; i++) {\n const r = (i % 2 === 0) ? outerRadius : innerRadius;\n const currentX = centerX + Math.cos(i * angle + angleOffsetToCenterStar) * r;\n const currentY = centerY + Math.sin(i * angle + angleOffsetToCenterStar) * r;\n points += `${currentX},${currentY} `;\n }\n return points;\n}\n\nexport function countOverhangsOnTheRightEdge(modifications: string[]): number {\n let i = 0;\n while (i < modifications.length && isOverhang(modifications[i]))\n i++;\n return (i === modifications.length - 1) ? 0 : i;\n}\n\nexport function textWidth(text: string, font: number): number {\n const context = document.createElement('canvas').getContext('2d');\n // @ts-ignore\n context.font = String(font);\n // @ts-ignore\n return 2 * context.measureText(text).width;\n}\n\nexport function textInsideCircle(bases: string[], index: number): string {\n return (isOverhang(bases[index]) || !NUCLEOTIDES.includes(bases[index])) ? '' : bases[index];\n}\n\nexport function fontColorVisibleOnBackground(base: string): string {\n const AXOLABS_MAP = axolabsStyleMap;\n const rgbIntList = AXOLABS_MAP[base].color.match(/\\d+/g)!.map((e) => Number(e));\n return (rgbIntList[0] * 0.299 + rgbIntList[1] * 0.587 + rgbIntList[2] * 0.114) > 186 ? '#33333' : '#ffffff';\n}\n\nexport function baseColor(base: string): string {\n const AXOLABS_MAP = axolabsStyleMap;\n return AXOLABS_MAP[base].color;\n}\n\nexport const svg = {\n xmlns: 'http://www.w3.org/2000/svg',\n render: function(width: number, height: number): Element {\n const e = document.createElementNS(this.xmlns, 'svg');\n e.setAttribute('id', 'mySvg');\n e.setAttribute('width', String(width));\n e.setAttribute('height', String(height));\n return e;\n },\n circle: function(x: number, y: number, radius: number, color: string): Element {\n const e = document.createElementNS(this.xmlns, 'circle');\n e.setAttribute('cx', String(x));\n e.setAttribute('cy', String(y));\n e.setAttribute('r', String(radius));\n e.setAttribute('fill', color);\n return e;\n },\n text: function(text: string, x: number, y: number, fontSize: number, color: string): Element {\n const e = document.createElementNS(this.xmlns, 'text');\n e.setAttribute('x', String(x));\n e.setAttribute('y', String(y));\n e.setAttribute('font-size', String(fontSize));\n e.setAttribute('font-weight', 'normal');\n e.setAttribute('font-family', 'Arial');\n e.setAttribute('fill', color);\n e.innerHTML = text;\n return e;\n },\n star: function(x: number, y: number, fill: string): Element {\n const e = document.createElementNS(this.xmlns, 'polygon');\n e.setAttribute('points', getPointsToDrawStar(x, y));\n e.setAttribute('fill', fill);\n return e;\n },\n};\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n// @ts-ignore\nimport * as svg from 'save-svg-as-png';\nimport $ from 'cash-dom';\n\nimport {isOverhang} from './helpers';\nimport {axolabsStyleMap} from '../data-loading-utils/json-loader';\n\nexport function generateExample(sequenceLength: number, sequenceBasis: string): string {\n const AXOLABS_MAP = axolabsStyleMap;\n const uniqueSymbols = AXOLABS_MAP[sequenceBasis].symbols.join('');\n return uniqueSymbols.repeat(Math.floor(sequenceLength / 4)) + uniqueSymbols.slice(0, sequenceLength % 4);\n}\n\nexport function findDuplicates(data: Int32Array | Float32Array | Float64Array | Uint32Array): number[] {\n return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));\n}\n\nexport async function isCurrentUserCreatedThisPattern(patternName: string): Promise<boolean> {\n return await grok.dapi.users.current().then((user) => {\n const [firstName, lastName] = getUserName(patternName);\n return (user.firstName !== firstName || user.lastName !== lastName);\n });\n}\n\nexport function getShortName(patternName: string): string {\n let first = patternName.length + 1;\n for (let i = 0; i < patternName.length; i++) {\n if (patternName[i] === '(') {\n first = i;\n break;\n }\n }\n return patternName.slice(0, first - 1);\n}\n\nfunction getUserName(patternName: string): string[] {\n let first = -1;\n for (let i = 0; i < patternName.length; i++) {\n if (patternName[i] === '(') {\n first = i;\n break;\n }\n }\n return (first === -1) ? ['', ''] : patternName.slice(first + 9, patternName.length - 1).split(' ').slice(1);\n}\n\nexport function translateSequence(\n sequence: string,\n bases: DG.InputBase[],\n ptoLinkages: DG.InputBase[],\n startModification: DG.InputBase,\n endModification: DG.InputBase,\n firstPtoExist: boolean): string {\n let i: number = -1;\n let mainSequence = sequence.replace(/[AUGC]/g, function(x: string) {\n i++;\n const AXOLABS_MAP = axolabsStyleMap;\n\n const baseChoices: string[] = Object.keys(AXOLABS_MAP);\n // const defaultBase: string = baseChoices[0];\n const indexOfSymbol = AXOLABS_MAP['RNA']['symbols'].indexOf(x);\n let symbol = AXOLABS_MAP[bases[i].value]['symbols'][indexOfSymbol];\n if (isOverhang(bases[i].value)) {\n if (i < sequence.length / 2 && !isOverhang(bases[i + 1].value))\n symbol = symbol + x + 'f';\n else if (i > sequence.length / 2 && !isOverhang(bases[i - 1].value))\n symbol = x + 'f' + symbol;\n }\n return (ptoLinkages[i].value) ? symbol + 's' : symbol;\n });\n if (mainSequence.slice(0, 5).split('mU').length === 3)\n mainSequence = '(uu)' + mainSequence.slice(4);\n if (mainSequence.slice(mainSequence.length - 7).split('mU').length === 3)\n mainSequence = mainSequence.slice(0, mainSequence.length - 4) + '(uu)';\n return startModification.value + (firstPtoExist ? 's' : '') + mainSequence + endModification.value;\n}\n\nexport function addColumnWithIds(tableName: string, columnName: string, patternName: string) {\n const nameOfNewColumn = 'ID ' + patternName;\n const columns = grok.shell.table(tableName).columns;\n if (columns.contains(nameOfNewColumn))\n columns.remove(nameOfNewColumn);\n const columnWithIds = columns.byName(columnName);\n return columns.addNewString(nameOfNewColumn).init((i: number) => {\n return (columnWithIds.getString(i) === '') ? '' : columnWithIds.get(i) + '_' + patternName;\n });\n}\n\nexport function addColumnWithTranslatedSequences(\n tableName: string,\n columnName: string,\n bases: DG.InputBase[],\n ptoLinkages: DG.InputBase[],\n startModification: DG.InputBase,\n endModification: DG.InputBase,\n firstPtoExist: boolean) {\n const nameOfNewColumn = 'Axolabs ' + columnName;\n const columns = grok.shell.table(tableName).columns;\n if (columns.contains(nameOfNewColumn))\n columns.remove(nameOfNewColumn);\n const columnWithInputSequences = columns.byName(columnName);\n return columns.addNewString(nameOfNewColumn).init((i: number) => {\n return columnWithInputSequences.getString(i) === '' ?\n '' :\n translateSequence(columnWithInputSequences.getString(i), bases, ptoLinkages, startModification, endModification,\n firstPtoExist);\n });\n}\n","import {NUCLEOTIDES} from '../const';\nimport {isOverhang, svg, textWidth, countOverhangsOnTheRightEdge, baseColor, textInsideCircle,\n fontColorVisibleOnBackground, isOneDigitNumber} from './helpers';\n\nconst BASE_RADIUS = 15;\nconst BASE_DIAMETER = 2 * BASE_RADIUS;\nconst shiftToAlignTwoDigitNumberNearCircle = -10;\nconst shiftToAlignOneDigitNumberNearCircle = -5;\nconst LEGEND_RADIUS = 6;\nconst PS_LINKAGE_RADIUS = 5;\nconst BASE_FONT_SIZE = 17;\nconst LEGEND_FONT_SIZE = 14;\nconst PS_LINKAGE_COLOR = 'red';\nconst FONT_COLOR = 'var(--grey-6)';\nconst TITLE_FONT_COLOR = 'black';\nconst MODIFICATIONS_COLOR = 'red';\nconst SS_LEFT_TEXT = 'SS: 5\\'';\nconst AS_LEFT_TEXT = 'AS: 3\\'';\nconst SS_RIGHT_TEXT = '3\\'';\nconst AS_RIGHT_TEXT = '5\\'';\n\nconst WIDTH_OF_LEFT_TEXT = Math.max(\n textWidth(SS_LEFT_TEXT, BASE_FONT_SIZE),\n textWidth(AS_LEFT_TEXT, BASE_FONT_SIZE),\n);\n\nconst WIDTH_OF_RIGHT_TEXT = Math.max(\n textWidth(SS_RIGHT_TEXT, BASE_FONT_SIZE),\n textWidth(AS_RIGHT_TEXT, BASE_FONT_SIZE),\n);\n\nconst X = {\n TITLE: BASE_RADIUS, // Math.round(width / 4),\n LEFT_TEXTS: 0,\n};\nconst X_OF_LEFT_MODIFICATIONS = X.LEFT_TEXTS + WIDTH_OF_LEFT_TEXT - 5;\n\nconst Y = {\n TITLE: BASE_RADIUS,\n SS_INDICES: 2 * BASE_RADIUS,\n SS_CIRCLES: 3.5 * BASE_RADIUS,\n SS_TEXTS: 4 * BASE_RADIUS,\n AS_CIRCLES: 6.5 * BASE_RADIUS,\n AS_TEXTS: 7 * BASE_RADIUS,\n AS_INDICES: 8.5 * BASE_RADIUS,\n comment: (asExists: boolean) => (asExists) ? 11 * BASE_RADIUS : 8.5 * BASE_RADIUS,\n circlesInLegends: (asExists: boolean) => (asExists) ? 9.5 * BASE_RADIUS : 6 * BASE_RADIUS,\n textLegend: (asExists: boolean) => (asExists) ? 10 * BASE_RADIUS - 3 : Y.AS_CIRCLES - 3,\n svgHeight: (asExists: boolean) => (asExists) ? 11 * BASE_RADIUS : 9 * BASE_RADIUS,\n};\n\nexport function drawAxolabsPattern(\n patternName: string, asExists: boolean, ssBases: string[],\n asBases: string[], ssPtoStatuses: boolean[], asPtoStatuses: boolean[],\n ss3Modification: string, ss5Modification: string,\n as3Modification: string, as5Modification: string, comment: string,\n enumerateModifications: string[],\n): Element {\n function equidistantXForLegend(index: number): number {\n return Math.round((index + startFrom) * width / (uniqueBases.length + startFrom) + LEGEND_RADIUS);\n }\n\n function xOfBaseCircles(index: number, rightOverhangs: number): number {\n return widthOfRightModification +\n (resultingNumberOfNucleotidesInStrands - index + rightOverhangs + 1) * BASE_DIAMETER;\n }\n\n function shiftToAlignNumberNearCircle(bases: string[], generalIndex: number, nucleotideIndex: number): number {\n return (isOneDigitNumber(nucleotideIndex) || NUCLEOTIDES.includes(bases[generalIndex])) ?\n shiftToAlignOneDigitNumberNearCircle : shiftToAlignTwoDigitNumberNearCircle;\n }\n\n ssBases = ssBases.reverse();\n ssPtoStatuses = ssPtoStatuses.reverse();\n\n const ssRightOverhangs = countOverhangsOnTheRightEdge(ssBases);\n const asRightOverhangs = countOverhangsOnTheRightEdge(asBases);\n\n const resultingNumberOfNucleotidesInStrands = Math.max(\n ssBases.length - ssRightOverhangs,\n asBases.length - asRightOverhangs,\n );\n\n const widthOfRightOverhangs = Math.max(ssRightOverhangs, asRightOverhangs);\n const widthOfBases = BASE_DIAMETER * (resultingNumberOfNucleotidesInStrands + widthOfRightOverhangs);\n\n const widthOfLeftModification = Math.max(\n textWidth(ss3Modification, BASE_FONT_SIZE),\n textWidth(as5Modification, BASE_FONT_SIZE),\n );\n\n const widthOfRightModification = Math.max(\n textWidth(ss5Modification, BASE_FONT_SIZE),\n textWidth(as3Modification, BASE_FONT_SIZE),\n );\n\n const uniqueBases = asExists ?\n [...new Set(ssBases.concat(asBases))] :\n [...new Set(ssBases)];\n\n const isPtoExist = asExists ?\n ssPtoStatuses.concat(asPtoStatuses).includes(true) :\n ssPtoStatuses.includes(true);\n\n const startFrom = isPtoExist ? 1 : 0;\n\n const xOfSsRightModifications = ssRightOverhangs * BASE_DIAMETER + xOfBaseCircles(-0.5, 0);\n const xOfAsRightModifications = asRightOverhangs * BASE_DIAMETER + xOfBaseCircles(-0.5, 0);\n\n const xOfRightTexts = Math.max(xOfSsRightModifications, xOfAsRightModifications) + widthOfLeftModification +\n BASE_DIAMETER * widthOfRightOverhangs;\n\n const width = WIDTH_OF_LEFT_TEXT + widthOfLeftModification + widthOfBases + widthOfRightModification +\n WIDTH_OF_RIGHT_TEXT + BASE_DIAMETER;\n const image = svg.render(width, Y.svgHeight(asExists));\n\n image.append(\n svg.text(SS_LEFT_TEXT, X.LEFT_TEXTS, Y.SS_TEXTS, BASE_FONT_SIZE, FONT_COLOR),\n asExists ? svg.text(AS_LEFT_TEXT, X.LEFT_TEXTS, Y.AS_TEXTS, BASE_FONT_SIZE, FONT_COLOR) : '',\n svg.text(SS_RIGHT_TEXT, xOfRightTexts, Y.SS_TEXTS, BASE_FONT_SIZE, FONT_COLOR),\n asExists ? svg.text(AS_RIGHT_TEXT, xOfRightTexts, Y.AS_TEXTS, BASE_FONT_SIZE, FONT_COLOR) : '',\n svg.text(ss5Modification, X_OF_LEFT_MODIFICATIONS, Y.SS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR),\n asExists ? svg.text(as3Modification, X_OF_LEFT_MODIFICATIONS, Y.AS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR) : '',\n svg.text(ss3Modification, xOfSsRightModifications, Y.SS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR),\n asExists ? svg.text(as5Modification, xOfAsRightModifications, Y.AS_TEXTS, BASE_FONT_SIZE, MODIFICATIONS_COLOR) : '',\n svg.text(comment, X.LEFT_TEXTS, Y.comment(asExists), LEGEND_FONT_SIZE, FONT_COLOR),\n isPtoExist ? svg.star(BASE_RADIUS, Y.circlesInLegends(asExists), PS_LINKAGE_COLOR) : '',\n isPtoExist ? svg.text('ps linkage', 2 * BASE_RADIUS - 8, Y.textLegend(asExists), LEGEND_FONT_SIZE, FONT_COLOR) : '',\n );\n\n const numberOfSsNucleotides = ssBases.filter((value) => !isOverhang(value)).length;\n let nucleotideCounter = numberOfSsNucleotides;\n for (let i = ssBases.length - 1; i > -1; i--) {\n const xOfNumbers = xOfBaseCircles(i, ssRightOverhangs) +\n shiftToAlignNumberNearCircle(ssBases, ssBases.length - i, numberOfSsNucleotides - nucleotideCounter);\n if (!isOverhang(ssBases[i]))\n nucleotideCounter--;\n const n = (!isOverhang(ssBases[i]) && enumerateModifications.includes(ssBases[i])) ?\n String(numberOfSsNucleotides - nucleotideCounter) : '';\n image.append(\n svg.text(n, xOfNumbers, Y.SS_INDICES, LEGEND_FONT_SIZE, FONT_COLOR),\n svg.circle(xOfBaseCircles(i, ssRightOverhangs), Y.SS_CIRCLES, BASE_RADIUS, baseColor(ssBases[i])),\n svg.text(textInsideCircle(ssBases, i), xOfNumbers, Y.SS_TEXTS, BASE_FONT_SIZE,\n fontColorVisibleOnBackground(ssBases[i])),\n ssPtoStatuses[i] ?\n svg.star(xOfBaseCircles(i, ssRightOverhangs) + BASE_RADIUS, Y.SS_TEXTS + PS_LINKAGE_RADIUS, PS_LINKAGE_COLOR) :\n '',\n );\n }\n image.append(\n ssPtoStatuses[ssBases.length] ?\n svg.star(xOfBaseCircles(ssBases.length, ssRightOverhangs) +\n BASE_RADIUS, Y.SS_TEXTS + PS_LINKAGE_RADIUS, PS_LINKAGE_COLOR) : '',\n );\n\n const numberOfAsNucleotides = asBases.filter((value) => !isOverhang(value)).length;\n if (asExists) {\n let nucleotideCounter = numberOfAsNucleotides;\n for (let i = asBases.length - 1; i > -1; i--) {\n if (!isOverhang(asBases[i]))\n nucleotideCounter--;\n const xOfNumbers = xOfBaseCircles(i, asRightOverhangs) +\n shiftToAlignNumberNearCircle(asBases, i, nucleotideCounter + 1);\n const n = (!isOverhang(asBases[i]) && enumerateModifications.includes(asBases[i])) ?\n String(nucleotideCounter + 1) : '';\n image.append(\n svg.text(n, xOfNumbers, Y.AS_INDICES, LEGEND_FONT_SIZE, FONT_COLOR),\n svg.circle(xOfBaseCircles(i, asRightOverhangs), Y.AS_CIRCLES, BASE_RADIUS, baseColor(asBases[i])),\n svg.text(textInsideCircle(asBases, i),\n xOfBaseCircles(i, asRightOverhangs) + shiftToAlignNumberNearCircle(asBases, i, nucleotideCounter + 1),\n Y.AS_TEXTS, BASE_FONT_SIZE, fontColorVisibleOnBackground(asBases[i])),\n asPtoStatuses[i] ? svg.star(xOfBaseCircles(i, asRightOverhangs) +\n BASE_RADIUS, Y.AS_TEXTS + PS_LINKAGE_RADIUS, PS_LINKAGE_COLOR) : '',\n );\n }\n image.append(\n asPtoStatuses[asBases.length] ?\n svg.star(xOfBaseCircles(asBases.length, asRightOverhangs) + BASE_RADIUS, Y.AS_TEXTS + PS_LINKAGE_RADIUS,\n PS_LINKAGE_COLOR) : '',\n );\n }\n\n const title = `${patternName} for ${numberOfSsNucleotides}${(asExists ? `/${numberOfAsNucleotides}` : '')}mer`;\n image.append(svg.text(title, X.TITLE, Y.TITLE, BASE_FONT_SIZE, TITLE_FONT_COLOR));\n for (let i = 0; i < uniqueBases.length; i++) {\n image.append(\n svg.circle(equidistantXForLegend(i), Y.circlesInLegends(asExists), LEGEND_RADIUS, baseColor(uniqueBases[i])),\n svg.text(uniqueBases[i], equidistantXForLegend(i) + LEGEND_RADIUS + 4, Y.textLegend(asExists), LEGEND_FONT_SIZE,\n FONT_COLOR),\n );\n }\n return image;\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {axolabsStyleMap} from '../../model/data-loading-utils/json-loader';\nimport {\n DEFAULT_PTO, DEFAULT_SEQUENCE_LENGTH, MAX_SEQUENCE_LENGTH, USER_STORAGE_KEY, SS, AS, STRAND_NAME, STRANDS, TERMINAL, TERMINAL_KEYS, THREE_PRIME, FIVE_PRIME, JSON_FIELD as FIELD\n} from '../../model/pattern-app/const';\nimport {isOverhang} from '../../model/pattern-app/helpers';\nimport {generateExample, translateSequence, getShortName, isCurrentUserCreatedThisPattern, findDuplicates, addColumnWithIds, addColumnWithTranslatedSequences} from '../../model//pattern-app/oligo-pattern';\nimport {drawAxolabsPattern} from '../../model/pattern-app/draw-svg';\n// todo: remove ts-ignore\n//@ts-ignore\nimport * as svg from 'save-svg-as-png';\nimport $ from 'cash-dom';\n\ntype BooleanInput = DG.InputBase<boolean | null>;\ntype StringInput = DG.InputBase<string | null>;\n\nexport class PatternLayoutHandler {\n get htmlDivElement() {\n function updateModification(strand: string) {\n modificationItems[strand].innerHTML = '';\n ptoLinkages[strand] = ptoLinkages[strand].concat(Array(maxStrandLength[strand] - baseInputsObject[strand].length).fill(fullyPto));\n baseInputsObject[strand] = baseInputsObject[strand].concat(Array(maxStrandLength[strand] - baseInputsObject[strand].length).fill(sequenceBase));\n let nucleotideCounter = 0;\n for (let i = 0; i < strandLengthInput[strand].value!; i++) {\n ptoLinkages[strand][i] = ui.boolInput('', ptoLinkages[strand][i].value!, () => {\n updateSvgScheme();\n updateOutputExamples();\n });\n baseInputsObject[strand][i] = ui.choiceInput('', baseInputsObject[strand][i].value, baseChoices, (v: string) => {\n if (!enumerateModifications.includes(v)) {\n enumerateModifications.push(v);\n isEnumerateModificationsDiv.append(\n ui.divText('', {style: {width: '25px'}}),\n ui.boolInput(v, true, (boolV: boolean) => {\n if (boolV) {\n if (!enumerateModifications.includes(v))\n enumerateModifications.push(v);\n } else {\n const index = enumerateModifications.indexOf(v, 0);\n if (index > -1)\n enumerateModifications.splice(index, 1);\n }\n updateSvgScheme();\n }).root,\n );\n }\n updateModification(AS);\n updateSvgScheme();\n updateOutputExamples();\n });\n $(baseInputsObject[strand][i].root).addClass('st-pattern-choice-input');\n if (!isOverhang(baseInputsObject[strand][i].value!))\n nucleotideCounter++;\n\n modificationItems[strand].append(\n ui.divH([\n ui.div([ui.label(isOverhang(baseInputsObject[strand][i].value!) ? '' : String(nucleotideCounter))],\n {style: {width: '20px'}})!,\n ui.block75([baseInputsObject[strand][i].root])!,\n ui.div([ptoLinkages[strand][i]])!,\n ], {style: {alignItems: 'center'}}),\n );\n }\n }\n\n function updateUiForNewSequenceLength() {\n if (Object.values(strandLengthInput).every((input) => input.value! < MAX_SEQUENCE_LENGTH)) {\n STRANDS.forEach((strand) => {\n if (strandLengthInput[strand].value! > maxStrandLength[strand])\n maxStrandLength[strand] = strandLengthInput[strand].value!;\n updateModification(strand);\n })\n\n updateSvgScheme();\n updateInputExamples();\n updateOutputExamples();\n } else {\n ui.dialog('Out of range')\n .add(ui.divText('Sequence length should be less than ' +\n MAX_SEQUENCE_LENGTH.toString() + ' due to UI constrains.'))\n .onOK(()=> {Object.values(strandLengthInput).every((input)=> input.value = 34)})\n .onCancel(()=> {Object.values(strandLengthInput).every((input)=> input.value = 34)})\n .showModal(false);\n }\n }\n\n // todo: unify with updateBases\n function updatePto(newPtoValue: boolean): void {\n STRANDS.forEach((strand) => {\n for (let i = 0; i < ptoLinkages[strand].length; i++)\n ptoLinkages[strand][i].value = newPtoValue;\n })\n updateSvgScheme();\n }\n\n function updateBases(newBasisValue: string): void {\n STRANDS.forEach((strand) => {\n for (let i = 0; i < baseInputsObject[strand].length; i++)\n baseInputsObject[strand][i].value = newBasisValue;\n })\n updateSvgScheme();\n }\n\n function updateInputExamples() {\n STRANDS.forEach((s) => {\n if (strandColumnInput[s].value === '')\n inputExample[s].value = generateExample(strandLengthInput[s].value!, sequenceBase.value!);\n });\n }\n\n function updateOutputExamples() {\n const conditions = [true, createAsStrand.value];\n STRANDS.forEach((strand, i) => {\n if (conditions[i]) {\n outputExample[strand].value = translateSequence(inputExample[strand].value, baseInputsObject[strand], ptoLinkages[strand], terminalModification[strand][FIVE_PRIME], terminalModification[strand][THREE_PRIME], firstPto[strand].value!);\n }\n })\n }\n\n function updateSvgScheme() {\n svgDiv.innerHTML = '';\n svgDiv.append(\n ui.span([\n\n // todo: refactor the funciton, reduce # of args\n drawAxolabsPattern(\n getShortName(saveAs.value),\n createAsStrand.value!,\n\n baseInputsObject[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value!),\n baseInputsObject[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value!),\n\n [firstPto[SS].value!].concat(ptoLinkages[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value!)),\n [firstPto[AS].value!].concat(ptoLinkages[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value!)),\n\n terminalModification[SS][THREE_PRIME].value,\n terminalModification[SS][FIVE_PRIME].value,\n\n terminalModification[AS][THREE_PRIME].value,\n terminalModification[AS][FIVE_PRIME].value,\n\n comment.value,\n enumerateModifications,\n ),\n ]),\n );\n }\n\n // todo: rename\n function detectDefaultBasis(array: string[]) {\n const modeMap: {[index: string]: number} = {};\n let maxEl = array[0];\n let maxCount = 1;\n for (let i = 0; i < array.length; i++) {\n const el = array[i];\n if (modeMap[el] === null)\n modeMap[el] = 1;\n else\n modeMap[el]++;\n if (modeMap[el] > maxCount) {\n maxEl = el;\n maxCount = modeMap[el];\n }\n }\n return maxEl;\n }\n\n async function parsePatternAndUpdateUi(newName: string) {\n const pi = DG.TaskBarProgressIndicator.create('Loading pattern...');\n await grok.dapi.userDataStorage.get(USER_STORAGE_KEY, false).then((entities) => {\n const obj = JSON.parse(entities[newName]);\n sequenceBase.value = detectDefaultBasis(obj[FIELD.AS_BASES].concat(obj[FIELD.SS_BASES]));\n createAsStrand.value = (obj[FIELD.AS_BASES].length > 0);\n saveAs.value = newName;\n\n let fields = [FIELD.SS_BASES, FIELD.AS_BASES];\n STRANDS.forEach((strand, i) => {\n baseInputsObject[strand] = [];\n const field = fields[i];\n for (let j = 0; j < obj[field].length; j++)\n baseInputsObject[strand].push(ui.choiceInput('', obj[field][j], baseChoices));\n })\n\n fields = [FIELD.SS_PTO, FIELD.AS_PTO];\n STRANDS.forEach((s, i) => {\n const field = fields[i];\n firstPto[s].value = obj[field][0];\n ptoLinkages[s] = [];\n for (let j = 1; j < obj[field].length; j++)\n ptoLinkages[s].push(ui.boolInput('', obj[field][j]));\n });\n\n fields = [FIELD.SS_BASES, FIELD.AS_BASES];\n STRANDS.forEach((strand, i) => {\n strandLengthInput[strand].value = obj[fields[i]].length;\n })\n\n const field = [[FIELD.SS_3, FIELD.SS_5], [FIELD.AS_3, FIELD.AS_5]];\n STRANDS.forEach((strand, i) => {\n TERMINAL_KEYS.forEach((terminal, j) => {\n terminalModification[strand][terminal].value = obj[field[i][j]];\n })\n })\n comment.value = obj[FIELD.COMMENT];\n });\n pi.close();\n }\n\n function allColumnValuesOfEqualLength(colName: string): boolean {\n const col = tableInput.value!.getCol(colName);\n let allLengthsAreTheSame = true;\n for (let i = 1; i < col.length; i++) {\n if (col.get(i - 1).length !== col.get(i).length && col.get(i).length !== 0) {\n allLengthsAreTheSame = false;\n break;\n }\n }\n if (!allLengthsAreTheSame) {\n const dialog = ui.dialog('Sequences lengths mismatch');\n $(dialog.getButton('OK')).hide();\n dialog\n .add(ui.divText('The sequence length should match the number of Raw sequences in the input file'))\n .add(ui.divText('\\'ADD COLUMN\\' to see sequences lengths'))\n .addButton('ADD COLUMN', () => {\n tableInput.value!.columns.addNewInt('Sequences lengths in ' + colName).init((j: number) => col.get(j).length);\n grok.shell.info('Column with lengths added to \\'' + tableInput.value!.name + '\\'');\n dialog.close();\n grok.shell.v = grok.shell.getTableView(tableInput.value!.name);\n })\n .show();\n }\n if (col.get(0).length !== strandLengthInput[SS].value) {\n const d = ui.dialog('Length was updated by value to from imported file');\n d.add(ui.divText('Latest modifications may not take effect during translation'))\n .onOK(() => grok.shell.info('Lengths changed')).show();\n }\n return allLengthsAreTheSame;\n }\n\n async function getCurrentUserName(): Promise<string> {\n return await grok.dapi.users.current().then((user) => {\n return ' (created by ' + user.friendlyName + ')';\n });\n }\n\n async function postPatternToUserStorage() {\n const currUserName = await getCurrentUserName();\n saveAs.value = (saveAs.stringValue.includes('(created by ')) ?\n getShortName(saveAs.value) + currUserName :\n saveAs.stringValue + currUserName;\n return grok.dapi.userDataStorage.postValue(\n USER_STORAGE_KEY,\n saveAs.value,\n JSON.stringify({\n [FIELD.SS_BASES]: baseInputsObject[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value),\n [FIELD.AS_BASES]: baseInputsObject[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value),\n [FIELD.SS_PTO]: [firstPto[SS].value].concat(ptoLinkages[SS].slice(0, strandLengthInput[SS].value!).map((e) => e.value)),\n [FIELD.AS_PTO]: [firstPto[AS].value].concat(ptoLinkages[AS].slice(0, strandLengthInput[AS].value!).map((e) => e.value)),\n [FIELD.SS_3]: terminalModification[SS][THREE_PRIME].value,\n [FIELD.SS_5]:terminalModification[SS][FIVE_PRIME].value,\n [FIELD.AS_3]: terminalModification[AS][THREE_PRIME].value,\n [FIELD.AS_5]: terminalModification[AS][FIVE_PRIME].value,\n [FIELD.COMMENT]: comment.value,\n }),\n false,\n ).then(() => grok.shell.info('Pattern \\'' + saveAs.value + '\\' was successfully uploaded!'));\n }\n\n async function updatePatternsList() {\n grok.dapi.userDataStorage.get(USER_STORAGE_KEY, false).then(async (entities) => {\n const lstMy: string[] = [];\n const lstOthers: string[] = [];\n\n // TODO: display short name, but use long for querying userdataStorage\n for (const ent of Object.keys(entities)) {\n if (await isCurrentUserCreatedThisPattern(ent))\n lstOthers.push(ent);\n else\n lstMy.push(ent);//getShortName(ent));\n }\n\n let loadPattern = ui.choiceInput('Load pattern', '', lstMy, (v: string) => parsePatternAndUpdateUi(v));\n\n const currentUserName = (await grok.dapi.users.current()).friendlyName;\n const otherUsers = 'Other users';\n\n const patternListChoiceInput = ui.choiceInput('', currentUserName, [currentUserName, otherUsers], (v: string) => {\n const currentList = v === currentUserName ? lstMy : lstOthers;\n loadPattern = ui.choiceInput('Load pattern', '', currentList, (v: string) => parsePatternAndUpdateUi(v));\n\n loadPattern.root.append(patternListChoiceInput.input);\n loadPattern.root.append(loadPattern.input);\n // @ts-ignore\n loadPattern.input.style.maxWidth = '120px';\n loadPattern.input.style.marginLeft = '12px';\n loadPattern.setTooltip('Apply Existing Pattern');\n\n loadPatternDiv.innerHTML = '';\n loadPatternDiv.append(loadPattern.root);\n loadPattern.root.append(\n ui.div([\n ui.button(ui.iconFA('trash-alt', () => {}), async () => {\n if (loadPattern.value === null)\n grok.shell.warning('Choose pattern to delete');\n else if (await isCurrentUserCreatedThisPattern(saveAs.value))\n grok.shell.warning('Cannot delete pattern, created by other user');\n else {\n await grok.dapi.userDataStorage.remove(USER_STORAGE_KEY, loadPattern.value, false)\n .then(() => grok.shell.info('Pattern \\'' + loadPattern.value + '\\' deleted'));\n }\n await updatePatternsList();\n }),\n ], 'ui-input-options'),\n );\n });\n patternListChoiceInput.input.style.maxWidth = '142px';\n loadPattern.root.append(patternListChoiceInput.input);\n loadPattern.root.append(loadPattern.input);\n // @ts-ignore\n loadPattern.input.style.maxWidth = '100px';\n loadPattern.setTooltip('Apply Existing Pattern');\n\n loadPatternDiv.innerHTML = '';\n loadPatternDiv.append(loadPattern.root);\n loadPattern.root.append(\n ui.div([\n ui.button(ui.iconFA('trash-alt', () => {}), async () => {\n if (loadPattern.value === null)\n grok.shell.warning('Choose pattern to delete');\n else if (await isCurrentUserCreatedThisPattern(saveAs.value))\n grok.shell.warning('Cannot delete pattern, created by other user');\n else {\n await grok.dapi.userDataStorage.remove(USER_STORAGE_KEY, loadPattern.value, false)\n .then(() => grok.shell.info('Pattern \\'' + loadPattern.value + '\\' deleted'));\n }\n await updatePatternsList();\n }),\n ], 'ui-input-options'),\n );\n });\n }\n\n async function savePattern() {\n await grok.dapi.userDataStorage.get(USER_STORAGE_KEY, false)\n .then((entities) => {\n if (Object.keys(entities).includes(saveAs.value)) {\n const dialog = ui.dialog('Pattern already exists');\n $(dialog.getButton('OK')).hide();\n dialog\n .add(ui.divText('Pattern name \\'' + saveAs.value + '\\' already exists.'))\n .add(ui.divText('Replace pattern?'))\n .addButton('YES', async () => {\n await grok.dapi.userDataStorage.remove(USER_STORAGE_KEY, saveAs.value, false)\n .then(() => postPatternToUserStorage());\n dialog.close();\n })\n .show();\n } else\n postPatternToUserStorage();\n });\n await updatePatternsList();\n }\n\n function validateStrandColumn(colName: string, strand: string): void {\n const allLengthsAreTheSame: boolean = allColumnValuesOfEqualLength(colName);\n const firstSequence = tableInput.value!.getCol(colName).get(0);\n if (allLengthsAreTheSame && firstSequence.length !== strandLengthInput[strand].value)\n strandLengthInput[strand].value = tableInput.value!.getCol(colName).get(0).length;\n inputExample[strand].value = firstSequence;\n }\n\n function validateIdsColumn(colName: string) {\n const col = tableInput.value!.getCol(colName);\n if (col.type !== DG.TYPE.INT)\n grok.shell.error('Column should contain integers only');\n //@ts-ignore\n else if (col.categories.filter((e) => e !== '').length < col.toList().filter((e) => e !== '').length) {\n const duplicates = findDuplicates(col.getRawData());\n ui.dialog('Non-unique IDs')\n .add(ui.divText('Press \\'OK\\' to select rows with non-unique values'))\n .onOK(() => {\n const selection = tableInput.value!.selection;\n selection.init((i: number) => duplicates.indexOf(col.get(i)) > -1);\n grok.shell.v = grok.shell.getTableView(tableInput.value!.name);\n grok.shell.info('Rows are selected in table \\'' + tableInput.value!.name + '\\'');\n })\n .show();\n }\n }\n\n const baseChoices: string[] = Object.keys(axolabsStyleMap);\n const defaultBase: string = baseChoices[0];\n const enumerateModifications = [defaultBase];\n const sequenceBase = ui.choiceInput('Sequence basis', defaultBase, baseChoices, (v: string) => {\n updateBases(v);\n updateOutputExamples();\n });\n const fullyPto = ui.boolInput('Fully PTO', DEFAULT_PTO, (v: boolean) => {\n STRANDS.forEach((s) => { firstPto[s].value = v; })\n updatePto(v);\n updateOutputExamples();\n });\n fullyPto.captionLabel.classList.add('ui-label-right');\n fullyPto.captionLabel.style.textAlign = 'left';\n fullyPto.captionLabel.style.maxWidth = '100px';\n fullyPto.captionLabel.style.maxWidth = '100px';\n fullyPto.captionLabel.style.minWidth = '40px';\n fullyPto.captionLabel.style.width = 'auto';\n\n const maxStrandLength = Object.fromEntries(STRANDS.map(\n (strand) => [strand, DEFAULT_SEQUENCE_LENGTH]\n ));\n // todo: remove vague legacy 'items' from name\n const modificationItems = Object.fromEntries(STRANDS.map(\n (strand) => [strand, ui.div([])]\n ));\n const ptoLinkages = Object.fromEntries(STRANDS.map(\n (strand) => [strand, Array<BooleanInput>(DEFAULT_SEQUENCE_LENGTH)\n .fill(ui.boolInput('', DEFAULT_PTO))]\n ));\n const baseInputsObject = Object.fromEntries(STRANDS.map(\n (strand) => {\n const choiceInputs = Array<StringInput>(DEFAULT_SEQUENCE_LENGTH)\n .fill(ui.choiceInput('', defaultBase, baseChoices));\n return [strand, choiceInputs];\n }\n ));\n const strandLengthInput = Object.fromEntries(STRANDS.map(\n (strand) => {\n const input = ui.intInput(`${STRAND_NAME[strand]} length`, DEFAULT_SEQUENCE_LENGTH, () => updateUiForNewSequenceLength());\n input.setTooltip(`Length of ${STRAND_NAME[strand].toLowerCase()}, including overhangs`);\n return [strand, input];\n }));\n const strandVar = Object.fromEntries(STRANDS.map((strand) => [strand, '']));\n const inputExample = Object.fromEntries(STRANDS.map(\n (strand) => [strand, ui.textInput(\n ``, generateExample(strandLengthInput[strand].value!, sequenceBase.value!))\n ]));\n\n const strandColumnInput = Object.fromEntries(STRANDS.map((strand) => {\n const input = ui.choiceInput(`${STRAND_NAME[strand]} column`, '', [], (colName: string) => {\n validateStrandColumn(colName, strand);\n strandVar[strand] = colName;\n });\n return [strand, input];\n }));\n\n const firstPto = Object.fromEntries(STRANDS.map((strand) => {\n const input = ui.boolInput(`First ${strand} PTO`, fullyPto.value!, () => updateSvgScheme());\n input.setTooltip(`ps linkage before first nucleotide of ${STRAND_NAME[strand].toLowerCase()}`);\n\n input.captionLabel.classList.add('ui-label-right');\n input.captionLabel.style.textAlign = 'left';\n input.captionLabel.style.maxWidth = '100px';\n input.captionLabel.style.minWidth = '40px';\n input.captionLabel.style.width = 'auto';\n\n return [strand, input];\n }));\n\n const terminalModification = Object.fromEntries(STRANDS.map((strand) => {\n const inputs = Object.fromEntries(TERMINAL_KEYS.map((key) => {\n const input = ui.stringInput(`${strand} ${TERMINAL[key]}\\' Modification`, '', () => {\n updateSvgScheme();\n updateOutputExamples();\n });\n input.setTooltip(`Additional ${strand} ${TERMINAL[key]}\\' Modification`);\n return [key, input];\n }));\n return [strand, inputs];\n }));\n\n const outputExample = Object.fromEntries(STRANDS.map((strand) => {\n const input = ui.textInput('', translateSequence(\n inputExample[strand].value, baseInputsObject[strand], ptoLinkages[strand], terminalModification[strand][THREE_PRIME],terminalModification[strand][FIVE_PRIME], firstPto[strand].value!\n ));\n input.input.style.minWidth = 'none';\n input.input.style.flexGrow = '1';\n $(input.root.lastChild).css('height', 'auto');\n return [strand, input];\n }));\n\n const modificationSection = Object.fromEntries(STRANDS.map((strand) => {\n const panel = ui.block([\n ui.h1(`${STRAND_NAME[strand]}`),\n ui.divH([\n ui.div([ui.divText('#')], {style: {width: '20px'}})!,\n ui.block75([ui.divText('Modification')])!,\n ui.div([ui.divText('PTO')])!,\n ]),\n modificationItems[strand],\n ], {style: {paddingTop: '12px'}});\n return [strand, panel];\n }));\n\n STRANDS.forEach((s) => {\n \n inputExample[s].input.style.resize = 'none';\n outputExample[s].input.style.resize = 'none';\n inputExample[s].input.style.minWidth = 'none';\n inputExample[s].input.style.flexGrow = '1';\n outputExample[s].input.style.minWidth = 'none';\n outputExample[s].input.style.flexGrow = '1';\n let options = ui.div([\n ui.button(ui.iconFA('copy', () => {}), () => {\n navigator.clipboard.writeText(outputExample[s].value).then(() =>\n grok.shell.info('Sequence was copied to clipboard'));\n }),\n ], 'ui-input-options');\n options.style.height = 'inherit';\n outputExample[s].root.append(\n options\n );\n })\n\n // const inputIdColumnDiv = ui.div([]);\n const svgDiv = ui.div([]);\n const asExampleDiv = ui.div([], 'ui-form ui-form-wide');\n const loadPatternDiv = ui.div([]);\n const asModificationDiv = ui.form([]);\n const isEnumerateModificationsDiv = ui.divH([\n ui.boolInput(defaultBase, true, (v: boolean) => {\n if (v) {\n if (!enumerateModifications.includes(defaultBase))\n enumerateModifications.push(defaultBase);\n } else {\n const index = enumerateModifications.indexOf(defaultBase, 0);\n if (index > -1)\n enumerateModifications.splice(index, 1);\n }\n updateSvgScheme();\n updateOutputExamples();\n }).root,\n ]);\n\n const asLengthDiv = ui.div([strandLengthInput[AS].root]);\n\n function getTableInput(tableList: DG.DataFrame[]): DG.InputBase {\n const tableInput = ui.tableInput('Tables', tableList[0], tableList, () => {\n const table = tableInput.value;\n if (table === null) {\n console.warn('Table is null');\n return;\n }\n const tableName = table!.name;\n if (!grok.shell.tableNames.includes(tableName)) {\n const view = grok.shell.v;\n grok.shell.addTableView(table!);\n grok.shell.v = view;\n }\n const columnNames = table.columns.names();\n\n STRANDS.forEach((strand) => {\n const defaultColumn = columnNames[0];\n validateStrandColumn(defaultColumn, strand);\n strandVar[strand] = defaultColumn;\n const input = ui.choiceInput(`${STRAND_NAME[strand]} column`, defaultColumn, columnNames, (colName: string) => {\n validateStrandColumn(colName, strand);\n strandVar[strand] = colName;\n console.log(`clicked ${strand} var:`, strandVar[strand]);\n });\n $(strandColumnInput[strand].root).replaceWith(input.root);\n })\n\n idVar = columnNames[0];\n // todo: unify with inputStrandColumn\n const idInput = ui.choiceInput('ID column', columnNames[0], columnNames, (colName: string) => {\n validateIdsColumn(colName);\n idVar = colName;\n });\n $(inputIdColumn.root).replaceWith(idInput.root);\n });\n return tableInput;\n }\n\n const tableInput = getTableInput([]);\n\n // todo: unify with strandVar\n let idVar = '';\n const inputIdColumn = ui.choiceInput('ID column', '', [], (colName: string) => {\n validateIdsColumn(colName);\n idVar = colName;\n });\n // inputIdColumnDiv.append(inputIdColumn.root);\n\n updatePatternsList();\n\n const createAsStrand = ui.boolInput('Anti sense strand', true, (v: boolean) => {\n modificationSection[AS].hidden = !v;\n strandColumnInput[AS].root.hidden = !v;\n asLengthDiv.hidden = !v;\n asModificationDiv.hidden = !v;\n asExampleDiv.hidden = !v;\n firstPto[AS].root.hidden = !v;\n updateSvgScheme();\n });\n createAsStrand.setTooltip('Create antisense strand sections on SVG and table to the right');\n\n const saveAs = ui.textInput('Save as', 'Pattern name', () => updateSvgScheme());\n saveAs.setTooltip('Name Of New Pattern');\n\n\n TERMINAL_KEYS.forEach((terminal) => {\n asModificationDiv.append(terminalModification[AS][terminal].root);\n })\n\n const comment = ui.textInput('Comment', '', () => updateSvgScheme());\n\n const savePatternButton = ui.bigButton('Save', () => {\n if (saveAs.value !== '')\n savePattern().then(() => grok.shell.info('Pattern saved'));\n else {\n const name = ui.stringInput('Enter name', '');\n ui.dialog('Pattern Name')\n .add(name.root)\n .onOK(() => {\n saveAs.value = name.value;\n savePattern().then(() => grok.shell.info('Pattern saved'));\n })\n .show();\n }\n });\n saveAs.addOptions(savePatternButton);\n\n const convertSequenceButton = ui.bigButton('Convert', () => {\n const condition = [true, createAsStrand.value];\n console.log(`strand vars:`, Object.values(strandVar));\n if (STRANDS.some((s, i) => condition[i] && strandVar[s] === ''))\n grok.shell.info('Please select table and columns on which to apply pattern');\n else if (STRANDS.some((s) => strandLengthInput[s].value !== inputExample[s].value.length)) {\n const dialog = ui.dialog('Length Mismatch');\n $(dialog.getButton('OK')).hide();\n dialog\n .add(ui.divText('Length of sequences in columns doesn\\'t match entered length. Update length value?'))\n .addButton('YES', () => {\n STRANDS.forEach((s) => {\n strandLengthInput[s].value = tableInput.value!.getCol(strandColumnInput[s].value!).getString(0).length;\n })\n dialog.close();\n })\n .show();\n } else {\n if (idVar !== '')\n addColumnWithIds(tableInput.value!.name, idVar, getShortName(saveAs.value));\n const condition = [true, createAsStrand.value];\n STRANDS.forEach((strand, i) => {\n if (condition[i])\n addColumnWithTranslatedSequences(\n tableInput.value!.name, strandVar[strand], baseInputsObject[strand], ptoLinkages[strand],\n terminalModification[strand][FIVE_PRIME], terminalModification[strand][THREE_PRIME], firstPto[strand].value!);\n })\n grok.shell.v = grok.shell.getTableView(tableInput.value!.name);\n grok.shell.info(((createAsStrand.value) ? 'Columns were' : 'Column was') +\n ' added to table \\'' + tableInput.value!.name + '\\'');\n updateOutputExamples();\n }\n });\n\n asExampleDiv.append(inputExample[AS].root);\n asExampleDiv.append(outputExample[AS].root);\n\n updateUiForNewSequenceLength();\n\n const exampleSection = ui.div([\n ui.h1('Conversion preview'),\n inputExample[SS].root,\n outputExample[SS].root,\n asExampleDiv,\n ], 'ui-form ui-form-wide');\n\n const inputsSection = ui.block50([\n ui.h1('Convert options'),\n tableInput.root,\n strandColumnInput[SS].root,\n strandColumnInput[AS].root,\n inputIdColumn.root,\n ui.buttonsInput([\n convertSequenceButton,\n ]),\n ]);\n inputsSection.classList.add('ui-form');\n\n const downloadButton = ui.link('Download', () => svg.saveSvgAsPng(document.getElementById('mySvg'), saveAs.value,\n {backgroundColor: 'white'}), 'Download pattern as PNG image', '');\n \n const editPattern = ui.link('Edit pattern', ()=>{\n ui.dialog('Edit pattern')\n .add(ui.divV([\n ui.h1('PTO'),\n ui.divH([\n fullyPto.root,\n firstPto[SS].root,\n firstPto[AS].root,\n ], {style:{gap:'12px'}})\n ]))\n .add(ui.divH([\n modificationSection[SS],\n modificationSection[AS],\n ], {style:{gap:'24px'}}))\n .onOK(()=>{grok.shell.info('Saved')})\n .show()\n }, 'Edit pattern', ''); \n\n strandLengthInput[SS].addCaption('Length');\n\n return ui.splitH([\n ui.box(\n ui.div([\n ui.h1('Pattern'),\n createAsStrand.root,\n strandLengthInput[SS],\n strandLengthInput[AS],\n sequenceBase.root,\n comment.root,\n loadPatternDiv,\n saveAs.root,\n ui.h1('Convert'),\n tableInput.root,\n strandColumnInput[SS],\n strandColumnInput[AS],\n inputIdColumn.root,\n ui.buttonsInput([\n convertSequenceButton,\n ]),\n ], 'ui-form')\n , {style:{maxWidth:'450px'}}),\n ui.panel([\n svgDiv,\n isEnumerateModificationsDiv,\n ui.divH([\n downloadButton,\n editPattern\n ], {style:{gap:'12px', marginTop:'12px'}}),\n ui.divH([\n ui.divV([\n ui.h1('Sense strand'),\n inputExample[SS].root,\n outputExample[SS].root,\n ], 'ui-block'),\n ui.divV([\n ui.h1('Anti sense'),\n inputExample[AS],\n outputExample[AS]\n ], 'ui-block'),\n ], {style:{gap:'24px', marginTop:'24px'}}),\n ui.h1('Additional modifications'),\n ui.form([\n terminalModification[SS][FIVE_PRIME],\n terminalModification[SS][THREE_PRIME],\n ]),\n asModificationDiv,\n ], {style: {overflowX: 'scroll', padding:'12px 24px'}})\n ], {}, true)\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport {errorToConsole} from '@datagrok-libraries/utils/src/to-console';\n\nimport $ from 'cash-dom';\n\nimport {extractAtomDataV3000} from '../../model/structure-app/mol-transformations';\n\n/** Draw molecule on the canvas and append it to the specified div, with the\n * option of zoom-in */\nexport async function drawMolecule(\n moleculeImgDiv: HTMLDivElement,\n canvasWidth: number, canvasHeight: number,\n molfile: string\n): Promise<void> {\n // clear div's content if any\n moleculeImgDiv.innerHTML = '';\n\n if (molfile !== '') {\n const canvas = ui.canvas(canvasWidth * window.devicePixelRatio, canvasHeight * window.devicePixelRatio);\n\n // Draw zoomed-out molecule\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n canvas.style.borderStyle = 'solid';\n canvas.style.borderColor = 'var(--grey-3)';\n canvas.style.borderWidth = 'thin';\n drawMolfileOnCanvas(canvas, molfile);\n\n // Dialog with zoomed-in molecule\n $(canvas).on('click', async () => { await drawZoomedInMolecule(molfile); });\n $(canvas).on('mouseover', () => $(canvas).css('cursor', 'grab')); // for some reason 'zoom-in' value wouldn't work\n $(canvas).on('mouseout', () => $(canvas).css('cursor', 'default'));\n\n moleculeImgDiv.append(canvas);\n }\n}\n\n\nexport async function drawZoomedInMolecule(molfile: string): Promise<void> {\n try {\n const dialogDivStyle = {\n overflowX: 'scroll',\n };\n const dialogDiv = ui.div([], {style: dialogDivStyle});\n\n // dialogDiv size required, but now available before dialog show()\n const atomCoordinates = extractAtomDataV3000(molfile);\n // const cw: number = $(window).width() * 0.80; // dialogDiv.clientWidth\n const clientHeight: number = $(window).height() * 0.70; // dialogDiv.clientHeight\n const molWidth: number = Math.max(...atomCoordinates.x) - Math.min(...atomCoordinates.x);\n const molHeight: number = Math.max(...atomCoordinates.y) - Math.min(...atomCoordinates.y);\n\n // const wR: number = cw / molWidth;\n const hR: number = clientHeight / molHeight;\n const r: number = hR; // Math.max(wR, hR);\n const dialogCanvasWidth = r * molWidth;\n const dialogCanvasHeight = r * molHeight;\n\n const dialogCanvas = ui.canvas(\n dialogCanvasWidth * window.devicePixelRatio, dialogCanvasHeight * window.devicePixelRatio\n );\n dialogCanvas.style.width = `${dialogCanvasWidth}px`;\n dialogCanvas.style.height = `${dialogCanvasHeight}px`;\n await drawMolfileOnCanvas(dialogCanvas, molfile);\n\n dialogDiv.appendChild(dialogCanvas);\n ui.dialog('Molecule')\n .add(dialogDiv)\n .showModal(true);\n } catch (err) {\n const errStr = errorToConsole(err);\n console.error(errStr);\n }\n};\n\n\nexport async function drawMolfileOnCanvas(canvas: HTMLCanvasElement, molfile: string): Promise<void> {\n await grok.functions.call('Chem:canvasMol', {\n x: 0, y: 0, w: canvas.width, h: canvas.height, canvas: canvas,\n molString: molfile, scaffoldMolString: '',\n options: {normalizeDepiction: false, straightenDepiction: false}\n });\n};\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {drawZoomedInMolecule} from '../utils/draw-molecule';\nimport {MonomerLibWrapper} from '../../model/monomer-lib/lib-wrapper';\n\nexport class MonomerLibViewer {\n static async view(): Promise<void> {\n const table = MonomerLibWrapper.getInstance().getTableForViewer();\n table.name = 'Monomer Library';\n const view = grok.shell.addTableView(table);\n view.grid.props.allowEdit = false;\n const onDoubleClick = view.grid.onCellDoubleClick;\n onDoubleClick.subscribe(async (gridCell: DG.GridCell) => {\n const molfile = gridCell.cell.value;\n if (gridCell.tableColumn?.semType === 'Molecule')\n await drawZoomedInMolecule(molfile);\n });\n }\n}\n","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {TAB, APP} from './const/ui';\nimport {TranslatorLayoutHandler} from './apps/oligo-translator';\nimport {StructureLayoutHandler} from './apps/oligo-structure';\nimport {PatternLayoutHandler} from './apps/oligo-pattern';\nimport {MonomerLibViewer} from './monomer-lib-viewer/viewer';\nimport {_package} from '../package';\nimport {tryCatch} from '../model/helpers';\n\ntype ViewFactories = {[name: string]: () => DG.View};\n\nexport abstract class AppUIBase {\n constructor(protected appName: string, protected parentAppName?: string) { }\n abstract addView(): Promise<void>;\n\n async createAppLayout(): Promise<void> {\n const pi: DG.TaskBarProgressIndicator = DG.TaskBarProgressIndicator.create(`Loading ${this.appName}...`);\n\n let currentView = grok.shell.v?.root;\n if (currentView)\n ui.setUpdateIndicator(currentView, true);\n\n await tryCatch(async () => {\n await this.addView();\n }, () => pi.close());\n\n if (currentView)\n ui.setUpdateIndicator(currentView, false);\n }\n}\n\nabstract class SimpleAppUIBase extends AppUIBase {\n constructor(appName: string) {\n super(appName);\n this.view = DG.View.create();\n this.setupView();\n }\n\n protected view: DG.View;\n async addView(): Promise<void> {\n await this.initView();\n const name = this.parentAppName ? this.parentAppName + '/' + this.appName : this.appName;\n this.view.path = `/apps/${_package.name}/${name.replace(/\\s/g, '')}/`;\n grok.shell.addView(this.view);\n }\n\n protected abstract getHtml(): Promise<HTMLDivElement>;\n async initView(): Promise<void> {\n const html = await this.getHtml();\n this.view.append(html);\n }\n\n protected setupView(): void {\n this.view.box = true;\n this.view.name = this.appName;\n\n const windows = grok.shell.windows;\n windows.showProperties = false;\n windows.showToolbox = false;\n windows.showHelp = false;\n }\n\n getView(): DG.View {\n return this.view;\n }\n}\n\nexport class CombinedAppUI extends AppUIBase {\n constructor(externalViewFactories: ViewFactories) {\n super(APP.COMBINED)\n this.externalViewFactories = externalViewFactories;\n const factories = this.getViewFactories();\n this.multiView = new DG.MultiView({viewFactories: factories}); \n }\n\n private multiView: DG.MultiView;\n private externalViewFactories?: ViewFactories;\n\n private getViewFactories(): ViewFactories {\n function viewFactory(uiConstructor: new (view: DG.View) => SimpleAppUIBase): () => DG.View {\n const view = DG.View.create();\n const translateUI = new uiConstructor(view);\n // intentonally don't await for the promise\n translateUI.initView();\n return () => translateUI.getView();\n }\n\n let result: {[key: string]: () => DG.View } = {\n [TAB.TRANSLATOR]: viewFactory(OligoTranslatorUI),\n [TAB.PATTERN]: viewFactory(OligoPatternUI),\n [TAB.STRUCTRE]: viewFactory(OligoStructureUI),\n }\n\n if (this.externalViewFactories)\n result = Object.assign({}, result, this.externalViewFactories);\n\n return result\n }\n\n private getPath(): string {\n let name = this.multiView.tabs.currentPane.name;\n name = name.charAt(0).toUpperCase() + name.substring(1).toLowerCase();\n const path = `/apps/${_package.name}/OligoToolkit/${name}`;\n return path;\n }\n\n private setUrl(): void {\n this.multiView.path = this.getPath();\n }\n\n async addView(): Promise<void> {\n this.multiView.tabs.onTabChanged.subscribe(() => this.setUrl());\n this.setUrl();\n grok.shell.addView(this.multiView);\n }\n}\n\n/** For plugins from external packages */\nexport class ExternalPluginUI extends SimpleAppUIBase {\n constructor(viewName: string, layout: HTMLDivElement) {\n super(viewName);\n this.layout = layout;\n }\n private layout: HTMLDivElement;\n\n protected getHtml(): Promise<HTMLDivElement> {\n return Promise.resolve(this.layout);\n }\n}\n\nexport class AppUIFactory {\n private constructor() {}\n\n static getUI(appName: string): SimpleAppUIBase {\n switch (appName) {\n case APP.TRANSLATOR:\n return new OligoTranslatorUI();\n case APP.PATTERN:\n return new OligoPatternUI();\n case APP.STRUCTRE:\n return new OligoStructureUI();\n default:\n throw new Error(`Unknown app name: ${appName}`);\n }\n }\n}\n\nclass OligoTranslatorUI extends SimpleAppUIBase {\n constructor() {\n super(APP.TRANSLATOR);\n\n const viewMonomerLibIcon = ui.iconFA('book', MonomerLibViewer.view, 'View monomer library');\n this.topPanel = [\n viewMonomerLibIcon,\n ];\n this.view.setRibbonPanels([this.topPanel]);\n this.ui = new TranslatorLayoutHandler();\n }\n\n private readonly topPanel: HTMLElement[];\n private readonly ui: TranslatorLayoutHandler;\n\n protected getHtml(): Promise<HTMLDivElement> {\n return this.ui.getHtmlElement();\n };\n}\n\nclass OligoPatternUI extends SimpleAppUIBase {\n constructor() {\n super(APP.PATTERN);\n this.ui = new PatternLayoutHandler();\n }\n private readonly ui: PatternLayoutHandler;\n protected getHtml(): Promise<HTMLDivElement> {\n return Promise.resolve(this.ui.htmlDivElement);\n }\n}\n\nclass OligoStructureUI extends SimpleAppUIBase {\n constructor() {\n super(APP.STRUCTRE)\n this.ui = new StructureLayoutHandler();\n }\n private readonly ui: StructureLayoutHandler;\n\n protected getHtml(): Promise<HTMLDivElement> {\n return this.ui.getHtmlDivElement();\n }\n}\n","import { CandidateType } from './types';\n/** enum type to simplify setting \"user-friendly\" notation if necessary */\nexport var NOTATION;\n(function (NOTATION) {\n NOTATION[\"FASTA\"] = \"fasta\";\n NOTATION[\"SEPARATOR\"] = \"separator\";\n NOTATION[\"HELM\"] = \"helm\";\n})(NOTATION || (NOTATION = {}));\nexport const positionSeparator = ', ';\nexport const monomerRe = /(?:\\[([A-Za-z0-9_\\-,()]+)\\])|([A-Za-z\\-])/g;\nexport const Alphabets = new class {\n constructor() {\n this.fasta = {\n peptide: new Set([\n 'G', 'L', 'Y', 'S', 'E', 'Q', 'D', 'N', 'F', 'A',\n 'K', 'R', 'H', 'C', 'V', 'P', 'W', 'I', 'M', 'T',\n ]),\n dna: new Set(['A', 'C', 'G', 'T']),\n rna: new Set(['A', 'C', 'G', 'U']),\n };\n }\n}();\nexport const candidateAlphabets = [\n new CandidateType(\"PT\" /* ALPHABET.PT */, Alphabets.fasta.peptide, 0.50),\n new CandidateType(\"DNA\" /* ALPHABET.DNA */, Alphabets.fasta.dna, 0.55),\n new CandidateType(\"RNA\" /* ALPHABET.RNA */, Alphabets.fasta.rna, 0.55),\n];\n//# sourceMappingURL=consts.js.map","const __WEBPACK_NAMESPACE_OBJECT__ = wu;","/** Alphabet candidate type */\nexport class CandidateType {\n constructor(name, alphabet, cutoff) {\n this.name = name;\n this.alphabet = alphabet;\n this.cutoff = cutoff;\n }\n}\n/** Alphabet candidate similarity type */\nexport class CandidateSimType extends CandidateType {\n constructor(candidate, freq, similarity) {\n super(candidate.name, candidate.alphabet, candidate.cutoff);\n this.freq = freq;\n this.similarity = similarity;\n }\n}\n//# sourceMappingURL=types.js.map","/**\n * Denotes a vector of floating poit values.\n *\n * @export\n * @class Vector\n * @extends {Float32Array}\n */\nexport class Vector extends Float32Array {\n}\n/**\n * Denotes a two-dimensional matrix.\n *\n * @export\n * @class Matrix\n * @extends {Array<Vector>}\n */\nexport class Matrix extends Array {\n}\n/**\n * Denotes cartesian coordinates.\n *\n * @export\n * @class Coordinates\n * @extends {Matrix}\n */\nexport class Coordinates extends Matrix {\n}\n/**\n * Denotes an array of arbitrary-typed vectors.\n *\n * @export\n * @class Vectors\n * @extends {Array<any>}\n */\nexport class Vectors extends Array {\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcbiJdfQ==","export class SeqPaletteBase {\n static makePalette(dt, simplified = false, PaletteType = SeqPaletteBase) {\n const palette = {};\n dt.forEach((cp) => {\n const objList = cp[0];\n const colour = cp[1];\n objList.forEach((obj, ind) => {\n palette[obj] = this.colourPalette[colour][simplified ? 0 : ind];\n });\n });\n return new PaletteType(palette);\n }\n constructor(palette) {\n this._palette = palette;\n }\n get(m) {\n return this._palette[m];\n }\n}\nSeqPaletteBase.undefinedColor = 'rgb(100,100,100)';\n/** Palette with shades of primary colors */\nSeqPaletteBase.colourPalette = {\n 'orange': ['rgb(255,187,120)', 'rgb(245,167,100)', 'rgb(235,137,70)', 'rgb(205, 111, 71)'],\n 'all_green': ['rgb(44,160,44)', 'rgb(74,160,74)', 'rgb(23,103,57)', 'rgb(30,110,96)', 'rgb(60,131,95)',\n 'rgb(24,110,79)', 'rgb(152,223,138)', 'rgb(182, 223, 138)', 'rgb(152, 193, 138)'],\n 'all_blue': ['rgb(31,119,180)', 'rgb(23,190,207)', 'rgb(122, 102, 189)', 'rgb(158,218,229)', 'rgb(141, 124, 217)',\n 'rgb(31, 120, 150)'],\n 'magenta': ['rgb(162,106,192)', 'rgb(197,165,224)', 'rgb(208,113,218)'],\n 'red': ['rgb(214,39,40)', 'rgb(255,152,150)'],\n 'st_blue': ['rgb(23,190,207)', 'rgb(158,218,229)', 'rgb(31,119,180)'],\n 'dark_blue': ['rgb(31,119,180)', 'rgb(31, 120, 150)'],\n 'light_blue': ['rgb(23,190,207)', 'rgb(158,218,229)', 'rgb(108, 218, 229)', 'rgb(23,190,227)'],\n 'lilac_blue': ['rgb(124,102,211)', 'rgb(149,134,217)', 'rgb(97, 81, 150)'],\n 'dark_green': ['rgb(23,103,57)', 'rgb(30,110,96)', 'rgb(60,131,95)', 'rgb(24,110,79)'],\n 'green': ['rgb(44,160,44)', 'rgb(74,160,74)'],\n 'light_green': ['rgb(152,223,138)', 'rgb(182, 223, 138)', 'rgb(152, 193, 138)'],\n 'st_green': ['rgb(44,160,44)', 'rgb(152,223,138)', 'rgb(39, 174, 96)', 'rgb(74,160,74)'],\n 'pink': ['rgb(247,182,210)'],\n 'brown': ['rgb(140,86,75)', 'rgb(102, 62, 54)'],\n 'gray': ['rgb(127,127,127)', 'rgb(199,199,199)', 'rgb(196,156,148)', 'rgb(222, 222, 180)'],\n 'yellow': ['rgb(188,189,34)'],\n 'white': ['rgb(230,230,230)'],\n};\n//# sourceMappingURL=seq-palettes.js.map","import { SeqPaletteBase } from './seq-palettes';\nexport class AminoacidsPalettes extends SeqPaletteBase {\n static get Lesk() {\n if (this.lesk === void 0) {\n this.lesk = this.makePalette([\n [['G', 'A', 'S', 'T'], 'orange'],\n [['C', 'V', 'I', 'L', 'P', 'F', 'Y', 'M', 'W'], 'all_green'],\n [['N', 'Q', 'H'], 'magenta'],\n [['D', 'E'], 'red'],\n [['K', 'R'], 'all_blue'],\n ], false, AminoacidsPalettes);\n }\n return this.lesk;\n }\n static get GrokGroups() {\n if (this.grokGroups === void 0) {\n this.grokGroups = this.makePalette([\n [['C', 'U'], 'yellow'],\n [['G', 'P'], 'red'],\n [['A', 'V', 'I', 'L', 'M', 'F', 'Y', 'W'], 'all_green'],\n [['R', 'H', 'K'], 'light_blue'],\n [['D', 'E'], 'dark_blue'],\n [['S', 'T', 'N', 'Q'], 'orange'],\n ], false, AminoacidsPalettes);\n }\n return this.grokGroups;\n }\n static get RasMol() {\n if (this.rasMol === void 0) {\n this.rasMol = new AminoacidsPalettes({\n // http://acces.ens-lyon.fr/biotic/rastop/help/colour.htm\n 'D': '#E60A0A',\n 'E': '#E60A0A',\n 'C': '#E6E600',\n 'M': '#E6E600',\n 'K': '#145AFF',\n 'R': '#145AFF',\n 'S': '#FA9600',\n 'T': '#FA9600',\n 'F': '#3232AA',\n 'Y': '#3232AA',\n 'N': '#00DCDC',\n 'Q': '#00DCDC',\n 'G': '#EBEBEB',\n 'L': '#0F820F',\n 'V': '#0F820F',\n 'I': '#0F820F',\n 'A': '#C8C8C8',\n 'W': '#B45AB4',\n 'H': '#8282D2',\n 'P': '#DC9682',\n 'others': '#BEA06E',\n });\n }\n return this.rasMol;\n }\n get(m) {\n const resM = m in AminoacidsPalettes.aaSynonyms ? AminoacidsPalettes.aaSynonyms[m] : m;\n const res = super.get(resM);\n return res;\n }\n}\n/** Only some of the synonyms. These were obtained from the clustered oligopeptide dataset. */\nAminoacidsPalettes.aaSynonyms = {\n 'MeNle': 'L',\n 'MeA': 'A',\n 'MeG': 'G',\n 'MeF': 'F',\n};\nexport class Aminoacids {\n static getPalette(scheme = 'grok') {\n switch (scheme) {\n case 'grok':\n return AminoacidsPalettes.GrokGroups;\n case 'lesk':\n return AminoacidsPalettes.Lesk;\n default:\n throw new Error(`ChemPalette: scheme \\`${scheme}\\` does not exist`);\n }\n }\n /**\n * Returns divided amino acid with its content in the bracket, if the content is number, then its omitted\n *\n * @param {string} c raw amino\n * @return {[string, string]} outer and inner content\n */\n static getInnerOuter(c) {\n let isInner = 0;\n let inner = '';\n let outer = '';\n for (const char of c) {\n if (char == '(')\n isInner++;\n else if (char == ')')\n isInner--;\n else if (isInner)\n inner += char;\n else\n outer += char;\n }\n return !isNaN(parseInt(inner)) ? [outer, ''] : [outer, inner];\n }\n static getColorAAPivot(monomer = '', scheme = 'grok') {\n //const chemPaletteInstance = AAPalettes.GrokGroups();\n const chemPaletteInstance = this.getPalette(scheme);\n let [outerMonomer, innerMonomer] = this.getInnerOuter(monomer);\n outerMonomer = (outerMonomer.length > 6 ? `${outerMonomer.slice(0, 3)}...` : outerMonomer);\n innerMonomer = (innerMonomer.length > 6 ? `${innerMonomer.slice(0, 3)}...` : innerMonomer);\n if (monomer.length == 1 || monomer[1] == '(') {\n const amino = monomer[0]?.toUpperCase();\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 1] :\n [this.undefinedColor, outerMonomer, innerMonomer, 1];\n }\n if (monomer[0] == 'd' && monomer[1] in chemPaletteInstance) {\n if (monomer.length == 2 || monomer[2] == '(') {\n const amino = monomer[1]?.toUpperCase();\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 2] :\n [this.undefinedColor, outerMonomer, innerMonomer, 2];\n }\n }\n if (monomer.substring(0, 3) in this.AAFullNames) {\n if (monomer.length == 3 || monomer[3] == '(') {\n const amino = this.AAFullNames[monomer.substring(0, 3)];\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 3] :\n [this.undefinedColor, outerMonomer, innerMonomer, 3];\n }\n }\n if (monomer[0]?.toLowerCase() == monomer[0]) {\n if (monomer.substring(1, 3) in this.AAFullNames) {\n if (monomer.length == 4 || monomer[4] == '(') {\n const amino = this.AAFullNames[monomer.substring(1, 3)];\n return amino in chemPaletteInstance ?\n [chemPaletteInstance.get(amino), amino, innerMonomer, 4] :\n [this.undefinedColor, outerMonomer, innerMonomer, 4];\n }\n }\n }\n return [this.undefinedColor, outerMonomer, innerMonomer, 0];\n }\n}\nAminoacids.SemType = 'Aminoacids';\nAminoacids.SemTypeMultipleAlignment = 'AminoacidsMultipleAlignment';\nAminoacids.undefinedColor = 'rgb(100,100,100)';\nAminoacids.Names = {\n 'G': 'Glycine',\n 'L': 'Leucine',\n 'Y': 'Tyrosine',\n 'S': 'Serine',\n 'E': 'Glutamic acid',\n 'Q': 'Glutamine',\n 'D': 'Aspartic acid',\n 'N': 'Asparagine',\n 'F': 'Phenylalanine',\n 'A': 'Alanine',\n 'K': 'Lysine',\n 'R': 'Arginine',\n 'H': 'Histidine',\n 'C': 'Cysteine',\n 'V': 'Valine',\n 'P': 'Proline',\n 'W': 'Tryptophan',\n 'I': 'Isoleucine',\n 'M': 'Methionine',\n 'T': 'Threonine',\n};\nAminoacids.AASmiles = {\n 'G': 'NCC(=O)O',\n 'L': 'N[C@H](CC(C)C)C(=O)O',\n 'Y': 'NC(CC1=CC=C(O)C=C1)C(=O)O',\n 'S': 'NC(CO)C(=O)O',\n 'E': 'N[C@@H](CCC(O)=O)C(=O)O',\n 'Q': 'N[C@@H](CCC(N)=O)C(=O)O',\n 'D': 'N[C@@H](CC(O)=O)C(=O)O',\n 'N': 'N[C@@H](CC(N)=O)C(=O)O',\n 'F': 'NC(CC1=CC=CC=C1)C(=O)O',\n 'A': 'N[C@H](C)C(=O)O',\n 'K': 'NC(CCCCN)C(=O)O',\n 'R': 'N[C@H](CCCNC(=N)C)C(=O)O',\n 'H': 'NC(CC1=CN=C[N]1)C(=O)O',\n 'C': 'N[C@@H](CS)C(=O)O',\n 'V': 'NC(C(C)C)C(=O)O',\n 'P': 'N(CCC1)C1C(=O)O',\n 'W': 'N[C@@H](Cc1c2ccccc2n([H])c1)C(=O)O',\n 'I': 'N[C@H]([C@H](C)CC)C(=O)O',\n 'M': 'NC(CCSC)C(=O)O',\n 'T': 'NC(C(O)C)C(=O)O',\n};\nAminoacids.AASmilesTruncated = {\n 'G': '*C*',\n 'L': 'CC(C)C[C@H](*)*',\n 'Y': 'C1=CC(=CC=C1CC(*)*)O',\n 'S': 'OCC(*)C*',\n 'E': '*[C@@H](CCC(O)=O)*',\n 'Q': '*N[C@@H](CCC(N)=O)*',\n 'D': '*[C@@H](CC(O)=O)*',\n 'N': '*[C@@H](CC(N)=O)*',\n 'F': 'C1=CC=C(C=C1)CC(*)*',\n 'A': 'C[C@H](*)*',\n 'K': 'C(CCN)CC(*)*',\n 'R': '*[C@H](CCCNC(=N)C)*',\n 'H': 'C1=C(NC=N1)CC(*)*',\n 'C': 'C([C@@H](*)*)S',\n 'V': 'CC(C)C(*)*',\n 'P': 'C1CCN(*)C1*',\n 'W': '*[C@@H](Cc1c2ccccc2n([H])c1)*',\n 'I': 'CC[C@H](C)[C@H](*)*',\n 'M': 'CSCCC(*)*',\n 'T': 'CC(O)C(*)*',\n};\n/** TODO: Full?\n */\nAminoacids.AAFullNames = {\n 'Ala': 'A',\n 'Arg': 'R',\n 'Asn': 'N',\n 'Asp': 'D',\n 'Cys': 'C',\n 'Gln': 'Q',\n 'Glu': 'E',\n 'Gly': 'G',\n 'His': 'H',\n 'Ile': 'I',\n 'Leu': 'L',\n 'Lys': 'K',\n 'Met': 'M',\n 'Phe': 'F',\n 'Pro': 'P',\n 'Ser': 'S',\n 'Thr': 'T',\n 'Trp': 'W',\n 'Tyr': 'Y',\n 'Val': 'V',\n};\n//# sourceMappingURL=aminoacids.js.map","import { SeqPaletteBase } from './seq-palettes';\nexport class NucleotidesPalettes extends SeqPaletteBase {\n static get Chromatogram() {\n if (this.chromatogram === void 0) {\n this.chromatogram = new NucleotidesPalettes({\n 'A': 'green',\n 'C': 'blue',\n 'G': 'black',\n 'T': 'red',\n 'U': 'red',\n 'others': 'gray',\n });\n }\n return this.chromatogram;\n }\n}\nexport class Nucleotides {\n}\nNucleotides.SemType = 'Nucleotides';\nNucleotides.SemTypeMultipleAlignment = 'NucleotidesMultipleAlignment';\nNucleotides.Names = {\n 'A': 'Adenine',\n 'C': 'Cytosine',\n 'G': 'Guanine',\n 'T': 'Thymine',\n 'U': 'Uracil',\n};\n//# sourceMappingURL=nucleotides.js.map","import * as DG from 'datagrok-api/dg';\n/** makes the color less white, makes the transparency effect always perceptible\n * @param {string} color x coordinate.\n * */\nfunction correctColor(color) {\n if (color == null)\n return 'rgb(100,100,100)';\n const dgColor = DG.Color.fromHtml(color);\n const g = DG.Color.g(dgColor);\n const r = DG.Color.r(dgColor);\n const b = DG.Color.b(dgColor);\n // calculate euclidean distance to white\n const distToBlack = Math.sqrt(Math.pow(0 - r, 2) + Math.pow(0 - g, 2) + Math.pow(0 - b, 2));\n // normalize vector r g b\n const normR = r / distToBlack;\n const normG = g / distToBlack;\n const normB = b / distToBlack;\n if (distToBlack > 210) {\n return `rgb(${normR * 210},${normG * 210},${normB * 210})`;\n }\n return DG.Color.toRgb(dgColor);\n}\nexport class StringUtils {\n static hashCode(s) {\n let hash = 0;\n if (s.length === 0)\n return hash;\n for (let i = 0; i < s.length; i++) {\n const chr = s.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n }\n}\nimport { SeqPaletteBase } from './seq-palettes';\nexport class UnknownSeqPalette {\n}\nexport class GrayAllPalette extends UnknownSeqPalette {\n get(m) {\n return '#666666';\n }\n}\nexport class UnknownColorPalette extends UnknownSeqPalette {\n static buildPalette() {\n const res = [].concat(...Object.values(SeqPaletteBase.colourPalette));\n return res;\n }\n get(m) {\n const hash = StringUtils.hashCode(m);\n const pI = hash % UnknownColorPalette.palette.length;\n return correctColor(UnknownColorPalette.palette[pI]);\n }\n}\nUnknownColorPalette.palette = UnknownColorPalette.buildPalette();\nexport class UnknownSeqPalettes extends SeqPaletteBase {\n static get Gray() {\n if (this.gray === void 0)\n this.gray = new GrayAllPalette();\n return this.gray;\n }\n static get Color() {\n if (this.color === void 0)\n this.color = new UnknownColorPalette();\n return this.color;\n }\n}\n//# sourceMappingURL=unknown.js.map","const peq = new Uint32Array(0x10000);\nconst myers_32 = (a, b) => {\n const n = a.length;\n const m = b.length;\n const lst = 1 << (n - 1);\n let pv = -1;\n let mv = 0;\n let sc = n;\n let i = n;\n while (i--) {\n peq[a.charCodeAt(i)] |= 1 << i;\n }\n for (i = 0; i < m; i++) {\n let eq = peq[b.charCodeAt(i)];\n const xv = eq | mv;\n eq |= ((eq & pv) + pv) ^ pv;\n mv |= ~(eq | pv);\n pv &= eq;\n if (mv & lst) {\n sc++;\n }\n if (pv & lst) {\n sc--;\n }\n mv = (mv << 1) | 1;\n pv = (pv << 1) | ~(xv | mv);\n mv &= xv;\n }\n i = n;\n while (i--) {\n peq[a.charCodeAt(i)] = 0;\n }\n return sc;\n};\nconst myers_x = (b, a) => {\n const n = a.length;\n const m = b.length;\n const mhc = [];\n const phc = [];\n const hsize = Math.ceil(n / 32);\n const vsize = Math.ceil(m / 32);\n for (let i = 0; i < hsize; i++) {\n phc[i] = -1;\n mhc[i] = 0;\n }\n let j = 0;\n for (; j < vsize - 1; j++) {\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n }\n let mv = 0;\n let pv = -1;\n const start = j * 32;\n const vlen = Math.min(32, m - start) + start;\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] |= 1 << k;\n }\n let score = m;\n for (let i = 0; i < n; i++) {\n const eq = peq[a.charCodeAt(i)];\n const pb = (phc[(i / 32) | 0] >>> i) & 1;\n const mb = (mhc[(i / 32) | 0] >>> i) & 1;\n const xv = eq | mv;\n const xh = ((((eq | mb) & pv) + pv) ^ pv) | eq | mb;\n let ph = mv | ~(xh | pv);\n let mh = pv & xh;\n score += (ph >>> (m - 1)) & 1;\n score -= (mh >>> (m - 1)) & 1;\n if ((ph >>> 31) ^ pb) {\n phc[(i / 32) | 0] ^= 1 << i;\n }\n if ((mh >>> 31) ^ mb) {\n mhc[(i / 32) | 0] ^= 1 << i;\n }\n ph = (ph << 1) | pb;\n mh = (mh << 1) | mb;\n pv = mh | ~(xv | ph);\n mv = ph & xv;\n }\n for (let k = start; k < vlen; k++) {\n peq[b.charCodeAt(k)] = 0;\n }\n return score;\n};\nconst distance = (a, b) => {\n if (a.length < b.length) {\n const tmp = b;\n b = a;\n a = tmp;\n }\n if (b.length === 0) {\n return a.length;\n }\n if (a.length <= 32) {\n return myers_32(a, b);\n }\n return myers_x(a, b);\n};\nconst closest = (str, arr) => {\n let min_distance = Infinity;\n let min_index = 0;\n for (let i = 0; i < arr.length; i++) {\n const dist = distance(str, arr[i]);\n if (dist < min_distance) {\n min_distance = dist;\n min_index = i;\n }\n }\n return arr[min_index];\n};\nexport { closest, distance };\n","import { hamming } from './hamming';\nimport { levenstein } from './levenstein';\nimport { needlemanWunch } from './needleman-wunsch';\n/** Enum containing currently supported macromolecule distance functions\n * Hamming distance will be used if the sequences are already aligned\n * Needleman distance will be used for protein sequences with known BLOSUM62 matrix\n * Levenshtein distance will be used for nucleotide sequences as for them substitution matrix is same as identity matrix\n */\nexport var MmDistanceFunctionsNames;\n(function (MmDistanceFunctionsNames) {\n MmDistanceFunctionsNames[\"HAMMING\"] = \"Hamming\";\n MmDistanceFunctionsNames[\"LEVENSHTEIN\"] = \"Levenshtein\";\n MmDistanceFunctionsNames[\"NEEDLEMANN_WUNSCH\"] = \"Needlemann-Wunsch\";\n})(MmDistanceFunctionsNames || (MmDistanceFunctionsNames = {}));\n;\nexport const mmDistanceFunctions = {\n [MmDistanceFunctionsNames.HAMMING]: hamming,\n [MmDistanceFunctionsNames.LEVENSHTEIN]: levenstein,\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: needlemanWunch\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBR2xEOzs7O0dBSUc7QUFDSCxNQUFNLENBQU4sSUFBWSx3QkFJWDtBQUpELFdBQVksd0JBQXdCO0lBQ2hDLCtDQUFtQixDQUFBO0lBQ25CLHVEQUEyQixDQUFBO0lBQzNCLG1FQUF1QyxDQUFBO0FBQzNDLENBQUMsRUFKVyx3QkFBd0IsS0FBeEIsd0JBQXdCLFFBSW5DO0FBQUEsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUE4RTtJQUM1RyxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU87SUFDM0MsQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxVQUFVO0lBQ2xELENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsRUFBRSxjQUFjO0NBQzdELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhbW1pbmd9IGZyb20gJy4vaGFtbWluZyc7XG5pbXBvcnQge2xldmVuc3RlaW59IGZyb20gJy4vbGV2ZW5zdGVpbic7XG5pbXBvcnQge25lZWRsZW1hbld1bmNofSBmcm9tICcuL25lZWRsZW1hbi13dW5zY2gnO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuLyoqIEVudW0gY29udGFpbmluZyBjdXJyZW50bHkgc3VwcG9ydGVkIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2UgZnVuY3Rpb25zXG4gKiBIYW1taW5nIGRpc3RhbmNlIHdpbGwgYmUgdXNlZCBpZiB0aGUgc2VxdWVuY2VzIGFyZSBhbHJlYWR5IGFsaWduZWRcbiAqIE5lZWRsZW1hbiBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgZm9yIHByb3RlaW4gc2VxdWVuY2VzIHdpdGgga25vd24gQkxPU1VNNjIgbWF0cml4XG4gKiBMZXZlbnNodGVpbiBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgZm9yIG51Y2xlb3RpZGUgc2VxdWVuY2VzIGFzIGZvciB0aGVtIHN1YnN0aXR1dGlvbiBtYXRyaXggaXMgc2FtZSBhcyBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGVudW0gTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzIHtcbiAgICBIQU1NSU5HID0gJ0hhbW1pbmcnLFxuICAgIExFVkVOU0hURUlOID0gJ0xldmVuc2h0ZWluJyxcbiAgICBORUVETEVNQU5OX1dVTlNDSCA9ICdOZWVkbGVtYW5uLVd1bnNjaCdcbn07XG5cbmV4cG9ydCBjb25zdCBtbURpc3RhbmNlRnVuY3Rpb25zOiBSZWNvcmQ8TW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLCAodmFsdWU/OiBhbnkpID0+IG1tRGlzdGFuY2VGdW5jdGlvblR5cGU+ID0ge1xuICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkhBTU1JTkddOiBoYW1taW5nLFxuICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLkxFVkVOU0hURUlOXTogbGV2ZW5zdGVpbixcbiAgW01tRGlzdGFuY2VGdW5jdGlvbnNOYW1lcy5ORUVETEVNQU5OX1dVTlNDSF06IG5lZWRsZW1hbld1bmNoXG59O1xuIl19","import * as DG from 'datagrok-api/dg';\nimport wu from 'wu';\nimport { NOTATION, candidateAlphabets, positionSeparator } from './macromolecule';\nimport { detectAlphabet, getSplitterForColumn, getSplitterWithSeparator, splitterAsFasta, splitterAsFastaSimple, splitterAsHelm } from './macromolecule/utils';\nimport { mmDistanceFunctions, MmDistanceFunctionsNames } from '@datagrok-libraries/ml/src/macromolecule-distance-functions';\nimport { getMonomerLibHelper } from '../monomer-works/monomer-utils';\nexport const Tags = new class {\n constructor() {\n /** Column's temp slot name for a UnitsHandler object */\n this.uhTemp = `units-handler.${DG.SEMTYPE.MACROMOLECULE}`;\n }\n}();\nexport const GapSymbols = {\n [NOTATION.FASTA]: '-',\n [NOTATION.SEPARATOR]: '',\n [NOTATION.HELM]: '*',\n};\n/** Class for handling notation units in Macromolecule columns and\n * conversion of notation systems in Macromolecule columns\n */\nexport class UnitsHandler {\n static setUnitsToFastaColumn(uh) {\n if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.getTag(DG.TAGS.UNITS) !== NOTATION.FASTA)\n throw new Error(`The column of notation '${NOTATION.FASTA}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);\n uh.column.setTag(DG.TAGS.UNITS, NOTATION.FASTA);\n UnitsHandler.setTags(uh);\n }\n static setUnitsToSeparatorColumn(uh, separator) {\n if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE || uh.column.getTag(DG.TAGS.UNITS) !== NOTATION.SEPARATOR)\n throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must be '${DG.SEMTYPE.MACROMOLECULE}'.`);\n if (!separator)\n throw new Error(`The column of notation '${NOTATION.SEPARATOR}' must have the separator tag.`);\n uh.column.setTag(DG.TAGS.UNITS, NOTATION.SEPARATOR);\n uh.column.setTag(\"separator\" /* TAGS.separator */, separator);\n UnitsHandler.setTags(uh);\n }\n static setUnitsToHelmColumn(uh) {\n if (uh.column.semType !== DG.SEMTYPE.MACROMOLECULE)\n throw new Error(`The column of notation '${NOTATION.HELM}' must be '${DG.SEMTYPE.MACROMOLECULE}'`);\n uh.column.setTag(DG.TAGS.UNITS, NOTATION.HELM);\n UnitsHandler.setTags(uh);\n }\n /** From detectMacromolecule */\n static setTags(uh) {\n const units = uh.column.getTag(DG.TAGS.UNITS);\n const stats = uh.stats;\n const alphabetIsMultichar = Object.keys(stats.freq).some((m) => m.length > 1);\n if ([NOTATION.FASTA, NOTATION.SEPARATOR].includes(units)) {\n // Empty monomer alphabet is not allowed\n if (Object.keys(stats.freq).length === 0)\n throw new Error('Alphabet is empty');\n const aligned = stats.sameLength ? \"SEQ.MSA\" /* ALIGNMENT.SEQ_MSA */ : \"SEQ\" /* ALIGNMENT.SEQ */;\n uh.column.setTag(\"aligned\" /* TAGS.aligned */, aligned);\n const alphabet = detectAlphabet(stats.freq, candidateAlphabets);\n uh.column.setTag(\"alphabet\" /* TAGS.alphabet */, alphabet);\n if (alphabet === \"UN\" /* ALPHABET.UN */) {\n const alphabetSize = Object.keys(stats.freq).length;\n const alphabetIsMultichar = Object.keys(stats.freq).some((m) => m.length > 1);\n uh.column.setTag(\".alphabetSize\" /* TAGS.alphabetSize */, alphabetSize.toString());\n uh.column.setTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */, alphabetIsMultichar ? 'true' : 'false');\n }\n }\n }\n get column() { return this._column; }\n get units() { return this._units; }\n get notation() { return this._notation; }\n get defaultGapSymbol() { return this._defaultGapSymbol; }\n get separator() {\n const separator = this.column.getTag(\"separator\" /* TAGS.separator */) ?? undefined;\n if (this.notation === NOTATION.SEPARATOR && separator === undefined)\n throw new Error(`Separator is mandatory for column '${this.column.name}' of notation '${this.notation}'.`);\n return separator;\n }\n get aligned() {\n const aligned = this.column.getTag(\"aligned\" /* TAGS.aligned */);\n // TAGS.aligned is mandatory for columns of NOTATION.FASTA and NOTATION.SEPARATOR\n if (!aligned && (this.isFasta() || this.isSeparator()))\n throw new Error('Tag aligned not set');\n return aligned;\n }\n /** Alphabet name (upper case) */\n get alphabet() {\n const alphabet = this.column.getTag(\"alphabet\" /* TAGS.alphabet */);\n // TAGS.alphabet is mandatory for columns of NOTATION.FASTA and NOTATION.SEPARATOR\n if (!alphabet && (this.isFasta() || this.isSeparator()))\n throw new Error('Tag alphabet not set');\n return alphabet;\n }\n get helmCompatible() {\n return this.column.getTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */);\n }\n getAlphabetSize() {\n if (this.notation == NOTATION.HELM || this.alphabet == \"UN\" /* ALPHABET.UN */) {\n const alphabetSizeStr = this.column.getTag(\".alphabetSize\" /* TAGS.alphabetSize */);\n let alphabetSize;\n if (alphabetSizeStr)\n alphabetSize = parseInt(alphabetSizeStr);\n else {\n // calculate alphabetSize on demand\n const stats = this.stats;\n alphabetSize = Object.keys(stats.freq).length;\n }\n return alphabetSize;\n }\n else {\n switch (this.alphabet) {\n case \"PT\" /* ALPHABET.PT */:\n return 20;\n case \"DNA\" /* ALPHABET.DNA */:\n case \"RNA\" /* ALPHABET.RNA */:\n return 4;\n case 'NT':\n console.warn(`Unexpected alphabet 'NT'.`);\n return 4;\n default:\n throw new Error(`Unexpected alphabet '${this.alphabet}'.`);\n }\n }\n }\n getAlphabetIsMultichar() {\n if (this.notation === NOTATION.HELM)\n return true;\n else if (this.alphabet !== \"UN\" /* ALPHABET.UN */)\n return false;\n else\n return this.column.getTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */) === 'true';\n }\n /** */\n get splitted() {\n if (this._splitted === null) {\n const splitter = this.getSplitter();\n const colLength = this._column.length;\n this._splitted = new Array(colLength);\n const catIdxList = this._column.getRawData();\n const catList = this._column.categories;\n for (let rowI = 0; rowI < colLength; rowI++) {\n const seq = catList[catIdxList[rowI]];\n this._splitted[rowI] = splitter(seq);\n }\n }\n return this._splitted;\n }\n get stats() {\n if (this._stats === null) {\n const freq = {};\n let sameLength = true;\n let firstLength = null;\n for (const mSeq of this.splitted) {\n if (firstLength == null)\n firstLength = mSeq.length;\n else if (mSeq.length !== firstLength)\n sameLength = false;\n for (const m of mSeq) {\n if (!(m in freq))\n freq[m] = 0;\n freq[m] += 1;\n }\n }\n this._stats = { freq: freq, sameLength: sameLength };\n }\n return this._stats;\n }\n get maxLength() {\n if (this._maxLength === null)\n this._maxLength = Math.max(...this.splitted.map((seqS) => seqS.length));\n return this._maxLength;\n }\n get posList() {\n if (this._posList === null) {\n const posListTxt = this.column.getTag(\".positionNames\" /* TAGS.positionNames */);\n this._posList = posListTxt ? posListTxt.split(positionSeparator).map((p) => p.trim()) :\n wu.count(1).take(this.maxLength).map((pos) => pos.toString()).toArray();\n }\n return this._posList;\n }\n isFasta() { return this.notation === NOTATION.FASTA; }\n isSeparator() { return this.notation === NOTATION.SEPARATOR; }\n isHelm() { return this.notation === NOTATION.HELM; }\n isRna() { return this.alphabet === \"RNA\" /* ALPHABET.RNA */; }\n isDna() { return this.alphabet === \"DNA\" /* ALPHABET.DNA */; }\n isPeptide() { return this.alphabet === \"PT\" /* ALPHABET.PT */; }\n isMsa() { return this.aligned ? this.aligned.toUpperCase().includes('MSA') : false; }\n isHelmCompatible() { return this.helmCompatible === 'true'; }\n isGap(m) {\n return !m || (this.units === NOTATION.FASTA && m === GapSymbols[NOTATION.FASTA]) ||\n (this.units === NOTATION.HELM && m === GapSymbols[NOTATION.HELM]);\n }\n /** Associate notation types with the corresponding units */\n /**\n * @return {NOTATION} Notation associated with the units type\n */\n getNotation() {\n if (this.units.toLowerCase().startsWith(NOTATION.FASTA))\n return NOTATION.FASTA;\n else if (this.units.toLowerCase().startsWith(NOTATION.SEPARATOR))\n return NOTATION.SEPARATOR;\n else if (this.units.toLowerCase().startsWith(NOTATION.HELM))\n return NOTATION.HELM;\n else\n throw new Error(`Column '${this.column.name}' has unexpected notation '${this.units}'.`);\n }\n /**\n * Get the wrapper strings for HELM, depending on the type of the\n * macromolecule (peptide, DNA, RNA)\n *\n * @return {string[]} Array of wrappers\n */\n getHelmWrappers() {\n const prefix = (this.isDna()) ? 'DNA1{' :\n (this.isRna() || this.isHelmCompatible()) ? 'RNA1{' : 'PEPTIDE1{';\n const postfix = '}$$$$';\n const leftWrapper = (this.isDna()) ? 'D(' :\n (this.isRna()) ? 'R(' : ''; // no wrapper for peptides\n const rightWrapper = (this.isDna() || this.isRna()) ? ')P' : ''; // no wrapper for peptides\n return [prefix, leftWrapper, rightWrapper, postfix];\n }\n /**\n * Create a new empty column of the specified notation type and the same\n * length as column\n *\n * @param {NOTATION} tgtNotation\n * @return {DG.Column}\n */\n getNewColumn(tgtNotation, tgtSeparator) {\n const col = this.column;\n const len = col.length;\n const name = tgtNotation.toLowerCase() + '(' + col.name + ')';\n const newColName = col.dataFrame.columns.getUnusedName(name);\n const newColumn = DG.Column.fromList('string', newColName, new Array(len).fill(''));\n newColumn.semType = DG.SEMTYPE.MACROMOLECULE;\n newColumn.setTag(DG.TAGS.UNITS, tgtNotation);\n if (tgtNotation === NOTATION.SEPARATOR) {\n if (!tgtSeparator)\n throw new Error(`Notation \\'${NOTATION.SEPARATOR}\\' requires separator value.`);\n newColumn.setTag(\"separator\" /* TAGS.separator */, tgtSeparator);\n }\n newColumn.setTag(DG.TAGS.CELL_RENDERER, 'Macromolecule'); // cell.renderer\n const srcAligned = col.getTag(\"aligned\" /* TAGS.aligned */);\n if (srcAligned)\n newColumn.setTag(\"aligned\" /* TAGS.aligned */, srcAligned);\n const srcAlphabet = col.getTag(\"alphabet\" /* TAGS.alphabet */);\n if (srcAlphabet != null)\n newColumn.setTag(\"alphabet\" /* TAGS.alphabet */, srcAlphabet);\n let srcAlphabetSize = col.getTag(\".alphabetSize\" /* TAGS.alphabetSize */);\n if (srcAlphabet != null && srcAlphabetSize)\n newColumn.setTag(\".alphabetSize\" /* TAGS.alphabetSize */, srcAlphabetSize);\n const srcAlphabetIsMultichar = col.getTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */);\n if (srcAlphabet != null && srcAlphabetIsMultichar !== undefined)\n newColumn.setTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */, srcAlphabetIsMultichar);\n if (tgtNotation == NOTATION.HELM) {\n srcAlphabetSize = this.getAlphabetSize().toString();\n newColumn.setTag(\".alphabetSize\" /* TAGS.alphabetSize */, srcAlphabetSize);\n }\n return newColumn;\n }\n /**\n * Create a new empty column using templateCol as a template\n *\n * @param {DG.Column} templateCol the properties and units of this column are used as a\n * template to build the new one\n * @return {DG.Column}\n */\n static getNewColumn(templateCol) {\n const col = UnitsHandler.getOrCreate(templateCol);\n const targetNotation = col.notation;\n return col.getNewColumn(targetNotation);\n }\n /**\n * A helper function checking the validity of the 'units' string\n *\n * @param {string} units the string to be validated\n * @return {boolean}\n */\n static unitsStringIsValid(units) {\n units = units.toLowerCase();\n const prefixes = [NOTATION.FASTA, NOTATION.SEPARATOR, NOTATION.HELM];\n const postfixes = ['rna', 'dna', 'pt'];\n const prefixCriterion = prefixes.some((p) => units.startsWith(p.toLowerCase()));\n return prefixCriterion;\n }\n /**\n * Construct a new column of semantic type MACROMOLECULE from the list of\n * specified parameters\n *\n * @param {number} len the length of the new column\n * @param {string} name the name of the new column\n * @param {string} units the units of the new column\n * @return {DG.Column}\n */\n static getNewColumnFromParams(len, name, units) {\n // WARNING: in this implementation is is impossible to verify the uniqueness\n // of the new column's name\n // TODO: verify the validity of units parameter\n if (!UnitsHandler.unitsStringIsValid(units))\n throw new Error('Invalid format of \\'units\\' parameter');\n const newColumn = DG.Column.fromList('string', name, new Array(len).fill(''));\n newColumn.semType = DG.SEMTYPE.MACROMOLECULE;\n newColumn.setTag(DG.TAGS.UNITS, units);\n return newColumn;\n }\n /** Gets function to split seq value to monomers */\n getSplitter(limit) {\n if (this.units.toLowerCase().startsWith(NOTATION.FASTA)) {\n const alphabet = this.column.getTag(\"alphabet\" /* TAGS.alphabet */);\n if (alphabet !== null && !this.getAlphabetIsMultichar())\n return splitterAsFastaSimple;\n else\n return splitterAsFasta;\n }\n else if (this.units.toLowerCase().startsWith(NOTATION.SEPARATOR))\n return getSplitterWithSeparator(this.separator, limit);\n else if (this.units.toLowerCase().startsWith(NOTATION.HELM))\n return splitterAsHelm;\n else\n throw new Error(`Unexpected units ${this.units} .`);\n // TODO: Splitter for HELM\n }\n getDistanceFunctionName() {\n // TODO add support for helm and separator notation\n if (!this.isFasta())\n throw new Error('Only FASTA notation is supported');\n if (this.isMsa())\n return MmDistanceFunctionsNames.HAMMING;\n switch (this.alphabet) {\n // As DNA and RNA scoring matrices are same as identity matrices(mostly),\n // we can use very fast and optimized Levenshtein distance library\n case \"DNA\" /* ALPHABET.DNA */:\n case \"RNA\" /* ALPHABET.RNA */:\n return MmDistanceFunctionsNames.LEVENSHTEIN;\n case \"PT\" /* ALPHABET.PT */:\n return MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH;\n // For default case, let's use Levenshtein distance\n default:\n return MmDistanceFunctionsNames.LEVENSHTEIN;\n }\n }\n getDistanceFunction() {\n return mmDistanceFunctions[this.getDistanceFunctionName()]();\n }\n // checks if the separator notation is compatible with helm library\n async checkHelmCompatibility() {\n // check first for the column tag to avoid extra processing\n if (this.column.tags.has(\".isHelmCompatible\" /* TAGS.isHelmCompatible */))\n return this.column.getTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */) === 'true';\n // get the monolmer lib and check against the column\n const monomerLibHelper = await getMonomerLibHelper();\n const bioLib = monomerLibHelper.getBioLib();\n // retrieve peptides\n const peptides = bioLib.getMonomerSymbolsByType(\"PEPTIDE\" /* HELM_POLYMER_TYPE.PEPTIDE */.toString());\n // convert the peptides list to a set for faster lookup\n const peptidesSet = new Set(peptides);\n // get splitter for given separator and check if all monomers are in the lib\n const splitterFunc = getSplitterWithSeparator(this.separator);\n // iterate over the columns, split them and check if all monomers are in the lib\n //TODO maybe add missing threshhold so that if there are not too many missing monomers\n // the column is still considered helm compatible\n for (const row of this.column.categories) {\n const monomers = splitterFunc(row);\n for (const monomer of monomers) {\n if (!peptidesSet.has(monomer)) {\n this.column.setTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */, 'false');\n return false;\n }\n }\n }\n this.column.setTag(\".isHelmCompatible\" /* TAGS.isHelmCompatible */, 'true');\n return true;\n }\n // -- Notation Converter --\n get splitter() {\n if (this._splitter === null)\n this._splitter = getSplitterForColumn(this.column);\n return this._splitter;\n }\n toFasta(targetNotation) { return targetNotation === NOTATION.FASTA; }\n toSeparator(targetNotation) { return targetNotation === NOTATION.SEPARATOR; }\n toHelm(targetNotation) { return targetNotation === NOTATION.HELM; }\n /**\n * Convert HELM string to FASTA/SEPARATOR\n *\n * @param {string} helmPolymer A string to be converted\n * @param {string} tgtNotation Target notation: FASTA or SEPARATOR\n * @param {string} tgtSeparator Optional target separator (for HELM ->\n * @param {string | null} tgtGapSymbol Optional target gap symbol\n * SEPARATOR)\n * @return {string} Converted string\n */\n convertHelmToFastaSeparator(helmPolymer, tgtNotation, tgtSeparator, tgtGapSymbol) {\n if (!tgtGapSymbol) {\n tgtGapSymbol = (this.toFasta(tgtNotation)) ?\n GapSymbols[NOTATION.FASTA] :\n GapSymbols[NOTATION.SEPARATOR];\n }\n if (!tgtSeparator)\n tgtSeparator = (this.toFasta(tgtNotation)) ? '' : this.separator;\n const helmWrappersRe = /(R\\(|D\\(|\\)|P)/g;\n const isNucleotide = helmPolymer.startsWith('DNA') || helmPolymer.startsWith('RNA');\n // items can be monomers or helms\n const helmItemsArray = this.splitter(helmPolymer);\n const tgtMonomersArray = [];\n for (let i = 0; i < helmItemsArray.length; i++) {\n let item = helmItemsArray[i];\n if (isNucleotide)\n item = item.replace(helmWrappersRe, '');\n if (item === GapSymbols[NOTATION.HELM])\n tgtMonomersArray.push(tgtGapSymbol);\n else if (this.toFasta(tgtNotation) && item.length > 1) {\n // the case of a multi-character monomer converted to FASTA\n const monomer = '[' + item + ']';\n tgtMonomersArray.push(monomer);\n }\n else\n tgtMonomersArray.push(item);\n }\n return tgtMonomersArray.join(tgtSeparator);\n }\n /** Dispatcher method for notation conversion\n *\n * @param {NOTATION} tgtNotation Notation we want to convert to\n * @param {string | null} tgtSeparator Possible separator\n * @return {DG.Column} Converted column\n */\n convert(tgtNotation, tgtSeparator) {\n const convert = this.getConverter(tgtNotation, tgtSeparator);\n const newColumn = this.getNewColumn(tgtNotation, tgtSeparator);\n // assign the values to the newly created empty column\n newColumn.init((rowI) => { return convert(this.column.get(rowI)); });\n // newColumn.setTag(DG.TAGS.UNITS, NOTATION.SEPARATOR);\n return newColumn;\n }\n /**\n * @param name\n * @param startIdx Start position index of the region (0-based)\n * @param endIdx End position index of the region (0-based, inclusive)\n */\n getRegion(startIdx, endIdx, name) {\n const regCol = this.getNewColumn(this.notation, this.separator);\n regCol.name = name;\n const maxLength = Math.max(...this.splitted.map((seqS) => seqS.length));\n const startIdxVal = startIdx ?? 0;\n const endIdxVal = endIdx ?? this.maxLength - 1;\n const join = this.getJoiner();\n const regLength = endIdxVal - startIdxVal + 1;\n regCol.init((rowI) => {\n const seqS = this.splitted[rowI];\n // Custom slicing instead of array method to maintain gaps\n const regMList = new Array(regLength);\n for (let regJPos = 0; regJPos < regLength; ++regJPos) {\n const seqJPos = startIdxVal + regJPos;\n regMList[regJPos] = seqJPos < seqS.length ? seqS[seqJPos] : GapSymbols[this.notation];\n }\n return join(regMList);\n });\n const getRegionOfPositionNames = (str) => {\n const srcPosList = str.split(',').map((p) => p.trim());\n const regPosList = new Array(regLength);\n for (let regJPos = 0; regJPos < regLength; ++regJPos) {\n const srcJPos = startIdxVal + regJPos;\n regPosList[regJPos] = srcJPos < srcPosList.length ? srcPosList[srcJPos] : '?';\n }\n return regPosList.join(positionSeparator);\n };\n const srcPositionNamesStr = this.column.getTag(\".positionNames\" /* TAGS.positionNames */);\n if (srcPositionNamesStr)\n regCol.setTag(\".positionNames\" /* TAGS.positionNames */, getRegionOfPositionNames(srcPositionNamesStr));\n const srcPositionLabelsStr = this.column.getTag(\".positionLabels\" /* TAGS.positionLabels */);\n if (srcPositionLabelsStr)\n regCol.setTag(\".positionLabels\" /* TAGS.positionLabels */, getRegionOfPositionNames(srcPositionLabelsStr));\n return regCol;\n }\n getJoiner() {\n const srcUh = this;\n if (this.notation === NOTATION.FASTA)\n return function (srcS) { return joinToFasta(srcUh, srcS); };\n else if (this.notation === NOTATION.SEPARATOR)\n return function (srcS) { return joinToSeparator(srcUh, srcS, srcUh.separator); };\n else if (this.notation === NOTATION.HELM) {\n const isDnaOrRna = srcUh.alphabet === \"DNA\" /* ALPHABET.DNA */ || srcUh.alphabet === \"RNA\" /* ALPHABET.RNA */;\n return function (srcS) { return joinToHelm(srcUh, srcS, isDnaOrRna); };\n }\n else\n throw new Error();\n }\n getConverter(tgtUnits, tgtSeparator = undefined) {\n if (tgtUnits === NOTATION.SEPARATOR && !tgtSeparator)\n throw new Error(`Target separator is not specified for target units '${NOTATION.SEPARATOR}'.`);\n const srcUh = this;\n if (tgtUnits === NOTATION.FASTA)\n return function (src) { return convertToFasta(srcUh, src); };\n if (tgtUnits === NOTATION.HELM)\n return function (src) { return convertToHelm(srcUh, src); };\n else if (tgtUnits === NOTATION.SEPARATOR)\n return function (src) { return convertToSeparator(srcUh, src, tgtSeparator); };\n else\n throw new Error();\n }\n constructor(col) {\n this._splitter = null;\n this._splitted = null;\n this._stats = null;\n this._maxLength = null;\n this._posList = null;\n if (col.type != DG.TYPE.STRING)\n throw new Error(`Unexpected column type '${col.type}', must be '${DG.TYPE.STRING}'.`);\n this._column = col;\n const units = this._column.getTag(DG.TAGS.UNITS);\n if (units !== null && units !== undefined)\n this._units = units;\n else\n throw new Error('Units are not specified in column');\n this._notation = this.getNotation();\n this._defaultGapSymbol = (this.isFasta()) ? GapSymbols[NOTATION.FASTA] :\n (this.isHelm()) ? GapSymbols[NOTATION.HELM] :\n GapSymbols[NOTATION.SEPARATOR];\n if (!this.column.tags.has(\"aligned\" /* TAGS.aligned */) || !this.column.tags.has(\"alphabet\" /* TAGS.alphabet */) ||\n (!this.column.tags.has(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */) && !this.isHelm() && this.alphabet === \"UN\" /* ALPHABET.UN */)) {\n // The following detectors and setters are to be called because the column is likely\n // as the UnitsHandler constructor was called on the column.\n if (this.isFasta())\n UnitsHandler.setUnitsToFastaColumn(this);\n else if (this.isSeparator()) {\n const separator = col.getTag(\"separator\" /* TAGS.separator */);\n UnitsHandler.setUnitsToSeparatorColumn(this, separator);\n }\n else if (this.isHelm())\n UnitsHandler.setUnitsToHelmColumn(this);\n else\n throw new Error(`Unexpected units '${this.column.getTag(DG.TAGS.UNITS)}'.`);\n }\n // if (!this.column.tags.has(TAGS.alphabetSize)) {\n // if (this.isHelm())\n // throw new Error(`For column '${this.column.name}' of notation '${this.notation}' ` +\n // `tag '${TAGS.alphabetSize}' is mandatory.`);\n // else if (['UN'].includes(this.alphabet))\n // throw new Error(`For column '${this.column.name}' of alphabet '${this.alphabet}' ` +\n // `tag '${TAGS.alphabetSize}' is mandatory.`);\n // }\n if (!this.column.tags.has(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */)) {\n if (this.isHelm())\n this.column.setTag(\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */, 'true');\n else if (['UN'].includes(this.alphabet)) {\n throw new Error(`For column '${this.column.name}' of alphabet '${this.alphabet}' ` +\n `tag '${\".alphabetIsMultichar\" /* TAGS.alphabetIsMultichar */}' is mandatory.`);\n }\n }\n }\n /** Gets a column's UnitsHandler object from temp slot or creates a new and stores it to the temp slot. */\n static getOrCreate(col) {\n if (!(Tags.uhTemp in col.temp))\n col.temp[Tags.uhTemp] = new UnitsHandler(col);\n return col.temp[Tags.uhTemp];\n }\n}\nconst helmWrappersRe = /[RD]\\((\\w)\\)P?/g;\nfunction joinToFasta(srcUh, seqS) {\n const resMList = new Array(seqS.length);\n for (const [srcM, mI] of wu.enumerate(seqS)) {\n let m = srcM;\n if (srcUh.isHelm())\n m = srcM.replace(helmWrappersRe, '$1');\n if (srcUh.isGap(m))\n m = GapSymbols[NOTATION.FASTA];\n else if (m.length > 1)\n m = '[' + seqS[mI] + ']';\n resMList[mI] = m;\n }\n return resMList.join('');\n}\nfunction convertToFasta(srcUh, src) {\n const srcMList = srcUh.isHelm() ? splitterAsHelmNucl(srcUh, src) : srcUh.getSplitter()(src);\n return joinToFasta(srcUh, srcMList);\n}\nfunction joinToSeparator(srcUh, seqS, tgtSeparator) {\n const resMList = new Array(seqS.length);\n for (const [srcM, mI] of wu.enumerate(seqS)) {\n let m = srcM;\n if (srcUh.isGap(m))\n m = GapSymbols[NOTATION.SEPARATOR];\n resMList[mI] = m;\n }\n return resMList.map((m) => m ?? '').join(tgtSeparator);\n}\nfunction convertToSeparator(srcUh, src, tgtSeparator) {\n const srcMList = srcUh.isHelm() ? splitterAsHelmNucl(srcUh, src) : srcUh.getSplitter()(src);\n return joinToSeparator(srcUh, srcMList, tgtSeparator);\n}\nfunction joinToHelm(srcUh, seqS, isDnaOrRna) {\n const [prefix, leftWrapper, rightWrapper, postfix] = srcUh.getHelmWrappers();\n const resMList = wu(seqS).map((srcM) => {\n let m = srcM;\n if (srcUh.isGap(m))\n m = GapSymbols[NOTATION.HELM];\n else if (isDnaOrRna)\n m = m.replace(helmWrappersRe, '$1');\n else\n m = srcM.length == 1 ? `${leftWrapper}${srcM}${rightWrapper}` : `${leftWrapper}[${srcM}]${rightWrapper}`;\n return m;\n }).toArray();\n return `${prefix}${resMList.join('.')}${postfix}`;\n}\nfunction convertToHelm(srcUh, src) {\n const isDnaOrRna = src.startsWith('DNA') || src.startsWith('RNA');\n const srcS = srcUh.getSplitter()(src);\n return joinToHelm(srcUh, srcS, isDnaOrRna);\n}\n/** Splits Helm sequence adjusting nucleotides to single char symbols. (!) Removes lone phosphorus. */\nfunction splitterAsHelmNucl(srcUh, src) {\n const srcMList = srcUh.getSplitter()(src);\n const tgtMList = new Array(srcMList.length);\n const isDna = src.startsWith('DNA');\n const isRna = src.startsWith('RNA');\n for (const [srcM, mI] of wu.enumerate(srcMList)) {\n let m = srcM;\n if (isDna || isRna) {\n m = m.replace(helmWrappersRe, '$1');\n m = m === 'P' ? null : m;\n }\n tgtMList[mI] = m;\n }\n return tgtMList.filter((m) => m !== null);\n}\n//# sourceMappingURL=units-handler.js.map","/* Do not change these import lines to match external modules in webpack configuration */\nimport * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {ExternalPluginUI} from '../view/app-ui';\nimport {ColoredTextInput} from '../view/utils/colored-input/colored-text-input';\nimport {highlightInvalidSubsequence} from '../view/utils/colored-input/input-painters';\nimport {codesToSymbolsDictionary} from '../model/data-loading-utils/json-loader';\nimport {MERMADE} from './const';\n\nexport async function getExternalAppViewFactories(): Promise<{[name: string]: () => DG.View} | undefined> {\n const externalPluginData = {\n [MERMADE.FUNCTION_NAME]: {\n tabName: MERMADE.TAB_NAME,\n parameters: getMerMadeParameters()\n },\n }\n\n const result: {[tabName: string]: () => DG.View} = {};\n\n for (const [pluginName, data] of Object.entries(externalPluginData)) {\n let div: HTMLDivElement;\n try {\n div = await grok.functions.call(pluginName, data.parameters);\n const pluginUI = new ExternalPluginUI(data.tabName, div);\n\n // intentonally don't await for the promise\n pluginUI.initView();\n\n result[data.tabName] = () => pluginUI.getView();\n } catch (err) {\n console.warn(`Plugin ${pluginName} not loaded, reason:`, err)\n continue;\n }\n }\n return result;\n}\n\nfunction getMerMadeParameters(): {[name: string]: any} {\n const base = ui.textInput('', '');\n const input = new ColoredTextInput(base, highlightInvalidSubsequence);\n\n return {\n coloredInput: input,\n codes: codesToSymbolsDictionary\n }\n}\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {AppUIFactory, CombinedAppUI} from './view/app-ui';\nimport {tryCatch} from './model/helpers';\nimport {LIB_PATH, DEFAULT_LIB_FILENAME} from './model/data-loading-utils/const';\nimport {IMonomerLib} from '@datagrok-libraries/bio/src/types';\nimport {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';\nimport {getJsonData} from './model/data-loading-utils/json-loader';\nimport {SequenceToMolfileConverter} from './model/structure-app/sequence-to-molfile';\nimport {linkStrandsV3000} from './model/structure-app/mol-transformations';\nimport {MonomerLibWrapper} from './model/monomer-lib/lib-wrapper';\nimport {FormatDetector} from './model/parsing-validation/format-detector';\nimport {SequenceValidator} from './model/parsing-validation/sequence-validator';\nimport {demoOligoTranslatorUI, demoOligoPatternUI, demoOligoStructureUI} from './demo/demo-st-ui';\nimport {FormatConverter} from './model/translator-app/format-converter';\nimport {APP} from './view/const/ui';\nimport {getExternalAppViewFactories} from './plugins/mermade';\n\nclass StPackage extends DG.Package {\n private _monomerLib?: IMonomerLib;\n\n get monomerLib(): IMonomerLib {\n if (!this._monomerLib)\n throw new Error ('Monomer lib not loaded')\n return this._monomerLib!;\n }\n\n public async initMonomerLib(): Promise<void> {\n if (this._monomerLib !== undefined)\n return;\n\n const pi: DG.TaskBarProgressIndicator = DG.TaskBarProgressIndicator.create(\n `Initializing ${APP.COMBINED} monomer library ...`);\n await tryCatch(async () => {\n const libHelper: IMonomerLibHelper = await getMonomerLibHelper();\n this._monomerLib = await libHelper.readLibrary(LIB_PATH, DEFAULT_LIB_FILENAME);\n }, () => pi.close());\n }\n}\n\nexport const _package: StPackage = new StPackage();\n\nasync function buildLayout(appName: string): Promise<void> {\n await initSequenceTranslatorLibData();\n const appUI = AppUIFactory.getUI(appName);\n await appUI.createAppLayout();\n}\n\n\n//name: Oligo Toolkit\n//meta.icon: img/icons/toolkit.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoToolkitApp(): Promise<void> {\n await initSequenceTranslatorLibData();\n const externalViewFactories = await getExternalAppViewFactories();\n if (!externalViewFactories)\n throw new Error('External app view factories not loaded');\n const appUI = new CombinedAppUI(externalViewFactories!);\n await appUI.createAppLayout();\n}\n\n//name: Oligo Translator\n//meta.icon: img/icons/translator.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoTranslatorApp(): Promise<void> {\n await buildLayout(APP.TRANSLATOR);\n}\n\n//name: Oligo Pattern\n//meta.icon: img/icons/pattern.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoPatternApp(): Promise<void> {\n await buildLayout(APP.PATTERN);\n}\n\n//name: Oligo Structure\n//meta.icon: img/icons/structure.png\n//meta.browsePath: Oligo\n//tags: app\nexport async function oligoStructureApp(): Promise<void> {\n await buildLayout(APP.STRUCTRE);\n}\n\n//name: initSequenceTranslatorLibData\nexport async function initSequenceTranslatorLibData(): Promise<void> {\n await getJsonData();\n await _package.initMonomerLib();\n}\n\n//name: getCodeToWeightsMap\n//output: object result\nexport function getCodeToWeightsMap(): {[key: string]: number} {\n const map = MonomerLibWrapper.getInstance().getCodesToWeightsMap();\n return Object.fromEntries(map);\n}\n\n//name: validateSequence\n//input: string sequence\n//output: bool result\nexport function validateSequence(sequence: string): boolean {\n const validator = new SequenceValidator(sequence);\n const format = (new FormatDetector(sequence).getFormat());\n return (format === null) ? false : validator.isValidSequence(format!);\n}\n\n//name: validateSequence\n//input: string sequence\n//input: bool invert\n//output: string result\nexport function getMolfileFromGcrsSequence(sequence: string, invert: boolean): string {\n return (new SequenceToMolfileConverter(sequence, invert, 'GCRS')).convert();\n}\n\n//name: linkStrands\n//input: object strands\n//output: string result\nexport function linkStrands(strands: { senseStrands: string[], antiStrands: string[] }): string {\n return linkStrandsV3000(strands, true);\n}\n\n//name: demoOligoTranslator\n//meta.demoPath: Bioinformatics | Oligo Toolkit | Translator\n//description: Translate oligonucleotide sequences across various formats accepted by different synthesizers\n//meta.path: /apps/Tutorials/Demo/Bioinformatics/Oligonucleotide%20Sequence:%20Translate\nexport async function demoTranslateSequence(): Promise<void> {\n await demoOligoTranslatorUI();\n}\n\n//name: demoOligoPattern\n//meta.demoPath: Bioinformatics | Oligo Toolkit | Pattern\n//description: Design a modification pattern for an oligonucleotide sequence\n//meta.path:%20/apps/Tutorials/Demo/Bioinformatics/Oligonucleotide%20Sequence:%20Visualize%20duplex\nexport async function demoOligoPattern(): Promise<void> {\n await demoOligoPatternUI();\n}\n\n//name: demoOligoStructure\n//meta.demoPath: Bioinformatics | Oligo Toolkit | Structure\n//description: Visualize duplex and save SDF\n//meta.path:%20/apps/Tutorials/Demo/Bioinformatics/Oligonucleotide%20Sequence:%20Visualize%20duplex\nexport async function demoOligoStructure(): Promise<void> {\n await demoOligoStructureUI();\n}\n\n//name: translateOligonucleotideSequence\n//input: string sequence\n//input: string sourceFormat\n//input: string targetFormat\n//output: string result\nexport async function translateOligonucleotideSequence(sequence: string, sourceFormat: string, targetFormat: string): Promise<string> {\n await initSequenceTranslatorLibData();\n return (new FormatConverter(sequence, sourceFormat)).convertTo(targetFormat);\n}\n","// import * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\nimport * as grok from 'datagrok-api/grok';\nimport { HELM_CORE_FIELDS, jsonSdfMonomerLibDict, MONOMER_ENCODE_MAX, MONOMER_ENCODE_MIN, SDF_MONOMER_NAME } from '../utils/const';\nimport { UnitsHandler } from '../utils/units-handler';\nimport { splitAlignedSequences } from '../utils/splitter';\nexport function encodeMonomers(col) {\n let encodeSymbol = MONOMER_ENCODE_MIN;\n const monomerSymbolDict = {};\n const uh = UnitsHandler.getOrCreate(col);\n const splitterFunc = uh.getSplitter();\n const encodedStringArray = [];\n for (let i = 0; i < col.length; ++i) {\n let encodedMonomerStr = '';\n const monomers = splitterFunc(col.get(i));\n for (const m of monomers) {\n if (!monomerSymbolDict[m]) {\n if (encodeSymbol > MONOMER_ENCODE_MAX) {\n grok.shell.error(`Not enough symbols to encode monomers`);\n return null;\n }\n monomerSymbolDict[m] = encodeSymbol;\n encodeSymbol++;\n }\n encodedMonomerStr += String.fromCodePoint(monomerSymbolDict[m]);\n }\n encodedStringArray.push(encodedMonomerStr);\n }\n return DG.Column.fromStrings('encodedMolecules', encodedStringArray);\n}\nexport function getMolfilesFromSeq(col, monomersLibObject) {\n const uh = UnitsHandler.getOrCreate(col);\n const splitter = uh.getSplitter();\n const monomersDict = createMomomersMolDict(monomersLibObject);\n const molFiles = [];\n for (let i = 0; i < col.length; ++i) {\n const macroMolecule = col.get(i);\n const monomers = splitter(macroMolecule);\n const molFilesForSeq = [];\n for (let j = 0; j < monomers.length; ++j) {\n if (monomers[j]) {\n if (!monomersDict[monomers[j]]) {\n grok.shell.warning(`Monomer ${monomers[j]} is missing in HELM library. Structure cannot be created`);\n return null;\n }\n // what is the reason of double conversion?\n molFilesForSeq.push(JSON.parse(JSON.stringify(monomersDict[monomers[j]])));\n }\n }\n molFiles.push(molFilesForSeq);\n }\n return molFiles;\n}\nexport function getMolfilesFromSingleSeq(cell, monomersLibObject) {\n const uh = UnitsHandler.getOrCreate(cell.column);\n const splitterFunc = uh.getSplitter();\n const monomersDict = createMomomersMolDict(monomersLibObject);\n const molFiles = [];\n const macroMolecule = cell.value;\n const monomers = splitterFunc(macroMolecule);\n const molFilesForSeq = [];\n for (let j = 0; j < monomers.length; ++j) {\n if (monomers[j]) {\n if (!monomersDict[monomers[j]]) {\n grok.shell.warning(`Monomer ${monomers[j]} is missing in HELM library. Structure cannot be created`);\n return null;\n }\n molFilesForSeq.push(JSON.parse(JSON.stringify(monomersDict[monomers[j]])));\n }\n }\n molFiles.push(molFilesForSeq);\n return molFiles;\n}\nexport function createMomomersMolDict(lib) {\n const dict = {};\n lib.forEach((it) => {\n if (it['polymerType'] === 'PEPTIDE') {\n const monomerObject = {};\n HELM_CORE_FIELDS.forEach((field) => {\n monomerObject[field] = it[field];\n });\n dict[it[\"symbol\" /* HELM_FIELDS.SYMBOL */]] = monomerObject;\n }\n });\n return dict;\n}\nexport function createJsonMonomerLibFromSdf(table) {\n const resultLib = [];\n for (let i = 0; i < table.rowCount; i++) {\n const monomer = {};\n Object.keys(jsonSdfMonomerLibDict).forEach((key) => {\n if (key === \"symbol\" /* HELM_FIELDS.SYMBOL */) {\n const monomerSymbol = table.get(jsonSdfMonomerLibDict[key], i);\n monomer[key] = monomerSymbol === '.' ? table.get(SDF_MONOMER_NAME, i) : monomerSymbol;\n }\n else if (key === \"rgroups\" /* HELM_FIELDS.RGROUPS */) {\n const rgroups = table.get(jsonSdfMonomerLibDict[key], i).split('\\n');\n const jsonRgroups = [];\n rgroups.forEach((g) => {\n const rgroup = {};\n const altAtom = g.substring(g.lastIndexOf(']') + 1);\n const radicalNum = g.match(/\\[R(\\d+)\\]/)[1];\n rgroup[\"capGroupSmiles\" /* HELM_RGROUP_FIELDS.CAP_GROUP_SMILES */] = altAtom === 'H' ? `[*:${radicalNum}][H]` : `O[*:${radicalNum}]`;\n rgroup[\"alternateId\" /* HELM_RGROUP_FIELDS.ALTERNATE_ID */] = altAtom === 'H' ? `R${radicalNum}-H` : `R${radicalNum}-OH`;\n rgroup[\"capGroupName\" /* HELM_RGROUP_FIELDS.CAP_GROUP_NAME */] = altAtom === 'H' ? `H` : `OH`;\n rgroup[\"label\" /* HELM_RGROUP_FIELDS.LABEL */] = `R${radicalNum}`;\n jsonRgroups.push(rgroup);\n });\n monomer[key] = jsonRgroups;\n }\n else {\n if (jsonSdfMonomerLibDict[key])\n monomer[key] = table.get(jsonSdfMonomerLibDict[key], i);\n }\n });\n resultLib.push(monomer);\n }\n return resultLib;\n}\nexport async function getMonomerLibHelper() {\n const funcList = DG.Func.find({ package: 'Bio', name: 'getMonomerLibHelper' });\n if (funcList.length === 0)\n throw new Error('Package \"Bio\" must be installed for MonomerLibHelper.');\n const res = (await funcList[0].prepare().call()).getOutputParamValue();\n return res;\n}\nexport async function sequenceChemSimilarity(positionColumns, referenceSequence) {\n if (positionColumns instanceof DG.Column)\n positionColumns = splitAlignedSequences(positionColumns).columns.toList();\n const libHelper = await getMonomerLibHelper();\n const monomerLib = libHelper.getBioLib();\n // const smilesCols: DG.Column<string>[] = new Array(monomerCols.length);\n const rawCols = new Array(positionColumns.length);\n const rowCount = positionColumns[0].length;\n const totalSimilarity = new Float32Array(rowCount);\n // Calculate base similarity\n for (let position = 0; position < positionColumns.length; ++position) {\n const referenceMonomer = referenceSequence[position];\n const referenceMol = monomerLib.getMonomer('PEPTIDE', referenceMonomer)?.smiles ?? '';\n const monomerCol = positionColumns[position];\n const monomerColData = monomerCol.getRawData();\n const monomerColCategories = monomerCol.categories;\n const emptyCategoryIdx = monomerColCategories.indexOf('');\n rawCols[position] = { categories: monomerColCategories, data: monomerColData, emptyIndex: emptyCategoryIdx };\n if (typeof referenceMonomer === 'undefined')\n continue;\n // Calculating similarity for \n const molCol = DG.Column.fromStrings('smiles', monomerColCategories.map((cat) => monomerLib.getMonomer('PEPTIDE', cat)?.smiles ?? ''));\n const _df = DG.DataFrame.fromColumns([molCol]); // getSimilarities expects that column is in dataframe\n const similarityCol = (await grok.chem.getSimilarities(molCol, referenceMol));\n const similarityColData = similarityCol.getRawData();\n for (let rowIdx = 0; rowIdx < rowCount; ++rowIdx) {\n const monomerCategoryIdx = monomerColData[rowIdx];\n totalSimilarity[rowIdx] += referenceMonomer !== '' && monomerCategoryIdx !== emptyCategoryIdx ?\n similarityColData[monomerCategoryIdx] :\n referenceMonomer === '' && monomerCategoryIdx === emptyCategoryIdx ? 1 : 0;\n }\n }\n for (let similarityIndex = 0; similarityIndex < totalSimilarity.length; ++similarityIndex) {\n let updatedSimilarity = totalSimilarity[similarityIndex] / referenceSequence.length;\n for (let position = 0; position < positionColumns.length; ++position) {\n const currentRawCol = rawCols[position];\n if ((position >= referenceSequence.length && currentRawCol.data[similarityIndex] !== currentRawCol.emptyIndex) ||\n (currentRawCol.data[similarityIndex] === currentRawCol.emptyIndex && position < referenceSequence.length)) {\n updatedSimilarity = DG.FLOAT_NULL;\n break;\n }\n }\n totalSimilarity[similarityIndex] = updatedSimilarity;\n }\n const similarityCol = DG.Column.fromFloat32Array('Similarity', totalSimilarity);\n return similarityCol;\n}\n//# sourceMappingURL=monomer-utils.js.map","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {delay} from '@datagrok-libraries/utils/src/test';\nimport {getJsonData} from '../model/data-loading-utils/json-loader';\nimport {_package, oligoTranslatorApp, oligoPatternApp, oligoStructureApp} from '../package';\nimport {tryCatch} from '../model/helpers';\n\nexport async function demoOligoTranslatorUI() {\n await tryCatch(async () => oligoTranslatorApp());\n}\n\nexport async function demoOligoPatternUI() {\n await tryCatch(async () => {\n async function emulateUserInput(value: string, idx: number, idxUpdate: (idx: number) => number): Promise<void> {\n await delay(3000);\n\n // warning: this redefinition is necessary because\n // the ids of the elements can dynamically change\n const choiceInputs: NodeListOf<HTMLSelectElement> = document.querySelectorAll('.st-pattern-choice-input > select');\n len = choiceInputs.length;\n const selectElement = choiceInputs[idxUpdate(idx)];\n selectElement.value = value;\n const event = new Event('input');\n selectElement.dispatchEvent(event);\n }\n\n await oligoPatternApp();\n\n let len: number;\n\n const ssNewValues = ['DNA', 'invAb', 'Z-New'];\n ssNewValues.forEach(async (value, idx) => {\n emulateUserInput(value, idx, (i) => 2 * i);\n });\n\n const asNewValues = ['2\\'-O-Methyl', '2\\'-Fluoro', '2\\'-O-MOE'];\n asNewValues.forEach(async (value, idx) => {\n emulateUserInput(value, idx, (i) => (len - 2 - 2 * i));\n });\n })\n}\n\nexport async function demoOligoStructureUI() {\n await tryCatch(async () => {\n async function setInputValue(idx: number, sequence: string): Promise<void> {\n await delay(500);\n const textInputs: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll('.colored-text-input > textarea');\n const textarea = textInputs[idx];\n textarea.value = sequence;\n const event = new Event('input');\n textarea.dispatchEvent(event);\n }\n await oligoStructureApp();\n const inputSequences = ['Afcgacsu', 'Afcgacsu', 'Afcgacsu'];\n inputSequences.forEach(async (sequence, idx) => {\n await setInputValue(idx, sequence);\n })\n });\n}\n","export const DEFAULT_INPUT = 'fAmCmGmAmCpsmU';\nexport const SEQUENCE_COPIED_MSG = 'Copied';\nexport const SEQ_TOOLTIP_MSG = 'Copy sequence';\n","export const enum TAB {\n TRANSLATOR = 'TRANSLATOR',\n PATTERN = 'PATTERN',\n STRUCTRE = 'STRUCTURE'\n}\n\nexport const enum APP {\n COMBINED = 'Oligo Toolkit',\n TRANSLATOR = 'Oligo Translator',\n PATTERN = 'Oligo Pattern',\n STRUCTRE = 'Oligo Structure',\n}\n\nexport const DEFAULT_AXOLABS_INPUT = 'Afcgacsu';\n","module.exports = DG;","module.exports = grok;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nc = undefined;","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(593);\n"],"names":["ChemicalTableParserBase","constructor","fileContent","this","init","replace","_atomCount","undefined","_atomTypes","_bondCount","_bondTypes","xyzAtomCoordinates","_pairsOfBondedAtoms","atomCount","setAtomAndBondCounts","bondCount","x","_a","parseAtomCoordinates","y","z","atomTypes","parseAtomTypes","pairsOfBondedAtoms","parseBondedAtomPairs","bondTypes","parseBondTypes","parseAtomAndBondCounts","getNextColumnIdx","idx","isWhitespace","shiftIdxToSpecifiedColumn","lineStartIdx","columnNumber","numberOfJumps","i","Array","getAtomBlockIdx","shiftIdxToAtomType","parseAtomType","getNextLineIdx","Float32Array","shiftIdxToXColumn","item","parseFloatValue","bondedAtomPairs","getBondBlockIdx","shiftIdxToBondedAtomsPair","pair","Uint16Array","parseIntValue","shiftIdxToBondType","symbol","indexOf","idxOfNumber","parseNumericValue","parseFloat","parseInt","parserFunction","end","substring","MolfileHandlerBase","molfile","super","begin","isQuote","getNextIdenticalChar","letter","charCodeAt","sym","isQuery","isQueryOrFragment","char","charCode","isFragment","condition","MolfileV3KHandler","getCountsLineIdx","static","numOfAtoms","assure","delay","ms","thisArg","_arguments","generator","Promise","r","setTimeout","P","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","notNull","name","Error","errorToConsole","err","String","stack","message","toString","___CSS_LOADER_EXPORT___","push","module","id","exports","cssWithMappingToString","list","map","content","needLayer","concat","length","join","modules","media","dedupe","supports","layer","alreadyImportedModules","k","_k","cssMapping","btoa","base64","unescape","encodeURIComponent","JSON","stringify","data","sourceMapping","out$","window","default","xmlNs","svgNs","urlRegex","fontFormats","woff2","woff","otf","ttf","eot","sfnt","svg","isElement","obj","HTMLElement","SVGElement","requireDomNode","el","requireDomNodePromise","getDimension","clone","dim","v","viewBox","baseVal","getAttribute","match","getBoundingClientRect","style","getComputedStyle","getPropertyValue","isNaN","uriToBlob","uri","byteString","atob","split","mimeString","buffer","ArrayBuffer","intArray","Uint8Array","Blob","type","cachedFonts","cachedRules","inlineCss","options","_ref","selectorRemap","modifyStyle","modifyCss","fonts","excludeUnusedCss","generateCss","selector","properties","css","detectFonts","fontList","from","document","styleSheets","sheet","rules","cssRules","href","console","warn","forEach","_ref2","rule","querySelector","parentNode","query","selectorText","cssText","font","url","fontUrl","formats","fullUrl","startsWith","text","format","Object","keys","filter","extension","error","detectCssFont","all","req","XMLHttpRequest","addEventListener","fontInBase64","binary","bytes","byteLength","fromCharCode","arrayBufferToBase64","response","fontUri","open","responseType","send","fontCss","inlineFonts","downloadOptions","navigator","msSaveOrOpenBlob","createElement","popup","prepareSvg","_ref3","_ref3$left","left","_ref3$top","top","w","width","h","height","_ref3$scale","scale","_ref3$responsive","responsive","_ref3$excludeCss","excludeCss","querySelectorAll","image","getAttributeNS","lastIndexOf","location","host","Date","valueOf","canvas","img","Image","crossOrigin","src","onerror","onload","getContext","drawImage","setAttributeNS","toDataURL","inlineImages","cloneNode","backgroundColor","_getDimensions","tagName","getBBox","_el$getBBox","getDimensions","setAttribute","createElementNS","appendChild","removeAttribute","foreignObject","innerHTML","defs","insertBefore","firstChild","outer","svgAsDataUri","_ref4","svgXml","decodeURIComponent","p1","c","svgAsPngUri","_ref5","_ref5$encoderType","encoderType","_ref5$encoderOptions","encoderOptions","canvg","convertToPng","_ref6","context","pixelRatio","devicePixelRatio","setTransform","png","SecurityError","slice","download","saveLink","display","body","blob","URL","createObjectURL","onclick","requestAnimationFrame","revokeObjectURL","click","removeChild","title","saveSvg","downloadOpts","saveSvgAsPng","stylesInDOM","getIndexByIdentifier","identifier","modulesToDom","idCountMap","identifiers","base","count","indexByIdentifier","sourceMap","references","updater","addElementStyle","byIndex","splice","api","domAPI","update","newObj","remove","lastIdentifiers","newList","index","newLastIdentifiers","_i","_index","memo","insert","target","styleTarget","HTMLIFrameElement","contentDocument","head","getTarget","element","setAttributes","attributes","styleElement","nonce","insertStyleElement","styleTagTransform","removeStyleElement","styleSheet","createTextNode","NUCLEOTIDES","DEFAULT_FORMATS","LIB_PATH","DEFAULT_LIB_FILENAME","APP_PATH","AXOLABS_STYLE_FILENAME","CODES_TO_HELM_DICT_FILENAME","CODES_TO_SYMBOLS_FILENAME","MONOMERS_WITH_PHOSPHATE_LINKERS","fileSource","axolabsStyleMap","codesToHelmDictionary","codesToSymbolsDictionary","monomersWithPhosphateLinkers","async","getJsonData","every","parse","path","parsedJson","readAsText","errMsg","hasOwnProperty","sortByReverseLength","array","sort","a","b","tryCatch","func","finallyFunc","callbackName","MonomerLibWrapper","lib","_package","allMonomers","getAllMonomers","formatMonomerForViewer","sourceObj","formattedObject","getAllFormats","codes","code","polymerTypes","getPolymerTypes","polymerType","monomersByType","getMonomerSymbolsByType","monomerSymbol","getMonomer","monomer","instance","getMolfileBySymbol","getNaturalAnalogBySymbol","naturalAnalog","isModification","includes","getCodeToSymbolMap","Map","entries","getCodesByFormat","getTableForViewer","formattedObjects","getCodesToWeightsMap","codesToWeightsMap","_","dict","weight","set","SequenceValidator","sequence","libWrapper","getInvalidCodeIndex","firstUniqueCharacters","indexOfFirstInvalidChar","matchedCode","find","isValidSequence","PHOSPHATE_SYMBOL","linkStrandsV3000","strands","useChirality","macroMolBlock","atomBlock","bondBlock","collectionBlock","collection","natom","nbond","xShift","antiStrands","invertNucleotidesV3000","inverted","molBlocks","senseStrands","ssYShift","replaceAll","numbers","extractAtomsBondsNumbersV3000","coordinates","extractAtomDataV3000","Math","min","xShiftRight","yShift","max","j","indexAtoms","indexEnd","atomNumber","coordinate","round","indexAtomsEnd","indexBonds","bondNumber","indexBondEnd","indexCollection","collectionEnd","collNumber","ceil","entriesCurrent","molBlock","atomIndex","xCenter","yCenter","angle","PI","cos","sin","xAdd","atomsNumber","indexes","types","atomType","GROUP_TYPE","NUCLEOSIDE","LINKAGE","UNKNOWN_SYMBOL","getTranslatedSequences","sourceFormat","supportedFormats","outputFormats","localeCompare","converter","fromEntries","translation","convertTo","nucleotides","helmString","monomerLib","re","RegExp","branches","branch","stripped","getNucleotidesSequence","inverseLengthComparator","FormatHandler","getFormats","getFormatNames","validateFormat","isHelm","getFormatCodes","getHelmToFormatDict","infoObj","values","helm","key","sorted","getHelmToCodeDict","getFormatToHelmDict","codesInfoObject","assign","getTargetFormatHelmCodes","getTargetFormatHelmCodesRegExp","helmCodes","getRegExpPattern","getFormatRegExp","getNonHelmFormatRegExp","getPhosphateHelmCodesRegExp","phosphateHELMPattern","Set","isValidFormat","formatCodes","arr","HELM_WRAPPER","LEFT","RIGHT","FormatConverter","targetFormat","helmToFormat","formatToHelm","helmSequence","wrapperRegExp","helmRegExp","formatRegExp","phosphateRegExp","group","ui","rxjs","FormatDetector","getFormat","possibleFormats","getListOfPossibleSynthesizersByFirstMatchedCode","validator","outputIndices","fill","formatIdx","some","synthesizers","start","s","$","highlightInvalidSubsequence","input","cutoff","isValid","greyTextSpan","redTextSpan","ColoredTextInput","textInputBase","painter","resizeable","root","addClass","onChanged","textArea","highlights","colorize","getElementsByTagName","inputBase","spans","span","MonomerSequenceParser","codeMap","parseSequence","parsedRawCodes","parseRawSequence","addLinkers","monomerSymbolSequence","getSymbolForCode","monomerHasLeftPhosphateLinker","pop","isPhosphate","monomerIsPhosphateLinker","lastMonomer","nextMonomerIsPhosphate","monomerHasRightPhosphateLinker","get","allCodesOfFormat","getAllCodesOfFormat","parsedCodes","allCodesInTheFormat","SequenceToMolfileConverter","invert","codeToSymbolMap","parser","convert","parsedSequence","monomerMolfiles","monomerMolfile","getMonomerMolfile","getPolymerMolfile","reflect","invertBondConfiguration","beginIdx","endIdx","group1","group2","rotateNucleotidesV3000","linkV3000","indexFivePrime","indexThreePrime","fix5Prime","derivative","atan","isBoundary","specLength","totalShift","indexFivePrimeNeighbour","base3PrimeX","base3PrimeY","base5PrimeX","base5PrimeY","rotated5PrimeX","rotated5PrimeY","dx","dy","dxRotated","dyRotated","sqrt","V2K_CONST","MolfileV2KHandler","HEADER","END","ATOM_TYPE_COL","NUM_OF_HEADER_LINES","FIRST_BONDED_ATOM_COL","BOND_TYPE_COL","NUM_OF_COUNTS_DIGITS","MolfileHandler","validate","InvalidMolfileError","MoleculeImage","molblok","molblock","_validMolBlock","validateMolBlock","errorMessage","molString","scaffoldMolString","normalizeDepiction","straightenDepiction","errStr","getMoleculeDimensions","molData","getInstance","dialog","showFooter","molDimensions","zoomRatio","dialogCanvasHeight","dialogCanvasWidth","dialogCanvas","drawMolBlockOnCanvas","dialogDiv","overflowX","add","showModal","removeClass","moleculeImgDiv","canvasWidth","canvasHeight","cursor","zoomIn","append","TranslatorLayoutHandler","INPUT_FORMATS","className","border","borderRadius","marginTop","outputTableDiv","formatChoiceInput","updateTable","updateMolImg","sequenceInputBase","onInput","subscribe","sequenceColoredInput","downloadMolfileButton","saveMolfile","copySmilesButton","copySmiles","clearButton","inputTableRow","textInput","clearBtn","upperBlock","classList","outputTable","mainTabBody","smiles","clipboard","writeText","indexOfInvalidChar","translatedSequences","tableRows","molImgObj","drawMolecule","getFormattedSequence","getMolfile","axolabs","getMolfileForStrand","strand","getLinkedMolfile","ss","as","as2","useChiral","nonEmptyStrands","ssMol","STRANDS","StructureLayoutHandler","onInvalidInput","useChiralInput","saveAllStrandsInput","directionInversion","updateMoleculeImg","tableLayout","getTableInput","boolInputsAndButton","getBoolInputsAndButton","bottomDiv","layout","saveButton","strandData","getStrandData","oneEntity","asMol","as2Mol","date","pad","dateString","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","saveSdf","boolInputsAndButtonArray","coloredInput","directionChoiceInput","selected","toUpperCase","labelNames","labelNameMap","label","clearBlock","clearIcon","clear","choiceInput","parentElement","USER_STORAGE_KEY","SS","AS","STRAND_NAME","THREE_PRIME","FIVE_PRIME","TERMINAL_KEYS","TERMINAL","isOverhang","modification","countOverhangsOnTheRightEdge","modifications","textWidth","measureText","textInsideCircle","bases","fontColorVisibleOnBackground","rgbIntList","color","Number","baseColor","xmlns","render","circle","radius","fontSize","star","centerX","centerY","points","innerCirclePoints","innerRadius","getPointsToDrawStar","generateExample","sequenceLength","sequenceBasis","uniqueSymbols","symbols","repeat","floor","isCurrentUserCreatedThisPattern","patternName","user","firstName","lastName","first","getUserName","getShortName","translateSequence","ptoLinkages","startModification","endModification","firstPtoExist","mainSequence","AXOLABS_MAP","indexOfSymbol","BASE_RADIUS","BASE_DIAMETER","BASE_FONT_SIZE","PS_LINKAGE_COLOR","FONT_COLOR","MODIFICATIONS_COLOR","SS_LEFT_TEXT","AS_LEFT_TEXT","WIDTH_OF_LEFT_TEXT","WIDTH_OF_RIGHT_TEXT","X_OF_LEFT_MODIFICATIONS","Y","TITLE","SS_INDICES","SS_CIRCLES","SS_TEXTS","AS_CIRCLES","AS_TEXTS","AS_INDICES","comment","asExists","circlesInLegends","textLegend","svgHeight","drawAxolabsPattern","ssBases","asBases","ssPtoStatuses","asPtoStatuses","ss3Modification","ss5Modification","as3Modification","as5Modification","enumerateModifications","equidistantXForLegend","startFrom","uniqueBases","xOfBaseCircles","rightOverhangs","widthOfRightModification","resultingNumberOfNucleotidesInStrands","shiftToAlignNumberNearCircle","generalIndex","nucleotideIndex","reverse","ssRightOverhangs","asRightOverhangs","widthOfRightOverhangs","widthOfBases","widthOfLeftModification","isPtoExist","xOfSsRightModifications","xOfAsRightModifications","xOfRightTexts","numberOfSsNucleotides","nucleotideCounter","xOfNumbers","n","numberOfAsNucleotides","PatternLayoutHandler","htmlDivElement","updateModification","modificationItems","maxStrandLength","baseInputsObject","fullyPto","sequenceBase","strandLengthInput","updateSvgScheme","updateOutputExamples","baseChoices","isEnumerateModificationsDiv","boolV","alignItems","updateUiForNewSequenceLength","strandColumnInput","inputExample","onOK","onCancel","conditions","createAsStrand","outputExample","terminalModification","firstPto","svgDiv","saveAs","parsePatternAndUpdateUi","newName","pi","entities","modeMap","maxEl","maxCount","detectDefaultBasis","fields","field","terminal","close","postPatternToUserStorage","currUserName","friendlyName","getCurrentUserName","stringValue","updatePatternsList","lstMy","lstOthers","ent","loadPattern","currentUserName","patternListChoiceInput","currentList","maxWidth","marginLeft","setTooltip","loadPatternDiv","savePattern","getButton","hide","addButton","show","validateStrandColumn","colName","allLengthsAreTheSame","col","tableInput","getCol","columns","addNewInt","allColumnValuesOfEqualLength","firstSequence","validateIdsColumn","categories","toList","duplicates","getRawData","selection","defaultBase","newBasisValue","newPtoValue","captionLabel","textAlign","minWidth","toLowerCase","strandVar","inputs","flexGrow","lastChild","modificationSection","paddingTop","resize","asExampleDiv","asModificationDiv","asLengthDiv","tableList","table","tableName","view","columnNames","names","defaultColumn","log","replaceWith","idVar","idInput","inputIdColumn","hidden","savePatternButton","addOptions","convertSequenceButton","getString","columnName","nameOfNewColumn","contains","columnWithIds","byName","addNewString","addColumnWithIds","columnWithInputSequences","addColumnWithTranslatedSequences","downloadButton","getElementById","editPattern","gap","addCaption","padding","drawZoomedInMolecule","dialogDivStyle","atomCoordinates","clientHeight","molWidth","molHeight","hR","drawMolfileOnCanvas","MonomerLibViewer","grid","props","allowEdit","onCellDoubleClick","gridCell","cell","tableColumn","semType","AppUIBase","appName","parentAppName","currentView","addView","SimpleAppUIBase","setupView","initView","html","getHtml","box","windows","showProperties","showToolbox","showHelp","getView","CombinedAppUI","externalViewFactories","factories","getViewFactories","multiView","viewFactories","viewFactory","uiConstructor","translateUI","OligoTranslatorUI","OligoPatternUI","OligoStructureUI","getPath","tabs","currentPane","charAt","setUrl","onTabChanged","ExternalPluginUI","viewName","AppUIFactory","viewMonomerLibIcon","topPanel","setRibbonPanels","getHtmlElement","getHtmlDivElement","NOTATION","wu","CandidateType","alphabet","fasta","peptide","dna","rna","dt","simplified","PaletteType","palette","cp","objList","colour","ind","colourPalette","_palette","m","undefinedColor","Lesk","lesk","makePalette","GrokGroups","grokGroups","RasMol","rasMol","resM","aaSynonyms","Aminoacids","scheme","isInner","inner","chemPaletteInstance","getPalette","outerMonomer","innerMonomer","getInnerOuter","amino","AAFullNames","SemType","SemTypeMultipleAlignment","Names","AASmiles","AASmilesTruncated","Nucleotides","StringUtils","hash","UnknownSeqPalette","UnknownColorPalette","pI","hashCode","dgColor","g","distToBlack","pow","correctColor","buildPalette","Uint32Array","MmDistanceFunctionsNames","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","uhTemp","getMerMadeParameters","StPackage","_monomerLib","libHelper","funcList","package","prepare","call","getOutputParamValue","readLibrary","buildLayout","initSequenceTranslatorLibData","appUI","getUI","createAppLayout","oligoToolkitApp","externalPluginData","tabName","parameters","pluginName","div","pluginUI","getExternalAppViewFactories","oligoTranslatorApp","oligoPatternApp","oligoStructureApp","initMonomerLib","getCodeToWeightsMap","validateSequence","getMolfileFromGcrsSequence","linkStrands","demoTranslateSequence","demoOligoTranslatorUI","demoOligoPattern","emulateUserInput","idxUpdate","choiceInputs","len","selectElement","event","Event","dispatchEvent","demoOligoPatternUI","demoOligoStructure","textarea","setInputValue","demoOligoStructureUI","translateOligonucleotideSequence","SEQUENCE_COPIED_MSG","SEQ_TOOLTIP_MSG","DEFAULT_AXOLABS_INPUT","DG","grok","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","getter","__esModule","d","definition","o","defineProperty","enumerable","prop","prototype","Symbol","toStringTag","nc","__webpack_exports__"],"sourceRoot":""}