@datagrok/helm 2.1.19 → 2.1.21

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-test.js","mappings":"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","sources":["webpack://helm/webpack/bootstrap","webpack://helm/webpack/runtime/compat get default export","webpack://helm/webpack/runtime/define property getters","webpack://helm/webpack/runtime/hasOwnProperty shorthand","webpack://helm/webpack/runtime/make namespace object","webpack://helm/external var \"DG\"","webpack://helm/external var \"grok\"","webpack://helm/./node_modules/@datagrok-libraries/utils/src/test.js","webpack://helm/./src/utils.ts","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/consts.js","webpack://helm/./src/tests/helm-tests.ts","webpack://helm/external var \"wu\"","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/types.js","webpack://helm/./node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/seq-palettes.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/aminoacids.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/nucleotides.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/unknown.js","webpack://helm/./node_modules/fastest-levenshtein/esm/mod.js","webpack://helm/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/macromolecule-distance-functions.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/units-handler.js","webpack://helm/./src/tests/findMonomers-tests.ts","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/monomer-utils.js","webpack://helm/external var \"$\"","webpack://helm/./src/tests/renderers-tests.ts","webpack://helm/./src/package-test.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\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};","const __WEBPACK_NAMESPACE_OBJECT__ = DG;","const __WEBPACK_NAMESPACE_OBJECT__ = grok;","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';\nconst STANDART_TIMEOUT = 30000;\nconst BENCHMARK_TIMEOUT = 10800000;\nexport const tests = {};\nconst autoTestsCatName = 'Auto Tests';\nconst wasRegistered = {};\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 = STANDART_TIMEOUT);\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 = true, error) {\n if (error)\n error = `${error}, `;\n else\n error = '';\n if (actual !== expected)\n throw new Error(`${error}Expected \"${expected}\", got \"${actual}\"`);\n}\nexport function expectFloat(actual, expected, tolerance = 0.001, error) {\n if ((actual === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) ||\n (actual === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) ||\n (actual === Number.NaN && expected === Number.NaN) || (isNaN(actual) && isNaN(expected)))\n return;\n const areEqual = Math.abs(actual - expected) < tolerance;\n expect(areEqual, true, `${error !== null && error !== void 0 ? error : ''} (tolerance = ${tolerance})`);\n if (!areEqual)\n throw new Error(`Expected ${expected}, got ${actual} (tolerance = ${tolerance})`);\n}\nexport function expectTable(actual, expected, error) {\n const expectedRowCount = expected.rowCount;\n const actualRowCount = actual.rowCount;\n expect(actualRowCount, expectedRowCount, `${error !== null && error !== void 0 ? error : ''}, row count`);\n for (const column of expected.columns) {\n const actualColumn = actual.columns.byName(column.name);\n if (actualColumn == null)\n throw new Error(`Column ${column.name} not found`);\n if (actualColumn.type != column.type)\n throw new Error(`Column ${column.name} type expected ${column.type} got ${actualColumn.type}`);\n for (let i = 0; i < expectedRowCount; i++) {\n const value = column.get(i);\n const actualValue = actualColumn.get(i);\n if (column.type == DG.TYPE.FLOAT)\n expectFloat(actualValue, value, 0.0001, error);\n else if (column.type == DG.TYPE.DATE_TIME)\n expect(actualValue.isSame(value), true, error);\n else\n expect(actualValue, value, error);\n }\n }\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_, options) {\n var _a;\n currentCategory = category;\n tests_();\n if (tests[currentCategory]) {\n tests[currentCategory].clear = (_a = options === null || options === void 0 ? void 0 : options.clear) !== null && _a !== void 0 ? _a : true;\n tests[currentCategory].timeout = options === null || options === void 0 ? void 0 : options.timeout;\n }\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}\nfunction addNamespace(s, f) {\n return s.replace(new RegExp(f.name, 'gi'), f.nqName);\n}\nexport function initAutoTests(packageId, module) {\n return __awaiter(this, void 0, void 0, function* () {\n if (wasRegistered[packageId])\n return;\n const moduleTests = module ? module.tests : tests;\n if (moduleTests[autoTestsCatName] !== undefined ||\n Object.keys(moduleTests).find((c) => c.startsWith(autoTestsCatName))) {\n wasRegistered[packageId] = true;\n return;\n }\n const moduleAutoTests = [];\n const packFunctions = yield grok.dapi.functions.filter(`package.id = \"${packageId}\"`).list();\n const reg = new RegExp(/skip:\\s*([^,\\s]+)|wait:\\s*(\\d+)|cat:\\s*([^,\\s]+)/g);\n for (const f of packFunctions) {\n const tests = f.options['test'];\n if (!(tests && Array.isArray(tests) && tests.length))\n continue;\n for (let i = 0; i < tests.length; i++) {\n const res = tests[i].matchAll(reg);\n const map = {};\n Array.from(res).forEach((arr) => {\n if (arr[0].startsWith('skip'))\n map['skip'] = arr[1];\n else if (arr[0].startsWith('wait'))\n map['wait'] = parseInt(arr[2]);\n else if (arr[0].startsWith('cat'))\n map['cat'] = arr[3];\n });\n const test = new Test(autoTestsCatName, tests.length === 1 ? f.name : `${f.name} ${i + 1}`, () => __awaiter(this, void 0, void 0, function* () {\n const res = yield grok.functions.eval(addNamespace(tests[i], f));\n if (map.wait)\n yield delay(map.wait);\n // eslint-disable-next-line no-throw-literal\n if (typeof res === 'boolean' && !res)\n throw `Failed: ${tests[i]}, expected true, got ${res}`;\n }), { skipReason: map.skip });\n if (map.cat) {\n const cat = autoTestsCatName + ': ' + map.cat;\n test.category = cat;\n if (moduleTests[cat] === undefined)\n moduleTests[cat] = { tests: [], clear: true };\n moduleTests[cat].tests.push(test);\n }\n else {\n moduleAutoTests.push(test);\n }\n }\n }\n wasRegistered[packageId] = true;\n if (!moduleAutoTests.length)\n return;\n moduleTests[autoTestsCatName] = { tests: moduleAutoTests, clear: true };\n });\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 package_ = (_b = (_a = grok.functions.getCurrentCall()) === null || _a === void 0 ? void 0 : _a.func) === null || _b === void 0 ? void 0 : _b.package;\n yield initAutoTests(package_.id);\n const results = [];\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 if (value.clear) {\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, value.timeout, package_.name));\n grok.shell.closeAll();\n DG.Balloon.closeAll();\n }\n }\n else {\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, value.timeout, package_.name));\n }\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 // Clear after category\n // grok.shell.closeAll();\n // DG.Balloon.closeAll();\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: package_\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, categoryTimeout, packageName) {\n var _a, _b, _c, _d, _e;\n return __awaiter(this, void 0, void 0, function* () {\n let r;\n const filter = predicate != undefined && (t.name.toLowerCase() !== 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 }\n else {\n let timeout_ = ((_c = t.options) === null || _c === void 0 ? void 0 : _c.timeout) === STANDART_TIMEOUT &&\n categoryTimeout ? categoryTimeout : (_d = t.options) === null || _d === void 0 ? void 0 : _d.timeout;\n timeout_ = DG.Test.isInBenchmark && timeout_ === STANDART_TIMEOUT ? BENCHMARK_TIMEOUT : timeout_;\n r = { success: true, result: (_e = yield timeout(t.test, timeout_)) !== null && _e !== void 0 ? _e : 'OK', ms: 0, skipped: false };\n }\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 if (!filter) {\n let params = { 'success': r.success, 'result': r.result, 'ms': r.ms, 'skipped': r.skipped,\n 'type': 'package', packageName, 'category': t.category, 'test': t.name };\n if (r.result.constructor == Object) {\n const res = Object.keys(r.result).reduce((acc, k) => (Object.assign(Object.assign({}, acc), { ['result.' + k]: r.result[k] })), {});\n params = Object.assign(Object.assign({}, params), res);\n }\n grok.log.usage(`${packageName}: ${t.category}: ${t.name}`, params, `test-package ${packageName}: ${t.category}: ${t.name}`);\n }\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, interval = 50) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n clearInterval(intervalId);\n reject(new Error(error));\n }, wait);\n // @ts-ignore\n const intervalId = setInterval(() => {\n if (checkHandler()) {\n clearInterval(intervalId);\n resolve();\n }\n }, interval);\n });\n });\n}\nfunction timeout(func, testTimeout) {\n return __awaiter(this, void 0, void 0, function* () {\n let timeout = null;\n const timeoutPromise = new Promise((_, reject) => {\n //@ts-ignore\n timeout = setTimeout(() => {\n // eslint-disable-next-line prefer-promise-reject-errors\n reject('EXECUTION TIMEOUT');\n }, testTimeout);\n });\n try {\n return yield Promise.race([func(), timeoutPromise]);\n }\n finally {\n if (timeout)\n clearTimeout(timeout);\n }\n });\n}\nexport function isDialogPresent(dialogTitle) {\n const dialogs = DG.Dialog.getOpenDialogs();\n for (let i = 0; i < dialogs.length; i++) {\n if (dialogs[i].title == dialogTitle)\n return true;\n }\n return false;\n}\n/** Expects an asynchronous {@link action} to throw an exception. Use {@link check} to perform\n * deeper inspection of the exception if necessary.\n * @param {function(): Promise<void>} action\n * @param {function(any): boolean} check\n * @return {Promise<void>}\n */\nexport function expectExceptionAsync(action, check) {\n return __awaiter(this, void 0, void 0, function* () {\n let caught = false;\n let checked = false;\n try {\n yield action();\n }\n catch (e) {\n caught = true;\n checked = !check || check(e);\n }\n finally {\n if (!caught)\n throw new Error('An exception is expected but not thrown');\n if (!checked)\n throw new Error('An expected exception is thrown, but it does not satisfy the condition');\n }\n });\n}\n/**\n * Universal test for viewers. It search viewers in DOM by tags: canvas, svg, img, input, h1, a\n * @param {string} v Viewer name\n * @param {DG.DataFrame} df Dataframe to use. Should have at least 3 rows\n * @param {boolean} options.detectSemanticTypes Specify whether to detect semantic types or not\n * @param {boolean} options.readOnly If set to true, the dataframe will not be modified during the test\n * @param {object} options List of options (optional)\n * @return {Promise<void>} The test is considered successful if it completes without errors\n */\nexport function testViewer(v, df, options) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n if (options === null || options === void 0 ? void 0 : options.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 let 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 const tag = (_a = document.querySelector(selector)) === null || _a === void 0 ? void 0 : _a.tagName;\n res.push(Array.from(tv.viewers).length);\n if (!(options === null || options === void 0 ? void 0 : options.readOnly)) {\n Array.from(df.row(0).cells).forEach((c) => c.value = null);\n const num = df.rowCount < 20 ? Math.floor(df.rowCount / 2) : 10;\n df.rows.select((row) => row.idx >= 0 && row.idx < num);\n yield delay(50);\n for (let i = num; i < num * 2; i++)\n df.filter.set(i, false);\n yield delay(50);\n df.currentRowIdx = 1;\n const df1 = df.clone();\n df.columns.names().slice(0, Math.ceil(df.columns.length / 2)).forEach((c) => df.columns.remove(c));\n yield delay(100);\n tv.dataFrame = df1;\n }\n const optns = viewer.getOptions(true).look;\n const props = viewer.getProperties();\n const newProps = {};\n Object.keys(optns).filter((k) => typeof optns[k] === 'boolean').forEach((k) => newProps[k] = !optns[k]);\n props.filter((p) => p.choices !== null)\n .forEach((p) => newProps[p.name] = p.choices.find((c) => c !== optns[p.name]));\n viewer.setOptions(newProps);\n yield delay(300);\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 selector = `${viewerName} ${tag}`;\n yield awaitCheck(() => document.querySelector(selector) !== null, 'cannot load viewer from layout', 3000);\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 DG.Balloon.closeAll();\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBS3RDLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBQy9CLE1BQU0saUJBQWlCLEdBQUcsUUFBUSxDQUFDO0FBRW5DLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FLZCxFQUFFLENBQUM7QUFFUCxNQUFNLGdCQUFnQixHQUFHLFlBQVksQ0FBQztBQUN0QyxNQUFNLGFBQWEsR0FBNkIsRUFBRSxDQUFDO0FBQ25ELE1BQU0sQ0FBQyxJQUFJLGVBQXVCLENBQUM7QUFFbkMsTUFBTSxLQUFXLE1BQU0sQ0FLdEI7QUFMRCxXQUFpQixNQUFNO0lBQ3JCLFNBQWdCLE9BQU8sQ0FBQyxLQUFVLEVBQUUsSUFBYTtRQUMvQyxJQUFJLEtBQUssSUFBSSxJQUFJO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxjQUFjLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBSGUsY0FBTyxVQUd0QixDQUFBO0FBQ0gsQ0FBQyxFQUxnQixNQUFNLEtBQU4sTUFBTSxRQUt0QjtBQWFELE1BQU0sT0FBTyxXQUFXO0lBSXRCLFlBQVksY0FBd0IsRUFBRSxNQUFnQjtRQUh0RCxtQkFBYyxHQUFHLElBQUksQ0FBQztRQUN0QixXQUFNLEdBQUcsS0FBSyxDQUFDO1FBR2IsSUFBSSxjQUFjLEtBQUssU0FBUztZQUFFLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3ZFLElBQUksTUFBTSxLQUFLLFNBQVM7WUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUNqRCxDQUFDO0lBQUEsQ0FBQztDQUNI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bEMsTUFBTSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQzlELGdDQUFnQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUUsQ0FBQztZQUNyRSxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FDNUU7Z0JBQVM7WUFDUixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQixFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3ZCOztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IFRpbWVvdXQgPSBOb2RlSlMuVGltZW91dDtcbmltcG9ydCB7RGF0YUZyYW1lfSBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5jb25zdCBTVEFOREFSVF9USU1FT1VUID0gMzAwMDA7XG5jb25zdCBCRU5DSE1BUktfVElNRU9VVCA9IDEwODAwMDAwO1xuXG5leHBvcnQgY29uc3QgdGVzdHM6IHtcbiAgW2tleTogc3RyaW5nXToge1xuICAgIHRlc3RzPzogVGVzdFtdLCBiZWZvcmU/OiAoKSA9PiBQcm9taXNlPHZvaWQ+LCBhZnRlcj86ICgpID0+IFByb21pc2U8dm9pZD4sXG4gICAgYmVmb3JlU3RhdHVzPzogc3RyaW5nLCBhZnRlclN0YXR1cz86IHN0cmluZywgY2xlYXI/OiBib29sZWFuLCB0aW1lb3V0PzogbnVtYmVyXG4gIH1cbn0gPSB7fTtcblxuY29uc3QgYXV0b1Rlc3RzQ2F0TmFtZSA9ICdBdXRvIFRlc3RzJztcbmNvbnN0IHdhc1JlZ2lzdGVyZWQ6IHtba2V5OiBzdHJpbmddOiBib29sZWFufSA9IHt9O1xuZXhwb3J0IGxldCBjdXJyZW50Q2F0ZWdvcnk6IHN0cmluZztcblxuZXhwb3J0IG5hbWVzcGFjZSBhc3N1cmUge1xuICBleHBvcnQgZnVuY3Rpb24gbm90TnVsbCh2YWx1ZTogYW55LCBuYW1lPzogc3RyaW5nKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bmFtZSA9PSBudWxsID8gJ1ZhbHVlJyA6IG5hbWV9IG5vdCBkZWZpbmVkYCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0T3B0aW9ucyB7XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIHVuaGFuZGxlZEV4Y2VwdGlvblRpbWVvdXQ/OiBudW1iZXI7XG4gIHNraXBSZWFzb24/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2F0ZWdvcnlPcHRpb25zIHtcbiAgY2xlYXI/OiBib29sZWFuO1xuICB0aW1lb3V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgVGVzdENvbnRleHQge1xuICBjYXRjaFVuaGFuZGxlZCA9IHRydWU7XG4gIHJlcG9ydCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKGNhdGNoVW5oYW5kbGVkPzogYm9vbGVhbiwgcmVwb3J0PzogYm9vbGVhbikge1xuICAgIGlmIChjYXRjaFVuaGFuZGxlZCAhPT0gdW5kZWZpbmVkKSB0aGlzLmNhdGNoVW5oYW5kbGVkID0gY2F0Y2hVbmhhbmRsZWQ7XG4gICAgaWYgKHJlcG9ydCAhPT0gdW5kZWZpbmVkKSB0aGlzLnJlcG9ydCA9IHJlcG9ydDtcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3Qge1xuICB0ZXN0OiAoKSA9PiBQcm9taXNlPGFueT47XG4gIG5hbWU6IHN0cmluZztcbiAgY2F0ZWdvcnk6IHN0cmluZztcbiAgb3B0aW9ucz86IFRlc3RPcHRpb25zO1xuXG4gIGNvbnN0cnVjdG9yKGNhdGVnb3J5OiBzdHJpbmcsIG5hbWU6IHN0cmluZywgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+LCBvcHRpb25zPzogVGVzdE9wdGlvbnMpIHtcbiAgICB0aGlzLmNhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICBvcHRpb25zID8/PSB7fTtcbiAgICBvcHRpb25zLnRpbWVvdXQgPz89IFNUQU5EQVJUX1RJTUVPVVQ7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnRlc3QgPSBhc3luYyAoKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGxldCByZXN1bHQgPSAnJztcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXN1bHQgPSBhd2FpdCB0ZXN0KCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0RXZlbnQ8VD4oZXZlbnQ6IE9ic2VydmFibGU8VD4sXG4gIGhhbmRsZXI6IChhcmdzOiBUKSA9PiB2b2lkLCB0cmlnZ2VyOiAoKSA9PiB2b2lkLCBtczogbnVtYmVyID0gMCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGxldCBzdWI6IFN1YnNjcmlwdGlvbjtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzdWIgPSBldmVudC5zdWJzY3JpYmUoKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlcihhcmdzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICByZXNvbHZlKCdPSycpO1xuICAgIH0pO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KCd0aW1lb3V0Jyk7XG4gICAgfSwgbXMpO1xuICAgIHRyaWdnZXIoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0KG5hbWU6IHN0cmluZywgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+LCBvcHRpb25zPzogVGVzdE9wdGlvbnMpOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPSBbXTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS50ZXN0cyEucHVzaChuZXcgVGVzdChjdXJyZW50Q2F0ZWdvcnksIG5hbWUsIHRlc3QsIG9wdGlvbnMpKTtcbn1cblxuLyogVGVzdHMgdHdvIG9iamVjdHMgZm9yIGVxdWFsaXR5LCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZXkgYXJlIG5vdCBlcXVhbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3QoYWN0dWFsOiBhbnksIGV4cGVjdGVkOiBhbnkgPSB0cnVlLCBlcnJvcj86IHN0cmluZyk6IHZvaWQge1xuICBpZiAoZXJyb3IpXG4gICAgZXJyb3IgPSBgJHtlcnJvcn0sIGA7XG4gIGVsc2UgZXJyb3IgPSAnJztcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpXG4gICAgdGhyb3cgbmV3IEVycm9yKGAke2Vycm9yfUV4cGVjdGVkIFwiJHtleHBlY3RlZH1cIiwgZ290IFwiJHthY3R1YWx9XCJgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdEZsb2F0KGFjdHVhbDogbnVtYmVyLCBleHBlY3RlZDogbnVtYmVyLCB0b2xlcmFuY2UgPSAwLjAwMSwgZXJyb3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKChhY3R1YWwgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSAmJiBleHBlY3RlZCA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKSB8fFxuICAgICAgKGFjdHVhbCA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZICYmIGV4cGVjdGVkID09PSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpIHx8XG4gICAgICAoYWN0dWFsID09PSBOdW1iZXIuTmFOICYmIGV4cGVjdGVkID09PSBOdW1iZXIuTmFOKSB8fCAoaXNOYU4oYWN0dWFsKSAmJiBpc05hTihleHBlY3RlZCkpKVxuICAgIHJldHVybjtcbiAgY29uc3QgYXJlRXF1YWwgPSBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPCB0b2xlcmFuY2U7XG4gIGV4cGVjdChhcmVFcXVhbCwgdHJ1ZSwgYCR7ZXJyb3IgPz8gJyd9ICh0b2xlcmFuY2UgPSAke3RvbGVyYW5jZX0pYCk7XG4gIGlmICghYXJlRXF1YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSwgZ290ICR7YWN0dWFsfSAodG9sZXJhbmNlID0gJHt0b2xlcmFuY2V9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0VGFibGUoYWN0dWFsOiBEYXRhRnJhbWUsIGV4cGVjdGVkOiBEYXRhRnJhbWUsIGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGV4cGVjdGVkUm93Q291bnQgPSBleHBlY3RlZC5yb3dDb3VudDtcbiAgY29uc3QgYWN0dWFsUm93Q291bnQgPSBhY3R1YWwucm93Q291bnQ7XG4gIGV4cGVjdChhY3R1YWxSb3dDb3VudCwgZXhwZWN0ZWRSb3dDb3VudCwgYCR7ZXJyb3IgPz8gJyd9LCByb3cgY291bnRgKTtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBleHBlY3RlZC5jb2x1bW5zKSB7XG4gICAgY29uc3QgYWN0dWFsQ29sdW1uID0gYWN0dWFsLmNvbHVtbnMuYnlOYW1lKGNvbHVtbi5uYW1lKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSBub3QgZm91bmRgKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uLnR5cGUgIT0gY29sdW1uLnR5cGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSB0eXBlIGV4cGVjdGVkICR7Y29sdW1uLnR5cGV9IGdvdCAke2FjdHVhbENvbHVtbi50eXBlfWApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRSb3dDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbHVtbi5nZXQoaSk7XG4gICAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbENvbHVtbi5nZXQoaSk7XG4gICAgICBpZiAoY29sdW1uLnR5cGUgPT0gREcuVFlQRS5GTE9BVClcbiAgICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIHZhbHVlLCAwLjAwMDEsIGVycm9yKTtcbiAgICAgIGVsc2UgaWYgKGNvbHVtbi50eXBlID09IERHLlRZUEUuREFURV9USU1FKVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUuaXNTYW1lKHZhbHVlKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgZWxzZVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUsIHZhbHVlLCBlcnJvcik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RPYmplY3QoYWN0dWFsOiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBleHBlY3RlZDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkge1xuICBmb3IgKGNvbnN0IFtleHBlY3RlZEtleSwgZXhwZWN0ZWRWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFhY3R1YWwuaGFzT3duUHJvcGVydHkoZXhwZWN0ZWRLZXkpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBwcm9wZXJ0eSBcIiR7ZXhwZWN0ZWRLZXl9XCIgbm90IGZvdW5kYCk7XG5cbiAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbFtleHBlY3RlZEtleV07XG4gICAgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgZXhwZWN0QXJyYXkoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIGV4cGVjdGVkVmFsdWUgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgICBleHBlY3RPYmplY3QoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKE51bWJlci5pc0Zpbml0ZShhY3R1YWxWYWx1ZSkgJiYgTnVtYmVyLmlzRmluaXRlKGV4cGVjdGVkVmFsdWUpKVxuICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlICE9IGV4cGVjdGVkVmFsdWUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICgke2V4cGVjdGVkVmFsdWV9KSBmb3Iga2V5ICcke2V4cGVjdGVkS2V5fScsIGdvdCAoJHthY3R1YWxWYWx1ZX0pYCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdEFycmF5KGFjdHVhbDogQXJyYXlMaWtlPGFueT4sIGV4cGVjdGVkOiBBcnJheUxpa2U8YW55Pikge1xuICBjb25zdCBhY3R1YWxMZW5ndGggPSBhY3R1YWwubGVuZ3RoO1xuICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDtcblxuICBpZiAoYWN0dWFsTGVuZ3RoICE9IGV4cGVjdGVkTGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBcnJheXMgYXJlIG9mIGRpZmZlcmVudCBsZW5ndGg6IGFjdHVhbCBhcnJheSBsZW5ndGggaXMgJHthY3R1YWxMZW5ndGh9IGAgK1xuICAgICAgYGFuZCBleHBlY3RlZCBhcnJheSBsZW5ndGggaXMgJHtleHBlY3RlZExlbmd0aH1gKTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0dWFsTGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYWN0dWFsW2ldIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRbaV0gaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgIGV4cGVjdEFycmF5KGFjdHVhbFtpXSwgZXhwZWN0ZWRbaV0pO1xuICAgIGVsc2UgaWYgKGFjdHVhbFtpXSBpbnN0YW5jZW9mIE9iamVjdCAmJiBleHBlY3RlZFtpXSBpbnN0YW5jZW9mIE9iamVjdClcbiAgICAgIGV4cGVjdE9iamVjdChhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTtcbiAgICBlbHNlIGlmIChhY3R1YWxbaV0gIT0gZXhwZWN0ZWRbaV0pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7ZXhwZWN0ZWRbaV19IGF0IHBvc2l0aW9uICR7aX0sIGdvdCAke2FjdHVhbFtpXX1gKTtcbiAgfVxufVxuXG4vKiBEZWZpbmVzIGEgdGVzdCBzdWl0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYXRlZ29yeShjYXRlZ29yeTogc3RyaW5nLCB0ZXN0c186ICgpID0+IHZvaWQsIG9wdGlvbnM/OiBDYXRlZ29yeU9wdGlvbnMpOiB2b2lkIHtcbiAgY3VycmVudENhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gIHRlc3RzXygpO1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSkge1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0uY2xlYXIgPSBvcHRpb25zPy5jbGVhciA/PyB0cnVlO1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQ7XG4gIH1cbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSB0aGUgdGVzdHMgaW4gdGhpcyBjYXRlZ29yeSBhcmUgZXhlY3V0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYmVmb3JlKGJlZm9yZTogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmJlZm9yZSA9IGJlZm9yZTtcbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGFmdGVyIHRoZSB0ZXN0cyBpbiB0aGlzIGNhdGVnb3J5IGFyZSBleGVjdXRlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlcihhZnRlcjogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmFmdGVyID0gYWZ0ZXI7XG59XG5cbmZ1bmN0aW9uIGFkZE5hbWVzcGFjZShzOiBzdHJpbmcsIGY6IERHLkZ1bmMpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKG5ldyBSZWdFeHAoZi5uYW1lLCAnZ2knKSwgZi5ucU5hbWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5pdEF1dG9UZXN0cyhwYWNrYWdlSWQ6IHN0cmluZywgbW9kdWxlPzogYW55KSB7XG4gIGlmICh3YXNSZWdpc3RlcmVkW3BhY2thZ2VJZF0pIHJldHVybjtcbiAgY29uc3QgbW9kdWxlVGVzdHMgPSBtb2R1bGUgPyBtb2R1bGUudGVzdHMgOiB0ZXN0cztcbiAgaWYgKG1vZHVsZVRlc3RzW2F1dG9UZXN0c0NhdE5hbWVdICE9PSB1bmRlZmluZWQgfHxcbiAgICBPYmplY3Qua2V5cyhtb2R1bGVUZXN0cykuZmluZCgoYykgPT4gYy5zdGFydHNXaXRoKGF1dG9UZXN0c0NhdE5hbWUpKSkge1xuICAgIHdhc1JlZ2lzdGVyZWRbcGFja2FnZUlkXSA9IHRydWU7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IG1vZHVsZUF1dG9UZXN0cyA9IFtdO1xuICBjb25zdCBwYWNrRnVuY3Rpb25zID0gYXdhaXQgZ3Jvay5kYXBpLmZ1bmN0aW9ucy5maWx0ZXIoYHBhY2thZ2UuaWQgPSBcIiR7cGFja2FnZUlkfVwiYCkubGlzdCgpO1xuICBjb25zdCByZWcgPSBuZXcgUmVnRXhwKC9za2lwOlxccyooW14sXFxzXSspfHdhaXQ6XFxzKihcXGQrKXxjYXQ6XFxzKihbXixcXHNdKykvZyk7XG4gIGZvciAoY29uc3QgZiBvZiBwYWNrRnVuY3Rpb25zKSB7XG4gICAgY29uc3QgdGVzdHMgPSBmLm9wdGlvbnNbJ3Rlc3QnXTtcbiAgICBpZiAoISh0ZXN0cyAmJiBBcnJheS5pc0FycmF5KHRlc3RzKSAmJiB0ZXN0cy5sZW5ndGgpKSBjb250aW51ZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByZXMgPSAodGVzdHNbaV0gYXMgc3RyaW5nKS5tYXRjaEFsbChyZWcpO1xuICAgICAgY29uc3QgbWFwOiB7c2tpcD86IHN0cmluZywgd2FpdD86IG51bWJlciwgY2F0Pzogc3RyaW5nfSA9IHt9O1xuICAgICAgQXJyYXkuZnJvbShyZXMpLmZvckVhY2goKGFycikgPT4ge1xuICAgICAgICBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ3NraXAnKSkgbWFwWydza2lwJ10gPSBhcnJbMV07XG4gICAgICAgIGVsc2UgaWYgKGFyclswXS5zdGFydHNXaXRoKCd3YWl0JykpIG1hcFsnd2FpdCddID0gcGFyc2VJbnQoYXJyWzJdKTtcbiAgICAgICAgZWxzZSBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ2NhdCcpKSBtYXBbJ2NhdCddID0gYXJyWzNdO1xuICAgICAgfSk7XG4gICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoYXV0b1Rlc3RzQ2F0TmFtZSwgdGVzdHMubGVuZ3RoID09PSAxID8gZi5uYW1lIDogYCR7Zi5uYW1lfSAke2kgKyAxfWAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ3Jvay5mdW5jdGlvbnMuZXZhbChhZGROYW1lc3BhY2UodGVzdHNbaV0sIGYpKTtcbiAgICAgICAgaWYgKG1hcC53YWl0KSBhd2FpdCBkZWxheShtYXAud2FpdCk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gICAgICAgIGlmICh0eXBlb2YgcmVzID09PSAnYm9vbGVhbicgJiYgIXJlcykgdGhyb3cgYEZhaWxlZDogJHt0ZXN0c1tpXX0sIGV4cGVjdGVkIHRydWUsIGdvdCAke3Jlc31gO1xuICAgICAgfSwge3NraXBSZWFzb246IG1hcC5za2lwfSk7XG4gICAgICBpZiAobWFwLmNhdCkge1xuICAgICAgICBjb25zdCBjYXQ6IHN0cmluZyA9IGF1dG9UZXN0c0NhdE5hbWUgKyAnOiAnICsgbWFwLmNhdDtcbiAgICAgICAgdGVzdC5jYXRlZ29yeSA9IGNhdDtcbiAgICAgICAgaWYgKG1vZHVsZVRlc3RzW2NhdF0gPT09IHVuZGVmaW5lZClcbiAgICAgICAgICBtb2R1bGVUZXN0c1tjYXRdID0ge3Rlc3RzOiBbXSwgY2xlYXI6IHRydWV9O1xuICAgICAgICBtb2R1bGVUZXN0c1tjYXRdLnRlc3RzLnB1c2godGVzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtb2R1bGVBdXRvVGVzdHMucHVzaCh0ZXN0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgd2FzUmVnaXN0ZXJlZFtwYWNrYWdlSWRdID0gdHJ1ZTtcbiAgaWYgKCFtb2R1bGVBdXRvVGVzdHMubGVuZ3RoKSByZXR1cm47XG4gIG1vZHVsZVRlc3RzW2F1dG9UZXN0c0NhdE5hbWVdID0ge3Rlc3RzOiBtb2R1bGVBdXRvVGVzdHMsIGNsZWFyOiB0cnVlfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RzKG9wdGlvbnM/OiB7Y2F0ZWdvcnk/OiBzdHJpbmcsIHRlc3Q/OiBzdHJpbmcsIHRlc3RDb250ZXh0PzogVGVzdENvbnRleHR9KSB7XG4gIGNvbnN0IHBhY2thZ2VfID0gZ3Jvay5mdW5jdGlvbnMuZ2V0Q3VycmVudENhbGwoKT8uZnVuYz8ucGFja2FnZTtcbiAgYXdhaXQgaW5pdEF1dG9UZXN0cyhwYWNrYWdlXy5pZCk7XG4gIGNvbnN0IHJlc3VsdHM6IHsgY2F0ZWdvcnk/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIHN1Y2Nlc3M6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfVtdID0gW107XG4gIGNvbnNvbGUubG9nKGBSdW5uaW5nIHRlc3RzYCk7XG4gIG9wdGlvbnMgPz89IHt9O1xuICBvcHRpb25zIS50ZXN0Q29udGV4dCA/Pz0gbmV3IFRlc3RDb250ZXh0KCk7XG4gIGdyb2suc2hlbGwubGFzdEVycm9yID0gJyc7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRlc3RzKSkge1xuICAgIGlmIChvcHRpb25zPy5jYXRlZ29yeSAhPSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICgha2V5LnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChvcHRpb25zPy5jYXRlZ29yeS50b0xvd2VyQ2FzZSgpKSlcbiAgICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBTdGFydGVkICR7a2V5fSBjYXRlZ29yeWApO1xuICAgIHRyeSB7XG4gICAgICBpZiAodmFsdWUuYmVmb3JlKVxuICAgICAgICBhd2FpdCB2YWx1ZS5iZWZvcmUoKTtcbiAgICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICAgIHZhbHVlLmJlZm9yZVN0YXR1cyA9IHgudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgY29uc3QgdCA9IHZhbHVlLnRlc3RzID8/IFtdO1xuICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgIGlmICh2YWx1ZS5jbGVhcikge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlcy5wdXNoKGF3YWl0IGV4ZWNUZXN0KHRbaV0sIG9wdGlvbnM/LnRlc3QsIHZhbHVlLnRpbWVvdXQsIHBhY2thZ2VfLm5hbWUpKTtcbiAgICAgICAgZ3Jvay5zaGVsbC5jbG9zZUFsbCgpO1xuICAgICAgICBERy5CYWxsb29uLmNsb3NlQWxsKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdC5sZW5ndGg7IGkrKylcbiAgICAgICAgcmVzLnB1c2goYXdhaXQgZXhlY1Rlc3QodFtpXSwgb3B0aW9ucz8udGVzdCwgdmFsdWUudGltZW91dCwgcGFja2FnZV8ubmFtZSkpO1xuICAgIH1cbiAgICBjb25zdCBkYXRhID0gKGF3YWl0IFByb21pc2UuYWxsKHJlcykpLmZpbHRlcigoZCkgPT4gZC5yZXN1bHQgIT0gJ3NraXBwZWQnKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHZhbHVlLmFmdGVyKVxuICAgICAgICBhd2FpdCB2YWx1ZS5hZnRlcigpO1xuICAgIH0gY2F0Y2ggKHg6IGFueSkge1xuICAgICAgdmFsdWUuYWZ0ZXJTdGF0dXMgPSB4LnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIC8vIENsZWFyIGFmdGVyIGNhdGVnb3J5XG4gICAgLy8gZ3Jvay5zaGVsbC5jbG9zZUFsbCgpO1xuICAgIC8vIERHLkJhbGxvb24uY2xvc2VBbGwoKTtcbiAgICBpZiAodmFsdWUuYWZ0ZXJTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5hZnRlclN0YXR1cywgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZX0pO1xuICAgIGlmICh2YWx1ZS5iZWZvcmVTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5iZWZvcmVTdGF0dXMsIHN1Y2Nlc3M6IGZhbHNlLCBtczogMCwgc2tpcHBlZDogZmFsc2V9KTtcbiAgICByZXN1bHRzLnB1c2goLi4uZGF0YSk7XG4gIH1cbiAgaWYgKG9wdGlvbnMudGVzdENvbnRleHQuY2F0Y2hVbmhhbmRsZWQpIHtcbiAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICBpZiAoZ3Jvay5zaGVsbC5sYXN0RXJyb3IubGVuZ3RoID4gMCkge1xuICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdVbmhhbmRsZWQgZXhjZXB0aW9ucycsXG4gICAgICAgIG5hbWU6ICdleGNlcHRpb25zJyxcbiAgICAgICAgcmVzdWx0OiBncm9rLnNoZWxsLmxhc3RFcnJvciwgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGlmIChvcHRpb25zLnRlc3RDb250ZXh0LnJlcG9ydCkge1xuICAgIGNvbnN0IGxvZ2dlciA9IG5ldyBERy5Mb2dnZXIoKTtcbiAgICBjb25zdCBzdWNjZXNzZnVsID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+IHIuc3VjY2VzcykubGVuZ3RoO1xuICAgIGNvbnN0IHNraXBwZWQgPSByZXN1bHRzLmZpbHRlcigocikgPT4gci5za2lwcGVkKS5sZW5ndGg7XG4gICAgY29uc3QgZmFpbGVkID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+ICFyLnN1Y2Nlc3MpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJ1BhY2thZ2UgQHBhY2thZ2UgdGVzdGVkOiBAc3VjY2Vzc2Z1bCBzdWNjZXNzZnVsLCBAc2tpcHBlZCBza2lwcGVkLCBAZmFpbGVkIGZhaWxlZCB0ZXN0cyc7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgc3VjY2Vzc2Z1bDogc3VjY2Vzc2Z1bCxcbiAgICAgIHNraXBwZWQ6IHNraXBwZWQsXG4gICAgICBmYWlsZWQ6IGZhaWxlZC5sZW5ndGgsXG4gICAgICBwYWNrYWdlOiBwYWNrYWdlX1xuICAgIH07XG4gICAgZm9yIChjb25zdCByIG9mIGZhaWxlZCkgT2JqZWN0LmFzc2lnbihwYXJhbXMsIHtbYCR7ci5jYXRlZ29yeX0gfCAke3IubmFtZX1gXTogci5yZXN1bHR9KTtcbiAgICBsb2dnZXIubG9nKGRlc2NyaXB0aW9uLCBwYXJhbXMsICdwYWNrYWdlLXRlc3RlZCcpO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjVGVzdCh0OiBUZXN0LCBwcmVkaWNhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgY2F0ZWdvcnlUaW1lb3V0PzogbnVtYmVyLCBwYWNrYWdlTmFtZT86IHN0cmluZykge1xuICBsZXQgcjogeyBjYXRlZ29yeT86IHN0cmluZywgbmFtZT86IHN0cmluZywgc3VjY2VzczogYm9vbGVhbiwgcmVzdWx0OiBhbnksIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfTtcbiAgY29uc3QgZmlsdGVyID0gcHJlZGljYXRlICE9IHVuZGVmaW5lZCAmJiAodC5uYW1lLnRvTG93ZXJDYXNlKCkgIT09IHByZWRpY2F0ZS50b0xvd2VyQ2FzZSgpKTtcbiAgY29uc3Qgc2tpcCA9IHQub3B0aW9ucz8uc2tpcFJlYXNvbiB8fCBmaWx0ZXI7XG4gIGNvbnN0IHNraXBSZWFzb24gPSBmaWx0ZXIgPyAnc2tpcHBlZCcgOiB0Lm9wdGlvbnM/LnNraXBSZWFzb247XG4gIGlmICghc2tpcClcbiAgICBjb25zb2xlLmxvZyhgU3RhcnRlZCAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfWApO1xuICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKCk7XG4gIHRyeSB7XG4gICAgaWYgKHNraXApIHtcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBza2lwUmVhc29uISwgbXM6IDAsIHNraXBwZWQ6IHRydWV9O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdGltZW91dF8gPSB0Lm9wdGlvbnM/LnRpbWVvdXQgPT09IFNUQU5EQVJUX1RJTUVPVVQgJiZcbiAgICAgICAgY2F0ZWdvcnlUaW1lb3V0ID8gY2F0ZWdvcnlUaW1lb3V0IDogdC5vcHRpb25zPy50aW1lb3V0ITtcbiAgICAgIHRpbWVvdXRfID0gREcuVGVzdC5pc0luQmVuY2htYXJrICYmIHRpbWVvdXRfID09PSBTVEFOREFSVF9USU1FT1VUID8gQkVOQ0hNQVJLX1RJTUVPVVQgOiB0aW1lb3V0XztcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBhd2FpdCB0aW1lb3V0KHQudGVzdCwgdGltZW91dF8pID8/ICdPSycsIG1zOiAwLCBza2lwcGVkOiBmYWxzZX07XG4gICAgfVxuICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICByID0ge3N1Y2Nlc3M6IGZhbHNlLCByZXN1bHQ6IHgudG9TdHJpbmcoKSwgbXM6IDAsIHNraXBwZWQ6IGZhbHNlfTtcbiAgfVxuICBjb25zdCBzdG9wID0gbmV3IERhdGUoKTtcbiAgLy8gQHRzLWlnbm9yZVxuICByLm1zID0gc3RvcCAtIHN0YXJ0O1xuICBpZiAoIXNraXApXG4gICAgY29uc29sZS5sb2coYEZpbmlzaGVkICR7dC5jYXRlZ29yeX0gJHt0Lm5hbWV9IGZvciAke3IubXN9IG1zYCk7XG4gIHIuY2F0ZWdvcnkgPSB0LmNhdGVnb3J5O1xuICByLm5hbWUgPSB0Lm5hbWU7XG4gIGlmICghZmlsdGVyKSB7XG4gICAgbGV0IHBhcmFtcyA9IHsnc3VjY2Vzcyc6IHIuc3VjY2VzcywgJ3Jlc3VsdCc6IHIucmVzdWx0LCAnbXMnOiByLm1zLCAnc2tpcHBlZCc6IHIuc2tpcHBlZCxcbiAgICAgICd0eXBlJzogJ3BhY2thZ2UnLCBwYWNrYWdlTmFtZSwgJ2NhdGVnb3J5JzogdC5jYXRlZ29yeSwgJ3Rlc3QnOiB0Lm5hbWV9O1xuICAgIGlmIChyLnJlc3VsdC5jb25zdHJ1Y3RvciA9PSBPYmplY3QpIHtcbiAgICAgIGNvbnN0IHJlcyA9IE9iamVjdC5rZXlzKHIucmVzdWx0KS5yZWR1Y2UoKGFjYywgaykgPT4gKHsuLi5hY2MsIFsncmVzdWx0LicgKyBrXTogci5yZXN1bHRba119KSwge30pO1xuICAgICAgcGFyYW1zID0gey4uLnBhcmFtcywgLi4ucmVzfTtcbiAgICB9XG4gICAgZ3Jvay5sb2cudXNhZ2UoYCR7cGFja2FnZU5hbWV9OiAke3QuY2F0ZWdvcnl9OiAke3QubmFtZX1gLFxuICAgICAgcGFyYW1zLCBgdGVzdC1wYWNrYWdlICR7cGFja2FnZU5hbWV9OiAke3QuY2F0ZWdvcnl9OiAke3QubmFtZX1gKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLyogV2FpdHMgW21zXSBtaWxsaXNlY29uZHMgKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxheShtczogbnVtYmVyKSB7XG4gIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIG1zKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhd2FpdENoZWNrKGNoZWNrSGFuZGxlcjogKCkgPT4gYm9vbGVhbixcbiAgZXJyb3I6IHN0cmluZyA9ICdUaW1lb3V0IGV4Y2VlZGVkJywgd2FpdDogbnVtYmVyID0gNTAwLCBpbnRlcnZhbDogbnVtYmVyID0gNTApOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGVycm9yKSk7XG4gICAgfSwgd2FpdCk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGludGVydmFsSWQ6IFRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAoY2hlY2tIYW5kbGVyKCkpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0sIGludGVydmFsKTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRpbWVvdXQoZnVuYzogKCkgPT4gUHJvbWlzZTxhbnk+LCB0ZXN0VGltZW91dDogbnVtYmVyKTogUHJvbWlzZTxhbnk+IHtcbiAgbGV0IHRpbWVvdXQ6IFRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZTxhbnk+KChfLCByZWplY3QpID0+IHtcbiAgICAvL0B0cy1pZ25vcmVcbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KCdFWEVDVVRJT04gVElNRU9VVCcpO1xuICAgIH0sIHRlc3RUaW1lb3V0KTtcbiAgfSk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IFByb21pc2UucmFjZShbZnVuYygpLCB0aW1lb3V0UHJvbWlzZV0pO1xuICB9IGZpbmFsbHkge1xuICAgIGlmICh0aW1lb3V0KVxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RpYWxvZ1ByZXNlbnQoZGlhbG9nVGl0bGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBkaWFsb2dzID0gREcuRGlhbG9nLmdldE9wZW5EaWFsb2dzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGlhbG9ncy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChkaWFsb2dzW2ldLnRpdGxlID09IGRpYWxvZ1RpdGxlKVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogRXhwZWN0cyBhbiBhc3luY2hyb25vdXMge0BsaW5rIGFjdGlvbn0gdG8gdGhyb3cgYW4gZXhjZXB0aW9uLiBVc2Uge0BsaW5rIGNoZWNrfSB0byBwZXJmb3JtXG4gKiBkZWVwZXIgaW5zcGVjdGlvbiBvZiB0aGUgZXhjZXB0aW9uIGlmIG5lY2Vzc2FyeS5cbiAqIEBwYXJhbSAge2Z1bmN0aW9uKCk6IFByb21pc2U8dm9pZD59IGFjdGlvblxuICogQHBhcmFtICB7ZnVuY3Rpb24oYW55KTogYm9vbGVhbn0gY2hlY2tcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHBlY3RFeGNlcHRpb25Bc3luYyhhY3Rpb246ICgpID0+IFByb21pc2U8dm9pZD4sXG4gIGNoZWNrPzogKGV4Y2VwdGlvbjogYW55KSA9PiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGxldCBjYXVnaHQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgbGV0IGNoZWNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBhY3Rpb24oKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNhdWdodCA9IHRydWU7XG4gICAgY2hlY2tlZCA9ICFjaGVjayB8fCBjaGVjayhlKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoIWNhdWdodClcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gZXhjZXB0aW9uIGlzIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duJyk7XG4gICAgaWYgKCFjaGVja2VkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBbiBleHBlY3RlZCBleGNlcHRpb24gaXMgdGhyb3duLCBidXQgaXQgZG9lcyBub3Qgc2F0aXNmeSB0aGUgY29uZGl0aW9uJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBVbml2ZXJzYWwgdGVzdCBmb3Igdmlld2Vycy4gSXQgc2VhcmNoIHZpZXdlcnMgaW4gRE9NIGJ5IHRhZ3M6IGNhbnZhcywgc3ZnLCBpbWcsIGlucHV0LCBoMSwgYVxuICogQHBhcmFtICB7c3RyaW5nfSB2IFZpZXdlciBuYW1lXG4gKiBAcGFyYW0gIHtERy5EYXRhRnJhbWV9IGRmIERhdGFmcmFtZSB0byB1c2UuIFNob3VsZCBoYXZlIGF0IGxlYXN0IDMgcm93c1xuICogQHBhcmFtICB7Ym9vbGVhbn0gb3B0aW9ucy5kZXRlY3RTZW1hbnRpY1R5cGVzIFNwZWNpZnkgd2hldGhlciB0byBkZXRlY3Qgc2VtYW50aWMgdHlwZXMgb3Igbm90XG4gKiBAcGFyYW0gIHtib29sZWFufSBvcHRpb25zLnJlYWRPbmx5IElmIHNldCB0byB0cnVlLCB0aGUgZGF0YWZyYW1lIHdpbGwgbm90IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgdGVzdFxuICogQHBhcmFtICB7b2JqZWN0fSBvcHRpb25zIExpc3Qgb2Ygb3B0aW9ucyAob3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBUaGUgdGVzdCBpcyBjb25zaWRlcmVkIHN1Y2Nlc3NmdWwgaWYgaXQgY29tcGxldGVzIHdpdGhvdXQgZXJyb3JzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0Vmlld2VyKHY6IHN0cmluZywgZGY6IERHLkRhdGFGcmFtZSxcbiAgb3B0aW9ucz86IHtkZXRlY3RTZW1hbnRpY1R5cGVzPzogYm9vbGVhbiwgcmVhZE9ubHk/OiBib29sZWFufSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAob3B0aW9ucz8uZGV0ZWN0U2VtYW50aWNUeXBlcykgYXdhaXQgZ3Jvay5kYXRhLmRldGVjdFNlbWFudGljVHlwZXMoZGYpO1xuICBjb25zdCB0diA9IGdyb2suc2hlbGwuYWRkVGFibGVWaWV3KGRmKTtcbiAgY29uc3Qgdmlld2VyTmFtZSA9IGBbbmFtZT12aWV3ZXItJHt2LnJlcGxhY2UoL1xccysvZywgJy0nKX0gaV1gO1xuICBsZXQgc2VsZWN0b3IgPSBgJHt2aWV3ZXJOYW1lfSBjYW52YXMsJHt2aWV3ZXJOYW1lfSBzdmcsJHt2aWV3ZXJOYW1lfSBpbWcsXG4gICAgJHt2aWV3ZXJOYW1lfSBpbnB1dCwke3ZpZXdlck5hbWV9IGgxLCR7dmlld2VyTmFtZX0gYWA7XG4gIGNvbnN0IHJlcyA9IFtdO1xuICB0cnkge1xuICAgIGxldCB2aWV3ZXIgPSB0di5hZGRWaWV3ZXIodik7XG4gICAgYXdhaXQgYXdhaXRDaGVjaygoKSA9PiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSAhPT0gbnVsbCxcbiAgICAgICdjYW5ub3QgbG9hZCB2aWV3ZXInLCAzMDAwKTtcbiAgICBjb25zdCB0YWcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKT8udGFnTmFtZTtcbiAgICByZXMucHVzaChBcnJheS5mcm9tKHR2LnZpZXdlcnMpLmxlbmd0aCk7XG4gICAgaWYgKCFvcHRpb25zPy5yZWFkT25seSkge1xuICAgICAgQXJyYXkuZnJvbShkZi5yb3coMCkuY2VsbHMpLmZvckVhY2goKGM6YW55KSA9PiBjLnZhbHVlID0gbnVsbCk7XG4gICAgICBjb25zdCBudW0gPSBkZi5yb3dDb3VudCA8IDIwID8gTWF0aC5mbG9vcihkZi5yb3dDb3VudCAvIDIpIDogMTA7XG4gICAgICBkZi5yb3dzLnNlbGVjdCgocm93OiBERy5Sb3cpID0+IHJvdy5pZHggPj0gMCAmJiByb3cuaWR4IDwgbnVtKTtcbiAgICAgIGF3YWl0IGRlbGF5KDUwKTtcbiAgICAgIGZvciAobGV0IGkgPSBudW07IGkgPCBudW0gKiAyOyBpKyspIGRmLmZpbHRlci5zZXQoaSwgZmFsc2UpO1xuICAgICAgYXdhaXQgZGVsYXkoNTApO1xuICAgICAgZGYuY3VycmVudFJvd0lkeCA9IDE7XG4gICAgICBjb25zdCBkZjEgPSBkZi5jbG9uZSgpO1xuICAgICAgZGYuY29sdW1ucy5uYW1lcygpLnNsaWNlKDAsIE1hdGguY2VpbChkZi5jb2x1bW5zLmxlbmd0aCAvIDIpKS5mb3JFYWNoKChjOiBhbnkpID0+IGRmLmNvbHVtbnMucmVtb3ZlKGMpKTtcbiAgICAgIGF3YWl0IGRlbGF5KDEwMCk7XG4gICAgICB0di5kYXRhRnJhbWUgPSBkZjE7XG4gICAgfVxuICAgIGNvbnN0IG9wdG5zID0gdmlld2VyLmdldE9wdGlvbnModHJ1ZSkubG9vaztcbiAgICBjb25zdCBwcm9wcyA9IHZpZXdlci5nZXRQcm9wZXJ0aWVzKCk7XG4gICAgY29uc3QgbmV3UHJvcHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IGJvb2xlYW4+ID0ge307XG4gICAgT2JqZWN0LmtleXMob3B0bnMpLmZpbHRlcigoaykgPT4gdHlwZW9mIG9wdG5zW2tdID09PSAnYm9vbGVhbicpLmZvckVhY2goKGspID0+IG5ld1Byb3BzW2tdID0gIW9wdG5zW2tdKTtcbiAgICBwcm9wcy5maWx0ZXIoKHA6IERHLlByb3BlcnR5KSA9PiBwLmNob2ljZXMgIT09IG51bGwpXG4gICAgICAuZm9yRWFjaCgocDogREcuUHJvcGVydHkpID0+IG5ld1Byb3BzW3AubmFtZV0gPSBwLmNob2ljZXMuZmluZCgoYzogYW55KSA9PiBjICE9PSBvcHRuc1twLm5hbWVdKSEpO1xuICAgIHZpZXdlci5zZXRPcHRpb25zKG5ld1Byb3BzKTtcbiAgICBhd2FpdCBkZWxheSgzMDApO1xuICAgIGNvbnN0IGxheW91dCA9IHR2LnNhdmVMYXlvdXQoKTtcbiAgICBjb25zdCBvbGRQcm9wcyA9IHZpZXdlci5nZXRPcHRpb25zKCkubG9vaztcbiAgICB0di5yZXNldExheW91dCgpO1xuICAgIHJlcy5wdXNoKEFycmF5LmZyb20odHYudmlld2VycykubGVuZ3RoKTtcbiAgICB0di5sb2FkTGF5b3V0KGxheW91dCk7XG4gICAgc2VsZWN0b3IgPSBgJHt2aWV3ZXJOYW1lfSAke3RhZ31gO1xuICAgIGF3YWl0IGF3YWl0Q2hlY2soKCkgPT4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikgIT09IG51bGwsXG4gICAgICAnY2Fubm90IGxvYWQgdmlld2VyIGZyb20gbGF5b3V0JywgMzAwMCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIHZpZXdlciA9IEFycmF5LmZyb20odHYudmlld2VycykuZmluZCgodjogYW55KSA9PiB2LnR5cGUgIT09ICdHcmlkJykhO1xuICAgIGV4cGVjdEFycmF5KHJlcywgWzIsIDEsIDJdKTtcbiAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkodmlld2VyLmdldE9wdGlvbnMoKS5sb29rKSwgSlNPTi5zdHJpbmdpZnkob2xkUHJvcHMpKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB0di5jbG9zZSgpO1xuICAgIGdyb2suc2hlbGwuY2xvc2VUYWJsZShkZik7XG4gICAgREcuQmFsbG9vbi5jbG9zZUFsbCgpO1xuICB9XG59XG4iXX0=","import * as DG from 'datagrok-api/dg';\nimport {\n RGROUP_CAP_GROUP_NAME,\n RGROUP_CAP_GROUP_SMILES,\n jsonSdfMonomerLibDict,\n MONOMER_SYMBOL,\n RGROUP_ALTER_ID,\n RGROUPS,\n RGROUP_LABEL,\n SDF_MONOMER_NAME\n} from './constants';\n\nexport function getParts(subParts: string[], s: string): string[] {\n const j = 0;\n const allParts: string[] = [];\n for (let k = 0; k < subParts.length; ++k) {\n const indexOfMonomer = s.indexOf(subParts[k]);\n const helmBeforeMonomer = s.slice(j, indexOfMonomer);\n allParts.push(helmBeforeMonomer);\n allParts.push(subParts[k]);\n s = s.substring(indexOfMonomer + subParts[k].length);\n }\n allParts.push(s);\n return allParts;\n}\n\nexport function parseHelm(s: string): string[] {\n const sections = split(s, '$');\n s = sections[0];\n const monomers = [];\n //@ts-ignore\n if (!scil.Utils.isNullOrEmpty(s)) {\n const seqs = split(s, '|');\n for (let i = 0; i < seqs.length; ++i) {\n const e = detachAnnotation(seqs[i]);\n s = e.str;\n\n let p = s.indexOf('{');\n\n s = s.substring(p + 1);\n p = s.indexOf('}');\n s = s.substring(0, p);\n\n const ss = split(s, '.');\n for (const monomer of ss) {\n if (!monomer || monomer === '') continue;\n if (monomer.startsWith('[') && monomer.includes(']')) {\n const element = monomer.substring(1, monomer.indexOf(']'));\n monomers.push(element);\n const residue = monomer.substring(monomer.indexOf(']') + 1);\n ss.push(residue);\n } else if (monomer.includes('[') && monomer.endsWith(']')) {\n const element = monomer.substring(monomer.lastIndexOf('[') + 1, monomer.length - 1);\n monomers.push(element);\n const residue = monomer.substring(0, monomer.lastIndexOf('['));\n ss.push(residue);\n } else if (monomer.includes('(') && monomer.includes(')')) {\n // here we only want to split the string at first '(' and last ')'\n // because entries like [L-hArg(Et,Et)]([L-hArg(Et,Et)]) where L-hArg(Et,Et) is a single monomer\n const firstPiece = monomer.substring(0, monomer.indexOf('('));\n const thirdPiece = monomer.substring(monomer.lastIndexOf(')') + 1);\n const secondPiece = monomer.substring(firstPiece.length + 1, monomer.length - thirdPiece.length - 1);\n const elements = [firstPiece, secondPiece, thirdPiece];\n for (const el of elements)\n ss.push(el);\n } else {\n monomers.push(monomer);\n }\n }\n }\n }\n return monomers;\n}\n\n// /** Find monomers missed in Helm monomer library configured and\n// * used in org.helm.webeditor / scil.helm.Monomers / org.helm.webeditor.Monomers .\n// */\n// export function findMonomers(helmString: string) {\n// //@ts-ignore\n// const types: string[] = Object.keys(org.helm.webeditor.monomerTypeList());\n// const monomerNameList: any[] = [];\n// const monomerNameI: number = 0;\n// const weMonomers = org.helm.webeditor.Monomers;\n// for (let typeI = 0; typeI < types.length; typeI++) {\n// //@ts-ignore\n// const ofTypeMonomers: {} = weMonomers.getMonomerSet(types[typeI]) ?? {};\n// Object.keys(ofTypeMonomers).forEach((key) => {\n// const monomer: any = ofTypeMonomers[key];\n// monomerNameList[monomerNameI] = monomer.id;\n// monomerNameI += 1;\n// });\n// }\n// const helmPartList = parseHelm(helmString);\n// return new Set(helmPartList.filter((val) => !monomerNameList.includes(val)));\n// }\n\n/** Searches monomers of helmString for missed. */\nexport function findMonomers(monomerSymbolList: string[]): Set<string> {\n const types = Object.keys(org.helm.webeditor.monomerTypeList());\n const monomers: any = [];\n const monomerNames: any = [];\n for (let i = 0; i < types.length; i++) {\n //@ts-ignore\n // eslint-disable-next-line new-cap\n monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));\n Object.keys(monomers[i]).forEach((k) => {\n monomerNames.push(monomers[i][k].id);\n });\n }\n return new Set(monomerSymbolList.filter((val) => !monomerNames.includes(val)));\n}\n\nfunction split(s: string, sep: string) {\n const ret = [];\n let frag = '';\n let parentheses = 0;\n let bracket = 0;\n let braces = 0;\n let quote = 0;\n for (let i = 0; i < s.length; ++i) {\n let c = s.substring(i, i + 1);\n if (c == sep && bracket == 0 && parentheses == 0 && braces == 0 && quote == 0) {\n ret.push(frag);\n frag = '';\n } else {\n frag += c;\n if (quote > 0) {\n if (c == '\\\\' && i + 1 < s.length) {\n ++i;\n const c2 = s.substring(i, i + 1);\n frag += c2;\n c += c2;\n }\n }\n if (c == '\\\"') {\n if (!(i > 0 && s.substring(i - 1, i) == '\\\\'))\n quote = quote == 0 ? 1 : 0;\n } else if (c == '[') {\n ++bracket;\n } else if (c == ']') {\n --bracket;\n } else if (c == '(') {\n ++parentheses;\n } else if (c == ')') {\n --parentheses;\n } else if (c == '{') {\n ++braces;\n } else if (c == '}') {\n --braces;\n }\n }\n }\n ret.push(frag);\n return ret;\n}\n\nfunction detachAnnotation(s: string) {\n const ret = _detachAppendix(s, '\\\"');\n if (ret.tag != null)\n return ret;\n\n const r = _detachAppendix(s, '\\'');\n return {tag: ret.tag, repeat: r.tag, str: r.str};\n}\n\nfunction _detachAppendix(s: string, c: string) {\n let tag = null;\n //@ts-ignore\n if (scil.Utils.endswith(s, c)) {\n let p = s.length - 1;\n while (p > 0) {\n p = s.lastIndexOf(c, p - 1);\n if (p <= 0 || s.substring(p - 1, p) != '\\\\')\n break;\n }\n\n if (p > 0 && p < s.length - 1) {\n tag = s.substring(p + 1, s.length - 1);\n s = s.substring(0, p);\n }\n }\n if (tag != null)\n tag = unescape(tag.replace(new RegExp('\\\\' + c, 'g'), c));\n return {tag: tag, str: s};\n}\n\nfunction unescape(s: string) {\n //@ts-ignore\n if (scil.Utils.isNullOrEmpty(s))\n return s;\n\n return s.replace(/[\\\\]./g, function(m) {\n switch (m) {\n case '\\\\r':\n return '\\r';\n case '\\\\n':\n return '\\n';\n case '\\\\t':\n return '\\t';\n default:\n return m.substring(1);\n }\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","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {after, before, category, delay, expect, test, expectArray} from '@datagrok-libraries/utils/src/test';\n//import {findMonomers, helmToFasta, helmToPeptide, helmToRNA, initHelm} from '../package';\nimport {parseHelm} from '../utils';\n\nimport {_package} from '../package-test';\n\ncategory('Helm', () => {\n //These tests require webservice that is not present on test stand\n // test('helmToFasta', async () => {\n // expect(await helmToFasta('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), '>RNA1UTGCA');\n // expect(await helmToFasta('RNA1{P.R(U).P.R(T)}$$$$'), '>RNA1UT');\n // expect(await helmToFasta('PEPTIDE1{A.G}$$$$V2.0'), '>PEPTIDE1AG');\n // });\n //\n // test('helmToRNA', async () => {\n // expect(await helmToRNA('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), 'UTGCA');\n // expect(await helmToRNA('RNA1{P.R(U).P.R(T)}$$$$'), 'UT');\n // // eslint-disable-next-line max-len\n // expect(\n // await helmToRNA('RNA1{R(U)P.R(T)P}|RNA2{P.R(A)P.R(A)}$RNA1,RNA2,2:pair-6:pair|RNA1,RNA2,5:pair-3:pair$$$'), 'UT AA'\n // );\n // });\n //\n // test('helmToPeptide', async () => {\n // expect(await helmToPeptide('PEPTIDE1{A.G}$$$$V2.0'), 'AG');\n // expect(await helmToPeptide('PEPTIDE1{L.V.A}|PEPTIDE2{L.V.A}$$$$'), 'LVA LVA');\n // // eslint-disable-next-line max-len\n // expect(await helmToPeptide('PEPTIDE1{A.R.C.A.A.K.T.C.D.A}$PEPTIDE1,PEPTIDE1,8:R3-3:R3$$$'), 'ARCAAKTCDA');\n // });\n\n // detectMacromolecule is a function of Bio package\n // test('detectMacromolecule', async () => {\n // const file = await _package.files.readAsText('tests/test.csv');\n // const df = DG.DataFrame.fromCsv(file);\n // const col = df.columns.byName('HELM string');\n // await grok.data.detectSemanticTypes(df);\n // expect(col.semType, DG.SEMTYPE.MACROMOLECULE);\n // });\n\n // semType and units tags are detecting by Bio package function detectMacromolecule\n // test('detectHelm', async () => {\n // const file = await _package.files.readAsText('tests/test.csv');\n // const df = DG.DataFrame.fromCsv(file);\n // const col = df.columns.byName('HELM string');\n // await grok.data.detectSemanticTypes(df);\n // expect(col.tags[DG.TAGS.UNITS], 'HELM');\n // });\n\n const complexMonomers = [\n // tests parsing of complex monomemer in square brackets like [L-hArg(Et,Et)]\n 'PEPTIDE1{[L-hArg(Et,Et)].E.F.G}|PEPTIDE2{C.E}$PEPTIDE1,PEPTIDE2,2:R3-1:R1$$$V2.0',\n // tests parsing of complex monomer and one as a side chain as well\n 'PEPTIDE1{[L-hArg(Et,Et)]([L-hArg(Et,Et)]).E.F.G}$$$$',\n // tests parsing of complex monomer and one as a side chain as well\n 'RNA1{[dhp]([m1A])p.r(T)p.r(T)p.r(G)p}$$$$V2.0',\n // tests complex monomer as side chain\n 'RNA1{r([mo6pur])p.r(T)p.r(T)p.r(G)p}$$$$V2.0',\n // test complex monomer, side chain and linker\n 'RNA1{[afhna]([mo6pur])[36SS].r(T)p}$$$$V2.0'\n ];\n\n const complexMonomersExpected = [\n ['L-hArg(Et,Et)', 'E', 'F', 'G', 'C', 'E'],\n ['L-hArg(Et,Et)', 'L-hArg(Et,Et)', 'E', 'F', 'G'],\n ['dhp', 'm1A', 'p', 'r', 'T', 'p', 'r', 'T', 'p', 'r', 'G', 'p'],\n ['r', 'mo6pur', 'p', 'r', 'T', 'p', 'r', 'T', 'p', 'r', 'G', 'p'],\n ['afhna', 'mo6pur', '36SS', 'r', 'T', 'p']\n ];\n\n const complexTestNames = [\n 'comples-monomer', 'complex-monomer+side-chain', 'complex-monomer+side-chain-RNA',\n 'complex-side-chain', 'complex+side-chain+linker'\n ];\n test('parseHelm', async () => {\n const expectedResults = [\n ['meI', 'hHis', 'Aca', 'N', 'T', 'dK', 'Thr_PO3H2', 'D-Tyr_Et', 'Aze', 'dV', 'E', 'Phe_4Me'],\n ['A', 'C', 'T', 'G', 'W', 'E', 'Q'],\n ['R', 'U', 'P', 'T', 'A'],\n ['A', '*', 'G', 'C']\n ];\n const helmStrings = [\n 'PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Aze.dV.E.N.dV.Phe_4Me}$$$',\n // eslint-disable-next-line max-len\n 'PEPTIDE1{A.C.T.G.C.T.W.G.T.W.E.C.W.C.Q.W}|PEPTIDE2{A.C.T.G.C.T.W.G.T.W.E.Q}$PEPTIDE1,PEPTIDE1,5:R3-14:R3|PEPTIDE2,PEPTIDE1,2:R3-12:R3$$$',\n 'RNA1{R(U)P.R(T)P}|RNA2{P.R(A)P.R(A)}$RNA1,RNA2,2:pair-6:pair|RNA1,RNA2,5:pair-3:pair$$$',\n 'PEPTIDE1{A.*.G.C}$$$$V2.0'\n ];\n for (let idx = 0; idx < helmStrings.length; ++idx) {\n const monomerSet = new Set(parseHelm(helmStrings[idx]));\n const monomerArray = Array.from(monomerSet);\n expect(JSON.stringify(monomerArray), JSON.stringify(expectedResults[idx]));\n }\n });\n complexMonomers.forEach((helm, i) => {\n test(complexTestNames[i], async () => {\n const monomersArray = parseHelm(helm);\n monomersArray.sort();\n const expected = complexMonomersExpected[i];\n expected.sort();\n expectArray(monomersArray, expected);\n });\n });\n});\n","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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcblxuXG5leHBvcnQgdHlwZSBDb2x1bW5JbnB1dE9wdGlvbnMgPSB7XG4gICAgZmlsdGVyPzogKGNvbDogREcuQ29sdW1uKSA9PiBib29sZWFuIHwgbnVsbDtcbn07XG4iXX0=","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 let aligned = uh.column.getTag(\"aligned\" /* TAGS.aligned */);\n if (aligned === null) {\n aligned = stats.sameLength ? \"SEQ.MSA\" /* ALIGNMENT.SEQ_MSA */ : \"SEQ\" /* ALIGNMENT.SEQ */;\n uh.column.setTag(\"aligned\" /* TAGS.aligned */, aligned);\n }\n let alphabet = uh.column.getTag(\"alphabet\" /* TAGS.alphabet */);\n if (alphabet === null) {\n alphabet = detectAlphabet(stats.freq, candidateAlphabets);\n uh.column.setTag(\"alphabet\" /* TAGS.alphabet */, alphabet);\n }\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.LEVENSHTEIN;\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","import * 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-test';\nimport {after, before, category, delay, expect, expectObject, test} from '@datagrok-libraries/utils/src/test';\nimport {findMonomers, parseHelm} from '../utils';\nimport {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';\n\nconst LIB_STORAGE_NAME = 'Libraries';\nexport const LIB_DEFAULT: { [fileName: string]: string } = {'HELMCoreLibrary.json': 'HELMCoreLibrary.json'};\n\n\n/** Tests with default monomer library */\ncategory('findMonomers', () => {\n\n let monomerLibHelper: IMonomerLibHelper;\n /** Backup actual user's monomer libraries settings */\n let userLibrariesSettings: any = null;\n\n before(async () => {\n monomerLibHelper = await getMonomerLibHelper();\n userLibrariesSettings = await grok.dapi.userDataStorage.get(LIB_STORAGE_NAME, true);\n\n // Tests 'findMonomers' requires default monomer library loaded\n await grok.dapi.userDataStorage.post(LIB_STORAGE_NAME, LIB_DEFAULT, true);\n await monomerLibHelper.loadLibraries(true); // load default libraries\n });\n\n after(async () => {\n await grok.dapi.userDataStorage.put(LIB_STORAGE_NAME, userLibrariesSettings, true);\n });\n\n const tests: { [testName: string]: { test: string, tgt: Set<string> } } = {\n 'withoutMissed': {\n test: 'PEPTIDE1{meI.hHis.Aca.N.T.dE.Thr_PO3H2.Aca.D-Tyr_Et}$$$$',\n tgt: new Set<string>(),\n },\n 'withMissed':\n {\n test: 'PEPTIDE1{meI.missed2.Aca.N.T.dE.Thr_PO3H2.Aca.D-Tyr_Et}$$$$',\n tgt: new Set<string>(['missed2'])\n }\n };\n\n for (const [testName, testData] of Object.entries(tests)) {\n test(testName, async () => {\n _testFindMonomers(testData.test, testData.tgt);\n });\n }\n\n function _testFindMonomers(testHelmValue: string, tgtMissedSet: Set<string>): void {\n const monomerSymbolList: string[] = parseHelm(testHelmValue);\n const resMissedSet: Set<string> = findMonomers(monomerSymbolList);\n expectObject(resMissedSet, tgtMissedSet);\n }\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, helmFieldsToEnumeratorInputFields, rGroupsDummy, dummyMonomer } 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 isValidEnumeratorLib(json) {\n return json.every((entry) => {\n return typeof entry === 'object' &&\n Object.values(helmFieldsToEnumeratorInputFields).every((field) => {\n return field in entry &&\n typeof entry[field] === 'string';\n });\n });\n}\n/** Specific to Enumerator for peptides */\nexport function getJsonMonomerLibForEnumerator(rawLib) {\n // todo\n function validateMonomerLibWithSmiles() {\n }\n function restoreRgroupsInSmiles(rawSmiles) {\n const regex = new RegExp('\\\\[r\\\\]', 'g');\n let i = 0;\n return rawSmiles.replace(regex, (match) => { ++i; return `[${i}*]`; });\n }\n function prepareOutputSmilesColValue(smilesWithRestoredRgroups) {\n const result = smilesWithRestoredRgroups.replace('[1*]', '[H:1]');\n return result.replace('[2*]', '[OH:2]');\n }\n function prepareMolblock(rawMolblock) {\n return rawMolblock.replace('M ISO', 'M RGP');\n }\n const resultLib = [];\n validateMonomerLibWithSmiles();\n rawLib.forEach((rawMonomer) => {\n const monomer = { ...dummyMonomer };\n Object.entries(helmFieldsToEnumeratorInputFields).forEach(([key, value]) => {\n const monomerSymbol = rawMonomer[value];\n //@ts-ignore\n monomer[key] = monomerSymbol;\n });\n let key = \"smiles\" /* HELM_FIELDS.SMILES */;\n const rawSmiles = rawMonomer[helmFieldsToEnumeratorInputFields[key]];\n const smilesWithRestoredRgroups = restoreRgroupsInSmiles(rawSmiles);\n const smiles = prepareOutputSmilesColValue(smilesWithRestoredRgroups);\n monomer[key] = smiles;\n key = \"rgroups\" /* HELM_FIELDS.RGROUPS */;\n monomer[key] = rGroupsDummy;\n key = \"molfile\" /* HELM_FIELDS.MOLFILE */;\n const smilesWithRgroups = restoreRgroupsInSmiles(rawSmiles);\n const rawMolfile = DG.chem.convert(smilesWithRgroups, DG.chem.Notation.Smiles, DG.chem.Notation.MolBlock);\n monomer[key] = prepareMolblock(rawMolfile);\n resultLib.push(monomer);\n });\n console.log('resultLib:', resultLib);\n return resultLib;\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","const __WEBPACK_NAMESPACE_OBJECT__ = $;","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport $ from 'cash-dom';\n\nimport {category, expect, test, awaitCheck, delay} from '@datagrok-libraries/utils/src/test';\nimport {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';\nimport {TAGS as helmTAGS} from '../constants';\n\ncategory('renderers', () => {\n test('missedInLib', async () => { await _testMissedInLib(); });\n});\n\nasync function _testMissedInLib() {\n const df: DG.DataFrame = await grok.dapi.files.readCsv('System:AppData/Helm/tests/sample_HELM-missedInLib.csv');\n const helmCol: DG.Column<string> = df.getCol('HELM');\n\n const tv: DG.TableView = grok.shell.addTableView(df);\n await awaitCheck(() => {\n return $(tv.root).find('.d4-grid canvas').length > 0;\n }, 'Table view canvas not found', 100);\n\n expect(helmCol.semType, DG.SEMTYPE.MACROMOLECULE);\n expect(helmCol.getTag(DG.TAGS.UNITS), NOTATION.HELM);\n expect(helmCol.getTag(DG.TAGS.CELL_RENDERER), 'helm');\n\n const cellRendererErrorJson: string = helmCol.getTag(helmTAGS.cellRendererRenderError);\n if (!!cellRendererErrorJson) {\n const cellRendererError: any = JSON.parse(cellRendererErrorJson);\n const err = new Error(cellRendererError['message']);\n err.stack = cellRendererError['stack'];\n throw err;\n }\n}\n","import * as DG from 'datagrok-api/dg';\nimport * as grok from 'datagrok-api/grok';\nimport {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';\n\nimport './tests/helm-tests.ts';\nimport './tests/findMonomers-tests';\nimport './tests/renderers-tests';\n\nexport const _package = new DG.Package();\nexport {tests};\n\n\n//name: test\n//input: string category {optional: true}\n//input: string test {optional: true}\n//input: object testContext {optional: true}\n//output: dataframe result\nexport async function test(category: string, test: string, testContext: TestContext): Promise<DG.DataFrame> {\n const data = await runTests({category, test, testContext});\n return DG.DataFrame.fromObjects(data)!;\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","DG","grok","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","result","done","then","apply","STANDART_TIMEOUT","tests","autoTestsCatName","wasRegistered","currentCategory","assure","notNull","name","Error","TestContext","constructor","catchUnhandled","report","this","undefined","Test","category","test","options","_a","timeout","push","expect","actual","expected","error","expectFloat","tolerance","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","NaN","isNaN","areEqual","Math","abs","expectObject","expectedKey","expectedValue","entries","actualValue","Array","expectArray","isFinite","actualLength","length","expectedLength","i","tests_","clear","before","after","addNamespace","s","f","replace","RegExp","nqName","execTest","t","predicate","categoryTimeout","packageName","_b","_c","_d","_e","r","filter","toLowerCase","skip","skipReason","console","log","start","Date","success","ms","skipped","timeout_","x","toString","stop","params","res","keys","reduce","acc","k","assign","delay","setTimeout","func","testTimeout","timeoutPromise","_","race","clearTimeout","parseHelm","split","monomers","scil","Utils","isNullOrEmpty","seqs","p","detachAnnotation","str","indexOf","substring","ss","monomer","startsWith","includes","element","residue","endsWith","lastIndexOf","firstPiece","thirdPiece","elements","el","sep","ret","frag","parentheses","bracket","braces","quote","c","c2","_detachAppendix","tag","repeat","endswith","m","NOTATION","complexMonomersExpected","complexTestNames","expectedResults","helmStrings","idx","monomerSet","Set","monomerArray","from","JSON","stringify","forEach","helm","monomersArray","sort","wu","CandidateType","alphabet","cutoff","fasta","peptide","dna","rna","Float32Array","static","dt","simplified","PaletteType","palette","cp","objList","colour","ind","colourPalette","_palette","undefinedColor","Lesk","lesk","makePalette","GrokGroups","grokGroups","RasMol","rasMol","resM","aaSynonyms","super","Aminoacids","scheme","isInner","inner","outer","char","parseInt","chemPaletteInstance","getPalette","outerMonomer","innerMonomer","getInnerOuter","slice","amino","toUpperCase","AAFullNames","SemType","SemTypeMultipleAlignment","Names","AASmiles","AASmilesTruncated","Nucleotides","UnknownColorPalette","concat","values","pI","hash","charCodeAt","hashCode","color","dgColor","g","b","distToBlack","sqrt","pow","correctColor","buildPalette","Uint32Array","MmDistanceFunctionsNames","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","uhTemp","LIB_STORAGE_NAME","LIB_DEFAULT","monomerLibHelper","userLibrariesSettings","async","funcList","package","prepare","getOutputParamValue","loadLibraries","tgt","testName","testData","_testFindMonomers","testHelmValue","tgtMissedSet","monomerSymbolList","types","org","webeditor","monomerTypeList","monomerNames","Monomers","getMonomerSet","id","val","findMonomers","$","df","helmCol","getCol","tv","checkHandler","wait","interval","clearInterval","intervalId","setInterval","awaitCheck","root","find","semType","getTag","cellRendererErrorJson","cellRendererError","parse","err","stack","_testMissedInLib","_package","testContext","data","package_","packageId","moduleTests","moduleAutoTests","packFunctions","list","reg","isArray","matchAll","map","arr","cat","initAutoTests","results","beforeStatus","all","afterStatus","logger","successful","failed","description","runTests"],"sourceRoot":""}
1
+ {"version":3,"file":"package-test.js","mappings":"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","sources":["webpack://helm/webpack/bootstrap","webpack://helm/webpack/runtime/compat get default export","webpack://helm/webpack/runtime/define property getters","webpack://helm/webpack/runtime/hasOwnProperty shorthand","webpack://helm/webpack/runtime/make namespace object","webpack://helm/external var \"DG\"","webpack://helm/external var \"grok\"","webpack://helm/./node_modules/@datagrok-libraries/utils/src/test.js","webpack://helm/./src/utils.ts","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/consts.js","webpack://helm/./src/tests/helm-tests.ts","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/const.js","webpack://helm/external var \"wu\"","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/types.js","webpack://helm/./node_modules/@datagrok-libraries/utils/src/type-declarations.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/seq-palettes.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/aminoacids.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/nucleotides.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/unknown.js","webpack://helm/./node_modules/fastest-levenshtein/esm/mod.js","webpack://helm/./node_modules/@datagrok-libraries/ml/src/macromolecule-distance-functions/macromolecule-distance-functions.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/units-handler.js","webpack://helm/./src/tests/findMonomers-tests.ts","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/monomer-utils.js","webpack://helm/external var \"$\"","webpack://helm/./src/tests/renderers-tests.ts","webpack://helm/./src/package-test.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\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};","const __WEBPACK_NAMESPACE_OBJECT__ = DG;","const __WEBPACK_NAMESPACE_OBJECT__ = grok;","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';\nconst STANDART_TIMEOUT = 30000;\nconst BENCHMARK_TIMEOUT = 10800000;\nexport const tests = {};\nconst autoTestsCatName = 'Auto Tests';\nconst wasRegistered = {};\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 = STANDART_TIMEOUT);\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 = true, error) {\n if (error)\n error = `${error}, `;\n else\n error = '';\n if (actual !== expected)\n throw new Error(`${error}Expected \"${expected}\", got \"${actual}\"`);\n}\nexport function expectFloat(actual, expected, tolerance = 0.001, error) {\n if ((actual === Number.POSITIVE_INFINITY && expected === Number.POSITIVE_INFINITY) ||\n (actual === Number.NEGATIVE_INFINITY && expected === Number.NEGATIVE_INFINITY) ||\n (actual === Number.NaN && expected === Number.NaN) || (isNaN(actual) && isNaN(expected)))\n return;\n const areEqual = Math.abs(actual - expected) < tolerance;\n expect(areEqual, true, `${error !== null && error !== void 0 ? error : ''} (tolerance = ${tolerance})`);\n if (!areEqual)\n throw new Error(`Expected ${expected}, got ${actual} (tolerance = ${tolerance})`);\n}\nexport function expectTable(actual, expected, error) {\n const expectedRowCount = expected.rowCount;\n const actualRowCount = actual.rowCount;\n expect(actualRowCount, expectedRowCount, `${error !== null && error !== void 0 ? error : ''}, row count`);\n for (const column of expected.columns) {\n const actualColumn = actual.columns.byName(column.name);\n if (actualColumn == null)\n throw new Error(`Column ${column.name} not found`);\n if (actualColumn.type != column.type)\n throw new Error(`Column ${column.name} type expected ${column.type} got ${actualColumn.type}`);\n for (let i = 0; i < expectedRowCount; i++) {\n const value = column.get(i);\n const actualValue = actualColumn.get(i);\n if (column.type == DG.TYPE.FLOAT)\n expectFloat(actualValue, value, 0.0001, error);\n else if (column.type == DG.TYPE.DATE_TIME)\n expect(actualValue.isSame(value), true, error);\n else\n expect(actualValue, value, error);\n }\n }\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_, options) {\n var _a;\n currentCategory = category;\n tests_();\n if (tests[currentCategory]) {\n tests[currentCategory].clear = (_a = options === null || options === void 0 ? void 0 : options.clear) !== null && _a !== void 0 ? _a : true;\n tests[currentCategory].timeout = options === null || options === void 0 ? void 0 : options.timeout;\n }\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}\nfunction addNamespace(s, f) {\n return s.replace(new RegExp(f.name, 'gi'), f.nqName);\n}\nexport function initAutoTests(packageId, module) {\n return __awaiter(this, void 0, void 0, function* () {\n if (wasRegistered[packageId])\n return;\n const moduleTests = module ? module.tests : tests;\n if (moduleTests[autoTestsCatName] !== undefined ||\n Object.keys(moduleTests).find((c) => c.startsWith(autoTestsCatName))) {\n wasRegistered[packageId] = true;\n return;\n }\n const moduleAutoTests = [];\n const packFunctions = yield grok.dapi.functions.filter(`package.id = \"${packageId}\"`).list();\n const reg = new RegExp(/skip:\\s*([^,\\s]+)|wait:\\s*(\\d+)|cat:\\s*([^,\\s]+)/g);\n for (const f of packFunctions) {\n const tests = f.options['test'];\n if (!(tests && Array.isArray(tests) && tests.length))\n continue;\n for (let i = 0; i < tests.length; i++) {\n const res = tests[i].matchAll(reg);\n const map = {};\n Array.from(res).forEach((arr) => {\n if (arr[0].startsWith('skip'))\n map['skip'] = arr[1];\n else if (arr[0].startsWith('wait'))\n map['wait'] = parseInt(arr[2]);\n else if (arr[0].startsWith('cat'))\n map['cat'] = arr[3];\n });\n const test = new Test(autoTestsCatName, tests.length === 1 ? f.name : `${f.name} ${i + 1}`, () => __awaiter(this, void 0, void 0, function* () {\n const res = yield grok.functions.eval(addNamespace(tests[i], f));\n if (map.wait)\n yield delay(map.wait);\n // eslint-disable-next-line no-throw-literal\n if (typeof res === 'boolean' && !res)\n throw `Failed: ${tests[i]}, expected true, got ${res}`;\n }), { skipReason: map.skip });\n if (map.cat) {\n const cat = autoTestsCatName + ': ' + map.cat;\n test.category = cat;\n if (moduleTests[cat] === undefined)\n moduleTests[cat] = { tests: [], clear: true };\n moduleTests[cat].tests.push(test);\n }\n else {\n moduleAutoTests.push(test);\n }\n }\n }\n wasRegistered[packageId] = true;\n if (!moduleAutoTests.length)\n return;\n moduleTests[autoTestsCatName] = { tests: moduleAutoTests, clear: true };\n });\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 package_ = (_b = (_a = grok.functions.getCurrentCall()) === null || _a === void 0 ? void 0 : _a.func) === null || _b === void 0 ? void 0 : _b.package;\n yield initAutoTests(package_.id);\n const results = [];\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 if (value.clear) {\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, value.timeout, package_.name));\n grok.shell.closeAll();\n DG.Balloon.closeAll();\n }\n }\n else {\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, value.timeout, package_.name));\n }\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 // Clear after category\n // grok.shell.closeAll();\n // DG.Balloon.closeAll();\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: package_\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, categoryTimeout, packageName) {\n var _a, _b, _c, _d, _e;\n return __awaiter(this, void 0, void 0, function* () {\n let r;\n const filter = predicate != undefined && (t.name.toLowerCase() !== 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 }\n else {\n let timeout_ = ((_c = t.options) === null || _c === void 0 ? void 0 : _c.timeout) === STANDART_TIMEOUT &&\n categoryTimeout ? categoryTimeout : (_d = t.options) === null || _d === void 0 ? void 0 : _d.timeout;\n timeout_ = DG.Test.isInBenchmark && timeout_ === STANDART_TIMEOUT ? BENCHMARK_TIMEOUT : timeout_;\n r = { success: true, result: (_e = yield timeout(t.test, timeout_)) !== null && _e !== void 0 ? _e : 'OK', ms: 0, skipped: false };\n }\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 if (!filter) {\n let params = { 'success': r.success, 'result': r.result, 'ms': r.ms, 'skipped': r.skipped,\n 'type': 'package', packageName, 'category': t.category, 'test': t.name };\n if (r.result.constructor == Object) {\n const res = Object.keys(r.result).reduce((acc, k) => (Object.assign(Object.assign({}, acc), { ['result.' + k]: r.result[k] })), {});\n params = Object.assign(Object.assign({}, params), res);\n }\n grok.log.usage(`${packageName}: ${t.category}: ${t.name}`, params, `test-package ${packageName}: ${t.category}: ${t.name}`);\n }\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, interval = 50) {\n return __awaiter(this, void 0, void 0, function* () {\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n clearInterval(intervalId);\n reject(new Error(error));\n }, wait);\n // @ts-ignore\n const intervalId = setInterval(() => {\n if (checkHandler()) {\n clearInterval(intervalId);\n resolve();\n }\n }, interval);\n });\n });\n}\nfunction timeout(func, testTimeout) {\n return __awaiter(this, void 0, void 0, function* () {\n let timeout = null;\n const timeoutPromise = new Promise((_, reject) => {\n //@ts-ignore\n timeout = setTimeout(() => {\n // eslint-disable-next-line prefer-promise-reject-errors\n reject('EXECUTION TIMEOUT');\n }, testTimeout);\n });\n try {\n return yield Promise.race([func(), timeoutPromise]);\n }\n finally {\n if (timeout)\n clearTimeout(timeout);\n }\n });\n}\nexport function isDialogPresent(dialogTitle) {\n const dialogs = DG.Dialog.getOpenDialogs();\n for (let i = 0; i < dialogs.length; i++) {\n if (dialogs[i].title == dialogTitle)\n return true;\n }\n return false;\n}\n/** Expects an asynchronous {@link action} to throw an exception. Use {@link check} to perform\n * deeper inspection of the exception if necessary.\n * @param {function(): Promise<void>} action\n * @param {function(any): boolean} check\n * @return {Promise<void>}\n */\nexport function expectExceptionAsync(action, check) {\n return __awaiter(this, void 0, void 0, function* () {\n let caught = false;\n let checked = false;\n try {\n yield action();\n }\n catch (e) {\n caught = true;\n checked = !check || check(e);\n }\n finally {\n if (!caught)\n throw new Error('An exception is expected but not thrown');\n if (!checked)\n throw new Error('An expected exception is thrown, but it does not satisfy the condition');\n }\n });\n}\n/**\n * Universal test for viewers. It search viewers in DOM by tags: canvas, svg, img, input, h1, a\n * @param {string} v Viewer name\n * @param {DG.DataFrame} df Dataframe to use. Should have at least 3 rows\n * @param {boolean} options.detectSemanticTypes Specify whether to detect semantic types or not\n * @param {boolean} options.readOnly If set to true, the dataframe will not be modified during the test\n * @param {object} options List of options (optional)\n * @return {Promise<void>} The test is considered successful if it completes without errors\n */\nexport function testViewer(v, df, options) {\n var _a;\n return __awaiter(this, void 0, void 0, function* () {\n if (options === null || options === void 0 ? void 0 : options.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 let 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 const tag = (_a = document.querySelector(selector)) === null || _a === void 0 ? void 0 : _a.tagName;\n res.push(Array.from(tv.viewers).length);\n if (!(options === null || options === void 0 ? void 0 : options.readOnly)) {\n Array.from(df.row(0).cells).forEach((c) => c.value = null);\n const num = df.rowCount < 20 ? Math.floor(df.rowCount / 2) : 10;\n df.rows.select((row) => row.idx >= 0 && row.idx < num);\n yield delay(50);\n for (let i = num; i < num * 2; i++)\n df.filter.set(i, false);\n yield delay(50);\n df.currentRowIdx = 1;\n const df1 = df.clone();\n df.columns.names().slice(0, Math.ceil(df.columns.length / 2)).forEach((c) => df.columns.remove(c));\n yield delay(100);\n tv.dataFrame = df1;\n }\n const optns = viewer.getOptions(true).look;\n const props = viewer.getProperties();\n const newProps = {};\n Object.keys(optns).filter((k) => typeof optns[k] === 'boolean').forEach((k) => newProps[k] = !optns[k]);\n props.filter((p) => p.choices !== null)\n .forEach((p) => newProps[p.name] = p.choices.find((c) => c !== optns[p.name]));\n viewer.setOptions(newProps);\n yield delay(300);\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 selector = `${viewerName} ${tag}`;\n yield awaitCheck(() => document.querySelector(selector) !== null, 'cannot load viewer from layout', 3000);\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 DG.Balloon.closeAll();\n }\n });\n}\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxtQkFBbUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBS3RDLE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0FBQy9CLE1BQU0saUJBQWlCLEdBQUcsUUFBUSxDQUFDO0FBRW5DLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FLZCxFQUFFLENBQUM7QUFFUCxNQUFNLGdCQUFnQixHQUFHLFlBQVksQ0FBQztBQUN0QyxNQUFNLGFBQWEsR0FBNkIsRUFBRSxDQUFDO0FBQ25ELE1BQU0sQ0FBQyxJQUFJLGVBQXVCLENBQUM7QUFFbkMsTUFBTSxLQUFXLE1BQU0sQ0FLdEI7QUFMRCxXQUFpQixNQUFNO0lBQ3JCLFNBQWdCLE9BQU8sQ0FBQyxLQUFVLEVBQUUsSUFBYTtRQUMvQyxJQUFJLEtBQUssSUFBSSxJQUFJO1lBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxjQUFjLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBSGUsY0FBTyxVQUd0QixDQUFBO0FBQ0gsQ0FBQyxFQUxnQixNQUFNLEtBQU4sTUFBTSxRQUt0QjtBQWFELE1BQU0sT0FBTyxXQUFXO0lBSXRCLFlBQVksY0FBd0IsRUFBRSxNQUFnQjtRQUh0RCxtQkFBYyxHQUFHLElBQUksQ0FBQztRQUN0QixXQUFNLEdBQUcsS0FBSyxDQUFDO1FBR2IsSUFBSSxjQUFjLEtBQUssU0FBUztZQUFFLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3ZFLElBQUksTUFBTSxLQUFLLFNBQVM7WUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUNqRCxDQUFDO0lBQUEsQ0FBQztDQUNI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bEMsTUFBTSxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQzlELGdDQUFnQyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEMsTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUUsQ0FBQztZQUNyRSxXQUFXLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7U0FDNUU7Z0JBQVM7WUFDUixFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQixFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ3ZCOztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZ3JvayBmcm9tICdkYXRhZ3Jvay1hcGkvZ3Jvayc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuaW1wb3J0IFRpbWVvdXQgPSBOb2RlSlMuVGltZW91dDtcbmltcG9ydCB7RGF0YUZyYW1lfSBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5jb25zdCBTVEFOREFSVF9USU1FT1VUID0gMzAwMDA7XG5jb25zdCBCRU5DSE1BUktfVElNRU9VVCA9IDEwODAwMDAwO1xuXG5leHBvcnQgY29uc3QgdGVzdHM6IHtcbiAgW2tleTogc3RyaW5nXToge1xuICAgIHRlc3RzPzogVGVzdFtdLCBiZWZvcmU/OiAoKSA9PiBQcm9taXNlPHZvaWQ+LCBhZnRlcj86ICgpID0+IFByb21pc2U8dm9pZD4sXG4gICAgYmVmb3JlU3RhdHVzPzogc3RyaW5nLCBhZnRlclN0YXR1cz86IHN0cmluZywgY2xlYXI/OiBib29sZWFuLCB0aW1lb3V0PzogbnVtYmVyXG4gIH1cbn0gPSB7fTtcblxuY29uc3QgYXV0b1Rlc3RzQ2F0TmFtZSA9ICdBdXRvIFRlc3RzJztcbmNvbnN0IHdhc1JlZ2lzdGVyZWQ6IHtba2V5OiBzdHJpbmddOiBib29sZWFufSA9IHt9O1xuZXhwb3J0IGxldCBjdXJyZW50Q2F0ZWdvcnk6IHN0cmluZztcblxuZXhwb3J0IG5hbWVzcGFjZSBhc3N1cmUge1xuICBleHBvcnQgZnVuY3Rpb24gbm90TnVsbCh2YWx1ZTogYW55LCBuYW1lPzogc3RyaW5nKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bmFtZSA9PSBudWxsID8gJ1ZhbHVlJyA6IG5hbWV9IG5vdCBkZWZpbmVkYCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBUZXN0T3B0aW9ucyB7XG4gIHRpbWVvdXQ/OiBudW1iZXI7XG4gIHVuaGFuZGxlZEV4Y2VwdGlvblRpbWVvdXQ/OiBudW1iZXI7XG4gIHNraXBSZWFzb24/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2F0ZWdvcnlPcHRpb25zIHtcbiAgY2xlYXI/OiBib29sZWFuO1xuICB0aW1lb3V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgY2xhc3MgVGVzdENvbnRleHQge1xuICBjYXRjaFVuaGFuZGxlZCA9IHRydWU7XG4gIHJlcG9ydCA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKGNhdGNoVW5oYW5kbGVkPzogYm9vbGVhbiwgcmVwb3J0PzogYm9vbGVhbikge1xuICAgIGlmIChjYXRjaFVuaGFuZGxlZCAhPT0gdW5kZWZpbmVkKSB0aGlzLmNhdGNoVW5oYW5kbGVkID0gY2F0Y2hVbmhhbmRsZWQ7XG4gICAgaWYgKHJlcG9ydCAhPT0gdW5kZWZpbmVkKSB0aGlzLnJlcG9ydCA9IHJlcG9ydDtcbiAgfTtcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3Qge1xuICB0ZXN0OiAoKSA9PiBQcm9taXNlPGFueT47XG4gIG5hbWU6IHN0cmluZztcbiAgY2F0ZWdvcnk6IHN0cmluZztcbiAgb3B0aW9ucz86IFRlc3RPcHRpb25zO1xuXG4gIGNvbnN0cnVjdG9yKGNhdGVnb3J5OiBzdHJpbmcsIG5hbWU6IHN0cmluZywgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+LCBvcHRpb25zPzogVGVzdE9wdGlvbnMpIHtcbiAgICB0aGlzLmNhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICBvcHRpb25zID8/PSB7fTtcbiAgICBvcHRpb25zLnRpbWVvdXQgPz89IFNUQU5EQVJUX1RJTUVPVVQ7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLnRlc3QgPSBhc3luYyAoKTogUHJvbWlzZTxhbnk+ID0+IHtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGxldCByZXN1bHQgPSAnJztcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXN1bHQgPSBhd2FpdCB0ZXN0KCk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0RXZlbnQ8VD4oZXZlbnQ6IE9ic2VydmFibGU8VD4sXG4gIGhhbmRsZXI6IChhcmdzOiBUKSA9PiB2b2lkLCB0cmlnZ2VyOiAoKSA9PiB2b2lkLCBtczogbnVtYmVyID0gMCk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGxldCBzdWI6IFN1YnNjcmlwdGlvbjtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzdWIgPSBldmVudC5zdWJzY3JpYmUoKGFyZ3M6IGFueSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlcihhcmdzKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgfVxuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICByZXNvbHZlKCdPSycpO1xuICAgIH0pO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgc3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KCd0aW1lb3V0Jyk7XG4gICAgfSwgbXMpO1xuICAgIHRyaWdnZXIoKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0KG5hbWU6IHN0cmluZywgdGVzdDogKCkgPT4gUHJvbWlzZTxhbnk+LCBvcHRpb25zPzogVGVzdE9wdGlvbnMpOiB2b2lkIHtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0gPSB7fTtcbiAgaWYgKHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPT0gdW5kZWZpbmVkKVxuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGVzdHMgPSBbXTtcbiAgdGVzdHNbY3VycmVudENhdGVnb3J5XS50ZXN0cyEucHVzaChuZXcgVGVzdChjdXJyZW50Q2F0ZWdvcnksIG5hbWUsIHRlc3QsIG9wdGlvbnMpKTtcbn1cblxuLyogVGVzdHMgdHdvIG9iamVjdHMgZm9yIGVxdWFsaXR5LCB0aHJvd3MgYW4gZXhjZXB0aW9uIGlmIHRoZXkgYXJlIG5vdCBlcXVhbC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3QoYWN0dWFsOiBhbnksIGV4cGVjdGVkOiBhbnkgPSB0cnVlLCBlcnJvcj86IHN0cmluZyk6IHZvaWQge1xuICBpZiAoZXJyb3IpXG4gICAgZXJyb3IgPSBgJHtlcnJvcn0sIGA7XG4gIGVsc2UgZXJyb3IgPSAnJztcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpXG4gICAgdGhyb3cgbmV3IEVycm9yKGAke2Vycm9yfUV4cGVjdGVkIFwiJHtleHBlY3RlZH1cIiwgZ290IFwiJHthY3R1YWx9XCJgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdEZsb2F0KGFjdHVhbDogbnVtYmVyLCBleHBlY3RlZDogbnVtYmVyLCB0b2xlcmFuY2UgPSAwLjAwMSwgZXJyb3I/OiBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKChhY3R1YWwgPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSAmJiBleHBlY3RlZCA9PT0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZKSB8fFxuICAgICAgKGFjdHVhbCA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZICYmIGV4cGVjdGVkID09PSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpIHx8XG4gICAgICAoYWN0dWFsID09PSBOdW1iZXIuTmFOICYmIGV4cGVjdGVkID09PSBOdW1iZXIuTmFOKSB8fCAoaXNOYU4oYWN0dWFsKSAmJiBpc05hTihleHBlY3RlZCkpKVxuICAgIHJldHVybjtcbiAgY29uc3QgYXJlRXF1YWwgPSBNYXRoLmFicyhhY3R1YWwgLSBleHBlY3RlZCkgPCB0b2xlcmFuY2U7XG4gIGV4cGVjdChhcmVFcXVhbCwgdHJ1ZSwgYCR7ZXJyb3IgPz8gJyd9ICh0b2xlcmFuY2UgPSAke3RvbGVyYW5jZX0pYCk7XG4gIGlmICghYXJlRXF1YWwpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSwgZ290ICR7YWN0dWFsfSAodG9sZXJhbmNlID0gJHt0b2xlcmFuY2V9KWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXhwZWN0VGFibGUoYWN0dWFsOiBEYXRhRnJhbWUsIGV4cGVjdGVkOiBEYXRhRnJhbWUsIGVycm9yPzogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGV4cGVjdGVkUm93Q291bnQgPSBleHBlY3RlZC5yb3dDb3VudDtcbiAgY29uc3QgYWN0dWFsUm93Q291bnQgPSBhY3R1YWwucm93Q291bnQ7XG4gIGV4cGVjdChhY3R1YWxSb3dDb3VudCwgZXhwZWN0ZWRSb3dDb3VudCwgYCR7ZXJyb3IgPz8gJyd9LCByb3cgY291bnRgKTtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBleHBlY3RlZC5jb2x1bW5zKSB7XG4gICAgY29uc3QgYWN0dWFsQ29sdW1uID0gYWN0dWFsLmNvbHVtbnMuYnlOYW1lKGNvbHVtbi5uYW1lKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uID09IG51bGwpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSBub3QgZm91bmRgKTtcbiAgICBpZiAoYWN0dWFsQ29sdW1uLnR5cGUgIT0gY29sdW1uLnR5cGUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiAke2NvbHVtbi5uYW1lfSB0eXBlIGV4cGVjdGVkICR7Y29sdW1uLnR5cGV9IGdvdCAke2FjdHVhbENvbHVtbi50eXBlfWApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRSb3dDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbHVtbi5nZXQoaSk7XG4gICAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbENvbHVtbi5nZXQoaSk7XG4gICAgICBpZiAoY29sdW1uLnR5cGUgPT0gREcuVFlQRS5GTE9BVClcbiAgICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIHZhbHVlLCAwLjAwMDEsIGVycm9yKTtcbiAgICAgIGVsc2UgaWYgKGNvbHVtbi50eXBlID09IERHLlRZUEUuREFURV9USU1FKVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUuaXNTYW1lKHZhbHVlKSwgdHJ1ZSwgZXJyb3IpO1xuICAgICAgZWxzZVxuICAgICAgICBleHBlY3QoYWN0dWFsVmFsdWUsIHZhbHVlLCBlcnJvcik7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBlY3RPYmplY3QoYWN0dWFsOiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBleHBlY3RlZDogeyBba2V5OiBzdHJpbmddOiBhbnkgfSkge1xuICBmb3IgKGNvbnN0IFtleHBlY3RlZEtleSwgZXhwZWN0ZWRWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZXhwZWN0ZWQpKSB7XG4gICAgaWYgKCFhY3R1YWwuaGFzT3duUHJvcGVydHkoZXhwZWN0ZWRLZXkpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBwcm9wZXJ0eSBcIiR7ZXhwZWN0ZWRLZXl9XCIgbm90IGZvdW5kYCk7XG5cbiAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGFjdHVhbFtleHBlY3RlZEtleV07XG4gICAgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KVxuICAgICAgZXhwZWN0QXJyYXkoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlIGluc3RhbmNlb2YgT2JqZWN0ICYmIGV4cGVjdGVkVmFsdWUgaW5zdGFuY2VvZiBPYmplY3QpXG4gICAgICBleHBlY3RPYmplY3QoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKE51bWJlci5pc0Zpbml0ZShhY3R1YWxWYWx1ZSkgJiYgTnVtYmVyLmlzRmluaXRlKGV4cGVjdGVkVmFsdWUpKVxuICAgICAgZXhwZWN0RmxvYXQoYWN0dWFsVmFsdWUsIGV4cGVjdGVkVmFsdWUpO1xuICAgIGVsc2UgaWYgKGFjdHVhbFZhbHVlICE9IGV4cGVjdGVkVmFsdWUpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICgke2V4cGVjdGVkVmFsdWV9KSBmb3Iga2V5ICcke2V4cGVjdGVkS2V5fScsIGdvdCAoJHthY3R1YWxWYWx1ZX0pYCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGVjdEFycmF5KGFjdHVhbDogQXJyYXlMaWtlPGFueT4sIGV4cGVjdGVkOiBBcnJheUxpa2U8YW55Pikge1xuICBjb25zdCBhY3R1YWxMZW5ndGggPSBhY3R1YWwubGVuZ3RoO1xuICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDtcblxuICBpZiAoYWN0dWFsTGVuZ3RoICE9IGV4cGVjdGVkTGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBcnJheXMgYXJlIG9mIGRpZmZlcmVudCBsZW5ndGg6IGFjdHVhbCBhcnJheSBsZW5ndGggaXMgJHthY3R1YWxMZW5ndGh9IGAgK1xuICAgICAgYGFuZCBleHBlY3RlZCBhcnJheSBsZW5ndGggaXMgJHtleHBlY3RlZExlbmd0aH1gKTtcbiAgfVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0dWFsTGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYWN0dWFsW2ldIGluc3RhbmNlb2YgQXJyYXkgJiYgZXhwZWN0ZWRbaV0gaW5zdGFuY2VvZiBBcnJheSlcbiAgICAgIGV4cGVjdEFycmF5KGFjdHVhbFtpXSwgZXhwZWN0ZWRbaV0pO1xuICAgIGVsc2UgaWYgKGFjdHVhbFtpXSBpbnN0YW5jZW9mIE9iamVjdCAmJiBleHBlY3RlZFtpXSBpbnN0YW5jZW9mIE9iamVjdClcbiAgICAgIGV4cGVjdE9iamVjdChhY3R1YWxbaV0sIGV4cGVjdGVkW2ldKTtcbiAgICBlbHNlIGlmIChhY3R1YWxbaV0gIT0gZXhwZWN0ZWRbaV0pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkICR7ZXhwZWN0ZWRbaV19IGF0IHBvc2l0aW9uICR7aX0sIGdvdCAke2FjdHVhbFtpXX1gKTtcbiAgfVxufVxuXG4vKiBEZWZpbmVzIGEgdGVzdCBzdWl0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYXRlZ29yeShjYXRlZ29yeTogc3RyaW5nLCB0ZXN0c186ICgpID0+IHZvaWQsIG9wdGlvbnM/OiBDYXRlZ29yeU9wdGlvbnMpOiB2b2lkIHtcbiAgY3VycmVudENhdGVnb3J5ID0gY2F0ZWdvcnk7XG4gIHRlc3RzXygpO1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSkge1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0uY2xlYXIgPSBvcHRpb25zPy5jbGVhciA/PyB0cnVlO1xuICAgIHRlc3RzW2N1cnJlbnRDYXRlZ29yeV0udGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQ7XG4gIH1cbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGJlZm9yZSB0aGUgdGVzdHMgaW4gdGhpcyBjYXRlZ29yeSBhcmUgZXhlY3V0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYmVmb3JlKGJlZm9yZTogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmJlZm9yZSA9IGJlZm9yZTtcbn1cblxuLyogRGVmaW5lcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGFmdGVyIHRoZSB0ZXN0cyBpbiB0aGlzIGNhdGVnb3J5IGFyZSBleGVjdXRlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlcihhZnRlcjogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICBpZiAodGVzdHNbY3VycmVudENhdGVnb3J5XSA9PSB1bmRlZmluZWQpXG4gICAgdGVzdHNbY3VycmVudENhdGVnb3J5XSA9IHt9O1xuICB0ZXN0c1tjdXJyZW50Q2F0ZWdvcnldLmFmdGVyID0gYWZ0ZXI7XG59XG5cbmZ1bmN0aW9uIGFkZE5hbWVzcGFjZShzOiBzdHJpbmcsIGY6IERHLkZ1bmMpOiBzdHJpbmcge1xuICByZXR1cm4gcy5yZXBsYWNlKG5ldyBSZWdFeHAoZi5uYW1lLCAnZ2knKSwgZi5ucU5hbWUpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5pdEF1dG9UZXN0cyhwYWNrYWdlSWQ6IHN0cmluZywgbW9kdWxlPzogYW55KSB7XG4gIGlmICh3YXNSZWdpc3RlcmVkW3BhY2thZ2VJZF0pIHJldHVybjtcbiAgY29uc3QgbW9kdWxlVGVzdHMgPSBtb2R1bGUgPyBtb2R1bGUudGVzdHMgOiB0ZXN0cztcbiAgaWYgKG1vZHVsZVRlc3RzW2F1dG9UZXN0c0NhdE5hbWVdICE9PSB1bmRlZmluZWQgfHxcbiAgICBPYmplY3Qua2V5cyhtb2R1bGVUZXN0cykuZmluZCgoYykgPT4gYy5zdGFydHNXaXRoKGF1dG9UZXN0c0NhdE5hbWUpKSkge1xuICAgIHdhc1JlZ2lzdGVyZWRbcGFja2FnZUlkXSA9IHRydWU7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IG1vZHVsZUF1dG9UZXN0cyA9IFtdO1xuICBjb25zdCBwYWNrRnVuY3Rpb25zID0gYXdhaXQgZ3Jvay5kYXBpLmZ1bmN0aW9ucy5maWx0ZXIoYHBhY2thZ2UuaWQgPSBcIiR7cGFja2FnZUlkfVwiYCkubGlzdCgpO1xuICBjb25zdCByZWcgPSBuZXcgUmVnRXhwKC9za2lwOlxccyooW14sXFxzXSspfHdhaXQ6XFxzKihcXGQrKXxjYXQ6XFxzKihbXixcXHNdKykvZyk7XG4gIGZvciAoY29uc3QgZiBvZiBwYWNrRnVuY3Rpb25zKSB7XG4gICAgY29uc3QgdGVzdHMgPSBmLm9wdGlvbnNbJ3Rlc3QnXTtcbiAgICBpZiAoISh0ZXN0cyAmJiBBcnJheS5pc0FycmF5KHRlc3RzKSAmJiB0ZXN0cy5sZW5ndGgpKSBjb250aW51ZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRlc3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByZXMgPSAodGVzdHNbaV0gYXMgc3RyaW5nKS5tYXRjaEFsbChyZWcpO1xuICAgICAgY29uc3QgbWFwOiB7c2tpcD86IHN0cmluZywgd2FpdD86IG51bWJlciwgY2F0Pzogc3RyaW5nfSA9IHt9O1xuICAgICAgQXJyYXkuZnJvbShyZXMpLmZvckVhY2goKGFycikgPT4ge1xuICAgICAgICBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ3NraXAnKSkgbWFwWydza2lwJ10gPSBhcnJbMV07XG4gICAgICAgIGVsc2UgaWYgKGFyclswXS5zdGFydHNXaXRoKCd3YWl0JykpIG1hcFsnd2FpdCddID0gcGFyc2VJbnQoYXJyWzJdKTtcbiAgICAgICAgZWxzZSBpZiAoYXJyWzBdLnN0YXJ0c1dpdGgoJ2NhdCcpKSBtYXBbJ2NhdCddID0gYXJyWzNdO1xuICAgICAgfSk7XG4gICAgICBjb25zdCB0ZXN0ID0gbmV3IFRlc3QoYXV0b1Rlc3RzQ2F0TmFtZSwgdGVzdHMubGVuZ3RoID09PSAxID8gZi5uYW1lIDogYCR7Zi5uYW1lfSAke2kgKyAxfWAsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgZ3Jvay5mdW5jdGlvbnMuZXZhbChhZGROYW1lc3BhY2UodGVzdHNbaV0sIGYpKTtcbiAgICAgICAgaWYgKG1hcC53YWl0KSBhd2FpdCBkZWxheShtYXAud2FpdCk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gICAgICAgIGlmICh0eXBlb2YgcmVzID09PSAnYm9vbGVhbicgJiYgIXJlcykgdGhyb3cgYEZhaWxlZDogJHt0ZXN0c1tpXX0sIGV4cGVjdGVkIHRydWUsIGdvdCAke3Jlc31gO1xuICAgICAgfSwge3NraXBSZWFzb246IG1hcC5za2lwfSk7XG4gICAgICBpZiAobWFwLmNhdCkge1xuICAgICAgICBjb25zdCBjYXQ6IHN0cmluZyA9IGF1dG9UZXN0c0NhdE5hbWUgKyAnOiAnICsgbWFwLmNhdDtcbiAgICAgICAgdGVzdC5jYXRlZ29yeSA9IGNhdDtcbiAgICAgICAgaWYgKG1vZHVsZVRlc3RzW2NhdF0gPT09IHVuZGVmaW5lZClcbiAgICAgICAgICBtb2R1bGVUZXN0c1tjYXRdID0ge3Rlc3RzOiBbXSwgY2xlYXI6IHRydWV9O1xuICAgICAgICBtb2R1bGVUZXN0c1tjYXRdLnRlc3RzLnB1c2godGVzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtb2R1bGVBdXRvVGVzdHMucHVzaCh0ZXN0KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgd2FzUmVnaXN0ZXJlZFtwYWNrYWdlSWRdID0gdHJ1ZTtcbiAgaWYgKCFtb2R1bGVBdXRvVGVzdHMubGVuZ3RoKSByZXR1cm47XG4gIG1vZHVsZVRlc3RzW2F1dG9UZXN0c0NhdE5hbWVdID0ge3Rlc3RzOiBtb2R1bGVBdXRvVGVzdHMsIGNsZWFyOiB0cnVlfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJ1blRlc3RzKG9wdGlvbnM/OiB7Y2F0ZWdvcnk/OiBzdHJpbmcsIHRlc3Q/OiBzdHJpbmcsIHRlc3RDb250ZXh0PzogVGVzdENvbnRleHR9KSB7XG4gIGNvbnN0IHBhY2thZ2VfID0gZ3Jvay5mdW5jdGlvbnMuZ2V0Q3VycmVudENhbGwoKT8uZnVuYz8ucGFja2FnZTtcbiAgYXdhaXQgaW5pdEF1dG9UZXN0cyhwYWNrYWdlXy5pZCk7XG4gIGNvbnN0IHJlc3VsdHM6IHsgY2F0ZWdvcnk/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcsIHN1Y2Nlc3M6IGJvb2xlYW4sXG4gICAgICAgICAgICAgICAgICAgcmVzdWx0OiBzdHJpbmcsIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfVtdID0gW107XG4gIGNvbnNvbGUubG9nKGBSdW5uaW5nIHRlc3RzYCk7XG4gIG9wdGlvbnMgPz89IHt9O1xuICBvcHRpb25zIS50ZXN0Q29udGV4dCA/Pz0gbmV3IFRlc3RDb250ZXh0KCk7XG4gIGdyb2suc2hlbGwubGFzdEVycm9yID0gJyc7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRlc3RzKSkge1xuICAgIGlmIChvcHRpb25zPy5jYXRlZ29yeSAhPSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICgha2V5LnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChvcHRpb25zPy5jYXRlZ29yeS50b0xvd2VyQ2FzZSgpKSlcbiAgICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGBTdGFydGVkICR7a2V5fSBjYXRlZ29yeWApO1xuICAgIHRyeSB7XG4gICAgICBpZiAodmFsdWUuYmVmb3JlKVxuICAgICAgICBhd2FpdCB2YWx1ZS5iZWZvcmUoKTtcbiAgICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICAgIHZhbHVlLmJlZm9yZVN0YXR1cyA9IHgudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgY29uc3QgdCA9IHZhbHVlLnRlc3RzID8/IFtdO1xuICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgIGlmICh2YWx1ZS5jbGVhcikge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlcy5wdXNoKGF3YWl0IGV4ZWNUZXN0KHRbaV0sIG9wdGlvbnM/LnRlc3QsIHZhbHVlLnRpbWVvdXQsIHBhY2thZ2VfLm5hbWUpKTtcbiAgICAgICAgZ3Jvay5zaGVsbC5jbG9zZUFsbCgpO1xuICAgICAgICBERy5CYWxsb29uLmNsb3NlQWxsKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdC5sZW5ndGg7IGkrKylcbiAgICAgICAgcmVzLnB1c2goYXdhaXQgZXhlY1Rlc3QodFtpXSwgb3B0aW9ucz8udGVzdCwgdmFsdWUudGltZW91dCwgcGFja2FnZV8ubmFtZSkpO1xuICAgIH1cbiAgICBjb25zdCBkYXRhID0gKGF3YWl0IFByb21pc2UuYWxsKHJlcykpLmZpbHRlcigoZCkgPT4gZC5yZXN1bHQgIT0gJ3NraXBwZWQnKTtcbiAgICB0cnkge1xuICAgICAgaWYgKHZhbHVlLmFmdGVyKVxuICAgICAgICBhd2FpdCB2YWx1ZS5hZnRlcigpO1xuICAgIH0gY2F0Y2ggKHg6IGFueSkge1xuICAgICAgdmFsdWUuYWZ0ZXJTdGF0dXMgPSB4LnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIC8vIENsZWFyIGFmdGVyIGNhdGVnb3J5XG4gICAgLy8gZ3Jvay5zaGVsbC5jbG9zZUFsbCgpO1xuICAgIC8vIERHLkJhbGxvb24uY2xvc2VBbGwoKTtcbiAgICBpZiAodmFsdWUuYWZ0ZXJTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5hZnRlclN0YXR1cywgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZX0pO1xuICAgIGlmICh2YWx1ZS5iZWZvcmVTdGF0dXMpXG4gICAgICBkYXRhLnB1c2goe2NhdGVnb3J5OiBrZXksIG5hbWU6ICdpbml0JywgcmVzdWx0OiB2YWx1ZS5iZWZvcmVTdGF0dXMsIHN1Y2Nlc3M6IGZhbHNlLCBtczogMCwgc2tpcHBlZDogZmFsc2V9KTtcbiAgICByZXN1bHRzLnB1c2goLi4uZGF0YSk7XG4gIH1cbiAgaWYgKG9wdGlvbnMudGVzdENvbnRleHQuY2F0Y2hVbmhhbmRsZWQpIHtcbiAgICBhd2FpdCBkZWxheSgxMDAwKTtcbiAgICBpZiAoZ3Jvay5zaGVsbC5sYXN0RXJyb3IubGVuZ3RoID4gMCkge1xuICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgY2F0ZWdvcnk6ICdVbmhhbmRsZWQgZXhjZXB0aW9ucycsXG4gICAgICAgIG5hbWU6ICdleGNlcHRpb25zJyxcbiAgICAgICAgcmVzdWx0OiBncm9rLnNoZWxsLmxhc3RFcnJvciwgc3VjY2VzczogZmFsc2UsIG1zOiAwLCBza2lwcGVkOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGlmIChvcHRpb25zLnRlc3RDb250ZXh0LnJlcG9ydCkge1xuICAgIGNvbnN0IGxvZ2dlciA9IG5ldyBERy5Mb2dnZXIoKTtcbiAgICBjb25zdCBzdWNjZXNzZnVsID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+IHIuc3VjY2VzcykubGVuZ3RoO1xuICAgIGNvbnN0IHNraXBwZWQgPSByZXN1bHRzLmZpbHRlcigocikgPT4gci5za2lwcGVkKS5sZW5ndGg7XG4gICAgY29uc3QgZmFpbGVkID0gcmVzdWx0cy5maWx0ZXIoKHIpID0+ICFyLnN1Y2Nlc3MpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJ1BhY2thZ2UgQHBhY2thZ2UgdGVzdGVkOiBAc3VjY2Vzc2Z1bCBzdWNjZXNzZnVsLCBAc2tpcHBlZCBza2lwcGVkLCBAZmFpbGVkIGZhaWxlZCB0ZXN0cyc7XG4gICAgY29uc3QgcGFyYW1zID0ge1xuICAgICAgc3VjY2Vzc2Z1bDogc3VjY2Vzc2Z1bCxcbiAgICAgIHNraXBwZWQ6IHNraXBwZWQsXG4gICAgICBmYWlsZWQ6IGZhaWxlZC5sZW5ndGgsXG4gICAgICBwYWNrYWdlOiBwYWNrYWdlX1xuICAgIH07XG4gICAgZm9yIChjb25zdCByIG9mIGZhaWxlZCkgT2JqZWN0LmFzc2lnbihwYXJhbXMsIHtbYCR7ci5jYXRlZ29yeX0gfCAke3IubmFtZX1gXTogci5yZXN1bHR9KTtcbiAgICBsb2dnZXIubG9nKGRlc2NyaXB0aW9uLCBwYXJhbXMsICdwYWNrYWdlLXRlc3RlZCcpO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufVxuXG5hc3luYyBmdW5jdGlvbiBleGVjVGVzdCh0OiBUZXN0LCBwcmVkaWNhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgY2F0ZWdvcnlUaW1lb3V0PzogbnVtYmVyLCBwYWNrYWdlTmFtZT86IHN0cmluZykge1xuICBsZXQgcjogeyBjYXRlZ29yeT86IHN0cmluZywgbmFtZT86IHN0cmluZywgc3VjY2VzczogYm9vbGVhbiwgcmVzdWx0OiBhbnksIG1zOiBudW1iZXIsIHNraXBwZWQ6IGJvb2xlYW4gfTtcbiAgY29uc3QgZmlsdGVyID0gcHJlZGljYXRlICE9IHVuZGVmaW5lZCAmJiAodC5uYW1lLnRvTG93ZXJDYXNlKCkgIT09IHByZWRpY2F0ZS50b0xvd2VyQ2FzZSgpKTtcbiAgY29uc3Qgc2tpcCA9IHQub3B0aW9ucz8uc2tpcFJlYXNvbiB8fCBmaWx0ZXI7XG4gIGNvbnN0IHNraXBSZWFzb24gPSBmaWx0ZXIgPyAnc2tpcHBlZCcgOiB0Lm9wdGlvbnM/LnNraXBSZWFzb247XG4gIGlmICghc2tpcClcbiAgICBjb25zb2xlLmxvZyhgU3RhcnRlZCAke3QuY2F0ZWdvcnl9ICR7dC5uYW1lfWApO1xuICBjb25zdCBzdGFydCA9IG5ldyBEYXRlKCk7XG4gIHRyeSB7XG4gICAgaWYgKHNraXApIHtcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBza2lwUmVhc29uISwgbXM6IDAsIHNraXBwZWQ6IHRydWV9O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgdGltZW91dF8gPSB0Lm9wdGlvbnM/LnRpbWVvdXQgPT09IFNUQU5EQVJUX1RJTUVPVVQgJiZcbiAgICAgICAgY2F0ZWdvcnlUaW1lb3V0ID8gY2F0ZWdvcnlUaW1lb3V0IDogdC5vcHRpb25zPy50aW1lb3V0ITtcbiAgICAgIHRpbWVvdXRfID0gREcuVGVzdC5pc0luQmVuY2htYXJrICYmIHRpbWVvdXRfID09PSBTVEFOREFSVF9USU1FT1VUID8gQkVOQ0hNQVJLX1RJTUVPVVQgOiB0aW1lb3V0XztcbiAgICAgIHIgPSB7c3VjY2VzczogdHJ1ZSwgcmVzdWx0OiBhd2FpdCB0aW1lb3V0KHQudGVzdCwgdGltZW91dF8pID8/ICdPSycsIG1zOiAwLCBza2lwcGVkOiBmYWxzZX07XG4gICAgfVxuICB9IGNhdGNoICh4OiBhbnkpIHtcbiAgICByID0ge3N1Y2Nlc3M6IGZhbHNlLCByZXN1bHQ6IHgudG9TdHJpbmcoKSwgbXM6IDAsIHNraXBwZWQ6IGZhbHNlfTtcbiAgfVxuICBjb25zdCBzdG9wID0gbmV3IERhdGUoKTtcbiAgLy8gQHRzLWlnbm9yZVxuICByLm1zID0gc3RvcCAtIHN0YXJ0O1xuICBpZiAoIXNraXApXG4gICAgY29uc29sZS5sb2coYEZpbmlzaGVkICR7dC5jYXRlZ29yeX0gJHt0Lm5hbWV9IGZvciAke3IubXN9IG1zYCk7XG4gIHIuY2F0ZWdvcnkgPSB0LmNhdGVnb3J5O1xuICByLm5hbWUgPSB0Lm5hbWU7XG4gIGlmICghZmlsdGVyKSB7XG4gICAgbGV0IHBhcmFtcyA9IHsnc3VjY2Vzcyc6IHIuc3VjY2VzcywgJ3Jlc3VsdCc6IHIucmVzdWx0LCAnbXMnOiByLm1zLCAnc2tpcHBlZCc6IHIuc2tpcHBlZCxcbiAgICAgICd0eXBlJzogJ3BhY2thZ2UnLCBwYWNrYWdlTmFtZSwgJ2NhdGVnb3J5JzogdC5jYXRlZ29yeSwgJ3Rlc3QnOiB0Lm5hbWV9O1xuICAgIGlmIChyLnJlc3VsdC5jb25zdHJ1Y3RvciA9PSBPYmplY3QpIHtcbiAgICAgIGNvbnN0IHJlcyA9IE9iamVjdC5rZXlzKHIucmVzdWx0KS5yZWR1Y2UoKGFjYywgaykgPT4gKHsuLi5hY2MsIFsncmVzdWx0LicgKyBrXTogci5yZXN1bHRba119KSwge30pO1xuICAgICAgcGFyYW1zID0gey4uLnBhcmFtcywgLi4ucmVzfTtcbiAgICB9XG4gICAgZ3Jvay5sb2cudXNhZ2UoYCR7cGFja2FnZU5hbWV9OiAke3QuY2F0ZWdvcnl9OiAke3QubmFtZX1gLFxuICAgICAgcGFyYW1zLCBgdGVzdC1wYWNrYWdlICR7cGFja2FnZU5hbWV9OiAke3QuY2F0ZWdvcnl9OiAke3QubmFtZX1gKTtcbiAgfVxuICByZXR1cm4gcjtcbn1cblxuLyogV2FpdHMgW21zXSBtaWxsaXNlY29uZHMgKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWxheShtczogbnVtYmVyKSB7XG4gIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIG1zKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhd2FpdENoZWNrKGNoZWNrSGFuZGxlcjogKCkgPT4gYm9vbGVhbixcbiAgZXJyb3I6IHN0cmluZyA9ICdUaW1lb3V0IGV4Y2VlZGVkJywgd2FpdDogbnVtYmVyID0gNTAwLCBpbnRlcnZhbDogbnVtYmVyID0gNTApOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG4gICAgICByZWplY3QobmV3IEVycm9yKGVycm9yKSk7XG4gICAgfSwgd2FpdCk7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGludGVydmFsSWQ6IFRpbWVvdXQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAoY2hlY2tIYW5kbGVyKCkpIHtcbiAgICAgICAgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElkKTtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0sIGludGVydmFsKTtcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRpbWVvdXQoZnVuYzogKCkgPT4gUHJvbWlzZTxhbnk+LCB0ZXN0VGltZW91dDogbnVtYmVyKTogUHJvbWlzZTxhbnk+IHtcbiAgbGV0IHRpbWVvdXQ6IFRpbWVvdXQgfCBudWxsID0gbnVsbDtcbiAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZTxhbnk+KChfLCByZWplY3QpID0+IHtcbiAgICAvL0B0cy1pZ25vcmVcbiAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXByb21pc2UtcmVqZWN0LWVycm9yc1xuICAgICAgcmVqZWN0KCdFWEVDVVRJT04gVElNRU9VVCcpO1xuICAgIH0sIHRlc3RUaW1lb3V0KTtcbiAgfSk7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGF3YWl0IFByb21pc2UucmFjZShbZnVuYygpLCB0aW1lb3V0UHJvbWlzZV0pO1xuICB9IGZpbmFsbHkge1xuICAgIGlmICh0aW1lb3V0KVxuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RpYWxvZ1ByZXNlbnQoZGlhbG9nVGl0bGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBkaWFsb2dzID0gREcuRGlhbG9nLmdldE9wZW5EaWFsb2dzKCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZGlhbG9ncy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChkaWFsb2dzW2ldLnRpdGxlID09IGRpYWxvZ1RpdGxlKVxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogRXhwZWN0cyBhbiBhc3luY2hyb25vdXMge0BsaW5rIGFjdGlvbn0gdG8gdGhyb3cgYW4gZXhjZXB0aW9uLiBVc2Uge0BsaW5rIGNoZWNrfSB0byBwZXJmb3JtXG4gKiBkZWVwZXIgaW5zcGVjdGlvbiBvZiB0aGUgZXhjZXB0aW9uIGlmIG5lY2Vzc2FyeS5cbiAqIEBwYXJhbSAge2Z1bmN0aW9uKCk6IFByb21pc2U8dm9pZD59IGFjdGlvblxuICogQHBhcmFtICB7ZnVuY3Rpb24oYW55KTogYm9vbGVhbn0gY2hlY2tcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHBlY3RFeGNlcHRpb25Bc3luYyhhY3Rpb246ICgpID0+IFByb21pc2U8dm9pZD4sXG4gIGNoZWNrPzogKGV4Y2VwdGlvbjogYW55KSA9PiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGxldCBjYXVnaHQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgbGV0IGNoZWNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgdHJ5IHtcbiAgICBhd2FpdCBhY3Rpb24oKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNhdWdodCA9IHRydWU7XG4gICAgY2hlY2tlZCA9ICFjaGVjayB8fCBjaGVjayhlKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoIWNhdWdodClcbiAgICAgIHRocm93IG5ldyBFcnJvcignQW4gZXhjZXB0aW9uIGlzIGV4cGVjdGVkIGJ1dCBub3QgdGhyb3duJyk7XG4gICAgaWYgKCFjaGVja2VkKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBbiBleHBlY3RlZCBleGNlcHRpb24gaXMgdGhyb3duLCBidXQgaXQgZG9lcyBub3Qgc2F0aXNmeSB0aGUgY29uZGl0aW9uJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBVbml2ZXJzYWwgdGVzdCBmb3Igdmlld2Vycy4gSXQgc2VhcmNoIHZpZXdlcnMgaW4gRE9NIGJ5IHRhZ3M6IGNhbnZhcywgc3ZnLCBpbWcsIGlucHV0LCBoMSwgYVxuICogQHBhcmFtICB7c3RyaW5nfSB2IFZpZXdlciBuYW1lXG4gKiBAcGFyYW0gIHtERy5EYXRhRnJhbWV9IGRmIERhdGFmcmFtZSB0byB1c2UuIFNob3VsZCBoYXZlIGF0IGxlYXN0IDMgcm93c1xuICogQHBhcmFtICB7Ym9vbGVhbn0gb3B0aW9ucy5kZXRlY3RTZW1hbnRpY1R5cGVzIFNwZWNpZnkgd2hldGhlciB0byBkZXRlY3Qgc2VtYW50aWMgdHlwZXMgb3Igbm90XG4gKiBAcGFyYW0gIHtib29sZWFufSBvcHRpb25zLnJlYWRPbmx5IElmIHNldCB0byB0cnVlLCB0aGUgZGF0YWZyYW1lIHdpbGwgbm90IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgdGVzdFxuICogQHBhcmFtICB7b2JqZWN0fSBvcHRpb25zIExpc3Qgb2Ygb3B0aW9ucyAob3B0aW9uYWwpXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBUaGUgdGVzdCBpcyBjb25zaWRlcmVkIHN1Y2Nlc3NmdWwgaWYgaXQgY29tcGxldGVzIHdpdGhvdXQgZXJyb3JzXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0ZXN0Vmlld2VyKHY6IHN0cmluZywgZGY6IERHLkRhdGFGcmFtZSxcbiAgb3B0aW9ucz86IHtkZXRlY3RTZW1hbnRpY1R5cGVzPzogYm9vbGVhbiwgcmVhZE9ubHk/OiBib29sZWFufSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAob3B0aW9ucz8uZGV0ZWN0U2VtYW50aWNUeXBlcykgYXdhaXQgZ3Jvay5kYXRhLmRldGVjdFNlbWFudGljVHlwZXMoZGYpO1xuICBjb25zdCB0diA9IGdyb2suc2hlbGwuYWRkVGFibGVWaWV3KGRmKTtcbiAgY29uc3Qgdmlld2VyTmFtZSA9IGBbbmFtZT12aWV3ZXItJHt2LnJlcGxhY2UoL1xccysvZywgJy0nKX0gaV1gO1xuICBsZXQgc2VsZWN0b3IgPSBgJHt2aWV3ZXJOYW1lfSBjYW52YXMsJHt2aWV3ZXJOYW1lfSBzdmcsJHt2aWV3ZXJOYW1lfSBpbWcsXG4gICAgJHt2aWV3ZXJOYW1lfSBpbnB1dCwke3ZpZXdlck5hbWV9IGgxLCR7dmlld2VyTmFtZX0gYWA7XG4gIGNvbnN0IHJlcyA9IFtdO1xuICB0cnkge1xuICAgIGxldCB2aWV3ZXIgPSB0di5hZGRWaWV3ZXIodik7XG4gICAgYXdhaXQgYXdhaXRDaGVjaygoKSA9PiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKSAhPT0gbnVsbCxcbiAgICAgICdjYW5ub3QgbG9hZCB2aWV3ZXInLCAzMDAwKTtcbiAgICBjb25zdCB0YWcgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKT8udGFnTmFtZTtcbiAgICByZXMucHVzaChBcnJheS5mcm9tKHR2LnZpZXdlcnMpLmxlbmd0aCk7XG4gICAgaWYgKCFvcHRpb25zPy5yZWFkT25seSkge1xuICAgICAgQXJyYXkuZnJvbShkZi5yb3coMCkuY2VsbHMpLmZvckVhY2goKGM6YW55KSA9PiBjLnZhbHVlID0gbnVsbCk7XG4gICAgICBjb25zdCBudW0gPSBkZi5yb3dDb3VudCA8IDIwID8gTWF0aC5mbG9vcihkZi5yb3dDb3VudCAvIDIpIDogMTA7XG4gICAgICBkZi5yb3dzLnNlbGVjdCgocm93OiBERy5Sb3cpID0+IHJvdy5pZHggPj0gMCAmJiByb3cuaWR4IDwgbnVtKTtcbiAgICAgIGF3YWl0IGRlbGF5KDUwKTtcbiAgICAgIGZvciAobGV0IGkgPSBudW07IGkgPCBudW0gKiAyOyBpKyspIGRmLmZpbHRlci5zZXQoaSwgZmFsc2UpO1xuICAgICAgYXdhaXQgZGVsYXkoNTApO1xuICAgICAgZGYuY3VycmVudFJvd0lkeCA9IDE7XG4gICAgICBjb25zdCBkZjEgPSBkZi5jbG9uZSgpO1xuICAgICAgZGYuY29sdW1ucy5uYW1lcygpLnNsaWNlKDAsIE1hdGguY2VpbChkZi5jb2x1bW5zLmxlbmd0aCAvIDIpKS5mb3JFYWNoKChjOiBhbnkpID0+IGRmLmNvbHVtbnMucmVtb3ZlKGMpKTtcbiAgICAgIGF3YWl0IGRlbGF5KDEwMCk7XG4gICAgICB0di5kYXRhRnJhbWUgPSBkZjE7XG4gICAgfVxuICAgIGNvbnN0IG9wdG5zID0gdmlld2VyLmdldE9wdGlvbnModHJ1ZSkubG9vaztcbiAgICBjb25zdCBwcm9wcyA9IHZpZXdlci5nZXRQcm9wZXJ0aWVzKCk7XG4gICAgY29uc3QgbmV3UHJvcHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IGJvb2xlYW4+ID0ge307XG4gICAgT2JqZWN0LmtleXMob3B0bnMpLmZpbHRlcigoaykgPT4gdHlwZW9mIG9wdG5zW2tdID09PSAnYm9vbGVhbicpLmZvckVhY2goKGspID0+IG5ld1Byb3BzW2tdID0gIW9wdG5zW2tdKTtcbiAgICBwcm9wcy5maWx0ZXIoKHA6IERHLlByb3BlcnR5KSA9PiBwLmNob2ljZXMgIT09IG51bGwpXG4gICAgICAuZm9yRWFjaCgocDogREcuUHJvcGVydHkpID0+IG5ld1Byb3BzW3AubmFtZV0gPSBwLmNob2ljZXMuZmluZCgoYzogYW55KSA9PiBjICE9PSBvcHRuc1twLm5hbWVdKSEpO1xuICAgIHZpZXdlci5zZXRPcHRpb25zKG5ld1Byb3BzKTtcbiAgICBhd2FpdCBkZWxheSgzMDApO1xuICAgIGNvbnN0IGxheW91dCA9IHR2LnNhdmVMYXlvdXQoKTtcbiAgICBjb25zdCBvbGRQcm9wcyA9IHZpZXdlci5nZXRPcHRpb25zKCkubG9vaztcbiAgICB0di5yZXNldExheW91dCgpO1xuICAgIHJlcy5wdXNoKEFycmF5LmZyb20odHYudmlld2VycykubGVuZ3RoKTtcbiAgICB0di5sb2FkTGF5b3V0KGxheW91dCk7XG4gICAgc2VsZWN0b3IgPSBgJHt2aWV3ZXJOYW1lfSAke3RhZ31gO1xuICAgIGF3YWl0IGF3YWl0Q2hlY2soKCkgPT4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcikgIT09IG51bGwsXG4gICAgICAnY2Fubm90IGxvYWQgdmlld2VyIGZyb20gbGF5b3V0JywgMzAwMCk7XG4gICAgcmVzLnB1c2goQXJyYXkuZnJvbSh0di52aWV3ZXJzKS5sZW5ndGgpO1xuICAgIHZpZXdlciA9IEFycmF5LmZyb20odHYudmlld2VycykuZmluZCgodjogYW55KSA9PiB2LnR5cGUgIT09ICdHcmlkJykhO1xuICAgIGV4cGVjdEFycmF5KHJlcywgWzIsIDEsIDJdKTtcbiAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkodmlld2VyLmdldE9wdGlvbnMoKS5sb29rKSwgSlNPTi5zdHJpbmdpZnkob2xkUHJvcHMpKTtcbiAgfSBmaW5hbGx5IHtcbiAgICB0di5jbG9zZSgpO1xuICAgIGdyb2suc2hlbGwuY2xvc2VUYWJsZShkZik7XG4gICAgREcuQmFsbG9vbi5jbG9zZUFsbCgpO1xuICB9XG59XG4iXX0=","import * as DG from 'datagrok-api/dg';\nimport {\n RGROUP_CAP_GROUP_NAME,\n RGROUP_CAP_GROUP_SMILES,\n jsonSdfMonomerLibDict,\n MONOMER_SYMBOL,\n RGROUP_ALTER_ID,\n RGROUPS,\n RGROUP_LABEL,\n SDF_MONOMER_NAME\n} from './constants';\n\nexport function getParts(subParts: string[], s: string): string[] {\n const j = 0;\n const allParts: string[] = [];\n for (let k = 0; k < subParts.length; ++k) {\n const indexOfMonomer = s.indexOf(subParts[k]);\n const helmBeforeMonomer = s.slice(j, indexOfMonomer);\n allParts.push(helmBeforeMonomer);\n allParts.push(subParts[k]);\n s = s.substring(indexOfMonomer + subParts[k].length);\n }\n allParts.push(s);\n return allParts;\n}\n\nexport function parseHelm(s: string): string[] {\n const sections = split(s, '$');\n s = sections[0];\n const monomers = [];\n //@ts-ignore\n if (!scil.Utils.isNullOrEmpty(s)) {\n const seqs = split(s, '|');\n for (let i = 0; i < seqs.length; ++i) {\n const e = detachAnnotation(seqs[i]);\n s = e.str;\n\n let p = s.indexOf('{');\n\n s = s.substring(p + 1);\n p = s.indexOf('}');\n s = s.substring(0, p);\n\n const ss = split(s, '.');\n for (const monomer of ss) {\n if (!monomer || monomer === '') continue;\n if (monomer.startsWith('[') && monomer.includes(']')) {\n const element = monomer.substring(1, monomer.indexOf(']'));\n monomers.push(element);\n const residue = monomer.substring(monomer.indexOf(']') + 1);\n ss.push(residue);\n } else if (monomer.includes('[') && monomer.endsWith(']')) {\n const element = monomer.substring(monomer.lastIndexOf('[') + 1, monomer.length - 1);\n monomers.push(element);\n const residue = monomer.substring(0, monomer.lastIndexOf('['));\n ss.push(residue);\n } else if (monomer.includes('(') && monomer.includes(')')) {\n // here we only want to split the string at first '(' and last ')'\n // because entries like [L-hArg(Et,Et)]([L-hArg(Et,Et)]) where L-hArg(Et,Et) is a single monomer\n const firstPiece = monomer.substring(0, monomer.indexOf('('));\n const thirdPiece = monomer.substring(monomer.lastIndexOf(')') + 1);\n const secondPiece = monomer.substring(firstPiece.length + 1, monomer.length - thirdPiece.length - 1);\n const elements = [firstPiece, secondPiece, thirdPiece];\n for (const el of elements)\n ss.push(el);\n } else {\n monomers.push(monomer);\n }\n }\n }\n }\n return monomers;\n}\n\n// /** Find monomers missed in Helm monomer library configured and\n// * used in org.helm.webeditor / scil.helm.Monomers / org.helm.webeditor.Monomers .\n// */\n// export function findMonomers(helmString: string) {\n// //@ts-ignore\n// const types: string[] = Object.keys(org.helm.webeditor.monomerTypeList());\n// const monomerNameList: any[] = [];\n// const monomerNameI: number = 0;\n// const weMonomers = org.helm.webeditor.Monomers;\n// for (let typeI = 0; typeI < types.length; typeI++) {\n// //@ts-ignore\n// const ofTypeMonomers: {} = weMonomers.getMonomerSet(types[typeI]) ?? {};\n// Object.keys(ofTypeMonomers).forEach((key) => {\n// const monomer: any = ofTypeMonomers[key];\n// monomerNameList[monomerNameI] = monomer.id;\n// monomerNameI += 1;\n// });\n// }\n// const helmPartList = parseHelm(helmString);\n// return new Set(helmPartList.filter((val) => !monomerNameList.includes(val)));\n// }\n\n/** Searches monomers of helmString for missed. */\nexport function findMonomers(monomerSymbolList: string[]): Set<string> {\n const types = Object.keys(org.helm.webeditor.monomerTypeList());\n const monomers: any = [];\n const monomerNames: any = [];\n for (let i = 0; i < types.length; i++) {\n //@ts-ignore\n // eslint-disable-next-line new-cap\n monomers.push(new scil.helm.Monomers.getMonomerSet(types[i]));\n Object.keys(monomers[i]).forEach((k) => {\n monomerNames.push(monomers[i][k].id);\n });\n }\n return new Set(monomerSymbolList.filter((val) => !monomerNames.includes(val)));\n}\n\nfunction split(s: string, sep: string) {\n const ret = [];\n let frag = '';\n let parentheses = 0;\n let bracket = 0;\n let braces = 0;\n let quote = 0;\n for (let i = 0; i < s.length; ++i) {\n let c = s.substring(i, i + 1);\n if (c == sep && bracket == 0 && parentheses == 0 && braces == 0 && quote == 0) {\n ret.push(frag);\n frag = '';\n } else {\n frag += c;\n if (quote > 0) {\n if (c == '\\\\' && i + 1 < s.length) {\n ++i;\n const c2 = s.substring(i, i + 1);\n frag += c2;\n c += c2;\n }\n }\n if (c == '\\\"') {\n if (!(i > 0 && s.substring(i - 1, i) == '\\\\'))\n quote = quote == 0 ? 1 : 0;\n } else if (c == '[') {\n ++bracket;\n } else if (c == ']') {\n --bracket;\n } else if (c == '(') {\n ++parentheses;\n } else if (c == ')') {\n --parentheses;\n } else if (c == '{') {\n ++braces;\n } else if (c == '}') {\n --braces;\n }\n }\n }\n ret.push(frag);\n return ret;\n}\n\nfunction detachAnnotation(s: string) {\n const ret = _detachAppendix(s, '\\\"');\n if (ret.tag != null)\n return ret;\n\n const r = _detachAppendix(s, '\\'');\n return {tag: ret.tag, repeat: r.tag, str: r.str};\n}\n\nfunction _detachAppendix(s: string, c: string) {\n let tag = null;\n //@ts-ignore\n if (scil.Utils.endswith(s, c)) {\n let p = s.length - 1;\n while (p > 0) {\n p = s.lastIndexOf(c, p - 1);\n if (p <= 0 || s.substring(p - 1, p) != '\\\\')\n break;\n }\n\n if (p > 0 && p < s.length - 1) {\n tag = s.substring(p + 1, s.length - 1);\n s = s.substring(0, p);\n }\n }\n if (tag != null)\n tag = unescape(tag.replace(new RegExp('\\\\' + c, 'g'), c));\n return {tag: tag, str: s};\n}\n\nfunction unescape(s: string) {\n //@ts-ignore\n if (scil.Utils.isNullOrEmpty(s))\n return s;\n\n return s.replace(/[\\\\]./g, function(m) {\n switch (m) {\n case '\\\\r':\n return '\\r';\n case '\\\\n':\n return '\\n';\n case '\\\\t':\n return '\\t';\n default:\n return m.substring(1);\n }\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","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {after, before, category, delay, expect, test, expectArray} from '@datagrok-libraries/utils/src/test';\n//import {findMonomers, helmToFasta, helmToPeptide, helmToRNA, initHelm} from '../package';\nimport {parseHelm} from '../utils';\n\nimport {_package} from '../package-test';\n\ncategory('Helm', () => {\n //These tests require webservice that is not present on test stand\n // test('helmToFasta', async () => {\n // expect(await helmToFasta('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), '>RNA1UTGCA');\n // expect(await helmToFasta('RNA1{P.R(U).P.R(T)}$$$$'), '>RNA1UT');\n // expect(await helmToFasta('PEPTIDE1{A.G}$$$$V2.0'), '>PEPTIDE1AG');\n // });\n //\n // test('helmToRNA', async () => {\n // expect(await helmToRNA('RNA1{R(U)P.R(T)P.R(G)P.R(C)P.R(A)}$$$$'), 'UTGCA');\n // expect(await helmToRNA('RNA1{P.R(U).P.R(T)}$$$$'), 'UT');\n // // eslint-disable-next-line max-len\n // expect(\n // await helmToRNA('RNA1{R(U)P.R(T)P}|RNA2{P.R(A)P.R(A)}$RNA1,RNA2,2:pair-6:pair|RNA1,RNA2,5:pair-3:pair$$$'), 'UT AA'\n // );\n // });\n //\n // test('helmToPeptide', async () => {\n // expect(await helmToPeptide('PEPTIDE1{A.G}$$$$V2.0'), 'AG');\n // expect(await helmToPeptide('PEPTIDE1{L.V.A}|PEPTIDE2{L.V.A}$$$$'), 'LVA LVA');\n // // eslint-disable-next-line max-len\n // expect(await helmToPeptide('PEPTIDE1{A.R.C.A.A.K.T.C.D.A}$PEPTIDE1,PEPTIDE1,8:R3-3:R3$$$'), 'ARCAAKTCDA');\n // });\n\n // detectMacromolecule is a function of Bio package\n // test('detectMacromolecule', async () => {\n // const file = await _package.files.readAsText('tests/test.csv');\n // const df = DG.DataFrame.fromCsv(file);\n // const col = df.columns.byName('HELM string');\n // await grok.data.detectSemanticTypes(df);\n // expect(col.semType, DG.SEMTYPE.MACROMOLECULE);\n // });\n\n // semType and units tags are detecting by Bio package function detectMacromolecule\n // test('detectHelm', async () => {\n // const file = await _package.files.readAsText('tests/test.csv');\n // const df = DG.DataFrame.fromCsv(file);\n // const col = df.columns.byName('HELM string');\n // await grok.data.detectSemanticTypes(df);\n // expect(col.tags[DG.TAGS.UNITS], 'HELM');\n // });\n\n const complexMonomers = [\n // tests parsing of complex monomemer in square brackets like [L-hArg(Et,Et)]\n 'PEPTIDE1{[L-hArg(Et,Et)].E.F.G}|PEPTIDE2{C.E}$PEPTIDE1,PEPTIDE2,2:R3-1:R1$$$V2.0',\n // tests parsing of complex monomer and one as a side chain as well\n 'PEPTIDE1{[L-hArg(Et,Et)]([L-hArg(Et,Et)]).E.F.G}$$$$',\n // tests parsing of complex monomer and one as a side chain as well\n 'RNA1{[dhp]([m1A])p.r(T)p.r(T)p.r(G)p}$$$$V2.0',\n // tests complex monomer as side chain\n 'RNA1{r([mo6pur])p.r(T)p.r(T)p.r(G)p}$$$$V2.0',\n // test complex monomer, side chain and linker\n 'RNA1{[afhna]([mo6pur])[36SS].r(T)p}$$$$V2.0'\n ];\n\n const complexMonomersExpected = [\n ['L-hArg(Et,Et)', 'E', 'F', 'G', 'C', 'E'],\n ['L-hArg(Et,Et)', 'L-hArg(Et,Et)', 'E', 'F', 'G'],\n ['dhp', 'm1A', 'p', 'r', 'T', 'p', 'r', 'T', 'p', 'r', 'G', 'p'],\n ['r', 'mo6pur', 'p', 'r', 'T', 'p', 'r', 'T', 'p', 'r', 'G', 'p'],\n ['afhna', 'mo6pur', '36SS', 'r', 'T', 'p']\n ];\n\n const complexTestNames = [\n 'comples-monomer', 'complex-monomer+side-chain', 'complex-monomer+side-chain-RNA',\n 'complex-side-chain', 'complex+side-chain+linker'\n ];\n test('parseHelm', async () => {\n const expectedResults = [\n ['meI', 'hHis', 'Aca', 'N', 'T', 'dK', 'Thr_PO3H2', 'D-Tyr_Et', 'Aze', 'dV', 'E', 'Phe_4Me'],\n ['A', 'C', 'T', 'G', 'W', 'E', 'Q'],\n ['R', 'U', 'P', 'T', 'A'],\n ['A', '*', 'G', 'C']\n ];\n const helmStrings = [\n 'PEPTIDE1{meI.hHis.Aca.N.T.dK.Thr_PO3H2.Aca.D-Tyr_Et.Aze.dV.E.N.dV.Phe_4Me}$$$',\n // eslint-disable-next-line max-len\n 'PEPTIDE1{A.C.T.G.C.T.W.G.T.W.E.C.W.C.Q.W}|PEPTIDE2{A.C.T.G.C.T.W.G.T.W.E.Q}$PEPTIDE1,PEPTIDE1,5:R3-14:R3|PEPTIDE2,PEPTIDE1,2:R3-12:R3$$$',\n 'RNA1{R(U)P.R(T)P}|RNA2{P.R(A)P.R(A)}$RNA1,RNA2,2:pair-6:pair|RNA1,RNA2,5:pair-3:pair$$$',\n 'PEPTIDE1{A.*.G.C}$$$$V2.0'\n ];\n for (let idx = 0; idx < helmStrings.length; ++idx) {\n const monomerSet = new Set(parseHelm(helmStrings[idx]));\n const monomerArray = Array.from(monomerSet);\n expect(JSON.stringify(monomerArray), JSON.stringify(expectedResults[idx]));\n }\n });\n complexMonomers.forEach((helm, i) => {\n test(complexTestNames[i], async () => {\n const monomersArray = parseHelm(helm);\n monomersArray.sort();\n const expected = complexMonomersExpected[i];\n expected.sort();\n expectArray(monomersArray, expected);\n });\n });\n});\n","export const HELM_CORE_LIB_FILENAME = '/data/HELMCoreLibrary.json';\n// core fields of HELM library object used in toAtomicLevel function\nexport const HELM_CORE_FIELDS = [\n \"symbol\" /* HELM_FIELDS.SYMBOL */,\n \"molfile\" /* HELM_FIELDS.MOLFILE */,\n \"rgroups\" /* HELM_FIELDS.RGROUPS */,\n \"name\" /* HELM_FIELDS.NAME */,\n // HELM_FIELDS.MONOMER_TYPE, // add if terminal monomers for PEPTIDEs to be\n // supported\n];\nexport const SDF_MONOMER_NAME = 'MonomerName';\n/** For PolyTool */\nexport const helmFieldsToPolyToolInputFields = {\n [\"symbol\" /* HELM_REQUIRED_FIELDS.SYMBOL */]: 'Short Name',\n [\"name\" /* HELM_REQUIRED_FIELDS.NAME */]: 'Medium Name',\n [\"smiles\" /* HELM_REQUIRED_FIELDS.SMILES */]: 'SMILES',\n};\n/** For PolyTool */\nexport const R_GROUP_BLOCK_DUMMY = [\n {\n 'capGroupSmiles': '[*:1][H]',\n 'alternateId': 'R1-H',\n 'capGroupName': 'H',\n 'label': 'R1'\n },\n {\n 'capGroupSmiles': 'O[*:2]',\n 'alternateId': 'R2-OH',\n 'capGroupName': 'OH',\n 'label': 'R2'\n },\n {\n 'capGroupSmiles': '[*:3][H]',\n 'alternateId': 'R3-H',\n 'capGroupName': 'H',\n 'label': 'R3'\n }\n];\n// todo: ideally, keys should be expressed via constants\nexport const jsonSdfMonomerLibDict = {\n 'monomerType': null,\n 'smiles': null,\n 'name': 'MonomerName',\n 'author': null,\n 'molfile': 'molecule',\n 'naturalAnalog': 'MonomerNaturalAnalogCode',\n 'rgroups': 'MonomerCaps',\n 'createDate': null,\n 'id': null,\n 'polymerType': 'MonomerType',\n 'symbol': 'MonomerCode'\n};\nexport const DUMMY_MONOMER = {\n 'monomerType': 'Backbone',\n 'smiles': '',\n 'name': '',\n 'author': 'Datagrok',\n 'molfile': '',\n 'naturalAnalog': '',\n 'rgroups': [],\n 'createDate': null,\n 'id': 0,\n 'polymerType': 'PEPTIDE',\n 'symbol': ''\n};\n// range of hex nubers used in PepSea library to endode monomers\nexport const MONOMER_ENCODE_MIN = 0x100;\nexport const MONOMER_ENCODE_MAX = 0x40A;\nexport const RIBOSE_SYMBOL = 'r';\nexport const DEOXYRIBOSE_SYMBOL = 'd';\nexport const PHOSPHATE_SYMBOL = 'p';\nexport const HELM_WRAPPERS_REGEXP = new RegExp(`[${RIBOSE_SYMBOL}${DEOXYRIBOSE_SYMBOL}]\\\\((\\\\w)\\\\)${PHOSPHATE_SYMBOL}?`, 'g');\n//# sourceMappingURL=const.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZS1kZWNsYXJhdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0eXBlLWRlY2xhcmF0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLFlBQVk7Q0FBRztBQUUzQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sTUFBTyxTQUFRLEtBQWE7Q0FBRztBQUU1Qzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sV0FBWSxTQUFRLE1BQU07Q0FBRztBQUUxQzs7Ozs7O0dBTUc7QUFDSCxNQUFNLE9BQU8sT0FBUSxTQUFRLEtBQVU7Q0FBRyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbi8qKlxuICogRGVub3RlcyBhIHZlY3RvciBvZiBmbG9hdGluZyBwb2l0IHZhbHVlcy5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAY2xhc3MgVmVjdG9yXG4gKiBAZXh0ZW5kcyB7RmxvYXQzMkFycmF5fVxuICovXG5leHBvcnQgY2xhc3MgVmVjdG9yIGV4dGVuZHMgRmxvYXQzMkFycmF5IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIHR3by1kaW1lbnNpb25hbCBtYXRyaXguXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIE1hdHJpeFxuICogQGV4dGVuZHMge0FycmF5PFZlY3Rvcj59XG4gKi9cbmV4cG9ydCBjbGFzcyBNYXRyaXggZXh0ZW5kcyBBcnJheTxWZWN0b3I+IHt9XG5cbi8qKlxuICogRGVub3RlcyBjYXJ0ZXNpYW4gY29vcmRpbmF0ZXMuXG4gKlxuICogQGV4cG9ydFxuICogQGNsYXNzIENvb3JkaW5hdGVzXG4gKiBAZXh0ZW5kcyB7TWF0cml4fVxuICovXG5leHBvcnQgY2xhc3MgQ29vcmRpbmF0ZXMgZXh0ZW5kcyBNYXRyaXgge31cblxuLyoqXG4gKiBEZW5vdGVzIGFuIGFycmF5IG9mIGFyYml0cmFyeS10eXBlZCB2ZWN0b3JzLlxuICpcbiAqIEBleHBvcnRcbiAqIEBjbGFzcyBWZWN0b3JzXG4gKiBAZXh0ZW5kcyB7QXJyYXk8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzIFZlY3RvcnMgZXh0ZW5kcyBBcnJheTxhbnk+IHt9XG5cbi8qKlxuICogRGVub3RlcyBhIGRpY3Rpb25hcnkgY29udGFpbmluZyBmdW5jdGlvbiBvcHRpb25zLlxuICpcbiAqIEBleHBvcnRcbiAqIEB0eXBlIE9wdGlvbnNcbiAqL1xuZXhwb3J0IHR5cGUgT3B0aW9ucyA9IHtbbmFtZTogc3RyaW5nXTogYW55fTtcblxuLyoqXG4gKiBEZW5vdGVzIGN1c3RvbSBkaXN0YW5jZSBtZXRyaWMgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHZlY3RvcnMuXG4gKlxuICogQGV4cG9ydFxuICogQHR5cGUgRGlzdGFuY2VNZXRyaWNcbiAqIEBwYXJhbSB7YW55fSB2MSBUaGUgZmlyc3QgdmVjdG9yLlxuICogQHBhcmFtIHthbnl9IHYyIFRoZSBzZWNvbmQgdmVjdG9yLlxuICogQHJldHVybiB7bnVtYmVyfSBEaXN0YW5jZSBiZXR3ZWVuIHRoZXNlIHR3byB2ZWN0b3JzLlxuICovXG5leHBvcnQgdHlwZSBEaXN0YW5jZU1ldHJpYyA9ICh2MTogYW55LCB2MjogYW55KSA9PiAobnVtYmVyKTtcblxuLyoqXG4gKiBEZW5vdGVzIGEgc2ltcGxlIHN0cmluZyB0byBzdHJpbmcgZGljdGlvbmFyeS5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAdHlwZSBTdHJpbmdEaWN0aW9uYXJ5XG4gKi9cbmV4cG9ydCB0eXBlIFN0cmluZ0RpY3Rpb25hcnkgPSB7W2tleTogc3RyaW5nXTogc3RyaW5nfTtcblxuXG5leHBvcnQgdHlwZSBDb2x1bW5JbnB1dE9wdGlvbnMgPSB7XG4gICAgZmlsdGVyPzogKGNvbDogREcuQ29sdW1uKSA9PiBib29sZWFuIHwgbnVsbDtcbn07XG4iXX0=","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[\"MONOMER_CHEMICAL_DISTANCE\"] = \"Monomer chemical distance\";\n})(MmDistanceFunctionsNames || (MmDistanceFunctionsNames = {}));\n;\nexport const mmDistanceFunctions = {\n [MmDistanceFunctionsNames.HAMMING]: hamming,\n [MmDistanceFunctionsNames.LEVENSHTEIN]: levenstein,\n [MmDistanceFunctionsNames.NEEDLEMANN_WUNSCH]: needlemanWunch,\n [MmDistanceFunctionsNames.MONOMER_CHEMICAL_DISTANCE]: hamming\n};\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFjcm9tb2xlY3VsZS1kaXN0YW5jZS1mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYWNyb21vbGVjdWxlLWRpc3RhbmNlLWZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBR2xEOzs7O0dBSUc7QUFDSCxNQUFNLENBQU4sSUFBWSx3QkFLWDtBQUxELFdBQVksd0JBQXdCO0lBQ2hDLCtDQUFtQixDQUFBO0lBQ25CLHVEQUEyQixDQUFBO0lBQzNCLG1FQUF1QyxDQUFBO0lBQ3ZDLG1GQUF1RCxDQUFBO0FBQzNELENBQUMsRUFMVyx3QkFBd0IsS0FBeEIsd0JBQXdCLFFBS25DO0FBQUEsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUE4RTtJQUM1RyxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxFQUFFLE9BQU87SUFDM0MsQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxVQUFVO0lBQ2xELENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsRUFBRSxjQUFjO0lBQzVELENBQUMsd0JBQXdCLENBQUMseUJBQXlCLENBQUMsRUFBRSxPQUFPO0NBQzlELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhbW1pbmd9IGZyb20gJy4vaGFtbWluZyc7XG5pbXBvcnQge2xldmVuc3RlaW59IGZyb20gJy4vbGV2ZW5zdGVpbic7XG5pbXBvcnQge25lZWRsZW1hbld1bmNofSBmcm9tICcuL25lZWRsZW1hbi13dW5zY2gnO1xuaW1wb3J0IHttbURpc3RhbmNlRnVuY3Rpb25UeXBlfSBmcm9tICcuL3R5cGVzJztcblxuLyoqIEVudW0gY29udGFpbmluZyBjdXJyZW50bHkgc3VwcG9ydGVkIG1hY3JvbW9sZWN1bGUgZGlzdGFuY2UgZnVuY3Rpb25zXG4gKiBIYW1taW5nIGRpc3RhbmNlIHdpbGwgYmUgdXNlZCBpZiB0aGUgc2VxdWVuY2VzIGFyZSBhbHJlYWR5IGFsaWduZWRcbiAqIE5lZWRsZW1hbiBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgZm9yIHByb3RlaW4gc2VxdWVuY2VzIHdpdGgga25vd24gQkxPU1VNNjIgbWF0cml4XG4gKiBMZXZlbnNodGVpbiBkaXN0YW5jZSB3aWxsIGJlIHVzZWQgZm9yIG51Y2xlb3RpZGUgc2VxdWVuY2VzIGFzIGZvciB0aGVtIHN1YnN0aXR1dGlvbiBtYXRyaXggaXMgc2FtZSBhcyBpZGVudGl0eSBtYXRyaXhcbiAqL1xuZXhwb3J0IGVudW0gTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzIHtcbiAgICBIQU1NSU5HID0gJ0hhbW1pbmcnLFxuICAgIExFVkVOU0hURUlOID0gJ0xldmVuc2h0ZWluJyxcbiAgICBORUVETEVNQU5OX1dVTlNDSCA9ICdOZWVkbGVtYW5uLVd1bnNjaCcsXG4gICAgTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRSA9ICdNb25vbWVyIGNoZW1pY2FsIGRpc3RhbmNlJ1xufTtcblxuZXhwb3J0IGNvbnN0IG1tRGlzdGFuY2VGdW5jdGlvbnM6IFJlY29yZDxNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMsICh2YWx1ZT86IGFueSkgPT4gbW1EaXN0YW5jZUZ1bmN0aW9uVHlwZT4gPSB7XG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuSEFNTUlOR106IGhhbW1pbmcsXG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTEVWRU5TSFRFSU5dOiBsZXZlbnN0ZWluLFxuICBbTW1EaXN0YW5jZUZ1bmN0aW9uc05hbWVzLk5FRURMRU1BTk5fV1VOU0NIXTogbmVlZGxlbWFuV3VuY2gsXG4gIFtNbURpc3RhbmNlRnVuY3Rpb25zTmFtZXMuTU9OT01FUl9DSEVNSUNBTF9ESVNUQU5DRV06IGhhbW1pbmdcbn07XG4iXX0=","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';\nimport { HELM_WRAPPERS_REGEXP, PHOSPHATE_SYMBOL } from './const';\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 allowed, only if alphabet tag is annotated\n if (!uh.column.getTag(\"alphabet\" /* TAGS.alphabet */) && Object.keys(stats.freq).length === 0)\n throw new Error('Alphabet is empty and not annotated.');\n let aligned = uh.column.getTag(\"aligned\" /* TAGS.aligned */);\n if (aligned === null) {\n aligned = stats.sameLength ? \"SEQ.MSA\" /* ALIGNMENT.SEQ_MSA */ : \"SEQ\" /* ALIGNMENT.SEQ */;\n uh.column.setTag(\"aligned\" /* TAGS.aligned */, aligned);\n }\n let alphabet = uh.column.getTag(\"alphabet\" /* TAGS.alphabet */);\n if (alphabet === null) {\n alphabet = detectAlphabet(stats.freq, candidateAlphabets);\n uh.column.setTag(\"alphabet\" /* TAGS.alphabet */, alphabet);\n }\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 = this.splitted.length === 0 ? 0 :\n Math.max(...this.splitted.map((seqS) => seqS.length));\n }\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()) ? 'RNA1{' :\n (this.isRna() || this.isHelmCompatible()) ? 'RNA1{' : 'PEPTIDE1{';\n const postfix = '}$$$$';\n const leftWrapper = (this.isDna()) ? 'd(' :\n (this.isRna()) ? 'r(' : '';\n const rightWrapper = (this.isDna() || this.isRna()) ? ')p' : '';\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.LEVENSHTEIN;\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 isNucleotide = 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(HELM_WRAPPERS_REGEXP, '');\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}\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(HELM_WRAPPERS_REGEXP, '$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(HELM_WRAPPERS_REGEXP, '$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(HELM_WRAPPERS_REGEXP, '$1');\n m = m === PHOSPHATE_SYMBOL ? null : m;\n }\n tgtMList[mI] = m;\n }\n return tgtMList.filter((m) => m !== null);\n}\n//# sourceMappingURL=units-handler.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 {_package} from '../package-test';\nimport {after, before, category, delay, expect, expectObject, test} from '@datagrok-libraries/utils/src/test';\nimport {findMonomers, parseHelm} from '../utils';\nimport {getMonomerLibHelper, IMonomerLibHelper} from '@datagrok-libraries/bio/src/monomer-works/monomer-utils';\n\nconst LIB_STORAGE_NAME = 'Libraries';\nexport const LIB_DEFAULT: { [fileName: string]: string } = {'HELMCoreLibrary.json': 'HELMCoreLibrary.json'};\n\n\n/** Tests with default monomer library */\ncategory('findMonomers', () => {\n\n let monomerLibHelper: IMonomerLibHelper;\n /** Backup actual user's monomer libraries settings */\n let userLibrariesSettings: any = null;\n\n before(async () => {\n monomerLibHelper = await getMonomerLibHelper();\n userLibrariesSettings = await grok.dapi.userDataStorage.get(LIB_STORAGE_NAME, true);\n\n // Tests 'findMonomers' requires default monomer library loaded\n await grok.dapi.userDataStorage.post(LIB_STORAGE_NAME, LIB_DEFAULT, true);\n await monomerLibHelper.loadLibraries(true); // load default libraries\n });\n\n after(async () => {\n await grok.dapi.userDataStorage.put(LIB_STORAGE_NAME, userLibrariesSettings, true);\n });\n\n const tests: { [testName: string]: { test: string, tgt: Set<string> } } = {\n 'withoutMissed': {\n test: 'PEPTIDE1{meI.hHis.Aca.N.T.dE.Thr_PO3H2.Aca.D-Tyr_Et}$$$$',\n tgt: new Set<string>(),\n },\n 'withMissed':\n {\n test: 'PEPTIDE1{meI.missed2.Aca.N.T.dE.Thr_PO3H2.Aca.D-Tyr_Et}$$$$',\n tgt: new Set<string>(['missed2'])\n }\n };\n\n for (const [testName, testData] of Object.entries(tests)) {\n test(testName, async () => {\n _testFindMonomers(testData.test, testData.tgt);\n });\n }\n\n function _testFindMonomers(testHelmValue: string, tgtMissedSet: Set<string>): void {\n const monomerSymbolList: string[] = parseHelm(testHelmValue);\n const resMissedSet: Set<string> = findMonomers(monomerSymbolList);\n expectObject(resMissedSet, tgtMissedSet);\n }\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/** Calculates chemical similarity between each pair of monomers.\n * @param {string[]} monomerSet Set of unique monomers.\n * @returns {Promise<{scoringMatrix: number[][], alphabetIndexes: {[monomerId: string]: number}}>} Ojbect containing similarity scoring matrix and monomer to index mapping. */\nexport async function calculateMonomerSimilarity(monomerSet) {\n const libHelper = await getMonomerLibHelper();\n const monomerLib = libHelper.getBioLib();\n const scoringMatrix = [];\n const alphabetIndexes = {};\n const monomerMolecules = monomerSet.map((monomer) => monomerLib.getMonomer('PEPTIDE', monomer)?.smiles ?? '');\n const monomerMoleculesCol = DG.Column.fromStrings('smiles', monomerMolecules);\n for (let monomerIndex = 0; monomerIndex < monomerMolecules.length; ++monomerIndex) {\n const monomer = monomerSet[monomerIndex];\n alphabetIndexes[monomer] = monomerIndex;\n const monomerMol = monomerMolecules[monomerIndex];\n const similarityScores = monomerMol === '' ? new Array(monomerMolecules.length).fill(0) :\n (await grok.chem.getSimilarities(monomerMoleculesCol, monomerMol)).getRawData();\n similarityScores[monomerIndex] = 1;\n scoringMatrix[monomerIndex] = Array.from(similarityScores);\n }\n return { scoringMatrix, alphabetIndexes };\n}\n//# sourceMappingURL=monomer-utils.js.map","const __WEBPACK_NAMESPACE_OBJECT__ = $;","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport $ from 'cash-dom';\n\nimport {category, expect, test, awaitCheck, delay} from '@datagrok-libraries/utils/src/test';\nimport {NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule';\nimport {TAGS as helmTAGS} from '../constants';\n\ncategory('renderers', () => {\n test('missedInLib', async () => { await _testMissedInLib(); });\n});\n\nasync function _testMissedInLib() {\n const df: DG.DataFrame = await grok.dapi.files.readCsv('System:AppData/Helm/tests/sample_HELM-missedInLib.csv');\n const helmCol: DG.Column<string> = df.getCol('HELM');\n\n const tv: DG.TableView = grok.shell.addTableView(df);\n await awaitCheck(() => {\n return $(tv.root).find('.d4-grid canvas').length > 0;\n }, 'Table view canvas not found', 100);\n\n expect(helmCol.semType, DG.SEMTYPE.MACROMOLECULE);\n expect(helmCol.getTag(DG.TAGS.UNITS), NOTATION.HELM);\n expect(helmCol.getTag(DG.TAGS.CELL_RENDERER), 'helm');\n\n const cellRendererErrorJson: string = helmCol.getTag(helmTAGS.cellRendererRenderError);\n if (!!cellRendererErrorJson) {\n const cellRendererError: any = JSON.parse(cellRendererErrorJson);\n const err = new Error(cellRendererError['message']);\n err.stack = cellRendererError['stack'];\n throw err;\n }\n}\n","import * as DG from 'datagrok-api/dg';\nimport * as grok from 'datagrok-api/grok';\nimport {runTests, tests, TestContext} from '@datagrok-libraries/utils/src/test';\n\nimport './tests/helm-tests.ts';\nimport './tests/findMonomers-tests';\nimport './tests/renderers-tests';\n\nexport const _package = new DG.Package();\nexport {tests};\n\n\n//name: test\n//input: string category {optional: true}\n//input: string test {optional: true}\n//input: object testContext {optional: true}\n//output: dataframe result\nexport async function test(category: string, test: string, testContext: TestContext): Promise<DG.DataFrame> {\n const data = await runTests({category, test, testContext});\n return DG.DataFrame.fromObjects(data)!;\n}\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","DG","grok","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","result","done","then","apply","STANDART_TIMEOUT","tests","autoTestsCatName","wasRegistered","currentCategory","assure","notNull","name","Error","TestContext","constructor","catchUnhandled","report","this","undefined","Test","category","test","options","_a","timeout","push","expect","actual","expected","error","expectFloat","tolerance","Number","POSITIVE_INFINITY","NEGATIVE_INFINITY","NaN","isNaN","areEqual","Math","abs","expectObject","expectedKey","expectedValue","entries","actualValue","Array","expectArray","isFinite","actualLength","length","expectedLength","i","tests_","clear","before","after","addNamespace","s","f","replace","RegExp","nqName","execTest","t","predicate","categoryTimeout","packageName","_b","_c","_d","_e","r","filter","toLowerCase","skip","skipReason","console","log","start","Date","success","ms","skipped","timeout_","x","toString","stop","params","res","keys","reduce","acc","k","assign","delay","setTimeout","func","testTimeout","timeoutPromise","_","race","clearTimeout","parseHelm","split","monomers","scil","Utils","isNullOrEmpty","seqs","p","detachAnnotation","str","indexOf","substring","ss","monomer","startsWith","includes","element","residue","endsWith","lastIndexOf","firstPiece","thirdPiece","elements","el","sep","ret","frag","parentheses","bracket","braces","quote","c","c2","_detachAppendix","tag","repeat","endswith","m","NOTATION","complexMonomersExpected","complexTestNames","expectedResults","helmStrings","idx","monomerSet","Set","monomerArray","from","JSON","stringify","forEach","helm","monomersArray","sort","wu","CandidateType","alphabet","cutoff","fasta","peptide","dna","rna","Float32Array","static","dt","simplified","PaletteType","palette","cp","objList","colour","ind","colourPalette","_palette","undefinedColor","Lesk","lesk","makePalette","GrokGroups","grokGroups","RasMol","rasMol","resM","aaSynonyms","super","Aminoacids","scheme","isInner","inner","outer","char","parseInt","chemPaletteInstance","getPalette","outerMonomer","innerMonomer","getInnerOuter","slice","amino","toUpperCase","AAFullNames","SemType","SemTypeMultipleAlignment","Names","AASmiles","AASmilesTruncated","Nucleotides","UnknownColorPalette","concat","values","pI","hash","charCodeAt","hashCode","color","dgColor","g","b","distToBlack","sqrt","pow","correctColor","buildPalette","Uint32Array","MmDistanceFunctionsNames","HAMMING","LEVENSHTEIN","NEEDLEMANN_WUNSCH","MONOMER_CHEMICAL_DISTANCE","uhTemp","LIB_STORAGE_NAME","LIB_DEFAULT","monomerLibHelper","userLibrariesSettings","async","funcList","package","prepare","getOutputParamValue","loadLibraries","tgt","testName","testData","_testFindMonomers","testHelmValue","tgtMissedSet","monomerSymbolList","types","org","webeditor","monomerTypeList","monomerNames","Monomers","getMonomerSet","id","val","findMonomers","$","df","helmCol","getCol","tv","checkHandler","wait","interval","clearInterval","intervalId","setInterval","awaitCheck","root","find","semType","getTag","cellRendererErrorJson","cellRendererError","parse","err","stack","_testMissedInLib","_package","testContext","data","package_","packageId","moduleTests","moduleAutoTests","packFunctions","list","reg","isArray","matchAll","map","arr","cat","initAutoTests","results","beforeStatus","all","afterStatus","logger","successful","failed","description","runTests"],"sourceRoot":""}