diff --git a/README.md b/README.md
index 001b42f..3eb2feb 100644
--- a/README.md
+++ b/README.md
@@ -48,11 +48,7 @@ npm run build-dev
4. Choose how to annotate proteins (this will prob, because of https://github.com/MICommunity/ComplexViewer/issues/80):
- myComplexViewer.setAnnotations("MI features"); //show features from MI data
- myComplexViewer.setAnnotations("UniprotKB"); //show annotations from uniprot
- myComplexViewer.setAnnotations("SuperFamily"); //from SuperFamily
- myComplexViewer.setAnnotations("None"); //no annotations
- myComplexViewer.setAnnotations("Interactor"); //colour bars and circles according to interactor (may help indicate stoichiometry)
+ // todo doc - see index.html for example, old way of doing should still be working
5. To change dataset without creating a new instance of the app,
call the clear function, then call the readMijson() function with the new data:
diff --git a/css/style.css b/css/style.css
index da07ffc..50a24bf 100755
--- a/css/style.css
+++ b/css/style.css
@@ -57,54 +57,54 @@
}
/*tables*/
-table {
- width: 100%;
- font-size: 0.9em;
- left: auto;
- position: relative;
- margin-left: auto;
- margin-right: auto;
- border-collapse: collapse;
- /*
- background-color: rgba(255, 255, 255, 1);
- */
- text-align: left;
-}
+/*table {*/
+/* width: 100%;*/
+/* font-size: 0.9em;*/
+/* left: auto;*/
+/* position: relative;*/
+/* margin-left: auto;*/
+/* margin-right: auto;*/
+/* border-collapse: collapse;*/
+/* !**/
+/* background-color: rgba(255, 255, 255, 1);*/
+/* *!*/
+/* text-align: left;*/
+/*}*/
-thead {
- margin-top: 10px;
- margin-bottom: 10px;
-}
+/*thead {*/
+/* margin-top: 10px;*/
+/* margin-bottom: 10px;*/
+/*}*/
-th {
- padding-left: 5px;
- padding-right: 5px;
- vertical-align: middle;
- height: 30px;
-}
+/*th {*/
+/* padding-left: 5px;*/
+/* padding-right: 5px;*/
+/* vertical-align: middle;*/
+/* height: 30px;*/
+/*}*/
-td {
- padding-left: 5px;
- padding-right: 5px;
- vertical-align: middle;
- text-align: left;
-}
+/*td {*/
+/* padding-left: 5px;*/
+/* padding-right: 5px;*/
+/* vertical-align: middle;*/
+/* text-align: left;*/
+/*}*/
-th:first-child {
- padding-left: 10px;
-}
+/*th:first-child {*/
+/* padding-left: 10px;*/
+/*}*/
-th:last-child {
- padding-right: 10px;
-}
+/*th:last-child {*/
+/* padding-right: 10px;*/
+/*}*/
-td:first-child {
- padding-left: 10px;
-}
+/*td:first-child {*/
+/* padding-left: 10px;*/
+/*}*/
-td:last-child {
- padding-right: 10px;
-}
+/*td:last-child {*/
+/* padding-right: 10px;*/
+/*}*/
/* fa */
@@ -152,19 +152,19 @@ body, input, select, textarea, button {
color: #fff;
}
-.tableContainer a {
- color: #091D42;
- text-decoration: underline;
- -webkit-transition: all 200ms ease-in-out;
- -moz-transition: all 200ms ease-in-out;
- -o-transition: all 200ms ease-in-out;
- transition: all 200ms ease-in-out;
-}
+/*.tableContainer a {*/
+/* color: #091D42;*/
+/* text-decoration: underline;*/
+/* -webkit-transition: all 200ms ease-in-out;*/
+/* -moz-transition: all 200ms ease-in-out;*/
+/* -o-transition: all 200ms ease-in-out;*/
+/* transition: all 200ms ease-in-out;*/
+/*}*/
-.tableContainer a:hover {
- color: #ffffff !important;
- background-color: #091D42;
-}
+/*.tableContainer a:hover {*/
+/* color: #ffffff !important;*/
+/* background-color: #091D42;*/
+/*}*/
#main {
@@ -184,49 +184,6 @@ body, input, select, textarea, button {
padding-left: 10px;
}
-
-/*
-#networkDiv {
- width:100%;
- height:100%;
- display:block;
-}
-*/
-
-/*.bar rect {
- fill: steelblue;
-}
-
-.bar text {
- fill: #fff;
-}
-
-.resize path {
- fill: #888;
- stroke: #000;
- stroke-width: 2px;
-}
-
-.axis path, .axis line {
- fill: none;
- stroke: #000;
- stroke-width: 1px;
-}
-
-.panelInner th {
- font-weight: 400;
- color: #039;
- height: 30px;
-}
-
-.panelInner thead td {
- color: #091D42;
-}
-
-.panelInner td, .helpPanel td {
- color: #777;
-}*/
-
.controls {
background: #ecedf2;
color: #091D42;
@@ -240,33 +197,27 @@ body, input, select, textarea, button {
/* margin-right: 0.5em;*/
/*}*/
-label.horizontalFlow input[type=number] {
- margin-left: 0.2em;
-}
-
-/* See http://jsfiddle.net/7jx02upg/1/ */
-label.horizontalFlow input[type=radio], label.horizontalFlow input[type=checkbox] {
- /*vertical-align: normal;*/
-}
+/*label.horizontalFlow input[type=number] {*/
+/* margin-left: 0.2em;*/
+/*}*/
-/*
+/*!* See http://jsfiddle.net/7jx02upg/1/ *!*/
+/*label.horizontalFlow input[type=radio], label.horizontalFlow input[type=checkbox] {*/
+/* !*vertical-align: normal;*!*/
+/*}*/
-/* span.noBreak asks for no line-breaks internally */
+/*!* */
-span.noBreak select {
- margin-left: 0.5em;
-}
+/*!* span.noBreak asks for no line-breaks internally *!*/
-/* and then put spaces after labels to give a known place for content to break */
+/*span.noBreak select {*/
+/* margin-left: 0.5em;*/
+/*}*/
-A.btn {
- text-decoration: none;
-}
+/*!* and then put spaces after labels to give a known place for content to break *!*/
-/* For use with Split.js */
+/*A.btn {*/
+/* text-decoration: none;*/
+/*}*/
-.btn:disabled {
- color: gray;
- border-color: gray;
-}
diff --git a/data/index.js b/data/index.js
index 2a10fc3..a6db25e 100644
--- a/data/index.js
+++ b/data/index.js
@@ -1,5 +1,10 @@
// eslint-disable-next-line no-unused-vars
const exampleIndex = [
+ {
+ "ac": "CPX-1920",
+ "name": "~CPX-1920",
+ "url": "https://www.ebi.ac.uk/complexportal/complex/CPX-1920",
+ },
{
"ac": "EBI-9008420",
"name": "Hemoglobin HbA complex",
@@ -10,11 +15,6 @@ const exampleIndex = [
"name": "EBI-12598622",
"url": "https://ebi-intact.github.io/intact-view/details/interaction/EBI-12598622",
},
- {
- "ac": "CPX-1920",
- "name": "~CPX-1920",
- "url": "https://www.ebi.ac.uk/complexportal/complex/CPX-1920",
- },
{
"ac": "EBI-4371590",
"name": "EBI-4371590",
diff --git a/dist/complexviewer.js b/dist/complexviewer.js
index a0186e7..f63fd56 100644
--- a/dist/complexviewer.js
+++ b/dist/complexviewer.js
@@ -103,7 +103,7 @@ return /******/ (function(modules) { // webpackBootstrap
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
-eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \".protein {\\n cursor: crosshair;\\n}\\n\\n.link {\\n /*\\n cursor: crosshair;\\n */\\n}\\n\\n/*you need this to stop horrible looking flickering of text as you drag*/\\nsvg {\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.xlv_text {\\n /*font-weight: bold;*/\\n text-shadow: -1px -1px 0 white,\\n 1px -1px 0 white,\\n -1px 1px 0 white,\\n 1px 1px 0 white;\\n /* -2px -1px 0 white,\\n 2px -1px 0 white,\\n -2px 1px 0 white,\\n 2px 1px 0 white;*/\\n}\\n\\n.proteinLabel {\\n font-size: 10pt;\\n /*font-weight: bold;*/\\n}\\n\\n.custom-menu-margin {\\n padding: 20px;\\n display: none;\\n z-index: 10000;\\n position: absolute;\\n}\\n\\n.custom-menu {\\n overflow: hidden;\\n border: 1px solid #CCC;\\n white-space: nowrap;\\n /*\\n font-family: sans-serif;\\n*/\\n background: #FFF;\\n color: #333;\\n list-style: none;\\n padding: 0;\\n margin: 0;\\n pointer-events: all;\\n}\\n\\n.custom-menu li {\\n padding: 8px 12px;\\n cursor: pointer;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.custom-menu li:hover {\\n background-color: #DEF;\\n}\\n\\n.barScale {\\n display: inline;\\n padding-left: 10px;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3NyYy9jc3MveGluZXQuY3NzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9jc3MveGluZXQuY3NzP2Y0YzQiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xudmFyIF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyA9IHJlcXVpcmUoXCIuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCIpO1xuZXhwb3J0cyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhmYWxzZSk7XG4vLyBNb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5wcm90ZWluIHtcXG4gICAgY3Vyc29yOiBjcm9zc2hhaXI7XFxufVxcblxcbi5saW5rIHtcXG4gICAgLypcXG4gICAgICAgY3Vyc29yOiBjcm9zc2hhaXI7XFxuICAgICovXFxufVxcblxcbi8qeW91IG5lZWQgdGhpcyB0byBzdG9wIGhvcnJpYmxlIGxvb2tpbmcgZmxpY2tlcmluZyBvZiB0ZXh0IGFzIHlvdSBkcmFnKi9cXG5zdmcge1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLnhsdl90ZXh0IHtcXG4gICAgLypmb250LXdlaWdodDogYm9sZDsqL1xcbiAgICB0ZXh0LXNoYWRvdzogLTFweCAtMXB4IDAgd2hpdGUsXFxuICAgIDFweCAtMXB4IDAgd2hpdGUsXFxuICAgIC0xcHggMXB4IDAgd2hpdGUsXFxuICAgIDFweCAxcHggMCB3aGl0ZTtcXG4gICAgLyogICAtMnB4IC0xcHggMCB3aGl0ZSxcXG4gICAgICAgIDJweCAtMXB4IDAgd2hpdGUsXFxuICAgICAgICAtMnB4IDFweCAwIHdoaXRlLFxcbiAgICAgICAgMnB4IDFweCAwIHdoaXRlOyovXFxufVxcblxcbi5wcm90ZWluTGFiZWwge1xcbiAgICBmb250LXNpemU6IDEwcHQ7XFxuICAgIC8qZm9udC13ZWlnaHQ6IGJvbGQ7Ki9cXG59XFxuXFxuLmN1c3RvbS1tZW51LW1hcmdpbiB7XFxuICAgIHBhZGRpbmc6IDIwcHg7XFxuICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIHotaW5kZXg6IDEwMDAwO1xcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxufVxcblxcbi5jdXN0b20tbWVudSB7XFxuICAgIG92ZXJmbG93OiBoaWRkZW47XFxuICAgIGJvcmRlcjogMXB4IHNvbGlkICNDQ0M7XFxuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICAgIC8qXFxuICBmb250LWZhbWlseTogc2Fucy1zZXJpZjtcXG4qL1xcbiAgICBiYWNrZ3JvdW5kOiAjRkZGO1xcbiAgICBjb2xvcjogIzMzMztcXG4gICAgbGlzdC1zdHlsZTogbm9uZTtcXG4gICAgcGFkZGluZzogMDtcXG4gICAgbWFyZ2luOiAwO1xcbiAgICBwb2ludGVyLWV2ZW50czogYWxsO1xcbn1cXG5cXG4uY3VzdG9tLW1lbnUgbGkge1xcbiAgICBwYWRkaW5nOiA4cHggMTJweDtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLmN1c3RvbS1tZW51IGxpOmhvdmVyIHtcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogI0RFRjtcXG59XFxuXFxuLmJhclNjYWxlIHtcXG4gICAgZGlzcGxheTogaW5saW5lO1xcbiAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XFxufVxcblwiLCBcIlwiXSk7XG4vLyBFeHBvcnRzXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHM7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/css-loader/dist/cjs.js!./src/css/xinet.css\n");
+eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \"/*you need this to stop horrible looking flickering of text as you drag*/\\nsvg {\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.highlight {\\n stroke: #ffff99;\\n}\\n\\n.link {\\n stroke-linecap: round;\\n stroke: black;\\n}\\n\\n.certain-link {\\n opacity: 0.6;\\n stroke-opacity: 0.6;\\n}\\n\\n.uncertain-link {\\n opacity: 0.2;\\n stroke-opacity: 0.6;\\n}\\n\\n.link-line {\\n stroke-width: 1;\\n}\\n\\n.link-highlight {\\n stroke-width: 10;\\n stroke-opacity: 0;\\n}\\n\\n.complex-outline {\\n stroke: white;\\n stroke-linejoin: round;\\n stroke-width: 7;\\n}\\n\\n.linked-complex {\\n stroke: black;\\n stroke-linejoin: round;\\n stroke-width: 1;\\n}\\n\\nfeature-link {\\n fill: black;\\n}\\n\\n.protein {\\n cursor: crosshair;\\n}\\n\\n/*todo - seperate out outline*/\\n.label {\\n font-size: 10pt;\\n /*font-weight: bold;*/\\n\\n /*color: #fff;*/\\n /*text-shadow: white 0px 0px 1px;*/\\n -webkit-font-smoothing: antialiased;\\n\\n /*text-shadow: #fff 0px 0px 1px, #fff 0px 0px 1px, #fff 0px 0px 1px,*/\\n /*#fff 0px 0px 1px, #fff 0px 0px 1px, #fff 0px 0px 1px;*/\\n\\n text-shadow: -1px -1px 0 white,\\n 1px -1px 0 white,\\n -1px 1px 0 white,\\n 1px 1px 0 white;\\n /*-2px -1px 0 white,*/\\n /* 2px -1px 0 white,*/\\n /* -2px 1px 0 white,*/\\n /* 2px 1px 0 white;*/\\n fill: black;\\n text-anchor: end;\\n}\\n\\n.tooltip{\\n text-anchor: start;\\n}\\n\\n.outline {\\n stroke: black;\\n stroke-width: 1;\\n stroke-opacity: 1;\\n fill: white;\\n fill-opacity: 1;\\n}\\n\\n.participant-highlight {\\n stroke-width: 5;\\n fill: none;\\n}\\n\\n/*for protein bar scale*/\\n.tick {\\n stroke: black;\\n}\\n\\n.tick-labels {\\n font-size: 8pt;\\n text-anchor: middle;\\n}\\n\\n/*not working right*/\\n.sequence {\\n font-family: 'Courier New', monospace;\\n font-size: 10px;\\n text-anchor: middle;\\n}\\n\\n.custom-menu-margin {\\n padding: 20px;\\n display: none;\\n z-index: 10000;\\n position: absolute;\\n}\\n\\n.custom-menu {\\n overflow: hidden;\\n border: 1px solid #CCC;\\n white-space: nowrap;\\n background: #FFF;\\n color: #333;\\n list-style: none;\\n padding: 0;\\n margin: 0;\\n pointer-events: all;\\n}\\n\\n.custom-menu li {\\n padding: 8px 12px;\\n cursor: pointer;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.custom-menu li:hover {\\n background-color: #DEF;\\n}\\n\\n.barScale {\\n display: inline;\\n padding-left: 10px;\\n}\\n\\n.tooltip-background {\\n fill-opacity: 0.75;\\n stroke-opacity: 1;\\n stroke-width: 1;\\n}\\n\\n.tooltip-sub-background {\\n fill: white;\\n stroke: white;\\n opacity: 1;\\n stroke-width: 1;\\n}\", \"\"]);\n// Exports\nmodule.exports = exports;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3NyYy9jc3MveGluZXQuY3NzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9jc3MveGluZXQuY3NzP2Y0YzQiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xudmFyIF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyA9IHJlcXVpcmUoXCIuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCIpO1xuZXhwb3J0cyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhmYWxzZSk7XG4vLyBNb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi8qeW91IG5lZWQgdGhpcyB0byBzdG9wIGhvcnJpYmxlIGxvb2tpbmcgZmxpY2tlcmluZyBvZiB0ZXh0IGFzIHlvdSBkcmFnKi9cXG5zdmcge1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLmhpZ2hsaWdodCB7XFxuICAgIHN0cm9rZTogI2ZmZmY5OTtcXG59XFxuXFxuLmxpbmsge1xcbiAgICBzdHJva2UtbGluZWNhcDogcm91bmQ7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxufVxcblxcbi5jZXJ0YWluLWxpbmsge1xcbiAgICBvcGFjaXR5OiAwLjY7XFxuICAgIHN0cm9rZS1vcGFjaXR5OiAwLjY7XFxufVxcblxcbi51bmNlcnRhaW4tbGluayB7XFxuICAgIG9wYWNpdHk6IDAuMjtcXG4gICAgc3Ryb2tlLW9wYWNpdHk6IDAuNjtcXG59XFxuXFxuLmxpbmstbGluZSB7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG59XFxuXFxuLmxpbmstaGlnaGxpZ2h0IHtcXG4gICAgc3Ryb2tlLXdpZHRoOiAxMDtcXG4gICAgc3Ryb2tlLW9wYWNpdHk6IDA7XFxufVxcblxcbi5jb21wbGV4LW91dGxpbmUge1xcbiAgICBzdHJva2U6IHdoaXRlO1xcbiAgICBzdHJva2UtbGluZWpvaW46IHJvdW5kO1xcbiAgICBzdHJva2Utd2lkdGg6IDc7XFxufVxcblxcbi5saW5rZWQtY29tcGxleCB7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxuICAgIHN0cm9rZS1saW5lam9pbjogcm91bmQ7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG59XFxuXFxuZmVhdHVyZS1saW5rIHtcXG4gICAgZmlsbDogYmxhY2s7XFxufVxcblxcbi5wcm90ZWluIHtcXG4gICAgY3Vyc29yOiBjcm9zc2hhaXI7XFxufVxcblxcbi8qdG9kbyAtIHNlcGVyYXRlIG91dCBvdXRsaW5lKi9cXG4ubGFiZWwge1xcbiAgICBmb250LXNpemU6IDEwcHQ7XFxuICAgIC8qZm9udC13ZWlnaHQ6IGJvbGQ7Ki9cXG5cXG4gICAgLypjb2xvcjogI2ZmZjsqL1xcbiAgICAvKnRleHQtc2hhZG93OiB3aGl0ZSAwcHggMHB4IDFweDsqL1xcbiAgICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcXG5cXG4gICAgLyp0ZXh0LXNoYWRvdzogI2ZmZiAwcHggMHB4IDFweCwgICAjZmZmIDBweCAwcHggMXB4LCAgICNmZmYgMHB4IDBweCAxcHgsKi9cXG4gICAgLyojZmZmIDBweCAwcHggMXB4LCAgICNmZmYgMHB4IDBweCAxcHgsICAgI2ZmZiAwcHggMHB4IDFweDsqL1xcblxcbiAgICB0ZXh0LXNoYWRvdzogLTFweCAtMXB4IDAgd2hpdGUsXFxuICAgIDFweCAtMXB4IDAgd2hpdGUsXFxuICAgIC0xcHggMXB4IDAgd2hpdGUsXFxuICAgIDFweCAxcHggMCB3aGl0ZTtcXG4gICAgICAgLyotMnB4IC0xcHggMCB3aGl0ZSwqL1xcbiAgICAgICAvKiAycHggLTFweCAwIHdoaXRlLCovXFxuICAgICAgIC8qIC0ycHggMXB4IDAgd2hpdGUsKi9cXG4gICAgICAgLyogMnB4IDFweCAwIHdoaXRlOyovXFxuICAgIGZpbGw6IGJsYWNrO1xcbiAgICB0ZXh0LWFuY2hvcjogZW5kO1xcbn1cXG5cXG4udG9vbHRpcHtcXG4gICAgdGV4dC1hbmNob3I6IHN0YXJ0O1xcbn1cXG5cXG4ub3V0bGluZSB7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG4gICAgc3Ryb2tlLW9wYWNpdHk6IDE7XFxuICAgIGZpbGw6IHdoaXRlO1xcbiAgICBmaWxsLW9wYWNpdHk6IDE7XFxufVxcblxcbi5wYXJ0aWNpcGFudC1oaWdobGlnaHQge1xcbiAgICBzdHJva2Utd2lkdGg6IDU7XFxuICAgIGZpbGw6IG5vbmU7XFxufVxcblxcbi8qZm9yIHByb3RlaW4gYmFyIHNjYWxlKi9cXG4udGljayB7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxufVxcblxcbi50aWNrLWxhYmVscyB7XFxuICAgIGZvbnQtc2l6ZTogOHB0O1xcbiAgICB0ZXh0LWFuY2hvcjogbWlkZGxlO1xcbn1cXG5cXG4vKm5vdCB3b3JraW5nIHJpZ2h0Ki9cXG4uc2VxdWVuY2Uge1xcbiAgICBmb250LWZhbWlseTogJ0NvdXJpZXIgTmV3JywgbW9ub3NwYWNlO1xcbiAgICBmb250LXNpemU6IDEwcHg7XFxuICAgIHRleHQtYW5jaG9yOiBtaWRkbGU7XFxufVxcblxcbi5jdXN0b20tbWVudS1tYXJnaW4ge1xcbiAgICBwYWRkaW5nOiAyMHB4O1xcbiAgICBkaXNwbGF5OiBub25lO1xcbiAgICB6LWluZGV4OiAxMDAwMDtcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcbn1cXG5cXG4uY3VzdG9tLW1lbnUge1xcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjQ0NDO1xcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcbiAgICBiYWNrZ3JvdW5kOiAjRkZGO1xcbiAgICBjb2xvcjogIzMzMztcXG4gICAgbGlzdC1zdHlsZTogbm9uZTtcXG4gICAgcGFkZGluZzogMDtcXG4gICAgbWFyZ2luOiAwO1xcbiAgICBwb2ludGVyLWV2ZW50czogYWxsO1xcbn1cXG5cXG4uY3VzdG9tLW1lbnUgbGkge1xcbiAgICBwYWRkaW5nOiA4cHggMTJweDtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLmN1c3RvbS1tZW51IGxpOmhvdmVyIHtcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogI0RFRjtcXG59XFxuXFxuLmJhclNjYWxlIHtcXG4gICAgZGlzcGxheTogaW5saW5lO1xcbiAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XFxufVxcblxcbi50b29sdGlwLWJhY2tncm91bmQge1xcbiAgICBmaWxsLW9wYWNpdHk6IDAuNzU7XFxuICAgIHN0cm9rZS1vcGFjaXR5OiAxO1xcbiAgICBzdHJva2Utd2lkdGg6IDE7XFxufVxcblxcbi50b29sdGlwLXN1Yi1iYWNrZ3JvdW5kIHtcXG4gICAgZmlsbDogd2hpdGU7XFxuICAgIHN0cm9rZTogd2hpdGU7XFxuICAgIG9wYWNpdHk6IDE7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG59XCIsIFwiXCJdKTtcbi8vIEV4cG9ydHNcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/css-loader/dist/cjs.js!./src/css/xinet.css\n");
/***/ }),
@@ -1130,7 +1130,7 @@ eval("var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/run
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"fetchAnnotations\", function() { return fetchAnnotations; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"chooseColors\", function() { return chooseColors; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./viz/interactor/annotation */ \"./src/js/viz/interactor/annotation.js\");\n/* harmony import */ var _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./viz/sequence-datum */ \"./src/js/viz/sequence-datum.js\");\n\n\n\n\n\n\n//todo - cache annotations in memory\nfunction fetchAnnotations(annotationChoice, /*App*/ app, callback) {\n annotationChoice = annotationChoice.toUpperCase();\n // we only show annotations on proteins\n const proteins = Array.from(app.participants.values()).filter(function (value) {\n return value.type === \"protein\";\n });\n\n function clearHighlights(){\n for (let prot of proteins){\n prot.showHighlight(false);\n }\n }\n let protsAnnotated = 0;\n const molCount = proteins.length;\n\n if (annotationChoice === \"INTERACTOR\") {\n if (app.proteinCount < 21) {\n for (let prot of proteins) {\n const annotation = new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](prot.json.label, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, 1 + \"-\" + prot.size));\n let annotations = prot.annotationSets.get(annotationChoice);\n if (typeof annotationSet === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(annotationChoice, annotations);\n }\n annotations.push(annotation);\n }\n // app.annotationSetsShown.set(\"INTERACTOR\", true);\n } else {\n alert(\"Too many (> 20) - can't color by interactor.\");\n }\n callback();\n } else if (annotationChoice.toUpperCase() === \"SUPERFAMILY\") {\n for (let prot of proteins) {\n getSuperFamFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n } else if (annotationChoice.toUpperCase() === \"UNIPROTKB\") {\n for (let prot of proteins) {\n getUniProtFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n }\n}\n\nfunction extractUniprotAccession(id) {\n const uniprotAccRegex = new RegExp(\"[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}\", \"i\");\n const match = uniprotAccRegex.exec(id);\n return match[0];\n}\n\nfunction getUniProtFeatures(prot, callback) {\n const url = \"https://www.ebi.ac.uk/proteins/api/proteins/\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"json\"](url, function (json) {\n let annotations = prot.annotationSets.get(\"UNIPROTKB\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"UNIPROTKB\", annotations);\n }\n var uniprotJsonFeatures = json.features.filter(function (ft) {\n return ft.type === \"DOMAIN\";\n });\n for (let feature of uniprotJsonFeatures) {\n feature.seqDatum = new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, feature.begin + \"-\" + feature.end);\n annotations.push(feature);\n }\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction getSuperFamFeatures(prot, callback) {\n const url = \"https://supfam.mrc-lmb.cam.ac.uk/SUPERFAMILY/cgi-bin/das/up/features?segment=\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"xml\"](url, function (xml) {\n let annotations = prot.annotationSets.get(\"SUPERFAMILY\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"SUPERFAMILY\", annotations);\n }\n const xmlDoc = new DOMParser().parseFromString(new XMLSerializer().serializeToString(xml), \"text/xml\");\n const xmlFeatures = xmlDoc.getElementsByTagName(\"FEATURE\");\n for (let xmlFeature of xmlFeatures) {\n const type = xmlFeature.getElementsByTagName(\"TYPE\")[0]; //might need to watch for text nodes getting mixed in here\n const category = type.getAttribute(\"category\");\n if (category === \"miscellaneous\") {\n const name = type.getAttribute(\"id\");\n const start = xmlFeature.getElementsByTagName(\"START\")[0].textContent;\n const end = xmlFeature.getElementsByTagName(\"END\")[0].textContent;\n annotations.push(new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](name, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, start + \"-\" + end)));\n }\n }\n //~ console.log(JSON.stringify(features));\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction chooseColors(app) {\n const categories = new Set();\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotationSet] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let annotation of annotationSet.values()) {\n categories.add(annotation.description);\n }\n }\n }\n }\n\n let colorScheme;\n if (categories.size < 11) {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].ordinal().range(d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__[\"schemeTableau10\"]);//colorbrewer.Dark2[catCount].slice().reverse());\n // } else if (catCount < 13) {\n // // var reversed = colorbrewer.Paired[catCount];//.slice().reverse();\n // colorScheme = d3.scale.ordinal().range(d3_chromatic.schemeSet3);\n } else {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].category20();\n }\n\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotations] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n\n let color;\n if (anno.description === \"No annotations\") {\n color = \"#eeeeee\";\n } else {\n color = colorScheme(anno.description);\n }\n\n //ToDO - way more of these are being created than needed\n app.createHatchedFill(\"checkers_\" + anno.description, color);\n const checkedFill = \"url('#checkers_\" + anno.description + \"')\";\n if (anno.fuzzyStart) {\n anno.fuzzyStart.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyStart.setAttribute(\"stroke\", color);\n }\n if (anno.certain) {\n anno.certain.setAttribute(\"fill\", color);\n // anno.certain.setAttribute(\"stroke\", color);\n }\n if (anno.fuzzyEnd) {\n anno.fuzzyEnd.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyEnd.setAttribute(\"stroke\", color);\n }\n }\n }\n }\n }\n\n app.featureColors = colorScheme;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYW5ub3RhdGlvbnMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb21wbGV4dmlld2VyLy4vc3JjL2pzL2Fubm90YXRpb25zLmpzP2Y5OTIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgKiBhcyBkM19jaHJvbWF0aWMgZnJvbSBcImQzLXNjYWxlLWNocm9tYXRpY1wiO1xuaW1wb3J0IHtBbm5vdGF0aW9ufSBmcm9tIFwiLi92aXovaW50ZXJhY3Rvci9hbm5vdGF0aW9uXCI7XG5pbXBvcnQge1NlcXVlbmNlRGF0dW19IGZyb20gXCIuL3Zpei9zZXF1ZW5jZS1kYXR1bVwiO1xuXG5cbi8vdG9kbyAtIGNhY2hlIGFubm90YXRpb25zIGluIG1lbW9yeVxuZXhwb3J0IGZ1bmN0aW9uIGZldGNoQW5ub3RhdGlvbnMoYW5ub3RhdGlvbkNob2ljZSwgLypBcHAqLyBhcHAsIGNhbGxiYWNrKSB7XG4gICAgYW5ub3RhdGlvbkNob2ljZSA9IGFubm90YXRpb25DaG9pY2UudG9VcHBlckNhc2UoKTtcbiAgICAvLyB3ZSBvbmx5IHNob3cgYW5ub3RhdGlvbnMgb24gcHJvdGVpbnNcbiAgICBjb25zdCBwcm90ZWlucyA9IEFycmF5LmZyb20oYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUudHlwZSA9PT0gXCJwcm90ZWluXCI7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjbGVhckhpZ2hsaWdodHMoKXtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucyl7XG4gICAgICAgICAgICBwcm90LnNob3dIaWdobGlnaHQoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBwcm90c0Fubm90YXRlZCA9IDA7XG4gICAgY29uc3QgbW9sQ291bnQgPSBwcm90ZWlucy5sZW5ndGg7XG5cbiAgICBpZiAoYW5ub3RhdGlvbkNob2ljZSA9PT0gXCJJTlRFUkFDVE9SXCIpIHtcbiAgICAgICAgaWYgKGFwcC5wcm90ZWluQ291bnQgPCAyMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFubm90YXRpb24gPSBuZXcgQW5ub3RhdGlvbihwcm90Lmpzb24ubGFiZWwsIG5ldyBTZXF1ZW5jZURhdHVtKG51bGwsIDEgKyBcIi1cIiArIHByb3Quc2l6ZSkpO1xuICAgICAgICAgICAgICAgIGxldCBhbm5vdGF0aW9ucyA9IHByb3QuYW5ub3RhdGlvblNldHMuZ2V0KGFubm90YXRpb25DaG9pY2UpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYW5ub3RhdGlvblNldCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBwcm90LmFubm90YXRpb25TZXRzLnNldChhbm5vdGF0aW9uQ2hvaWNlLCBhbm5vdGF0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFubm90YXRpb25zLnB1c2goYW5ub3RhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBhcHAuYW5ub3RhdGlvblNldHNTaG93bi5zZXQoXCJJTlRFUkFDVE9SXCIsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoXCJUb28gbWFueSAoPiAyMCkgLSBjYW4ndCBjb2xvciBieSBpbnRlcmFjdG9yLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSBpZiAoYW5ub3RhdGlvbkNob2ljZS50b1VwcGVyQ2FzZSgpID09PSBcIlNVUEVSRkFNSUxZXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvdHNBbm5vdGF0ZWQrKztcbiAgICAgICAgICAgICAgICBpZiAocHJvdHNBbm5vdGF0ZWQgPT09IG1vbENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFySGlnaGxpZ2h0cygpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChhbm5vdGF0aW9uQ2hvaWNlLnRvVXBwZXJDYXNlKCkgPT09IFwiVU5JUFJPVEtCXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0VW5pUHJvdEZlYXR1cmVzKHByb3QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm90c0Fubm90YXRlZCsrO1xuICAgICAgICAgICAgICAgIGlmIChwcm90c0Fubm90YXRlZCA9PT0gbW9sQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xlYXJIaWdobGlnaHRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKGlkKSB7XG4gICAgY29uc3QgdW5pcHJvdEFjY1JlZ2V4ID0gbmV3IFJlZ0V4cChcIltPUFFdWzAtOV1bQS1aMC05XXszfVswLTldfFtBLU5SLVpdWzAtOV0oW0EtWl1bQS1aMC05XXsyfVswLTldKXsxLDJ9XCIsIFwiaVwiKTtcbiAgICBjb25zdCBtYXRjaCA9IHVuaXByb3RBY2NSZWdleC5leGVjKGlkKTtcbiAgICByZXR1cm4gbWF0Y2hbMF07XG59XG5cbmZ1bmN0aW9uIGdldFVuaVByb3RGZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly93d3cuZWJpLmFjLnVrL3Byb3RlaW5zL2FwaS9wcm90ZWlucy9cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLmpzb24odXJsLCBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICBsZXQgYW5ub3RhdGlvbnMgPSBwcm90LmFubm90YXRpb25TZXRzLmdldChcIlVOSVBST1RLQlwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiVU5JUFJPVEtCXCIsIGFubm90YXRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdW5pcHJvdEpzb25GZWF0dXJlcyA9IGpzb24uZmVhdHVyZXMuZmlsdGVyKGZ1bmN0aW9uIChmdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ0LnR5cGUgPT09IFwiRE9NQUlOXCI7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGxldCBmZWF0dXJlIG9mIHVuaXByb3RKc29uRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGZlYXR1cmUuc2VxRGF0dW0gPSBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBmZWF0dXJlLmJlZ2luICsgXCItXCIgKyBmZWF0dXJlLmVuZCk7XG4gICAgICAgICAgICBhbm5vdGF0aW9ucy5wdXNoKGZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb3Quc2hvd0hpZ2hsaWdodCh0cnVlKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly9zdXBmYW0ubXJjLWxtYi5jYW0uYWMudWsvU1VQRVJGQU1JTFkvY2dpLWJpbi9kYXMvdXAvZmVhdHVyZXM/c2VnbWVudD1cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLnhtbCh1cmwsIGZ1bmN0aW9uICh4bWwpIHtcbiAgICAgICAgbGV0IGFubm90YXRpb25zID0gcHJvdC5hbm5vdGF0aW9uU2V0cy5nZXQoXCJTVVBFUkZBTUlMWVwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiU1VQRVJGQU1JTFlcIiwgYW5ub3RhdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHhtbERvYyA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcobmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh4bWwpLCBcInRleHQveG1sXCIpO1xuICAgICAgICBjb25zdCB4bWxGZWF0dXJlcyA9IHhtbERvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcIkZFQVRVUkVcIik7XG4gICAgICAgIGZvciAobGV0IHhtbEZlYXR1cmUgb2YgeG1sRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB4bWxGZWF0dXJlLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiVFlQRVwiKVswXTsgLy9taWdodCBuZWVkIHRvIHdhdGNoIGZvciB0ZXh0IG5vZGVzIGdldHRpbmcgbWl4ZWQgaW4gaGVyZVxuICAgICAgICAgICAgY29uc3QgY2F0ZWdvcnkgPSB0eXBlLmdldEF0dHJpYnV0ZShcImNhdGVnb3J5XCIpO1xuICAgICAgICAgICAgaWYgKGNhdGVnb3J5ID09PSBcIm1pc2NlbGxhbmVvdXNcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0eXBlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0geG1sRmVhdHVyZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcIlNUQVJUXCIpWzBdLnRleHRDb250ZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IHhtbEZlYXR1cmUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJFTkRcIilbMF0udGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMucHVzaChuZXcgQW5ub3RhdGlvbihuYW1lLCBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBzdGFydCArIFwiLVwiICsgZW5kKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vfiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShmZWF0dXJlcykpO1xuICAgICAgICAvLyBwcm90LnNob3dIaWdobGlnaHQodHJ1ZSk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaG9vc2VDb2xvcnMoYXBwKSB7XG4gICAgY29uc3QgY2F0ZWdvcmllcyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiBhcHAucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvblNldF0gb2YgcGFydGljaXBhbnQuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgICAgIGlmIChhcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYW5ub3RhdGlvbiBvZiBhbm5vdGF0aW9uU2V0LnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhdGVnb3JpZXMuYWRkKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBjb2xvclNjaGVtZTtcbiAgICBpZiAoY2F0ZWdvcmllcy5zaXplIDwgMTEpIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5vcmRpbmFsKCkucmFuZ2UoZDNfY2hyb21hdGljLnNjaGVtZVRhYmxlYXUxMCk7Ly9jb2xvcmJyZXdlci5EYXJrMltjYXRDb3VudF0uc2xpY2UoKS5yZXZlcnNlKCkpO1xuICAgICAgICAvLyB9IGVsc2UgaWYgKGNhdENvdW50IDwgMTMpIHtcbiAgICAgICAgLy8gICAgIC8vIHZhciByZXZlcnNlZCA9IGNvbG9yYnJld2VyLlBhaXJlZFtjYXRDb3VudF07Ly8uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgICAgIC8vICAgICBjb2xvclNjaGVtZSA9IGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jaHJvbWF0aWMuc2NoZW1lU2V0Myk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5jYXRlZ29yeTIwKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBmb3IgKGxldCBbYW5ub3RhdGlvblR5cGUsIGFubm90YXRpb25zXSBvZiBwYXJ0aWNpcGFudC5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICAgICAgaWYgKGFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbG9yO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5kZXNjcmlwdGlvbiA9PT0gXCJObyBhbm5vdGF0aW9uc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFwiI2VlZWVlZVwiO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb2xvclNjaGVtZShhbm5vLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vVG9ETyAtIHdheSBtb3JlIG9mIHRoZXNlIGFyZSBiZWluZyBjcmVhdGVkIHRoYW4gbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIGFwcC5jcmVhdGVIYXRjaGVkRmlsbChcImNoZWNrZXJzX1wiICsgYW5uby5kZXNjcmlwdGlvbiwgY29sb3IpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGVja2VkRmlsbCA9IFwidXJsKCcjY2hlY2tlcnNfXCIgKyBhbm5vLmRlc2NyaXB0aW9uICsgXCInKVwiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjaGVja2VkRmlsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjb2xvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIGNoZWNrZWRGaWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFubm8uZnV6enlFbmQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFwcC5mZWF0dXJlQ29sb3JzID0gY29sb3JTY2hlbWU7XG59Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/annotations.js\n");
+eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"fetchAnnotations\", function() { return fetchAnnotations; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"chooseColors\", function() { return chooseColors; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./viz/interactor/annotation */ \"./src/js/viz/interactor/annotation.js\");\n/* harmony import */ var _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./viz/sequence-datum */ \"./src/js/viz/sequence-datum.js\");\n\n\n\n\n\n\n//todo - cache annotations in memory\nfunction fetchAnnotations(annotationChoice, /*App*/ app, callback) {\n annotationChoice = annotationChoice.toUpperCase();\n // we only show annotations on proteins\n const proteins = Array.from(app.participants.values()).filter(function (value) {\n return value.type === \"protein\";\n });\n\n function clearHighlights(){\n for (let prot of proteins){\n prot.showHighlight(false);\n }\n }\n let protsAnnotated = 0;\n const molCount = proteins.length;\n\n if (annotationChoice === \"INTERACTOR\") { //todo - move this out of here\n if (app.proteinCount < 21) {\n for (let prot of proteins) {\n const annotation = new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](prot.json.label, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, 1 + \"-\" + prot.size));\n let annotations = prot.annotationSets.get(annotationChoice);\n if (typeof annotationSet === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(annotationChoice, annotations);\n }\n annotations.push(annotation);\n }\n // app.annotationSetsShown.set(\"INTERACTOR\", true);\n } else {\n // alert(\"Too many (> 20) - can't color by interactor.\"); // people are gong to complain about why arent my interactor colours showing up\n }\n callback();\n } else if (annotationChoice.toUpperCase() === \"SUPERFAMILY\") {\n for (let prot of proteins) {\n getSuperFamFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n } else if (annotationChoice.toUpperCase() === \"UNIPROTKB\") {\n for (let prot of proteins) {\n getUniProtFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n }\n}\n\nfunction extractUniprotAccession(id) {\n const uniprotAccRegex = new RegExp(\"[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}\", \"i\");\n const match = uniprotAccRegex.exec(id);\n return match[0];\n}\n\nfunction getUniProtFeatures(prot, callback) {\n const url = \"https://www.ebi.ac.uk/proteins/api/proteins/\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"json\"](url, function (json) {\n let annotations = prot.annotationSets.get(\"UNIPROTKB\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"UNIPROTKB\", annotations);\n }\n var uniprotJsonFeatures = json.features.filter(function (ft) {\n return ft.type === \"DOMAIN\";\n });\n for (let feature of uniprotJsonFeatures) {\n feature.seqDatum = new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, feature.begin + \"-\" + feature.end);\n annotations.push(feature);\n }\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction getSuperFamFeatures(prot, callback) {\n const url = \"https://supfam.mrc-lmb.cam.ac.uk/SUPERFAMILY/cgi-bin/das/up/features?segment=\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"xml\"](url, function (xml) {\n let annotations = prot.annotationSets.get(\"SUPERFAMILY\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"SUPERFAMILY\", annotations);\n }\n const xmlDoc = new DOMParser().parseFromString(new XMLSerializer().serializeToString(xml), \"text/xml\");\n const xmlFeatures = xmlDoc.getElementsByTagName(\"FEATURE\");\n for (let xmlFeature of xmlFeatures) {\n const type = xmlFeature.getElementsByTagName(\"TYPE\")[0]; //might need to watch for text nodes getting mixed in here\n const category = type.getAttribute(\"category\");\n if (category === \"miscellaneous\") {\n const name = type.getAttribute(\"id\");\n const start = xmlFeature.getElementsByTagName(\"START\")[0].textContent;\n const end = xmlFeature.getElementsByTagName(\"END\")[0].textContent;\n annotations.push(new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](name, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, start + \"-\" + end)));\n }\n }\n //~ console.log(JSON.stringify(features));\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction chooseColors(app) {\n const categories = new Set();\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotationSet] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let annotation of annotationSet.values()) {\n categories.add(annotation.description);\n }\n }\n }\n }\n\n let colorScheme;\n if (categories.size < 11) {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].ordinal().range(d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__[\"schemeTableau10\"]);//colorbrewer.Dark2[catCount].slice().reverse());\n // } else if (catCount < 13) {\n // // var reversed = colorbrewer.Paired[catCount];//.slice().reverse();\n // colorScheme = d3.scale.ordinal().range(d3_chromatic.schemeSet3);\n } else {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].category20();\n }\n\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotations] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n\n let color;\n if (anno.description === \"No annotations\") {\n color = \"#eeeeee\";\n } else {\n color = colorScheme(anno.description);\n }\n\n //ToDO - way more of these are being created than needed\n app.createHatchedFill(\"checkers_\" + anno.description, color);\n const checkedFill = \"url('#checkers_\" + anno.description + \"')\";\n if (anno.fuzzyStart) {\n anno.fuzzyStart.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyStart.setAttribute(\"stroke\", color);\n }\n if (anno.certain) {\n anno.certain.setAttribute(\"fill\", color);\n // anno.certain.setAttribute(\"stroke\", color);\n }\n if (anno.fuzzyEnd) {\n anno.fuzzyEnd.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyEnd.setAttribute(\"stroke\", color);\n }\n }\n }\n }\n }\n\n app.featureColors = colorScheme;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYW5ub3RhdGlvbnMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb21wbGV4dmlld2VyLy4vc3JjL2pzL2Fubm90YXRpb25zLmpzP2Y5OTIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgKiBhcyBkM19jaHJvbWF0aWMgZnJvbSBcImQzLXNjYWxlLWNocm9tYXRpY1wiO1xuaW1wb3J0IHtBbm5vdGF0aW9ufSBmcm9tIFwiLi92aXovaW50ZXJhY3Rvci9hbm5vdGF0aW9uXCI7XG5pbXBvcnQge1NlcXVlbmNlRGF0dW19IGZyb20gXCIuL3Zpei9zZXF1ZW5jZS1kYXR1bVwiO1xuXG5cbi8vdG9kbyAtIGNhY2hlIGFubm90YXRpb25zIGluIG1lbW9yeVxuZXhwb3J0IGZ1bmN0aW9uIGZldGNoQW5ub3RhdGlvbnMoYW5ub3RhdGlvbkNob2ljZSwgLypBcHAqLyBhcHAsIGNhbGxiYWNrKSB7XG4gICAgYW5ub3RhdGlvbkNob2ljZSA9IGFubm90YXRpb25DaG9pY2UudG9VcHBlckNhc2UoKTtcbiAgICAvLyB3ZSBvbmx5IHNob3cgYW5ub3RhdGlvbnMgb24gcHJvdGVpbnNcbiAgICBjb25zdCBwcm90ZWlucyA9IEFycmF5LmZyb20oYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUudHlwZSA9PT0gXCJwcm90ZWluXCI7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjbGVhckhpZ2hsaWdodHMoKXtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucyl7XG4gICAgICAgICAgICBwcm90LnNob3dIaWdobGlnaHQoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBwcm90c0Fubm90YXRlZCA9IDA7XG4gICAgY29uc3QgbW9sQ291bnQgPSBwcm90ZWlucy5sZW5ndGg7XG5cbiAgICBpZiAoYW5ub3RhdGlvbkNob2ljZSA9PT0gXCJJTlRFUkFDVE9SXCIpIHsgLy90b2RvIC0gbW92ZSB0aGlzIG91dCBvZiBoZXJlXG4gICAgICAgIGlmIChhcHAucHJvdGVpbkNvdW50IDwgMjEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHByb3Qgb2YgcHJvdGVpbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbm5vdGF0aW9uID0gbmV3IEFubm90YXRpb24ocHJvdC5qc29uLmxhYmVsLCBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCAxICsgXCItXCIgKyBwcm90LnNpemUpKTtcbiAgICAgICAgICAgICAgICBsZXQgYW5ub3RhdGlvbnMgPSBwcm90LmFubm90YXRpb25TZXRzLmdldChhbm5vdGF0aW9uQ2hvaWNlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFubm90YXRpb25TZXQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgcHJvdC5hbm5vdGF0aW9uU2V0cy5zZXQoYW5ub3RhdGlvbkNob2ljZSwgYW5ub3RhdGlvbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucy5wdXNoKGFubm90YXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gYXBwLmFubm90YXRpb25TZXRzU2hvd24uc2V0KFwiSU5URVJBQ1RPUlwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGFsZXJ0KFwiVG9vIG1hbnkgKD4gMjApIC0gY2FuJ3QgY29sb3IgYnkgaW50ZXJhY3Rvci5cIik7IC8vIHBlb3BsZSBhcmUgZ29uZyB0byBjb21wbGFpbiBhYm91dCB3aHkgYXJlbnQgbXkgaW50ZXJhY3RvciBjb2xvdXJzIHNob3dpbmcgdXBcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSBpZiAoYW5ub3RhdGlvbkNob2ljZS50b1VwcGVyQ2FzZSgpID09PSBcIlNVUEVSRkFNSUxZXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvdHNBbm5vdGF0ZWQrKztcbiAgICAgICAgICAgICAgICBpZiAocHJvdHNBbm5vdGF0ZWQgPT09IG1vbENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFySGlnaGxpZ2h0cygpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChhbm5vdGF0aW9uQ2hvaWNlLnRvVXBwZXJDYXNlKCkgPT09IFwiVU5JUFJPVEtCXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0VW5pUHJvdEZlYXR1cmVzKHByb3QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm90c0Fubm90YXRlZCsrO1xuICAgICAgICAgICAgICAgIGlmIChwcm90c0Fubm90YXRlZCA9PT0gbW9sQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xlYXJIaWdobGlnaHRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKGlkKSB7XG4gICAgY29uc3QgdW5pcHJvdEFjY1JlZ2V4ID0gbmV3IFJlZ0V4cChcIltPUFFdWzAtOV1bQS1aMC05XXszfVswLTldfFtBLU5SLVpdWzAtOV0oW0EtWl1bQS1aMC05XXsyfVswLTldKXsxLDJ9XCIsIFwiaVwiKTtcbiAgICBjb25zdCBtYXRjaCA9IHVuaXByb3RBY2NSZWdleC5leGVjKGlkKTtcbiAgICByZXR1cm4gbWF0Y2hbMF07XG59XG5cbmZ1bmN0aW9uIGdldFVuaVByb3RGZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly93d3cuZWJpLmFjLnVrL3Byb3RlaW5zL2FwaS9wcm90ZWlucy9cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLmpzb24odXJsLCBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICBsZXQgYW5ub3RhdGlvbnMgPSBwcm90LmFubm90YXRpb25TZXRzLmdldChcIlVOSVBST1RLQlwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiVU5JUFJPVEtCXCIsIGFubm90YXRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdW5pcHJvdEpzb25GZWF0dXJlcyA9IGpzb24uZmVhdHVyZXMuZmlsdGVyKGZ1bmN0aW9uIChmdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ0LnR5cGUgPT09IFwiRE9NQUlOXCI7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGxldCBmZWF0dXJlIG9mIHVuaXByb3RKc29uRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGZlYXR1cmUuc2VxRGF0dW0gPSBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBmZWF0dXJlLmJlZ2luICsgXCItXCIgKyBmZWF0dXJlLmVuZCk7XG4gICAgICAgICAgICBhbm5vdGF0aW9ucy5wdXNoKGZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb3Quc2hvd0hpZ2hsaWdodCh0cnVlKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly9zdXBmYW0ubXJjLWxtYi5jYW0uYWMudWsvU1VQRVJGQU1JTFkvY2dpLWJpbi9kYXMvdXAvZmVhdHVyZXM/c2VnbWVudD1cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLnhtbCh1cmwsIGZ1bmN0aW9uICh4bWwpIHtcbiAgICAgICAgbGV0IGFubm90YXRpb25zID0gcHJvdC5hbm5vdGF0aW9uU2V0cy5nZXQoXCJTVVBFUkZBTUlMWVwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiU1VQRVJGQU1JTFlcIiwgYW5ub3RhdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHhtbERvYyA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcobmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh4bWwpLCBcInRleHQveG1sXCIpO1xuICAgICAgICBjb25zdCB4bWxGZWF0dXJlcyA9IHhtbERvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcIkZFQVRVUkVcIik7XG4gICAgICAgIGZvciAobGV0IHhtbEZlYXR1cmUgb2YgeG1sRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB4bWxGZWF0dXJlLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiVFlQRVwiKVswXTsgLy9taWdodCBuZWVkIHRvIHdhdGNoIGZvciB0ZXh0IG5vZGVzIGdldHRpbmcgbWl4ZWQgaW4gaGVyZVxuICAgICAgICAgICAgY29uc3QgY2F0ZWdvcnkgPSB0eXBlLmdldEF0dHJpYnV0ZShcImNhdGVnb3J5XCIpO1xuICAgICAgICAgICAgaWYgKGNhdGVnb3J5ID09PSBcIm1pc2NlbGxhbmVvdXNcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0eXBlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0geG1sRmVhdHVyZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcIlNUQVJUXCIpWzBdLnRleHRDb250ZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IHhtbEZlYXR1cmUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJFTkRcIilbMF0udGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMucHVzaChuZXcgQW5ub3RhdGlvbihuYW1lLCBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBzdGFydCArIFwiLVwiICsgZW5kKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vfiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShmZWF0dXJlcykpO1xuICAgICAgICAvLyBwcm90LnNob3dIaWdobGlnaHQodHJ1ZSk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaG9vc2VDb2xvcnMoYXBwKSB7XG4gICAgY29uc3QgY2F0ZWdvcmllcyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiBhcHAucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvblNldF0gb2YgcGFydGljaXBhbnQuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgICAgIGlmIChhcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYW5ub3RhdGlvbiBvZiBhbm5vdGF0aW9uU2V0LnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhdGVnb3JpZXMuYWRkKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBjb2xvclNjaGVtZTtcbiAgICBpZiAoY2F0ZWdvcmllcy5zaXplIDwgMTEpIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5vcmRpbmFsKCkucmFuZ2UoZDNfY2hyb21hdGljLnNjaGVtZVRhYmxlYXUxMCk7Ly9jb2xvcmJyZXdlci5EYXJrMltjYXRDb3VudF0uc2xpY2UoKS5yZXZlcnNlKCkpO1xuICAgICAgICAvLyB9IGVsc2UgaWYgKGNhdENvdW50IDwgMTMpIHtcbiAgICAgICAgLy8gICAgIC8vIHZhciByZXZlcnNlZCA9IGNvbG9yYnJld2VyLlBhaXJlZFtjYXRDb3VudF07Ly8uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgICAgIC8vICAgICBjb2xvclNjaGVtZSA9IGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jaHJvbWF0aWMuc2NoZW1lU2V0Myk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5jYXRlZ29yeTIwKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBmb3IgKGxldCBbYW5ub3RhdGlvblR5cGUsIGFubm90YXRpb25zXSBvZiBwYXJ0aWNpcGFudC5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICAgICAgaWYgKGFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbG9yO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5kZXNjcmlwdGlvbiA9PT0gXCJObyBhbm5vdGF0aW9uc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFwiI2VlZWVlZVwiO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb2xvclNjaGVtZShhbm5vLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vVG9ETyAtIHdheSBtb3JlIG9mIHRoZXNlIGFyZSBiZWluZyBjcmVhdGVkIHRoYW4gbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIGFwcC5jcmVhdGVIYXRjaGVkRmlsbChcImNoZWNrZXJzX1wiICsgYW5uby5kZXNjcmlwdGlvbiwgY29sb3IpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGVja2VkRmlsbCA9IFwidXJsKCcjY2hlY2tlcnNfXCIgKyBhbm5vLmRlc2NyaXB0aW9uICsgXCInKVwiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjaGVja2VkRmlsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjb2xvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIGNoZWNrZWRGaWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFubm8uZnV6enlFbmQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFwcC5mZWF0dXJlQ29sb3JzID0gY29sb3JTY2hlbWU7XG59Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/annotations.js\n");
/***/ }),
@@ -1142,7 +1142,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) *
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
-eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"App\", function() { return App; });\n/* harmony import */ var _css_xinet_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../css/xinet.css */ \"./src/css/xinet.css\");\n/* harmony import */ var _css_xinet_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_xinet_css__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../package.json */ \"./package.json\");\nvar _package_json__WEBPACK_IMPORTED_MODULE_1___namespace = /*#__PURE__*/__webpack_require__.t(/*! ../../package.json */ \"./package.json\", 1);\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _cola__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./cola */ \"./src/js/cola.js\");\n/* harmony import */ var _cola__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_cola__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _read_mijson__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./read-mijson */ \"./src/js/read-mijson.js\");\n/* harmony import */ var _annotations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./annotations */ \"./src/js/annotations.js\");\n/* harmony import */ var _color_scheme_key__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./color-scheme-key */ \"./src/js/color-scheme-key.js\");\n/* harmony import */ var _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./viz/link/nary-link */ \"./src/js/viz/link/nary-link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./config */ \"./src/js/config.js\");\n// eslint-disable-next-line no-unused-vars\n\n\n\n\n\n\n\n\n// import {SymbolKey} from \"./symbol-key\";\n\n\n\n\n// could refactor everything to use ES6 class syntax\n// but https://benmccormick.org/2015/04/07/es6-classes-and-backbone-js\n// \"ES6 classes don’t support adding properties directly to the class instance, only functions/methods\"\n// so backbone doesn't work\n// so continuing to use prototypical inheritance in things for time being\n\nfunction App(/*HTMLDivElement*/networkDiv) {\n // this.debug = true; // things aren't exactly lined up in the bounding boxes cola is using, to do so breaks symetery of some things\n this.el = networkDiv;\n\n this.STATES = {};\n this.STATES.MOUSE_UP = 0; //start state, also set when mouse up on svgElement\n this.STATES.PANNING = 1; //set by mouse down on svgElement - left button, no shift or util\n this.STATES.DRAGGING = 2; //set by mouse down on Protein or Link\n this.STATES.ROTATING = 3; //set by mouse down on Rotator, drag?\n this.STATES.SELECTING = 4; //set by mouse down on svgElement- right button or left button shift or util, drag\n\n //avoids prob with 'save - web page complete'\n this.el.textContent = \"\"; //https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript\n\n this.d3cola = _cola__WEBPACK_IMPORTED_MODULE_4__[\"d3adaptor\"]();\n\n const customMenuSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.el)\n .append(\"div\").classed(\"custom-menu-margin\", true)\n .append(\"div\").classed(\"custom-menu\", true)\n .append(\"ul\");\n\n const self = this;\n const collapse = customMenuSel.append(\"li\").classed(\"collapse\", true); //.append(\"button\");\n collapse.text(\"Collapse\");\n collapse[0][0].onclick = function (evt) {\n self.collapseProtein(evt);\n };\n const scaleButtonsListItemSel = customMenuSel.append(\"li\").text(\"Scale: \");\n\n this.barScales = [0.01, 0.2, 1, 2, 4, 8];\n const scaleButtons = scaleButtonsListItemSel.selectAll(\"ul.custom-menu\")\n .data(this.barScales)\n .enter()\n .append(\"div\")\n .attr(\"class\", \"barScale\")\n .append(\"label\");\n scaleButtons.append(\"span\")\n .text(function (d) {\n if (d === 8) return \"AA\";\n else return d;\n });\n scaleButtons.append(\"input\")\n // .attr (\"id\", function(d) { return d*100; })\n .attr(\"class\", function (d) {\n return \"scaleButton scaleButton_\" + (d * 100);\n })\n .attr(\"name\", \"scaleButtons\")\n .attr(\"type\", \"radio\")\n .on(\"change\", function (d) {\n self.preventDefaultsAndStopPropagation(d);\n self.contextMenuProt.setStickScale(d, self.contextMenuPoint);\n });\n\n const contextMenu = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\").node();\n contextMenu.onmouseout = function (evt) {\n let e = evt.relatedTarget;\n do {\n if (e === this) return;\n e = e.parentNode;\n } while (e);\n self.contextMenuProt = null;\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this).style(\"display\", \"none\");\n };\n\n\n //create SVG element\n this.svgElement = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"svg\");\n this.svgElement.setAttribute(\"id\", \"complexViewerSVG\");\n\n //add listeners\n this.svgElement.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.svgElement.onmousemove = function (evt) {\n self.mouseMove(evt);\n };\n this.svgElement.onmouseup = function (evt) {\n self.mouseUp(evt);\n };\n this.svgElement.onmouseout = function (evt) {\n self.hideTooltip(evt);\n };\n this.lastMouseUp = new Date().getTime();\n /*this.svgElement.ontouchstart = function(evt) {\n self.touchStart(evt);\n };\n this.svgElement.ontouchmove = function(evt) {\n self.touchMove(evt);\n };\n this.svgElement.ontouchend = function(evt) {\n self.touchEnd(evt);\n };\n */\n\n this.el.oncontextmenu = function (evt) {\n if (evt.preventDefault) { // necessary for addEventListener, works with traditional\n evt.preventDefault();\n }\n evt.returnValue = false; // necessary for attachEvent, works with traditional\n return false; // works with traditional, not with attachEvent or addEventListener\n };\n\n //legend changed callbacks\n this.colorSchemeKeyDivs = new Set();\n\n this.el.appendChild(this.svgElement);\n\n // various groups needed\n this.container = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.container.setAttribute(\"id\", \"container\");\n\n const svg = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.svgElement);\n this.defs = svg.append(\"defs\");\n this.createHatchedFill(\"checkers_uncertain\", \"black\");\n\n //markers\n const data = [{\n id: 1,\n name: \"diamond\",\n path: \"M 0,-7.0710768 L 0,7.0710589 L 7.0710462,0 z\",\n viewbox: \"-15 -15 25 25\",\n transform: \"scale(1.5) translate(-5,0)\",\n color: \"black\"\n }];\n\n this.defs.selectAll(\"marker\")\n .data(data)\n .enter()\n .append(\"svg:marker\")\n .attr(\"id\", function (d) {\n return \"marker_\" + d.name;\n })\n .attr(\"markerHeight\", 15)\n .attr(\"markerWidth\", 15)\n .attr(\"markerUnits\", \"userSpaceOnUse\")\n .attr(\"orient\", \"auto\")\n .attr(\"refX\", 0)\n .attr(\"refY\", 0)\n .attr(\"viewBox\", function (d) {\n return d.viewbox;\n })\n .append(\"svg:path\")\n .attr(\"d\", function (d) {\n return d.path;\n })\n .attr(\"fill\", function (d) {\n return d.color;\n })\n .attr(\"transform\", function (d) {\n return d.transform;\n });\n\n this.acknowledgement = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n const ackText = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"text\");\n ackText.innerHTML = \"ComplexViewer \"\n + _package_json__WEBPACK_IMPORTED_MODULE_1__[\"version\"] + \"by Rappsilber Laboratory\";\n\n this.acknowledgement.appendChild(ackText);\n ackText.classList.add(\"xlv_text\");\n ackText.setAttribute(\"font-size\", \"8pt\");\n this.svgElement.appendChild(this.acknowledgement);\n\n this.naryLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.naryLinks.setAttribute(\"id\", \"naryLinks\");\n this.container.appendChild(this.naryLinks);\n\n this.p_pLinksWide = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.p_pLinksWide.setAttribute(\"id\", \"p_pLinksWide\");\n this.container.appendChild(this.p_pLinksWide);\n\n this.highlights = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.highlights.setAttribute(\"class\", \"highlights\"); //interactors also contain highlight groups\n this.container.appendChild(this.highlights);\n\n this.res_resLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.res_resLinks.setAttribute(\"id\", \"res_resLinks\");\n this.container.appendChild(this.res_resLinks);\n\n this.p_pLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.p_pLinks.setAttribute(\"id\", \"p_pLinks\");\n this.container.appendChild(this.p_pLinks);\n\n this.proteinUpper = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.proteinUpper.setAttribute(\"id\", \"proteinUpper\");\n this.container.appendChild(this.proteinUpper);\n\n this.selfRes_resLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.selfRes_resLinks.setAttribute(\"id\", \"res_resLinks\");\n this.container.appendChild(this.selfRes_resLinks);\n\n this.svgElement.appendChild(this.container);\n\n //showing title as tooltips is NOT part of svg spec (even though some browsers do this)\n //also more responsive / more control if we do out own\n this.tooltip = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"text\");\n this.tooltip.setAttribute(\"x\", \"0\");\n this.tooltip.setAttribute(\"y\", \"0\");\n this.tooltip.setAttribute(\"class\", \"xlv_text\");\n const tooltipTextNode = document.createTextNode(\"tooltip\");\n\n this.tooltip.appendChild(tooltipTextNode);\n\n this.tooltip_bg = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"rect\");\n this.tooltip_bg.setAttribute(\"class\", \"tooltip_bg\");\n\n this.tooltip_bg.setAttribute(\"fill-opacity\", \"0.75\");\n this.tooltip_bg.setAttribute(\"stroke-opacity\", \"1\");\n this.tooltip_bg.setAttribute(\"stroke-width\", \"1\");\n\n this.tooltip_subBg = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"rect\");\n this.tooltip_subBg.setAttribute(\"fill\", \"white\");\n this.tooltip_subBg.setAttribute(\"stroke\", \"white\");\n this.tooltip_subBg.setAttribute(\"class\", \"tooltip_bg\");\n this.tooltip_subBg.setAttribute(\"opacity\", \"1\");\n this.tooltip_subBg.setAttribute(\"stroke-width\", \"1\");\n\n this.svgElement.appendChild(this.tooltip_subBg);\n this.svgElement.appendChild(this.tooltip_bg);\n this.svgElement.appendChild(this.tooltip);\n\n this.clear();\n}\n\nApp.prototype.createHatchedFill = function (name, color) {\n const pattern = this.defs.append(\"pattern\")\n .attr(\"id\", name)\n .attr(\"patternUnits\", \"userSpaceOnUse\")\n .attr(\"x\", 0)\n .attr(\"y\", 0)\n .attr(\"width\", 12)\n .attr(\"height\", 12)\n .attr(\"patternTransform\", \"rotate(45)\");\n\n pattern.append(\"rect\")\n .attr(\"x\", 0)\n .attr(\"y\", 2)\n .attr(\"width\", 12)\n .attr(\"height\", 4)\n .attr(\"fill\", color);\n\n pattern.append(\"rect\")\n .attr(\"x\", 0)\n .attr(\"y\", 8)\n .attr(\"width\", 12)\n .attr(\"height\", 4)\n .attr(\"fill\", color);\n};\n\nApp.prototype.clear = function () {\n this.d3cola.stop();\n\n this.annotationSetsShown = new Map();\n // this.annotationSetsShown.set(\"MI FEATURES\", true);\n\n //lighten colors\n const complexColors = [];\n for (let c of d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_3__[\"schemePastel2\"]) {//colorbrewer.Pastel2[8]) {\n const hsl = d3__WEBPACK_IMPORTED_MODULE_2__[\"hsl\"](c);\n hsl.l = 0.9;\n complexColors.push(hsl + \"\");\n }\n\n _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_8__[\"NaryLink\"].naryColors = d3__WEBPACK_IMPORTED_MODULE_2__[\"scale\"].ordinal().range(complexColors);\n this.defs.selectAll(\".feature_checkers\").remove();\n\n this.naryLinks.textContent = \"\";\n this.p_pLinksWide.textContent = \"\";\n this.highlights.textContent = \"\";\n this.p_pLinks.textContent = \"\";\n this.res_resLinks.textContent = \"\";\n this.proteinUpper.textContent = \"\";\n this.selfRes_resLinks.textContent = \"\";\n\n // if we are dragging something at the moment - this will be the element that is dragged\n this.dragElement = null;\n // from where did we start dragging\n this.dragStart = {};\n\n this.participants = new Map();\n this.allNaryLinks = new Map();\n this.allBinaryLinks = new Map();\n this.allUnaryLinks = new Map();\n this.allSequenceLinks = new Map();\n this.complexes = [];\n\n this.proteinCount = 0;\n this.z = 1;\n this.hideTooltip();\n this.state = this.STATES.MOUSE_UP;\n};\n\nApp.prototype.collapseProtein = function () {\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\").style(\"display\", \"none\");\n this.contextMenuProt.setForm(0, this.contextMenuPoint);\n this.contextMenuProt = null;\n};\n\nApp.prototype.init = function () {\n this.d3cola.stop();\n\n // let i = 0;\n for (let participant of this.participants.values()) {\n if (participant.type != \"complex\") {\n // let pos = rotatePointAboutPoint([0, -500], [0, 0], (360 / this.participants.size * i));\n participant.setPosition(-500, -500);//pos[0], pos[1]);\n // if (participant.type === \"protein\") {\n // participant.setPositionalFeatures();\n // }\n }\n // i++;\n }\n this.updateAnnotations();\n this.checkLinks(); //totally needed, not sure why tbh todo - check this out\n this.setAllLinkCoordinates(); // just to move them off screen at first\n\n let maxSeqLength = 0;\n for (let participant of this.participants.values()) {\n if (participant.size > maxSeqLength) {\n maxSeqLength = participant.size;\n }\n }\n const width = this.svgElement.parentNode.clientWidth;\n const defaultPixPerRes = width * 0.8 / maxSeqLength;\n //console.log(\"defaultPixPerRes:\" + defaultPixPerRes);\n // https://stackoverflow.com/questions/12141150/from-list-of-integers-get-number-closest-to-a-given-value/12141511#12141511\n function takeClosest(myList, myNumber) {\n const bisect = d3__WEBPACK_IMPORTED_MODULE_2__[\"bisector\"](function (d) {\n return d;\n }).left;\n const pos = bisect(myList, myNumber);\n if (pos === 0 || pos === 1) {\n return myList[1]; // don't return smallest scale as default\n }\n if (pos === myList.length) {\n return myList[myList.length - 1];\n }\n return myList[pos - 1];\n }\n\n this.defaultBarScale = takeClosest(this.barScales, defaultPixPerRes);\n //console.log(\"default bar scale: \" + this.defaultBarScale)\n\n for (let participant of this.participants.values()) {\n if (participant.type !== \"complex\") {\n this.proteinUpper.appendChild(participant.upperGroup);\n if (participant.json.type.name === \"protein\") {\n // participant.initSelfLinkSVG(); // todo - may not even do anything, not sure its working\n participant.stickZoom = this.defaultBarScale;\n if (this.participants.size < 4) {\n participant.toStickNoTransition();\n }\n }\n }\n }\n\n this.autoLayout();\n};\n\nApp.prototype.zoomToExtent = function () {\n const width = this.svgElement.parentNode.clientWidth;\n const height = this.svgElement.parentNode.clientHeight;\n const bbox = this.container.getBBox();\n let xr = (width / bbox.width).toFixed(4) - 0;\n let yr = (height / bbox.height).toFixed(4) - 0;\n let scaleFactor;\n if (yr < xr) {\n scaleFactor = yr;\n } else {\n scaleFactor = xr;\n }\n if (scaleFactor < 1) { ///didn't fit in div\n //console.log(\"no fit\", scaleFactor);\n xr = (width - 40) / (bbox.width);\n yr = (height - 40) / (bbox.height);\n let scaleFactor;\n if (yr < xr) {\n scaleFactor = yr;\n } else {\n scaleFactor = xr;\n }\n\n if (scaleFactor > this.z) {\n scaleFactor = this.z;\n }\n\n //bbox.x + x = 0;\n let x = -bbox.x + (20 / scaleFactor);\n //box.y + y = 0\n let y = -bbox.y + (20 / scaleFactor);\n this.container.setAttribute(\"transform\", \"scale(\" + scaleFactor + \") translate(\" + x + \" \" + y + \") \");\n this.z = this.container.getCTM().inverse().a;\n } else {\n //console.log(\"fit\", scaleFactor);\n // this.container.setAttribute(\"transform\", \"scale(\" + 1 + \") translate(\" + -(width/2) + \" \" + -bbox.y + \")\");\n const deltaWidth = width - bbox.width;\n const deltaHeight = height - bbox.height;\n //bbox.x + x = deltaWidth /2;\n let x = (deltaWidth / 2) - bbox.x;\n //box.y + y = deltaHeight / 2\n let y = (deltaHeight / 2) - bbox.y;\n this.container.setAttribute(\"transform\", \"scale(\" + 1 + \") translate(\" + x + \" \" + y + \")\");\n this.z = 1;\n }\n\n //todo - following could be tided up by using acknowledgement bbox or positioning att's of text\n this.acknowledgement.setAttribute(\"transform\", \"translate(\" + (width - 150) + \", \" + (height - 30) + \")\");\n};\n\n//listeners also attached to mouse events by Interactor (and Rotator) and Link, those consume their events\n//mouse down on svgElement must be allowed to propogate (to fire event on Prots/Links)\n\nApp.prototype.mouseDown = function (evt) {\n //prevent default, but allow propogation\n evt.preventDefault();\n this.d3cola.stop();\n const p = this.getEventPoint(evt); // seems to be correct, see below\n this.dragStart = this.mouseToSVG(p.x, p.y);\n return false;\n};\n\n// dragging/rotation/panning/selecting\nApp.prototype.mouseMove = function (evt) {\n const p = this.getEventPoint(evt); // seems to be correct, see below\n const c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) { //dragging or rotating\n this.hideTooltip();\n const dx = this.dragStart.x - c.x;\n const dy = this.dragStart.y - c.y;\n\n if (this.state === this.STATES.DRAGGING) {\n // we are currently dragging things around\n let ox, oy, nx, ny;\n if (!this.dragElement.ix) {\n for (let participant of this.dragElement.participants) {\n participant.changePosition(dx, dy);\n }\n this.setAllLinkCoordinates();\n } else {\n ox = this.dragElement.ix;\n oy = this.dragElement.iy;\n nx = ox - dx;\n ny = oy - dy;\n this.dragElement.setPosition(nx, ny);\n this.dragElement.setAllLinkCoordinates();\n }\n this.dragStart = c;\n } else { //not dragging or rotating yet, maybe we should start\n // don't start dragging just on a click - we need to move the mouse a bit first\n if (Math.sqrt(dx * dx + dy * dy) > (5 * this.z)) {\n this.state = this.STATES.DRAGGING;\n\n }\n }\n } else {\n this.showTooltip(p);\n }\n return false;\n};\n\n// this ends all dragging and rotating\nApp.prototype.mouseUp = function (evt) {\n const time = new Date().getTime();\n //console.log(\"Mouse up: \" + evt.srcElement + \" \" + (time - this.lastMouseUp));\n this.preventDefaultsAndStopPropagation(evt);\n //eliminate some spurious mouse up events\n if ((time - this.lastMouseUp) > 150) {\n\n const p = this.getEventPoint(evt); // seems to be correct, see below\n const c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement && this.dragElement.type === \"protein\") { /// todo be consistent about how to check if thing is protein\n if (!(this.state === this.STATES.DRAGGING || this.state === this.STATES.ROTATING)) { //not dragging or rotating\n if (this.dragElement.form === 0) {\n this.dragElement.setForm(1);\n } else {\n this.contextMenuProt = this.dragElement;\n this.contextMenuPoint = c;\n const menu = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\");\n menu.style(\"top\", (evt.pageY - 20) + \"px\").style(\"left\", (evt.pageX - 20) + \"px\").style(\"display\", \"block\");\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".scaleButton_\" + (this.dragElement.stickZoom * 100)).property(\"checked\", true);\n }\n }\n }\n }\n\n this.dragElement = null;\n this.state = this.STATES.MOUSE_UP;\n\n this.lastMouseUp = time;\n return false;\n};\n\n//gets mouse position\nApp.prototype.getEventPoint = function (evt) {\n const p = this.svgElement.createSVGPoint();\n let element = this.svgElement.parentNode;\n let top = 0,\n left = 0;\n do {\n top += element.offsetTop || 0;\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n p.x = evt.pageX - left;\n p.y = evt.pageY - top;\n return p;\n};\n\n//stop event propogation and defaults; only do what we ask\nApp.prototype.preventDefaultsAndStopPropagation = function (evt) {\n if (evt.stopPropagation)\n evt.stopPropagation();\n if (evt.cancelBubble != null)\n evt.cancelBubble = true;\n if (evt.preventDefault)\n evt.preventDefault();\n};\n\n/**\n * Handle touchstart event.\n\n App.prototype.touchStart = function(evt) {\n //prevent default, but allow propogation\n evt.preventDefault();\n\n //stop force layout\n if (typeof this.d3cola !== 'undefined' && this.d3cola != null) {\n this.d3cola.stop();\n }\n\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n this.dragStart = this.mouseToSVG(p.x, p.y);\n};\n\n // dragging/rotation/panning/selecting\n App.prototype.touchMove = function(evt) {\n // if (this.sequenceInitComplete) { // just being cautious\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n var c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) { //dragging or rotating\n this.hideTooltip();\n var dx = this.dragStart.x - c.x;\n var dy = this.dragStart.y - c.y;\n\n if (this.state === this.STATES.DRAGGING) {\n // we are currently dragging things around\n var ox, oy, nx, ny;\n if (typeof this.dragElement.ix=== 'undefined') { // if not an Interactor\n var nodes = this.dragElement.interactors;\n var nodeCount = nodes.length;\n for (var i = 0; i < nodeCount; i++) {\n var protein = nodes[i];\n ox = protein.cx;\n oy = protein.cy;\n nx = ox - dx;\n ny = oy - dy;\n protein.setPosition(nx, ny);\n protein.setAllLinkCoordinates();\n }\n for (i = 0; i < nodeCount; i++) {\n nodes[i].setAllLinkCoordinates();\n }\n } else {\n ox = this.dragElement.cx;\n oy = this.dragElement.cy;\n nx = ox - dx;\n ny = oy - dy;\n this.dragElement.setPosition(nx, ny);\n this.dragElement.setAllLinkCoordinates();\n }\n this.dragStart = c;\n } else { //not dragging or rotating yet, maybe we should start\n // don't start dragging just on a click - we need to move the mouse a bit first\n if (Math.sqrt(dx * dx + dy * dy) > (5 * this.z)) {\n this.state = this.STATES.DRAGGING;\n\n }\n }\n } else {\n this.showTooltip(p);\n }\n return false;\n};\n\n// this ends all dragging and rotating\nApp.prototype.touchEnd = function(evt) {\n var time = new Date().getTime();\n //console.log(\"Mouse up: \" + evt.srcElement + \" \" + (time - this.lastMouseUp));\n this.preventDefaultsAndStopPropagation(evt);\n //eliminate some spurious mouse up events\n if ((time - this.lastMouseUp) > 150) {\n\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n var c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) {\n if (!(this.state === this.STATES.DRAGGING || this.state === this.STATES.ROTATING)) { //not dragging or rotating\n if (this.dragElement.form === 0) {\n this.dragElement.setForm(1);\n } else {\n this.contextMenuProt = this.dragElement;\n this.contextMenuPoint = c;\n var menu = d3.select(\".custom-menu-margin\")\n menu.style(\"top\", (evt.pageY - 20) + \"px\").style(\"left\", (evt.pageX - 20) + \"px\").style(\"display\", \"block\");\n d3.select(\".scaleButton_\" + (this.dragElement.stickZoom * 100)).property(\"checked\", true)\n }\n }\n }\n }\n\n this.dragElement = null;\n this.whichRotator = -1;\n this.state = this.STATES.MOUSE_UP;\n\n this.lastMouseUp = time;\n return false;\n};\n\n//gets mouse position\nApp.prototype.getTouchEventPoint = function(evt) {\n var p = this.svgElement.createSVGPoint();\n var element = this.svgElement.parentNode;\n var top = 0,\n left = 0;\n do {\n top += element.offsetTop || 0;\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n p.x = evt.touches[0].pageX - left;\n p.y = evt.touches[0].pageY - top;\n return p;\n};\n */\nApp.prototype.autoLayout = function () {\n this.d3cola.stop();\n const self = this;\n\n // needed to ensure consistent results\n for (let p of self.participants.values()) {\n delete p.x;\n delete p.y;\n delete p.px;\n delete p.py;\n delete p.bounds;\n p.fixed = 0;\n }\n\n //// prune leaves from network then layout, then add back leaves and layout again (fixes haemoglobin)\n const pruned = [];\n for (let participant of self.participants.values()) {\n if (participant.binaryLinks.size > 2 && participant.type !== \"complex\") {\n pruned.push(participant);\n }\n }\n const allNodesExceptComplexes = Array.from(self.participants.values()).filter(function (value) {\n return value.type !== \"complex\";\n });\n\n if (pruned.length < allNodesExceptComplexes.length\n && pruned.length > 3 && self.participants.size < 9) {\n // <9 include hemoglobin, possibly some other small cases, but is catious, tends to mess other things up\n // console.log(prunedIn);\n doLayout(pruned, true);\n } else {\n doLayout(allNodesExceptComplexes, self.complexes.length > 0);\n }\n\n function doLayout(nodes, preRun) {\n const layoutObj = {}; // todo get rid\n layoutObj.nodes = nodes;\n layoutObj.links = [];\n\n const molLookUp = {};\n let mi = 0;\n for (let mol of nodes) {\n molLookUp[mol.id] = mi;\n mi++;\n }\n\n for (let binaryLink of self.allBinaryLinks.values()) {\n const fromMol = binaryLink.participants[0];\n const toMol = binaryLink.participants[1];\n // if (preRun || (fromMol.binaryLinks.size === 4 || toMol.binaryLinks.size == 4)) {\n const source = fromMol; //molLookUp[fromMol.id];\n const target = toMol; //molLookUp[toMol.id];\n\n if (source !== target && nodes.indexOf(source) !== -1 && nodes.indexOf(target) !== -1) { // todo - check what this is doing\n const linkObj = {};\n linkObj.source = molLookUp[fromMol.id];\n linkObj.target = molLookUp[toMol.id];\n linkObj.id = binaryLink.id;\n layoutObj.links.push(linkObj);\n }\n // }\n }\n\n const groups = [];\n if (!preRun && self.complexes) {\n for (let g of self.complexes) {\n g.leaves = [];\n g.groups = [];\n for (let interactor of g.naryLink.participants) {\n if (interactor.type !== \"complex\") {\n g.leaves.push(layoutObj.nodes.indexOf(interactor));\n }\n }\n groups.push(g);\n }\n for (let g of self.complexes) {\n for (let interactor of g.naryLink.participants) {\n if (interactor.type === \"complex\") {\n //console.log(groups.indexOf(interactor));\n g.groups.push(groups.indexOf(interactor));\n }\n }\n }\n }\n\n // if (preRun) {\n // layoutObj.nodes = layoutObj.nodes.concat(prunedOut);\n // }\n\n // self.d3cola.convergenceThreshold = 0.01;\n //console.log(\"groups\", groups);\n delete self.d3cola._lastStress;\n delete self.d3cola._alpha;\n delete self.d3cola._descent;\n delete self.d3cola._rootGroup;\n\n let linkLength = (nodes.length < 30) ? 30 : 20;\n const width = self.svgElement.parentNode.clientWidth;\n const height = self.svgElement.parentNode.clientHeight;\n //console.log(\"**\", layoutObj);\n self.d3cola.size([height - 40, width - 40])\n .nodes(layoutObj.nodes).groups(groups).links(layoutObj.links).avoidOverlaps(true);\n let groupDebugSel, participantDebugSel;\n if (self.debug) {\n groupDebugSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](self.container).selectAll(\".group\")\n .data(groups);\n\n groupDebugSel.enter().append(\"rect\")\n .classed(\"group\", true)\n .attr({\n rx: 5,\n ry: 5\n })\n .style(\"stroke\", \"blue\")\n .style(\"fill\", \"none\");\n\n participantDebugSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](self.container).selectAll(\".node\")\n .data(layoutObj.nodes);\n\n participantDebugSel.enter().append(\"rect\")\n .classed(\"node\", true)\n .attr({\n rx: 5,\n ry: 5\n })\n .style(\"stroke\", \"red\")\n .style(\"fill\", \"none\");\n\n groupDebugSel.exit().remove();\n participantDebugSel.exit().remove();\n }\n\n const startTime = Date.now();\n self.d3cola.symmetricDiffLinkLengths(linkLength)\n .on(\"tick\", function () {\n if (Date.now() - startTime > 400) {//!preRun) {\n const nodes = self.d3cola.nodes();\n for (let node of nodes) {\n node.setPosition(node.x, node.y);\n }\n self.setAllLinkCoordinates();\n self.zoomToExtent();\n if (self.debug) {\n groupDebugSel.attr({\n x: function (d) {\n return d.bounds.x;// + (width / 2);\n },\n y: function (d) {\n return d.bounds.y;// + (height / 2);\n },\n width: function (d) {\n return d.bounds.width();\n },\n height: function (d) {\n return d.bounds.height();\n }\n });\n\n participantDebugSel.attr({\n x: function (d) {\n return d.bounds.x;// + (width / 2);\n },\n y: function (d) {\n return d.bounds.y;// + (height / 2);\n },\n width: function (d) {\n return d.bounds.width();\n },\n height: function (d) {\n return d.bounds.height();\n }\n });\n }\n }\n })\n .on(\"end\", function () {\n if (preRun) {\n // alert(\"initial run complete\");\n // // for (let p of layoutObj.nodes) {\n // // p.fixed = 1;\n // // }\n // // let nodesExceptComplexes = Array.from(self.participants.values());\n // // allNodesExceptComplexes = allNodesExceptComplexes.filter(function (value) {\n // // return value.type !== \"complex\";\n // // });\n doLayout(allNodesExceptComplexes, false);\n } else {\n for (let node of nodes) {\n node.setPosition(node.x, node.y);\n }\n self.setAllLinkCoordinates();\n self.zoomToExtent();\n }\n });\n if (preRun) {\n self.d3cola.start(23, 23, 0, 0, true);//, false, false);\n } else {\n self.d3cola.start(0, 23, 23, 0, true);//, false, false);\n }\n }\n};\n\nApp.prototype.getSVG = function () { //todo - update after styling of svg is moved to css\n let svgXml = this.svgElement.outerHTML.replace(//i, \"\"); //take out white background fill\n const viewBox = \"viewBox=\\\"0 0 \" + this.svgElement.parentNode.clientWidth + \" \" + this.svgElement.parentNode.clientHeight + \"\\\" \";\n svgXml = svgXml.replace(\"