From 48f95e63b39c5768ebc67e822728f7be247f087f Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 10 Jan 2020 11:29:11 +0000
Subject: [PATCH 01/66] factor out labels from visualization manager.

---
 src/manager.ts | 104 +++++++++++++++++++++++--------------------------
 src/ui.ts      |  49 ++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 58 deletions(-)

diff --git a/src/manager.ts b/src/manager.ts
index 1e4637c..026c10f 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -7,6 +7,9 @@ const clickEvent = 'PDB.interactions.click';
 const mouseoverEvent = 'PDB.interactions.mouseover';
 const mouseoutEvent = 'PDB.interactions.mouseout'
 
+const showLabelEvent = 'PDB.interactions.showLabel'
+const hideLabelEvent = 'PDB.interactions.hideLabel'
+
 class Visualization {
     // component related
     private parent: HTMLElement;
@@ -21,11 +24,6 @@ class Visualization {
     private links: any
     // #endregion
 
-    // #region ui properties
-    private residueLabel: d3.Selection<d3.BaseType, {}, HTMLElement, any>;
-    private tooltip: d3.Selection<d3.BaseType, {}, HTMLElement, any>;
-    // #endregion
-
     // #region data properties    
     private pdbId: string;
     private bindingSite: Model.BindingSite;
@@ -42,9 +40,6 @@ class Visualization {
 
         new UI(this.parent, this).register(new Model.UIParameters());
 
-        this.tooltip = d3.select("#int-tooltip");
-        this.residueLabel = d3.select('#int-residue-label');
-
         this.canvas = d3.select(this.parent)
             .append('div')
             .attr('id', 'int-canvas');
@@ -89,24 +84,15 @@ class Visualization {
     }
 
     private linkMouseClickEventHandler(x: Model.Link) {
-        this.fireLinkEvent(x, clickEvent);
+        this.fireExternalLinkEvent(x, clickEvent);
     }
 
     private linkMouseOverEventHandler(x: Model.Link) {
-        this.tooltip.transition()
-            .duration(200)
-            .style('opacity', .9);
-
-        this.tooltip.html(x.toTooltip());
-        this.fireLinkEvent(x, mouseoverEvent);
+        this.fireExternalLinkEvent(x, mouseoverEvent);
     }
 
     private linkMouseOutEventHandler() {
-        this.tooltip.transition()
-            .duration(200)
-            .style('opacity', 0);
-
-        this.fireLinkLeaveEvent();
+        this.fireExternalLinkLeaveEvent();
     }
 
     private zoom_handler = d3.zoom()
@@ -213,9 +199,7 @@ class Visualization {
         if (ctx.depiction === undefined) ctx.setupScene();
         else ctx.setupLigandScene();
 
-        ctx.residueLabel.transition()
-            .duration(200)
-            .style('opacity', 0);
+        ctx.hideLigandLabel();
     }
 
     private resize(ctx: Visualization) {
@@ -277,13 +261,14 @@ class Visualization {
     // #endregion menu functions
 
     // #region mouse events
+
     //https://stackoverflow.com/questions/40722344/understanding-d3-with-an-example-mouseover-mouseup-with-multiple-arguments
-    private fireNodeMouseEnterEvent(x: Model.InteractionNode, i: number, g: any) {
+    private fireExternalNodeMouseEnterEvent(x: Model.InteractionNode, i: number, g: any) {
         this.nodeHighlight(x, i, g);
-        this.fireNodeEvent(x, mouseoverEvent);
+        this.fireExternalNodeEvent(x, mouseoverEvent);
     }
 
-    private fireNodeMouseLeaveEvent(x: Model.InteractionNode, i: number, g: any) {
+    private fireExternalNodeMouseLeaveEvent(x: Model.InteractionNode, i: number, g: any) {
         this.nodeDim(x, i, g);
 
         const e = new CustomEvent(mouseoutEvent, {
@@ -293,7 +278,7 @@ class Visualization {
         this.parent.dispatchEvent(e);
     }
 
-    private fireLinkEvent(link: Model.Link, eventName: string) {
+    private fireExternalLinkEvent(link: Model.Link, eventName: string) {
         let atomsSource = [];
         let atomsTarget = [];
 
@@ -323,14 +308,15 @@ class Visualization {
                         auth_ins_code_id: link.target.residue.authorInsertionCode,
                         atoms: atomsTarget
                     }
-                ]
+                ],
+                tooltip: link.toTooltip()
             }
         });
 
         this.parent.dispatchEvent(e);
     }
 
-    private fireNodeEvent(node: Model.InteractionNode, eventName: string) {
+    private fireExternalNodeEvent(node: Model.InteractionNode, eventName: string) {
         const e = new CustomEvent(eventName, {
             bubbles: true,
             detail: {
@@ -339,14 +325,15 @@ class Visualization {
                     auth_asym_id: node.residue.chainId,
                     auth_seq_id: node.residue.authorResidueNumber,
                     auth_ins_code_id: node.residue.authorInsertionCode
-                }
+                },
+                tooltip: node.toTooltip()
             }
         });
 
         this.parent.dispatchEvent(e);
     }
 
-    private fireLinkLeaveEvent() {
+    private fireExternalLinkLeaveEvent() {
         const e = new CustomEvent(mouseoutEvent, {
             bubbles: true,
             detail: {}
@@ -357,23 +344,14 @@ class Visualization {
 
     // #endregion mouse events
 
-    // #region Labels
-    private showLabel(x: Model.InteractionNode) {
-        this.residueLabel.transition()
-            .duration(200)
-            .style('opacity', .9);
-
-        this.residueLabel.html(x.toTooltip());
-    }
-    //#endregion labels
 
     private selectLigand(n: Model.InteractionNode, i: number, g: any) {
-        this.fireNodeEvent(n, clickEvent);
+        this.fireExternalNodeEvent(n, clickEvent);
 
         if (!n.residue.isLigand) return;
 
         this.visualization.remove();
-        this.fireNodeMouseLeaveEvent(n, i, g);
+        this.fireExternalNodeMouseLeaveEvent(n, i, g);
         this.showLabel(n);
 
         this.initialiseLigand(this.pdbId, n.residue.authorResidueNumber, n.residue.chainId);
@@ -441,9 +419,9 @@ class Visualization {
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
             .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`)
-            .on('click', (x: Model.InteractionNode) => this.fireNodeEvent(x, clickEvent))
-            .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireNodeMouseEnterEvent(x, i, g))
-            .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireNodeMouseLeaveEvent(x, i, g));
+            .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, clickEvent))
+            .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
+            .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand && this.visualsMapper.glycanMapping.has(x.residue.chemCompId))
             .html((e: Model.InteractionNode) => this.visualsMapper.getGlycanImage(e.residue.chemCompId));
@@ -520,8 +498,8 @@ class Visualization {
             .enter().append('g')
             .attr('class', (e: Model.InteractionNode) => `svg-node svg-${e.residue.getResidueType()}-res`)
             .on('click', (x: Model.InteractionNode, i: number, g: any) => this.selectLigand(x, i, g))
-            .on('mouseover', (x: Model.InteractionNode, i: number, g: any) => this.fireNodeMouseEnterEvent(x, i, g))
-            .on('mouseout', (x: Model.InteractionNode, i: number, g: any) => this.fireNodeMouseLeaveEvent(x, i, g));
+            .on('mouseover', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
+            .on('mouseout', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
 
         await this.visualsMapper.graphicsPromise;
@@ -583,12 +561,6 @@ class Visualization {
         if (x.residue.isLigand) d3.select(g[i]).style('cursor', 'pointer');
         d3.select(g[i])
             .attr('transform', () => `translate(${x.x},${x.y}) scale(${x.scale})`);
-
-        this.tooltip.transition()
-            .duration(200)
-            .style('opacity', .9);
-
-        this.tooltip.html(x.toTooltip());
     }
 
     private nodeDim(x: Model.InteractionNode, i: number, g: any) {
@@ -597,12 +569,32 @@ class Visualization {
         if (x.residue.isLigand) d3.select(g[i]).style('cursor', 'default');
         d3.select(g[i])
             .attr('transform', `translate(${x.x},${x.y}) scale(${x.scale})`);
+    }
+
+
+    private showLabel(x: Model.InteractionNode) {
+        const e = new CustomEvent(showLabelEvent, {
+            bubbles: true,
+            detail: {
+                label: x.toTooltip()
+            }
+        });
+
+        this.parent.dispatchEvent(e);
+    }
 
-        this.tooltip.transition()
-            .duration(200)
-            .style('opacity', 0);
+    private hideLigandLabel() {
+        const e = new CustomEvent(hideLabelEvent, {
+            bubbles: true,
+            detail: {
+
+            }
+        });
+
+        this.parent.dispatchEvent(e);
     }
 
+
     private addMarkers() {
         // let mapping = new Map<string, string>([
         //     // ["arrow-electrostatic", "#3F26BF"],
diff --git a/src/ui.ts b/src/ui.ts
index fb9d01d..34fc80d 100644
--- a/src/ui.ts
+++ b/src/ui.ts
@@ -174,7 +174,7 @@ class UI {
         if (params.center) {
             dynamicPanel.append('i')
                 .attr('id', 'int-center-btn')
-                .attr('title', 'Center screeeeeeeeeeeen')
+                .attr('title', 'Center screen')
                 .attr('class', 'icon icon-common icon-crosshairs')
                 .on('click', () => this.center());
         }
@@ -220,7 +220,18 @@ class UI {
         }
 
         console.log(this.residueLabel);
-        console.log(this.tooltip);
+
+        if (this.tooltip !== undefined) {
+            document.addEventListener(clickEvent, e => this.nodeMouseEnterEventHandler(e));
+            document.addEventListener(mouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
+            document.addEventListener(mouseoutEvent, () => this.nodeMouseLeaveEventHandler());
+        }
+
+        if (this.residueLabel !== undefined) {
+            document.addEventListener(showLabelEvent, e => this.showLigandLabel(e));
+            document.addEventListener(hideLabelEvent, () => this.hideLigandLabel());
+        }
+
     }
 
     // #region UI methods
@@ -292,4 +303,38 @@ class UI {
     }
 
     // #endregion UI methods
+
+    // #region event handlers
+    private nodeMouseEnterEventHandler(e: any) {
+        this.tooltip.transition()
+            .duration(200)
+            .style('opacity', .9);
+
+        this.tooltip.html(e.detail.tooltip);
+
+    }
+
+    private nodeMouseLeaveEventHandler() {
+        this.tooltip.transition()
+            .duration(200)
+            .style('opacity', 0);
+
+    }
+
+    private showLigandLabel(e: any) {
+        this.residueLabel.transition()
+            .duration(200)
+            .style('opacity', .9);
+
+        this.residueLabel.html(e.detail.label);
+
+    }
+
+    private hideLigandLabel() {
+        this.residueLabel.transition()
+            .duration(200)
+            .style('opacity', 0);
+    }
+    // #endregion event handlers
+
 }
\ No newline at end of file
-- 
GitLab


From c0c2b37eb1fc4e7e9a1d835d62cef2d85bf12bdc Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 10 Jan 2020 11:31:53 +0000
Subject: [PATCH 02/66] fix zoom, to be component dependent

---
 src/manager.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/manager.ts b/src/manager.ts
index 026c10f..c00de22 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -97,7 +97,9 @@ class Visualization {
 
     private zoom_handler = d3.zoom()
         .scaleExtent([1 / 10, 10])
-        .on('zoom', () => d3.select('#vis-root').attr('transform', d3.event.transform));
+        .on('zoom', () => d3.select(this.parent)
+            .select('#vis-root')
+            .attr('transform', d3.event.transform));
 
     private drag_handler = d3.drag()
         .on('start', (x: Model.InteractionNode) => {
-- 
GitLab


From 133e2df97b67e4e09b347d092b0d9841e2757e80 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 10 Jan 2020 11:35:38 +0000
Subject: [PATCH 03/66] do not pass context unnecessary

---
 src/manager.ts | 78 ++++++++++++++++++++++++--------------------------
 src/ui.ts      |  8 +++---
 2 files changed, 42 insertions(+), 44 deletions(-)

diff --git a/src/manager.ts b/src/manager.ts
index c00de22..5e35edb 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -54,7 +54,7 @@ class Visualization {
         document.addEventListener('PDB.molstar.mouseover', e => this.nodeMouseEnterEventHandler(e));
         document.addEventListener('PDB.molstar.mouseout', () => this.nodeMouseLeaveEventHandler());
 
-        d3.select(window).on('resize', () => this.resize(this));
+        d3.select(window).on('resize', () => this.resize());
     }
 
     // #region even handlers
@@ -160,7 +160,7 @@ class Visualization {
     }
 
     // #region menu functions
-    public saveSvg(ctx: Visualization) {
+    public saveSvg() {
         d3.text('pdbe-interactions-svgstyles.css').then(x => {
             let svgToDl = d3.select('#int-canvas');
             svgToDl.select('svg')
@@ -173,7 +173,7 @@ class Visualization {
             let downloadLink = document.createElement('a');
 
             downloadLink.href = svgUrl;
-            downloadLink.download = `${ctx.pdbId}_${ctx.bindingSite.bmId}.svg`;
+            downloadLink.download = `${this.pdbId}_${this.bindingSite.bmId}.svg`;
 
             document.body.appendChild(downloadLink);
             downloadLink.click();
@@ -182,61 +182,61 @@ class Visualization {
     }
 
 
-    public downloadInteractionsData(ctx: Visualization): void {
+    public downloadInteractionsData(this: Visualization): void {
         let downloadLink = document.createElement('a');
 
-        let dataBlob = new Blob([JSON.stringify(ctx.interactionsData, null, 4)], { type: 'application/json' });
+        let dataBlob = new Blob([JSON.stringify(this.interactionsData, null, 4)], { type: 'application/json' });
 
         downloadLink.href = URL.createObjectURL(dataBlob);
-        downloadLink.download = `${ctx.pdbId}_${ctx.bindingSite.bmId}_interactions.json`;
+        downloadLink.download = `${this.pdbId}_${this.bindingSite.bmId}_interactions.json`;
         document.body.appendChild(downloadLink);
         downloadLink.click();
         document.body.removeChild(downloadLink);
     }
 
 
-    public reinitialize(ctx: Visualization) {
-        ctx.visualization.remove();
+    public reinitialize() {
+        this.visualization.remove();
 
-        if (ctx.depiction === undefined) ctx.setupScene();
-        else ctx.setupLigandScene();
+        if (this.depiction === undefined) this.setupScene();
+        else this.setupLigandScene();
 
-        ctx.hideLigandLabel();
+        this.hideLigandLabel();
     }
 
-    private resize(ctx: Visualization) {
-        ctx.svg
-            .attr('width', ctx.parent.offsetWidth)
-            .attr('height', ctx.parent.offsetHeight);
+    private resize() {
+        this.svg
+            .attr('width', this.parent.offsetWidth)
+            .attr('height', this.parent.offsetHeight);
 
-        if (ctx.depiction === undefined) {
-            ctx.simulation
+        if (this.depiction === undefined) {
+            this.simulation
                 .force('center', d3.forceCenter(this.parent.offsetWidth / 2, this.parent.offsetHeight / 2))
                 .restart();
-        } else ctx.simulation.restart();
+        } else this.simulation.restart();
 
-        ctx.zoom_handler(ctx.svg);
+        this.zoom_handler(this.svg);
     }
 
 
-    public centerScene(ctx: Visualization) {
-        if (ctx.nodes.length === 0)
+    public centerScene() {
+        if (this.nodes.length === 0)
             return;
 
         // Get the bounding box
-        let minX: any = d3.min(ctx.nodes.data().map((x) => x.x));
-        let minY: any = d3.min(ctx.nodes.data().map((x) => x.y));
+        let minX: any = d3.min(this.nodes.data().map((x) => x.x));
+        let minY: any = d3.min(this.nodes.data().map((x) => x.y));
 
-        let maxX: any = d3.max(ctx.nodes.data().map((x) => x.x));
-        let maxY: any = d3.max(ctx.nodes.data().map((x) => x.y));
+        let maxX: any = d3.max(this.nodes.data().map((x) => x.x));
+        let maxY: any = d3.max(this.nodes.data().map((x) => x.y));
 
         // The width and the height of the graph
         let molWidth = maxX - minX;
         let molHeight = maxY - minY;
 
         // how much larger the drawing area is than the width and the height
-        let widthRatio = ctx.parent.offsetWidth / molWidth;
-        let heightRatio = ctx.parent.offsetHeight / molHeight;
+        let widthRatio = this.parent.offsetWidth / molWidth;
+        let heightRatio = this.parent.offsetHeight / molHeight;
 
         // we need to fit it in both directions, so we scale according to
         // the direction in which we need to shrink the most
@@ -247,15 +247,15 @@ class Visualization {
         let newMolHeight = molHeight * minRatio;
 
         // translate so that it's in the center of the window
-        let xTrans = -(minX) * minRatio + (ctx.parent.offsetWidth - newMolWidth) / 2;
-        let yTrans = -(minY) * minRatio + (ctx.parent.offsetHeight - newMolHeight) / 2;
+        let xTrans = -(minX) * minRatio + (this.parent.offsetWidth - newMolWidth) / 2;
+        let yTrans = -(minY) * minRatio + (this.parent.offsetHeight - newMolHeight) / 2;
 
         // do the actual moving
-        ctx.visualization.attr('transform', `translate(${xTrans}, ${yTrans}) scale(${minRatio})`);
+        this.visualization.attr('transform', `translate(${xTrans}, ${yTrans}) scale(${minRatio})`);
 
         // tell the zoomer what we did so that next we zoom, it uses the
         // transformation we entered here        
-        ctx.zoom_handler.transform(ctx.svg, d3.zoomIdentity);
+        this.zoom_handler.transform(this.svg, d3.zoomIdentity);
 
 
 
@@ -463,21 +463,19 @@ class Visualization {
             //            .force('charge', charge) //strength 
             .force('collision', collision)
             //                    .force('center', center)
-            .on('tick', () => this.simulationStep(this));
+            .on('tick', () => this.simulationStep());
 
         this.drag_handler(this.nodes);
         this.zoom_handler(this.svg);
-        this.centerScene(this);
+        this.centerScene();
     }
 
     private async setupScene() {
-        let context = this;
-
         this.visualization = this.svg.append('g').attr('id', 'vis-root');
         this.links = this.visualization.append('g')
             .attr('id', 'links')
             .selectAll()
-            .data(context.bindingSite.links)
+            .data(this.bindingSite.links)
             .enter().append('g')
 
         this.links
@@ -543,15 +541,15 @@ class Visualization {
             .force('charge', charge) //strength 
             .force('collision', collision)
             .force('center', center)
-            .on('tick', () => this.simulationStep(this));
+            .on('tick', () => this.simulationStep());
 
         this.drag_handler(this.nodes);
         this.zoom_handler(this.svg);
     }
 
-    private simulationStep(ctx: Visualization) {
-        ctx.nodes.attr('transform', (d) => `translate(${d.x},${d.y}) scale(${d.scale})`);
-        ctx.links.selectAll('line').attr('x1', (x: any) => x.source.x)
+    private simulationStep() {
+        this.nodes.attr('transform', (d) => `translate(${d.x},${d.y}) scale(${d.scale})`);
+        this.links.selectAll('line').attr('x1', (x: any) => x.source.x)
             .attr('y1', (x: any) => x.source.y)
             .attr('x2', (x: any) => x.target.x)
             .attr('y2', (x: any) => x.target.y);
diff --git a/src/ui.ts b/src/ui.ts
index 34fc80d..0874ccd 100644
--- a/src/ui.ts
+++ b/src/ui.ts
@@ -236,19 +236,19 @@ class UI {
 
     // #region UI methods
     private saveSVG() {
-        this.display.saveSvg(this.display);
+        this.display.saveSvg();
     }
 
     private reinitialize() {
-        this.display.reinitialize(this.display)
+        this.display.reinitialize()
     }
 
     private download() {
-        this.display.downloadInteractionsData(this.display)
+        this.display.downloadInteractionsData()
     }
 
     private center() {
-        this.display.centerScene(this.display)
+        this.display.centerScene()
     }
 
     private changeHelp(showResidues: boolean) {
-- 
GitLab


From 59816df071bfc880ae6b79ed0fd94c4c846cf08c Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 10 Jan 2020 13:14:24 +0000
Subject: [PATCH 04/66] few fixes

---
 src/manager.ts | 15 +++++++--------
 src/ui.ts      | 31 +++++++++++++++----------------
 2 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/src/manager.ts b/src/manager.ts
index 5e35edb..760579f 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -262,7 +262,7 @@ class Visualization {
     };
     // #endregion menu functions
 
-    // #region mouse events
+    // #region fire events
 
     //https://stackoverflow.com/questions/40722344/understanding-d3-with-an-example-mouseover-mouseup-with-multiple-arguments
     private fireExternalNodeMouseEnterEvent(x: Model.InteractionNode, i: number, g: any) {
@@ -344,7 +344,7 @@ class Visualization {
         this.parent.dispatchEvent(e);
     }
 
-    // #endregion mouse events
+    // #endregion fire events
 
 
     private selectLigand(n: Model.InteractionNode, i: number, g: any) {
@@ -354,7 +354,7 @@ class Visualization {
 
         this.visualization.remove();
         this.fireExternalNodeMouseLeaveEvent(n, i, g);
-        this.showLabel(n);
+        this.showLigandLabel(n);
 
         this.initialiseLigand(this.pdbId, n.residue.authorResidueNumber, n.residue.chainId);
     }
@@ -484,7 +484,7 @@ class Visualization {
             .attr('class', 'svg-shadow-bond')
             .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
             .on('mouseover', (x: Model.Link) => this.linkMouseOverEventHandler(x))
-            .on('mouseout', (x: Model.Link) => this.linkMouseOverEventHandler(x));
+            .on('mouseout', () => this.linkMouseOutEventHandler());
 
         this.links
             .append('line')
@@ -567,12 +567,13 @@ class Visualization {
         x.scale = 1.0;
 
         if (x.residue.isLigand) d3.select(g[i]).style('cursor', 'default');
+
         d3.select(g[i])
             .attr('transform', `translate(${x.x},${x.y}) scale(${x.scale})`);
     }
 
 
-    private showLabel(x: Model.InteractionNode) {
+    private showLigandLabel(x: Model.InteractionNode) {
         const e = new CustomEvent(showLabelEvent, {
             bubbles: true,
             detail: {
@@ -586,9 +587,7 @@ class Visualization {
     private hideLigandLabel() {
         const e = new CustomEvent(hideLabelEvent, {
             bubbles: true,
-            detail: {
-
-            }
+            detail: {}
         });
 
         this.parent.dispatchEvent(e);
diff --git a/src/ui.ts b/src/ui.ts
index 0874ccd..0250abe 100644
--- a/src/ui.ts
+++ b/src/ui.ts
@@ -219,17 +219,15 @@ class UI {
                 .style('opacity', 0)
         }
 
-        console.log(this.residueLabel);
-
         if (this.tooltip !== undefined) {
-            document.addEventListener(clickEvent, e => this.nodeMouseEnterEventHandler(e));
-            document.addEventListener(mouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
-            document.addEventListener(mouseoutEvent, () => this.nodeMouseLeaveEventHandler());
+            this.root.addEventListener(clickEvent, e => this.nodeMouseEnterEventHandler(e));
+            this.root.addEventListener(mouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
+            this.root.addEventListener(mouseoutEvent, () => this.nodeMouseLeaveEventHandler());
         }
 
         if (this.residueLabel !== undefined) {
-            document.addEventListener(showLabelEvent, e => this.showLigandLabel(e));
-            document.addEventListener(hideLabelEvent, () => this.hideLigandLabel());
+            this.root.addEventListener(showLabelEvent, e => this.showLigandLabel(e));
+            this.root.addEventListener(hideLabelEvent, () => this.hideLigandLabel());
         }
 
     }
@@ -252,10 +250,10 @@ class UI {
     }
 
     private changeHelp(showResidues: boolean) {
-        let ligHelpBtn = d3.select('#int-help-residues-btn');
-        let bondHelpBtn = d3.select('#int-help-bonds-btn');
-        let bondHelpSection = d3.select('#int-help-bonds');
-        let ligHelpSection = d3.select('#int-help-ligands');
+        let ligHelpBtn = d3.select(this.root).select('#int-help-residues-btn');
+        let bondHelpBtn = d3.select(this.root).select('#int-help-bonds-btn');
+        let bondHelpSection = d3.select(this.root).select('#int-help-bonds');
+        let ligHelpSection = d3.select(this.root).select('#int-help-ligands');
 
         if (showResidues) {
             bondHelpBtn.classed('active', false);
@@ -271,9 +269,9 @@ class UI {
         }
     }
 
-    showHelp() {
-        let el = d3.select('#int-help-container');
-        let btn = d3.select('#int-help-btn');
+    private showHelp() {
+        let el = d3.select(this.root).select('#int-help-container');
+        let btn = d3.select(this.root).select('#int-help-btn');
 
         if (el.style('display') === 'block') {
             el.style('display', 'none');
@@ -287,8 +285,8 @@ class UI {
     }
 
     displayToolbarPanel(show: boolean) {
-        let dynPanel = d3.select('#int-menu-dynamic-panel');
-        let el = d3.select('#int-help-container');
+        let dynPanel = d3.select(this.root).select('#int-menu-dynamic-panel');
+        let el = d3.select(this.root).select('#int-help-container');
 
         if (!dynPanel && !el) return;
 
@@ -306,6 +304,7 @@ class UI {
 
     // #region event handlers
     private nodeMouseEnterEventHandler(e: any) {
+
         this.tooltip.transition()
             .duration(200)
             .style('opacity', .9);
-- 
GitLab


From b9c60f031b957048ad090b2abd288bcdc8b2d771 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 14 Jan 2020 17:06:03 +0000
Subject: [PATCH 05/66] add fullscreen mode

---
 build/index.html | 14 +++++++-------
 src/manager.ts   | 31 +++++++++++++++++++++++++++++--
 src/model.ts     |  2 ++
 src/ui.ts        | 27 +++++++++++++++++++++++++--
 4 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/build/index.html b/build/index.html
index b919569..5d9ef6c 100644
--- a/build/index.html
+++ b/build/index.html
@@ -24,13 +24,13 @@
 <script type="module" src="component.js"></script>
 <script>
     var renderBmInteractions = function (id, bmId) {
-        var int = `<pdb-interactions pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
+        var int = `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
     var renderLigandInteractions = function (id, chain, resId) {
         var int =
-            `<pdb-interactions pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}"></pdb-interactions>`
+            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}"></pdb-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
@@ -112,16 +112,16 @@
 
 <body>
     <div style="position: relative; float: left;">
-        <div id="rt" style="width: 500px; height: 500px; border: 1px solid black; position: relative">
+        <div id="rt" style="width: 500px; height: 500px; position: relative">
         </div>
     </div>
     <div style="position: relative; float: left;">
         <div id='3dViewer' style="position:relative; width: 500px;height: 500px;"></div>
     </div>
-    <!-- <div style="position: relative; float: left;">
-        <div id="rt" style="width: 500px; height: 500px; border: 1px solid black; position: relative">
-            <pdb-interactions pdb-id="3d11" bound-molecule-id="bm1"></pdb-interactions>
-        </div> -->
+    <div style="position: relative; float: left;">
+        <div id="rt 1" style="width: 500px; height: 500px; position: relative">
+            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+        </div>
     </div>
 
     <!--
diff --git a/src/manager.ts b/src/manager.ts
index 760579f..94f938b 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -32,6 +32,9 @@ class Visualization {
     private visualsMapper: VisualsMapper;
     private interactionsData: any;
     private selectedResidueHash: string;
+
+    private originalWidth: number;
+    private originalHeight: number;
     // #endregion
 
     constructor(element: HTMLElement) {
@@ -46,9 +49,15 @@ class Visualization {
 
         this.svg = this.canvas
             .append('svg')
+            .style('background-color', 'white')
             .attr('xmlns', 'http://www.w3.org/2000/svg')
-            .attr('width', () => this.parent.offsetWidth)
-            .attr('height', () => this.parent.offsetHeight)
+            .attr('width', '100%')
+            .attr('height', '100%')
+
+        this.visualization = this.svg.append('g').attr('id', 'vis-root');
+
+        this.originalWidth = this.parent.offsetWidth;
+        this.originalHeight = this.parent.offsetHeight;
 
         document.addEventListener('PDB.molstar.click', e => this.nodeMouseEnterEventHandler(e));
         document.addEventListener('PDB.molstar.mouseover', e => this.nodeMouseEnterEventHandler(e));
@@ -260,6 +269,24 @@ class Visualization {
 
 
     };
+
+    public fullScreen() {
+        this.parent.parentElement.style.width = '100%'
+        this.parent.parentElement.style.height = '100%'
+        this.parent.parentElement.style.position = 'fixed';
+        this.parent.parentElement.style.zIndex = '10000000000000';
+
+        this.centerScene();
+    }
+
+    public minimizeScreen() {
+        this.parent.parentElement.style.width = `${this.originalWidth}px`;
+        this.parent.parentElement.style.height = `${this.originalHeight}px`;
+        this.parent.parentElement.style.position = 'relative';
+        this.parent.parentElement.style.zIndex = '';
+
+        this.centerScene();
+    }
     // #endregion menu functions
 
     // #region fire events
diff --git a/src/model.ts b/src/model.ts
index 8384393..0b7ad14 100644
--- a/src/model.ts
+++ b/src/model.ts
@@ -25,6 +25,7 @@ namespace Model {
 
     export class UIParameters {
         reinitialize: boolean;
+        fullScreen: boolean;
         downloadImage: boolean;
         downloadData: boolean;
         center: boolean;
@@ -34,6 +35,7 @@ namespace Model {
 
         constructor() {
             this.reinitialize = true;
+            this.fullScreen = true;
             this.downloadImage = true;
             this.downloadData = true;
             this.center = true;
diff --git a/src/ui.ts b/src/ui.ts
index 0250abe..c207f17 100644
--- a/src/ui.ts
+++ b/src/ui.ts
@@ -1,4 +1,4 @@
-/// <reference path="./manager.ts" />
+/// <reference path="./config.ts" />
 
 // #region help
 let helpLigands = `
@@ -147,6 +147,14 @@ class UI {
             .style('display', 'none')
             .style('opacity', 0);
 
+        if (params.fullScreen) {
+            dynamicPanel.append('i')
+                .attr('id', 'int-fullscreen-btn')
+                .attr('title', 'Fullscreen')
+                .attr('class', 'icon icon-common icon-fullscreen')
+                .on('click', () => this.fullScreen());
+        }
+
         if (params.reinitialize) {
             dynamicPanel.append('i')
                 .attr('id', 'int-home-btn')
@@ -284,7 +292,7 @@ class UI {
         }
     }
 
-    displayToolbarPanel(show: boolean) {
+    private displayToolbarPanel(show: boolean) {
         let dynPanel = d3.select(this.root).select('#int-menu-dynamic-panel');
         let el = d3.select(this.root).select('#int-help-container');
 
@@ -300,6 +308,21 @@ class UI {
         }
     }
 
+    private fullScreen() {
+        let btn = d3.select(this.root).select('#int-fullscreen-btn');
+        // d3.select(this.root).style('z-index', Number.MAX_VALUE);
+
+        if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
+            this.display.fullScreen();
+            btn.classed('icon-fullscreen', false);
+            btn.classed('icon-fullscreen-collapse', true);
+        } else {
+            btn.classed('icon-fullscreen', true);
+            btn.classed('icon-fullscreen-collapse', false);
+            this.display.minimizeScreen();
+        }
+    }
+
     // #endregion UI methods
 
     // #region event handlers
-- 
GitLab


From e94886ae3eeffa2b3198614f05b45cc2d6f9566a Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 15 Jan 2020 09:36:49 +0000
Subject: [PATCH 06/66] update dependencies

---
 package-lock.json | 1231 +++++++++++++++++++++++++--------------------
 package.json      |   18 +-
 2 files changed, 692 insertions(+), 557 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 639c163..4b675eb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,256 +5,290 @@
   "requires": true,
   "dependencies": {
     "@babel/code-frame": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
-      "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+      "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
       "dev": true,
       "requires": {
-        "@babel/highlight": "^7.0.0"
+        "@babel/highlight": "^7.8.3"
+      }
+    },
+    "@babel/compat-data": {
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.8.1.tgz",
+      "integrity": "sha512-Z+6ZOXvyOWYxJ50BwxzdhRnRsGST8Y3jaZgxYig575lTjVSs3KtJnmESwZegg6e2Dn0td1eDhoWlp1wI4BTCPw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.8.2",
+        "invariant": "^2.2.4",
+        "semver": "^5.5.0"
       }
     },
     "@babel/core": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz",
-      "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "@babel/generator": "^7.4.4",
-        "@babel/helpers": "^7.4.4",
-        "@babel/parser": "^7.4.5",
-        "@babel/template": "^7.4.4",
-        "@babel/traverse": "^7.4.5",
-        "@babel/types": "^7.4.4",
-        "convert-source-map": "^1.1.0",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz",
+      "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.8.3",
+        "@babel/helpers": "^7.8.3",
+        "@babel/parser": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3",
+        "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
+        "gensync": "^1.0.0-beta.1",
         "json5": "^2.1.0",
-        "lodash": "^4.17.11",
+        "lodash": "^4.17.13",
         "resolve": "^1.3.2",
         "semver": "^5.4.1",
         "source-map": "^0.5.0"
       }
     },
     "@babel/generator": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz",
-      "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz",
+      "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.4.4",
+        "@babel/types": "^7.8.3",
         "jsesc": "^2.5.1",
-        "lodash": "^4.17.11",
-        "source-map": "^0.5.0",
-        "trim-right": "^1.0.1"
+        "lodash": "^4.17.13",
+        "source-map": "^0.5.0"
       }
     },
     "@babel/helper-annotate-as-pure": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz",
-      "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz",
+      "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz",
-      "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz",
+      "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==",
       "dev": true,
       "requires": {
-        "@babel/helper-explode-assignable-expression": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-explode-assignable-expression": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-call-delegate": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz",
-      "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.8.3.tgz",
+      "integrity": "sha512-6Q05px0Eb+N4/GTyKPPvnkig7Lylw+QzihMpws9iiZQv7ZImf84ZsZpQH7QoWN4n4tm81SnSzPgHw2qtO0Zf3A==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-hoist-variables": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
+      }
+    },
+    "@babel/helper-compilation-targets": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.3.tgz",
+      "integrity": "sha512-JLylPCsFjhLN+6uBSSh3iYdxKdeO9MNmoY96PE/99d8kyBFaXLORtAVhqN6iHa+wtPeqxKLghDOZry0+Aiw9Tw==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.8.1",
+        "browserslist": "^4.8.2",
+        "invariant": "^2.2.4",
+        "levenary": "^1.1.0",
+        "semver": "^5.5.0"
+      }
+    },
+    "@babel/helper-create-regexp-features-plugin": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.3.tgz",
+      "integrity": "sha512-Gcsm1OHCUr9o9TcJln57xhWHtdXbA2pgQ58S0Lxlks0WMGNXuki4+GLfX0p+L2ZkINUGZvfkz8rzoqJQSthI+Q==",
       "dev": true,
       "requires": {
-        "@babel/helper-hoist-variables": "^7.4.4",
-        "@babel/traverse": "^7.4.4",
-        "@babel/types": "^7.4.4"
+        "@babel/helper-regex": "^7.8.3",
+        "regexpu-core": "^4.6.0"
       }
     },
     "@babel/helper-define-map": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz",
-      "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz",
+      "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/types": "^7.4.4",
-        "lodash": "^4.17.11"
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/types": "^7.8.3",
+        "lodash": "^4.17.13"
       }
     },
     "@babel/helper-explode-assignable-expression": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz",
-      "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz",
+      "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==",
       "dev": true,
       "requires": {
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-function-name": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
-      "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
+      "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
       "dev": true,
       "requires": {
-        "@babel/helper-get-function-arity": "^7.0.0",
-        "@babel/template": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-get-function-arity": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-get-function-arity": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
-      "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+      "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-hoist-variables": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz",
-      "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz",
+      "integrity": "sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.4.4"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-member-expression-to-functions": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz",
-      "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz",
+      "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-module-imports": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz",
-      "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz",
+      "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-module-transforms": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz",
-      "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.8.3.tgz",
+      "integrity": "sha512-C7NG6B7vfBa/pwCOshpMbOYUmrYQDfCpVL/JCRu0ek8B5p8kue1+BCXpg2vOYs7w5ACB9GTOBYQ5U6NwrMg+3Q==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-simple-access": "^7.1.0",
-        "@babel/helper-split-export-declaration": "^7.4.4",
-        "@babel/template": "^7.4.4",
-        "@babel/types": "^7.4.4",
-        "lodash": "^4.17.11"
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-simple-access": "^7.8.3",
+        "@babel/helper-split-export-declaration": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/types": "^7.8.3",
+        "lodash": "^4.17.13"
       }
     },
     "@babel/helper-optimise-call-expression": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz",
-      "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz",
+      "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.0.0"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-plugin-utils": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
-      "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
+      "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
       "dev": true
     },
     "@babel/helper-regex": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz",
-      "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz",
+      "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==",
       "dev": true,
       "requires": {
-        "lodash": "^4.17.11"
+        "lodash": "^4.17.13"
       }
     },
     "@babel/helper-remap-async-to-generator": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz",
-      "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz",
+      "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==",
       "dev": true,
       "requires": {
-        "@babel/helper-annotate-as-pure": "^7.0.0",
-        "@babel/helper-wrap-function": "^7.1.0",
-        "@babel/template": "^7.1.0",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-wrap-function": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-replace-supers": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz",
-      "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.3.tgz",
+      "integrity": "sha512-xOUssL6ho41U81etpLoT2RTdvdus4VfHamCuAm4AHxGr+0it5fnwoVdwUJ7GFEqCsQYzJUhcbsN9wB9apcYKFA==",
       "dev": true,
       "requires": {
-        "@babel/helper-member-expression-to-functions": "^7.0.0",
-        "@babel/helper-optimise-call-expression": "^7.0.0",
-        "@babel/traverse": "^7.4.4",
-        "@babel/types": "^7.4.4"
+        "@babel/helper-member-expression-to-functions": "^7.8.3",
+        "@babel/helper-optimise-call-expression": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-simple-access": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz",
-      "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz",
+      "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==",
       "dev": true,
       "requires": {
-        "@babel/template": "^7.1.0",
-        "@babel/types": "^7.0.0"
+        "@babel/template": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-split-export-declaration": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
-      "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+      "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.4.4"
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helper-wrap-function": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz",
-      "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz",
+      "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/template": "^7.1.0",
-        "@babel/traverse": "^7.1.0",
-        "@babel/types": "^7.2.0"
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/helpers": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz",
-      "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz",
+      "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==",
       "dev": true,
       "requires": {
-        "@babel/template": "^7.4.4",
-        "@babel/traverse": "^7.4.4",
-        "@babel/types": "^7.4.4"
+        "@babel/template": "^7.8.3",
+        "@babel/traverse": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/highlight": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
-      "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
+      "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
       "dev": true,
       "requires": {
         "chalk": "^2.0.0",
@@ -263,517 +297,593 @@
       }
     },
     "@babel/parser": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz",
-      "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz",
+      "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==",
       "dev": true
     },
     "@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz",
-      "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz",
+      "integrity": "sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-remap-async-to-generator": "^7.8.3",
+        "@babel/plugin-syntax-async-generators": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz",
+      "integrity": "sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-remap-async-to-generator": "^7.1.0",
-        "@babel/plugin-syntax-async-generators": "^7.2.0"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0"
       }
     },
     "@babel/plugin-proposal-json-strings": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz",
-      "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz",
+      "integrity": "sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-json-strings": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-json-strings": "^7.2.0"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
       }
     },
     "@babel/plugin-proposal-object-rest-spread": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz",
-      "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-object-rest-spread": "^7.2.0"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0"
       }
     },
     "@babel/plugin-proposal-optional-catch-binding": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz",
-      "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+      }
+    },
+    "@babel/plugin-proposal-optional-chaining": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz",
+      "integrity": "sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.2.0"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0"
       }
     },
     "@babel/plugin-proposal-unicode-property-regex": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz",
-      "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.3.tgz",
+      "integrity": "sha512-1/1/rEZv2XGweRwwSkLpY+s60za9OZ1hJs4YDqFHCw0kYWYwL5IFljVY1MYBL+weT1l9pokDO2uhSTLVxzoHkQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.4.4",
-        "regexpu-core": "^4.5.4"
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-syntax-async-generators": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz",
-      "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==",
+      "version": "7.8.4",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+      "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-dynamic-import": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+      "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
       }
     },
     "@babel/plugin-syntax-json-strings": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz",
-      "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+      "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-nullish-coalescing-operator": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+      "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
       }
     },
     "@babel/plugin-syntax-object-rest-spread": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz",
-      "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+      "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.0"
       }
     },
     "@babel/plugin-syntax-optional-catch-binding": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz",
-      "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+      "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-optional-chaining": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+      "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.0"
+      }
+    },
+    "@babel/plugin-syntax-top-level-await": {
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz",
+      "integrity": "sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-arrow-functions": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz",
-      "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz",
+      "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-async-to-generator": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz",
-      "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz",
+      "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-remap-async-to-generator": "^7.1.0"
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-remap-async-to-generator": "^7.8.3"
       }
     },
     "@babel/plugin-transform-block-scoped-functions": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz",
-      "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz",
+      "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-block-scoping": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz",
-      "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz",
+      "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "lodash": "^4.17.11"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "lodash": "^4.17.13"
       }
     },
     "@babel/plugin-transform-classes": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz",
-      "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-annotate-as-pure": "^7.0.0",
-        "@babel/helper-define-map": "^7.4.4",
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/helper-optimise-call-expression": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-replace-supers": "^7.4.4",
-        "@babel/helper-split-export-declaration": "^7.4.4",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.3.tgz",
+      "integrity": "sha512-SjT0cwFJ+7Rbr1vQsvphAHwUHvSUPmMjMU/0P59G8U2HLFqSa082JO7zkbDNWs9kH/IUqpHI6xWNesGf8haF1w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-define-map": "^7.8.3",
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/helper-optimise-call-expression": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-replace-supers": "^7.8.3",
+        "@babel/helper-split-export-declaration": "^7.8.3",
         "globals": "^11.1.0"
       }
     },
     "@babel/plugin-transform-computed-properties": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz",
-      "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz",
+      "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-destructuring": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz",
-      "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz",
+      "integrity": "sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-dotall-regex": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz",
-      "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz",
+      "integrity": "sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.4.4",
-        "regexpu-core": "^4.5.4"
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-duplicate-keys": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz",
-      "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz",
+      "integrity": "sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz",
-      "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz",
+      "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-for-of": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz",
-      "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.3.tgz",
+      "integrity": "sha512-ZjXznLNTxhpf4Q5q3x1NsngzGA38t9naWH8Gt+0qYZEJAcvPI9waSStSh56u19Ofjr7QmD0wUsQ8hw8s/p1VnA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-function-name": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz",
-      "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz",
+      "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-literals": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz",
-      "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz",
+      "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-member-expression-literals": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz",
-      "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz",
+      "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-modules-amd": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz",
-      "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.8.3.tgz",
+      "integrity": "sha512-MadJiU3rLKclzT5kBH4yxdry96odTUwuqrZM+GllFI/VhxfPz+k9MshJM+MwhfkCdxxclSbSBbUGciBngR+kEQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-transforms": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-module-transforms": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "babel-plugin-dynamic-import-node": "^2.3.0"
       }
     },
     "@babel/plugin-transform-modules-commonjs": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz",
-      "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz",
+      "integrity": "sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-transforms": "^7.4.4",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-simple-access": "^7.1.0"
+        "@babel/helper-module-transforms": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-simple-access": "^7.8.3",
+        "babel-plugin-dynamic-import-node": "^2.3.0"
       }
     },
     "@babel/plugin-transform-modules-systemjs": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz",
-      "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.8.3.tgz",
+      "integrity": "sha512-8cESMCJjmArMYqa9AO5YuMEkE4ds28tMpZcGZB/jl3n0ZzlsxOAi3mC+SKypTfT8gjMupCnd3YiXCkMjj2jfOg==",
       "dev": true,
       "requires": {
-        "@babel/helper-hoist-variables": "^7.4.4",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-hoist-variables": "^7.8.3",
+        "@babel/helper-module-transforms": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "babel-plugin-dynamic-import-node": "^2.3.0"
       }
     },
     "@babel/plugin-transform-modules-umd": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz",
-      "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.8.3.tgz",
+      "integrity": "sha512-evhTyWhbwbI3/U6dZAnx/ePoV7H6OUG+OjiJFHmhr9FPn0VShjwC2kdxqIuQ/+1P50TMrneGzMeyMTFOjKSnAw==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-transforms": "^7.1.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-module-transforms": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-named-capturing-groups-regex": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz",
-      "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz",
+      "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==",
       "dev": true,
       "requires": {
-        "regexp-tree": "^0.1.6"
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3"
       }
     },
     "@babel/plugin-transform-new-target": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz",
-      "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz",
+      "integrity": "sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-object-super": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz",
-      "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz",
+      "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-replace-supers": "^7.1.0"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-replace-supers": "^7.8.3"
       }
     },
     "@babel/plugin-transform-parameters": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz",
-      "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.3.tgz",
+      "integrity": "sha512-/pqngtGb54JwMBZ6S/D3XYylQDFtGjWrnoCF4gXZOUpFV/ujbxnoNGNvDGu6doFWRPBveE72qTx/RRU44j5I/Q==",
       "dev": true,
       "requires": {
-        "@babel/helper-call-delegate": "^7.4.4",
-        "@babel/helper-get-function-arity": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-call-delegate": "^7.8.3",
+        "@babel/helper-get-function-arity": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-property-literals": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz",
-      "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz",
+      "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-regenerator": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz",
-      "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.3.tgz",
+      "integrity": "sha512-qt/kcur/FxrQrzFR432FGZznkVAjiyFtCOANjkAKwCbt465L6ZCiUQh2oMYGU3Wo8LRFJxNDFwWn106S5wVUNA==",
       "dev": true,
       "requires": {
         "regenerator-transform": "^0.14.0"
       }
     },
     "@babel/plugin-transform-reserved-words": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz",
-      "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz",
+      "integrity": "sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-runtime": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.4.tgz",
-      "integrity": "sha512-aMVojEjPszvau3NRg+TIH14ynZLvPewH4xhlCW1w6A3rkxTS1m4uwzRclYR9oS+rl/dr+kT+pzbfHuAWP/lc7Q==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz",
+      "integrity": "sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
         "resolve": "^1.8.1",
         "semver": "^5.5.1"
       }
     },
     "@babel/plugin-transform-shorthand-properties": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz",
-      "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz",
+      "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-spread": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz",
-      "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz",
+      "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-sticky-regex": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz",
-      "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz",
+      "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/helper-regex": "^7.8.3"
       }
     },
     "@babel/plugin-transform-template-literals": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz",
-      "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz",
+      "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-annotate-as-pure": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-annotate-as-pure": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-typeof-symbol": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz",
-      "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.3.tgz",
+      "integrity": "sha512-3TrkKd4LPqm4jHs6nPtSDI/SV9Cm5PRJkHLUgTcqRQQTMAZ44ZaAdDZJtvWFSaRcvT0a1rTmJ5ZA5tDKjleF3g==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0"
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/plugin-transform-unicode-regex": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz",
-      "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz",
+      "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/helper-regex": "^7.4.4",
-        "regexpu-core": "^4.5.4"
+        "@babel/helper-create-regexp-features-plugin": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3"
       }
     },
     "@babel/preset-env": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.5.tgz",
-      "integrity": "sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-module-imports": "^7.0.0",
-        "@babel/helper-plugin-utils": "^7.0.0",
-        "@babel/plugin-proposal-async-generator-functions": "^7.2.0",
-        "@babel/plugin-proposal-json-strings": "^7.2.0",
-        "@babel/plugin-proposal-object-rest-spread": "^7.4.4",
-        "@babel/plugin-proposal-optional-catch-binding": "^7.2.0",
-        "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
-        "@babel/plugin-syntax-async-generators": "^7.2.0",
-        "@babel/plugin-syntax-json-strings": "^7.2.0",
-        "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
-        "@babel/plugin-syntax-optional-catch-binding": "^7.2.0",
-        "@babel/plugin-transform-arrow-functions": "^7.2.0",
-        "@babel/plugin-transform-async-to-generator": "^7.4.4",
-        "@babel/plugin-transform-block-scoped-functions": "^7.2.0",
-        "@babel/plugin-transform-block-scoping": "^7.4.4",
-        "@babel/plugin-transform-classes": "^7.4.4",
-        "@babel/plugin-transform-computed-properties": "^7.2.0",
-        "@babel/plugin-transform-destructuring": "^7.4.4",
-        "@babel/plugin-transform-dotall-regex": "^7.4.4",
-        "@babel/plugin-transform-duplicate-keys": "^7.2.0",
-        "@babel/plugin-transform-exponentiation-operator": "^7.2.0",
-        "@babel/plugin-transform-for-of": "^7.4.4",
-        "@babel/plugin-transform-function-name": "^7.4.4",
-        "@babel/plugin-transform-literals": "^7.2.0",
-        "@babel/plugin-transform-member-expression-literals": "^7.2.0",
-        "@babel/plugin-transform-modules-amd": "^7.2.0",
-        "@babel/plugin-transform-modules-commonjs": "^7.4.4",
-        "@babel/plugin-transform-modules-systemjs": "^7.4.4",
-        "@babel/plugin-transform-modules-umd": "^7.2.0",
-        "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5",
-        "@babel/plugin-transform-new-target": "^7.4.4",
-        "@babel/plugin-transform-object-super": "^7.2.0",
-        "@babel/plugin-transform-parameters": "^7.4.4",
-        "@babel/plugin-transform-property-literals": "^7.2.0",
-        "@babel/plugin-transform-regenerator": "^7.4.5",
-        "@babel/plugin-transform-reserved-words": "^7.2.0",
-        "@babel/plugin-transform-shorthand-properties": "^7.2.0",
-        "@babel/plugin-transform-spread": "^7.2.0",
-        "@babel/plugin-transform-sticky-regex": "^7.2.0",
-        "@babel/plugin-transform-template-literals": "^7.4.4",
-        "@babel/plugin-transform-typeof-symbol": "^7.2.0",
-        "@babel/plugin-transform-unicode-regex": "^7.4.4",
-        "@babel/types": "^7.4.4",
-        "browserslist": "^4.6.0",
-        "core-js-compat": "^3.1.1",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.3.tgz",
+      "integrity": "sha512-Rs4RPL2KjSLSE2mWAx5/iCH+GC1ikKdxPrhnRS6PfFVaiZeom22VFKN4X8ZthyN61kAaR05tfXTbCvatl9WIQg==",
+      "dev": true,
+      "requires": {
+        "@babel/compat-data": "^7.8.0",
+        "@babel/helper-compilation-targets": "^7.8.3",
+        "@babel/helper-module-imports": "^7.8.3",
+        "@babel/helper-plugin-utils": "^7.8.3",
+        "@babel/plugin-proposal-async-generator-functions": "^7.8.3",
+        "@babel/plugin-proposal-dynamic-import": "^7.8.3",
+        "@babel/plugin-proposal-json-strings": "^7.8.3",
+        "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
+        "@babel/plugin-proposal-object-rest-spread": "^7.8.3",
+        "@babel/plugin-proposal-optional-catch-binding": "^7.8.3",
+        "@babel/plugin-proposal-optional-chaining": "^7.8.3",
+        "@babel/plugin-proposal-unicode-property-regex": "^7.8.3",
+        "@babel/plugin-syntax-async-generators": "^7.8.0",
+        "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+        "@babel/plugin-syntax-json-strings": "^7.8.0",
+        "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+        "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+        "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+        "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+        "@babel/plugin-syntax-top-level-await": "^7.8.3",
+        "@babel/plugin-transform-arrow-functions": "^7.8.3",
+        "@babel/plugin-transform-async-to-generator": "^7.8.3",
+        "@babel/plugin-transform-block-scoped-functions": "^7.8.3",
+        "@babel/plugin-transform-block-scoping": "^7.8.3",
+        "@babel/plugin-transform-classes": "^7.8.3",
+        "@babel/plugin-transform-computed-properties": "^7.8.3",
+        "@babel/plugin-transform-destructuring": "^7.8.3",
+        "@babel/plugin-transform-dotall-regex": "^7.8.3",
+        "@babel/plugin-transform-duplicate-keys": "^7.8.3",
+        "@babel/plugin-transform-exponentiation-operator": "^7.8.3",
+        "@babel/plugin-transform-for-of": "^7.8.3",
+        "@babel/plugin-transform-function-name": "^7.8.3",
+        "@babel/plugin-transform-literals": "^7.8.3",
+        "@babel/plugin-transform-member-expression-literals": "^7.8.3",
+        "@babel/plugin-transform-modules-amd": "^7.8.3",
+        "@babel/plugin-transform-modules-commonjs": "^7.8.3",
+        "@babel/plugin-transform-modules-systemjs": "^7.8.3",
+        "@babel/plugin-transform-modules-umd": "^7.8.3",
+        "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
+        "@babel/plugin-transform-new-target": "^7.8.3",
+        "@babel/plugin-transform-object-super": "^7.8.3",
+        "@babel/plugin-transform-parameters": "^7.8.3",
+        "@babel/plugin-transform-property-literals": "^7.8.3",
+        "@babel/plugin-transform-regenerator": "^7.8.3",
+        "@babel/plugin-transform-reserved-words": "^7.8.3",
+        "@babel/plugin-transform-shorthand-properties": "^7.8.3",
+        "@babel/plugin-transform-spread": "^7.8.3",
+        "@babel/plugin-transform-sticky-regex": "^7.8.3",
+        "@babel/plugin-transform-template-literals": "^7.8.3",
+        "@babel/plugin-transform-typeof-symbol": "^7.8.3",
+        "@babel/plugin-transform-unicode-regex": "^7.8.3",
+        "@babel/types": "^7.8.3",
+        "browserslist": "^4.8.2",
+        "core-js-compat": "^3.6.2",
         "invariant": "^2.2.2",
-        "js-levenshtein": "^1.1.3",
+        "levenary": "^1.1.0",
         "semver": "^5.5.0"
       }
     },
     "@babel/runtime": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz",
-      "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz",
+      "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==",
       "dev": true,
       "requires": {
         "regenerator-runtime": "^0.13.2"
       }
     },
     "@babel/template": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
-      "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
+      "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "@babel/parser": "^7.4.4",
-        "@babel/types": "^7.4.4"
+        "@babel/code-frame": "^7.8.3",
+        "@babel/parser": "^7.8.3",
+        "@babel/types": "^7.8.3"
       }
     },
     "@babel/traverse": {
-      "version": "7.4.5",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz",
-      "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz",
+      "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "^7.0.0",
-        "@babel/generator": "^7.4.4",
-        "@babel/helper-function-name": "^7.1.0",
-        "@babel/helper-split-export-declaration": "^7.4.4",
-        "@babel/parser": "^7.4.5",
-        "@babel/types": "^7.4.4",
+        "@babel/code-frame": "^7.8.3",
+        "@babel/generator": "^7.8.3",
+        "@babel/helper-function-name": "^7.8.3",
+        "@babel/helper-split-export-declaration": "^7.8.3",
+        "@babel/parser": "^7.8.3",
+        "@babel/types": "^7.8.3",
         "debug": "^4.1.0",
         "globals": "^11.1.0",
-        "lodash": "^4.17.11"
+        "lodash": "^4.17.13"
       }
     },
     "@babel/types": {
-      "version": "7.4.4",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
-      "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
+      "version": "7.8.3",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
+      "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
       "dev": true,
       "requires": {
         "esutils": "^2.0.2",
-        "lodash": "^4.17.11",
+        "lodash": "^4.17.13",
         "to-fast-properties": "^2.0.0"
       }
     },
@@ -1202,9 +1312,9 @@
       }
     },
     "@webcomponents/webcomponentsjs": {
-      "version": "2.2.10",
-      "resolved": "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.2.10.tgz",
-      "integrity": "sha512-5dzhUhP+h0qMiK0IWb7VNb0OGBoXO3AuI6Qi8t9PoKT50s5L1jv0xnwnLq+cFgPuTB8FLTNP8xIDmyoOsKBy9Q==",
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.4.1.tgz",
+      "integrity": "sha512-7jxBb+KoWncKb/JGFyTY40PjV4yRx2zd35ZLuvRP+6WndJDL7X32ZIZ7bN3sSQIl+NzJkCo7chfXJyzn+6WZaQ==",
       "dev": true
     },
     "@xtuc/ieee754": {
@@ -1556,6 +1666,15 @@
         "pify": "^4.0.1"
       }
     },
+    "babel-plugin-dynamic-import-node": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz",
+      "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==",
+      "dev": true,
+      "requires": {
+        "object.assign": "^4.1.0"
+      }
+    },
     "backo2": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
@@ -1882,14 +2001,14 @@
       }
     },
     "browserslist": {
-      "version": "4.6.1",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.1.tgz",
-      "integrity": "sha512-1MC18ooMPRG2UuVFJTHFIAkk6mpByJfxCrnUyvSlu/hyQSFHMrlhM02SzNuCV+quTP4CKmqtOMAIjrifrpBJXQ==",
+      "version": "4.8.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.3.tgz",
+      "integrity": "sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30000971",
-        "electron-to-chromium": "^1.3.137",
-        "node-releases": "^1.1.21"
+        "caniuse-lite": "^1.0.30001017",
+        "electron-to-chromium": "^1.3.322",
+        "node-releases": "^1.1.44"
       }
     },
     "bs-recipes": {
@@ -2038,9 +2157,9 @@
       "dev": true
     },
     "caniuse-lite": {
-      "version": "1.0.30000971",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000971.tgz",
-      "integrity": "sha512-TQFYFhRS0O5rdsmSbF1Wn+16latXYsQJat66f7S7lizXW1PVpWJeZw9wqqVLIjuxDRz7s7xRUj13QCfd8hKn6g==",
+      "version": "1.0.30001021",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001021.tgz",
+      "integrity": "sha512-wuMhT7/hwkgd8gldgp2jcrUjOU9RXJ4XxGumQeOsUr91l3WwmM68Cpa/ymCnWEDqakwFXhuDQbaKNHXBPgeE9g==",
       "dev": true
     },
     "chalk": {
@@ -2307,9 +2426,9 @@
       "dev": true
     },
     "convert-source-map": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
-      "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+      "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
       "dev": true,
       "requires": {
         "safe-buffer": "~5.1.1"
@@ -2342,30 +2461,23 @@
       "dev": true
     },
     "core-js-compat": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.3.tgz",
-      "integrity": "sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA==",
+      "version": "3.6.4",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz",
+      "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.6.0",
-        "core-js-pure": "3.1.3",
-        "semver": "^6.1.0"
+        "browserslist": "^4.8.3",
+        "semver": "7.0.0"
       },
       "dependencies": {
         "semver": {
-          "version": "6.1.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz",
-          "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==",
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+          "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
           "dev": true
         }
       }
     },
-    "core-js-pure": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.3.tgz",
-      "integrity": "sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==",
-      "dev": true
-    },
     "core-util-is": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -2481,9 +2593,9 @@
       "dev": true
     },
     "d3": {
-      "version": "5.9.2",
-      "resolved": "https://registry.npmjs.org/d3/-/d3-5.9.2.tgz",
-      "integrity": "sha512-ydrPot6Lm3nTWH+gJ/Cxf3FcwuvesYQ5uk+j/kXEH/xbuYWYWTMAHTJQkyeuG8Y5WM5RSEYB41EctUrXQQytRQ==",
+      "version": "5.15.0",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-5.15.0.tgz",
+      "integrity": "sha512-C+E80SL2nLLtmykZ6klwYj5rPqB5nlfN5LdWEAVdWPppqTD8taoJi2PxLZjPeYT8FFRR2yucXq+kBlOnnvZeLg==",
       "requires": {
         "d3-array": "1",
         "d3-axis": "1",
@@ -2529,9 +2641,9 @@
       "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ=="
     },
     "d3-brush": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz",
-      "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==",
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.1.5.tgz",
+      "integrity": "sha512-rEaJ5gHlgLxXugWjIkolTA0OyMvw8UWU1imYXy1v642XyyswmI1ybKOv05Ft+ewq+TFmdliD3VuK0pRp1VT/5A==",
       "requires": {
         "d3-dispatch": "1",
         "d3-drag": "1",
@@ -2555,9 +2667,9 @@
       "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A=="
     },
     "d3-color": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz",
-      "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw=="
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz",
+      "integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg=="
     },
     "d3-contour": {
       "version": "1.3.2",
@@ -2573,9 +2685,9 @@
       "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g=="
     },
     "d3-drag": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz",
-      "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==",
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
+      "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
       "requires": {
         "d3-dispatch": "1",
         "d3-selection": "1"
@@ -2592,9 +2704,9 @@
       }
     },
     "d3-ease": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz",
-      "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ=="
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.6.tgz",
+      "integrity": "sha512-SZ/lVU7LRXafqp7XtIcBdxnWl8yyLpgOmzAk0mWBI9gXNzLDx5ybZgnRbH9dN/yY5tzVBqCQ9avltSnqVwessQ=="
     },
     "d3-fetch": {
       "version": "1.1.2",
@@ -2616,45 +2728,45 @@
       }
     },
     "d3-format": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz",
-      "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ=="
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.3.tgz",
+      "integrity": "sha512-mm/nE2Y9HgGyjP+rKIekeITVgBtX97o1nrvHCWX8F/yBYyevUTvu9vb5pUnKwrcSw7o7GuwMOWjS9gFDs4O+uQ=="
     },
     "d3-geo": {
-      "version": "1.11.3",
-      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.3.tgz",
-      "integrity": "sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==",
+      "version": "1.11.9",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.9.tgz",
+      "integrity": "sha512-9edcH6J3s/Aa3KJITWqFJbyB/8q3mMlA9Fi7z6yy+FAYMnRaxmC7jBhUnsINxVWD14GmqX3DK8uk7nV6/Ekt4A==",
       "requires": {
         "d3-array": "1"
       }
     },
     "d3-hierarchy": {
-      "version": "1.1.8",
-      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz",
-      "integrity": "sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w=="
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz",
+      "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ=="
     },
     "d3-interpolate": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz",
-      "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
+      "integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
       "requires": {
         "d3-color": "1"
       }
     },
     "d3-path": {
-      "version": "1.0.7",
-      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz",
-      "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA=="
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
     },
     "d3-polygon": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.5.tgz",
-      "integrity": "sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w=="
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.6.tgz",
+      "integrity": "sha512-k+RF7WvI08PC8reEoXa/w2nSg5AUMTi+peBD9cmFc+0ixHfbs4QmxxkarVal1IkVkgxVuk9JSHhJURHiyHKAuQ=="
     },
     "d3-quadtree": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.6.tgz",
-      "integrity": "sha512-NUgeo9G+ENQCQ1LsRr2qJg3MQ4DJvxcDNCiohdJGHt5gRhBW6orIB5m5FJ9kK3HNL8g9F4ERVoBzcEwQBfXWVA=="
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.7.tgz",
+      "integrity": "sha512-RKPAeXnkC59IDGD0Wu5mANy0Q2V28L+fNe65pOCXVdVuTJS3WPKaJlFHer32Rbh9gIo9qMuJXio8ra4+YmIymA=="
     },
     "d3-queue": {
       "version": "3.0.7",
@@ -2691,9 +2803,9 @@
       }
     },
     "d3-scale-chromatic": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz",
-      "integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==",
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.5.0.tgz",
+      "integrity": "sha512-ACcL46DYImpRFMBcpk9HhtIyC7bTBR4fNOPxwVSl0LfulDAwyiHyPOTqcDG1+t5d4P9W7t/2NAuWu59aKko/cg==",
       "requires": {
         "d3-color": "1",
         "d3-interpolate": "1"
@@ -2705,30 +2817,30 @@
       "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg=="
     },
     "d3-shape": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.5.tgz",
-      "integrity": "sha512-VKazVR3phgD+MUCldapHD7P9kcrvPcexeX/PkMJmkUov4JM8IxsSg1DvbYoYich9AtdTsa5nNk2++ImPiDiSxg==",
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+      "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
       "requires": {
         "d3-path": "1"
       }
     },
     "d3-time": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.11.tgz",
-      "integrity": "sha512-Z3wpvhPLW4vEScGeIMUckDW7+3hWKOQfAWg/U7PlWBnQmeKQ00gCUsTtWSYulrKNA7ta8hJ+xXc6MHrMuITwEw=="
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
+      "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
     },
     "d3-time-format": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz",
-      "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==",
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
+      "integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
       "requires": {
         "d3-time": "1"
       }
     },
     "d3-timer": {
-      "version": "1.0.9",
-      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz",
-      "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg=="
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
+      "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
     },
     "d3-tip": {
       "version": "0.9.1",
@@ -2740,9 +2852,9 @@
       }
     },
     "d3-transition": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.2.0.tgz",
-      "integrity": "sha512-VJ7cmX/FPIPJYuaL2r1o1EMHLttvoIuZhhuAlRoOxDzogV8iQS6jYulDm3xEU3TqL80IZIhI551/ebmCMrkvhw==",
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.3.2.tgz",
+      "integrity": "sha512-sc0gRU4PFqZ47lPVHloMn9tlPcv8jxgOQg+0zjhfZXMQuvppjG6YuwdMBE0TuqCZjeJkLecku/l9R0JPcRhaDA==",
       "requires": {
         "d3-color": "1",
         "d3-dispatch": "1",
@@ -2758,9 +2870,9 @@
       "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg=="
     },
     "d3-zoom": {
-      "version": "1.7.3",
-      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.3.tgz",
-      "integrity": "sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==",
+      "version": "1.8.3",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.8.3.tgz",
+      "integrity": "sha512-VoLXTK4wvy1a0JpH2Il+F2CiOhVu7VRXWF5M/LroMIh3/zBAC3WAt7QoIvPibOavVo20hN6/37vwAsdBejLyKQ==",
       "requires": {
         "d3-dispatch": "1",
         "d3-drag": "1",
@@ -3204,9 +3316,9 @@
       "dev": true
     },
     "electron-to-chromium": {
-      "version": "1.3.143",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.143.tgz",
-      "integrity": "sha512-J9jOpxIljQZlV6GIP2fwAWq0T69syawU0sH3EW3O2Bgxquiy+veeIT5mBDRz+i3oHUSL1tvVgRKH3/4QiQh9Pg==",
+      "version": "1.3.334",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.334.tgz",
+      "integrity": "sha512-RcjJhpsVaX0X6ntu/WSBlW9HE9pnCgXS9B8mTUObl1aDxaiOa0Lu+NMveIS5IDC+VELzhM32rFJDCC+AApVwcA==",
       "dev": true
     },
     "elliptic": {
@@ -4618,6 +4730,12 @@
       "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
       "dev": true
     },
+    "gensync": {
+      "version": "1.0.0-beta.1",
+      "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
+      "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
+      "dev": true
+    },
     "get-caller-file": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
@@ -5310,12 +5428,6 @@
       "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
       "dev": true
     },
-    "js-levenshtein": {
-      "version": "1.1.6",
-      "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
-      "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
-      "dev": true
-    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -5357,9 +5469,9 @@
       "dev": true
     },
     "json5": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz",
-      "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==",
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz",
+      "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==",
       "dev": true,
       "requires": {
         "minimist": "^1.2.0"
@@ -5395,6 +5507,21 @@
         "invert-kv": "^1.0.0"
       }
     },
+    "leven": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+      "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+      "dev": true
+    },
+    "levenary": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.0.tgz",
+      "integrity": "sha512-VHcwhO0UTpUW7rLPN2/OiWJdgA1e9BqEDALhrgCe/F+uUJnep6CoUsTzMeP8Rh0NGr9uKquXxqe7lwLZo509nQ==",
+      "dev": true,
+      "requires": {
+        "leven": "^3.1.0"
+      }
+    },
     "levn": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -5412,17 +5539,17 @@
       "dev": true
     },
     "lit-element": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.1.0.tgz",
-      "integrity": "sha512-0z/KHm1xZweivfOVRr8AKR06+D3k02u15m9s4jkuRdnGe5wfmEwePzrQQBsSZNILdnfJvfo3TJOeGhBCVZaPbw==",
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-2.2.1.tgz",
+      "integrity": "sha512-ipDcgQ1EpW6Va2Z6dWm79jYdimVepO5GL0eYkZrFvdr0OD/1N260Q9DH+K5HXHFrRoC7dOg+ZpED2XE0TgGdXw==",
       "requires": {
         "lit-html": "^1.0.0"
       }
     },
     "lit-html": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.1.0.tgz",
-      "integrity": "sha512-ZDJHpJi09yknMpjwPI8fuSl5sUG7+pF+eE5WciFtgyX7zebvgMDBgSLq4knXa7grxM00RkQ7PBd7UZQiruA78Q=="
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.1.2.tgz",
+      "integrity": "sha512-FFlUMKHKi+qG1x1iHNZ1hrtc/zHmfYTyrSvs3/wBTvaNtpZjOZGWzU7efGYVpgp6KvWeKF6ql9/KsCq6Z/mEDA=="
     },
     "live-server": {
       "version": "1.2.1",
@@ -6034,12 +6161,20 @@
       }
     },
     "node-releases": {
-      "version": "1.1.22",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.22.tgz",
-      "integrity": "sha512-O6XpteBuntW1j86mw6LlovBIwTe+sO2+7vi9avQffNeIW4upgnaCVm6xrBWH+KATz7mNNRNNeEpuWB7dT6Cr3w==",
+      "version": "1.1.45",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.45.tgz",
+      "integrity": "sha512-cXvGSfhITKI8qsV116u2FTzH5EWZJfgG7d4cpqwF8I8+1tWpD6AsvvGRKq2onR0DNj1jfqsjkXZsm14JMS7Cyg==",
       "dev": true,
       "requires": {
-        "semver": "^5.3.0"
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
       }
     },
     "normalize-package-data": {
@@ -6225,6 +6360,18 @@
         "isobject": "^3.0.0"
       }
     },
+    "object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.0",
+        "object-keys": "^1.0.11"
+      }
+    },
     "object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -6915,15 +7062,15 @@
       }
     },
     "regenerator-runtime": {
-      "version": "0.13.2",
-      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
-      "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==",
+      "version": "0.13.3",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz",
+      "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==",
       "dev": true
     },
     "regenerator-transform": {
-      "version": "0.14.0",
-      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz",
-      "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==",
+      "version": "0.14.1",
+      "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.1.tgz",
+      "integrity": "sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ==",
       "dev": true,
       "requires": {
         "private": "^0.1.6"
@@ -6939,12 +7086,6 @@
         "safe-regex": "^1.1.0"
       }
     },
-    "regexp-tree": {
-      "version": "0.1.10",
-      "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz",
-      "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==",
-      "dev": true
-    },
     "regexpp": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
@@ -6952,13 +7093,13 @@
       "dev": true
     },
     "regexpu-core": {
-      "version": "4.5.4",
-      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz",
-      "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==",
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.6.0.tgz",
+      "integrity": "sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg==",
       "dev": true,
       "requires": {
         "regenerate": "^1.4.0",
-        "regenerate-unicode-properties": "^8.0.2",
+        "regenerate-unicode-properties": "^8.1.0",
         "regjsgen": "^0.5.0",
         "regjsparser": "^0.6.0",
         "unicode-match-property-ecmascript": "^1.0.4",
@@ -6966,15 +7107,15 @@
       }
     },
     "regjsgen": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz",
-      "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==",
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz",
+      "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==",
       "dev": true
     },
     "regjsparser": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz",
-      "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==",
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.2.tgz",
+      "integrity": "sha512-E9ghzUtoLwDekPT0DYCp+c4h+bvuUpe6rRHCTYn6eGoqj1LgKXxT6I0Il4WbjhQkOghzi/V+y03bPKvbllL93Q==",
       "dev": true,
       "requires": {
         "jsesc": "~0.5.0"
@@ -8334,12 +8475,6 @@
       "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
       "dev": true
     },
-    "trim-right": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
-      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
-      "dev": true
-    },
     "ts-node": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz",
@@ -8384,9 +8519,9 @@
       "dev": true
     },
     "typescript": {
-      "version": "3.5.1",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.1.tgz",
-      "integrity": "sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw=="
+      "version": "3.7.4",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz",
+      "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw=="
     },
     "ua-parser-js": {
       "version": "0.7.17",
diff --git a/package.json b/package.json
index eedd371..e207526 100644
--- a/package.json
+++ b/package.json
@@ -1,23 +1,23 @@
 {
-  "name": "interactions",
+  "name": "pdbe-ligand-display",
   "version": "1.0.0",
   "description": "",
   "main": "app.js",
   "dependencies": {
     "@types/d3": "^5.0.1",
     "@types/d3-tip": "^3.5.5",
-    "d3": "^5.7.0",
+    "d3": "^5.15.0",
     "d3-tip": "^0.9.1",
     "d3scription": "^1.0.1",
-    "lit-element": "^2.1.0",
-    "typescript": "^3.1.6"
+    "lit-element": "^2.2.1",
+    "typescript": "^3.7.4"
   },
   "devDependencies": {
-    "@babel/core": "^7.3.3",
-    "@babel/plugin-transform-runtime": "^7.2.0",
-    "@babel/preset-env": "^7.3.1",
-    "@babel/runtime": "^7.3.1",
-    "@webcomponents/webcomponentsjs": "^2.1.3",
+    "@babel/core": "^7.8.3",
+    "@babel/plugin-transform-runtime": "^7.8.3",
+    "@babel/preset-env": "^7.8.3",
+    "@babel/runtime": "^7.8.3",
+    "@webcomponents/webcomponentsjs": "^2.4.1",
     "babel-loader": "^8.0.5",
     "browser-sync": "^2.26.7",
     "camelcase": "^5.0.0",
-- 
GitLab


From 73b480adc5e78b914251bd94b53108dc9630bcd6 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 15 Jan 2020 14:31:02 +0000
Subject: [PATCH 07/66] update tsconfig.json

---
 tsconfig.json | 16 +++++-----------
 1 file changed, 5 insertions(+), 11 deletions(-)

diff --git a/tsconfig.json b/tsconfig.json
index 60d88a7..ac2e77e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -5,23 +5,17 @@
         "noUnusedLocals": true,
         "noUnusedParameters": true,
         "target": "es2016",
-        "lib": [ "es5", "es6", "es7", "es2015.collection", "dom", "es2015.promise"],
+        "lib": ["es5", "es6", "es7", "es2015.collection", "dom", "es2015.promise"],
         "sourceMap": false,
         "declaration": true,
         "module": "none",
-        "moduleResolution": "node",        
+        "moduleResolution": "node",
         "out": "build/app.js"
-    },    
-    "files": [
-        "src/model.ts",     
-        "src/ui.ts",   
-        "src/manager.ts",
-        "src/visualsMapping.ts",
-        "src/depiction.ts",               
-    ],
+    },
+    "include": ["src/**/*", ],
     "exclude": [
         "node_modules",
         "build",
-        "dist"      
+        "dist"
     ]
 }
\ No newline at end of file
-- 
GitLab


From 11093487f65a372dec93193b48cffc6e02be3503 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 21 Jan 2020 11:29:59 +0000
Subject: [PATCH 08/66] basic refactor done

---
 build/pdbe-interactions-styles.css |   4 +-
 src/component.js                   |   4 +-
 src/config.ts                      |  75 +++++++++++
 src/depiction.ts                   |  69 ++++++++--
 src/manager.ts                     | 201 +++++++++++++----------------
 src/model.ts                       |  53 +-------
 src/ui.ts                          |  90 ++++++++-----
 src/visualsMapping.ts              |   4 +-
 8 files changed, 295 insertions(+), 205 deletions(-)
 create mode 100644 src/config.ts

diff --git a/build/pdbe-interactions-styles.css b/build/pdbe-interactions-styles.css
index f50dfa6..39674f4 100644
--- a/build/pdbe-interactions-styles.css
+++ b/build/pdbe-interactions-styles.css
@@ -1,8 +1,8 @@
-#int-canvas {
+#pdbe-ligand-display-root {
     cursor: default;
     border-radius: 3px;
     width: 100%;
-    height: 98.5vh;
+    height: 100%;
 }
 
 .int-label {
diff --git a/src/component.js b/src/component.js
index fa5b743..5e4cac0 100644
--- a/src/component.js
+++ b/src/component.js
@@ -33,10 +33,10 @@ class pdbInteractions extends LitElement {
       this.display = new Visualization(this);
 
       if (this['bound-molecule-id']) {
-        this.display.initialiseBoundMolecule(this['pdb-id'], this['bound-molecule-id']);
+        this.display.initBMInteractions(this['pdb-id'], this['bound-molecule-id']);
       }
       else {
-        this.display.initialiseLigand(this['pdb-id'], this['pdb-res-id'], this['pdb-chain-id'])
+        this.display.initLigandInteractions(this['pdb-id'], this['pdb-res-id'], this['pdb-chain-id'])
       }
     }
   }
diff --git a/src/config.ts b/src/config.ts
new file mode 100644
index 0000000..8738521
--- /dev/null
+++ b/src/config.ts
@@ -0,0 +1,75 @@
+namespace Config {
+    export const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
+    export const glycanSymbols: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/visuals.xml";
+    export const glycanMapping: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
+
+
+    export const interactionClickEvent = 'PDB.interactions.click';
+    export const interactionMouseoverEvent = 'PDB.interactions.mouseover';
+    export const interactionMouseoutEvent = 'PDB.interactions.mouseout'
+
+    export const interactionShowLabelEvent = 'PDB.interactions.showLabel';
+    export const interactionHideLabelEvent = 'PDB.interactions.hideLabel';
+
+    export const molstarClickEvent = 'PDB.molstar.click';
+    export const molstarMouseoverEvent = 'PDB.molstar.mouseover';
+    export const molstarMouseoutEvent = 'PDB.molstar.mouseout';
+
+    export const aminoAcids = new Map<string, Array<string>>([
+        ['cystein', new Array<string>('CYS', 'SEC', 'CSO')],
+        ['positive', new Array<string>('LYS', 'ARG')],
+        ['negative', new Array<string>('ASP', 'GLU')],
+        ['polar', new Array<string>('SER', 'SEP', 'THR', 'ASN', 'GLN', 'TPO')],
+        ['aliphatic', new Array<string>('ALA', 'VAL', 'ILE', 'LEU', 'MET', 'PRO', 'MSE')],
+        ['aromatic', new Array<string>('TRP', 'TYR', 'PHE', 'HIS')]
+    ]);
+
+    export const backboneAtoms = ['N', 'CA', 'C', 'O'];
+
+    export const interactionsClasses = new Map<string, Array<string>>([
+        ["covalent", new Array<string>("covalent")],
+        ["electrostatic", new Array<string>("ionic", "hbond", "weak_hbond", "polar", "weak_polar", "xbond", "carbonyl")],
+        ['amide', new Array<string>("AMIDEAMIDE", "AMIDERING")],
+        ["vdw", new Array<string>("vdw")],
+        ["hydrophobic", new Array<string>("hydrophobic")],
+        ["aromatic", new Array<string>("aromatic", "FF", "OF", "EE", "FT", "OT", "ET", "FE", "OE", "EF", "CARBONPI", "CATIONPI", "DONORPI", "HALOGENPI", "METSULPHURPI")],
+        ["metal", new Array<string>("metal_complex")],
+        ["clashes", new Array<string>("clash", "vdw_clash")]
+    ]);
+
+    export class UIParameters {
+        reinitialize: boolean;
+        zoom: boolean;
+        fullScreen: boolean;
+        downloadImage: boolean;
+        downloadData: boolean;
+        center: boolean;
+        help: boolean;
+        residueLabel: boolean;
+        tooltip: boolean;
+
+        constructor() {
+            this.reinitialize = true;
+            this.zoom = true;
+            this.fullScreen = true;
+            this.downloadImage = true;
+            this.downloadData = true;
+            this.center = true;
+            this.help = true;
+            this.residueLabel = true;
+            this.tooltip = true;
+
+        }
+    }
+    //TODO
+    export class InitParameters {
+        ligandParams: InitLigandParameters;
+
+    }
+
+    export class InitLigandParameters {
+        chemCompId: string;
+        highlight: string[];
+
+    }
+}
\ No newline at end of file
diff --git a/src/depiction.ts b/src/depiction.ts
index 8505247..8531dcb 100644
--- a/src/depiction.ts
+++ b/src/depiction.ts
@@ -17,9 +17,21 @@ class Depiction {
     ccdId: string;
     atoms: Atom[];
     bonds: Bond[];
+
     resolution: Vector2D;
 
-    constructor(data: any) {
+    private root: d3.Selection<SVGGElement, unknown, null, undefined>;
+    private structure: d3.Selection<SVGGElement, unknown, null, undefined>;
+    private contour: d3.Selection<SVGGElement, unknown, null, undefined>;
+    private highlight: d3.Selection<SVGGElement, unknown, null, undefined>;
+
+    constructor(parent: any, data: any) {
+        this.root = parent
+
+        this.highlight = this.root.append('g').attr('id', 'highlight');
+        this.structure = this.root.append('g').attr('id', 'structure');
+        this.contour = this.root.append('g').attr('id', 'contour');
+
         this.ccdId = data.ccd_id;
         this.resolution = new Vector2D(data.resolution.x, data.resolution.y);
 
@@ -33,6 +45,8 @@ class Depiction {
 
             this.bonds.push(bond);
         });
+
+        console.log(this.contour);
     }
 
 
@@ -76,16 +90,50 @@ class Depiction {
         return new Vector2D(x, y);
     }
 
+    public draw() {
+        this.structure.selectAll("*").remove();
+        this.appendClarityNodes();
+        this.appendBondVisuals();
+        this.appendTexts();
+    }
+
+    public highlightSubgraph(atoms: Array<string>, color: string = undefined) {
+        if (!this.atoms || !atoms) return;        
+
+        this.highlight.selectAll('*').remove();
+
+        color = color ? color : "#BFBFBF";
+        let atomsToHighlight = this.atoms.filter(x => atoms.includes(x.name));
+        
+        this.highlight.selectAll()
+            .data(atomsToHighlight)
+            .enter()
+            .append('circle')
+            .attr('r', '16.12')
+            .attr('cx', x => x.position.x)
+            .attr('cy', x => x.position.y)
+            .attr('style', `fill:${color};fill-rule:evenodd;stroke:${color};stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1`);
+
+        let bondsToHighlight = this.bonds.filter(x => atoms.includes(x.bgn.name) && atoms.includes(x.end.name))
+
+        this.highlight.selectAll()
+            .data(bondsToHighlight)
+            .enter()
+            .append('path')
+            .attr('d', x => `M ${x.bgn.position.x},${x.bgn.position.y} ${x.end.position.x},${x.end.position.y}`)
+            .attr('style', `fill:none;fill-rule:evenodd;stroke:${color};stroke-width:22px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1`)
+    }
+
 
     /**
      * Appends to a given selection the visual representation of bonds as svg:path elements.
      *
-     * @param {d3.Selection<d3.BaseType, {}, HTMLElement, any>} selection where to append SVG
      * representation of the bond visuals.
      * @memberof Depiction
      */
-    public appendBondVisualsTo(root: d3.Selection<d3.BaseType, {}, HTMLElement, any>): void {
-        root.selectAll()
+    private appendBondVisuals(): void {
+
+        this.structure.selectAll()
             .data(this.bonds)
             .enter()
             .append('path')
@@ -100,12 +148,10 @@ class Depiction {
      * Also there are all sorts of colorful subscripts and superscripts, 
      * so it is much easier to use it this way.
      *
-     * @param {d3.Selection<d3.BaseType, {}, HTMLElement, any>} root where to append SVG
-     * representation of compounds' labels. 
      * @memberof Depiction
      */
-    public appendTextsTo(root: any): void {
-        root.selectAll()
+    private appendTexts(): void {
+        this.structure.selectAll()
             .data(this.atoms.filter(x => Object.keys(x.label).length !== 0).map(x => x.label))
             .enter()
             .append('text')
@@ -126,18 +172,17 @@ class Depiction {
      * Add small white circle on the background of atoms with label
      * just to make the interaction lines pretty.
      *
-     * @param {*} root
      * @memberof Depiction
      */
-    public appendClarityNodes(root: any): void {
-        root.selectAll()
+    private appendClarityNodes(): void {
+
+        this.structure.selectAll()
             .data(this.atoms.filter(x => Object.keys(x.label).length != 0))
             .enter().append('circle')
             .attr('class', 'svg-shadow-node')
             .attr('cx', (x: any) => x.position.x)
             .attr('cy', (x: any) => x.position.y)
             .attr('r', 15);
-
     }
 
 
diff --git a/src/manager.ts b/src/manager.ts
index 94f938b..7b30924 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -1,27 +1,20 @@
-/// <reference path="./visualsMapping.ts" />
-/// <reference path="./depiction.ts" />
-
-const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
-
-const clickEvent = 'PDB.interactions.click';
-const mouseoverEvent = 'PDB.interactions.mouseover';
-const mouseoutEvent = 'PDB.interactions.mouseout'
-
-const showLabelEvent = 'PDB.interactions.showLabel'
-const hideLabelEvent = 'PDB.interactions.hideLabel'
 
 class Visualization {
     // component related
     private parent: HTMLElement;
 
     // #region svg properties
-    private canvas: d3.Selection<d3.BaseType, {}, HTMLElement, any>;
     private simulation: d3.Simulation<d3.SimulationNodeDatum, undefined>;
     private svg: d3.Selection<any, {}, HTMLElement, any>;
-    private visualization: d3.Selection<d3.BaseType, {}, HTMLElement, any>;
+    private canvas: d3.Selection<SVGGElement, {}, HTMLElement, any>;
+    private depictionRoot: d3.Selection<SVGGElement, {}, HTMLElement, any>;
+    private nodesRoot: d3.Selection<SVGGElement, {}, HTMLElement, any>;
+    private linksRoot: d3.Selection<SVGGElement, {}, HTMLElement, any>;
+
+    private zoomHandler: d3.ZoomBehavior<Element, unknown>
 
     private nodes: any;
-    private links: any
+    private links: any;
     // #endregion
 
     // #region data properties    
@@ -32,38 +25,44 @@ class Visualization {
     private visualsMapper: VisualsMapper;
     private interactionsData: any;
     private selectedResidueHash: string;
-
-    private originalWidth: number;
-    private originalHeight: number;
     // #endregion
 
-    constructor(element: HTMLElement) {
+    constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
         this.parent = element;
         this.visualsMapper = new VisualsMapper();
 
-        new UI(this.parent, this).register(new Model.UIParameters());
+        if (uiParameters === undefined) uiParameters = new Config.UIParameters();
 
-        this.canvas = d3.select(this.parent)
-            .append('div')
-            .attr('id', 'int-canvas');
+        new UI(this.parent, this).register(uiParameters);
 
-        this.svg = this.canvas
+        this.svg = d3.select(this.parent)
+            .append('div')
+            .attr('id', 'pdbe-ligand-display-root')
             .append('svg')
             .style('background-color', 'white')
             .attr('xmlns', 'http://www.w3.org/2000/svg')
             .attr('width', '100%')
-            .attr('height', '100%')
-
-        this.visualization = this.svg.append('g').attr('id', 'vis-root');
-
-        this.originalWidth = this.parent.offsetWidth;
-        this.originalHeight = this.parent.offsetHeight;
+            .attr('height', '100%');
+
+        this.canvas = this.svg.append('g').attr('id', 'vis-root');
+        
+        this.linksRoot = this.canvas.append('g').attr('id', 'links');
+        this.depictionRoot = this.canvas.append('g').attr('id', 'depiction');
+        this.nodesRoot = this.canvas.append('g').attr('id', 'nodes');
+
+        if (uiParameters.zoom) {
+            this.zoomHandler = d3.zoom()
+                .scaleExtent([1 / 10, 10])
+                .on('zoom', () => this.canvas
+                    .attr('transform', d3.event.transform));
+        }
 
-        document.addEventListener('PDB.molstar.click', e => this.nodeMouseEnterEventHandler(e));
-        document.addEventListener('PDB.molstar.mouseover', e => this.nodeMouseEnterEventHandler(e));
-        document.addEventListener('PDB.molstar.mouseout', () => this.nodeMouseLeaveEventHandler());
+        document.addEventListener(Config.molstarClickEvent, e => this.nodeMouseEnterEventHandler(e));
+        document.addEventListener(Config.molstarMouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
+        document.addEventListener(Config.molstarMouseoutEvent, () => this.nodeMouseLeaveEventHandler());
 
-        d3.select(window).on('resize', () => this.resize());
+        d3.select(this.parent).on('resize', () => this.resize());
+        this.addMarkers();
     }
 
     // #region even handlers
@@ -93,24 +92,18 @@ class Visualization {
     }
 
     private linkMouseClickEventHandler(x: Model.Link) {
-        this.fireExternalLinkEvent(x, clickEvent);
+        this.fireExternalLinkEvent(x, Config.interactionClickEvent);
     }
 
     private linkMouseOverEventHandler(x: Model.Link) {
-        this.fireExternalLinkEvent(x, mouseoverEvent);
+        this.fireExternalLinkEvent(x, Config.interactionMouseoverEvent);
     }
 
     private linkMouseOutEventHandler() {
         this.fireExternalLinkLeaveEvent();
     }
 
-    private zoom_handler = d3.zoom()
-        .scaleExtent([1 / 10, 10])
-        .on('zoom', () => d3.select(this.parent)
-            .select('#vis-root')
-            .attr('transform', d3.event.transform));
-
-    private drag_handler = d3.drag()
+    private dragHandler = d3.drag()
         .on('start', (x: Model.InteractionNode) => {
             if (!d3.event.active) this.simulation.alphaTarget(0.3).restart();
 
@@ -129,11 +122,10 @@ class Visualization {
 
     // #endregion event handlers
 
-    public async initialiseBoundMolecule(pdbid: string, bmId: string) {
+    public initBMInteractions(pdbid: string, bmId: string) {
         this.pdbId = pdbid;
-        this.addMarkers();
 
-        d3.json(`${server}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
+        d3.json(`${Config.server}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
             .catch(e => { throw e; })
             .then((data: any) => {
                 let key = Object.keys(data)[0];
@@ -143,36 +135,45 @@ class Visualization {
                 this.bindingSite.bmId = bmId;
                 let ligands = this.bindingSite.residues.filter(x => x.isLigand);
 
-                if (ligands.length === 1) this.initialiseLigand(this.pdbId, ligands[0].authorResidueNumber, ligands[0].chainId);
+                if (ligands.length === 1) this.initLigandInteractions(this.pdbId, ligands[0].authorResidueNumber, ligands[0].chainId);
                 else this.setupScene();
             });
     }
 
-    public async initialiseLigand(pdbId: string, resId: number, chainId: string) {
+    public async initLigand(ligandId: string) {
+        return d3.json(`https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/${ligandId}/annotation`)
+            .catch(e => { throw e; })
+            .then((d: any) => {
+                this.depiction = new Depiction(this.depictionRoot, d);
+            });
+    }
+
+    public initLigandInteractions(pdbId: string, resId: number, chainId: string) {
         this.pdbId = pdbId;
 
-        d3.json(`${server}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
+        d3.json(`${Config.server}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
             .catch(e => { throw e; })
             .then((data: any) => {
                 let key = Object.keys(data)[0];
                 let body = data[key][0];
                 this.interactionsData = data;
 
-                d3.json(`https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/${body.ligand.chem_comp_id}/annotation`)
-                    .catch(e => { throw e; })
-                    .then((d: any) => {
-                        this.depiction = new Depiction(d);
+                if (this.depiction === undefined || this.depiction.ccdId !== body.ligand.chem_comp_id) {
+                    this.initLigand(body.ligand.chem_comp_id).then(() => {
                         this.bindingSite = new Model.BindingSite().fromLigand(key, body, this.depiction);
                         this.setupLigandScene();
                     });
+                } else {
+                    this.bindingSite = new Model.BindingSite().fromLigand(key, body, this.depiction);
+                    this.setupLigandScene();
+                }
             });
     }
 
     // #region menu functions
     public saveSvg() {
         d3.text('pdbe-interactions-svgstyles.css').then(x => {
-            let svgToDl = d3.select('#int-canvas');
-            svgToDl.select('svg')
+            let svgToDl = this.svg
                 .append('style')
                 .text(`/* <![CDATA[ */ \n ${x} \n /* ]]> */`);
 
@@ -191,7 +192,7 @@ class Visualization {
     }
 
 
-    public downloadInteractionsData(this: Visualization): void {
+    public downloadInteractionsData(): void {
         let downloadLink = document.createElement('a');
 
         let dataBlob = new Blob([JSON.stringify(this.interactionsData, null, 4)], { type: 'application/json' });
@@ -205,8 +206,6 @@ class Visualization {
 
 
     public reinitialize() {
-        this.visualization.remove();
-
         if (this.depiction === undefined) this.setupScene();
         else this.setupLigandScene();
 
@@ -224,7 +223,7 @@ class Visualization {
                 .restart();
         } else this.simulation.restart();
 
-        this.zoom_handler(this.svg);
+        if (this.zoomHandler !== undefined) this.zoomHandler(this.svg);
     }
 
 
@@ -260,33 +259,17 @@ class Visualization {
         let yTrans = -(minY) * minRatio + (this.parent.offsetHeight - newMolHeight) / 2;
 
         // do the actual moving
-        this.visualization.attr('transform', `translate(${xTrans}, ${yTrans}) scale(${minRatio})`);
+        this.canvas.attr('transform', `translate(${xTrans}, ${yTrans}) scale(${minRatio})`);
 
         // tell the zoomer what we did so that next we zoom, it uses the
         // transformation we entered here        
-        this.zoom_handler.transform(this.svg, d3.zoomIdentity);
-
+        if (this.zoomHandler !== undefined) {
+            let translation = d3.zoomIdentity.translate(xTrans, yTrans).scale(minRatio)
+            this.zoomHandler.transform(this.svg, translation);
+        }
 
 
     };
-
-    public fullScreen() {
-        this.parent.parentElement.style.width = '100%'
-        this.parent.parentElement.style.height = '100%'
-        this.parent.parentElement.style.position = 'fixed';
-        this.parent.parentElement.style.zIndex = '10000000000000';
-
-        this.centerScene();
-    }
-
-    public minimizeScreen() {
-        this.parent.parentElement.style.width = `${this.originalWidth}px`;
-        this.parent.parentElement.style.height = `${this.originalHeight}px`;
-        this.parent.parentElement.style.position = 'relative';
-        this.parent.parentElement.style.zIndex = '';
-
-        this.centerScene();
-    }
     // #endregion menu functions
 
     // #region fire events
@@ -294,13 +277,13 @@ class Visualization {
     //https://stackoverflow.com/questions/40722344/understanding-d3-with-an-example-mouseover-mouseup-with-multiple-arguments
     private fireExternalNodeMouseEnterEvent(x: Model.InteractionNode, i: number, g: any) {
         this.nodeHighlight(x, i, g);
-        this.fireExternalNodeEvent(x, mouseoverEvent);
+        this.fireExternalNodeEvent(x, Config.interactionMouseoverEvent);
     }
 
     private fireExternalNodeMouseLeaveEvent(x: Model.InteractionNode, i: number, g: any) {
         this.nodeDim(x, i, g);
 
-        const e = new CustomEvent(mouseoutEvent, {
+        const e = new CustomEvent(Config.interactionMouseoutEvent, {
             bubbles: true,
             detail: {}
         });
@@ -363,7 +346,7 @@ class Visualization {
     }
 
     private fireExternalLinkLeaveEvent() {
-        const e = new CustomEvent(mouseoutEvent, {
+        const e = new CustomEvent(Config.interactionMouseoutEvent, {
             bubbles: true,
             detail: {}
         });
@@ -375,30 +358,29 @@ class Visualization {
 
 
     private selectLigand(n: Model.InteractionNode, i: number, g: any) {
-        this.fireExternalNodeEvent(n, clickEvent);
+        this.fireExternalNodeEvent(n, Config.interactionClickEvent);
 
         if (!n.residue.isLigand) return;
 
-        this.visualization.remove();
         this.fireExternalNodeMouseLeaveEvent(n, i, g);
         this.showLigandLabel(n);
 
-        this.initialiseLigand(this.pdbId, n.residue.authorResidueNumber, n.residue.chainId);
+        this.initLigandInteractions(this.pdbId, n.residue.authorResidueNumber, n.residue.chainId);
     }
 
     private async setupLigandScene() {
-        this.addMarkers();
+        this.nodesRoot.selectAll('*').remove();
+        this.linksRoot.selectAll('*').remove();
 
         let xShift = (this.parent.offsetWidth / 2) - (this.depiction.resolution.x / 2);
         let yShift = (this.parent.offsetHeight / 2) - (this.depiction.resolution.y / 2);
 
-        this.visualization = this.svg.append('g')
-            .attr('id', 'vis-root')
-            .append('g')
-            .attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
+        this.depictionRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
+        this.nodesRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
+        this.linksRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
 
-        this.links = this.visualization.append('g')
-            .attr('id', 'links')
+
+        this.links = this.linksRoot
             .selectAll()
             .data(this.bindingSite.links)
             .enter().append('g');
@@ -415,10 +397,8 @@ class Visualization {
             .attr('class', (e: Model.LigandResidueLink) => `svg-bond svg-bond-${e.getLinkClass()}`)
             .attr('marker-mid', (e: Model.LigandResidueLink) => e.hasClash() ? 'url(#clash)' : '')
 
-        let depictionRoot = this.visualization.append('g').attr('id', 'depiction');
-        this.depiction.appendClarityNodes(depictionRoot)
-        this.depiction.appendBondVisualsTo(depictionRoot);
-        this.depiction.appendTextsTo(depictionRoot);
+        this.depiction.draw();
+        this.depiction.highlightSubgraph(['C6', 'C7']);
 
         this.bindingSite.interactionNodes
             .filter((x: Model.InteractionNode) => !x.residue.isLigand)
@@ -436,7 +416,7 @@ class Visualization {
 
 
         //setup nodes
-        this.nodes = this.visualization.append('g')
+        this.nodes = this.nodesRoot.append('g')
             .attr('id', 'nodes')
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -448,7 +428,7 @@ class Visualization {
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
             .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`)
-            .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, clickEvent))
+            .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, Config.interactionClickEvent))
             .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
@@ -492,15 +472,17 @@ class Visualization {
             //                    .force('center', center)
             .on('tick', () => this.simulationStep());
 
-        this.drag_handler(this.nodes);
-        this.zoom_handler(this.svg);
+        this.dragHandler(this.nodes);
+        if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, d3.zoomIdentity);
         this.centerScene();
     }
 
     private async setupScene() {
-        this.visualization = this.svg.append('g').attr('id', 'vis-root');
-        this.links = this.visualization.append('g')
-            .attr('id', 'links')
+
+        this.linksRoot.selectAll('*').remove();
+        this.nodesRoot.selectAll('*').remove();
+
+        this.links = this.linksRoot
             .selectAll()
             .data(this.bindingSite.links)
             .enter().append('g')
@@ -518,8 +500,7 @@ class Visualization {
             .attr('class', (x: Model.Link) => `svg-bond svg-bond-${x.getLinkClass()}`)
             .attr('marker-end', (x: Model.Link) => `url(#arrow-${x.getLinkClass()})`);
 
-        this.nodes = this.visualization.append('g')
-            .attr('id', 'nodes')
+        this.nodes = this.nodesRoot
             .selectAll()
             .data(this.bindingSite.interactionNodes)
             .enter().append('g')
@@ -570,8 +551,9 @@ class Visualization {
             .force('center', center)
             .on('tick', () => this.simulationStep());
 
-        this.drag_handler(this.nodes);
-        this.zoom_handler(this.svg);
+        this.dragHandler(this.nodes);
+
+        if (this.zoomHandler) this.zoomHandler(this.svg);
     }
 
     private simulationStep() {
@@ -601,7 +583,7 @@ class Visualization {
 
 
     private showLigandLabel(x: Model.InteractionNode) {
-        const e = new CustomEvent(showLabelEvent, {
+        const e = new CustomEvent(Config.interactionShowLabelEvent, {
             bubbles: true,
             detail: {
                 label: x.toTooltip()
@@ -612,7 +594,7 @@ class Visualization {
     }
 
     private hideLigandLabel() {
-        const e = new CustomEvent(hideLabelEvent, {
+        const e = new CustomEvent(Config.interactionHideLabelEvent, {
             bubbles: true,
             detail: {}
         });
@@ -628,6 +610,7 @@ class Visualization {
         //     // ["arrow-metal", "#008080"],
         //     // ["arrow-aromatic", "#AD4379"],
         // ]);
+
         this.svg
             .append('defs')
             .append('marker')
diff --git a/src/model.ts b/src/model.ts
index 0b7ad14..027b8eb 100644
--- a/src/model.ts
+++ b/src/model.ts
@@ -1,51 +1,6 @@
 namespace Model {
     "use strict";
 
-    const aminoAcids = new Map<string, Array<string>>([
-        ['cystein', new Array<string>('CYS', 'SEC', 'CSO')],
-        ['positive', new Array<string>('LYS', 'ARG')],
-        ['negative', new Array<string>('ASP', 'GLU')],
-        ['polar', new Array<string>('SER', 'SEP', 'THR', 'ASN', 'GLN', 'TPO')],
-        ['aliphatic', new Array<string>('ALA', 'VAL', 'ILE', 'LEU', 'MET', 'PRO', 'MSE')],
-        ['aromatic', new Array<string>('TRP', 'TYR', 'PHE', 'HIS')]
-    ]);
-
-    const backboneAtoms = ['N', 'CA', 'C', 'O'];
-
-    const interactionsClasses = new Map<string, Array<string>>([
-        ["covalent", new Array<string>("covalent")],
-        ["electrostatic", new Array<string>("ionic", "hbond", "weak_hbond", "polar", "weak_polar", "xbond", "carbonyl")],
-        ['amide', new Array<string>("AMIDEAMIDE", "AMIDERING")],
-        ["vdw", new Array<string>("vdw")],
-        ["hydrophobic", new Array<string>("hydrophobic")],
-        ["aromatic", new Array<string>("aromatic", "FF", "OF", "EE", "FT", "OT", "ET", "FE", "OE", "EF", "CARBONPI", "CATIONPI", "DONORPI", "HALOGENPI", "METSULPHURPI")],
-        ["metal", new Array<string>("metal_complex")],
-        ["clashes", new Array<string>("clash", "vdw_clash")]
-    ]);
-
-    export class UIParameters {
-        reinitialize: boolean;
-        fullScreen: boolean;
-        downloadImage: boolean;
-        downloadData: boolean;
-        center: boolean;
-        help: boolean;
-        residueLabel: boolean;
-        tooltip: boolean;
-
-        constructor() {
-            this.reinitialize = true;
-            this.fullScreen = true;
-            this.downloadImage = true;
-            this.downloadData = true;
-            this.center = true;
-            this.help = true;
-            this.residueLabel = true;
-            this.tooltip = true;
-
-        }
-    }
-
     /**
      *
      *
@@ -122,7 +77,7 @@ namespace Model {
                 return 'water';
             }
 
-            for (let [key, value] of aminoAcids) {
+            for (let [key, value] of Config.aminoAcids) {
                 if (value.includes(this.chemCompId)) {
                     return key;
                 }
@@ -249,7 +204,7 @@ namespace Model {
             if (this.isBoundMoleculeLink()) return 'ligand';
 
             // JS map preserves order of elements
-            for (let [key, value] of interactionsClasses) {
+            for (let [key, value] of Config.interactionsClasses) {
                 for (let interactionDetails of this.interactions.values()) {
                     if (interactionDetails.filter(x => -1 !== value.indexOf(x)).length > 0) {
                         return key;
@@ -301,7 +256,7 @@ namespace Model {
             // JS map preserves order of elements
             let allInteractions = this.interaction.map(x => x.interactionsClases).reduce((x, y) => x.concat(y));
 
-            for (let [key, value] of interactionsClasses) {
+            for (let [key, value] of Config.interactionsClasses) {
                 if (allInteractions.filter(x => -1 !== value.indexOf(x)).length > 0) {
                     return key;
                 }
@@ -328,7 +283,7 @@ namespace Model {
         public toTooltip() {
             let msg = [];
             this.interaction.forEach(x => {
-                let isMainChain = !this.target.residue.isLigand && x.targetAtoms.every(y => backboneAtoms.includes(y));
+                let isMainChain = !this.target.residue.isLigand && x.targetAtoms.every(y => Config.backboneAtoms.includes(y));
                 let interactionFlag = isMainChain ? 'backbone' : 'side chain';
 
                 msg.push(`<li><span>${interactionFlag}</span> interaction (<b>${x.targetAtoms}</b> | ${x.interactionsClases}): ${x.distance}Ã…</li>`);
diff --git a/src/ui.ts b/src/ui.ts
index c207f17..b06ae9f 100644
--- a/src/ui.ts
+++ b/src/ui.ts
@@ -1,5 +1,3 @@
-/// <reference path="./config.ts" />
-
 // #region help
 let helpLigands = `
     <table class='int-help-table'>
@@ -111,25 +109,41 @@ let helpBonds = `
 
 
 class UI {
-    private root: HTMLElement;
+    private parent: HTMLElement;
     private display: Visualization;
 
-    private residueLabel: d3.Selection<d3.BaseType, {}, HTMLElement, any>;
-    private tooltip: d3.Selection<d3.BaseType, {}, HTMLElement, any>;
+    private residueLabel: d3.Selection<d3.BaseType, {}, HTMLElement, any>; //label used to display ligand ids
+    private tooltip: d3.Selection<d3.BaseType, {}, HTMLElement, any>; // mouseover tooltips
+
+    private originalWidth: number;
+    private originalHeight: number;
 
 
     constructor(element: HTMLElement, vis: Visualization) {
-        this.root = element;
+        this.parent = element;
         this.display = vis;
 
+        this.originalWidth = this.parent.offsetWidth;
+        this.originalHeight = this.parent.offsetHeight;
+
+
     }
 
-    public register(params: Model.UIParameters) {
+    /**
+     * Registers UI elements on the top of SVG canvas with interactions
+     * and ligands
+     *
+     * @param {Config.UIParameters} params Object with annotation which
+     * UI elements should be created.
+     * @returns
+     * @memberof UI
+     */
+    public register(params: Config.UIParameters) {
         if (!Object.keys(params).some(x => params[x])) {
             return;
         }
 
-        let toolbar = d3.select(this.root)
+        let toolbar = d3.select(this.parent)
             .append('div')
             .classed('int-toolbar-container', true)
             .on('mouseover', () => this.displayToolbarPanel(true))
@@ -194,7 +208,7 @@ class UI {
                 .attr('class', 'icon icon-common icon-question-circle')
                 .on('click', () => this.showHelp());
 
-            let cont = d3.select(this.root).append('div').attr('id', 'int-help-container')
+            let cont = d3.select(this.parent).append('div').attr('id', 'int-help-container')
             let navbar = cont.append('div').classed('int-help-navbar', true);
 
             navbar.append('a')
@@ -214,28 +228,28 @@ class UI {
         }
 
         if (params.tooltip) {
-            this.tooltip = d3.select(this.root).append('div')
+            this.tooltip = d3.select(this.parent).append('div')
                 .classed('int-label', true)
                 .attr('id', 'int-tooltip')
                 .style('opacity', 0)
         }
 
         if (params.residueLabel) {
-            this.residueLabel = d3.select(this.root).append('div')
+            this.residueLabel = d3.select(this.parent).append('div')
                 .classed('int-label', true)
                 .attr('id', 'int-residue-label')
                 .style('opacity', 0)
         }
 
         if (this.tooltip !== undefined) {
-            this.root.addEventListener(clickEvent, e => this.nodeMouseEnterEventHandler(e));
-            this.root.addEventListener(mouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
-            this.root.addEventListener(mouseoutEvent, () => this.nodeMouseLeaveEventHandler());
+            this.parent.addEventListener(Config.interactionClickEvent, e => this.nodeMouseEnterEventHandler(e));
+            this.parent.addEventListener(Config.interactionMouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
+            this.parent.addEventListener(Config.interactionMouseoutEvent, () => this.nodeMouseLeaveEventHandler());
         }
 
         if (this.residueLabel !== undefined) {
-            this.root.addEventListener(showLabelEvent, e => this.showLigandLabel(e));
-            this.root.addEventListener(hideLabelEvent, () => this.hideLigandLabel());
+            this.parent.addEventListener(Config.interactionShowLabelEvent, e => this.showLigandLabel(e));
+            this.parent.addEventListener(Config.interactionHideLabelEvent, () => this.hideLigandLabel());
         }
 
     }
@@ -258,10 +272,10 @@ class UI {
     }
 
     private changeHelp(showResidues: boolean) {
-        let ligHelpBtn = d3.select(this.root).select('#int-help-residues-btn');
-        let bondHelpBtn = d3.select(this.root).select('#int-help-bonds-btn');
-        let bondHelpSection = d3.select(this.root).select('#int-help-bonds');
-        let ligHelpSection = d3.select(this.root).select('#int-help-ligands');
+        let ligHelpBtn = d3.select(this.parent).select('#int-help-residues-btn');
+        let bondHelpBtn = d3.select(this.parent).select('#int-help-bonds-btn');
+        let bondHelpSection = d3.select(this.parent).select('#int-help-bonds');
+        let ligHelpSection = d3.select(this.parent).select('#int-help-ligands');
 
         if (showResidues) {
             bondHelpBtn.classed('active', false);
@@ -278,8 +292,8 @@ class UI {
     }
 
     private showHelp() {
-        let el = d3.select(this.root).select('#int-help-container');
-        let btn = d3.select(this.root).select('#int-help-btn');
+        let el = d3.select(this.parent).select('#int-help-container');
+        let btn = d3.select(this.parent).select('#int-help-btn');
 
         if (el.style('display') === 'block') {
             el.style('display', 'none');
@@ -293,8 +307,8 @@ class UI {
     }
 
     private displayToolbarPanel(show: boolean) {
-        let dynPanel = d3.select(this.root).select('#int-menu-dynamic-panel');
-        let el = d3.select(this.root).select('#int-help-container');
+        let dynPanel = d3.select(this.parent).select('#int-menu-dynamic-panel');
+        let el = d3.select(this.parent).select('#int-help-container');
 
         if (!dynPanel && !el) return;
 
@@ -308,21 +322,39 @@ class UI {
         }
     }
 
+    /**
+     * Switch component view and full screen.
+     *
+     * @private
+     * @memberof UI
+     */
     private fullScreen() {
-        let btn = d3.select(this.root).select('#int-fullscreen-btn');
-        // d3.select(this.root).style('z-index', Number.MAX_VALUE);
+        let btn = d3.select(this.parent).select('#int-fullscreen-btn');        
 
         if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
-            this.display.fullScreen();
+            this.parent.parentElement.style.width = '100%'
+            this.parent.parentElement.style.height = '100%'
+            this.parent.parentElement.style.position = 'fixed';
+            this.parent.parentElement.style.zIndex = '10000000000000';
+
             btn.classed('icon-fullscreen', false);
             btn.classed('icon-fullscreen-collapse', true);
+
+            this.display.centerScene();
         } else {
             btn.classed('icon-fullscreen', true);
             btn.classed('icon-fullscreen-collapse', false);
-            this.display.minimizeScreen();
+
+            this.parent.parentElement.style.width = `${this.originalWidth}px`;
+            this.parent.parentElement.style.height = `${this.originalHeight}px`;
+            this.parent.parentElement.style.position = 'relative';
+            this.parent.parentElement.style.zIndex = '';
+
+            this.display.centerScene();
+
+
         }
     }
-
     // #endregion UI methods
 
     // #region event handlers
diff --git a/src/visualsMapping.ts b/src/visualsMapping.ts
index 79db6dd..6b1ed2b 100644
--- a/src/visualsMapping.ts
+++ b/src/visualsMapping.ts
@@ -18,8 +18,8 @@ class VisualsMapper {
         this.glycanMapping = new Map<string, string>();
         this.glycanImages = new Map<string, SVGElement>();
 
-        this.graphicsPromise = this.parseSymbols('https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/visuals.xml');
-        this.mappingPromise = this.parseGlycanMapping('https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json');        
+        this.graphicsPromise = this.parseSymbols(Config.glycanSymbols);
+        this.mappingPromise = this.parseGlycanMapping(Config.glycanMapping);        
     }
     
     /**
-- 
GitLab


From 0afb601fe7c41a188ab2b4a4cd4a5e433ce2c7e5 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 22 Jan 2020 14:37:33 +0000
Subject: [PATCH 09/66] reworked component parameters

---
 build/index.html |   6 +-
 src/component.js |  76 +++++++++-----
 src/manager.ts   | 259 +++++++++++++++++++++++++++++++++--------------
 3 files changed, 237 insertions(+), 104 deletions(-)

diff --git a/build/index.html b/build/index.html
index 5d9ef6c..2b92d96 100644
--- a/build/index.html
+++ b/build/index.html
@@ -30,7 +30,7 @@
 
     var renderLigandInteractions = function (id, chain, resId) {
         var int =
-            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}"></pdb-interactions>`
+            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
@@ -71,8 +71,6 @@
                         query: "https://wwwdev.ebi.ac.uk/pdbe/coordinates/1cbs/ligandInteraction?&authAsymId=$A&authSeqNumber=$200&radius=5&dataSource=hydrogens"
                     };
                 }
-                console.log('Perceived parameters:');
-                console.log(params);
 
                 if (params.bmid === undefined) {
                     renderLigandInteractions(params.pdbid, params.chain, params.resid);
@@ -120,7 +118,7 @@
     </div>
     <div style="position: relative; float: left;">
         <div id="rt 1" style="width: 500px; height: 500px; position: relative">
-            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+            <pdb-interactions pdb-res-name="HEM" zoom-on></pdb-interactions>
         </div>
     </div>
 
diff --git a/src/component.js b/src/component.js
index 5e4cac0..39bf634 100644
--- a/src/component.js
+++ b/src/component.js
@@ -7,10 +7,14 @@ class pdbInteractions extends LitElement {
   //Get properties / attribute values
   static get properties() {
     return {
-      'pdb-id': { type: String },
-      'bound-molecule-id': { type: String },
-      'pdb-res-id': { type: Number },
-      'pdb-chain-id': { type: String }
+      pdbId: { type: String, attribute: 'pdb-id' },
+      bmId: { type: String, attribute: 'bound-molecule-id' },
+      resName: { type: String, attribute: 'pdb-res-name' },
+      resId: { type: Number, attribute: 'pdb-res-id' },
+      chainId: { type: String, attribute: 'pdb-chain-id' },
+      substructureHighlight: { type: Array, attribute: 'substructure' },
+      substructureColor: { type: String, attribute: 'color' },
+      zoomOn: { type: Boolean, attribute: 'zoom-on' },
     };
   }
 
@@ -18,39 +22,61 @@ class pdbInteractions extends LitElement {
     super();
   }
 
-  render() {
-    return html`
-      
-      ${!this['pdb-id'] ?
-        html`<div style='text-align:center;font-weight:bold;margin-top:20px;'>Error: Specify valid 'pdb-id' attribute to render the component.<div>` :
-        html``
-      }
-    `;
-  }
+  async connectedCallback() {
+    let uiParams = new Config.UIParameters();
 
-  updated(changedProperties) {
-    if (this['pdb-id']) {
-      this.display = new Visualization(this);
+    this.style.display = 'block';
+    this.style.height = '100%';
+    this.style.width = '100%';
+    this.style.position = 'relative';
 
-      if (this['bound-molecule-id']) {
-        this.display.initBMInteractions(this['pdb-id'], this['bound-molecule-id']);
+    uiParams.zoom = this.zoomOn;
+    this.display = new Visualization(this, uiParams);
+
+    if (this.pdbId) {
+      if (this.bmId) {
+        this.display.initBoundMoleculeInteractions(this.pdbId, this.bmId);
       }
       else {
-        this.display.initLigandInteractions(this['pdb-id'], this['pdb-res-id'], this['pdb-chain-id'])
+        this.display.initLigandInteractions(this.pdbId, this.resId, this.chainId)
       }
     }
+    else if (this.resName) {
+      this.display.initLigandDisplay(this.resName).then(() => this.display.centerScene());
+    }
   }
 
-  connectedCallback() {
-    super.connectedCallback();
 
-    this.style.display = 'block';
-    this.style.height = '100%';
-    this.style.width = '100%';
-    this.style.position = 'relative';
+  //#region properties
+  set depiction(data) {
+    if (!data) return;
+
+    this.display.addDepiction(data);
+  }
 
+  set ligandHighlight(data) {
+    if (!data || !this.display) {
+      console.log(`Argument needs to be a non empty array of strings.`);
+      return;
+    }
+
+    this.display.addLigandHighlight(data, this.highlightColor);
+    this.substructureHighlight = data;
   }
 
+  set highlightColor(data) {
+    if (!data || !this.display) return;
+
+    this.highlightColor = data;
+    this.display(this.substructureHighlight, this.highlightColor);
+  }
+
+  set zoom(data) {
+    if (this.display !== undefined) this.display.toogleZoom(data);
+  }
+  //#endregion properties
+
+
   createRenderRoot() {
     /**
      * Render template in light DOM. Note that shadow DOM features like 
diff --git a/src/manager.ts b/src/manager.ts
index 7b30924..009abdf 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -30,7 +30,7 @@ class Visualization {
     constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
         this.parent = element;
         this.visualsMapper = new VisualsMapper();
-
+        console.log(uiParameters);
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
 
         new UI(this.parent, this).register(uiParameters);
@@ -45,17 +45,12 @@ class Visualization {
             .attr('height', '100%');
 
         this.canvas = this.svg.append('g').attr('id', 'vis-root');
-        
+
         this.linksRoot = this.canvas.append('g').attr('id', 'links');
         this.depictionRoot = this.canvas.append('g').attr('id', 'depiction');
         this.nodesRoot = this.canvas.append('g').attr('id', 'nodes');
 
-        if (uiParameters.zoom) {
-            this.zoomHandler = d3.zoom()
-                .scaleExtent([1 / 10, 10])
-                .on('zoom', () => this.canvas
-                    .attr('transform', d3.event.transform));
-        }
+        if (uiParameters.zoom) this.zoomHandler = this.getZoomHandler();
 
         document.addEventListener(Config.molstarClickEvent, e => this.nodeMouseEnterEventHandler(e));
         document.addEventListener(Config.molstarMouseoverEvent, e => this.nodeMouseEnterEventHandler(e));
@@ -69,26 +64,32 @@ class Visualization {
     private nodeMouseEnterEventHandler(e: any) {
         let hash = `${e.eventData.auth_asym_id}${e.eventData.auth_seq_id}${e.eventData.ins_code}`;
 
-        if (this.nodes !== undefined) {
-            this.nodes.each((node: Model.InteractionNode, index: number, group: any) => {
-                if (node.id === hash) {
-                    this.selectedResidueHash = hash;
-                    this.nodeHighlight(node, index, group);
-                    return;
-                }
-            });
-        }
+        this.nodes?.each((node: Model.InteractionNode, index: number, group: any) => {
+            if (node.id === hash) {
+                this.selectedResidueHash = hash;
+                this.nodeHighlight(node, index, group);
+                return;
+            }
+        });
+
+    }
+
+
+    private getZoomHandler() {
+        return d3.zoom()
+            .scaleExtent([1 / 10, 10])
+            .on('zoom', () => this.canvas
+                .attr('transform', d3.event.transform));
     }
 
+
     private nodeMouseLeaveEventHandler() {
-        if (this.nodes !== undefined) {
-            this.nodes.each((node: Model.InteractionNode, index: number, group: any) => {
-                if (node.id == this.selectedResidueHash) {
-                    this.nodeDim(node, index, group);
-                    return;
-                }
-            });
-        }
+        this.nodes?.each((node: Model.InteractionNode, index: number, group: any) => {
+            if (node.id == this.selectedResidueHash) {
+                this.nodeDim(node, index, group);
+                return;
+            }
+        });
     }
 
     private linkMouseClickEventHandler(x: Model.Link) {
@@ -122,52 +123,137 @@ class Visualization {
 
     // #endregion event handlers
 
-    public initBMInteractions(pdbid: string, bmId: string) {
+    /**
+     * Download bound molecule interactions data from PDBe Graph API end point
+     * /pdb/bound_molecule_interactions
+     * 
+     * Correct parameters can be obtained using API call:
+     * /pdb/bound_molecules
+     *
+     * @param {string} pdbid
+     * @param {string} bmId bound molecule identifier: e.g. bm1, bm2, ...
+     * @memberof Visualization
+     */
+    public initBoundMoleculeInteractions(pdbid: string, bmId: string) {
         this.pdbId = pdbid;
 
         d3.json(`${Config.server}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
             .catch(e => { throw e; })
             .then((data: any) => {
-                let key = Object.keys(data)[0];
-                this.interactionsData = data;
+                this.addBoundMoleculeInteractions(data, bmId);
+            });
+    }
 
-                this.bindingSite = new Model.BindingSite().fromBoundMolecule(key, data[key][0]);
-                this.bindingSite.bmId = bmId;
-                let ligands = this.bindingSite.residues.filter(x => x.isLigand);
+    /**
+     * Download ligand interactions data from PDBe Graph API end point
+     * /pdb/bound_ligand_interactions.
+     * 
+     * Correct parameters can be obtained using API call:
+     * /pdb/bound_molecules
+     * 
+     * @param {string} pdbId pdb id
+     * @param {number} resId residue number aka: auth_seq_id
+     * @param {string} chainId chain id aka: auth_asym_id
+     * @memberof Visualization
+     */
+    public initLigandInteractions(pdbId: string, resId: number, chainId: string) {
+        this.pdbId = pdbId;
 
-                if (ligands.length === 1) this.initLigandInteractions(this.pdbId, ligands[0].authorResidueNumber, ligands[0].chainId);
-                else this.setupScene();
+        d3.json(`${Config.server}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
+            .catch(e => { throw e; })
+            .then((data: any) => {
+                this.addLigandInteractions(data);
             });
     }
 
-    public async initLigand(ligandId: string) {
+    /**
+     * Download ligand structure given the anotation generated by the 
+     * PDBeChem process.
+     *
+     * @param {string} ligandId
+     * @returns
+     * @memberof Visualization
+     */
+    public async initLigandDisplay(ligandId: string) {
         return d3.json(`https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/${ligandId}/annotation`)
             .catch(e => { throw e; })
-            .then((d: any) => {
-                this.depiction = new Depiction(this.depictionRoot, d);
-            });
+            .then((d: any) => this.addDepiction(d));
     }
 
-    public initLigandInteractions(pdbId: string, resId: number, chainId: string) {
-        this.pdbId = pdbId;
 
-        d3.json(`${Config.server}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
-            .catch(e => { throw e; })
-            .then((data: any) => {
-                let key = Object.keys(data)[0];
-                let body = data[key][0];
-                this.interactionsData = data;
-
-                if (this.depiction === undefined || this.depiction.ccdId !== body.ligand.chem_comp_id) {
-                    this.initLigand(body.ligand.chem_comp_id).then(() => {
-                        this.bindingSite = new Model.BindingSite().fromLigand(key, body, this.depiction);
-                        this.setupLigandScene();
-                    });
-                } else {
-                    this.bindingSite = new Model.BindingSite().fromLigand(key, body, this.depiction);
-                    this.setupLigandScene();
-                }
+    /**
+     * Add depiction to the canvas from external resource.
+     *
+     * @param {*} depiction Content of annotation.json file generated by
+     * the PDBeChem process.
+     * @memberof Visualization
+     */
+    public addDepiction(depiction: any) {
+        this.depiction = new Depiction(this.depictionRoot, depiction);
+        this.depiction.draw();
+    }
+
+
+    /**
+     *
+     *
+     * @param {string[]} highlight
+     * @param {string} [color=undefined]
+     * @memberof Visualization
+     */
+    public addLigandHighlight(highlight: string[], color: string = undefined) {
+        this.depiction.highlightSubgraph(highlight, color);
+    }
+
+    public toogleZoom(active: boolean) {
+        if (active) {
+            this.zoomHandler = this.getZoomHandler();
+        } else {
+            this.zoomHandler = undefined;
+        }
+    }
+
+    /**
+     * Add ligand interactions to the canvas
+     *
+     * @param {*} data Data content of the API end point 
+     * /pdb/bound_ligand_interactions
+     * @memberof Visualization
+     */
+    public addLigandInteractions(data: any) {
+        let key = Object.keys(data)[0];
+        let body = data[key][0];
+        this.interactionsData = data;
+
+        if (this.depiction === undefined || this.depiction.ccdId !== body.ligand.chem_comp_id) {
+            this.initLigandDisplay(body.ligand.chem_comp_id).then(() => {
+                this.bindingSite = new Model.BindingSite().fromLigand(key, body, this.depiction);
+                this.setupLigandScene();
             });
+        } else {
+            this.bindingSite = new Model.BindingSite().fromLigand(key, body, this.depiction);
+            this.setupLigandScene();
+        }
+    }
+
+    /**
+     * Add bound molecule interactions to the canvas.
+     *
+     * @param {*} data Data content of the API end point 
+     * /pdb/bound_molecule_interactions
+     * @param {string} bmId Bound molecule id
+     * @memberof Visualization
+     */
+    public addBoundMoleculeInteractions(data: any, bmId: string) {
+        let key = Object.keys(data)[0];
+        this.interactionsData = data;
+
+        this.bindingSite = new Model.BindingSite().fromBoundMolecule(key, data[key][0]);
+        this.bindingSite.bmId = bmId;
+        let ligands = this.bindingSite.residues.filter(x => x.isLigand);
+
+        if (ligands.length === 1) this.initLigandInteractions(this.pdbId, ligands[0].authorResidueNumber, ligands[0].chainId);
+        else this.setupScene();
     }
 
     // #region menu functions
@@ -183,7 +269,7 @@ class Visualization {
             let downloadLink = document.createElement('a');
 
             downloadLink.href = svgUrl;
-            downloadLink.download = `${this.pdbId}_${this.bindingSite.bmId}.svg`;
+            downloadLink.download = this.getSVGName();
 
             document.body.appendChild(downloadLink);
             downloadLink.click();
@@ -191,14 +277,23 @@ class Visualization {
         });
     }
 
+    private getSVGName(): string { 
+        if (this.bindingSite !== undefined) return `${this.bindingSite.bmId}.svg`;
+        if (this.depiction !== undefined) return `${this.depiction.ccdId}.svg`;
+
+        return 'no name.svg';
+    }
+
 
     public downloadInteractionsData(): void {
         let downloadLink = document.createElement('a');
 
+            
+
         let dataBlob = new Blob([JSON.stringify(this.interactionsData, null, 4)], { type: 'application/json' });
 
         downloadLink.href = URL.createObjectURL(dataBlob);
-        downloadLink.download = `${this.pdbId}_${this.bindingSite.bmId}_interactions.json`;
+        downloadLink.download = this.interactionsData === undefined? 'no name.json' : `${this.pdbId}_${this.bindingSite.bmId}_interactions.json`;
         document.body.appendChild(downloadLink);
         downloadLink.click();
         document.body.removeChild(downloadLink);
@@ -228,16 +323,31 @@ class Visualization {
 
 
     public centerScene() {
-        if (this.nodes.length === 0)
-            return;
+        console.log('centering');
+        if (this.nodes !== undefined) {
+            console.log('have interactions');
+            // Get the bounding box
+            let minX: any = d3.min(this.nodes.data().map((x) => x.x));
+            let minY: any = d3.min(this.nodes.data().map((x) => x.y));
 
-        // Get the bounding box
-        let minX: any = d3.min(this.nodes.data().map((x) => x.x));
-        let minY: any = d3.min(this.nodes.data().map((x) => x.y));
+            let maxX: any = d3.max(this.nodes.data().map((x) => x.x));
+            let maxY: any = d3.max(this.nodes.data().map((x) => x.y));
 
-        let maxX: any = d3.max(this.nodes.data().map((x) => x.x));
-        let maxY: any = d3.max(this.nodes.data().map((x) => x.y));
+            this.computeBoundingBox(minX, maxX, minY, maxY);
 
+        } else if (this.depiction !== undefined) {
+            console.log('have depiction');
+            let minX: any = d3.min(this.depiction.atoms.map((x: Atom) => x.position.x));
+            let minY: any = d3.min(this.depiction.atoms.map((x: Atom) => x.position.y));
+
+            let maxX: any = d3.max(this.depiction.atoms.map((x: Atom) => x.position.x));
+            let maxY: any = d3.max(this.depiction.atoms.map((x: Atom) => x.position.y));
+
+            this.computeBoundingBox(minX, maxX, minY, maxY);
+        }
+    }
+
+    private computeBoundingBox(minX: number, maxX: number, minY: number, maxY: number) {
         // The width and the height of the graph
         let molWidth = maxX - minX;
         let molHeight = maxY - minY;
@@ -263,12 +373,9 @@ class Visualization {
 
         // tell the zoomer what we did so that next we zoom, it uses the
         // transformation we entered here        
-        if (this.zoomHandler !== undefined) {
-            let translation = d3.zoomIdentity.translate(xTrans, yTrans).scale(minRatio)
-            this.zoomHandler.transform(this.svg, translation);
-        }
-
 
+        let translation = d3.zoomIdentity.translate(xTrans, yTrans).scale(minRatio);
+        if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, translation);
     };
     // #endregion menu functions
 
@@ -368,6 +475,7 @@ class Visualization {
         this.initLigandInteractions(this.pdbId, n.residue.authorResidueNumber, n.residue.chainId);
     }
 
+
     private async setupLigandScene() {
         this.nodesRoot.selectAll('*').remove();
         this.linksRoot.selectAll('*').remove();
@@ -395,10 +503,7 @@ class Visualization {
         this.links
             .append('line')
             .attr('class', (e: Model.LigandResidueLink) => `svg-bond svg-bond-${e.getLinkClass()}`)
-            .attr('marker-mid', (e: Model.LigandResidueLink) => e.hasClash() ? 'url(#clash)' : '')
-
-        this.depiction.draw();
-        this.depiction.highlightSubgraph(['C6', 'C7']);
+            .attr('marker-mid', (e: Model.LigandResidueLink) => e.hasClash() ? 'url(#clash)' : '');
 
         this.bindingSite.interactionNodes
             .filter((x: Model.InteractionNode) => !x.residue.isLigand)
@@ -436,7 +541,7 @@ class Visualization {
             .html((e: Model.InteractionNode) => this.visualsMapper.getGlycanImage(e.residue.chemCompId));
 
         // draw rest
-        this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand && !this.visualsMapper.glycanMapping.has(x.residue.chemCompId))
+        this.nodes.filter((x: Model.InteractionNode) => !this.visualsMapper.glycanMapping.has(x.residue.chemCompId))
             .append('circle')
             .attr('r', (x: Model.InteractionNode) => x.scale * 25);
 
@@ -477,8 +582,8 @@ class Visualization {
         this.centerScene();
     }
 
-    private async setupScene() {
 
+    private async setupScene() {
         this.linksRoot.selectAll('*').remove();
         this.nodesRoot.selectAll('*').remove();
 
@@ -556,6 +661,7 @@ class Visualization {
         if (this.zoomHandler) this.zoomHandler(this.svg);
     }
 
+
     private simulationStep() {
         this.nodes.attr('transform', (d) => `translate(${d.x},${d.y}) scale(${d.scale})`);
         this.links.selectAll('line').attr('x1', (x: any) => x.source.x)
@@ -564,6 +670,7 @@ class Visualization {
             .attr('y2', (x: any) => x.target.y);
     }
 
+
     private nodeHighlight(x: Model.InteractionNode, i: number, g: any) {
         x.scale = 1.5;
 
@@ -572,6 +679,7 @@ class Visualization {
             .attr('transform', () => `translate(${x.x},${x.y}) scale(${x.scale})`);
     }
 
+
     private nodeDim(x: Model.InteractionNode, i: number, g: any) {
         x.scale = 1.0;
 
@@ -593,6 +701,7 @@ class Visualization {
         this.parent.dispatchEvent(e);
     }
 
+
     private hideLigandLabel() {
         const e = new CustomEvent(Config.interactionHideLabelEvent, {
             bubbles: true,
-- 
GitLab


From 657d3250afe3efb6abd629f4587d26a478961723 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 22 Jan 2020 16:24:28 +0000
Subject: [PATCH 10/66] add README

---
 README.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 README.md

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..135d78b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,73 @@
+# PDBe interactions component
+
+This is a web-component to display ligand structure in 2D along with its interactions. Ligand can be perceived as a set of covalently linked pdb residues (refered to as bound molecule) or a single pdb residue. This depiction can be enriched with a substructure highlight and binding site interactions.
+
+## Component modes
+
+### A) Display bound molecule and its interactions
+
+### B) Display ligand and its interactions
+
+### C) Display ligand (chemical component) only
+
+<div style="text-align:center;">
+ <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=CLR&size=400"/>
+ <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=Y01&size=400"/>
+</div>
+
+## Usage: web-component
+
+### A) Bound molecule interactions
+
+```html
+<pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+```
+
+### Ligand interactions
+
+```html
+<ligand-display pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></ligand-display>
+```
+
+### Ligand/chemical component
+
+```html
+<ligand-display pdb-res-name="CLR" zoom ></ligand-display>
+```
+
+## Usage: Data injection
+
+First you need to define a component on the page
+
+```html
+<ligand-display id='SIA-component'></ligand-display>
+```
+
+and then inject data you want to display.
+
+```javascript
+let chemUrl = `https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/SIA/annotation`;
+let interactionsURL = "";
+let component = document.getElementById('SIA-component');
+
+const depiction = await (await fetch(chemUrl)).json();
+const interactionsData = await (await fetch(interactionsURL)).json();
+const atomsToHighlight = ['C10', 'C11', 'O10'];
+
+component.depiction = depiction;
+component.ligandHighlight = atomsToHighlight;
+component.interactions = interactionsData;
+```
+
+## Parameters
+
+| Parametr            | Type      | Required | Description |
+|-------------------- | --------- | -------- | -------     |
+| pdb-id              | string    | No       | PDB id of a protein to retrieve interactions from. `(mode A and B only)` |
+| bound-molecule-id   | string    | No       | PDB bound molecule id `(mode A only)` |
+| pdb-res-name        | string    | No       | PDB residue name aka: *auth_comp_id* `(mode C only)`
+| pdb-res-id          | number    | No       | PDB residue id aka: *auth_seq_id* `(mode B only)`
+| pdb-chain-id        | string    | No       | PDB residue chain aka: *auth_asym_id*  `(mode B only)`|
+| substructure        | string[]  | No       | List of atom names to be highlighted on the ligand structure |
+| color               | string    | No       | HEX representation of the color highlight. `(Default: #D3D3D3)` |
+| zoom-on             | boolean   | No       | Allow zoom functionality on the component level. |
-- 
GitLab


From 2e534d0cd7e05981776653af2ef43945a93249e5 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 23 Jan 2020 15:20:24 +0000
Subject: [PATCH 11/66] fix broken SVG save

---
 src/config.ts  | 11 -----------
 src/manager.ts | 51 +++++++++++++++++++++++++++-----------------------
 2 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/src/config.ts b/src/config.ts
index 8738521..64ba2d0 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -61,15 +61,4 @@ namespace Config {
 
         }
     }
-    //TODO
-    export class InitParameters {
-        ligandParams: InitLigandParameters;
-
-    }
-
-    export class InitLigandParameters {
-        chemCompId: string;
-        highlight: string[];
-
-    }
 }
\ No newline at end of file
diff --git a/src/manager.ts b/src/manager.ts
index 009abdf..af7e013 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -7,6 +7,7 @@ class Visualization {
     private simulation: d3.Simulation<d3.SimulationNodeDatum, undefined>;
     private svg: d3.Selection<any, {}, HTMLElement, any>;
     private canvas: d3.Selection<SVGGElement, {}, HTMLElement, any>;
+
     private depictionRoot: d3.Selection<SVGGElement, {}, HTMLElement, any>;
     private nodesRoot: d3.Selection<SVGGElement, {}, HTMLElement, any>;
     private linksRoot: d3.Selection<SVGGElement, {}, HTMLElement, any>;
@@ -30,7 +31,7 @@ class Visualization {
     constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
         this.parent = element;
         this.visualsMapper = new VisualsMapper();
-        console.log(uiParameters);
+
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
 
         new UI(this.parent, this).register(uiParameters);
@@ -45,7 +46,6 @@ class Visualization {
             .attr('height', '100%');
 
         this.canvas = this.svg.append('g').attr('id', 'vis-root');
-
         this.linksRoot = this.canvas.append('g').attr('id', 'links');
         this.depictionRoot = this.canvas.append('g').attr('id', 'depiction');
         this.nodesRoot = this.canvas.append('g').attr('id', 'nodes');
@@ -258,12 +258,16 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
-        d3.text('pdbe-interactions-svgstyles.css').then(x => {
-            let svgToDl = this.svg
-                .append('style')
-                .text(`/* <![CDATA[ */ \n ${x} \n /* ]]> */`);
+        d3.text('pdbe-interactions-svgstyles.css')
+            .then(x => {
+            let svgData = `
+                <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" style="background-color: white;">
+                ${this.svg.html()}
+                <style>
+                /* <![CDATA[ */ \n ${x} \n /* ]]> */
+                </style>
+                </svg>`;
 
-            let svgData = svgToDl.html();
             let svgBlob = new Blob([svgData], { type: 'image/svg;charset=utf-8' });
             let svgUrl = URL.createObjectURL(svgBlob);
             let downloadLink = document.createElement('a');
@@ -277,23 +281,13 @@ class Visualization {
         });
     }
 
-    private getSVGName(): string { 
-        if (this.bindingSite !== undefined) return `${this.bindingSite.bmId}.svg`;
-        if (this.depiction !== undefined) return `${this.depiction.ccdId}.svg`;
-
-        return 'no name.svg';
-    }
-
 
     public downloadInteractionsData(): void {
         let downloadLink = document.createElement('a');
-
-            
-
         let dataBlob = new Blob([JSON.stringify(this.interactionsData, null, 4)], { type: 'application/json' });
 
         downloadLink.href = URL.createObjectURL(dataBlob);
-        downloadLink.download = this.interactionsData === undefined? 'no name.json' : `${this.pdbId}_${this.bindingSite.bmId}_interactions.json`;
+        downloadLink.download = this.interactionsData === undefined ? 'no name.json' : `${this.pdbId}_${this.bindingSite.bmId}_interactions.json`;
         document.body.appendChild(downloadLink);
         downloadLink.click();
         document.body.removeChild(downloadLink);
@@ -321,12 +315,23 @@ class Visualization {
         if (this.zoomHandler !== undefined) this.zoomHandler(this.svg);
     }
 
+    private getSVGName(): string {
+        if (this.bindingSite !== undefined) return `${this.bindingSite.bmId}.svg`;
+        if (this.depiction !== undefined) return `${this.depiction.ccdId}.svg`;
+
+        return 'no name.svg';
+    }
+
+
 
+    /**
+     * Center the scene around ligand or interactions.
+     *
+     * @memberof Visualization
+     */
     public centerScene() {
-        console.log('centering');
+        // Get the bounding box
         if (this.nodes !== undefined) {
-            console.log('have interactions');
-            // Get the bounding box
             let minX: any = d3.min(this.nodes.data().map((x) => x.x));
             let minY: any = d3.min(this.nodes.data().map((x) => x.y));
 
@@ -336,7 +341,6 @@ class Visualization {
             this.computeBoundingBox(minX, maxX, minY, maxY);
 
         } else if (this.depiction !== undefined) {
-            console.log('have depiction');
             let minX: any = d3.min(this.depiction.atoms.map((x: Atom) => x.position.x));
             let minY: any = d3.min(this.depiction.atoms.map((x: Atom) => x.position.y));
 
@@ -375,7 +379,8 @@ class Visualization {
         // transformation we entered here        
 
         let translation = d3.zoomIdentity.translate(xTrans, yTrans).scale(minRatio);
-        if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, translation);
+        this.zoomHandler?.transform(this.svg, translation);
+
     };
     // #endregion menu functions
 
-- 
GitLab


From 9cd91f9a01d08847f6065d3207a9afb3304a022d Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 23 Jan 2020 15:42:20 +0000
Subject: [PATCH 12/66] improve README

---
 README.md | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index 135d78b..d8be90c 100644
--- a/README.md
+++ b/README.md
@@ -4,16 +4,15 @@ This is a web-component to display ligand structure in 2D along with its interac
 
 ## Component modes
 
-### A) Display bound molecule and its interactions
+* Mode A: Display bound molecule and its interactions
+* Mode B: Display ligand and its interactions
+* Mode C: Display ligand (chemical component) only
 
-### B) Display ligand and its interactions
-
-### C) Display ligand (chemical component) only
-
-<div style="text-align:center;">
- <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=CLR&size=400"/>
- <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=Y01&size=400"/>
-</div>
+| Mode A | Mode B | Mode C |
+|-------------------- | --------- | -------- | 
+| <img src="https://www.ebi.ac.uk/~lpravda/imgs/1cbs_REA_200_A.png"/>| <img src="https://www.ebi.ac.uk/~lpravda/imgs/3d12_bm1.png"/> | <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=VIA&size=400"/> |
+| 1cbs REA 200 A | 3D12 bm1 (`2xGLC-2xBGC-LXZ-NGA-GL0`)| wwPDB CCD - VIA
+ 
 
 ## Usage: web-component
 
@@ -23,16 +22,16 @@ This is a web-component to display ligand structure in 2D along with its interac
 <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
 ```
 
-### Ligand interactions
+### B) Ligand interactions
 
 ```html
 <ligand-display pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></ligand-display>
 ```
 
-### Ligand/chemical component
+### C) Ligand/chemical component
 
 ```html
-<ligand-display pdb-res-name="CLR" zoom ></ligand-display>
+<ligand-display pdb-res-name="CLR" zoom-on ></ligand-display>
 ```
 
 ## Usage: Data injection
-- 
GitLab


From 034b8c83e1f143f91ad6e3be512d413c7f8e7dbe Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 23 Jan 2020 16:05:21 +0000
Subject: [PATCH 13/66] add hook for adding contour levels

---
 build/index.html |   2 +-
 src/component.js |   9 +++-
 src/depiction.ts |  11 +++--
 src/manager.ts   | 104 +++++++++++++++++++++++++++++++----------------
 4 files changed, 85 insertions(+), 41 deletions(-)

diff --git a/build/index.html b/build/index.html
index 2b92d96..293a138 100644
--- a/build/index.html
+++ b/build/index.html
@@ -118,7 +118,7 @@
     </div>
     <div style="position: relative; float: left;">
         <div id="rt 1" style="width: 500px; height: 500px; position: relative">
-            <pdb-interactions pdb-res-name="HEM" zoom-on></pdb-interactions>
+            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-interactions>
         </div>
     </div>
 
diff --git a/src/component.js b/src/component.js
index 39bf634..94a6cd0 100644
--- a/src/component.js
+++ b/src/component.js
@@ -1,5 +1,6 @@
 // Import the LitElement base class and html helper function
 import { LitElement, html } from 'lit-element';
+import { tickStep } from 'd3';
 
 // Extend the LitElement base class
 class pdbInteractions extends LitElement {
@@ -68,7 +69,13 @@ class pdbInteractions extends LitElement {
     if (!data || !this.display) return;
 
     this.highlightColor = data;
-    this.display(this.substructureHighlight, this.highlightColor);
+    this.display.addLigandHighlight(this.substructureHighlight, this.highlightColor);
+  }
+
+  set contourData(data) { 
+    if (!data || !this.display || !this.display.hasDepiction()) return;
+
+    this.display.addContours(data);
   }
 
   set zoom(data) {
diff --git a/src/depiction.ts b/src/depiction.ts
index 8531dcb..ede9308 100644
--- a/src/depiction.ts
+++ b/src/depiction.ts
@@ -45,8 +45,6 @@ class Depiction {
 
             this.bonds.push(bond);
         });
-
-        console.log(this.contour);
     }
 
 
@@ -92,6 +90,7 @@ class Depiction {
 
     public draw() {
         this.structure.selectAll("*").remove();
+
         this.appendClarityNodes();
         this.appendBondVisuals();
         this.appendTexts();
@@ -124,6 +123,11 @@ class Depiction {
             .attr('style', `fill:none;fill-rule:evenodd;stroke:${color};stroke-width:22px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1`)
     }
 
+    public addContour(data: any) { 
+        this.contour.selectAll('*').remove();
+
+        this.contour.append('div').text(`'contour data goes here: ${data}`);
+    }
 
     /**
      * Appends to a given selection the visual representation of bonds as svg:path elements.
@@ -132,7 +136,6 @@ class Depiction {
      * @memberof Depiction
      */
     private appendBondVisuals(): void {
-
         this.structure.selectAll()
             .data(this.bonds)
             .enter()
@@ -175,7 +178,6 @@ class Depiction {
      * @memberof Depiction
      */
     private appendClarityNodes(): void {
-
         this.structure.selectAll()
             .data(this.atoms.filter(x => Object.keys(x.label).length != 0))
             .enter().append('circle')
@@ -188,6 +190,7 @@ class Depiction {
 
     public getCenter(ids: string[]): Vector2D {
         let coords = new Array<Vector2D>();
+        
         ids.forEach(x => {
             let pos = this.atoms.find(y => y.name === x).position;
             coords.push(pos);
diff --git a/src/manager.ts b/src/manager.ts
index af7e013..ae82a47 100644
--- a/src/manager.ts
+++ b/src/manager.ts
@@ -123,6 +123,7 @@ class Visualization {
 
     // #endregion event handlers
 
+    // #region public methods
     /**
      * Download bound molecule interactions data from PDBe Graph API end point
      * /pdb/bound_molecule_interactions
@@ -195,16 +196,29 @@ class Visualization {
 
 
     /**
+     * Add atom highlight to the ligand structure. The previous highlight
+     * is going to be removed.
      *
-     *
-     * @param {string[]} highlight
-     * @param {string} [color=undefined]
+     * @param {string[]} highlight List of atom names to be highlighted.
+     * @param {string} [color=undefined] Color in #HEXHEX format.
      * @memberof Visualization
      */
     public addLigandHighlight(highlight: string[], color: string = undefined) {
         this.depiction.highlightSubgraph(highlight, color);
     }
 
+    /**
+     * Add contours to the ligand structure. The previous contours are
+     * going to be removed.
+     *
+     * @param {*} data
+     * @memberof Visualization
+     */
+    public addContours(data: any) {
+        this.depiction.addContour(data);
+    }
+
+
     public toogleZoom(active: boolean) {
         if (active) {
             this.zoomHandler = this.getZoomHandler();
@@ -213,6 +227,11 @@ class Visualization {
         }
     }
 
+
+    public hasDepiction(): boolean {
+        return this.depiction !== undefined;
+    }
+
     /**
      * Add ligand interactions to the canvas
      *
@@ -236,6 +255,7 @@ class Visualization {
         }
     }
 
+
     /**
      * Add bound molecule interactions to the canvas.
      *
@@ -256,11 +276,12 @@ class Visualization {
         else this.setupScene();
     }
 
+
     // #region menu functions
     public saveSvg() {
         d3.text('pdbe-interactions-svgstyles.css')
             .then(x => {
-            let svgData = `
+                let svgData = `
                 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" style="background-color: white;">
                 ${this.svg.html()}
                 <style>
@@ -268,20 +289,25 @@ class Visualization {
                 </style>
                 </svg>`;
 
-            let svgBlob = new Blob([svgData], { type: 'image/svg;charset=utf-8' });
-            let svgUrl = URL.createObjectURL(svgBlob);
-            let downloadLink = document.createElement('a');
+                let svgBlob = new Blob([svgData], { type: 'image/svg;charset=utf-8' });
+                let svgUrl = URL.createObjectURL(svgBlob);
+                let downloadLink = document.createElement('a');
 
-            downloadLink.href = svgUrl;
-            downloadLink.download = this.getSVGName();
+                downloadLink.href = svgUrl;
+                downloadLink.download = this.getSVGName();
 
-            document.body.appendChild(downloadLink);
-            downloadLink.click();
-            document.body.removeChild(downloadLink);
-        });
+                document.body.appendChild(downloadLink);
+                downloadLink.click();
+                document.body.removeChild(downloadLink);
+            });
     }
 
 
+    /**
+     * Download interactions data in the JSON format.
+     *
+     * @memberof Visualization
+     */
     public downloadInteractionsData(): void {
         let downloadLink = document.createElement('a');
         let dataBlob = new Blob([JSON.stringify(this.interactionsData, null, 4)], { type: 'application/json' });
@@ -294,6 +320,11 @@ class Visualization {
     }
 
 
+    /**
+     * Reinitialize the scene (basicaly rerun the simulation to place interaction partners)
+     *
+     * @memberof Visualization
+     */
     public reinitialize() {
         if (this.depiction === undefined) this.setupScene();
         else this.setupLigandScene();
@@ -301,31 +332,10 @@ class Visualization {
         this.hideLigandLabel();
     }
 
-    private resize() {
-        this.svg
-            .attr('width', this.parent.offsetWidth)
-            .attr('height', this.parent.offsetHeight);
-
-        if (this.depiction === undefined) {
-            this.simulation
-                .force('center', d3.forceCenter(this.parent.offsetWidth / 2, this.parent.offsetHeight / 2))
-                .restart();
-        } else this.simulation.restart();
-
-        if (this.zoomHandler !== undefined) this.zoomHandler(this.svg);
-    }
-
-    private getSVGName(): string {
-        if (this.bindingSite !== undefined) return `${this.bindingSite.bmId}.svg`;
-        if (this.depiction !== undefined) return `${this.depiction.ccdId}.svg`;
-
-        return 'no name.svg';
-    }
-
 
 
     /**
-     * Center the scene around ligand or interactions.
+     * Center scene to the viewbox
      *
      * @memberof Visualization
      */
@@ -382,8 +392,32 @@ class Visualization {
         this.zoomHandler?.transform(this.svg, translation);
 
     };
+
     // #endregion menu functions
 
+    // #endregion public methods
+
+    private resize() {
+        this.svg
+            .attr('width', this.parent.offsetWidth)
+            .attr('height', this.parent.offsetHeight);
+
+        if (this.depiction === undefined) {
+            this.simulation
+                .force('center', d3.forceCenter(this.parent.offsetWidth / 2, this.parent.offsetHeight / 2))
+                .restart();
+        } else this.simulation.restart();
+
+        if (this.zoomHandler !== undefined) this.zoomHandler(this.svg);
+    }
+
+    private getSVGName(): string {
+        if (this.bindingSite !== undefined) return `${this.bindingSite.bmId}.svg`;
+        if (this.depiction !== undefined) return `${this.depiction.ccdId}.svg`;
+
+        return 'no name.svg';
+    }
+
     // #region fire events
 
     //https://stackoverflow.com/questions/40722344/understanding-d3-with-an-example-mouseover-mouseup-with-multiple-arguments
-- 
GitLab


From fe507b3225d5c9c314cc6d3dd970792250cc0173 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 24 Jan 2020 14:20:22 +0000
Subject: [PATCH 14/66] refactoring of the repository structure

---
 .gitignore                                    |    3 +-
 .gitlab-ci.yml                                |    3 +-
 build/index.html                              |    8 +-
 dependencies/het_mapping.json                 |  307 ++++
 dependencies/index.html                       |  138 ++
 .../snfg_visuals.xml                          |    0
 gulpfile.js                                   |   74 +
 package-lock.json                             | 1357 ++++++++++++++++-
 package.json                                  |   20 +-
 src/{ => component}/component.js              |    2 +-
 src/{ => plugin}/config.ts                    |    4 +-
 src/{ => plugin}/depiction.ts                 |    0
 src/{ => plugin}/manager.ts                   |    2 +-
 src/{ => plugin}/model.ts                     |    0
 src/{ => plugin}/ui.ts                        |    1 +
 src/{ => plugin}/visualsMapping.ts            |    0
 .../styles/pdbe-interactions-svg.css          |    0
 .../styles/pdbe-interactions.css              |    0
 tsconfig.json                                 |    4 +-
 webpack.config.js                             |   28 +-
 20 files changed, 1913 insertions(+), 38 deletions(-)
 create mode 100644 dependencies/het_mapping.json
 create mode 100644 dependencies/index.html
 rename build/visuals.xml => dependencies/snfg_visuals.xml (100%)
 create mode 100644 gulpfile.js
 rename src/{ => component}/component.js (98%)
 rename src/{ => plugin}/config.ts (91%)
 rename src/{ => plugin}/depiction.ts (100%)
 rename src/{ => plugin}/manager.ts (99%)
 rename src/{ => plugin}/model.ts (100%)
 rename src/{ => plugin}/ui.ts (99%)
 rename src/{ => plugin}/visualsMapping.ts (100%)
 rename build/pdbe-interactions-svgstyles.css => src/styles/pdbe-interactions-svg.css (100%)
 rename build/pdbe-interactions-styles.css => src/styles/pdbe-interactions.css (100%)

diff --git a/.gitignore b/.gitignore
index eca9dd3..517220d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,4 @@
 .mypy_cache
 node_modules
 
-build/*.js*
-build/app*
\ No newline at end of file
+build/*
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cb69204..086d8e6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,8 +3,7 @@ image: node:latest
 before_script:
   - npm install
   - npm install --save-dev webpack
-  - node_modules/.bin/webpack --mode=production
-  - node_modules/.bin/tsc
+  - npm run buildProduction
 
 pages:
   script:
diff --git a/build/index.html b/build/index.html
index 293a138..ce450b5 100644
--- a/build/index.html
+++ b/build/index.html
@@ -3,8 +3,8 @@
 <script src="https://d3js.org/d3.v5.min.js"></script>
 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
 <!--testing purposes only-->
-<link rel="stylesheet" href="pdbe-interactions-styles.css" />
-<link rel="stylesheet" href="pdbe-interactions-svgstyles.css" />
+<!-- <link rel="stylesheet" href="pdbe-interactions-styles.css" /> -->
+<link rel="stylesheet" href="pdbe-interactions-svg.css" />
 <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
 <!-- MOL* -->
@@ -12,7 +12,7 @@
     href="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/css/molstar-light-0.0.1.css">
 <script src="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/js/molstar-0.0.1.js"></script>
 
-<script src="app.js"></script>
+<!-- <script src="pdbe-interactions-plugin.js"></script> -->
 
 <!-- Web component polyfill (only loads what it needs) -->
 <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8">
@@ -21,7 +21,7 @@
 <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
     charset="utf-8"></script>
 
-<script type="module" src="component.js"></script>
+<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
 <script>
     var renderBmInteractions = function (id, bmId) {
         var int = `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
diff --git a/dependencies/het_mapping.json b/dependencies/het_mapping.json
new file mode 100644
index 0000000..f9bae8d
--- /dev/null
+++ b/dependencies/het_mapping.json
@@ -0,0 +1,307 @@
+[
+    {
+        "name": "Abe",
+        "het_codes": [
+            "ABE"
+        ]
+    },
+    {
+        "name": "All",
+        "het_codes": [
+            "ALL",
+            "AFD"
+        ]
+    },
+    {
+        "name": "AllNAc",
+        "het_codes": [
+            "NAA"
+        ]
+    },
+    {
+        "name": "Alt",
+        "het_codes": [
+            "SHD"
+        ]
+    },
+    {
+        "name": "Api",
+        "het_codes": [
+            "XXM"
+        ]
+    },
+    {
+        "name": "Ara",
+        "het_codes": [
+            "ARA",
+            "ARB"
+        ]
+    },
+    {
+        "name": "Bac",
+        "het_codes": [
+            "B6D"
+        ]
+    },
+    {
+        "name": "DDManHep",
+        "het_codes": [
+            "289"
+        ]
+    },
+    {
+        "name": "Fru",
+        "het_codes": [
+            "BDF"
+        ]
+    },
+    {
+        "name": "Fuc",
+        "het_codes": [
+            "FUC",
+            "FUL"
+        ]
+    },
+    {
+        "name": "Gal",
+        "het_codes": [
+            "GAL",
+            "GLA"
+        ]
+    },
+    {
+        "name": "GalA",
+        "het_codes": [
+            "ADA",
+            "GTR"
+        ]
+    },
+    {
+        "name": "GalN",
+        "het_codes": [
+            "X6X",
+            "1GN"
+        ]
+    },
+    {
+        "name": "GalNAc",
+        "het_codes": [
+            "NGA",
+            "A2G"
+        ]
+    },
+    {
+        "name": "Glc",
+        "het_codes": [
+            "GLC",
+            "BGC"
+        ]
+    },
+    {
+        "name": "GlcA",
+        "het_codes": [
+            "GCU",
+            "BDP"
+        ]
+    },
+    {
+        "name": "GlcN",
+        "het_codes": [
+            "GCS",
+            "PA1"
+        ]
+    },
+    {
+        "name": "GlcNAc",
+        "het_codes": [
+            "NAG",
+            "NDG"
+        ]
+    },
+    {
+        "name": "Gul",
+        "het_codes": [
+            "GUP",
+            "GL0"
+        ]
+    },
+    {
+        "name": "GulA",
+        "het_codes": [
+            "LGU"
+        ]
+    },
+    {
+        "name": "GulNAc",
+        "het_codes": [
+            "LXB"
+        ]
+    },
+    {
+        "name": "Ido",
+        "het_codes": [
+            "4N2"
+        ]
+    },
+    {
+        "name": "IdoA",
+        "het_codes": [
+            "IDR"
+        ]
+    },
+    {
+        "name": "IdoNAc",
+        "het_codes": [
+            "HSQ"
+        ]
+    },
+    {
+        "name": "Kdn",
+        "het_codes": [
+            "KDN",
+            "KDM"
+        ]
+    },
+    {
+        "name": "Kdo",
+        "het_codes": [
+            "KDO"
+        ]
+    },
+    {
+        "name": "LDManHep",
+        "het_codes": [
+            "GMH"
+        ]
+    },
+    {
+        "name": "Lyx",
+        "het_codes": [
+            "LDY"
+        ]
+    },
+    {
+        "name": "Man",
+        "het_codes": [
+            "MAN",
+            "BMA"
+        ]
+    },
+    {
+        "name": "ManA",
+        "het_codes": [
+            "MAV",
+            "BEM"
+        ]
+    },
+    {
+        "name": "ManN",
+        "het_codes": [
+            "95Z"
+        ]
+    },
+    {
+        "name": "ManNAc",
+        "het_codes": [
+            "BM3",
+            "BM7"
+        ]
+    },
+    {
+        "name": "Mur",
+        "het_codes": [
+            "MUR"
+        ]
+    },
+    {
+        "name": "MurNAc",
+        "het_codes": [
+            "AMU",
+            "MUB"
+        ]
+    },
+    {
+        "name": "Neu5Ac",
+        "het_codes": [
+            "SIA",
+            "SLB"
+        ]
+    },
+    {
+        "name": "Neu5Gc",
+        "het_codes": [
+            "NGC",
+            "NGE"
+        ]
+    },
+    {
+        "name": "Oli",
+        "het_codes": [
+            "DDA"
+        ]
+    },
+    {
+        "name": "Par",
+        "het_codes": [
+            "PZU"
+        ]
+    },
+    {
+        "name": "Pse",
+        "het_codes": [
+            "6PZ"
+        ]
+    },
+    {
+        "name": "Qui",
+        "het_codes": [
+            "G6D"
+        ]
+    },
+    {
+        "name": "Rha",
+        "het_codes": [
+            "RAM",
+            "RM4"
+        ]
+    },
+    {
+        "name": "Rib",
+        "het_codes": [
+            "RIP",
+            "0MK"
+        ]
+    },
+    {
+        "name": "Sor",
+        "het_codes": [
+            "SOE"
+        ]
+    },
+    {
+        "name": "Tag",
+        "het_codes": [
+            "T6T"
+        ]
+    },
+    {
+        "name": "TalA",
+        "het_codes": [
+            "X0X",
+            "X1X"
+        ]
+    },
+    {
+        "name": "Tyv",
+        "het_codes": [
+            "TYV"
+        ]
+    },
+    {
+        "name": "Xyl",
+        "het_codes": [
+            "XYS",
+            "XYP"
+        ]
+    }
+]
\ No newline at end of file
diff --git a/dependencies/index.html b/dependencies/index.html
new file mode 100644
index 0000000..ce450b5
--- /dev/null
+++ b/dependencies/index.html
@@ -0,0 +1,138 @@
+<!doctype html>
+<html lang="en">
+<script src="https://d3js.org/d3.v5.min.js"></script>
+<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
+<!--testing purposes only-->
+<!-- <link rel="stylesheet" href="pdbe-interactions-styles.css" /> -->
+<link rel="stylesheet" href="pdbe-interactions-svg.css" />
+<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
+
+<!-- MOL* -->
+<link rel="stylesheet" type="text/css"
+    href="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/css/molstar-light-0.0.1.css">
+<script src="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/js/molstar-0.0.1.js"></script>
+
+<!-- <script src="pdbe-interactions-plugin.js"></script> -->
+
+<!-- Web component polyfill (only loads what it needs) -->
+<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8">
+</script>
+<!-- Required to polyfill modern browsers as code is ES5 for IE... -->
+<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
+    charset="utf-8"></script>
+
+<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+<script>
+    var renderBmInteractions = function (id, bmId) {
+        var int = `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
+        document.getElementById('rt').innerHTML = int;
+    };
+
+    var renderLigandInteractions = function (id, chain, resId) {
+        var int =
+            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-interactions>`
+        document.getElementById('rt').innerHTML = int;
+    };
+
+    var parseParameters = function (par) {
+        let result = {}
+
+        par.split('&').forEach(x => {
+            let splitted = x.split('=');
+            result[splitted[0].toLowerCase()] = splitted[1].toLowerCase();
+        });
+
+        if (result.bmid === undefined) {
+            result['query'] =
+                `https://wwwdev.ebi.ac.uk/pdbe/coordinates/${result.pdbid}/ligandInteraction?&authAsymId=$${result.chain}&authSeqNumber=${result.resid}&radius=5&dataSource=hydrogens`
+        } else {
+            result['query'] = `https://wwwdev.ebi.ac.uk/pdbe/coordinates/${result.pdbid}?dataSource=hydrogens`
+        }
+
+        if (result.chain !== undefined) result.chain = result.chain.toUpperCase();
+
+        return result;
+    };
+
+    (function () {
+        'use strict';
+        $(document)
+            .ready(function ($http) {
+                var tokens = window.location.href.split('/').reverse();
+                let params = {};
+
+                if (tokens[0].startsWith('?')) {
+                    params = parseParameters(tokens[0].slice(1));
+                } else {
+                    params = {
+                        pdbid: '1cbs',
+                        chain: 'A',
+                        resid: 200,
+                        query: "https://wwwdev.ebi.ac.uk/pdbe/coordinates/1cbs/ligandInteraction?&authAsymId=$A&authSeqNumber=$200&radius=5&dataSource=hydrogens"
+                    };
+                }
+
+                if (params.bmid === undefined) {
+                    renderLigandInteractions(params.pdbid, params.chain, params.resid);
+                } else {
+                    renderBmInteractions(params.pdbid, params.bmid);
+                }
+
+                var initParams = {
+                    moleculeId: params.pdbid,
+                    pdbeUrl: 'https://wwwdev.ebi.ac.uk/pdbe/',
+                    loadMaps: true,
+                    validationAnnotation: true,
+                    domainAnnotation: true,
+                    lowPrecisionCoords: true,
+                    isExpanded: false,
+                    hideControls: true,
+                    showLogs: false,
+                    subscribeEvents: true,
+                    showPDBeLogo: false,
+                    assemblyId: 'preferred', //'deposited'
+                    // selectInteraction: false,
+                    ligandView: {auth_asym_Id: params.chain, auth_seq_id: params.resid, hydrogens: true},
+                    backgroundColour: '0xFFFFFF',
+                    //customColorList: [0xff0000, 0x0000ff],
+                    //representationStyle: representationStyle//,
+                    // customData: {
+                    //     url: `https://wwwdev.ebi.ac.uk/pdbe/coordinates/${params.pdbid}/ligandInteraction?&authAsymId=${params.chain}&authSeqNumber=${params.resid}&radius=5&dataSource=hydrogens`,
+                    //     format: 'cif'
+                    // }
+                }
+                var pdbeMolstar = new MolStarPdbeWrapper();
+                pdbeMolstar.render(document.getElementById('3dViewer'), initParams);
+            });
+    }());
+</script>
+
+
+<body>
+    <div style="position: relative; float: left;">
+        <div id="rt" style="width: 500px; height: 500px; position: relative">
+        </div>
+    </div>
+    <div style="position: relative; float: left;">
+        <div id='3dViewer' style="position:relative; width: 500px;height: 500px;"></div>
+    </div>
+    <div style="position: relative; float: left;">
+        <div id="rt 1" style="width: 500px; height: 500px; position: relative">
+            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-interactions>
+        </div>
+    </div>
+
+    <!--
+        Further use in the app for bound molecule interactions:
+        
+        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+        
+        for ligand interactions:
+        <pdb-interactions pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdb-interactions>
+    -->
+    <script>
+
+    </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/build/visuals.xml b/dependencies/snfg_visuals.xml
similarity index 100%
rename from build/visuals.xml
rename to dependencies/snfg_visuals.xml
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000..8793dfc
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,74 @@
+var gulp = require('gulp');
+const path = require('path');
+var del = require('del');
+var concat = require('gulp-concat');
+var header = require('gulp-header');
+
+const PACKAGE_ROOT_PATH = process.cwd();
+const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
+
+const banner = ['/**',
+  ` * ${PKG_JSON.name}`,
+  ` * @version ${PKG_JSON.version}`,
+  ' * @link https://github.com/PDBeurope/pdbe-molstar',
+  ' * @license Apache 2.0',
+  ' */',
+  ''].join('\n');
+
+  const license = ['/**',
+  ' * Copyright 2019-2020 Mandar Deshpande <mandar@ebi.ac.uk>',
+  ' * European Bioinformatics Institute (EBI, http://www.ebi.ac.uk/)',
+  ' * European Molecular Biology Laboratory (EMBL, http://www.embl.de/)',
+  ' * Licensed under the Apache License, Version 2.0 (the "License");',
+  ' * you may not use this file except in compliance with the License.',
+  ' * You may obtain a copy of the License at ',
+  ' * http://www.apache.org/licenses/LICENSE-2.0',
+  ' * ',
+  ' * Unless required by applicable law or agreed to in writing, software',
+  ' * distributed under the License is distributed on an "AS IS" BASIS, ',
+  ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
+  ' * See the License for the specific language governing permissions and ',
+  ' * limitations under the License.',
+  ' */',
+  ''].join('\n');
+
+
+gulp.task('clean', function() {
+    return del([`build/${PKG_JSON.name}-component-${PKG_JSON.version}.js`, '!build']);
+});
+
+gulp.task('concatCSS', function () {
+    return gulp.src(['src/styles/pdbe-interactions-svg.css'])
+        .pipe(concat(`${PKG_JSON.name}-svg.css`))
+        .pipe(header(license, {} ))
+		.pipe(header(banner, {} ))
+        .pipe(gulp.dest('build/'));
+});
+
+gulp.task('copyIndex', function () {
+    return gulp.src(['dependencies/index.html'])
+        .pipe(concat(`index.html`))
+        .pipe(gulp.dest('build/'));
+});
+
+gulp.task('copyMapping', function () {
+    return gulp.src(['dependencies/het_mapping.json'])
+        .pipe(concat(`het_mapping.json`))
+        .pipe(gulp.dest('build/'));
+});
+
+gulp.task('copyXML', function () {
+    return gulp.src(['dependencies/snfg_visuals.xml'])
+        .pipe(concat(`snfg_visuals.xml`))
+        .pipe(gulp.dest('build/'));
+});
+
+gulp.task('concat', function () {
+    return gulp.src([`build/${PKG_JSON.name}-plugin.js`,`build/${PKG_JSON.name}-component-init.js`])
+        .pipe(concat(`${PKG_JSON.name}-component-${PKG_JSON.version}.js`))
+        .pipe(header(license, {} ))
+		.pipe(header(banner, {} ))
+        .pipe(gulp.dest('build/'));
+});
+
+gulp.task('default', gulp.series('clean', 'concat', 'concatCSS', 'copyXML', 'copyIndex', 'copyMapping'));
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 4b675eb..162131c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
-  "name": "interactions",
-  "version": "1.0.0",
+  "name": "pdbe-interactions",
+  "version": "0.1.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -887,6 +887,32 @@
         "to-fast-properties": "^2.0.0"
       }
     },
+    "@nodelib/fs.scandir": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "2.0.3",
+        "run-parallel": "^1.1.9"
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+      "dev": true
+    },
+    "@nodelib/fs.walk": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.3",
+        "fastq": "^1.6.0"
+      }
+    },
     "@types/d3": {
       "version": "5.7.2",
       "resolved": "https://registry.npmjs.org/@types/d3/-/d3-5.7.2.tgz",
@@ -1130,11 +1156,40 @@
         "@types/d3-selection": "*"
       }
     },
+    "@types/events": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+      "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+      "dev": true
+    },
     "@types/geojson": {
       "version": "7946.0.7",
       "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
       "integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ=="
     },
+    "@types/glob": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+      "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+      "dev": true,
+      "requires": {
+        "@types/events": "*",
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "13.5.0",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-13.5.0.tgz",
+      "integrity": "sha512-Onhn+z72D2O2Pb2ql2xukJ55rglumsVo1H6Fmyi8mlU9SvKdBk/pUSUAiBY/d9bAOF7VVWajX3sths/+g6ZiAQ==",
+      "dev": true
+    },
     "@webassemblyjs/ast": {
       "version": "1.8.5",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@@ -1368,6 +1423,16 @@
       "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
       "dev": true
     },
+    "aggregate-error": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
+      "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      }
+    },
     "ajv": {
       "version": "6.10.0",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
@@ -1392,12 +1457,30 @@
       "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==",
       "dev": true
     },
+    "ansi-colors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+      "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "^0.1.0"
+      }
+    },
     "ansi-escapes": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
       "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
       "dev": true
     },
+    "ansi-gray": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+      "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
     "ansi-regex": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
@@ -1413,6 +1496,12 @@
         "color-convert": "^1.9.0"
       }
     },
+    "ansi-wrap": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+      "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+      "dev": true
+    },
     "anymatch": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
@@ -1449,12 +1538,27 @@
       "integrity": "sha1-7klza2ObTxCLbp5ibG2pkwa0FpI=",
       "dev": true
     },
+    "append-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+      "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+      "dev": true,
+      "requires": {
+        "buffer-equal": "^1.0.0"
+      }
+    },
     "aproba": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
       "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
       "dev": true
     },
+    "archy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+      "dev": true
+    },
     "argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -1470,24 +1574,83 @@
       "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
       "dev": true
     },
+    "arr-filter": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+      "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
+      "dev": true,
+      "requires": {
+        "make-iterator": "^1.0.0"
+      }
+    },
     "arr-flatten": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
       "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
       "dev": true
     },
+    "arr-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+      "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+      "dev": true,
+      "requires": {
+        "make-iterator": "^1.0.0"
+      }
+    },
     "arr-union": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
       "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
       "dev": true
     },
+    "array-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+      "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+      "dev": true
+    },
     "array-filter": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
       "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=",
       "dev": true
     },
+    "array-initial": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+      "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+      "dev": true,
+      "requires": {
+        "array-slice": "^1.0.0",
+        "is-number": "^4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "array-last": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+      "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+      "dev": true,
+      "requires": {
+        "is-number": "^4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
     "array-map": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
@@ -1500,6 +1663,37 @@
       "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=",
       "dev": true
     },
+    "array-slice": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+      "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+      "dev": true
+    },
+    "array-sort": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+      "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+      "dev": true,
+      "requires": {
+        "default-compare": "^1.0.0",
+        "get-value": "^2.0.6",
+        "kind-of": "^5.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true
+    },
     "array-unique": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
@@ -1568,6 +1762,18 @@
       "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
       "dev": true
     },
+    "async-done": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
+      "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.2",
+        "process-nextick-args": "^2.0.0",
+        "stream-exhaust": "^1.0.1"
+      }
+    },
     "async-each": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
@@ -1586,6 +1792,15 @@
       "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==",
       "dev": true
     },
+    "async-settle": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+      "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+      "dev": true,
+      "requires": {
+        "async-done": "^1.2.2"
+      }
+    },
     "atob": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@@ -1675,6 +1890,23 @@
         "object.assign": "^4.1.0"
       }
     },
+    "bach": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+      "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+      "dev": true,
+      "requires": {
+        "arr-filter": "^1.1.1",
+        "arr-flatten": "^1.0.1",
+        "arr-map": "^2.0.0",
+        "array-each": "^1.0.0",
+        "array-initial": "^1.0.0",
+        "array-last": "^1.1.1",
+        "async-done": "^1.2.2",
+        "async-settle": "^1.0.0",
+        "now-and-later": "^2.0.0"
+      }
+    },
     "backo2": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
@@ -2042,6 +2274,12 @@
         }
       }
     },
+    "buffer-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+      "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+      "dev": true
+    },
     "buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@@ -2253,6 +2491,12 @@
         }
       }
     },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
     "clean-webpack-plugin": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-1.0.1.tgz",
@@ -2288,6 +2532,35 @@
         "wrap-ansi": "^2.0.0"
       }
     },
+    "clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+      "dev": true
+    },
+    "clone-buffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+      "dev": true
+    },
+    "clone-stats": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+      "dev": true
+    },
+    "cloneable-readable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+      "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "process-nextick-args": "^2.0.0",
+        "readable-stream": "^2.3.5"
+      }
+    },
     "co": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -2300,6 +2573,17 @@
       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
       "dev": true
     },
+    "collection-map": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+      "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
+      "dev": true,
+      "requires": {
+        "arr-map": "^2.0.2",
+        "for-own": "^1.0.0",
+        "make-iterator": "^1.0.0"
+      }
+    },
     "collection-visit": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
@@ -2325,6 +2609,12 @@
       "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
       "dev": true
     },
+    "color-support": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+      "dev": true
+    },
     "colors": {
       "version": "1.3.3",
       "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
@@ -2378,6 +2668,23 @@
         "typedarray": "^0.0.6"
       }
     },
+    "concat-with-sourcemaps": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz",
+      "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
     "connect": {
       "version": "3.6.6",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
@@ -2460,6 +2767,16 @@
       "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
       "dev": true
     },
+    "copy-props": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
+      "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
+      "dev": true,
+      "requires": {
+        "each-props": "^1.3.0",
+        "is-plain-object": "^2.0.1"
+      }
+    },
     "core-js-compat": {
       "version": "3.6.4",
       "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz",
@@ -2592,6 +2909,16 @@
       "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
       "dev": true
     },
+    "d": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+      "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+      "dev": true,
+      "requires": {
+        "es5-ext": "^0.10.50",
+        "type": "^1.0.1"
+      }
+    },
     "d3": {
       "version": "5.15.0",
       "resolved": "https://registry.npmjs.org/d3/-/d3-5.15.0.tgz",
@@ -3157,6 +3484,29 @@
       "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
       "dev": true
     },
+    "default-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+      "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^5.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "default-resolution": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+      "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
+      "dev": true
+    },
     "define-properties": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -3207,6 +3557,39 @@
         }
       }
     },
+    "del": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
+      "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
+      "dev": true,
+      "requires": {
+        "globby": "^10.0.1",
+        "graceful-fs": "^4.2.2",
+        "is-glob": "^4.0.1",
+        "is-path-cwd": "^2.2.0",
+        "is-path-inside": "^3.0.1",
+        "p-map": "^3.0.0",
+        "rimraf": "^3.0.0",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        },
+        "rimraf": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
+          "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        }
+      }
+    },
     "depd": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -3258,6 +3641,23 @@
         "randombytes": "^2.0.0"
       }
     },
+    "dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "requires": {
+        "path-type": "^4.0.0"
+      },
+      "dependencies": {
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+          "dev": true
+        }
+      }
+    },
     "doctrine": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
@@ -3291,6 +3691,16 @@
         "stream-shift": "^1.0.0"
       }
     },
+    "each-props": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+      "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+      "dev": true,
+      "requires": {
+        "is-plain-object": "^2.0.1",
+        "object.defaults": "^1.1.0"
+      }
+    },
     "easy-extender": {
       "version": "2.3.4",
       "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz",
@@ -3508,6 +3918,50 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "es5-ext": {
+      "version": "0.10.53",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+      "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.3",
+        "next-tick": "~1.0.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+      "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+      "dev": true,
+      "requires": {
+        "d": "^1.0.1",
+        "ext": "^1.1.2"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
+      "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.46",
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.1"
+      }
+    },
     "escape-html": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -3810,6 +4264,29 @@
         "homedir-polyfill": "^1.0.1"
       }
     },
+    "ext": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+      "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+      "dev": true,
+      "requires": {
+        "type": "^2.0.0"
+      },
+      "dependencies": {
+        "type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
+          "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==",
+          "dev": true
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
     "extend-shallow": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
@@ -3907,12 +4384,91 @@
         }
       }
     },
+    "fancy-log": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+      "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
+      "dev": true,
+      "requires": {
+        "ansi-gray": "^0.1.1",
+        "color-support": "^1.1.3",
+        "parse-node-version": "^1.0.0",
+        "time-stamp": "^1.0.0"
+      }
+    },
     "fast-deep-equal": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
       "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
       "dev": true
     },
+    "fast-glob": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz",
+      "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.0",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.2"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "glob-parent": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+          "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+          "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@@ -3925,6 +4481,15 @@
       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
       "dev": true
     },
+    "fastq": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
+      "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
+      "dev": true,
+      "requires": {
+        "reusify": "^1.0.0"
+      }
+    },
     "faye-websocket": {
       "version": "0.11.1",
       "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
@@ -4056,6 +4621,25 @@
         "resolve-dir": "^1.0.1"
       }
     },
+    "fined": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
+      "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.2",
+        "is-plain-object": "^2.0.3",
+        "object.defaults": "^1.1.0",
+        "object.pick": "^1.2.0",
+        "parse-filepath": "^1.0.1"
+      }
+    },
+    "flagged-respawn": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+      "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+      "dev": true
+    },
     "flat-cache": {
       "version": "1.3.4",
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
@@ -4110,6 +4694,15 @@
       "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
       "dev": true
     },
+    "for-own": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.1"
+      }
+    },
     "fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -4152,6 +4745,16 @@
         "universalify": "^0.1.0"
       }
     },
+    "fs-mkdirp-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+      "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "through2": "^2.0.3"
+      }
+    },
     "fs-write-stream-atomic": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -4792,6 +5395,38 @@
         }
       }
     },
+    "glob-stream": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+      "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
+      "dev": true,
+      "requires": {
+        "extend": "^3.0.0",
+        "glob": "^7.1.1",
+        "glob-parent": "^3.1.0",
+        "is-negated-glob": "^1.0.0",
+        "ordered-read-streams": "^1.0.0",
+        "pumpify": "^1.3.5",
+        "readable-stream": "^2.1.5",
+        "remove-trailing-separator": "^1.0.1",
+        "to-absolute-glob": "^2.0.0",
+        "unique-stream": "^2.0.2"
+      }
+    },
+    "glob-watcher": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
+      "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==",
+      "dev": true,
+      "requires": {
+        "anymatch": "^2.0.0",
+        "async-done": "^1.2.0",
+        "chokidar": "^2.0.0",
+        "is-negated-glob": "^1.0.0",
+        "just-debounce": "^1.0.0",
+        "object.defaults": "^1.1.0"
+      }
+    },
     "global-modules": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
@@ -4833,12 +5468,161 @@
       "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
       "dev": true
     },
+    "globby": {
+      "version": "10.0.2",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
+      "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.0.3",
+        "glob": "^7.1.3",
+        "ignore": "^5.1.1",
+        "merge2": "^1.2.3",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "ignore": {
+          "version": "5.1.4",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+          "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+          "dev": true
+        }
+      }
+    },
+    "glogg": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
+      "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+      "dev": true,
+      "requires": {
+        "sparkles": "^1.0.0"
+      }
+    },
     "graceful-fs": {
       "version": "4.1.15",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
       "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
       "dev": true
     },
+    "gulp": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
+      "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+      "dev": true,
+      "requires": {
+        "glob-watcher": "^5.0.3",
+        "gulp-cli": "^2.2.0",
+        "undertaker": "^1.2.1",
+        "vinyl-fs": "^3.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+          "dev": true
+        },
+        "gulp-cli": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz",
+          "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==",
+          "dev": true,
+          "requires": {
+            "ansi-colors": "^1.0.1",
+            "archy": "^1.0.0",
+            "array-sort": "^1.0.0",
+            "color-support": "^1.1.3",
+            "concat-stream": "^1.6.0",
+            "copy-props": "^2.0.1",
+            "fancy-log": "^1.3.2",
+            "gulplog": "^1.0.0",
+            "interpret": "^1.1.0",
+            "isobject": "^3.0.1",
+            "liftoff": "^3.1.0",
+            "matchdep": "^2.0.0",
+            "mute-stdout": "^1.0.0",
+            "pretty-hrtime": "^1.0.0",
+            "replace-homedir": "^1.0.0",
+            "semver-greatest-satisfied-range": "^1.1.0",
+            "v8flags": "^3.0.1",
+            "yargs": "^7.1.0"
+          }
+        },
+        "yargs": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+          "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+          "dev": true,
+          "requires": {
+            "camelcase": "^3.0.0",
+            "cliui": "^3.2.0",
+            "decamelize": "^1.1.1",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^1.4.0",
+            "read-pkg-up": "^1.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^1.0.2",
+            "which-module": "^1.0.0",
+            "y18n": "^3.2.1",
+            "yargs-parser": "^5.0.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+          "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+          "dev": true,
+          "requires": {
+            "camelcase": "^3.0.0"
+          }
+        }
+      }
+    },
+    "gulp-concat": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz",
+      "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=",
+      "dev": true,
+      "requires": {
+        "concat-with-sourcemaps": "^1.0.0",
+        "through2": "^2.0.0",
+        "vinyl": "^2.0.0"
+      }
+    },
+    "gulp-header": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-2.0.9.tgz",
+      "integrity": "sha512-LMGiBx+qH8giwrOuuZXSGvswcIUh0OiioNkUpLhNyvaC6/Ga8X6cfAeme2L5PqsbXMhL8o8b/OmVqIQdxprhcQ==",
+      "dev": true,
+      "requires": {
+        "concat-with-sourcemaps": "^1.1.0",
+        "lodash.template": "^4.5.0",
+        "map-stream": "0.0.7",
+        "through2": "^2.0.0"
+      },
+      "dependencies": {
+        "map-stream": {
+          "version": "0.0.7",
+          "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
+          "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
+          "dev": true
+        }
+      }
+    },
+    "gulplog": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+      "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+      "dev": true,
+      "requires": {
+        "glogg": "^1.0.0"
+      }
+    },
     "has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -5080,6 +5864,12 @@
       "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
       "dev": true
     },
+    "indent-string": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+      "dev": true
+    },
     "indexes-of": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
@@ -5196,6 +5986,16 @@
       "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
       "dev": true
     },
+    "is-absolute": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+      "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+      "dev": true,
+      "requires": {
+        "is-relative": "^1.0.0",
+        "is-windows": "^1.0.1"
+      }
+    },
     "is-accessor-descriptor": {
       "version": "0.1.6",
       "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
@@ -5318,6 +6118,12 @@
         "is-extglob": "^2.1.1"
       }
     },
+    "is-negated-glob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+      "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+      "dev": true
+    },
     "is-number": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
@@ -5347,6 +6153,18 @@
         "lodash.isfinite": "^3.3.2"
       }
     },
+    "is-path-cwd": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+      "dev": true
+    },
+    "is-path-inside": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+      "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+      "dev": true
+    },
     "is-plain-object": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -5371,6 +6189,15 @@
         "has": "^1.0.1"
       }
     },
+    "is-relative": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+      "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+      "dev": true,
+      "requires": {
+        "is-unc-path": "^1.0.0"
+      }
+    },
     "is-resolvable": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
@@ -5392,12 +6219,27 @@
         "has-symbols": "^1.0.0"
       }
     },
+    "is-unc-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+      "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+      "dev": true,
+      "requires": {
+        "unc-path-regex": "^0.1.2"
+      }
+    },
     "is-utf8": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
       "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
       "dev": true
     },
+    "is-valid-glob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+      "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
+      "dev": true
+    },
     "is-windows": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
@@ -5492,12 +6334,37 @@
       "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
       "dev": true
     },
+    "just-debounce": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
+      "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
+      "dev": true
+    },
     "kind-of": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
       "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
       "dev": true
     },
+    "last-run": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
+      "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
+      "dev": true,
+      "requires": {
+        "default-resolution": "^2.0.0",
+        "es6-weak-map": "^2.0.1"
+      }
+    },
+    "lazystream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+      "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.5"
+      }
+    },
     "lcid": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
@@ -5507,6 +6374,15 @@
         "invert-kv": "^1.0.0"
       }
     },
+    "lead": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+      "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
+      "dev": true,
+      "requires": {
+        "flush-write-stream": "^1.0.2"
+      }
+    },
     "leven": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -5532,6 +6408,22 @@
         "type-check": "~0.3.2"
       }
     },
+    "liftoff": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
+      "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
+      "dev": true,
+      "requires": {
+        "extend": "^3.0.0",
+        "findup-sync": "^3.0.0",
+        "fined": "^1.0.1",
+        "flagged-respawn": "^1.0.0",
+        "is-plain-object": "^2.0.4",
+        "object.map": "^1.0.0",
+        "rechoir": "^0.6.2",
+        "resolve": "^1.1.7"
+      }
+    },
     "limiter": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz",
@@ -5745,12 +6637,37 @@
       "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
       "dev": true
     },
+    "lodash._reinterpolate": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
+      "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
+      "dev": true
+    },
     "lodash.isfinite": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz",
       "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=",
       "dev": true
     },
+    "lodash.template": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
+      "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
+      "dev": true,
+      "requires": {
+        "lodash._reinterpolate": "^3.0.0",
+        "lodash.templatesettings": "^4.0.0"
+      }
+    },
+    "lodash.templatesettings": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
+      "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
+      "dev": true,
+      "requires": {
+        "lodash._reinterpolate": "^3.0.0"
+      }
+    },
     "loose-envify": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@@ -5786,6 +6703,15 @@
       "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
       "dev": true
     },
+    "make-iterator": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+      "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^6.0.2"
+      }
+    },
     "mamacro": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
@@ -5822,6 +6748,41 @@
         "object-visit": "^1.0.0"
       }
     },
+    "matchdep": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
+      "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
+      "dev": true,
+      "requires": {
+        "findup-sync": "^2.0.0",
+        "micromatch": "^3.0.4",
+        "resolve": "^1.4.0",
+        "stack-trace": "0.0.10"
+      },
+      "dependencies": {
+        "findup-sync": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+          "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+          "dev": true,
+          "requires": {
+            "detect-file": "^1.0.0",
+            "is-glob": "^3.1.0",
+            "micromatch": "^3.0.4",
+            "resolve-dir": "^1.0.1"
+          }
+        },
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.0"
+          }
+        }
+      }
+    },
     "md5.js": {
       "version": "1.3.5",
       "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -5868,6 +6829,12 @@
       "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
       "dev": true
     },
+    "merge2": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
+      "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
+      "dev": true
+    },
     "micromatch": {
       "version": "3.1.10",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@@ -6065,6 +7032,12 @@
       "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
       "dev": true
     },
+    "mute-stdout": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+      "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+      "dev": true
+    },
     "mute-stream": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
@@ -6115,6 +7088,12 @@
       "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
       "dev": true
     },
+    "next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
     "nice-try": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -6195,6 +7174,15 @@
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
       "dev": true
     },
+    "now-and-later": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
+      "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.2"
+      }
+    },
     "npm-run-all": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz",
@@ -6372,6 +7360,28 @@
         "object-keys": "^1.0.11"
       }
     },
+    "object.defaults": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+      "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+      "dev": true,
+      "requires": {
+        "array-each": "^1.0.1",
+        "array-slice": "^1.0.0",
+        "for-own": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+      "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
+      "dev": true,
+      "requires": {
+        "for-own": "^1.0.0",
+        "make-iterator": "^1.0.0"
+      }
+    },
     "object.pick": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@@ -6381,6 +7391,16 @@
         "isobject": "^3.0.1"
       }
     },
+    "object.reduce": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
+      "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
+      "dev": true,
+      "requires": {
+        "for-own": "^1.0.0",
+        "make-iterator": "^1.0.0"
+      }
+    },
     "on-finished": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -6443,6 +7463,15 @@
         "wordwrap": "~1.0.0"
       }
     },
+    "ordered-read-streams": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+      "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.1"
+      }
+    },
     "os-browserify": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
@@ -6500,6 +7529,15 @@
         "p-limit": "^2.0.0"
       }
     },
+    "p-map": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+      "dev": true,
+      "requires": {
+        "aggregate-error": "^3.0.0"
+      }
+    },
     "p-try": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -6537,6 +7575,17 @@
         "safe-buffer": "^5.1.1"
       }
     },
+    "parse-filepath": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+      "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+      "dev": true,
+      "requires": {
+        "is-absolute": "^1.0.0",
+        "map-cache": "^0.2.0",
+        "path-root": "^0.1.1"
+      }
+    },
     "parse-json": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
@@ -6546,6 +7595,12 @@
         "error-ex": "^1.2.0"
       }
     },
+    "parse-node-version": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+      "dev": true
+    },
     "parse-passwd": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
@@ -6624,6 +7679,21 @@
       "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
       "dev": true
     },
+    "path-root": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+      "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+      "dev": true,
+      "requires": {
+        "path-root-regex": "^0.1.0"
+      }
+    },
+    "path-root-regex": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+      "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+      "dev": true
+    },
     "path-type": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
@@ -6665,6 +7735,12 @@
         "sha.js": "^2.4.8"
       }
     },
+    "picomatch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
+      "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
+      "dev": true
+    },
     "pidtree": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz",
@@ -6814,6 +7890,12 @@
       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
       "dev": true
     },
+    "pretty-hrtime": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+      "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+      "dev": true
+    },
     "private": {
       "version": "0.1.8",
       "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
@@ -7046,6 +8128,15 @@
         "readable-stream": "^2.0.2"
       }
     },
+    "rechoir": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+      "dev": true,
+      "requires": {
+        "resolve": "^1.1.6"
+      }
+    },
     "regenerate": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
@@ -7129,6 +8220,27 @@
         }
       }
     },
+    "remove-bom-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+      "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+      "dev": true,
+      "requires": {
+        "is-buffer": "^1.1.5",
+        "is-utf8": "^0.2.1"
+      }
+    },
+    "remove-bom-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+      "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
+      "dev": true,
+      "requires": {
+        "remove-bom-buffer": "^3.0.0",
+        "safe-buffer": "^5.1.0",
+        "through2": "^2.0.3"
+      }
+    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -7147,6 +8259,23 @@
       "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
       "dev": true
     },
+    "replace-ext": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+      "dev": true
+    },
+    "replace-homedir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
+      "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1",
+        "is-absolute": "^1.0.0",
+        "remove-trailing-separator": "^1.1.0"
+      }
+    },
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -7230,6 +8359,15 @@
       "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
       "dev": true
     },
+    "resolve-options": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+      "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
+      "dev": true,
+      "requires": {
+        "value-or-function": "^3.0.0"
+      }
+    },
     "resolve-url": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -7279,6 +8417,12 @@
       "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
       "dev": true
     },
+    "reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true
+    },
     "rimraf": {
       "version": "2.6.3",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
@@ -7307,6 +8451,12 @@
         "is-promise": "^2.1.0"
       }
     },
+    "run-parallel": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+      "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
+      "dev": true
+    },
     "run-queue": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
@@ -7388,6 +8538,15 @@
       "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
       "dev": true
     },
+    "semver-greatest-satisfied-range": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+      "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+      "dev": true,
+      "requires": {
+        "sver-compat": "^1.5.0"
+      }
+    },
     "send": {
       "version": "0.16.2",
       "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
@@ -7614,6 +8773,12 @@
       "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
       "dev": true
     },
+    "slash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true
+    },
     "slice-ansi": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
@@ -7969,6 +9134,12 @@
       "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
       "dev": true
     },
+    "sparkles": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+      "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+      "dev": true
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -8034,6 +9205,12 @@
         "figgy-pudding": "^3.5.1"
       }
     },
+    "stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
+      "dev": true
+    },
     "static-extend": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
@@ -8090,6 +9267,12 @@
         "stream-shift": "^1.0.0"
       }
     },
+    "stream-exhaust": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+      "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+      "dev": true
+    },
     "stream-http": {
       "version": "2.8.3",
       "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
@@ -8199,6 +9382,16 @@
         "has-flag": "^3.0.0"
       }
     },
+    "sver-compat": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+      "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "^2.0.1",
+        "es6-symbol": "^3.1.1"
+      }
+    },
     "symbol-observable": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
@@ -8391,6 +9584,22 @@
         "xtend": "~4.0.1"
       }
     },
+    "through2-filter": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+      "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+      "dev": true,
+      "requires": {
+        "through2": "~2.0.0",
+        "xtend": "~4.0.0"
+      }
+    },
+    "time-stamp": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+      "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
+      "dev": true
+    },
     "timers-browserify": {
       "version": "2.0.11",
       "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
@@ -8409,6 +9618,16 @@
         "os-tmpdir": "~1.0.2"
       }
     },
+    "to-absolute-glob": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+      "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+      "dev": true,
+      "requires": {
+        "is-absolute": "^1.0.0",
+        "is-negated-glob": "^1.0.0"
+      }
+    },
     "to-array": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
@@ -8469,6 +9688,15 @@
         "repeat-string": "^1.6.1"
       }
     },
+    "to-through": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+      "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
+      "dev": true,
+      "requires": {
+        "through2": "^2.0.3"
+      }
+    },
     "toidentifier": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -8503,6 +9731,12 @@
       "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
       "dev": true
     },
+    "type": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+      "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+      "dev": true
+    },
     "type-check": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -8535,6 +9769,35 @@
       "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
       "dev": true
     },
+    "unc-path-regex": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+      "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+      "dev": true
+    },
+    "undertaker": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz",
+      "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.0.1",
+        "arr-map": "^2.0.0",
+        "bach": "^1.0.0",
+        "collection-map": "^1.0.0",
+        "es6-weak-map": "^2.0.1",
+        "last-run": "^1.1.0",
+        "object.defaults": "^1.0.0",
+        "object.reduce": "^1.0.0",
+        "undertaker-registry": "^1.0.0"
+      }
+    },
+    "undertaker-registry": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+      "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
+      "dev": true
+    },
     "unicode-canonical-property-names-ecmascript": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -8599,6 +9862,16 @@
         "imurmurhash": "^0.1.4"
       }
     },
+    "unique-stream": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+      "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+      "dev": true,
+      "requires": {
+        "json-stable-stringify-without-jsonify": "^1.0.1",
+        "through2-filter": "^3.0.0"
+      }
+    },
     "universalify": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@@ -8760,6 +10033,15 @@
       "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==",
       "dev": true
     },
+    "v8flags": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz",
+      "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1"
+      }
+    },
     "validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -8770,12 +10052,83 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "value-or-function": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+      "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
+      "dev": true
+    },
     "vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
       "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
       "dev": true
     },
+    "vinyl": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+      "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.1",
+        "clone-buffer": "^1.0.0",
+        "clone-stats": "^1.0.0",
+        "cloneable-readable": "^1.0.0",
+        "remove-trailing-separator": "^1.0.1",
+        "replace-ext": "^1.0.0"
+      }
+    },
+    "vinyl-fs": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+      "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+      "dev": true,
+      "requires": {
+        "fs-mkdirp-stream": "^1.0.0",
+        "glob-stream": "^6.1.0",
+        "graceful-fs": "^4.0.0",
+        "is-valid-glob": "^1.0.0",
+        "lazystream": "^1.0.0",
+        "lead": "^1.0.0",
+        "object.assign": "^4.0.4",
+        "pumpify": "^1.3.5",
+        "readable-stream": "^2.3.3",
+        "remove-bom-buffer": "^3.0.0",
+        "remove-bom-stream": "^1.2.0",
+        "resolve-options": "^1.1.0",
+        "through2": "^2.0.0",
+        "to-through": "^2.0.0",
+        "value-or-function": "^3.0.0",
+        "vinyl": "^2.0.0",
+        "vinyl-sourcemap": "^1.1.0"
+      }
+    },
+    "vinyl-sourcemap": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+      "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
+      "dev": true,
+      "requires": {
+        "append-buffer": "^1.0.2",
+        "convert-source-map": "^1.5.0",
+        "graceful-fs": "^4.1.6",
+        "normalize-path": "^2.1.1",
+        "now-and-later": "^2.0.0",
+        "remove-bom-buffer": "^3.0.0",
+        "vinyl": "^2.0.0"
+      },
+      "dependencies": {
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "dev": true,
+          "requires": {
+            "remove-trailing-separator": "^1.0.1"
+          }
+        }
+      }
+    },
     "vm-browserify": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
diff --git a/package.json b/package.json
index e207526..5bc830f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
-  "name": "pdbe-ligand-display",
-  "version": "1.0.0",
+  "name": "pdbe-interactions",
+  "version": "0.1.0",
   "description": "",
   "main": "app.js",
   "dependencies": {
@@ -31,15 +31,19 @@
     "ts-node": "^7.0.1",
     "url-loader": "^1.1.2",
     "webpack": "^4.41.5",
-    "webpack-cli": "^3.3.10"
+    "webpack-cli": "^3.3.10",
+    "gulp": "^4.0.2",
+    "gulp-concat": "^2.6.1",
+    "gulp-header": "^2.0.9",
+    "del": "^5.1.0"
   },
   "scripts": {
-    "tsc:w": "tsc -w",
+    "tscW": "tsc -w",
     "prestart": "tsc",
-    "serve": "live-server build --watch=src/**/*.html,src/bundle.js,src/**/*.css",
-    "start": "npm-run-all --parallel serve tsc:w",
-    "webpack": "webpack",
-    "buildComponent": "webpack --mode=development"
+    "serve": "live-server build --watch=src/**/*",
+    "start": "run-p serve gulp",    
+    "build": "npm run prestart && webpack --mode=development && gulp",
+    "buildProduction": "npm run prestart && npm run webpack --mode=production && gulp"
   },
   "author": "Lukas Pravda",
   "license": "Apache License 2.0"
diff --git a/src/component.js b/src/component/component.js
similarity index 98%
rename from src/component.js
rename to src/component/component.js
index 94a6cd0..6145ac0 100644
--- a/src/component.js
+++ b/src/component/component.js
@@ -1,6 +1,6 @@
 // Import the LitElement base class and html helper function
 import { LitElement, html } from 'lit-element';
-import { tickStep } from 'd3';
+import "../styles/pdbe-interactions.css";
 
 // Extend the LitElement base class
 class pdbInteractions extends LitElement {
diff --git a/src/config.ts b/src/plugin/config.ts
similarity index 91%
rename from src/config.ts
rename to src/plugin/config.ts
index 64ba2d0..2f193a5 100644
--- a/src/config.ts
+++ b/src/plugin/config.ts
@@ -1,7 +1,7 @@
 namespace Config {
     export const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
-    export const glycanSymbols: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/visuals.xml";
-    export const glycanMapping: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
+    export const glycanSymbols: string = "snfg_visuals.xml";
+    export const glycanMapping: string = "het_mapping.json";
 
 
     export const interactionClickEvent = 'PDB.interactions.click';
diff --git a/src/depiction.ts b/src/plugin/depiction.ts
similarity index 100%
rename from src/depiction.ts
rename to src/plugin/depiction.ts
diff --git a/src/manager.ts b/src/plugin/manager.ts
similarity index 99%
rename from src/manager.ts
rename to src/plugin/manager.ts
index ae82a47..336390d 100644
--- a/src/manager.ts
+++ b/src/plugin/manager.ts
@@ -279,7 +279,7 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
-        d3.text('pdbe-interactions-svgstyles.css')
+        d3.text('pdbe-interactions-svg.css')
             .then(x => {
                 let svgData = `
                 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" style="background-color: white;">
diff --git a/src/model.ts b/src/plugin/model.ts
similarity index 100%
rename from src/model.ts
rename to src/plugin/model.ts
diff --git a/src/ui.ts b/src/plugin/ui.ts
similarity index 99%
rename from src/ui.ts
rename to src/plugin/ui.ts
index b06ae9f..9c08e2b 100644
--- a/src/ui.ts
+++ b/src/plugin/ui.ts
@@ -1,6 +1,7 @@
 // #region help
 let helpLigands = `
     <table class='int-help-table'>
+    Foobar!
         <tr>
             <td>
                 <div class="int-help-residue" style="background: #808080; "></div>
diff --git a/src/visualsMapping.ts b/src/plugin/visualsMapping.ts
similarity index 100%
rename from src/visualsMapping.ts
rename to src/plugin/visualsMapping.ts
diff --git a/build/pdbe-interactions-svgstyles.css b/src/styles/pdbe-interactions-svg.css
similarity index 100%
rename from build/pdbe-interactions-svgstyles.css
rename to src/styles/pdbe-interactions-svg.css
diff --git a/build/pdbe-interactions-styles.css b/src/styles/pdbe-interactions.css
similarity index 100%
rename from build/pdbe-interactions-styles.css
rename to src/styles/pdbe-interactions.css
diff --git a/tsconfig.json b/tsconfig.json
index ac2e77e..26381c6 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,9 +10,9 @@
         "declaration": true,
         "module": "none",
         "moduleResolution": "node",
-        "out": "build/app.js"
+        "out": "build/pdbe-interactions-plugin.js"
     },
-    "include": ["src/**/*", ],
+    "include": ["src/plugin/**/*", ],
     "exclude": [
         "node_modules",
         "build",
diff --git a/webpack.config.js b/webpack.config.js
index 2d28104..4481cb7 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -4,13 +4,13 @@ const camelCase = require("camelcase");
 const CleanWebpackPlugin = require("clean-webpack-plugin");
 
 const PACKAGE_ROOT_PATH = process.cwd();
-const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
+//const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
 
 const config = {
-  entry: ["./src/component.js"],
+  entry: ["./src/component/component.js"],
   output: {
     path: path.resolve(PACKAGE_ROOT_PATH, "build"),
-    filename: "component.js"
+    filename: "pdbe-interactions-component-init.js"
   },
   target: "web",
   devtool: "source-map",
@@ -26,17 +26,17 @@ const config = {
 //   plugins: [new CleanWebpackPlugin([path.join(PACKAGE_ROOT_PATH, "dist")])],
   module: {
     rules: [
-    //   {
-    //     test: /\.css$/,
-    //     use: [
-    //       "style-loader",
-    //       { loader: "css-loader", options: { importLoaders: 1 } }
-    //     ]
-    //   },
-    //   {
-    //     test: /.(jpg|jpeg|png|svg)$/,
-    //     use: ['url-loader'],
-    //   },
+      {
+        test: /\.css$/,
+        use: [
+          "style-loader",
+          { loader: "css-loader", options: { importLoaders: 1 } }
+        ]
+      },
+      {
+        test: /.(jpg|jpeg|png|svg)$/,
+        use: ['url-loader'],
+      },
       {
         test: /\.(js)$/,
         exclude: function excludeCondition(path){
-- 
GitLab


From 339c26515d604f1823fef97064c28516606cb2bf Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 24 Jan 2020 15:33:01 +0000
Subject: [PATCH 15/66] get npm scripts working

---
 build/het_mapping.json  | 307 ----------------------------------------
 build/index.html        | 138 ------------------
 dependencies/index.html |  10 +-
 package-lock.json       | 169 ++++++++++++++++++++++
 package.json            |  21 +--
 src/plugin/ui.ts        |   1 -
 6 files changed, 187 insertions(+), 459 deletions(-)
 delete mode 100644 build/het_mapping.json
 delete mode 100644 build/index.html

diff --git a/build/het_mapping.json b/build/het_mapping.json
deleted file mode 100644
index f9bae8d..0000000
--- a/build/het_mapping.json
+++ /dev/null
@@ -1,307 +0,0 @@
-[
-    {
-        "name": "Abe",
-        "het_codes": [
-            "ABE"
-        ]
-    },
-    {
-        "name": "All",
-        "het_codes": [
-            "ALL",
-            "AFD"
-        ]
-    },
-    {
-        "name": "AllNAc",
-        "het_codes": [
-            "NAA"
-        ]
-    },
-    {
-        "name": "Alt",
-        "het_codes": [
-            "SHD"
-        ]
-    },
-    {
-        "name": "Api",
-        "het_codes": [
-            "XXM"
-        ]
-    },
-    {
-        "name": "Ara",
-        "het_codes": [
-            "ARA",
-            "ARB"
-        ]
-    },
-    {
-        "name": "Bac",
-        "het_codes": [
-            "B6D"
-        ]
-    },
-    {
-        "name": "DDManHep",
-        "het_codes": [
-            "289"
-        ]
-    },
-    {
-        "name": "Fru",
-        "het_codes": [
-            "BDF"
-        ]
-    },
-    {
-        "name": "Fuc",
-        "het_codes": [
-            "FUC",
-            "FUL"
-        ]
-    },
-    {
-        "name": "Gal",
-        "het_codes": [
-            "GAL",
-            "GLA"
-        ]
-    },
-    {
-        "name": "GalA",
-        "het_codes": [
-            "ADA",
-            "GTR"
-        ]
-    },
-    {
-        "name": "GalN",
-        "het_codes": [
-            "X6X",
-            "1GN"
-        ]
-    },
-    {
-        "name": "GalNAc",
-        "het_codes": [
-            "NGA",
-            "A2G"
-        ]
-    },
-    {
-        "name": "Glc",
-        "het_codes": [
-            "GLC",
-            "BGC"
-        ]
-    },
-    {
-        "name": "GlcA",
-        "het_codes": [
-            "GCU",
-            "BDP"
-        ]
-    },
-    {
-        "name": "GlcN",
-        "het_codes": [
-            "GCS",
-            "PA1"
-        ]
-    },
-    {
-        "name": "GlcNAc",
-        "het_codes": [
-            "NAG",
-            "NDG"
-        ]
-    },
-    {
-        "name": "Gul",
-        "het_codes": [
-            "GUP",
-            "GL0"
-        ]
-    },
-    {
-        "name": "GulA",
-        "het_codes": [
-            "LGU"
-        ]
-    },
-    {
-        "name": "GulNAc",
-        "het_codes": [
-            "LXB"
-        ]
-    },
-    {
-        "name": "Ido",
-        "het_codes": [
-            "4N2"
-        ]
-    },
-    {
-        "name": "IdoA",
-        "het_codes": [
-            "IDR"
-        ]
-    },
-    {
-        "name": "IdoNAc",
-        "het_codes": [
-            "HSQ"
-        ]
-    },
-    {
-        "name": "Kdn",
-        "het_codes": [
-            "KDN",
-            "KDM"
-        ]
-    },
-    {
-        "name": "Kdo",
-        "het_codes": [
-            "KDO"
-        ]
-    },
-    {
-        "name": "LDManHep",
-        "het_codes": [
-            "GMH"
-        ]
-    },
-    {
-        "name": "Lyx",
-        "het_codes": [
-            "LDY"
-        ]
-    },
-    {
-        "name": "Man",
-        "het_codes": [
-            "MAN",
-            "BMA"
-        ]
-    },
-    {
-        "name": "ManA",
-        "het_codes": [
-            "MAV",
-            "BEM"
-        ]
-    },
-    {
-        "name": "ManN",
-        "het_codes": [
-            "95Z"
-        ]
-    },
-    {
-        "name": "ManNAc",
-        "het_codes": [
-            "BM3",
-            "BM7"
-        ]
-    },
-    {
-        "name": "Mur",
-        "het_codes": [
-            "MUR"
-        ]
-    },
-    {
-        "name": "MurNAc",
-        "het_codes": [
-            "AMU",
-            "MUB"
-        ]
-    },
-    {
-        "name": "Neu5Ac",
-        "het_codes": [
-            "SIA",
-            "SLB"
-        ]
-    },
-    {
-        "name": "Neu5Gc",
-        "het_codes": [
-            "NGC",
-            "NGE"
-        ]
-    },
-    {
-        "name": "Oli",
-        "het_codes": [
-            "DDA"
-        ]
-    },
-    {
-        "name": "Par",
-        "het_codes": [
-            "PZU"
-        ]
-    },
-    {
-        "name": "Pse",
-        "het_codes": [
-            "6PZ"
-        ]
-    },
-    {
-        "name": "Qui",
-        "het_codes": [
-            "G6D"
-        ]
-    },
-    {
-        "name": "Rha",
-        "het_codes": [
-            "RAM",
-            "RM4"
-        ]
-    },
-    {
-        "name": "Rib",
-        "het_codes": [
-            "RIP",
-            "0MK"
-        ]
-    },
-    {
-        "name": "Sor",
-        "het_codes": [
-            "SOE"
-        ]
-    },
-    {
-        "name": "Tag",
-        "het_codes": [
-            "T6T"
-        ]
-    },
-    {
-        "name": "TalA",
-        "het_codes": [
-            "X0X",
-            "X1X"
-        ]
-    },
-    {
-        "name": "Tyv",
-        "het_codes": [
-            "TYV"
-        ]
-    },
-    {
-        "name": "Xyl",
-        "het_codes": [
-            "XYS",
-            "XYP"
-        ]
-    }
-]
\ No newline at end of file
diff --git a/build/index.html b/build/index.html
deleted file mode 100644
index ce450b5..0000000
--- a/build/index.html
+++ /dev/null
@@ -1,138 +0,0 @@
-<!doctype html>
-<html lang="en">
-<script src="https://d3js.org/d3.v5.min.js"></script>
-<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
-<!--testing purposes only-->
-<!-- <link rel="stylesheet" href="pdbe-interactions-styles.css" /> -->
-<link rel="stylesheet" href="pdbe-interactions-svg.css" />
-<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
-
-<!-- MOL* -->
-<link rel="stylesheet" type="text/css"
-    href="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/css/molstar-light-0.0.1.css">
-<script src="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/js/molstar-0.0.1.js"></script>
-
-<!-- <script src="pdbe-interactions-plugin.js"></script> -->
-
-<!-- Web component polyfill (only loads what it needs) -->
-<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8">
-</script>
-<!-- Required to polyfill modern browsers as code is ES5 for IE... -->
-<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
-    charset="utf-8"></script>
-
-<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
-<script>
-    var renderBmInteractions = function (id, bmId) {
-        var int = `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
-        document.getElementById('rt').innerHTML = int;
-    };
-
-    var renderLigandInteractions = function (id, chain, resId) {
-        var int =
-            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-interactions>`
-        document.getElementById('rt').innerHTML = int;
-    };
-
-    var parseParameters = function (par) {
-        let result = {}
-
-        par.split('&').forEach(x => {
-            let splitted = x.split('=');
-            result[splitted[0].toLowerCase()] = splitted[1].toLowerCase();
-        });
-
-        if (result.bmid === undefined) {
-            result['query'] =
-                `https://wwwdev.ebi.ac.uk/pdbe/coordinates/${result.pdbid}/ligandInteraction?&authAsymId=$${result.chain}&authSeqNumber=${result.resid}&radius=5&dataSource=hydrogens`
-        } else {
-            result['query'] = `https://wwwdev.ebi.ac.uk/pdbe/coordinates/${result.pdbid}?dataSource=hydrogens`
-        }
-
-        if (result.chain !== undefined) result.chain = result.chain.toUpperCase();
-
-        return result;
-    };
-
-    (function () {
-        'use strict';
-        $(document)
-            .ready(function ($http) {
-                var tokens = window.location.href.split('/').reverse();
-                let params = {};
-
-                if (tokens[0].startsWith('?')) {
-                    params = parseParameters(tokens[0].slice(1));
-                } else {
-                    params = {
-                        pdbid: '1cbs',
-                        chain: 'A',
-                        resid: 200,
-                        query: "https://wwwdev.ebi.ac.uk/pdbe/coordinates/1cbs/ligandInteraction?&authAsymId=$A&authSeqNumber=$200&radius=5&dataSource=hydrogens"
-                    };
-                }
-
-                if (params.bmid === undefined) {
-                    renderLigandInteractions(params.pdbid, params.chain, params.resid);
-                } else {
-                    renderBmInteractions(params.pdbid, params.bmid);
-                }
-
-                var initParams = {
-                    moleculeId: params.pdbid,
-                    pdbeUrl: 'https://wwwdev.ebi.ac.uk/pdbe/',
-                    loadMaps: true,
-                    validationAnnotation: true,
-                    domainAnnotation: true,
-                    lowPrecisionCoords: true,
-                    isExpanded: false,
-                    hideControls: true,
-                    showLogs: false,
-                    subscribeEvents: true,
-                    showPDBeLogo: false,
-                    assemblyId: 'preferred', //'deposited'
-                    // selectInteraction: false,
-                    ligandView: {auth_asym_Id: params.chain, auth_seq_id: params.resid, hydrogens: true},
-                    backgroundColour: '0xFFFFFF',
-                    //customColorList: [0xff0000, 0x0000ff],
-                    //representationStyle: representationStyle//,
-                    // customData: {
-                    //     url: `https://wwwdev.ebi.ac.uk/pdbe/coordinates/${params.pdbid}/ligandInteraction?&authAsymId=${params.chain}&authSeqNumber=${params.resid}&radius=5&dataSource=hydrogens`,
-                    //     format: 'cif'
-                    // }
-                }
-                var pdbeMolstar = new MolStarPdbeWrapper();
-                pdbeMolstar.render(document.getElementById('3dViewer'), initParams);
-            });
-    }());
-</script>
-
-
-<body>
-    <div style="position: relative; float: left;">
-        <div id="rt" style="width: 500px; height: 500px; position: relative">
-        </div>
-    </div>
-    <div style="position: relative; float: left;">
-        <div id='3dViewer' style="position:relative; width: 500px;height: 500px;"></div>
-    </div>
-    <div style="position: relative; float: left;">
-        <div id="rt 1" style="width: 500px; height: 500px; position: relative">
-            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-interactions>
-        </div>
-    </div>
-
-    <!--
-        Further use in the app for bound molecule interactions:
-        
-        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
-        
-        for ligand interactions:
-        <pdb-interactions pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdb-interactions>
-    -->
-    <script>
-
-    </script>
-</body>
-
-</html>
\ No newline at end of file
diff --git a/dependencies/index.html b/dependencies/index.html
index ce450b5..2ee362f 100644
--- a/dependencies/index.html
+++ b/dependencies/index.html
@@ -3,7 +3,6 @@
 <script src="https://d3js.org/d3.v5.min.js"></script>
 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
 <!--testing purposes only-->
-<!-- <link rel="stylesheet" href="pdbe-interactions-styles.css" /> -->
 <link rel="stylesheet" href="pdbe-interactions-svg.css" />
 <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
@@ -24,7 +23,8 @@
 <script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
 <script>
     var renderBmInteractions = function (id, bmId) {
-        var int = `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
+        var int =
+            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
@@ -92,7 +92,11 @@
                     showPDBeLogo: false,
                     assemblyId: 'preferred', //'deposited'
                     // selectInteraction: false,
-                    ligandView: {auth_asym_Id: params.chain, auth_seq_id: params.resid, hydrogens: true},
+                    ligandView: {
+                        auth_asym_Id: params.chain,
+                        auth_seq_id: params.resid,
+                        hydrogens: true
+                    },
                     backgroundColour: '0xFFFFFF',
                     //customColorList: [0xff0000, 0x0000ff],
                     //representationStyle: representationStyle//,
diff --git a/package-lock.json b/package-lock.json
index 162131c..c50c9bb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -887,6 +887,12 @@
         "to-fast-properties": "^2.0.0"
       }
     },
+    "@blakeembrey/deque": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@blakeembrey/deque/-/deque-1.0.5.tgz",
+      "integrity": "sha512-6xnwtvp9DY1EINIKdTfvfeAtCYw4OqBZJhtiqkT3ivjnEfa25VQ3TsKvaFfKm8MyGIEfE95qLe+bNEt3nB0Ylg==",
+      "dev": true
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@@ -7425,6 +7431,163 @@
         "wrappy": "1"
       }
     },
+    "onchange": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/onchange/-/onchange-6.1.0.tgz",
+      "integrity": "sha512-T0wvi3yzNd+Lut2ymJp2e6fTiob0TLrXnjqGaiK9MAFB8MYo/k/ZClx6ps7YhTtQ88dDm+hDHmtJXP1nJT5WNA==",
+      "dev": true,
+      "requires": {
+        "@blakeembrey/deque": "^1.0.3",
+        "arrify": "^2.0.0",
+        "chokidar": "^3.0.0",
+        "cross-spawn": "^6.0.0",
+        "ignore": "^5.1.4",
+        "minimist": "^1.2.0",
+        "supports-color": "^7.0.0",
+        "tree-kill": "^1.2.0"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+          "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+          "dev": true,
+          "requires": {
+            "normalize-path": "^3.0.0",
+            "picomatch": "^2.0.4"
+          }
+        },
+        "arrify": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+          "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+          "dev": true
+        },
+        "binary-extensions": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+          "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+          "dev": true
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chokidar": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.1.tgz",
+          "integrity": "sha512-4QYCEWOcK3OJrxwvyyAOxFuhpvOVCYkr33LPfFNBjAD/w3sEzWsp2BUOkI4l9bHvWioAd0rc6NlHUOEaWkTeqg==",
+          "dev": true,
+          "requires": {
+            "anymatch": "~3.1.1",
+            "braces": "~3.0.2",
+            "fsevents": "~2.1.2",
+            "glob-parent": "~5.1.0",
+            "is-binary-path": "~2.1.0",
+            "is-glob": "~4.0.1",
+            "normalize-path": "~3.0.0",
+            "readdirp": "~3.3.0"
+          }
+        },
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "dev": true,
+          "requires": {
+            "nice-try": "^1.0.4",
+            "path-key": "^2.0.1",
+            "semver": "^5.5.0",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "fsevents": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
+          "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
+          "dev": true,
+          "optional": true
+        },
+        "glob-parent": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+          "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "ignore": {
+          "version": "5.1.4",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+          "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+          "dev": true
+        },
+        "is-binary-path": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+          "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+          "dev": true,
+          "requires": {
+            "binary-extensions": "^2.0.0"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "readdirp": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.3.0.tgz",
+          "integrity": "sha512-zz0pAkSPOXXm1viEwygWIPSPkcBYjW1xU5j/JBh5t9bGCJwa6f9+BJa6VaB2g+b55yVrmXzqkyLf4xaWYM0IkQ==",
+          "dev": true,
+          "requires": {
+            "picomatch": "^2.0.7"
+          }
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
     "onetime": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
@@ -9703,6 +9866,12 @@
       "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
       "dev": true
     },
+    "tree-kill": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+      "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+      "dev": true
+    },
     "ts-node": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz",
diff --git a/package.json b/package.json
index 5bc830f..8a0d325 100644
--- a/package.json
+++ b/package.json
@@ -23,27 +23,28 @@
     "camelcase": "^5.0.0",
     "clean-webpack-plugin": "^1.0.1",
     "css-loader": "^2.1.0",
+    "del": "^5.1.0",
     "eslint": "^4.12.0",
     "file-loader": "^3.0.1",
+    "gulp": "^4.0.2",
+    "gulp-concat": "^2.6.1",
+    "gulp-header": "^2.0.9",
     "live-server": "^1.2.1",
     "npm-run-all": "^4.1.3",
+    "onchange": "^6.1.0",
     "style-loader": "^0.23.1",
     "ts-node": "^7.0.1",
     "url-loader": "^1.1.2",
     "webpack": "^4.41.5",
-    "webpack-cli": "^3.3.10",
-    "gulp": "^4.0.2",
-    "gulp-concat": "^2.6.1",
-    "gulp-header": "^2.0.9",
-    "del": "^5.1.0"
+    "webpack-cli": "^3.3.10"
   },
   "scripts": {
     "tscW": "tsc -w",
-    "prestart": "tsc",
-    "serve": "live-server build --watch=src/**/*",
-    "start": "run-p serve gulp",    
-    "build": "npm run prestart && webpack --mode=development && gulp",
-    "buildProduction": "npm run prestart && npm run webpack --mode=production && gulp"
+    "serve": "live-server build --watch=build",
+    "start": "npm-run-all --parallel watch serve",
+    "build": "tsc && webpack --mode=development && gulp",
+    "watch": "onchange 'src/**/*' -- npm run build",
+    "buildProduction": "tsc && webpack --mode=production && gulp"
   },
   "author": "Lukas Pravda",
   "license": "Apache License 2.0"
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index 9c08e2b..b06ae9f 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -1,7 +1,6 @@
 // #region help
 let helpLigands = `
     <table class='int-help-table'>
-    Foobar!
         <tr>
             <td>
                 <div class="int-help-residue" style="background: #808080; "></div>
-- 
GitLab


From 26e8161587fc4c0e645b5efdb0f5a4da7422c8e3 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 24 Jan 2020 15:33:47 +0000
Subject: [PATCH 16/66] Fix CI

---
 .gitlab-ci.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 086d8e6..652aa58 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,8 +2,7 @@ image: node:latest
 
 before_script:
   - npm install
-  - npm install --save-dev webpack
-  - npm run buildProduction
+  - npm run build
 
 pages:
   script:
-- 
GitLab


From 5022078a5774c785f0be5b068eb3383025336f00 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 24 Jan 2020 17:00:14 +0000
Subject: [PATCH 17/66] few improvements

---
 src/component/component.js       | 9 ++-------
 src/plugin/manager.ts            | 2 ++
 src/plugin/ui.ts                 | 1 -
 src/styles/pdbe-interactions.css | 3 +--
 4 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/src/component/component.js b/src/component/component.js
index 6145ac0..127a747 100644
--- a/src/component/component.js
+++ b/src/component/component.js
@@ -25,13 +25,8 @@ class pdbInteractions extends LitElement {
 
   async connectedCallback() {
     let uiParams = new Config.UIParameters();
-
-    this.style.display = 'block';
-    this.style.height = '100%';
-    this.style.width = '100%';
-    this.style.position = 'relative';
-
     uiParams.zoom = this.zoomOn;
+
     this.display = new Visualization(this, uiParams);
 
     if (this.pdbId) {
@@ -39,7 +34,7 @@ class pdbInteractions extends LitElement {
         this.display.initBoundMoleculeInteractions(this.pdbId, this.bmId);
       }
       else {
-        this.display.initLigandInteractions(this.pdbId, this.resId, this.chainId)
+        this.display.initLigandInteractions(this.pdbId, this.resId, this.chainId);
       }
     }
     else if (this.resName) {
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 336390d..957a312 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -30,6 +30,8 @@ class Visualization {
 
     constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
         this.parent = element;
+        this.parent.style.cssText += "display: block; height: 100%; width: 100%; position: relative;";
+
         this.visualsMapper = new VisualsMapper();
 
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index b06ae9f..b23e524 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -218,7 +218,6 @@ class UI {
                 .on('click', () => this.changeHelp(true));
 
             navbar.append('a')
-                .classed('active', true)
                 .attr('id', 'int-help-bonds-btn')
                 .text('Interactions')
                 .on('click', () => this.changeHelp(false));
diff --git a/src/styles/pdbe-interactions.css b/src/styles/pdbe-interactions.css
index 39674f4..9e6d7f3 100644
--- a/src/styles/pdbe-interactions.css
+++ b/src/styles/pdbe-interactions.css
@@ -158,8 +158,7 @@
     cursor: pointer;
 }
 
-.int-help-navbar a.active,
-.int-help-navbar a:hover {
+.int-help-navbar a.active {
     border-bottom: 2px solid #637ca0;
     color: #637ca0;
 }
\ No newline at end of file
-- 
GitLab


From 5605b2cd6f76de3e3639b85c4272d6fb6eca4504 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 24 Jan 2020 17:00:20 +0000
Subject: [PATCH 18/66] update readme

---
 README.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 63 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index d8be90c..f9d58de 100644
--- a/README.md
+++ b/README.md
@@ -10,43 +10,67 @@ This is a web-component to display ligand structure in 2D along with its interac
 
 | Mode A | Mode B | Mode C |
 |-------------------- | --------- | -------- | 
-| <img src="https://www.ebi.ac.uk/~lpravda/imgs/1cbs_REA_200_A.png"/>| <img src="https://www.ebi.ac.uk/~lpravda/imgs/3d12_bm1.png"/> | <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=VIA&size=400"/> |
+| <img src="https://www.ebi.ac.uk/~lpravda/imgs/1cbs_REA_200_A.png"/>| <img src="https://www.ebi.ac.uk/~lpravda/imgs/3d12_bm1.png"/> | <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=VIA&size=500"/> |
 | 1cbs REA 200 A | 3D12 bm1 (`2xGLC-2xBGC-LXZ-NGA-GL0`)| wwPDB CCD - VIA
  
 
-## Usage: web-component
+## How to use it
+The component can be inserted into the pages by two different ways. Either as a web-component using html tag, or by using 
 
-### A) Bound molecule interactions
+### web-component
+
+#### Prerequisities
+
+These files need to be inserted in the page before the component is attempted to be loaded:
+
+```html
+
+<!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
+<link rel="stylesheet" href="pdbe-interactions-svg.css" />
+
+<!-- UI icons -->
+<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" /> 
+
+<!-- Web component polyfill (only loads what it needs) -->
+<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8"></script>
+<script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
+    charset="utf-8"></script>
+
+<!--PDBe interactions component-->
+<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+```
+
+#### A) Bound molecule interactions
 
 ```html
 <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
 ```
 
-### B) Ligand interactions
+#### B) Ligand interactions
 
 ```html
 <ligand-display pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></ligand-display>
 ```
 
-### C) Ligand/chemical component
+#### C) Ligand/chemical component
 
 ```html
 <ligand-display pdb-res-name="CLR" zoom-on ></ligand-display>
 ```
 
-## Usage: Data injection
+### data injection
 
-First you need to define a component on the page
+The component contains a number of properties that can be set, in order to change data that are being displayed. First you need to define a component on the page:
 
 ```html
 <ligand-display id='SIA-component'></ligand-display>
 ```
 
-and then inject data you want to display.
+and then inject data you want to display e.g.:
 
 ```javascript
 let chemUrl = `https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/SIA/annotation`;
-let interactionsURL = "";
+let interactionsURL = "https://wwwdev.ebi.ac.uk/pdbe/graph-api/pdb/bound_ligand_interactions/4yy1/A/604";
 let component = document.getElementById('SIA-component');
 
 const depiction = await (await fetch(chemUrl)).json();
@@ -58,6 +82,36 @@ component.ligandHighlight = atomsToHighlight;
 component.interactions = interactionsData;
 ```
 
+### Plugin
+
+The component can be also added to DOM directly from JavaScript. There are some requirements
+
+```html
+<!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
+<link rel="stylesheet" href="pdbe-interactions-svg.css" />
+
+<!-- UI icons -->
+<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
+
+<!--PDBe interactions component-->
+<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+```
+
+and then the component can be instantiated as simply as:
+
+```javascript
+let component = document.getElementById('SIA-component');
+this.display = new Visualization(this, uiParams);
+
+// to display bound molecule interactions
+this.display.initBoundMoleculeInteractions('3d12', 'bm1'
+// to display ligand interactions
+this.display.initLigandInteractions('1cbs', 200, 'A');
+
+// to display chemical component only
+this.display.initLigandDisplay('HEM').then(() => this.display.centerScene());
+````
+
 ## Parameters
 
 | Parametr            | Type      | Required | Description |
-- 
GitLab


From 257d0b2281cf209b10e9f7f3980fa7a62111c015 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 24 Jan 2020 17:13:49 +0000
Subject: [PATCH 19/66] readme improvements

---
 README.md | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index f9d58de..f99c804 100644
--- a/README.md
+++ b/README.md
@@ -9,19 +9,17 @@ This is a web-component to display ligand structure in 2D along with its interac
 * Mode C: Display ligand (chemical component) only
 
 | Mode A | Mode B | Mode C |
-|-------------------- | --------- | -------- | 
+|:------------------: | :-------: | :-------: |
 | <img src="https://www.ebi.ac.uk/~lpravda/imgs/1cbs_REA_200_A.png"/>| <img src="https://www.ebi.ac.uk/~lpravda/imgs/3d12_bm1.png"/> | <img src="https://www.ebi.ac.uk/pdbe-srv/pdbechem/image/showNew?code=VIA&size=500"/> |
-| 1cbs REA 200 A | 3D12 bm1 (`2xGLC-2xBGC-LXZ-NGA-GL0`)| wwPDB CCD - VIA
- 
+| [1cbs REA 200 A](https://www.ebi.ac.uk/pdbe/entry/pdb/1cbs/bound/REA) | 3D12 bm1 (`2xGLC-2xBGC-LXZ-NGA-GL0`)| [wwPDB CCD - VIA](https://pdbe.org/chem/VIA)
 
 ## How to use it
-The component can be inserted into the pages by two different ways. Either as a web-component using html tag, or by using 
 
-### web-component
+The component can be inserted into the pages by two different ways. Either as a `web-component` using html tag, or directly by using javascript as a `plugin`.
 
-#### Prerequisities
+### Web-component
 
-These files need to be inserted in the page before the component is attempted to be loaded:
+A few files needs to be imported in the page before the component is attempted to be loaded:
 
 ```html
 
@@ -40,26 +38,24 @@ These files need to be inserted in the page before the component is attempted to
 <script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
 ```
 
-#### A) Bound molecule interactions
+**A) Bound molecule interactions**
 
 ```html
 <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
 ```
 
-#### B) Ligand interactions
+**B) Ligand interactions**
 
 ```html
 <ligand-display pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></ligand-display>
 ```
 
-#### C) Ligand/chemical component
+**C) Ligand/chemical component**
 
 ```html
 <ligand-display pdb-res-name="CLR" zoom-on ></ligand-display>
 ```
 
-### data injection
-
 The component contains a number of properties that can be set, in order to change data that are being displayed. First you need to define a component on the page:
 
 ```html
-- 
GitLab


From ef3893efe7dadcda2b65d5a0b8eb90b2560e5398 Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Tue, 4 Feb 2020 00:38:40 +0000
Subject: [PATCH 20/66] add demos

---
 README.md           |  9 +++++++++
 demo_component.html | 45 ++++++++++++++++++++++++++++++++++++++++++
 demo_plugin.html    | 48 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 102 insertions(+)
 create mode 100644 demo_component.html
 create mode 100644 demo_plugin.html

diff --git a/README.md b/README.md
index f99c804..43c9735 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,15 @@
 
 This is a web-component to display ligand structure in 2D along with its interactions. Ligand can be perceived as a set of covalently linked pdb residues (refered to as bound molecule) or a single pdb residue. This depiction can be enriched with a substructure highlight and binding site interactions.
 
+## Step after cloning (use local server to see demo pages)
+
+```shell
+npm run-script build
+cp demo* build/
+cd build
+python3 -m http.server
+```
+
 ## Component modes
 
 * Mode A: Display bound molecule and its interactions
diff --git a/demo_component.html b/demo_component.html
new file mode 100644
index 0000000..3407c0a
--- /dev/null
+++ b/demo_component.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<html lang="en">
+  <head> 
+
+    <script src="https://d3js.org/d3.v5.min.js"></script>    
+    <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
+    <link rel="stylesheet" href="pdbe-interactions-svg.css" />    
+    <!-- UI icons -->
+    <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />    
+    <!-- Web component polyfill (only loads what it needs) -->
+    <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js"
+        charset="utf-8"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
+        charset="utf-8"></script>    
+    <!--PDBe interactions component-->
+    <script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+
+  </head>
+  
+  <body>
+    
+    <!--Mode A-->
+    <div style="position: relative; float: left;">
+      <div style="width: 500px; height: 500px; position: relative">
+        <pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
+      </div>
+    </div>
+
+    <!--Mode B-->
+    <div style="position: relative; float: left;">
+      <div style="width: 500px; height: 500px; position: relative">
+        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+      </div>
+    </div>
+
+    <!--Mode C-->
+    <div style="position: relative; float: left;">
+        <div style="width: 500px; height: 500px; position: relative">
+          <pdb-interactions pdb-res-name="CLR" zoom-on></pdb-interactions>
+        </div>
+      </div>
+      
+  </body>
+
+</html>
\ No newline at end of file
diff --git a/demo_plugin.html b/demo_plugin.html
new file mode 100644
index 0000000..8eb9ae3
--- /dev/null
+++ b/demo_plugin.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    
+    <script src="https://d3js.org/d3.v5.min.js"></script>
+    <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
+    <link rel="stylesheet" href="pdbe-interactions-svg.css" />
+    <!-- UI icons -->
+    <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
+    <!-- Web component polyfill (only loads what it needs) -->
+    <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js"
+        charset="utf-8"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
+        charset="utf-8"></script>
+  
+    <!--PDBe interactions plugin-->
+    <script src="pdbe-interactions-plugin.js"></script>
+    
+    <!--Initialize Visualization-->
+    <script>
+      document.addEventListener("DOMContentLoaded", function (event) {
+        var eleLigInteraction = document.getElementById('ligand-interaction');
+        this.display = new Visualization(eleLigInteraction, undefined);
+        this.display.initLigandInteractions('1cbs', 200, 'A');
+
+        var eleLigInteraction = document.getElementById('boundmolecule-interaction');
+        this.display = new Visualization(eleLigInteraction, undefined);
+        this.display.initBoundMoleculeInteractions('3d12', 'bm1');
+      });
+    </script>
+
+  </head>
+  <body>  
+
+    <div style="position: relative; float: left;">
+      <div style="width: 800px; height: 800px; position: relative">
+        <div id='ligand-interaction'></div>
+      </div>
+    </div>
+    <div style="position: relative; float: left;">
+        <div style="width: 800px; height: 800px; position: relative">
+          <div id='boundmolecule-interaction'></div>
+        </div>
+      </div>
+
+  </body>
+  
+</html>
\ No newline at end of file
-- 
GitLab


From ced420813c685e2b0f08b8fc1c676ffcbaacce38 Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Tue, 4 Feb 2020 00:59:25 +0000
Subject: [PATCH 21/66] add css at the top as temporary measure

---
 demo_plugin.html | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/demo_plugin.html b/demo_plugin.html
index 8eb9ae3..b7dfb81 100644
--- a/demo_plugin.html
+++ b/demo_plugin.html
@@ -2,6 +2,8 @@
 <html lang="en">
   <head>
     
+    <link rel="stylesheet" href="pdbe-interactions.css" />
+
     <script src="https://d3js.org/d3.v5.min.js"></script>
     <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
     <link rel="stylesheet" href="pdbe-interactions-svg.css" />
@@ -19,29 +21,44 @@
     <!--Initialize Visualization-->
     <script>
       document.addEventListener("DOMContentLoaded", function (event) {
+        //<!--Mode A-->
         var eleLigInteraction = document.getElementById('ligand-interaction');
-        this.display = new Visualization(eleLigInteraction, undefined);
-        this.display.initLigandInteractions('1cbs', 200, 'A');
+        this.lidisplay = new Visualization(eleLigInteraction, undefined);
+        this.lidisplay.initLigandInteractions('1cbs', 200, 'A');
+
+        //<!--Mode B-->
+        var eleBoundInteraction = document.getElementById('boundmolecule-interaction');
+        this.bmdisplay = new Visualization(eleBoundInteraction, undefined);
+        this.bmdisplay.initBoundMoleculeInteractions('3d12', 'bm1');
 
-        var eleLigInteraction = document.getElementById('boundmolecule-interaction');
-        this.display = new Visualization(eleLigInteraction, undefined);
-        this.display.initBoundMoleculeInteractions('3d12', 'bm1');
+        //<!--Mode C-->
+        var eleChemComp = document.getElementById('chem-comp');
+        this.ccdisplay = new Visualization(eleChemComp, undefined);
+        this.ccdisplay.initLigandDisplay('HEM').then(() => this.display.centerScene());
       });
     </script>
 
   </head>
   <body>  
-
+    <!--Mode A-->
     <div style="position: relative; float: left;">
       <div style="width: 800px; height: 800px; position: relative">
-        <div id='ligand-interaction'></div>
+      <div id='ligand-interaction'></div>
       </div>
     </div>
+
+    <!--Mode B-->
+    <div style="position: relative; float: left;">
+      <div style="width: 800px; height: 800px; position: relative">
+      <div id='boundmolecule-interaction'></div>
+    </div>
+
+    <!--Mode C-->
     <div style="position: relative; float: left;">
-        <div style="width: 800px; height: 800px; position: relative">
-          <div id='boundmolecule-interaction'></div>
-        </div>
+      <div style="width: 800px; height: 800px; position: relative">
+        <div id='chem-comp'></div>
       </div>
+    </div>
 
   </body>
   
-- 
GitLab


From e8d3c7058d5835c88d1b4220a1bfe895ce95fdfa Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Tue, 4 Feb 2020 10:25:16 +0000
Subject: [PATCH 22/66] demo changes

---
 README.md        | 25 +++++++++++++++++--------
 demo_plugin.html |  6 +++---
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md
index 43c9735..4a800de 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ This is a web-component to display ligand structure in 2D along with its interac
 
 ```shell
 npm run-script build
-cp demo* build/
+cp demo* build/ (this copies demo_component.html and demo_plugin.html to build folder)
 cd build
 python3 -m http.server
 ```
@@ -32,6 +32,9 @@ A few files needs to be imported in the page before the component is attempted t
 
 ```html
 
+<!-- D3 -->
+<script src="https://d3js.org/d3.v5.min.js"></script>
+
 <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
 <link rel="stylesheet" href="pdbe-interactions-svg.css" />
 
@@ -47,22 +50,22 @@ A few files needs to be imported in the page before the component is attempted t
 <script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
 ```
 
-**A) Bound molecule interactions**
+**A) Ligand interactions**
 
 ```html
-<pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+<pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
 ```
 
-**B) Ligand interactions**
+**B) Bound molecule interactions**
 
 ```html
-<ligand-display pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></ligand-display>
+<pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
 ```
 
 **C) Ligand/chemical component**
 
 ```html
-<ligand-display pdb-res-name="CLR" zoom-on ></ligand-display>
+<pdb-interactions pdb-res-name="CLR" zoom-on ></pdb-interactions>
 ```
 
 The component contains a number of properties that can be set, in order to change data that are being displayed. First you need to define a component on the page:
@@ -92,14 +95,20 @@ component.interactions = interactionsData;
 The component can be also added to DOM directly from JavaScript. There are some requirements
 
 ```html
+
+<!-- D3 -->
+<script src="https://d3js.org/d3.v5.min.js"></script>
+
 <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
 <link rel="stylesheet" href="pdbe-interactions-svg.css" />
 
 <!-- UI icons -->
 <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
-<!--PDBe interactions component-->
-<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+<!--PDBe interactions plugin-->
+<script src="pdbe-interactions-plugin.js"></script>
+<link rel="stylesheet" href="pdbe-interactions.css" />
+
 ```
 
 and then the component can be instantiated as simply as:
diff --git a/demo_plugin.html b/demo_plugin.html
index b7dfb81..6341e3f 100644
--- a/demo_plugin.html
+++ b/demo_plugin.html
@@ -42,20 +42,20 @@
   <body>  
     <!--Mode A-->
     <div style="position: relative; float: left;">
-      <div style="width: 800px; height: 800px; position: relative">
+      <div style="width: 600px; height: 600px; position: relative">
       <div id='ligand-interaction'></div>
       </div>
     </div>
 
     <!--Mode B-->
     <div style="position: relative; float: left;">
-      <div style="width: 800px; height: 800px; position: relative">
+      <div style="width: 600px; height: 600px; position: relative">
       <div id='boundmolecule-interaction'></div>
     </div>
 
     <!--Mode C-->
     <div style="position: relative; float: left;">
-      <div style="width: 800px; height: 800px; position: relative">
+      <div style="width: 600px; height: 600px; position: relative">
         <div id='chem-comp'></div>
       </div>
     </div>
-- 
GitLab


From 7c787fe394a2c14962debcb12388fa11799a67d1 Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Tue, 4 Feb 2020 16:01:58 +0000
Subject: [PATCH 23/66] create url link rather than relative

---
 src/plugin/config.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index 2f193a5..0938e0b 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -1,7 +1,7 @@
 namespace Config {
     export const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
-    export const glycanSymbols: string = "snfg_visuals.xml";
-    export const glycanMapping: string = "het_mapping.json";
+    export const glycanSymbols: string = "http://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml";
+    export const glycanMapping: string = "http://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
 
 
     export const interactionClickEvent = 'PDB.interactions.click';
-- 
GitLab


From 8a4a0e7faf52bd8e6fb8f9115b304b741eda0cdf Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Tue, 4 Feb 2020 16:40:32 +0000
Subject: [PATCH 24/66] give URL link for pdbe-interactions-svg.css

---
 src/plugin/manager.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 957a312..e2d8042 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -281,7 +281,7 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
-        d3.text('pdbe-interactions-svg.css')
+        d3.text('http://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css')
             .then(x => {
                 let svgData = `
                 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" style="background-color: white;">
-- 
GitLab


From a4c79e056813b165027aa2fd6317373750a4f06e Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Wed, 5 Feb 2020 11:39:28 +0000
Subject: [PATCH 25/66] change to https

---
 src/plugin/config.ts  | 4 ++--
 src/plugin/manager.ts | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index 0938e0b..fe4b6cd 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -1,7 +1,7 @@
 namespace Config {
     export const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
-    export const glycanSymbols: string = "http://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml";
-    export const glycanMapping: string = "http://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
+    export const glycanSymbols: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml";
+    export const glycanMapping: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
 
 
     export const interactionClickEvent = 'PDB.interactions.click';
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index e2d8042..26098ed 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -281,7 +281,7 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
-        d3.text('http://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css')
+        d3.text('https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css')
             .then(x => {
                 let svgData = `
                 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" style="background-color: white;">
-- 
GitLab


From 6f7c1cf81db423dc4af0fea18d8f620bdaa56cb6 Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Wed, 5 Feb 2020 12:19:25 +0000
Subject: [PATCH 26/66] change chain_id to split by '-'

---
 src/plugin/model.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 027b8eb..e633f67 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -56,7 +56,7 @@ namespace Model {
         isLigand: boolean;
 
         constructor(data: any, isLigand: boolean) {
-            this.chainId = data.chain_id;
+            this.chainId = data.chain_id.split("-")[0];
             this.authorResidueNumber = data.author_residue_number;
             this.chemCompId = data.chem_comp_id;
             this.authorInsertionCode = data.author_insertion_code;
-- 
GitLab


From 2dac7d4218cf301dff458583b570ff97caf3df1d Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Wed, 5 Feb 2020 13:20:05 +0000
Subject: [PATCH 27/66] Revert "change chain_id to split by '-'"

This reverts commit 6f7c1cf81db423dc4af0fea18d8f620bdaa56cb6.
---
 src/plugin/model.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index e633f67..027b8eb 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -56,7 +56,7 @@ namespace Model {
         isLigand: boolean;
 
         constructor(data: any, isLigand: boolean) {
-            this.chainId = data.chain_id.split("-")[0];
+            this.chainId = data.chain_id;
             this.authorResidueNumber = data.author_residue_number;
             this.chemCompId = data.chem_comp_id;
             this.authorInsertionCode = data.author_insertion_code;
-- 
GitLab


From 16af5fef11435fbb4c27bf3a063207f93e744b42 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Fri, 7 Feb 2020 16:30:45 +0000
Subject: [PATCH 28/66] unify colors with conservation component

First part done
---
 src/plugin/config.ts                 | 21 ++++----
 src/plugin/manager.ts                | 10 +++-
 src/plugin/model.ts                  |  9 ++--
 src/plugin/residuefactory.ts         | 73 ++++++++++++++++++++++++++++
 src/styles/pdbe-interactions-svg.css | 28 +++++++----
 5 files changed, 118 insertions(+), 23 deletions(-)
 create mode 100644 src/plugin/residuefactory.ts

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index fe4b6cd..beac3c6 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -2,7 +2,8 @@ namespace Config {
     export const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
     export const glycanSymbols: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml";
     export const glycanMapping: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
-
+    
+    export const residueTypeAPI: string = "https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/";
 
     export const interactionClickEvent = 'PDB.interactions.click';
     export const interactionMouseoverEvent = 'PDB.interactions.mouseover';
@@ -15,14 +16,16 @@ namespace Config {
     export const molstarMouseoverEvent = 'PDB.molstar.mouseover';
     export const molstarMouseoutEvent = 'PDB.molstar.mouseout';
 
-    export const aminoAcids = new Map<string, Array<string>>([
-        ['cystein', new Array<string>('CYS', 'SEC', 'CSO')],
-        ['positive', new Array<string>('LYS', 'ARG')],
-        ['negative', new Array<string>('ASP', 'GLU')],
-        ['polar', new Array<string>('SER', 'SEP', 'THR', 'ASN', 'GLN', 'TPO')],
-        ['aliphatic', new Array<string>('ALA', 'VAL', 'ILE', 'LEU', 'MET', 'PRO', 'MSE')],
-        ['aromatic', new Array<string>('TRP', 'TYR', 'PHE', 'HIS')]
-    ]);
+    export const aminoAcidTypes = new Map<string, Array<string>>([
+        ['hydrophobic', new Array<string>('A', 'I', 'L', 'M', 'F', 'W', 'V')],
+        ['positive', Array<string>('K', 'R')],
+        ['negative', Array<string>('E', 'D')],
+        ['polar', Array<string>('N', 'Q', 'S', 'T')],
+        ['cystein', Array<string>('C', 'U')],
+        ['glycine', Array<string>('G')],
+        ['proline', Array<string>('P')],
+        ['aromatic', Array<string>('H', 'Y')]
+    ]);    
 
     export const backboneAtoms = ['N', 'CA', 'C', 'O'];
 
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 26098ed..a0bb1f7 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -568,16 +568,23 @@ class Visualization {
             .data(this.bindingSite.interactionNodes)
             .enter().append('g');
 
+        let promises = this.nodes.data().map((x: Model.InteractionNode) => ResidueProvider.getInstance().downloadAnnotation(x.residue.chemCompId));
+
         // draw glycans
         await this.visualsMapper.graphicsPromise;
         await this.visualsMapper.mappingPromise;
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
-            .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`)
             .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, Config.interactionClickEvent))
             .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
+        Promise.all(promises).then(() => {
+            this.nodes
+                .filter((x: Model.InteractionNode) => !x.residue.isLigand)
+                .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`);
+        });
+
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand && this.visualsMapper.glycanMapping.has(x.residue.chemCompId))
             .html((e: Model.InteractionNode) => this.visualsMapper.getGlycanImage(e.residue.chemCompId));
 
@@ -636,7 +643,6 @@ class Visualization {
         this.links
             .append('line')
             .classed('svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
-            .attr('class', 'svg-shadow-bond')
             .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
             .on('mouseover', (x: Model.Link) => this.linkMouseOverEventHandler(x))
             .on('mouseout', () => this.linkMouseOutEventHandler());
diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 027b8eb..4d6945c 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -76,14 +76,17 @@ namespace Model {
             if (this.chemCompId === 'HOH') {
                 return 'water';
             }
+            console.log(ResidueProvider.getInstance().mapping);
+            let code = ResidueProvider.getInstance().getAminoAcidAbbreviation(this.chemCompId);
 
-            for (let [key, value] of Config.aminoAcids) {
-                if (value.includes(this.chemCompId)) {
+            for (let [key, value] of Config.aminoAcidTypes) {
+                console.log(`Looking up ${code} in ${value}`);
+                if (value.includes(code)) {
                     return key;
                 }
             }
 
-            return 'others';
+            return 'other';
         }
 
         public equals(other: Residue): boolean {
diff --git a/src/plugin/residuefactory.ts b/src/plugin/residuefactory.ts
new file mode 100644
index 0000000..2e26d56
--- /dev/null
+++ b/src/plugin/residuefactory.ts
@@ -0,0 +1,73 @@
+/**
+ * Singleton instance to provide residue abbreviations to the component
+ *
+ * @class ResidueProvider
+ */
+class ResidueProvider {
+    private static instance: ResidueProvider;
+    public mapping: Map<string, string>;
+
+
+    /**
+     * The Singleton's constructor should always be private to prevent direct
+     * construction calls with the `new` operator.
+     * @memberof ResidueProvider
+     */
+    private constructor() {
+        this.mapping = new Map<string, string>();
+    }
+
+
+    /**
+     * The static method that controls the access to the singleton instance.
+     *
+     * This implementation let you subclass the Singleton class while keeping
+     * just one instance of each subclass around.
+     *
+     * @static
+     * @returns {ResidueProvider}
+     * @memberof ResidueProvider
+     */
+    public static getInstance(): ResidueProvider {
+        if (!ResidueProvider.instance) {
+            ResidueProvider.instance = new ResidueProvider();
+        }
+
+        return ResidueProvider.instance;
+    }
+
+
+    /**
+     * Get single letter abbreviation of the ligand.
+     *
+     * @param {string} name Name of the chemical compound
+     * @returns Single letter abbreviation of the ligand
+     * @memberof ResidueProvider
+     */
+    public getAminoAcidAbbreviation(name: string): string {
+        if (this.mapping.has(name)) return this.mapping.get(name);
+
+        else { 
+            this.downloadAnnotation(name)
+        }
+    }
+
+
+    /**
+     * Fetch single letter abbreviations from API if they are not present
+     *
+     * @param {string} n
+     * @returns
+     * @memberof ResidueProvider
+     */
+    public async downloadAnnotation(n: string): Promise<string> {
+        return d3.json(`${Config.residueTypeAPI}${n}`).then(x => {
+            let code = x[n][0].one_letter_code;
+            this.mapping.set(n, code);
+
+            return code
+        });
+
+
+    }
+}
\ No newline at end of file
diff --git a/src/styles/pdbe-interactions-svg.css b/src/styles/pdbe-interactions-svg.css
index 4a397dc..a3a211e 100644
--- a/src/styles/pdbe-interactions-svg.css
+++ b/src/styles/pdbe-interactions-svg.css
@@ -113,36 +113,46 @@
 
 .svg-cystein-res {
     stroke: #A9A9A9;
-    fill: yellow;
+    fill: #F08080;
 }
 
 .svg-positive-res {
     stroke: #A9A9A9;
-    fill: #007FFF;
+    fill: #F01505;
 }
 
 .svg-negative-res {
     stroke: #A9A9A9;
-    fill: #FF4500;
+    fill: #C048C0;
+}
+
+.svg-proline-res {
+    stroke: #A9A9A9;
+    fill: #C0C000;
 }
 
 .svg-polar-res {
     stroke: #A9A9A9;
-    fill: #9DC183;
+    fill: #15C015;
 }
 
 .svg-aromatic-res {
     stroke: #A9A9A9;
-    fill: #FFA2FF;
+    fill: #15A4A4;
 }
 
-.svg-aliphatic-res {
+.svg-hydrophobic-res {
     stroke: #A9A9A9;
-    fill: #808080;
+    fill: #80A0f0;
 }
 
-.svg-others-res {
+.svg-glycine-res {
+    stroke: #A9A9A9;
+    fill: #F09048;
+}
+ 
+.svg-other-res {
     stroke: #A9A9A9;
-    fill: #C0C0C0;
+    fill: #F2F2F2;
 
 }
\ No newline at end of file
-- 
GitLab


From 62283f53483e57366772fd9df80e973c00a864ff Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 10 Feb 2020 15:20:47 +0000
Subject: [PATCH 29/66] unify colors with sequence conservation

---
 src/plugin/config.ts                 | 27 +++++++++++++++++++++--
 src/plugin/manager.ts                | 26 +++++++++++-----------
 src/plugin/model.ts                  |  7 +++---
 src/plugin/residuefactory.ts         | 26 +++++++++++-----------
 src/plugin/ui.ts                     | 32 +++++++++++++++++-----------
 src/styles/pdbe-interactions-svg.css |  2 +-
 6 files changed, 75 insertions(+), 45 deletions(-)

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index beac3c6..650a8ce 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -16,7 +16,7 @@ namespace Config {
     export const molstarMouseoverEvent = 'PDB.molstar.mouseover';
     export const molstarMouseoutEvent = 'PDB.molstar.mouseout';
 
-    export const aminoAcidTypes = new Map<string, Array<string>>([
+    export const aaTypes = new Map<string, Array<string>>([
         ['hydrophobic', new Array<string>('A', 'I', 'L', 'M', 'F', 'W', 'V')],
         ['positive', Array<string>('K', 'R')],
         ['negative', Array<string>('E', 'D')],
@@ -25,7 +25,30 @@ namespace Config {
         ['glycine', Array<string>('G')],
         ['proline', Array<string>('P')],
         ['aromatic', Array<string>('H', 'Y')]
-    ]);    
+    ]);
+    
+    export const aaAbreviations = new Map<string, string>([
+        ['ALA', 'A'],
+        ['ARG', 'R'],
+        ['ASN', 'N'],
+        ['ASP', 'D'],
+        ['CYS', 'C'],
+        ['GLU', 'E'],
+        ['GLN', 'Q'],
+        ['GLY', 'G'],
+        ['HIS', 'H'],
+        ['ILE', 'I'],
+        ['LEU', 'L'],
+        ['LYS', 'K'],
+        ['MET', 'M'],
+        ['PHE', 'F'],
+        ['PRO', 'P'],
+        ['SER', 'S'],
+        ['THR', 'T'],
+        ['TRP', 'W'],
+        ['TYR', 'Y'],
+        ['VAL', 'V']
+    ]);
 
     export const backboneAtoms = ['N', 'CA', 'C', 'O'];
 
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index a0bb1f7..20d7084 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -26,6 +26,8 @@ class Visualization {
     private visualsMapper: VisualsMapper;
     private interactionsData: any;
     private selectedResidueHash: string;
+
+    private rProvider: ResidueProvider;
     // #endregion
 
     constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
@@ -33,6 +35,7 @@ class Visualization {
         this.parent.style.cssText += "display: block; height: 100%; width: 100%; position: relative;";
 
         this.visualsMapper = new VisualsMapper();
+        this.rProvider = ResidueProvider.getInstance();
 
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
 
@@ -561,30 +564,26 @@ class Visualization {
             });
 
 
-        //setup nodes
+        // setup nodes
+        
+        this.bindingSite.interactionNodes.forEach(x => this.rProvider.downloadAnnotation(x.residue));
         this.nodes = this.nodesRoot.append('g')
             .attr('id', 'nodes')
             .selectAll()
             .data(this.bindingSite.interactionNodes)
             .enter().append('g');
 
-        let promises = this.nodes.data().map((x: Model.InteractionNode) => ResidueProvider.getInstance().downloadAnnotation(x.residue.chemCompId));
 
-        // draw glycans
-        await this.visualsMapper.graphicsPromise;
-        await this.visualsMapper.mappingPromise;
+        // wait for resources to be ready or crash.
+        await Promise.all(this.rProvider.downloadPromises);
+        await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
             .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, Config.interactionClickEvent))
+            .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`)
             .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
-        Promise.all(promises).then(() => {
-            this.nodes
-                .filter((x: Model.InteractionNode) => !x.residue.isLigand)
-                .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`);
-        });
-
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand && this.visualsMapper.glycanMapping.has(x.residue.chemCompId))
             .html((e: Model.InteractionNode) => this.visualsMapper.getGlycanImage(e.residue.chemCompId));
 
@@ -652,6 +651,8 @@ class Visualization {
             .attr('class', (x: Model.Link) => `svg-bond svg-bond-${x.getLinkClass()}`)
             .attr('marker-end', (x: Model.Link) => `url(#arrow-${x.getLinkClass()})`);
 
+
+        this.bindingSite.interactionNodes.forEach(x => ResidueProvider.getInstance().downloadAnnotation(x.residue));
         this.nodes = this.nodesRoot
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -662,8 +663,7 @@ class Visualization {
             .on('mouseout', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
 
-        await this.visualsMapper.graphicsPromise;
-        await this.visualsMapper.mappingPromise;
+        await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise, ResidueProvider.getInstance().downloadPromises]);
 
         this.nodes.filter((n: Model.InteractionNode) =>
             this.visualsMapper.glycanMapping.has(n.residue.chemCompId))
diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 4d6945c..573acd8 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -61,7 +61,7 @@ namespace Model {
             this.chemCompId = data.chem_comp_id;
             this.authorInsertionCode = data.author_insertion_code;
             this.id = `${this.chainId}${this.authorResidueNumber}${(this.authorInsertionCode === ' ' ? '' : this.authorInsertionCode)}`;
-            this.isLigand = isLigand
+            this.isLigand = isLigand;
         }
 
         /**
@@ -76,11 +76,10 @@ namespace Model {
             if (this.chemCompId === 'HOH') {
                 return 'water';
             }
-            console.log(ResidueProvider.getInstance().mapping);
+
             let code = ResidueProvider.getInstance().getAminoAcidAbbreviation(this.chemCompId);
 
-            for (let [key, value] of Config.aminoAcidTypes) {
-                console.log(`Looking up ${code} in ${value}`);
+            for (let [key, value] of Config.aaTypes) {
                 if (value.includes(code)) {
                     return key;
                 }
diff --git a/src/plugin/residuefactory.ts b/src/plugin/residuefactory.ts
index 2e26d56..30f163f 100644
--- a/src/plugin/residuefactory.ts
+++ b/src/plugin/residuefactory.ts
@@ -5,7 +5,8 @@
  */
 class ResidueProvider {
     private static instance: ResidueProvider;
-    public mapping: Map<string, string>;
+    private mapping: Map<string, string>;
+    public downloadPromises: Array<Promise<any>>;
 
 
     /**
@@ -14,7 +15,8 @@ class ResidueProvider {
      * @memberof ResidueProvider
      */
     private constructor() {
-        this.mapping = new Map<string, string>();
+        this.mapping = new Map<string, string>(Config.aaAbreviations);
+        this.downloadPromises = new Array<Promise<any>>();
     }
 
 
@@ -45,11 +47,7 @@ class ResidueProvider {
      * @memberof ResidueProvider
      */
     public getAminoAcidAbbreviation(name: string): string {
-        if (this.mapping.has(name)) return this.mapping.get(name);
-
-        else { 
-            this.downloadAnnotation(name)
-        }
+        return this.mapping.has(name) ? this.mapping.get(name) : undefined;
     }
 
 
@@ -60,14 +58,16 @@ class ResidueProvider {
      * @returns
      * @memberof ResidueProvider
      */
-    public async downloadAnnotation(n: string): Promise<string> {
-        return d3.json(`${Config.residueTypeAPI}${n}`).then(x => {
-            let code = x[n][0].one_letter_code;
-            this.mapping.set(n, code);
+    public downloadAnnotation(r: Model.Residue): void {
+        if (this.mapping.has(r.chemCompId) || r.isLigand) return;
 
-            return code
+        let res = d3.json(`${Config.residueTypeAPI}${r.chemCompId}`).then(x => {
+            let code = x[r.chemCompId][0].one_letter_code;
+            this.mapping.set(r.chemCompId, code);
+            
+            return code;
         });
 
-
+        this.downloadPromises.push(res);
     }
 }
\ No newline at end of file
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index b23e524..0fecac2 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -3,38 +3,38 @@ let helpLigands = `
     <table class='int-help-table'>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #808080; "></div>
+                <div class="int-help-residue" style="background: #80A0F0; "></div>
             </td>
-            <td>aliphatic</td>
+            <td>hydrophobic</td>
             <td>
-                <div class="int-help-residue" style="background: #FF4500;"></div>
+                <div class="int-help-residue" style="background: #C048C0;"></div>
             </td>
             <td>negativelly charged</td>
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #FFA2FF;"></div>
+                <div class="int-help-residue" style="background: #15A4A4;"></div>
             </td>
             <td>aromatic</td>
             <td>
-                <div class="int-help-residue" style="background: #C0C0C0;"></div>
+                <div class="int-help-residue" style="background: #F2F2F2;"></div>
             </td>
             <td>other</td>
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: yellow;"></div>
+                <div class="int-help-residue" style="background: #F08080;"></div>
             </td>
             <td>cystein</td>
             <td>
-                <div class="int-help-residue" style="background: #9DC183;"></div>
+                <div class="int-help-residue" style="background: #15C015;"></div>
             </td>
             <td>polar</td>
             <td>
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #007FFF;"></div>
+                <div class="int-help-residue" style="background: #F01505;"></div>
             </td>
             <td>positivelly charged</td>
             <td>
@@ -44,11 +44,19 @@ let helpLigands = `
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: white; border: 1.2px solid black;"></div>
+                 <div class="int-help-residue" style="background: #F09048;"></div>
+            </td>
+            <td>glycine</td>                            
+            <td>
+                <div class="int-help-residue" style="background: #F2F2F2; border: 1.2px solid black;"></div>
             </td>
             <td>bound molecule</td>
-            <td></td>
-            <td><a href="https://www.ncbi.nlm.nih.gov/glycans/snfg.html" target="blank">glycans (SNFG)</a></td>
+        </tr>
+        <tr>
+        <td></td>
+        <td><a href="https://www.ncbi.nlm.nih.gov/glycans/snfg.html" target="blank">glycans (SNFG)</a></td>
+        <td></td>
+        <td></td>
         </tr>
     </table>
     `
@@ -328,7 +336,7 @@ class UI {
      * @memberof UI
      */
     private fullScreen() {
-        let btn = d3.select(this.parent).select('#int-fullscreen-btn');        
+        let btn = d3.select(this.parent).select('#int-fullscreen-btn');
 
         if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
             this.parent.parentElement.style.width = '100%'
diff --git a/src/styles/pdbe-interactions-svg.css b/src/styles/pdbe-interactions-svg.css
index a3a211e..f539d7b 100644
--- a/src/styles/pdbe-interactions-svg.css
+++ b/src/styles/pdbe-interactions-svg.css
@@ -143,7 +143,7 @@
 
 .svg-hydrophobic-res {
     stroke: #A9A9A9;
-    fill: #80A0f0;
+    fill: #80A0F0;
 }
 
 .svg-glycine-res {
-- 
GitLab


From 9d8f37d2e4f8bf3a9fe48910c47b4feb876f7062 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 10 Feb 2020 18:16:31 +0000
Subject: [PATCH 30/66] code cleanup

---
 src/plugin/manager.ts | 137 +++++++++++++++++++-----------------------
 src/plugin/model.ts   |  12 ++++
 2 files changed, 74 insertions(+), 75 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 20d7084..f25fd14 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -508,6 +508,53 @@ class Visualization {
     // #endregion fire events
 
 
+    //#region setup scene micromethods
+    private wipeOutVisuals() {
+        this.nodesRoot.selectAll('*').remove();
+        this.linksRoot.selectAll('*').remove();
+    }
+
+    private setupLinks() {
+        this.links = this.linksRoot
+            .selectAll()
+            .data(this.bindingSite.links)
+            .enter().append('g');
+
+        this.links
+            .append('line')
+            .classed('svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
+            .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
+            .on('mouseenter', (x: Model.Link) => this.linkMouseOverEventHandler(x))
+            .on('mouseleave', () => this.linkMouseOutEventHandler());
+
+        this.links
+            .append('line')
+            .attr('class', (e: Model.Link) => `svg-bond svg-bond-${e.getLinkClass()}`)
+            .attr('marker-mid', (e: Model.Link) => e.hasClash() ? 'url(#clash)' : '');
+    }
+
+    // private setupNodes() {
+
+    // }
+
+    private addNodeLabels(selection: any) {
+        selection
+            .append('text')
+            .style('text-anchor', 'middle')
+            .style('dominant-baseline', 'central')
+            .each(function (e: Model.InteractionNode) {
+                let labels = [e.residue.chemCompId, `${e.residue.chainId} ${e.residue.authorResidueNumber}`];
+                for (var i = 0; i < labels.length; i++) {
+                    d3.select(this)
+                        .append('tspan')
+                        .attr('dy', (i * 20) - 4)
+                        .attr('x', 0)
+                        .text(labels[i]);
+                }
+            });
+    }
+    //#endregion
+
     private selectLigand(n: Model.InteractionNode, i: number, g: any) {
         this.fireExternalNodeEvent(n, Config.interactionClickEvent);
 
@@ -521,8 +568,7 @@ class Visualization {
 
 
     private async setupLigandScene() {
-        this.nodesRoot.selectAll('*').remove();
-        this.linksRoot.selectAll('*').remove();
+        this.wipeOutVisuals();
 
         let xShift = (this.parent.offsetWidth / 2) - (this.depiction.resolution.x / 2);
         let yShift = (this.parent.offsetHeight / 2) - (this.depiction.resolution.y / 2);
@@ -532,22 +578,7 @@ class Visualization {
         this.linksRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
 
 
-        this.links = this.linksRoot
-            .selectAll()
-            .data(this.bindingSite.links)
-            .enter().append('g');
-
-        this.links
-            .append('line')
-            .classed('svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
-            .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
-            .on('mouseenter', (x: Model.Link) => this.linkMouseOverEventHandler(x))
-            .on('mouseleave', () => this.linkMouseOutEventHandler());
-
-        this.links
-            .append('line')
-            .attr('class', (e: Model.LigandResidueLink) => `svg-bond svg-bond-${e.getLinkClass()}`)
-            .attr('marker-mid', (e: Model.LigandResidueLink) => e.hasClash() ? 'url(#clash)' : '');
+        this.setupLinks();
 
         this.bindingSite.interactionNodes
             .filter((x: Model.InteractionNode) => !x.residue.isLigand)
@@ -564,20 +595,17 @@ class Visualization {
             });
 
 
-        // setup nodes
-        
+        // setup nodes; wait for resources to be ready
         this.bindingSite.interactionNodes.forEach(x => this.rProvider.downloadAnnotation(x.residue));
+        await Promise.all(this.rProvider.downloadPromises);
+        await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
+        
         this.nodes = this.nodesRoot.append('g')
-            .attr('id', 'nodes')
             .selectAll()
             .data(this.bindingSite.interactionNodes)
             .enter().append('g');
 
 
-        // wait for resources to be ready or crash.
-        await Promise.all(this.rProvider.downloadPromises);
-        await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
             .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, Config.interactionClickEvent))
             .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`)
@@ -592,21 +620,8 @@ class Visualization {
             .append('circle')
             .attr('r', (x: Model.InteractionNode) => x.scale * 25);
 
-        this.nodes
-            .filter((x: Model.InteractionNode) => !x.residue.isLigand)
-            .append('text')
-            .style('text-anchor', 'middle')
-            .style('dominant-baseline', 'central')
-            .each(function (e: Model.InteractionNode) {
-                let labels = [e.residue.chemCompId, `${e.residue.chainId} ${e.residue.authorResidueNumber}`];
-                for (var i = 0; i < labels.length; i++) {
-                    d3.select(this)
-                        .append('tspan')
-                        .attr('dy', (i * 20) - 4)
-                        .attr('x', 0)
-                        .text(labels[i]);
-                }
-            });
+        let nodesWithText = this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand);
+        this.addNodeLabels(nodesWithText);
 
         //        let forceLink = d3.forceLink()
         //            .links(visuals.links)
@@ -631,28 +646,14 @@ class Visualization {
 
 
     private async setupScene() {
-        this.linksRoot.selectAll('*').remove();
-        this.nodesRoot.selectAll('*').remove();
-
-        this.links = this.linksRoot
-            .selectAll()
-            .data(this.bindingSite.links)
-            .enter().append('g')
-
-        this.links
-            .append('line')
-            .classed('svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
-            .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
-            .on('mouseover', (x: Model.Link) => this.linkMouseOverEventHandler(x))
-            .on('mouseout', () => this.linkMouseOutEventHandler());
-
-        this.links
-            .append('line')
-            .attr('class', (x: Model.Link) => `svg-bond svg-bond-${x.getLinkClass()}`)
-            .attr('marker-end', (x: Model.Link) => `url(#arrow-${x.getLinkClass()})`);
-
+        this.wipeOutVisuals();
+        this.setupLinks();
 
+        // setup nodes; wait for resources to be ready
         this.bindingSite.interactionNodes.forEach(x => ResidueProvider.getInstance().downloadAnnotation(x.residue));
+        await Promise.all(this.rProvider.downloadPromises);
+        await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
+        
         this.nodes = this.nodesRoot
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -663,8 +664,6 @@ class Visualization {
             .on('mouseout', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
 
-        await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise, ResidueProvider.getInstance().downloadPromises]);
-
         this.nodes.filter((n: Model.InteractionNode) =>
             this.visualsMapper.glycanMapping.has(n.residue.chemCompId))
             .html((e: Model.InteractionNode) => this.visualsMapper.getGlycanImage(e.residue.chemCompId));
@@ -673,19 +672,7 @@ class Visualization {
             .append('circle')
             .attr('r', '25');
 
-        this.nodes.append('text')
-            .style('text-anchor', 'middle')
-            .style('dominant-baseline', 'central')
-            .each(function (e: Model.InteractionNode) {
-                let labels = [e.residue.chemCompId, `${e.residue.chainId} ${e.residue.authorResidueNumber}`];
-                for (var i = 0; i < labels.length; i++) {
-                    d3.select(this)
-                        .append('tspan')
-                        .attr('dy', (i * 20) - 4)
-                        .attr('x', 0)
-                        .text(labels[i]);
-                }
-            });
+        this.addNodeLabels(this.nodes);
 
         let forceLink = d3.forceLink()
             .links(this.bindingSite.links)
diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 573acd8..07b26e4 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -147,6 +147,7 @@ namespace Model {
         target: InteractionNode;
 
         getLinkClass(): string;
+        hasClash(): boolean;
         toTooltip(): string;
     }
 
@@ -174,6 +175,17 @@ namespace Model {
             return this.target.equals(n) || this.source.equals(n);
         }
 
+        public hasClash(): boolean {
+            this.interactions.forEach(x => {
+                if (x.includes('clash')) {
+                    return true
+                }
+            });
+            return false;
+        }
+
+
+
         /**
          * Shorthand to check if the link contains particular underlying
          * residue.
-- 
GitLab


From 9d686b84c7dd3748e426a9274023b7f43b7a8f4c Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 10 Feb 2020 18:19:33 +0000
Subject: [PATCH 31/66] center scene on simulation end.

---
 src/plugin/manager.ts | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index f25fd14..be1dc6e 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -599,7 +599,7 @@ class Visualization {
         this.bindingSite.interactionNodes.forEach(x => this.rProvider.downloadAnnotation(x.residue));
         await Promise.all(this.rProvider.downloadPromises);
         await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-        
+
         this.nodes = this.nodesRoot.append('g')
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -637,7 +637,8 @@ class Visualization {
             //            .force('charge', charge) //strength 
             .force('collision', collision)
             //                    .force('center', center)
-            .on('tick', () => this.simulationStep());
+            .on('tick', () => this.simulationStep())
+            .on('end', () => this.centerScene());
 
         this.dragHandler(this.nodes);
         if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, d3.zoomIdentity);
@@ -653,7 +654,7 @@ class Visualization {
         this.bindingSite.interactionNodes.forEach(x => ResidueProvider.getInstance().downloadAnnotation(x.residue));
         await Promise.all(this.rProvider.downloadPromises);
         await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-        
+
         this.nodes = this.nodesRoot
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -688,7 +689,8 @@ class Visualization {
             .force('charge', charge) //strength 
             .force('collision', collision)
             .force('center', center)
-            .on('tick', () => this.simulationStep());
+            .on('tick', () => this.simulationStep())
+            .on('end', () => this.centerScene());
 
         this.dragHandler(this.nodes);
 
-- 
GitLab


From cc631a1da1f204d8c14568b106f0e094e7d55980 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 10:32:28 +0000
Subject: [PATCH 32/66] code cleanup

---
 src/plugin/config.ts         |  6 ------
 src/plugin/manager.ts        | 10 ++++++----
 src/plugin/residuefactory.ts |  2 +-
 src/plugin/resources.ts      | 12 ++++++++++++
 src/plugin/ui.ts             |  2 +-
 src/plugin/visualsMapping.ts |  4 ++--
 6 files changed, 22 insertions(+), 14 deletions(-)
 create mode 100644 src/plugin/resources.ts

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index 650a8ce..9f65507 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -1,10 +1,4 @@
 namespace Config {
-    export const server: string = "https://wwwdev.ebi.ac.uk/pdbe/graph-api";
-    export const glycanSymbols: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml";
-    export const glycanMapping: string = "https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json";
-    
-    export const residueTypeAPI: string = "https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/";
-
     export const interactionClickEvent = 'PDB.interactions.click';
     export const interactionMouseoverEvent = 'PDB.interactions.mouseover';
     export const interactionMouseoutEvent = 'PDB.interactions.mouseout'
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index be1dc6e..0b67788 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -143,7 +143,7 @@ class Visualization {
     public initBoundMoleculeInteractions(pdbid: string, bmId: string) {
         this.pdbId = pdbid;
 
-        d3.json(`${Config.server}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
+        d3.json(`${Resources.apiServer}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
             .catch(e => { throw e; })
             .then((data: any) => {
                 this.addBoundMoleculeInteractions(data, bmId);
@@ -165,7 +165,7 @@ class Visualization {
     public initLigandInteractions(pdbId: string, resId: number, chainId: string) {
         this.pdbId = pdbId;
 
-        d3.json(`${Config.server}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
+        d3.json(`${Resources.apiServer}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
             .catch(e => { throw e; })
             .then((data: any) => {
                 this.addLigandInteractions(data);
@@ -181,7 +181,9 @@ class Visualization {
      * @memberof Visualization
      */
     public async initLigandDisplay(ligandId: string) {
-        return d3.json(`https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/${ligandId}/annotation`)
+        const ligandUrl = Resources.ligandAnnotationURL(ligandId);
+        
+        return d3.json(ligandUrl)
             .catch(e => { throw e; })
             .then((d: any) => this.addDepiction(d));
     }
@@ -284,7 +286,7 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
-        d3.text('https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css')
+        d3.text(Resources.componentSvgCss)
             .then(x => {
                 let svgData = `
                 <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" style="background-color: white;">
diff --git a/src/plugin/residuefactory.ts b/src/plugin/residuefactory.ts
index 30f163f..b488d45 100644
--- a/src/plugin/residuefactory.ts
+++ b/src/plugin/residuefactory.ts
@@ -61,7 +61,7 @@ class ResidueProvider {
     public downloadAnnotation(r: Model.Residue): void {
         if (this.mapping.has(r.chemCompId) || r.isLigand) return;
 
-        let res = d3.json(`${Config.residueTypeAPI}${r.chemCompId}`).then(x => {
+        let res = d3.json(`${Resources.residueTypeAPI}${r.chemCompId}`).then(x => {
             let code = x[r.chemCompId][0].one_letter_code;
             this.mapping.set(r.chemCompId, code);
             
diff --git a/src/plugin/resources.ts b/src/plugin/resources.ts
new file mode 100644
index 0000000..0ae690e
--- /dev/null
+++ b/src/plugin/resources.ts
@@ -0,0 +1,12 @@
+namespace Resources { 
+    export const apiServer: string = 'https://wwwdev.ebi.ac.uk/pdbe/graph-api';
+    export const glycanSymbols: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml';
+    export const glycanMapping: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json';
+    export const componentSvgCss: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css';
+
+    export const residueTypeAPI: string = "https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/";
+
+    export function ligandAnnotationURL(ligandName: string): string { 
+        return `https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/${ligandName}/annotation`;
+    }
+}
\ No newline at end of file
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index 0fecac2..87b0cc6 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -48,7 +48,7 @@ let helpLigands = `
             </td>
             <td>glycine</td>                            
             <td>
-                <div class="int-help-residue" style="background: #F2F2F2; border: 1.2px solid black;"></div>
+                <div class="int-help-residue" style="background: white; border: 1.2px solid black;"></div>
             </td>
             <td>bound molecule</td>
         </tr>
diff --git a/src/plugin/visualsMapping.ts b/src/plugin/visualsMapping.ts
index 6b1ed2b..de34c5c 100644
--- a/src/plugin/visualsMapping.ts
+++ b/src/plugin/visualsMapping.ts
@@ -18,8 +18,8 @@ class VisualsMapper {
         this.glycanMapping = new Map<string, string>();
         this.glycanImages = new Map<string, SVGElement>();
 
-        this.graphicsPromise = this.parseSymbols(Config.glycanSymbols);
-        this.mappingPromise = this.parseGlycanMapping(Config.glycanMapping);        
+        this.graphicsPromise = this.parseSymbols(Resources.glycanSymbols);
+        this.mappingPromise = this.parseGlycanMapping(Resources.glycanMapping);        
     }
     
     /**
-- 
GitLab


From 3e649a2b5252ae83943686409bf4d1332a1065fd Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 10:41:32 +0000
Subject: [PATCH 33/66] rename of css classes

---
 src/plugin/depiction.ts              |  2 +-
 src/plugin/manager.ts                | 10 ++--
 src/plugin/ui.ts                     | 84 ++++++++++++++--------------
 src/styles/pdbe-interactions-svg.css | 60 ++++++++++----------
 src/styles/pdbe-interactions.css     | 50 ++++++++---------
 5 files changed, 103 insertions(+), 103 deletions(-)

diff --git a/src/plugin/depiction.ts b/src/plugin/depiction.ts
index ede9308..0cd076c 100644
--- a/src/plugin/depiction.ts
+++ b/src/plugin/depiction.ts
@@ -181,7 +181,7 @@ class Depiction {
         this.structure.selectAll()
             .data(this.atoms.filter(x => Object.keys(x.label).length != 0))
             .enter().append('circle')
-            .attr('class', 'svg-shadow-node')
+            .classed('pdbe-int-svg-shadow-node', true)
             .attr('cx', (x: any) => x.position.x)
             .attr('cy', (x: any) => x.position.y)
             .attr('r', 15);
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 0b67788..fb7b69b 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -43,7 +43,7 @@ class Visualization {
 
         this.svg = d3.select(this.parent)
             .append('div')
-            .attr('id', 'pdbe-ligand-display-root')
+            .attr('id', 'pdbe-int-root')
             .append('svg')
             .style('background-color', 'white')
             .attr('xmlns', 'http://www.w3.org/2000/svg')
@@ -524,14 +524,14 @@ class Visualization {
 
         this.links
             .append('line')
-            .classed('svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
+            .classed('pdbe-int-svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
             .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
             .on('mouseenter', (x: Model.Link) => this.linkMouseOverEventHandler(x))
             .on('mouseleave', () => this.linkMouseOutEventHandler());
 
         this.links
             .append('line')
-            .attr('class', (e: Model.Link) => `svg-bond svg-bond-${e.getLinkClass()}`)
+            .attr('class', (e: Model.Link) => `pdbe-int-svg-bond pdbe-int-svg-bond-${e.getLinkClass()}`)
             .attr('marker-mid', (e: Model.Link) => e.hasClash() ? 'url(#clash)' : '');
     }
 
@@ -610,7 +610,7 @@ class Visualization {
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
             .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, Config.interactionClickEvent))
-            .attr('class', (x: Model.InteractionNode) => `svg-node svg-${x.residue.getResidueType()}-res`)
+            .attr('class', (x: Model.InteractionNode) => `pdbe-int-svg-node pdbe-int-svg-${x.residue.getResidueType()}-res`)
             .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
@@ -661,7 +661,7 @@ class Visualization {
             .selectAll()
             .data(this.bindingSite.interactionNodes)
             .enter().append('g')
-            .attr('class', (e: Model.InteractionNode) => `svg-node svg-${e.residue.getResidueType()}-res`)
+            .attr('class', (e: Model.InteractionNode) => `pdbe-int-svg-node pdbe-int-svg-${e.residue.getResidueType()}-res`)
             .on('click', (x: Model.InteractionNode, i: number, g: any) => this.selectLigand(x, i, g))
             .on('mouseover', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseout', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index 87b0cc6..ecec54c 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -1,54 +1,54 @@
 // #region help
 let helpLigands = `
-    <table class='int-help-table'>
+    <table class='pdbe-int-help-table'>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #80A0F0; "></div>
+                <div class="pdbe-int-help-residue" style="background: #80A0F0; "></div>
             </td>
             <td>hydrophobic</td>
             <td>
-                <div class="int-help-residue" style="background: #C048C0;"></div>
+                <div class="pdbe-int-help-residue" style="background: #C048C0;"></div>
             </td>
             <td>negativelly charged</td>
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #15A4A4;"></div>
+                <div class="pdbe-int-help-residue" style="background: #15A4A4;"></div>
             </td>
             <td>aromatic</td>
             <td>
-                <div class="int-help-residue" style="background: #F2F2F2;"></div>
+                <div class="pdbe-int-help-residue" style="background: #F2F2F2;"></div>
             </td>
             <td>other</td>
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #F08080;"></div>
+                <div class="pdbe-int-help-residue" style="background: #F08080;"></div>
             </td>
             <td>cystein</td>
             <td>
-                <div class="int-help-residue" style="background: #15C015;"></div>
+                <div class="pdbe-int-help-residue" style="background: #15C015;"></div>
             </td>
             <td>polar</td>
             <td>
         </tr>
         <tr>
             <td>
-                <div class="int-help-residue" style="background: #F01505;"></div>
+                <div class="pdbe-int-help-residue" style="background: #F01505;"></div>
             </td>
             <td>positivelly charged</td>
             <td>
-                <div class="int-help-residue" style="background: #00BFFF;"></div>
+                <div class="pdbe-int-help-residue" style="background: #00BFFF;"></div>
             </td>
             <td>water</td>                    
         </tr>
         <tr>
             <td>
-                 <div class="int-help-residue" style="background: #F09048;"></div>
+                 <div class="pdbe-int-help-residue" style="background: #F09048;"></div>
             </td>
             <td>glycine</td>                            
             <td>
-                <div class="int-help-residue" style="background: white; border: 1.2px solid black;"></div>
+                <div class="pdbe-int-help-residue" style="background: white; border: 1.2px solid black;"></div>
             </td>
             <td>bound molecule</td>
         </tr>
@@ -61,7 +61,7 @@ let helpLigands = `
     </table>
     `
 let helpBonds = `
-<table class='int-help-table' style="border-bottom: 0.5px solid black; padding-bottom: 10px;">
+<table class='pdbe-int-help-table' style="border-bottom: 0.5px solid black; padding-bottom: 10px;">
 <tr>
     <td>
         <hr style="border: 0 none; border-top: 5px solid #AD4379; background: none; height: 0;" />
@@ -99,7 +99,7 @@ let helpBonds = `
     <td>vdw</td>
 </tr>
 </table>
-<table class="int-help-table" style="margin-top: 5px;">
+<table class="pdbe-int-help-table" style="margin-top: 5px;">
 <tr>
     <td>
         <hr style="border: 0 none; border-top: 5px solid black; background: none; height: 0;" />
@@ -153,25 +153,25 @@ class UI {
 
         let toolbar = d3.select(this.parent)
             .append('div')
-            .classed('int-toolbar-container', true)
+            .classed('pdbe-int-toolbar-container', true)
             .on('mouseover', () => this.displayToolbarPanel(true))
             .on('mouseout', () => this.displayToolbarPanel(false));
 
         toolbar.append('div')
-            .classed('int-menu-panel', true)
+            .classed('pdbe-int-menu-panel', true)
             .append('i')
             .attr('title', 'Menu')
             .attr('class', 'icon icon-common icon-bars');
 
         let dynamicPanel = toolbar.append('div')
-            .classed('int-menu-panel', true)
-            .attr('id', 'int-menu-dynamic-panel')
+            .classed('pdbe-int-menu-panel', true)
+            .attr('id', 'pdbe-int-menu-dynamic-panel')
             .style('display', 'none')
             .style('opacity', 0);
 
         if (params.fullScreen) {
             dynamicPanel.append('i')
-                .attr('id', 'int-fullscreen-btn')
+                .attr('id', 'pdbe-int-fullscreen-btn')
                 .attr('title', 'Fullscreen')
                 .attr('class', 'icon icon-common icon-fullscreen')
                 .on('click', () => this.fullScreen());
@@ -179,7 +179,7 @@ class UI {
 
         if (params.reinitialize) {
             dynamicPanel.append('i')
-                .attr('id', 'int-home-btn')
+                .attr('id', 'pdbe-int-home-btn')
                 .attr('title', 'Reset camera')
                 .attr('class', 'icon icon-common icon-sync-alt')
                 .on('click', () => this.reinitialize());
@@ -187,7 +187,7 @@ class UI {
 
         if (params.downloadImage) {
             dynamicPanel.append('i')
-                .attr('id', 'int-screenshot-btn')
+                .attr('id', 'pdbe-int-screenshot-btn')
                 .attr('title', 'Save SVG')
                 .attr('class', 'icon icon-common icon-camera')
                 .on('click', () => this.saveSVG());
@@ -195,7 +195,7 @@ class UI {
 
         if (params.downloadData) {
             dynamicPanel.append('i')
-                .attr('id', 'int-download-btn')
+                .attr('id', 'pdbe-int-download-btn')
                 .attr('title', 'Download interactions')
                 .attr('class', 'icon icon-common icon-download')
                 .on('click', () => this.download());
@@ -203,7 +203,7 @@ class UI {
 
         if (params.center) {
             dynamicPanel.append('i')
-                .attr('id', 'int-center-btn')
+                .attr('id', 'pdbe-int-center-btn')
                 .attr('title', 'Center screen')
                 .attr('class', 'icon icon-common icon-crosshairs')
                 .on('click', () => this.center());
@@ -211,40 +211,40 @@ class UI {
 
         if (params.help) {
             dynamicPanel.append('i')
-                .attr('id', 'int-help-btn')
+                .attr('id', 'pdbe-int-help-btn')
                 .attr('title', 'Show help')
                 .attr('class', 'icon icon-common icon-question-circle')
                 .on('click', () => this.showHelp());
 
-            let cont = d3.select(this.parent).append('div').attr('id', 'int-help-container')
-            let navbar = cont.append('div').classed('int-help-navbar', true);
+            let cont = d3.select(this.parent).append('div').attr('id', 'pdbe-int-help-container')
+            let navbar = cont.append('div').classed('pdbe-int-help-navbar', true);
 
             navbar.append('a')
                 .classed('active', true)
-                .attr('id', 'int-help-residues-btn')
+                .attr('id', 'pdbe-int-help-residues-btn')
                 .text('Ligands and residues')
                 .on('click', () => this.changeHelp(true));
 
             navbar.append('a')
-                .attr('id', 'int-help-bonds-btn')
+                .attr('id', 'pdbe-int-help-bonds-btn')
                 .text('Interactions')
                 .on('click', () => this.changeHelp(false));
 
-            cont.append('div').attr('id', 'int-help-ligands').html(helpLigands);
-            cont.append('div').attr('id', 'int-help-bonds').html(helpBonds);
+            cont.append('div').attr('id', 'pdbe-int-help-ligands').html(helpLigands);
+            cont.append('div').attr('id', 'pdbe-int-help-bonds').html(helpBonds);
         }
 
         if (params.tooltip) {
             this.tooltip = d3.select(this.parent).append('div')
-                .classed('int-label', true)
-                .attr('id', 'int-tooltip')
+                .classed('pdbe-int-label', true)
+                .attr('id', 'pdbe-int-tooltip')
                 .style('opacity', 0)
         }
 
         if (params.residueLabel) {
             this.residueLabel = d3.select(this.parent).append('div')
-                .classed('int-label', true)
-                .attr('id', 'int-residue-label')
+                .classed('pdbe-int-label', true)
+                .attr('id', 'pdbe-int-residue-label')
                 .style('opacity', 0)
         }
 
@@ -279,10 +279,10 @@ class UI {
     }
 
     private changeHelp(showResidues: boolean) {
-        let ligHelpBtn = d3.select(this.parent).select('#int-help-residues-btn');
-        let bondHelpBtn = d3.select(this.parent).select('#int-help-bonds-btn');
-        let bondHelpSection = d3.select(this.parent).select('#int-help-bonds');
-        let ligHelpSection = d3.select(this.parent).select('#int-help-ligands');
+        let ligHelpBtn = d3.select(this.parent).select('#pdbe-int-help-residues-btn');
+        let bondHelpBtn = d3.select(this.parent).select('#pdbe-int-help-bonds-btn');
+        let bondHelpSection = d3.select(this.parent).select('#pdbe-int-help-bonds');
+        let ligHelpSection = d3.select(this.parent).select('#pdbe-int-help-ligands');
 
         if (showResidues) {
             bondHelpBtn.classed('active', false);
@@ -299,8 +299,8 @@ class UI {
     }
 
     private showHelp() {
-        let el = d3.select(this.parent).select('#int-help-container');
-        let btn = d3.select(this.parent).select('#int-help-btn');
+        let el = d3.select(this.parent).select('#pdbe-int-help-container');
+        let btn = d3.select(this.parent).select('#pdbe-int-help-btn');
 
         if (el.style('display') === 'block') {
             el.style('display', 'none');
@@ -314,8 +314,8 @@ class UI {
     }
 
     private displayToolbarPanel(show: boolean) {
-        let dynPanel = d3.select(this.parent).select('#int-menu-dynamic-panel');
-        let el = d3.select(this.parent).select('#int-help-container');
+        let dynPanel = d3.select(this.parent).select('#pdbe-int-menu-dynamic-panel');
+        let el = d3.select(this.parent).select('#pdbe-int-help-container');
 
         if (!dynPanel && !el) return;
 
@@ -336,7 +336,7 @@ class UI {
      * @memberof UI
      */
     private fullScreen() {
-        let btn = d3.select(this.parent).select('#int-fullscreen-btn');
+        let btn = d3.select(this.parent).select('#pdbe-int-fullscreen-btn');
 
         if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
             this.parent.parentElement.style.width = '100%'
diff --git a/src/styles/pdbe-interactions-svg.css b/src/styles/pdbe-interactions-svg.css
index f539d7b..d3f6aba 100644
--- a/src/styles/pdbe-interactions-svg.css
+++ b/src/styles/pdbe-interactions-svg.css
@@ -1,14 +1,14 @@
-.svg-shadow-node {
+.pdbe-int-svg-shadow-node {
     stroke-width: 0;
     fill: white;
 }
 
-.svg-shadow-bond {
+.pdbe-int-svg-shadow-bond {
     stroke-width: 15px;
     stroke: transparent;
 }
 
-.svg-bond {
+.pdbe-int-svg-bond {
     fill: none;
     fill-rule: evenodd;
     stroke-linecap: butt;
@@ -16,142 +16,142 @@
     stroke-opacity: 1;
 }
 
-.svg-bond-ligand {
+.pdbe-int-svg-bond-ligand {
     stroke-width: 4px;
     stroke: black;
 }
 
-.svg-bond-electrostatic {
+.pdbe-int-svg-bond-electrostatic {
     stroke-width: 3px;
     stroke-dasharray: 10 10;
     stroke: #3F26BF;
 }
 
-.svg-bond-stacking {
+.pdbe-int-svg-bond-stacking {
     stroke-width: 3px;
     stroke: green;
 }
 
-.svg-bond-atom-pi {
+.pdbe-int-svg-bond-atom-pi {
     stroke-width: 3px;
     stroke: green;
 }
 
-.svg-bond-amide {
+.pdbe-int-svg-bond-amide {
     stroke-width: 3px;
     stroke: green;
 }
 
-.svg-bond-vdw {
+.pdbe-int-svg-bond-vdw {
     stroke-width: 3px;
     stroke-dasharray: 10 10;
     stroke: #9B7653;
 }
 
-.svg-bond-hydrophobic {
+.pdbe-int-svg-bond-hydrophobic {
     stroke-width: 0px;
 }
 
-.svg-bond-aromatic {
+.pdbe-int-svg-bond-aromatic {
     stroke-width: 4px;
     stroke-dasharray: 1 10;
     stroke: #AD4379;
 }
 
-.svg-bond-metal {
+.pdbe-int-svg-bond-metal {
     stroke-width: 4px;
     stroke: #008080;
 }
 
-.svg-bond-clashes {
+.pdbe-int-svg-bond-clashes {
     stroke-width: 3px;
     stroke: #FF5050;
 }
 
-.svg-bond-covalent {
+.pdbe-int-svg-bond-covalent {
     stroke-width: 3px;
     stroke: black;
 }
 
-.svg-bond-other {
+.pdbe-int-svg-bond-other {
     stroke-width: 1px;
     stroke: black;
 }
 
-.svg-node circle {
+.pdbe-int-svg-node circle {
     stroke-width: 3px;
 }
 
-.svg-node text {
+.pdbe-int-svg-node text {
     cursor: inherit;
     font-family: Arial, Helvetica, sans-serif;
     stroke: black !important;
     fill: black !important;
 }
 
-.svg-node text tspan:first-child {
+.pdbe-int-svg-node text tspan:first-child {
     cursor: inherit;
     font-weight: 100;
     font-size: 0.75em;
 }
 
-.svg-node text tspan:nth-child(2) {
+.pdbe-int-svg-node text tspan:nth-child(2) {
     cursor: inherit;
     font-weight: lighter;
     font-size: 0.55em;
 }
 
-.svg-ligand-res {
+.pdbe-int-svg-ligand-res {
     stroke: black;
     fill: white;
 }
 
-.svg-water-res {
+.pdbe-int-svg-water-res {
     stroke: #A9A9A9;
     fill: #00BFFF;
 }
 
-.svg-cystein-res {
+.pdbe-int-svg-cystein-res {
     stroke: #A9A9A9;
     fill: #F08080;
 }
 
-.svg-positive-res {
+.pdbe-int-svg-positive-res {
     stroke: #A9A9A9;
     fill: #F01505;
 }
 
-.svg-negative-res {
+.pdbe-int-svg-negative-res {
     stroke: #A9A9A9;
     fill: #C048C0;
 }
 
-.svg-proline-res {
+.pdbe-int-svg-proline-res {
     stroke: #A9A9A9;
     fill: #C0C000;
 }
 
-.svg-polar-res {
+.pdbe-int-svg-polar-res {
     stroke: #A9A9A9;
     fill: #15C015;
 }
 
-.svg-aromatic-res {
+.pdbe-int-svg-aromatic-res {
     stroke: #A9A9A9;
     fill: #15A4A4;
 }
 
-.svg-hydrophobic-res {
+.pdbe-int-svg-hydrophobic-res {
     stroke: #A9A9A9;
     fill: #80A0F0;
 }
 
-.svg-glycine-res {
+.pdbe-int-svg-glycine-res {
     stroke: #A9A9A9;
     fill: #F09048;
 }
  
-.svg-other-res {
+.pdbe-int-svg-other-res {
     stroke: #A9A9A9;
     fill: #F2F2F2;
 
diff --git a/src/styles/pdbe-interactions.css b/src/styles/pdbe-interactions.css
index 9e6d7f3..0a714af 100644
--- a/src/styles/pdbe-interactions.css
+++ b/src/styles/pdbe-interactions.css
@@ -1,11 +1,11 @@
-#pdbe-ligand-display-root {
+#pdbe-int-root {
     cursor: default;
     border-radius: 3px;
     width: 100%;
     height: 100%;
 }
 
-.int-label {
+.pdbe-int-label {
     position: absolute;
     height: auto;
     padding: 10px;
@@ -16,24 +16,24 @@
     word-wrap: normal;
 }
 
-#int-tooltip {
+#pdbe-int-tooltip {
     margin: 10px 0 0 10px;
     bottom: 10px;
 }
 
-#int-tooltip>ul {
+#pdbe-int-tooltip>ul {
     margin: 0;
     padding: 0;
     list-style-type: none;
 }
 
-#int-tooltip>ul>li:first-of-type(span) {
+#pdbe-int-tooltip>ul>li:first-of-type(span) {
     text-align: left;
     padding: 0px !important;
     font-weight: 900;
 }
 
-.int-menu-panel {
+.pdbe-int-menu-panel {
     background: #ccd4e0;
     opacity: 0.9;
     float: right;
@@ -47,28 +47,28 @@
     transition: .2s;
 }
 
-.int-menu-panel>i {
+.pdbe-int-menu-panel>i {
     margin-right: 15px;
     cursor: pointer;
     font: 12px sans-serif;
 }
 
-.int-menu-panel>i:last-child {
+.pdbe-int-menu-panel>i:last-child {
     margin-right: 0px;
 }
 
-.int-menu-panel>i:hover {
+.pdbe-int-menu-panel>i:hover {
     color: #637ca0;
 }
 
-.int-toolbar-container {
+.pdbe-int-toolbar-container {
     top: 20px;
     right: 20px;
     position: absolute;
     overflow: hidden;
 }
 
-#int-help-container {
+#pdbe-int-help-container {
     font-family: sans-serif;
     background: #f6f5f3;
     display: none;
@@ -87,67 +87,67 @@
     transition: 1s;
 }
 
-#int-help-container:first-child {
+#pdbe-int-help-container:first-child {
     font-weight: bold;
 }
 
-#int-residue-label {
+#pdbe-int-residue-label {
     margin: 0 0 10px 10px;
     left: 10px;
     top: 10px;
 }
 
-#int-tooltip span:first-child {
+#pdbe-int-tooltip span:first-child {
     text-align: left;
     padding-left: 0px !important;
     font-weight: 900;
 }
 
-#int-tooltip span:last-child {
+#pdbe-int-tooltip span:last-child {
     padding-left: 10px;
 }
 
-.int-help-table tr {
+.pdbe-int-help-table tr {
     height: 25px;
 }
 
-.int-help-table tr td:first-child {
+.pdbe-int-help-table tr td:first-child {
     width: 25px;
     min-width: 25px;
     max-width: 25px;
 }
 
-.int-help-table tr td:nth-child(2) {
+.pdbe-int-help-table tr td:nth-child(2) {
     min-width: 100px;
 }
 
-.int-help-table tr td:nth-child(3) {
+.pdbe-int-help-table tr td:nth-child(3) {
     width: 25px;
     min-width: 25px;
     max-width: 25px;
 }
 
-#int-help-bonds {
+#pdbe-int-help-bonds {
     display: none;
 }
 
-.int-btn:hover {
+.pdbe-int-btn:hover {
     color: #637ca0;
 }
 
-.int-help-residue {
+.pdbe-int-help-residue {
     width: 20px;
     height: 20px;
     border-radius: 50%;
     border: 1.2px solid #a9a9a9;
 }
 
-.int-help-navbar {
+.pdbe-int-help-navbar {
     height: 20px;
     margin-bottom: 10px;
 }
 
-.int-help-navbar a {
+.pdbe-int-help-navbar a {
     width: 49%;
     padding-bottom: 5px;
     border: none;
@@ -158,7 +158,7 @@
     cursor: pointer;
 }
 
-.int-help-navbar a.active {
+.pdbe-int-help-navbar a.active {
     border-bottom: 2px solid #637ca0;
     color: #637ca0;
 }
\ No newline at end of file
-- 
GitLab


From 0b552474443f1f62646cea673d5f1017e05c0786 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 11:12:06 +0000
Subject: [PATCH 34/66] make ligand interaction nodes static

---
 src/plugin/manager.ts | 1 +
 src/plugin/model.ts   | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index fb7b69b..c97e552 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -110,6 +110,7 @@ class Visualization {
     }
 
     private dragHandler = d3.drag()
+        .filter((x: Model.InteractionNode) => !x.static)
         .on('start', (x: Model.InteractionNode) => {
             if (!d3.event.active) this.simulation.alphaTarget(0.3).restart();
 
diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 07b26e4..f0a6ec2 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -102,7 +102,8 @@ namespace Model {
     export class InteractionNode implements d3.SimulationNodeDatum {
         id: string;
         residue: Residue;
-        scale: number;
+        scale: number; // how is the node scaled up in comparison to its original size
+        static: boolean // whether or not can be dragged and droped
 
         index?: number;
         x?: number;
@@ -115,6 +116,7 @@ namespace Model {
         constructor(r: Residue, scale: number, id: string, x: number = undefined, y: number = undefined) {
             this.residue = r;
             this.id = id;
+            this.static = Boolean(scale < 1.0);
             this.scale = scale;
 
             if (x !== undefined) {
-- 
GitLab


From 45d56661f7f9b016527bb1f4d5426b21808a1392 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 11:12:39 +0000
Subject: [PATCH 35/66] link tooltips contain only unique values

---
 src/plugin/model.ts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index f0a6ec2..b4f2988 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -297,15 +297,15 @@ namespace Model {
         }
 
         public toTooltip() {
-            let msg = [];
+            let msg = new Set();
             this.interaction.forEach(x => {
                 let isMainChain = !this.target.residue.isLigand && x.targetAtoms.every(y => Config.backboneAtoms.includes(y));
                 let interactionFlag = isMainChain ? 'backbone' : 'side chain';
 
-                msg.push(`<li><span>${interactionFlag}</span> interaction (<b>${x.targetAtoms}</b> | ${x.interactionsClases}): ${x.distance}Ã…</li>`);
+                msg.add(`<li><span>${interactionFlag}</span> interaction (<b>${x.targetAtoms}</b> | ${x.interactionsClases}): ${x.distance}Ã…</li>`);
             });
 
-            return `<ul>${msg.join('\n')}</ul>`;
+            return `<ul>${Array.from(msg.values()).join('\n')}</ul>`;
         }
 
     }
-- 
GitLab


From c73e16030a40f275811a64de372e17e4ba5d6de6 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 11:19:00 +0000
Subject: [PATCH 36/66] improve interaction tooltip visibility

---
 src/plugin/manager.ts | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index c97e552..b0fb5d7 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -533,7 +533,9 @@ class Visualization {
         this.links
             .append('line')
             .attr('class', (e: Model.Link) => `pdbe-int-svg-bond pdbe-int-svg-bond-${e.getLinkClass()}`)
-            .attr('marker-mid', (e: Model.Link) => e.hasClash() ? 'url(#clash)' : '');
+            .attr('marker-mid', (e: Model.Link) => e.hasClash() ? 'url(#clash)' : '')
+            .on('mouseenter', (x: Model.Link) => this.linkMouseOverEventHandler(x))
+            .on('mouseleave', () => this.linkMouseOutEventHandler());
     }
 
     // private setupNodes() {
-- 
GitLab


From 28b350dd1ce00ea76b0334b2d091104f2af5220e Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 11:19:54 +0000
Subject: [PATCH 37/66] Revert "center scene on simulation end."

This reverts commit 9d686b84c7dd3748e426a9274023b7f43b7a8f4c.
---
 src/plugin/manager.ts | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index b0fb5d7..a652146 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -604,7 +604,7 @@ class Visualization {
         this.bindingSite.interactionNodes.forEach(x => this.rProvider.downloadAnnotation(x.residue));
         await Promise.all(this.rProvider.downloadPromises);
         await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-
+        
         this.nodes = this.nodesRoot.append('g')
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -642,8 +642,7 @@ class Visualization {
             //            .force('charge', charge) //strength 
             .force('collision', collision)
             //                    .force('center', center)
-            .on('tick', () => this.simulationStep())
-            .on('end', () => this.centerScene());
+            .on('tick', () => this.simulationStep());
 
         this.dragHandler(this.nodes);
         if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, d3.zoomIdentity);
@@ -659,7 +658,7 @@ class Visualization {
         this.bindingSite.interactionNodes.forEach(x => ResidueProvider.getInstance().downloadAnnotation(x.residue));
         await Promise.all(this.rProvider.downloadPromises);
         await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-
+        
         this.nodes = this.nodesRoot
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -694,8 +693,7 @@ class Visualization {
             .force('charge', charge) //strength 
             .force('collision', collision)
             .force('center', center)
-            .on('tick', () => this.simulationStep())
-            .on('end', () => this.centerScene());
+            .on('tick', () => this.simulationStep());
 
         this.dragHandler(this.nodes);
 
-- 
GitLab


From 8eca455e6fa9d1ee6c16f9ac99bf1c048677c33c Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 13:12:18 +0000
Subject: [PATCH 38/66] fix full screen mode

---
 src/plugin/ui.ts | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index ecec54c..d1074de 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -342,11 +342,14 @@ class UI {
             this.parent.parentElement.style.width = '100%'
             this.parent.parentElement.style.height = '100%'
             this.parent.parentElement.style.position = 'fixed';
+            this.parent.parentElement.style.top = '0';
+            this.parent.parentElement.style.left = '0';
             this.parent.parentElement.style.zIndex = '10000000000000';
 
             btn.classed('icon-fullscreen', false);
             btn.classed('icon-fullscreen-collapse', true);
 
+
             this.display.centerScene();
         } else {
             btn.classed('icon-fullscreen', true);
-- 
GitLab


From 3386513ccfe0513a68851c5d61bfb867ddbd965e Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 15:23:43 +0000
Subject: [PATCH 39/66] =?UTF-8?q?get=20rid=20of=20=E2=80=98self=20interact?=
 =?UTF-8?q?ions=E2=80=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

do not display intra-ligand interactions
---
 src/plugin/model.ts     | 67 ++++++++++++++++++++++-------------------
 src/plugin/objectSet.ts | 30 ++++++++++++++++++
 2 files changed, 66 insertions(+), 31 deletions(-)
 create mode 100644 src/plugin/objectSet.ts

diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index b4f2988..6993f11 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -323,6 +323,8 @@ namespace Model {
         interactionNodes: InteractionNode[];
         links: Link[];
 
+        private tmpResidueSet: ObjectSet<Residue>;
+        private tmpNodesSet: ObjectSet<InteractionNode>;
 
         constructor() {
             this.residues = new Array<Residue>();
@@ -335,36 +337,30 @@ namespace Model {
             this.pdbId = pdbId;
             this.bmId = data.bm_id;
 
-            data.composition.ligands.forEach(x => this.residues.push(new Residue(x, true)));
+            this.tmpResidueSet = new ObjectSet<Residue>();
+            this.tmpNodesSet = new ObjectSet<InteractionNode>();
+
+            data.composition.ligands.forEach(x => this.tmpResidueSet.tryAdd(new Residue(x, true)));
             data.interactions.forEach(x => {
-                let beginingNode = this.processResidueInteractionPartner(x.begin);
+                let bgnNode = this.processResidueInteractionPartner(x.begin);
                 let endNode = this.processResidueInteractionPartner(x.end);
-                let link = new ResidueResidueLink(beginingNode, endNode, x.interactions)
+
+                let link = new ResidueResidueLink(bgnNode, endNode, x.interactions)
 
                 this.links.push(link);
             });
 
+            this.interactionNodes = Array.from(this.tmpNodesSet.values());
+
             return this;
         }
 
 
         private processResidueInteractionPartner(r: any): InteractionNode {
-            let residue = this.residues.find(x => {
-                let hash = `${r.chain_id}${r.author_residue_number}${(r.author_insertion_code === ' ' ? '' : r.author_insertion_code)}`;;
-                return hash === x.id;
-            });
-
-            if (residue === undefined) {
-                residue = new Residue(r, false);
-                this.residues.push(residue);
-            }
-
-            let node = this.interactionNodes.find(x => x.id === residue.id);
-            if (node === undefined) {
-                let node = new InteractionNode(residue, 1.0, residue.id);
-                this.interactionNodes.push(node);
-                return node;
-            }
+            let residue = new Residue(r, false);
+            residue = this.tmpResidueSet.tryAdd(residue);
+            let node = new InteractionNode(residue, 1.0, residue.id);
+            node = this.tmpNodesSet.tryAdd(node);
 
             return node;
         }
@@ -376,15 +372,12 @@ namespace Model {
             else scale = 1.0
 
             let center = d.getCenter(atom_names);
-            let id = `${r.id}_${atom_names.reduce((x, y) => x + "_" + y)}`;
-            let nodeProvider = this.interactionNodes.find(x => x.id === id);
+            let id = `${r.id}_${atom_names.sort().reduce((x, y) => x + "_" + y)}`;
 
-            if (nodeProvider === undefined) {
-                let tmpNode = new InteractionNode(r, scale, id, center.x, center.y);
-                this.interactionNodes.push(tmpNode);
-                return tmpNode;
-            }
-            return nodeProvider;
+            let node = new InteractionNode(r, scale, id, center.x, center.y);
+            node = this.tmpNodesSet.tryAdd(node);
+
+            return node;
         }
 
 
@@ -392,21 +385,33 @@ namespace Model {
             this.pdbId = pdbId;
             this.bmId = `${data.ligand.chem_comp_id}_${data.ligand.chain_id}_${data.ligand.author_residue_number}`;
 
+            this.tmpResidueSet = new ObjectSet<Residue>();
+            this.tmpNodesSet = new ObjectSet<InteractionNode>();
+
             let ligandResidue = new Residue(data.ligand, true);
-            this.residues.push(ligandResidue);
+            this.tmpResidueSet.tryAdd(ligandResidue);
 
             data.interactions.forEach(x => {
-                let beginingNode = this.processLigandInteractionPartner(ligandResidue, ligand, x.ligand_atoms);
+                let bgnNode = this.processLigandInteractionPartner(ligandResidue, ligand, x.ligand_atoms);
                 let endNode = this.processResidueInteractionPartner(x.end);
-                let tmpLink = this.links.find(x => (<LigandResidueLink>x).containsBothNodes(beginingNode, endNode)) as LigandResidueLink;
+
+                if (bgnNode.residue.equals(endNode.residue)) {
+                    this.tmpNodesSet.delete(endNode);
+                    return; // we do not want to show 'self interactions'  
+                } 
+
+                let tmpLink = this.links.find(x => (<LigandResidueLink>x).containsBothNodes(bgnNode, endNode)) as LigandResidueLink;
 
                 if (tmpLink !== undefined) {
                     tmpLink.addInteraction(x.ligand_atoms, x.end.atom_names, x.interaction_type, x.interaction_details, x.distance);
                 } else {
-                    let link = new LigandResidueLink(beginingNode, endNode, x.ligand_atoms, x.end.atom_names, x.interaction_type, x.interaction_details, x.distance);
+                    let link = new LigandResidueLink(bgnNode, endNode, x.ligand_atoms, x.end.atom_names, x.interaction_type, x.interaction_details, x.distance);
                     this.links.push(link);
                 }
             });
+
+            this.interactionNodes = Array.from(this.tmpNodesSet);
+
             return this;
         }
     }
diff --git a/src/plugin/objectSet.ts b/src/plugin/objectSet.ts
new file mode 100644
index 0000000..5ff62f3
--- /dev/null
+++ b/src/plugin/objectSet.ts
@@ -0,0 +1,30 @@
+/**
+ * Extension class just to get objects and collections work nicely.
+ * Not sure what the javascript way is if you need distinct on 
+ *
+ * @export
+ * @class ObjectSet
+ * @extends {Set<T>}
+ * @template T
+ */
+class ObjectSet<T> extends Set<T> { 
+    
+    public tryAdd(value: T): T {
+        let item = undefined;
+
+        this.forEach((x: any) => {
+            if (x.equals(value)) {
+                item = x;
+                return;
+            }
+        });
+
+        if (item === undefined) { 
+            item = value;
+            super.add(value);
+        }
+
+        return item;
+    }
+
+}
\ No newline at end of file
-- 
GitLab


From 95ac9bd3c630e1376b7521c3b26c3d3c23143e31 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 17:40:11 +0000
Subject: [PATCH 40/66] correctly distinguis main chain and side chain
 interactions

---
 src/plugin/model.ts | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 6993f11..a808475 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -298,10 +298,18 @@ namespace Model {
 
         public toTooltip() {
             let msg = new Set();
+            let rProvider = ResidueProvider.getInstance();
+            
             this.interaction.forEach(x => {
                 let isMainChain = !this.target.residue.isLigand && x.targetAtoms.every(y => Config.backboneAtoms.includes(y));
-                let interactionFlag = isMainChain ? 'backbone' : 'side chain';
-
+                let targetAbbreviation = rProvider.getAminoAcidAbbreviation(this.target.residue.chemCompId);
+                let isResidue = Boolean(targetAbbreviation !== 'X');
+                let interactionFlag = '';
+                
+                if (isMainChain && isResidue) interactionFlag = 'backbone';
+                else if (!isMainChain && isResidue) interactionFlag = 'side chain';
+                else interactionFlag = 'ligand';   
+                
                 msg.add(`<li><span>${interactionFlag}</span> interaction (<b>${x.targetAtoms}</b> | ${x.interactionsClases}): ${x.distance}Ã…</li>`);
             });
 
-- 
GitLab


From 66c5ea1db351cae1384f0dcbc34d52183a98150d Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 11 Feb 2020 18:39:23 +0000
Subject: [PATCH 41/66] filter out aromatic atom-atom interactions

this is done provided this atom is part of stacking. clarity only.
---
 src/plugin/model.ts | 54 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 47 insertions(+), 7 deletions(-)

diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index a808475..11cd1a9 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -299,17 +299,17 @@ namespace Model {
         public toTooltip() {
             let msg = new Set();
             let rProvider = ResidueProvider.getInstance();
-            
+
             this.interaction.forEach(x => {
                 let isMainChain = !this.target.residue.isLigand && x.targetAtoms.every(y => Config.backboneAtoms.includes(y));
                 let targetAbbreviation = rProvider.getAminoAcidAbbreviation(this.target.residue.chemCompId);
                 let isResidue = Boolean(targetAbbreviation !== 'X');
                 let interactionFlag = '';
-                
+
                 if (isMainChain && isResidue) interactionFlag = 'backbone';
                 else if (!isMainChain && isResidue) interactionFlag = 'side chain';
-                else interactionFlag = 'ligand';   
-                
+                else interactionFlag = 'ligand';
+
                 msg.add(`<li><span>${interactionFlag}</span> interaction (<b>${x.targetAtoms}</b> | ${x.interactionsClases}): ${x.distance}Ã…</li>`);
             });
 
@@ -395,6 +395,7 @@ namespace Model {
 
             this.tmpResidueSet = new ObjectSet<Residue>();
             this.tmpNodesSet = new ObjectSet<InteractionNode>();
+            let tmpLinks = new Array<LigandResidueLink>();
 
             let ligandResidue = new Residue(data.ligand, true);
             this.tmpResidueSet.tryAdd(ligandResidue);
@@ -406,22 +407,61 @@ namespace Model {
                 if (bgnNode.residue.equals(endNode.residue)) {
                     this.tmpNodesSet.delete(endNode);
                     return; // we do not want to show 'self interactions'  
-                } 
+                }
 
-                let tmpLink = this.links.find(x => (<LigandResidueLink>x).containsBothNodes(bgnNode, endNode)) as LigandResidueLink;
+                let tmpLink = tmpLinks.find(x => (<LigandResidueLink>x).containsBothNodes(bgnNode, endNode)) as LigandResidueLink;
 
                 if (tmpLink !== undefined) {
                     tmpLink.addInteraction(x.ligand_atoms, x.end.atom_names, x.interaction_type, x.interaction_details, x.distance);
                 } else {
                     let link = new LigandResidueLink(bgnNode, endNode, x.ligand_atoms, x.end.atom_names, x.interaction_type, x.interaction_details, x.distance);
-                    this.links.push(link);
+                    tmpLinks.push(link);
                 }
             });
 
             this.interactionNodes = Array.from(this.tmpNodesSet);
+            this.links = this.filterOutAromaticAtomAtomInteractions(tmpLinks);
 
             return this;
         }
+
+        /**
+         * Filter out Aromatic atom atom interactions provided there is
+         * an evidence of the same atom being part of the stacking information
+         * 
+         * This is for clarity purposes only.
+         *
+         * @private
+         * @param {Array<LigandResidueLink>} src
+         * @returns {Array<LigandResidueLink>}
+         * @memberof BindingSite
+         */
+        private filterOutAromaticAtomAtomInteractions(src: Array<LigandResidueLink>): Array<LigandResidueLink> {
+            let result = new Array<LigandResidueLink>();
+            src.forEach((x: LigandResidueLink) => {
+                let isAtomAtom = x.interaction.map(y => y.interactionType).every(z => z === InteractionType.AtomAtom);
+
+                if (x.getLinkClass() === 'aromatic' && isAtomAtom) {
+                    let targetAtoms = x.interaction.map(y => y.targetAtoms).reduce((a, b) => a.concat(b));
+                    let otherInteractions = new Set(src.filter(y => y.target.equals(x.target)));
+                    otherInteractions.delete(x);
+
+                    let otherBoundAtoms = Array.from(otherInteractions)
+                        .map(y => y.interaction)
+                        .reduce((a, b) => a.concat(b))
+                        .map(y => y.targetAtoms)
+                        .reduce((a, b) => a.concat(b));
+
+                    if (otherBoundAtoms.includes(targetAtoms[0])) {
+                        return;
+                    }
+                }
+
+                result.push(x);
+            });
+
+            return result;
+        }
     }
 
 }
\ No newline at end of file
-- 
GitLab


From 33169468b8f43d4a2780861a88cec6b5f24f2eb1 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 12 Feb 2020 18:04:26 +0000
Subject: [PATCH 42/66] center interaction scene properly

---
 src/plugin/manager.ts | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index a652146..f5f1b1e 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -183,7 +183,7 @@ class Visualization {
      */
     public async initLigandDisplay(ligandId: string) {
         const ligandUrl = Resources.ligandAnnotationURL(ligandId);
-        
+
         return d3.json(ligandUrl)
             .catch(e => { throw e; })
             .then((d: any) => this.addDepiction(d));
@@ -380,7 +380,7 @@ class Visualization {
 
         // we need to fit it in both directions, so we scale according to
         // the direction in which we need to shrink the most
-        let minRatio = Math.min(widthRatio, heightRatio) * 0.8;
+        let minRatio = Math.min(widthRatio, heightRatio) * 0.75;
 
         // the new dimensions of the molecule
         let newMolWidth = molWidth * minRatio;
@@ -574,15 +574,6 @@ class Visualization {
 
     private async setupLigandScene() {
         this.wipeOutVisuals();
-
-        let xShift = (this.parent.offsetWidth / 2) - (this.depiction.resolution.x / 2);
-        let yShift = (this.parent.offsetHeight / 2) - (this.depiction.resolution.y / 2);
-
-        this.depictionRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
-        this.nodesRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
-        this.linksRoot.attr('transform', `translate(${xShift}, ${yShift}) scale(1)`);
-
-
         this.setupLinks();
 
         this.bindingSite.interactionNodes
@@ -604,7 +595,7 @@ class Visualization {
         this.bindingSite.interactionNodes.forEach(x => this.rProvider.downloadAnnotation(x.residue));
         await Promise.all(this.rProvider.downloadPromises);
         await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-        
+
         this.nodes = this.nodesRoot.append('g')
             .selectAll()
             .data(this.bindingSite.interactionNodes)
@@ -658,7 +649,7 @@ class Visualization {
         this.bindingSite.interactionNodes.forEach(x => ResidueProvider.getInstance().downloadAnnotation(x.residue));
         await Promise.all(this.rProvider.downloadPromises);
         await Promise.all([this.visualsMapper.graphicsPromise, this.visualsMapper.mappingPromise]);
-        
+
         this.nodes = this.nodesRoot
             .selectAll()
             .data(this.bindingSite.interactionNodes)
-- 
GitLab


From 7469bb0a8540466c4305dbb92f3e11fc5bf14ff5 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 11:27:35 +0000
Subject: [PATCH 43/66] minor improvement of the layouting

---
 src/plugin/manager.ts | 20 ++++++++++----------
 src/plugin/model.ts   |  2 ++
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index f5f1b1e..e393369 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -619,20 +619,20 @@ class Visualization {
         let nodesWithText = this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand);
         this.addNodeLabels(nodesWithText);
 
-        //        let forceLink = d3.forceLink()
-        //            .links(visuals.links)
-        //            .distance(150)
-        //            .strength(0.5);
+        let forceLink = d3.forceLink()
+            .links(this.links.filter((x: Model.LigandResidueLink) => x.getLinkClass() !== 'hydrophobic'))
+                .distance(70)
+                .strength(0.5);
 
-        //let charge = d3.forceManyBody().strength(-1000).distanceMin(50).distanceMax(150);
-        let collision = d3.forceCollide().radius(50)
-        //let center = d3.forceCenter(xShift, yShift);
+        let charge = d3.forceManyBody().strength(-100).distanceMin(40).distanceMax(120);
+        let collision = d3.forceCollide().radius(40)
+        // let center = d3.forceCenter(this.parent.offsetWidth, this.parent.offsetHeight);
 
         this.simulation = d3.forceSimulation(this.bindingSite.interactionNodes)
-            //            .force('link', forceLink)
-            //            .force('charge', charge) //strength 
+            .force('link', forceLink)
+            .force('charge', charge) //strength 
             .force('collision', collision)
-            //                    .force('center', center)
+            // .force('center', center)
             .on('tick', () => this.simulationStep());
 
         this.dragHandler(this.nodes);
diff --git a/src/plugin/model.ts b/src/plugin/model.ts
index 11cd1a9..c0dfe63 100644
--- a/src/plugin/model.ts
+++ b/src/plugin/model.ts
@@ -400,6 +400,8 @@ namespace Model {
             let ligandResidue = new Residue(data.ligand, true);
             this.tmpResidueSet.tryAdd(ligandResidue);
 
+            ligand.atoms.forEach(x => this.processLigandInteractionPartner(ligandResidue, ligand, [x.name]));
+
             data.interactions.forEach(x => {
                 let bgnNode = this.processLigandInteractionPartner(ligandResidue, ligand, x.ligand_atoms);
                 let endNode = this.processResidueInteractionPartner(x.end);
-- 
GitLab


From 516158c82cf18660421de41bf5939b5f0bcd82e2 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 13:00:22 +0000
Subject: [PATCH 44/66] add error message to the component on error

---
 src/component/component.js |  2 +-
 src/plugin/manager.ts      | 74 +++++++++++++++++++++++++++++++-------
 2 files changed, 62 insertions(+), 14 deletions(-)

diff --git a/src/component/component.js b/src/component/component.js
index 127a747..888375d 100644
--- a/src/component/component.js
+++ b/src/component/component.js
@@ -68,7 +68,7 @@ class pdbInteractions extends LitElement {
   }
 
   set contourData(data) { 
-    if (!data || !this.display || !this.display.hasDepiction()) return;
+    if (!data || !this.display || !this.display.depiction !== undefined ) return;
 
     this.display.addContours(data);
   }
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index e393369..a3de3d9 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -145,7 +145,7 @@ class Visualization {
         this.pdbId = pdbid;
 
         d3.json(`${Resources.apiServer}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
-            .catch(e => { throw e; })
+            .catch(e => this.processError(e, 'No interactions to display'))
             .then((data: any) => {
                 this.addBoundMoleculeInteractions(data, bmId);
             });
@@ -167,10 +167,10 @@ class Visualization {
         this.pdbId = pdbId;
 
         d3.json(`${Resources.apiServer}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
-            .catch(e => { throw e; })
+            .catch(e => this.processError(e, 'No interactions to display'))
             .then((data: any) => {
                 this.addLigandInteractions(data);
-            });
+            })
     }
 
     /**
@@ -185,7 +185,7 @@ class Visualization {
         const ligandUrl = Resources.ligandAnnotationURL(ligandId);
 
         return d3.json(ligandUrl)
-            .catch(e => { throw e; })
+            .catch(e => this.processError(e, `Depiction ${ligandId} not found`))
             .then((d: any) => this.addDepiction(d));
     }
 
@@ -236,10 +236,6 @@ class Visualization {
     }
 
 
-    public hasDepiction(): boolean {
-        return this.depiction !== undefined;
-    }
-
     /**
      * Add ligand interactions to the canvas
      *
@@ -423,7 +419,7 @@ class Visualization {
         if (this.bindingSite !== undefined) return `${this.bindingSite.bmId}.svg`;
         if (this.depiction !== undefined) return `${this.depiction.ccdId}.svg`;
 
-        return 'no name.svg';
+        return 'blank.svg';
     }
 
     // #region fire events
@@ -538,9 +534,7 @@ class Visualization {
             .on('mouseleave', () => this.linkMouseOutEventHandler());
     }
 
-    // private setupNodes() {
 
-    // }
 
     private addNodeLabels(selection: any) {
         selection
@@ -560,6 +554,16 @@ class Visualization {
     }
     //#endregion
 
+    /**
+     * Initialize scene after user selected a part of bound molecule.
+     *
+     * @private
+     * @param {Model.InteractionNode} n Interaction node user clicked to
+     * @param {number} i index o the interaction node
+     * @param {*} g group of interaction nodes
+     * @returns
+     * @memberof Visualization
+     */
     private selectLigand(n: Model.InteractionNode, i: number, g: any) {
         this.fireExternalNodeEvent(n, Config.interactionClickEvent);
 
@@ -571,7 +575,36 @@ class Visualization {
         this.initLigandInteractions(this.pdbId, n.residue.authorResidueNumber, n.residue.chainId);
     }
 
+    /**
+     * Display error message on the SVG canvas if any of the resources
+     * are not available.
+     *
+     * @private
+     * @param {*} e error object
+     * @param {string} msg Error message to display
+     * @memberof Visualization
+     */
+    private processError(e: any, msg: string) {
+        this.canvas.append('text')
+            .classed('pdbe-int-svg-node', true)
+            .attr('x', this.parent.clientWidth / 3)
+            .attr('y', this.parent.clientHeight / 2)
+            .text(msg)
+        
+        throw e;
+
+    }    
+
 
+    /**
+     * Setup ligand scene for display of ligand and interactions.
+     * This includes: setup of links, nodes, simulation and subscribing to relevant events.
+     *
+     * Depiction is expected to be downloaded already.
+     *
+     * @private
+     * @memberof Visualization
+     */
     private async setupLigandScene() {
         this.wipeOutVisuals();
         this.setupLinks();
@@ -621,8 +654,8 @@ class Visualization {
 
         let forceLink = d3.forceLink()
             .links(this.links.filter((x: Model.LigandResidueLink) => x.getLinkClass() !== 'hydrophobic'))
-                .distance(70)
-                .strength(0.5);
+            .distance(70)
+            .strength(0.5);
 
         let charge = d3.forceManyBody().strength(-100).distanceMin(40).distanceMax(120);
         let collision = d3.forceCollide().radius(40)
@@ -641,6 +674,14 @@ class Visualization {
     }
 
 
+    /**
+     * Setup display of interactions for bound molecule. 
+     * * This includes: setup of links, nodes, simulation and subscribing to relevant events.
+     * No depiction is required for this step.
+     *
+     * @private
+     * @memberof Visualization
+     */
     private async setupScene() {
         this.wipeOutVisuals();
         this.setupLinks();
@@ -692,6 +733,13 @@ class Visualization {
     }
 
 
+    /**
+     * This is a tick in a simulation that updates position of nodes and links
+     * Depiction does not change its conformation.
+     *
+     * @private
+     * @memberof Visualization
+     */
     private simulationStep() {
         this.nodes.attr('transform', (d) => `translate(${d.x},${d.y}) scale(${d.scale})`);
         this.links.selectAll('line').attr('x1', (x: any) => x.source.x)
-- 
GitLab


From 06373075c15ca7bf234546a5696630b3311967dd Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 13:23:00 +0000
Subject: [PATCH 45/66] do not propagate events on fullscreen

---
 src/plugin/manager.ts | 22 ++++++++++++++--------
 src/plugin/ui.ts      |  9 ++++++---
 2 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index a3de3d9..8c00d42 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -22,6 +22,7 @@ class Visualization {
     private pdbId: string;
     private bindingSite: Model.BindingSite;
     private depiction: Depiction;
+    public fullScreen: boolean;
 
     private visualsMapper: VisualsMapper;
     private interactionsData: any;
@@ -35,6 +36,7 @@ class Visualization {
         this.parent.style.cssText += "display: block; height: 100%; width: 100%; position: relative;";
 
         this.visualsMapper = new VisualsMapper();
+        this.fullScreen = false;
         this.rProvider = ResidueProvider.getInstance();
 
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
@@ -66,7 +68,17 @@ class Visualization {
     }
 
     // #region even handlers
+    private getZoomHandler() {
+        return d3.zoom()
+            .scaleExtent([1 / 10, 10])
+            .on('zoom', () => this.canvas
+                .attr('transform', d3.event.transform));
+    }
+    
+
     private nodeMouseEnterEventHandler(e: any) {
+        if (this.fullScreen) return;
+
         let hash = `${e.eventData.auth_asym_id}${e.eventData.auth_seq_id}${e.eventData.ins_code}`;
 
         this.nodes?.each((node: Model.InteractionNode, index: number, group: any) => {
@@ -80,15 +92,9 @@ class Visualization {
     }
 
 
-    private getZoomHandler() {
-        return d3.zoom()
-            .scaleExtent([1 / 10, 10])
-            .on('zoom', () => this.canvas
-                .attr('transform', d3.event.transform));
-    }
-
-
     private nodeMouseLeaveEventHandler() {
+        if (this.fullScreen) return;
+
         this.nodes?.each((node: Model.InteractionNode, index: number, group: any) => {
             if (node.id == this.selectedResidueHash) {
                 this.nodeDim(node, index, group);
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index d1074de..c27b561 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -339,6 +339,8 @@ class UI {
         let btn = d3.select(this.parent).select('#pdbe-int-fullscreen-btn');
 
         if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
+            this.display.fullScreen = true;
+
             this.parent.parentElement.style.width = '100%'
             this.parent.parentElement.style.height = '100%'
             this.parent.parentElement.style.position = 'fixed';
@@ -349,17 +351,18 @@ class UI {
             btn.classed('icon-fullscreen', false);
             btn.classed('icon-fullscreen-collapse', true);
 
-
             this.display.centerScene();
         } else {
-            btn.classed('icon-fullscreen', true);
-            btn.classed('icon-fullscreen-collapse', false);
+            this.display.fullScreen = true;            
 
             this.parent.parentElement.style.width = `${this.originalWidth}px`;
             this.parent.parentElement.style.height = `${this.originalHeight}px`;
             this.parent.parentElement.style.position = 'relative';
             this.parent.parentElement.style.zIndex = '';
 
+            btn.classed('icon-fullscreen', true);
+            btn.classed('icon-fullscreen-collapse', false);
+
             this.display.centerScene();
 
 
-- 
GitLab


From 7a441d53ae2e2a5be8db6588a38bd6cf76a2ac83 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 13:52:09 +0000
Subject: [PATCH 46/66] fix help menu

fix CSS so that it does not collide with EBI style framework
---
 src/styles/pdbe-interactions.css | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/styles/pdbe-interactions.css b/src/styles/pdbe-interactions.css
index 0a714af..4213549 100644
--- a/src/styles/pdbe-interactions.css
+++ b/src/styles/pdbe-interactions.css
@@ -107,6 +107,16 @@
     padding-left: 10px;
 }
 
+.pdbe-int-help-table {
+    border: none !important;
+    margin: 0 !important;
+    background-color: #f6f5f3 !important;
+}
+
+.pdbe-int-help-table td {
+    border: none !important;
+}
+
 .pdbe-int-help-table tr {
     height: 25px;
 }
-- 
GitLab


From 215946e4c8665ba97f1d67dbb5f7ff99576df1ac Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 13:52:28 +0000
Subject: [PATCH 47/66] shuffle order of ligands and residues in help

---
 src/plugin/ui.ts | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index c27b561..446cf85 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -17,20 +17,20 @@ let helpLigands = `
             </td>
             <td>aromatic</td>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #F2F2F2;"></div>
+                <div class="pdbe-int-help-residue" style="background: #15C015;"></div>
             </td>
-            <td>other</td>
+            <td>polar</td>
+            <td>
         </tr>
         <tr>
             <td>
                 <div class="pdbe-int-help-residue" style="background: #F08080;"></div>
             </td>
-            <td>cystein</td>
+            <td>cystein</td>         
             <td>
-                <div class="pdbe-int-help-residue" style="background: #15C015;"></div>
+                <div class="pdbe-int-help-residue" style="background: #00BFFF;"></div>
             </td>
-            <td>polar</td>
-            <td>
+            <td>water</td>                    
         </tr>
         <tr>
             <td>
@@ -38,9 +38,9 @@ let helpLigands = `
             </td>
             <td>positivelly charged</td>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #00BFFF;"></div>
+                <div class="pdbe-int-help-residue" style="background: #F2F2F2;"></div>
             </td>
-            <td>water</td>                    
+            <td>other</td>               
         </tr>
         <tr>
             <td>
-- 
GitLab


From ba3f9329a23d45f2143962b036e92cb709af12b3 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 13:52:34 +0000
Subject: [PATCH 48/66] code cleanup

---
 src/plugin/manager.ts        | 14 ++++++++------
 src/plugin/residuefactory.ts |  5 +++--
 src/plugin/resources.ts      | 16 ++++++++++++++--
 3 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 8c00d42..22e5771 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -74,7 +74,7 @@ class Visualization {
             .on('zoom', () => this.canvas
                 .attr('transform', d3.event.transform));
     }
-    
+
 
     private nodeMouseEnterEventHandler(e: any) {
         if (this.fullScreen) return;
@@ -149,8 +149,9 @@ class Visualization {
      */
     public initBoundMoleculeInteractions(pdbid: string, bmId: string) {
         this.pdbId = pdbid;
+        let url = Resources.boundMoleculeAPI(pdbid, bmId);
 
-        d3.json(`${Resources.apiServer}/pdb/bound_molecule_interactions/${this.pdbId}/${bmId}`)
+        d3.json(url)
             .catch(e => this.processError(e, 'No interactions to display'))
             .then((data: any) => {
                 this.addBoundMoleculeInteractions(data, bmId);
@@ -171,8 +172,9 @@ class Visualization {
      */
     public initLigandInteractions(pdbId: string, resId: number, chainId: string) {
         this.pdbId = pdbId;
+        let url = Resources.ligandInteractionsAPI(pdbId, chainId, resId);
 
-        d3.json(`${Resources.apiServer}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`)
+        d3.json(url)
             .catch(e => this.processError(e, 'No interactions to display'))
             .then((data: any) => {
                 this.addLigandInteractions(data);
@@ -188,7 +190,7 @@ class Visualization {
      * @memberof Visualization
      */
     public async initLigandDisplay(ligandId: string) {
-        const ligandUrl = Resources.ligandAnnotationURL(ligandId);
+        const ligandUrl = Resources.ligandAnnotationAPI(ligandId);
 
         return d3.json(ligandUrl)
             .catch(e => this.processError(e, `Depiction ${ligandId} not found`))
@@ -596,10 +598,10 @@ class Visualization {
             .attr('x', this.parent.clientWidth / 3)
             .attr('y', this.parent.clientHeight / 2)
             .text(msg)
-        
+
         throw e;
 
-    }    
+    }
 
 
     /**
diff --git a/src/plugin/residuefactory.ts b/src/plugin/residuefactory.ts
index b488d45..cb232af 100644
--- a/src/plugin/residuefactory.ts
+++ b/src/plugin/residuefactory.ts
@@ -61,10 +61,11 @@ class ResidueProvider {
     public downloadAnnotation(r: Model.Residue): void {
         if (this.mapping.has(r.chemCompId) || r.isLigand) return;
 
-        let res = d3.json(`${Resources.residueTypeAPI}${r.chemCompId}`).then(x => {
+        let url = Resources.residueTypeAPI(r.chemCompId);
+        let res = d3.json(url).then(x => {
             let code = x[r.chemCompId][0].one_letter_code;
             this.mapping.set(r.chemCompId, code);
-            
+
             return code;
         });
 
diff --git a/src/plugin/resources.ts b/src/plugin/resources.ts
index 0ae690e..7afd14a 100644
--- a/src/plugin/resources.ts
+++ b/src/plugin/resources.ts
@@ -4,9 +4,21 @@ namespace Resources {
     export const glycanMapping: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json';
     export const componentSvgCss: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css';
 
-    export const residueTypeAPI: string = "https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/";
+    export const residueTypeURL: string = "https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/";
 
-    export function ligandAnnotationURL(ligandName: string): string { 
+    export function ligandAnnotationAPI(ligandName: string): string { 
         return `https://www.ebi.ac.uk/pdbe/static/files/pdbechem_v2/${ligandName}/annotation`;
     }
+
+    export function boundMoleculeAPI(pdbId: string, bmId: string): string { 
+        return `${apiServer}/pdb/bound_molecule_interactions/${pdbId}/${bmId}`;
+    }
+
+    export function ligandInteractionsAPI(pdbId: string, chainId: string, resId: number) { 
+        return `${apiServer}/pdb/bound_ligand_interactions/${pdbId}/${chainId}/${resId}`;
+    }
+
+    export function residueTypeAPI(chemCompId: string): string { 
+        return `${residueTypeURL}${chemCompId}`;
+    }
 }
\ No newline at end of file
-- 
GitLab


From b014833fb5ea8ce8710f39f0d1c238c019361953 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 14:04:57 +0000
Subject: [PATCH 49/66] improve display of ions

---
 src/plugin/manager.ts | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 22e5771..6139894 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -22,22 +22,25 @@ class Visualization {
     private pdbId: string;
     private bindingSite: Model.BindingSite;
     private depiction: Depiction;
-    public fullScreen: boolean;
+    private realigned: boolean; // whether or not the scene was automatically aligned happens only once.
 
     private visualsMapper: VisualsMapper;
     private interactionsData: any;
     private selectedResidueHash: string;
 
     private rProvider: ResidueProvider;
+
+    public fullScreen: boolean;    
     // #endregion
 
     constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
         this.parent = element;
         this.parent.style.cssText += "display: block; height: 100%; width: 100%; position: relative;";
 
-        this.visualsMapper = new VisualsMapper();
-        this.fullScreen = false;
+        this.visualsMapper = new VisualsMapper();        
         this.rProvider = ResidueProvider.getInstance();
+        this.fullScreen = false;
+        this.realigned = false;
 
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
 
@@ -338,6 +341,8 @@ class Visualization {
      * @memberof Visualization
      */
     public reinitialize() {
+        this.realigned = false;
+
         if (this.depiction === undefined) this.setupScene();
         else this.setupLigandScene();
 
@@ -384,7 +389,7 @@ class Visualization {
 
         // we need to fit it in both directions, so we scale according to
         // the direction in which we need to shrink the most
-        let minRatio = Math.min(widthRatio, heightRatio) * 0.75;
+        let minRatio = Math.min(widthRatio, heightRatio) * 0.9;
 
         // the new dimensions of the molecule
         let newMolWidth = molWidth * minRatio;
@@ -674,7 +679,8 @@ class Visualization {
             .force('charge', charge) //strength 
             .force('collision', collision)
             // .force('center', center)
-            .on('tick', () => this.simulationStep());
+            .on('tick', () => this.simulationStep())
+            .on('end', () => this.positionSceneOnSimulationEnd());
 
         this.dragHandler(this.nodes);
         if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, d3.zoomIdentity);
@@ -756,6 +762,19 @@ class Visualization {
             .attr('y2', (x: any) => x.target.y);
     }
 
+    /**
+     * Bit of a hack to improve visual for ions.
+     *
+     * @private
+     * @memberof Visualization
+     */
+    private positionSceneOnSimulationEnd() { 
+        if (!this.realigned) {
+            this.realigned = true;
+            this.centerScene();
+        }
+    }
+
 
     private nodeHighlight(x: Model.InteractionNode, i: number, g: any) {
         x.scale = 1.5;
-- 
GitLab


From 5244d8d0dc3efb2c73719785ffa8715f45907b26 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 14:20:44 +0000
Subject: [PATCH 50/66] improvements

---
 src/plugin/config.ts  | 19 ++++++++++---------
 src/plugin/manager.ts | 14 ++++++--------
 2 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index 9f65507..2d39277 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -1,14 +1,15 @@
 namespace Config {
-    export const interactionClickEvent = 'PDB.interactions.click';
-    export const interactionMouseoverEvent = 'PDB.interactions.mouseover';
-    export const interactionMouseoutEvent = 'PDB.interactions.mouseout'
+    export const nodeSize: number = 25;
+    export const interactionClickEvent: string = 'PDB.interactions.click';
+    export const interactionMouseoverEvent: string = 'PDB.interactions.mouseover';
+    export const interactionMouseoutEvent: string = 'PDB.interactions.mouseout'
 
-    export const interactionShowLabelEvent = 'PDB.interactions.showLabel';
-    export const interactionHideLabelEvent = 'PDB.interactions.hideLabel';
+    export const interactionShowLabelEvent: string = 'PDB.interactions.showLabel';
+    export const interactionHideLabelEvent: string = 'PDB.interactions.hideLabel';
 
-    export const molstarClickEvent = 'PDB.molstar.click';
-    export const molstarMouseoverEvent = 'PDB.molstar.mouseover';
-    export const molstarMouseoutEvent = 'PDB.molstar.mouseout';
+    export const molstarClickEvent: string = 'PDB.molstar.click';
+    export const molstarMouseoverEvent: string = 'PDB.molstar.mouseover';
+    export const molstarMouseoutEvent: string = 'PDB.molstar.mouseout';
 
     export const aaTypes = new Map<string, Array<string>>([
         ['hydrophobic', new Array<string>('A', 'I', 'L', 'M', 'F', 'W', 'V')],
@@ -44,7 +45,7 @@ namespace Config {
         ['VAL', 'V']
     ]);
 
-    export const backboneAtoms = ['N', 'CA', 'C', 'O'];
+    export const backboneAtoms: Array<string> = ['N', 'CA', 'C', 'O'];
 
     export const interactionsClasses = new Map<string, Array<string>>([
         ["covalent", new Array<string>("covalent")],
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 6139894..0eedb37 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -389,7 +389,7 @@ class Visualization {
 
         // we need to fit it in both directions, so we scale according to
         // the direction in which we need to shrink the most
-        let minRatio = Math.min(widthRatio, heightRatio) * 0.9;
+        let minRatio = Math.min(widthRatio, heightRatio) * 0.85;
 
         // the new dimensions of the molecule
         let newMolWidth = molWidth * minRatio;
@@ -660,7 +660,7 @@ class Visualization {
         // draw rest
         this.nodes.filter((x: Model.InteractionNode) => !this.visualsMapper.glycanMapping.has(x.residue.chemCompId))
             .append('circle')
-            .attr('r', (x: Model.InteractionNode) => x.scale * 25);
+            .attr('r', (x: Model.InteractionNode) => x.scale * Config.nodeSize);
 
         let nodesWithText = this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand);
         this.addNodeLabels(nodesWithText);
@@ -670,15 +670,13 @@ class Visualization {
             .distance(70)
             .strength(0.5);
 
-        let charge = d3.forceManyBody().strength(-100).distanceMin(40).distanceMax(120);
-        let collision = d3.forceCollide().radius(40)
-        // let center = d3.forceCenter(this.parent.offsetWidth, this.parent.offsetHeight);
+        let charge = d3.forceManyBody().strength(-100).distanceMin(40).distanceMax(80);
+        let collision = d3.forceCollide().radius(40);
 
         this.simulation = d3.forceSimulation(this.bindingSite.interactionNodes)
             .force('link', forceLink)
             .force('charge', charge) //strength 
             .force('collision', collision)
-            // .force('center', center)
             .on('tick', () => this.simulationStep())
             .on('end', () => this.positionSceneOnSimulationEnd());
 
@@ -721,7 +719,7 @@ class Visualization {
 
         this.nodes.filter((e: Model.InteractionNode) => !this.visualsMapper.glycanMapping.has(e.residue.chemCompId))
             .append('circle')
-            .attr('r', '25');
+            .attr('r', Config.nodeSize);
 
         this.addNodeLabels(this.nodes);
 
@@ -755,7 +753,7 @@ class Visualization {
      * @memberof Visualization
      */
     private simulationStep() {
-        this.nodes.attr('transform', (d) => `translate(${d.x},${d.y}) scale(${d.scale})`);
+        this.nodes.attr('transform', (n: Model.InteractionNode) => `translate(${n.x},${n.y}) scale(${n.scale})`);
         this.links.selectAll('line').attr('x1', (x: any) => x.source.x)
             .attr('y1', (x: any) => x.source.y)
             .attr('x2', (x: any) => x.target.x)
-- 
GitLab


From 1b8a4355297bbb7463eb5574aae940d1af503030 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 16:20:06 +0000
Subject: [PATCH 51/66] add pyrrolysine to the perceived AA

---
 src/plugin/config.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index 2d39277..ca888f4 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -13,7 +13,7 @@ namespace Config {
 
     export const aaTypes = new Map<string, Array<string>>([
         ['hydrophobic', new Array<string>('A', 'I', 'L', 'M', 'F', 'W', 'V')],
-        ['positive', Array<string>('K', 'R')],
+        ['positive', Array<string>('K', 'R', 'O')],
         ['negative', Array<string>('E', 'D')],
         ['polar', Array<string>('N', 'Q', 'S', 'T')],
         ['cystein', Array<string>('C', 'U')],
-- 
GitLab


From a6617678035ebee8c0744f890bb20ae318789e28 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 16:20:38 +0000
Subject: [PATCH 52/66] add graphics for atom-PI interactions

---
 src/plugin/config.ts                 | 3 ++-
 src/styles/pdbe-interactions-svg.css | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index ca888f4..0e54cb7 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -53,7 +53,8 @@ namespace Config {
         ['amide', new Array<string>("AMIDEAMIDE", "AMIDERING")],
         ["vdw", new Array<string>("vdw")],
         ["hydrophobic", new Array<string>("hydrophobic")],
-        ["aromatic", new Array<string>("aromatic", "FF", "OF", "EE", "FT", "OT", "ET", "FE", "OE", "EF", "CARBONPI", "CATIONPI", "DONORPI", "HALOGENPI", "METSULPHURPI")],
+        ["aromatic", new Array<string>("aromatic", "FF", "OF", "EE", "FT", "OT", "ET", "FE", "OE", "EF")],
+        ["atom-pi", new Array<string>("CARBONPI", "CATIONPI", "DONORPI", "HALOGENPI", "METSULPHURPI")],
         ["metal", new Array<string>("metal_complex")],
         ["clashes", new Array<string>("clash", "vdw_clash")]
     ]);
diff --git a/src/styles/pdbe-interactions-svg.css b/src/styles/pdbe-interactions-svg.css
index d3f6aba..ab0ecdf 100644
--- a/src/styles/pdbe-interactions-svg.css
+++ b/src/styles/pdbe-interactions-svg.css
@@ -34,7 +34,7 @@
 
 .pdbe-int-svg-bond-atom-pi {
     stroke-width: 3px;
-    stroke: green;
+    stroke: #2E8B57;
 }
 
 .pdbe-int-svg-bond-amide {
-- 
GitLab


From 879c7d5f9fabe01f47dfc6c54996ac955e58f285 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Thu, 13 Feb 2020 16:22:00 +0000
Subject: [PATCH 53/66] make bond graphic primitives smaller

---
 src/styles/pdbe-interactions-svg.css | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/styles/pdbe-interactions-svg.css b/src/styles/pdbe-interactions-svg.css
index ab0ecdf..03f87df 100644
--- a/src/styles/pdbe-interactions-svg.css
+++ b/src/styles/pdbe-interactions-svg.css
@@ -22,28 +22,28 @@
 }
 
 .pdbe-int-svg-bond-electrostatic {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke-dasharray: 10 10;
     stroke: #3F26BF;
 }
 
 .pdbe-int-svg-bond-stacking {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke: green;
 }
 
 .pdbe-int-svg-bond-atom-pi {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke: #2E8B57;
 }
 
 .pdbe-int-svg-bond-amide {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke: green;
 }
 
 .pdbe-int-svg-bond-vdw {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke-dasharray: 10 10;
     stroke: #9B7653;
 }
@@ -64,12 +64,12 @@
 }
 
 .pdbe-int-svg-bond-clashes {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke: #FF5050;
 }
 
 .pdbe-int-svg-bond-covalent {
-    stroke-width: 3px;
+    stroke-width: 2px;
     stroke: black;
 }
 
@@ -79,7 +79,7 @@
 }
 
 .pdbe-int-svg-node circle {
-    stroke-width: 3px;
+    stroke-width: 2px;
 }
 
 .pdbe-int-svg-node text {
-- 
GitLab


From 66920d3d0f236ec7343d94fb6ae136c6a6dd43c2 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 18 Feb 2020 10:23:10 +0000
Subject: [PATCH 54/66] few improvements

---
 README.md             | 22 +++++++++++++++++-----
 gulpfile.js           |  4 ++--
 src/plugin/manager.ts | 14 +++++++++++++-
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 4a800de..c9dc3ea 100644
--- a/README.md
+++ b/README.md
@@ -50,19 +50,19 @@ A few files needs to be imported in the page before the component is attempted t
 <script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
 ```
 
-**A) Ligand interactions**
+#### A) Ligand interactions
 
 ```html
 <pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
 ```
 
-**B) Bound molecule interactions**
+#### B) Bound molecule interactions
 
 ```html
 <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
 ```
 
-**C) Ligand/chemical component**
+#### C) Ligand/chemical component
 
 ```html
 <pdb-interactions pdb-res-name="CLR" zoom-on ></pdb-interactions>
@@ -115,15 +115,27 @@ and then the component can be instantiated as simply as:
 
 ```javascript
 let component = document.getElementById('SIA-component');
+let uiParams = {
+    reinitialize: true, // allow reinitialize option in the component menu
+    zoom: true, // allow scene zoom
+    fullScreen: true, // allow allow full screen option in the component menu
+    downloadImage: true, // allow image download from  the component menu
+    downloadData: true, // allow interactions data download from compoment menu
+    center: true, // allow scene centering option from the component menu
+    help: false, // allow help option from the component menu
+    residueLabel: true, // show residue label
+    tooltip: true // show residue tooltip on mouse hover
+};
+
 this.display = new Visualization(this, uiParams);
 
 // to display bound molecule interactions
-this.display.initBoundMoleculeInteractions('3d12', 'bm1'
+this.display.initBoundMoleculeInteractions('3d12', 'bm1');
 // to display ligand interactions
 this.display.initLigandInteractions('1cbs', 200, 'A');
 
 // to display chemical component only
-this.display.initLigandDisplay('HEM').then(() => this.display.centerScene());
+this.display.initLigandDisplay('HEM');
 ````
 
 ## Parameters
diff --git a/gulpfile.js b/gulpfile.js
index 8793dfc..acdded9 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -10,13 +10,13 @@ const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
 const banner = ['/**',
   ` * ${PKG_JSON.name}`,
   ` * @version ${PKG_JSON.version}`,
-  ' * @link https://github.com/PDBeurope/pdbe-molstar',
+  ' * @link https://gitlab.ebi.ac.uk/pdbe/web-components/interactions',
   ' * @license Apache 2.0',
   ' */',
   ''].join('\n');
 
   const license = ['/**',
-  ' * Copyright 2019-2020 Mandar Deshpande <mandar@ebi.ac.uk>',
+  ' * Copyright 2019-2020 Lukas Pravda <lpravda@ebi.ac.uk>',
   ' * European Bioinformatics Institute (EBI, http://www.ebi.ac.uk/)',
   ' * European Molecular Biology Laboratory (EMBL, http://www.embl.de/)',
   ' * Licensed under the Apache License, Version 2.0 (the "License");',
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 0eedb37..a5f32d9 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -197,7 +197,8 @@ class Visualization {
 
         return d3.json(ligandUrl)
             .catch(e => this.processError(e, `Depiction ${ligandId} not found`))
-            .then((d: any) => this.addDepiction(d));
+            .then((d: any) => this.addDepiction(d))
+            .then(() => this.centerScene());
     }
 
 
@@ -294,6 +295,17 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
+        //let css = new Array<string>();
+        
+        for (const key in document.styleSheets) {
+            console.log(key);
+            console.log(document.styleSheets[key]);
+            let rules = (document.styleSheets[key] as CSSStyleSheet).cssRules
+            for (const rule in rules) {
+                console.log(rules[rule].cssText);
+            }
+        }
+
         d3.text(Resources.componentSvgCss)
             .then(x => {
                 let svgData = `
-- 
GitLab


From 7b44b32f894cad92103638bcf9907c036f4f804f Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 18 Feb 2020 11:15:40 +0000
Subject: [PATCH 55/66] change component name

pdb-interactions -> pdbe-interactions
---
 demo_component.html        |  6 +++---
 dependencies/index.html    | 10 +++++-----
 src/component/component.js |  5 +++--
 3 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/demo_component.html b/demo_component.html
index 3407c0a..2273b0f 100644
--- a/demo_component.html
+++ b/demo_component.html
@@ -22,21 +22,21 @@
     <!--Mode A-->
     <div style="position: relative; float: left;">
       <div style="width: 500px; height: 500px; position: relative">
-        <pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
+        <pdbe-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdbe-interactions>
       </div>
     </div>
 
     <!--Mode B-->
     <div style="position: relative; float: left;">
       <div style="width: 500px; height: 500px; position: relative">
-        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+        <pdbe-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdbe-interactions>
       </div>
     </div>
 
     <!--Mode C-->
     <div style="position: relative; float: left;">
         <div style="width: 500px; height: 500px; position: relative">
-          <pdb-interactions pdb-res-name="CLR" zoom-on></pdb-interactions>
+          <pdbe-interactions pdb-res-name="CLR" zoom-on></pdbe-interactions>
         </div>
       </div>
       
diff --git a/dependencies/index.html b/dependencies/index.html
index 2ee362f..fe43c24 100644
--- a/dependencies/index.html
+++ b/dependencies/index.html
@@ -24,13 +24,13 @@
 <script>
     var renderBmInteractions = function (id, bmId) {
         var int =
-            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
+            `<pdbe-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdbe-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
     var renderLigandInteractions = function (id, chain, resId) {
         var int =
-            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-interactions>`
+            `<pdbe-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdbe-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
@@ -122,17 +122,17 @@
     </div>
     <div style="position: relative; float: left;">
         <div id="rt 1" style="width: 500px; height: 500px; position: relative">
-            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-interactions>
+            <pdbe-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdbe-interactions>
         </div>
     </div>
 
     <!--
         Further use in the app for bound molecule interactions:
         
-        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+        <pdbe-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdbe-interactions>
         
         for ligand interactions:
-        <pdb-interactions pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdb-interactions>
+        <pdbe-interactions pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdbe-interactions>
     -->
     <script>
 
diff --git a/src/component/component.js b/src/component/component.js
index 888375d..0b6b087 100644
--- a/src/component/component.js
+++ b/src/component/component.js
@@ -3,7 +3,7 @@ import { LitElement, html } from 'lit-element';
 import "../styles/pdbe-interactions.css";
 
 // Extend the LitElement base class
-class pdbInteractions extends LitElement {
+class pdbeInteractions extends LitElement {
 
   //Get properties / attribute values
   static get properties() {
@@ -48,6 +48,7 @@ class pdbInteractions extends LitElement {
     if (!data) return;
 
     this.display.addDepiction(data);
+    this.display.centerScene();
   }
 
   set ligandHighlight(data) {
@@ -89,4 +90,4 @@ class pdbInteractions extends LitElement {
 
 }
 // Register the new element with the browser.
-customElements.define('pdb-interactions', pdbInteractions);
\ No newline at end of file
+customElements.define('pdbe-interactions', pdbeInteractions);
\ No newline at end of file
-- 
GitLab


From 949fbcbadd32dcfa742f094356353161ebd5e611 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 18 Feb 2020 11:15:54 +0000
Subject: [PATCH 56/66] remove unecessary function.

---
 demo_plugin.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/demo_plugin.html b/demo_plugin.html
index 6341e3f..a1f1a87 100644
--- a/demo_plugin.html
+++ b/demo_plugin.html
@@ -34,7 +34,7 @@
         //<!--Mode C-->
         var eleChemComp = document.getElementById('chem-comp');
         this.ccdisplay = new Visualization(eleChemComp, undefined);
-        this.ccdisplay.initLigandDisplay('HEM').then(() => this.display.centerScene());
+        this.ccdisplay.initLigandDisplay('HEM');
       });
     </script>
 
-- 
GitLab


From fe770529056fdbb65934d13aae0ab94b62cdc2de Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Tue, 18 Feb 2020 11:28:11 +0000
Subject: [PATCH 57/66] do not draw clarity nodes in component level only

---
 src/component/component.js | 2 +-
 src/plugin/depiction.ts    | 4 ++--
 src/plugin/manager.ts      | 8 +++++---
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/component/component.js b/src/component/component.js
index 0b6b087..0716439 100644
--- a/src/component/component.js
+++ b/src/component/component.js
@@ -47,7 +47,7 @@ class pdbeInteractions extends LitElement {
   set depiction(data) {
     if (!data) return;
 
-    this.display.addDepiction(data);
+    this.display.addDepiction(data, false);
     this.display.centerScene();
   }
 
diff --git a/src/plugin/depiction.ts b/src/plugin/depiction.ts
index 0cd076c..0a08a57 100644
--- a/src/plugin/depiction.ts
+++ b/src/plugin/depiction.ts
@@ -88,10 +88,10 @@ class Depiction {
         return new Vector2D(x, y);
     }
 
-    public draw() {
+    public draw(withClarityNodes: boolean = false) {
         this.structure.selectAll("*").remove();
 
-        this.appendClarityNodes();
+        if (withClarityNodes) this.appendClarityNodes();
         this.appendBondVisuals();
         this.appendTexts();
     }
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index a5f32d9..449acde 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -197,7 +197,7 @@ class Visualization {
 
         return d3.json(ligandUrl)
             .catch(e => this.processError(e, `Depiction ${ligandId} not found`))
-            .then((d: any) => this.addDepiction(d))
+            .then((d: any) => this.addDepiction(d, true))
             .then(() => this.centerScene());
     }
 
@@ -207,11 +207,13 @@ class Visualization {
      *
      * @param {*} depiction Content of annotation.json file generated by
      * the PDBeChem process.
+     * @param {*} withClarityNodes Control if shadow nodes should be drawn
+     * in the background of nodes with labels
      * @memberof Visualization
      */
-    public addDepiction(depiction: any) {
+    public addDepiction(depiction: any, withClarityNodes: boolean) {
         this.depiction = new Depiction(this.depictionRoot, depiction);
-        this.depiction.draw();
+        this.depiction.draw(withClarityNodes);
     }
 
 
-- 
GitLab


From c9df6467c4bda710ecc5e696e5754cb0df7e45aa Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 19 Feb 2020 10:31:41 +0000
Subject: [PATCH 58/66] improve scene centering on startup

---
 src/plugin/manager.ts | 48 ++++++++-----------------------------------
 1 file changed, 9 insertions(+), 39 deletions(-)

diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 449acde..5ccee44 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -22,7 +22,6 @@ class Visualization {
     private pdbId: string;
     private bindingSite: Model.BindingSite;
     private depiction: Depiction;
-    private realigned: boolean; // whether or not the scene was automatically aligned happens only once.
 
     private visualsMapper: VisualsMapper;
     private interactionsData: any;
@@ -30,17 +29,16 @@ class Visualization {
 
     private rProvider: ResidueProvider;
 
-    public fullScreen: boolean;    
+    public fullScreen: boolean;
     // #endregion
 
     constructor(element: HTMLElement, uiParameters: Config.UIParameters = undefined) {
         this.parent = element;
         this.parent.style.cssText += "display: block; height: 100%; width: 100%; position: relative;";
 
-        this.visualsMapper = new VisualsMapper();        
+        this.visualsMapper = new VisualsMapper();
         this.rProvider = ResidueProvider.getInstance();
         this.fullScreen = false;
-        this.realigned = false;
 
         if (uiParameters === undefined) uiParameters = new Config.UIParameters();
 
@@ -156,9 +154,9 @@ class Visualization {
 
         d3.json(url)
             .catch(e => this.processError(e, 'No interactions to display'))
-            .then((data: any) => {
-                this.addBoundMoleculeInteractions(data, bmId);
-            });
+            .then((data: any) => this.addBoundMoleculeInteractions(data, bmId))
+            .then(() => new Promise(resolve => setTimeout(resolve, 1500)))
+            .then(() => this.centerScene());
     }
 
     /**
@@ -179,9 +177,9 @@ class Visualization {
 
         d3.json(url)
             .catch(e => this.processError(e, 'No interactions to display'))
-            .then((data: any) => {
-                this.addLigandInteractions(data);
-            })
+            .then((data: any) => this.addLigandInteractions(data))
+            .then(() => new Promise(resolve => setTimeout(resolve, 1500)))
+            .then(() => this.centerScene());
     }
 
     /**
@@ -297,17 +295,6 @@ class Visualization {
 
     // #region menu functions
     public saveSvg() {
-        //let css = new Array<string>();
-        
-        for (const key in document.styleSheets) {
-            console.log(key);
-            console.log(document.styleSheets[key]);
-            let rules = (document.styleSheets[key] as CSSStyleSheet).cssRules
-            for (const rule in rules) {
-                console.log(rules[rule].cssText);
-            }
-        }
-
         d3.text(Resources.componentSvgCss)
             .then(x => {
                 let svgData = `
@@ -355,8 +342,6 @@ class Visualization {
      * @memberof Visualization
      */
     public reinitialize() {
-        this.realigned = false;
-
         if (this.depiction === undefined) this.setupScene();
         else this.setupLigandScene();
 
@@ -691,12 +676,10 @@ class Visualization {
             .force('link', forceLink)
             .force('charge', charge) //strength 
             .force('collision', collision)
-            .on('tick', () => this.simulationStep())
-            .on('end', () => this.positionSceneOnSimulationEnd());
+            .on('tick', () => this.simulationStep());
 
         this.dragHandler(this.nodes);
         if (this.zoomHandler !== undefined) this.zoomHandler(this.svg, d3.zoomIdentity);
-        this.centerScene();
     }
 
 
@@ -774,19 +757,6 @@ class Visualization {
             .attr('y2', (x: any) => x.target.y);
     }
 
-    /**
-     * Bit of a hack to improve visual for ions.
-     *
-     * @private
-     * @memberof Visualization
-     */
-    private positionSceneOnSimulationEnd() { 
-        if (!this.realigned) {
-            this.realigned = true;
-            this.centerScene();
-        }
-    }
-
 
     private nodeHighlight(x: Model.InteractionNode, i: number, g: any) {
         x.scale = 1.5;
-- 
GitLab


From 16f301ff2db1bd67a6ca31ffccd8d9ca8d037743 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 19 Feb 2020 11:04:56 +0000
Subject: [PATCH 59/66] revert name change

---
 demo_component.html        | 6 +++---
 dependencies/index.html    | 6 +++---
 src/component/component.js | 4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/demo_component.html b/demo_component.html
index 2273b0f..3407c0a 100644
--- a/demo_component.html
+++ b/demo_component.html
@@ -22,21 +22,21 @@
     <!--Mode A-->
     <div style="position: relative; float: left;">
       <div style="width: 500px; height: 500px; position: relative">
-        <pdbe-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdbe-interactions>
+        <pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
       </div>
     </div>
 
     <!--Mode B-->
     <div style="position: relative; float: left;">
       <div style="width: 500px; height: 500px; position: relative">
-        <pdbe-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdbe-interactions>
+        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
       </div>
     </div>
 
     <!--Mode C-->
     <div style="position: relative; float: left;">
         <div style="width: 500px; height: 500px; position: relative">
-          <pdbe-interactions pdb-res-name="CLR" zoom-on></pdbe-interactions>
+          <pdb-interactions pdb-res-name="CLR" zoom-on></pdb-interactions>
         </div>
       </div>
       
diff --git a/dependencies/index.html b/dependencies/index.html
index fe43c24..e1b9f6d 100644
--- a/dependencies/index.html
+++ b/dependencies/index.html
@@ -24,13 +24,13 @@
 <script>
     var renderBmInteractions = function (id, bmId) {
         var int =
-            `<pdbe-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdbe-interactions>`
+            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
     var renderLigandInteractions = function (id, chain, resId) {
         var int =
-            `<pdbe-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdbe-interactions>`
+            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-interactions>`
         document.getElementById('rt').innerHTML = int;
     };
 
@@ -122,7 +122,7 @@
     </div>
     <div style="position: relative; float: left;">
         <div id="rt 1" style="width: 500px; height: 500px; position: relative">
-            <pdbe-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdbe-interactions>
+            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-interactions>
         </div>
     </div>
 
diff --git a/src/component/component.js b/src/component/component.js
index 0716439..4eeb155 100644
--- a/src/component/component.js
+++ b/src/component/component.js
@@ -3,7 +3,7 @@ import { LitElement, html } from 'lit-element';
 import "../styles/pdbe-interactions.css";
 
 // Extend the LitElement base class
-class pdbeInteractions extends LitElement {
+class pdbeLigandEnv extends LitElement {
 
   //Get properties / attribute values
   static get properties() {
@@ -90,4 +90,4 @@ class pdbeInteractions extends LitElement {
 
 }
 // Register the new element with the browser.
-customElements.define('pdbe-interactions', pdbeInteractions);
\ No newline at end of file
+customElements.define('pdb-interactions', pdbeLigandEnv);
\ No newline at end of file
-- 
GitLab


From 06c36249f6b5f54ce5b727940c356ef9a8e045c2 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Wed, 19 Feb 2020 15:04:51 +0000
Subject: [PATCH 60/66] few menu changes

change of labels and general order of icons
---
 src/plugin/ui.ts | 73 +++++++++++++++++++++++++-----------------------
 1 file changed, 38 insertions(+), 35 deletions(-)

diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index 446cf85..8c63d3f 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -169,26 +169,35 @@ class UI {
             .style('display', 'none')
             .style('opacity', 0);
 
-        if (params.fullScreen) {
+        if (params.help) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-fullscreen-btn')
-                .attr('title', 'Fullscreen')
-                .attr('class', 'icon icon-common icon-fullscreen')
-                .on('click', () => this.fullScreen());
-        }
+                .attr('id', 'pdbe-int-help-btn')
+                .attr('title', 'Help')
+                .attr('class', 'icon icon-common icon-question-circle')
+                .on('click', () => this.showHelp());
 
-        if (params.reinitialize) {
-            dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-home-btn')
-                .attr('title', 'Reset camera')
-                .attr('class', 'icon icon-common icon-sync-alt')
-                .on('click', () => this.reinitialize());
+            let cont = d3.select(this.parent).append('div').attr('id', 'pdbe-int-help-container')
+            let navbar = cont.append('div').classed('pdbe-int-help-navbar', true);
+
+            navbar.append('a')
+                .classed('active', true)
+                .attr('id', 'pdbe-int-help-residues-btn')
+                .text('Ligands and residues')
+                .on('click', () => this.changeHelp(true));
+
+            navbar.append('a')
+                .attr('id', 'pdbe-int-help-bonds-btn')
+                .text('Interactions')
+                .on('click', () => this.changeHelp(false));
+
+            cont.append('div').attr('id', 'pdbe-int-help-ligands').html(helpLigands);
+            cont.append('div').attr('id', 'pdbe-int-help-bonds').html(helpBonds);
         }
 
         if (params.downloadImage) {
             dynamicPanel.append('i')
                 .attr('id', 'pdbe-int-screenshot-btn')
-                .attr('title', 'Save SVG')
+                .attr('title', 'Screenshot')
                 .attr('class', 'icon icon-common icon-camera')
                 .on('click', () => this.saveSVG());
         }
@@ -201,6 +210,9 @@ class UI {
                 .on('click', () => this.download());
         }
 
+
+
+
         if (params.center) {
             dynamicPanel.append('i')
                 .attr('id', 'pdbe-int-center-btn')
@@ -209,29 +221,20 @@ class UI {
                 .on('click', () => this.center());
         }
 
-        if (params.help) {
+        if (params.fullScreen) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-help-btn')
-                .attr('title', 'Show help')
-                .attr('class', 'icon icon-common icon-question-circle')
-                .on('click', () => this.showHelp());
-
-            let cont = d3.select(this.parent).append('div').attr('id', 'pdbe-int-help-container')
-            let navbar = cont.append('div').classed('pdbe-int-help-navbar', true);
-
-            navbar.append('a')
-                .classed('active', true)
-                .attr('id', 'pdbe-int-help-residues-btn')
-                .text('Ligands and residues')
-                .on('click', () => this.changeHelp(true));
-
-            navbar.append('a')
-                .attr('id', 'pdbe-int-help-bonds-btn')
-                .text('Interactions')
-                .on('click', () => this.changeHelp(false));
+                .attr('id', 'pdbe-int-fullscreen-btn')
+                .attr('title', 'Toggle Expanded')
+                .attr('class', 'icon icon-common icon-fullscreen')
+                .on('click', () => this.fullScreen());
+        }
 
-            cont.append('div').attr('id', 'pdbe-int-help-ligands').html(helpLigands);
-            cont.append('div').attr('id', 'pdbe-int-help-bonds').html(helpBonds);
+        if (params.reinitialize) {
+            dynamicPanel.append('i')
+                .attr('id', 'pdbe-int-home-btn')
+                .attr('title', 'Reset Camera')
+                .attr('class', 'icon icon-common icon-sync-alt')
+                .on('click', () => this.reinitialize());
         }
 
         if (params.tooltip) {
@@ -353,7 +356,7 @@ class UI {
 
             this.display.centerScene();
         } else {
-            this.display.fullScreen = true;            
+            this.display.fullScreen = true;
 
             this.parent.parentElement.style.width = `${this.originalWidth}px`;
             this.parent.parentElement.style.height = `${this.originalHeight}px`;
-- 
GitLab


From f9c5c549ef6546725f523dd085d2b56da33e286e Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 24 Feb 2020 11:31:46 +0000
Subject: [PATCH 61/66] rebrand component pdbe-interactions -> pdb-ligand-env

---
 CHANGELOG.md                                  | 12 ++-
 README.md                                     | 25 +++---
 demo_component.html                           |  4 +-
 demo_plugin.html                              |  6 +-
 dependencies/index.html                       | 16 ++--
 ...{snfg_visuals.xml => pdb-snfg-visuals.xml} |  0
 gulpfile.js                                   |  8 +-
 package-lock.json                             |  4 +-
 package.json                                  |  4 +-
 src/component/component.js                    |  6 +-
 src/plugin/manager.ts                         | 12 +--
 src/plugin/resources.ts                       |  6 +-
 src/plugin/ui.ts                              | 84 +++++++++----------
 ...actions-svg.css => pdb-ligand-env-svg.css} | 60 ++++++-------
 ...be-interactions.css => pdb-ligand-env.css} | 54 ++++++------
 tsconfig.json                                 |  2 +-
 webpack.config.js                             | 57 +++++--------
 17 files changed, 174 insertions(+), 186 deletions(-)
 rename dependencies/{snfg_visuals.xml => pdb-snfg-visuals.xml} (100%)
 rename src/styles/{pdbe-interactions-svg.css => pdb-ligand-env-svg.css} (62%)
 rename src/styles/{pdbe-interactions.css => pdb-ligand-env.css} (71%)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9cc32c9..5a8572c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,16 @@
-# RELEASE 0.1 - 28 January 2019
+## RELEASE 0.2 - 24 February 2020
+
+Component rembranded to `pdb-ligand-env`
+
+### Features
+
+* A lot of bug fixes and under the hood improvements
+
+## RELEASE 0.1 - 28 January 2019
 
 First release for public testing.
 
-## Features
+### Features
 
 * Bound molecule interactions view
 * Residue-level interactions view
diff --git a/README.md b/README.md
index c9dc3ea..6353f85 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# PDBe interactions component
+# PDB ligand environment component
 
 This is a web-component to display ligand structure in 2D along with its interactions. Ligand can be perceived as a set of covalently linked pdb residues (refered to as bound molecule) or a single pdb residue. This depiction can be enriched with a substructure highlight and binding site interactions.
 
@@ -36,10 +36,10 @@ A few files needs to be imported in the page before the component is attempted t
 <script src="https://d3js.org/d3.v5.min.js"></script>
 
 <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
-<link rel="stylesheet" href="pdbe-interactions-svg.css" />
+<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
 
 <!-- UI icons -->
-<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" /> 
+<link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
 <!-- Web component polyfill (only loads what it needs) -->
 <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8"></script>
@@ -47,31 +47,32 @@ A few files needs to be imported in the page before the component is attempted t
     charset="utf-8"></script>
 
 <!--PDBe interactions component-->
-<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+<script type="module" src="pdb-ligand-env-component-0.1.0.js"></script>
 ```
 
 #### A) Ligand interactions
 
 ```html
-<pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
+<pdb-ligand-env pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-ligand-env>
 ```
 
 #### B) Bound molecule interactions
 
 ```html
-<pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+<pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1"></pdb-ligand-env>
 ```
 
 #### C) Ligand/chemical component
 
 ```html
-<pdb-interactions pdb-res-name="CLR" zoom-on ></pdb-interactions>
+<pdb-ligand-env pdb-res-name="CLR" zoom-on ></pdb-ligand-env>
 ```
 
 The component contains a number of properties that can be set, in order to change data that are being displayed. First you need to define a component on the page:
 
 ```html
-<ligand-display id='SIA-component'></ligand-display>
+
+<pdb-ligand-env id='SIA-component'></pdb-ligand-env>
 ```
 
 and then inject data you want to display e.g.:
@@ -100,14 +101,14 @@ The component can be also added to DOM directly from JavaScript. There are some
 <script src="https://d3js.org/d3.v5.min.js"></script>
 
 <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
-<link rel="stylesheet" href="pdbe-interactions-svg.css" />
+<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
 
 <!-- UI icons -->
 <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
-<!--PDBe interactions plugin-->
-<script src="pdbe-interactions-plugin.js"></script>
-<link rel="stylesheet" href="pdbe-interactions.css" />
+<!--PDB ligand environment plugin-->
+<script src="pdb-ligand-env-plugin.js"></script>
+<link rel="stylesheet" href="pdb-ligand-env.css" />
 
 ```
 
diff --git a/demo_component.html b/demo_component.html
index 3407c0a..fd06611 100644
--- a/demo_component.html
+++ b/demo_component.html
@@ -4,7 +4,7 @@
 
     <script src="https://d3js.org/d3.v5.min.js"></script>    
     <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
-    <link rel="stylesheet" href="pdbe-interactions-svg.css" />    
+    <link rel="stylesheet" href="pdb-ligand-env-svg.css" />    
     <!-- UI icons -->
     <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />    
     <!-- Web component polyfill (only loads what it needs) -->
@@ -13,7 +13,7 @@
     <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
         charset="utf-8"></script>    
     <!--PDBe interactions component-->
-    <script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+    <script type="module" src="pdb-ligand-env-component-0.2.0.js"></script>
 
   </head>
   
diff --git a/demo_plugin.html b/demo_plugin.html
index a1f1a87..33903a0 100644
--- a/demo_plugin.html
+++ b/demo_plugin.html
@@ -2,11 +2,11 @@
 <html lang="en">
   <head>
     
-    <link rel="stylesheet" href="pdbe-interactions.css" />
+    <link rel="stylesheet" href="pdb-ligand-env.css" />
 
     <script src="https://d3js.org/d3.v5.min.js"></script>
     <!-- CSS style to be used for scene drawing (required for saving SVGs.) -->
-    <link rel="stylesheet" href="pdbe-interactions-svg.css" />
+    <link rel="stylesheet" href="pdb-ligand-env-svg.css" />
     <!-- UI icons -->
     <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
     <!-- Web component polyfill (only loads what it needs) -->
@@ -16,7 +16,7 @@
         charset="utf-8"></script>
   
     <!--PDBe interactions plugin-->
-    <script src="pdbe-interactions-plugin.js"></script>
+    <script src="pdb-ligand-env-plugin.js"></script>
     
     <!--Initialize Visualization-->
     <script>
diff --git a/dependencies/index.html b/dependencies/index.html
index e1b9f6d..4f1e3fc 100644
--- a/dependencies/index.html
+++ b/dependencies/index.html
@@ -3,7 +3,7 @@
 <script src="https://d3js.org/d3.v5.min.js"></script>
 <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
 <!--testing purposes only-->
-<link rel="stylesheet" href="pdbe-interactions-svg.css" />
+<link rel="stylesheet" href="pdb-ligand-env-svg.css" />
 <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
 <!-- MOL* -->
@@ -11,8 +11,6 @@
     href="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/css/molstar-light-0.0.1.css">
 <script src="https://wwwdev.ebi.ac.uk/pdbe/pdb-component-library/v1.0/js/molstar-0.0.1.js"></script>
 
-<!-- <script src="pdbe-interactions-plugin.js"></script> -->
-
 <!-- Web component polyfill (only loads what it needs) -->
 <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-lite.js" charset="utf-8">
 </script>
@@ -20,17 +18,17 @@
 <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
     charset="utf-8"></script>
 
-<script type="module" src="pdbe-interactions-component-0.1.0.js"></script>
+<script type="module" src="pdb-ligand-env-component-0.2.0.js"></script>
 <script>
     var renderBmInteractions = function (id, bmId) {
         var int =
-            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-interactions>`
+            `<pdb-ligand-env style="border: 1px solid black" pdb-id="${id}" bound-molecule-id="${bmId}"></pdb-ligand-env>`
         document.getElementById('rt').innerHTML = int;
     };
 
     var renderLigandInteractions = function (id, chain, resId) {
         var int =
-            `<pdb-interactions style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-interactions>`
+            `<pdb-ligand-env style="border: 1px solid black" pdb-id="${id}" pdb-chain-id="${chain}" pdb-res-id="${resId}" zoom-on></pdb-ligand-env>`
         document.getElementById('rt').innerHTML = int;
     };
 
@@ -122,17 +120,17 @@
     </div>
     <div style="position: relative; float: left;">
         <div id="rt 1" style="width: 500px; height: 500px; position: relative">
-            <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-interactions>
+            <pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-ligand-env>
         </div>
     </div>
 
     <!--
         Further use in the app for bound molecule interactions:
         
-        <pdbe-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdbe-interactions>
+        <pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1"></pdb-ligand-env>
         
         for ligand interactions:
-        <pdbe-interactions pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdbe-interactions>
+        <pdb-ligand-env pdb-id="3d12" pdb-chain-id="A" pdb-res-id="200"></pdb-ligand-env>
     -->
     <script>
 
diff --git a/dependencies/snfg_visuals.xml b/dependencies/pdb-snfg-visuals.xml
similarity index 100%
rename from dependencies/snfg_visuals.xml
rename to dependencies/pdb-snfg-visuals.xml
diff --git a/gulpfile.js b/gulpfile.js
index acdded9..0fed71c 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -10,7 +10,7 @@ const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
 const banner = ['/**',
   ` * ${PKG_JSON.name}`,
   ` * @version ${PKG_JSON.version}`,
-  ' * @link https://gitlab.ebi.ac.uk/pdbe/web-components/interactions',
+  ' * @link https://gitlab.ebi.ac.uk/pdbe/web-components/ligand-env',
   ' * @license Apache 2.0',
   ' */',
   ''].join('\n');
@@ -38,7 +38,7 @@ gulp.task('clean', function() {
 });
 
 gulp.task('concatCSS', function () {
-    return gulp.src(['src/styles/pdbe-interactions-svg.css'])
+    return gulp.src(['src/styles/pdb-ligand-env-svg.css'])
         .pipe(concat(`${PKG_JSON.name}-svg.css`))
         .pipe(header(license, {} ))
 		.pipe(header(banner, {} ))
@@ -58,8 +58,8 @@ gulp.task('copyMapping', function () {
 });
 
 gulp.task('copyXML', function () {
-    return gulp.src(['dependencies/snfg_visuals.xml'])
-        .pipe(concat(`snfg_visuals.xml`))
+    return gulp.src(['dependencies/pdb-snfg-visuals.xml'])
+        .pipe(concat(`pdb-snfg-visuals.xml`))
         .pipe(gulp.dest('build/'));
 });
 
diff --git a/package-lock.json b/package-lock.json
index c50c9bb..3c5878e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
-  "name": "pdbe-interactions",
-  "version": "0.1.0",
+  "name": "pdb-ligand-env",
+  "version": "0.2.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index 8a0d325..6903dfc 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
-  "name": "pdbe-interactions",
-  "version": "0.1.0",
+  "name": "pdb-ligand-env",
+  "version": "0.2.0",
   "description": "",
   "main": "app.js",
   "dependencies": {
diff --git a/src/component/component.js b/src/component/component.js
index 4eeb155..5787f89 100644
--- a/src/component/component.js
+++ b/src/component/component.js
@@ -1,9 +1,9 @@
 // Import the LitElement base class and html helper function
 import { LitElement, html } from 'lit-element';
-import "../styles/pdbe-interactions.css";
+import "../styles/pdb-ligand-env.css";
 
 // Extend the LitElement base class
-class pdbeLigandEnv extends LitElement {
+class pdbLigandEnv extends LitElement {
 
   //Get properties / attribute values
   static get properties() {
@@ -90,4 +90,4 @@ class pdbeLigandEnv extends LitElement {
 
 }
 // Register the new element with the browser.
-customElements.define('pdb-interactions', pdbeLigandEnv);
\ No newline at end of file
+customElements.define('pdb-ligand-env', pdbLigandEnv);
\ No newline at end of file
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 5ccee44..3e03172 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -46,7 +46,7 @@ class Visualization {
 
         this.svg = d3.select(this.parent)
             .append('div')
-            .attr('id', 'pdbe-int-root')
+            .attr('id', 'pdb-lig-env-root')
             .append('svg')
             .style('background-color', 'white')
             .attr('xmlns', 'http://www.w3.org/2000/svg')
@@ -533,14 +533,14 @@ class Visualization {
 
         this.links
             .append('line')
-            .classed('pdbe-int-svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
+            .classed('pdb-lig-env-svg-shadow-bond', (x: Model.Link) => x.getLinkClass() !== 'hydrophobic')
             .on('click', (x: Model.Link) => this.linkMouseClickEventHandler(x))
             .on('mouseenter', (x: Model.Link) => this.linkMouseOverEventHandler(x))
             .on('mouseleave', () => this.linkMouseOutEventHandler());
 
         this.links
             .append('line')
-            .attr('class', (e: Model.Link) => `pdbe-int-svg-bond pdbe-int-svg-bond-${e.getLinkClass()}`)
+            .attr('class', (e: Model.Link) => `pdb-lig-env-svg-bond pdb-lig-env-svg-bond-${e.getLinkClass()}`)
             .attr('marker-mid', (e: Model.Link) => e.hasClash() ? 'url(#clash)' : '')
             .on('mouseenter', (x: Model.Link) => this.linkMouseOverEventHandler(x))
             .on('mouseleave', () => this.linkMouseOutEventHandler());
@@ -598,7 +598,7 @@ class Visualization {
      */
     private processError(e: any, msg: string) {
         this.canvas.append('text')
-            .classed('pdbe-int-svg-node', true)
+            .classed('pdb-lig-env-svg-node', true)
             .attr('x', this.parent.clientWidth / 3)
             .attr('y', this.parent.clientHeight / 2)
             .text(msg)
@@ -649,7 +649,7 @@ class Visualization {
 
         this.nodes.filter((x: Model.InteractionNode) => !x.residue.isLigand)
             .on('click', (x: Model.InteractionNode) => this.fireExternalNodeEvent(x, Config.interactionClickEvent))
-            .attr('class', (x: Model.InteractionNode) => `pdbe-int-svg-node pdbe-int-svg-${x.residue.getResidueType()}-res`)
+            .attr('class', (x: Model.InteractionNode) => `pdb-lig-env-svg-node pdb-lig-env-svg-${x.residue.getResidueType()}-res`)
             .on('mouseenter', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseleave', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
 
@@ -704,7 +704,7 @@ class Visualization {
             .selectAll()
             .data(this.bindingSite.interactionNodes)
             .enter().append('g')
-            .attr('class', (e: Model.InteractionNode) => `pdbe-int-svg-node pdbe-int-svg-${e.residue.getResidueType()}-res`)
+            .attr('class', (e: Model.InteractionNode) => `pdb-lig-env-svg-node pdb-lig-env-svg-${e.residue.getResidueType()}-res`)
             .on('click', (x: Model.InteractionNode, i: number, g: any) => this.selectLigand(x, i, g))
             .on('mouseover', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseEnterEvent(x, i, g))
             .on('mouseout', (x: Model.InteractionNode, i: number, g: any) => this.fireExternalNodeMouseLeaveEvent(x, i, g));
diff --git a/src/plugin/resources.ts b/src/plugin/resources.ts
index 7afd14a..7c3148e 100644
--- a/src/plugin/resources.ts
+++ b/src/plugin/resources.ts
@@ -1,8 +1,8 @@
 namespace Resources { 
     export const apiServer: string = 'https://wwwdev.ebi.ac.uk/pdbe/graph-api';
-    export const glycanSymbols: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/snfg_visuals.xml';
-    export const glycanMapping: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/het_mapping.json';
-    export const componentSvgCss: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/interactions/pdbe-interactions-svg.css';
+    export const glycanSymbols: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/ligand-env/pdb-snfg-visuals.xml';
+    export const glycanMapping: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/ligand-env/het_mapping.json';
+    export const componentSvgCss: string = 'https://pdbe.gitdocs.ebi.ac.uk/web-components/ligand-env/pdb-ligand-env-svg.css';
 
     export const residueTypeURL: string = "https://www.ebi.ac.uk/pdbe/api/pdb/compound/summary/";
 
diff --git a/src/plugin/ui.ts b/src/plugin/ui.ts
index 8c63d3f..0751872 100644
--- a/src/plugin/ui.ts
+++ b/src/plugin/ui.ts
@@ -1,54 +1,54 @@
 // #region help
 let helpLigands = `
-    <table class='pdbe-int-help-table'>
+    <table class='pdb-lig-env-help-table'>
         <tr>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #80A0F0; "></div>
+                <div class="pdb-lig-env-help-residue" style="background: #80A0F0; "></div>
             </td>
             <td>hydrophobic</td>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #C048C0;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #C048C0;"></div>
             </td>
             <td>negativelly charged</td>
         </tr>
         <tr>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #15A4A4;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #15A4A4;"></div>
             </td>
             <td>aromatic</td>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #15C015;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #15C015;"></div>
             </td>
             <td>polar</td>
             <td>
         </tr>
         <tr>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #F08080;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #F08080;"></div>
             </td>
             <td>cystein</td>         
             <td>
-                <div class="pdbe-int-help-residue" style="background: #00BFFF;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #00BFFF;"></div>
             </td>
             <td>water</td>                    
         </tr>
         <tr>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #F01505;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #F01505;"></div>
             </td>
             <td>positivelly charged</td>
             <td>
-                <div class="pdbe-int-help-residue" style="background: #F2F2F2;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: #F2F2F2;"></div>
             </td>
             <td>other</td>               
         </tr>
         <tr>
             <td>
-                 <div class="pdbe-int-help-residue" style="background: #F09048;"></div>
+                 <div class="pdb-lig-env-help-residue" style="background: #F09048;"></div>
             </td>
             <td>glycine</td>                            
             <td>
-                <div class="pdbe-int-help-residue" style="background: white; border: 1.2px solid black;"></div>
+                <div class="pdb-lig-env-help-residue" style="background: white; border: 1.2px solid black;"></div>
             </td>
             <td>bound molecule</td>
         </tr>
@@ -61,7 +61,7 @@ let helpLigands = `
     </table>
     `
 let helpBonds = `
-<table class='pdbe-int-help-table' style="border-bottom: 0.5px solid black; padding-bottom: 10px;">
+<table class='pdb-lig-env-help-table' style="border-bottom: 0.5px solid black; padding-bottom: 10px;">
 <tr>
     <td>
         <hr style="border: 0 none; border-top: 5px solid #AD4379; background: none; height: 0;" />
@@ -99,7 +99,7 @@ let helpBonds = `
     <td>vdw</td>
 </tr>
 </table>
-<table class="pdbe-int-help-table" style="margin-top: 5px;">
+<table class="pdb-lig-env-help-table" style="margin-top: 5px;">
 <tr>
     <td>
         <hr style="border: 0 none; border-top: 5px solid black; background: none; height: 0;" />
@@ -153,50 +153,50 @@ class UI {
 
         let toolbar = d3.select(this.parent)
             .append('div')
-            .classed('pdbe-int-toolbar-container', true)
+            .classed('pdb-lig-env-toolbar-container', true)
             .on('mouseover', () => this.displayToolbarPanel(true))
             .on('mouseout', () => this.displayToolbarPanel(false));
 
         toolbar.append('div')
-            .classed('pdbe-int-menu-panel', true)
+            .classed('pdb-lig-env-menu-panel', true)
             .append('i')
             .attr('title', 'Menu')
             .attr('class', 'icon icon-common icon-bars');
 
         let dynamicPanel = toolbar.append('div')
-            .classed('pdbe-int-menu-panel', true)
-            .attr('id', 'pdbe-int-menu-dynamic-panel')
+            .classed('pdb-lig-env-menu-panel', true)
+            .attr('id', 'pdb-lig-env-menu-dynamic-panel')
             .style('display', 'none')
             .style('opacity', 0);
 
         if (params.help) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-help-btn')
+                .attr('id', 'pdb-lig-env-help-btn')
                 .attr('title', 'Help')
                 .attr('class', 'icon icon-common icon-question-circle')
                 .on('click', () => this.showHelp());
 
-            let cont = d3.select(this.parent).append('div').attr('id', 'pdbe-int-help-container')
-            let navbar = cont.append('div').classed('pdbe-int-help-navbar', true);
+            let cont = d3.select(this.parent).append('div').attr('id', 'pdb-lig-env-help-container')
+            let navbar = cont.append('div').classed('pdb-lig-env-help-navbar', true);
 
             navbar.append('a')
                 .classed('active', true)
-                .attr('id', 'pdbe-int-help-residues-btn')
+                .attr('id', 'pdb-lig-env-help-residues-btn')
                 .text('Ligands and residues')
                 .on('click', () => this.changeHelp(true));
 
             navbar.append('a')
-                .attr('id', 'pdbe-int-help-bonds-btn')
+                .attr('id', 'pdb-lig-env-help-bonds-btn')
                 .text('Interactions')
                 .on('click', () => this.changeHelp(false));
 
-            cont.append('div').attr('id', 'pdbe-int-help-ligands').html(helpLigands);
-            cont.append('div').attr('id', 'pdbe-int-help-bonds').html(helpBonds);
+            cont.append('div').attr('id', 'pdb-lig-env-help-ligands').html(helpLigands);
+            cont.append('div').attr('id', 'pdb-lig-env-help-bonds').html(helpBonds);
         }
 
         if (params.downloadImage) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-screenshot-btn')
+                .attr('id', 'pdb-lig-env-screenshot-btn')
                 .attr('title', 'Screenshot')
                 .attr('class', 'icon icon-common icon-camera')
                 .on('click', () => this.saveSVG());
@@ -204,7 +204,7 @@ class UI {
 
         if (params.downloadData) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-download-btn')
+                .attr('id', 'pdb-lig-env-download-btn')
                 .attr('title', 'Download interactions')
                 .attr('class', 'icon icon-common icon-download')
                 .on('click', () => this.download());
@@ -215,7 +215,7 @@ class UI {
 
         if (params.center) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-center-btn')
+                .attr('id', 'pdb-lig-env-center-btn')
                 .attr('title', 'Center screen')
                 .attr('class', 'icon icon-common icon-crosshairs')
                 .on('click', () => this.center());
@@ -223,7 +223,7 @@ class UI {
 
         if (params.fullScreen) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-fullscreen-btn')
+                .attr('id', 'pdb-lig-env-fullscreen-btn')
                 .attr('title', 'Toggle Expanded')
                 .attr('class', 'icon icon-common icon-fullscreen')
                 .on('click', () => this.fullScreen());
@@ -231,7 +231,7 @@ class UI {
 
         if (params.reinitialize) {
             dynamicPanel.append('i')
-                .attr('id', 'pdbe-int-home-btn')
+                .attr('id', 'pdb-lig-env-home-btn')
                 .attr('title', 'Reset Camera')
                 .attr('class', 'icon icon-common icon-sync-alt')
                 .on('click', () => this.reinitialize());
@@ -239,15 +239,15 @@ class UI {
 
         if (params.tooltip) {
             this.tooltip = d3.select(this.parent).append('div')
-                .classed('pdbe-int-label', true)
-                .attr('id', 'pdbe-int-tooltip')
+                .classed('pdb-lig-env-label', true)
+                .attr('id', 'pdb-lig-env-tooltip')
                 .style('opacity', 0)
         }
 
         if (params.residueLabel) {
             this.residueLabel = d3.select(this.parent).append('div')
-                .classed('pdbe-int-label', true)
-                .attr('id', 'pdbe-int-residue-label')
+                .classed('pdb-lig-env-label', true)
+                .attr('id', 'pdb-lig-env-residue-label')
                 .style('opacity', 0)
         }
 
@@ -282,10 +282,10 @@ class UI {
     }
 
     private changeHelp(showResidues: boolean) {
-        let ligHelpBtn = d3.select(this.parent).select('#pdbe-int-help-residues-btn');
-        let bondHelpBtn = d3.select(this.parent).select('#pdbe-int-help-bonds-btn');
-        let bondHelpSection = d3.select(this.parent).select('#pdbe-int-help-bonds');
-        let ligHelpSection = d3.select(this.parent).select('#pdbe-int-help-ligands');
+        let ligHelpBtn = d3.select(this.parent).select('#pdb-lig-env-help-residues-btn');
+        let bondHelpBtn = d3.select(this.parent).select('#pdb-lig-env-help-bonds-btn');
+        let bondHelpSection = d3.select(this.parent).select('#pdb-lig-env-help-bonds');
+        let ligHelpSection = d3.select(this.parent).select('#pdb-lig-env-help-ligands');
 
         if (showResidues) {
             bondHelpBtn.classed('active', false);
@@ -302,8 +302,8 @@ class UI {
     }
 
     private showHelp() {
-        let el = d3.select(this.parent).select('#pdbe-int-help-container');
-        let btn = d3.select(this.parent).select('#pdbe-int-help-btn');
+        let el = d3.select(this.parent).select('#pdb-lig-env-help-container');
+        let btn = d3.select(this.parent).select('#pdb-lig-env-help-btn');
 
         if (el.style('display') === 'block') {
             el.style('display', 'none');
@@ -317,8 +317,8 @@ class UI {
     }
 
     private displayToolbarPanel(show: boolean) {
-        let dynPanel = d3.select(this.parent).select('#pdbe-int-menu-dynamic-panel');
-        let el = d3.select(this.parent).select('#pdbe-int-help-container');
+        let dynPanel = d3.select(this.parent).select('#pdb-lig-env-menu-dynamic-panel');
+        let el = d3.select(this.parent).select('#pdb-lig-env-help-container');
 
         if (!dynPanel && !el) return;
 
@@ -339,7 +339,7 @@ class UI {
      * @memberof UI
      */
     private fullScreen() {
-        let btn = d3.select(this.parent).select('#pdbe-int-fullscreen-btn');
+        let btn = d3.select(this.parent).select('#pdb-lig-env-fullscreen-btn');
 
         if (btn.attr('class') === 'icon icon-common icon-fullscreen') {
             this.display.fullScreen = true;
diff --git a/src/styles/pdbe-interactions-svg.css b/src/styles/pdb-ligand-env-svg.css
similarity index 62%
rename from src/styles/pdbe-interactions-svg.css
rename to src/styles/pdb-ligand-env-svg.css
index 03f87df..974929f 100644
--- a/src/styles/pdbe-interactions-svg.css
+++ b/src/styles/pdb-ligand-env-svg.css
@@ -1,14 +1,14 @@
-.pdbe-int-svg-shadow-node {
+.pdb-lig-env-svg-shadow-node {
     stroke-width: 0;
     fill: white;
 }
 
-.pdbe-int-svg-shadow-bond {
+.pdb-lig-env-svg-shadow-bond {
     stroke-width: 15px;
     stroke: transparent;
 }
 
-.pdbe-int-svg-bond {
+.pdb-lig-env-svg-bond {
     fill: none;
     fill-rule: evenodd;
     stroke-linecap: butt;
@@ -16,142 +16,142 @@
     stroke-opacity: 1;
 }
 
-.pdbe-int-svg-bond-ligand {
+.pdb-lig-env-svg-bond-ligand {
     stroke-width: 4px;
     stroke: black;
 }
 
-.pdbe-int-svg-bond-electrostatic {
+.pdb-lig-env-svg-bond-electrostatic {
     stroke-width: 2px;
     stroke-dasharray: 10 10;
     stroke: #3F26BF;
 }
 
-.pdbe-int-svg-bond-stacking {
+.pdb-lig-env-svg-bond-stacking {
     stroke-width: 2px;
     stroke: green;
 }
 
-.pdbe-int-svg-bond-atom-pi {
+.pdb-lig-env-svg-bond-atom-pi {
     stroke-width: 2px;
     stroke: #2E8B57;
 }
 
-.pdbe-int-svg-bond-amide {
+.pdb-lig-env-svg-bond-amide {
     stroke-width: 2px;
     stroke: green;
 }
 
-.pdbe-int-svg-bond-vdw {
+.pdb-lig-env-svg-bond-vdw {
     stroke-width: 2px;
     stroke-dasharray: 10 10;
     stroke: #9B7653;
 }
 
-.pdbe-int-svg-bond-hydrophobic {
+.pdb-lig-env-svg-bond-hydrophobic {
     stroke-width: 0px;
 }
 
-.pdbe-int-svg-bond-aromatic {
+.pdb-lig-env-svg-bond-aromatic {
     stroke-width: 4px;
     stroke-dasharray: 1 10;
     stroke: #AD4379;
 }
 
-.pdbe-int-svg-bond-metal {
+.pdb-lig-env-svg-bond-metal {
     stroke-width: 4px;
     stroke: #008080;
 }
 
-.pdbe-int-svg-bond-clashes {
+.pdb-lig-env-svg-bond-clashes {
     stroke-width: 2px;
     stroke: #FF5050;
 }
 
-.pdbe-int-svg-bond-covalent {
+.pdb-lig-env-svg-bond-covalent {
     stroke-width: 2px;
     stroke: black;
 }
 
-.pdbe-int-svg-bond-other {
+.pdb-lig-env-svg-bond-other {
     stroke-width: 1px;
     stroke: black;
 }
 
-.pdbe-int-svg-node circle {
+.pdb-lig-env-svg-node circle {
     stroke-width: 2px;
 }
 
-.pdbe-int-svg-node text {
+.pdb-lig-env-svg-node text {
     cursor: inherit;
     font-family: Arial, Helvetica, sans-serif;
     stroke: black !important;
     fill: black !important;
 }
 
-.pdbe-int-svg-node text tspan:first-child {
+.pdb-lig-env-svg-node text tspan:first-child {
     cursor: inherit;
     font-weight: 100;
     font-size: 0.75em;
 }
 
-.pdbe-int-svg-node text tspan:nth-child(2) {
+.pdb-lig-env-svg-node text tspan:nth-child(2) {
     cursor: inherit;
     font-weight: lighter;
     font-size: 0.55em;
 }
 
-.pdbe-int-svg-ligand-res {
+.pdb-lig-env-svg-ligand-res {
     stroke: black;
     fill: white;
 }
 
-.pdbe-int-svg-water-res {
+.pdb-lig-env-svg-water-res {
     stroke: #A9A9A9;
     fill: #00BFFF;
 }
 
-.pdbe-int-svg-cystein-res {
+.pdb-lig-env-svg-cystein-res {
     stroke: #A9A9A9;
     fill: #F08080;
 }
 
-.pdbe-int-svg-positive-res {
+.pdb-lig-env-svg-positive-res {
     stroke: #A9A9A9;
     fill: #F01505;
 }
 
-.pdbe-int-svg-negative-res {
+.pdb-lig-env-svg-negative-res {
     stroke: #A9A9A9;
     fill: #C048C0;
 }
 
-.pdbe-int-svg-proline-res {
+.pdb-lig-env-svg-proline-res {
     stroke: #A9A9A9;
     fill: #C0C000;
 }
 
-.pdbe-int-svg-polar-res {
+.pdb-lig-env-svg-polar-res {
     stroke: #A9A9A9;
     fill: #15C015;
 }
 
-.pdbe-int-svg-aromatic-res {
+.pdb-lig-env-svg-aromatic-res {
     stroke: #A9A9A9;
     fill: #15A4A4;
 }
 
-.pdbe-int-svg-hydrophobic-res {
+.pdb-lig-env-svg-hydrophobic-res {
     stroke: #A9A9A9;
     fill: #80A0F0;
 }
 
-.pdbe-int-svg-glycine-res {
+.pdb-lig-env-svg-glycine-res {
     stroke: #A9A9A9;
     fill: #F09048;
 }
  
-.pdbe-int-svg-other-res {
+.pdb-lig-env-svg-other-res {
     stroke: #A9A9A9;
     fill: #F2F2F2;
 
diff --git a/src/styles/pdbe-interactions.css b/src/styles/pdb-ligand-env.css
similarity index 71%
rename from src/styles/pdbe-interactions.css
rename to src/styles/pdb-ligand-env.css
index 4213549..e6181bf 100644
--- a/src/styles/pdbe-interactions.css
+++ b/src/styles/pdb-ligand-env.css
@@ -1,11 +1,11 @@
-#pdbe-int-root {
+#pdb-lig-env-root {
     cursor: default;
     border-radius: 3px;
     width: 100%;
     height: 100%;
 }
 
-.pdbe-int-label {
+.pdb-lig-env-label {
     position: absolute;
     height: auto;
     padding: 10px;
@@ -16,24 +16,24 @@
     word-wrap: normal;
 }
 
-#pdbe-int-tooltip {
+#pdb-lig-env-tooltip {
     margin: 10px 0 0 10px;
     bottom: 10px;
 }
 
-#pdbe-int-tooltip>ul {
+#pdb-lig-env-tooltip>ul {
     margin: 0;
     padding: 0;
     list-style-type: none;
 }
 
-#pdbe-int-tooltip>ul>li:first-of-type(span) {
+#pdb-lig-env-tooltip>ul>li:first-of-type(span) {
     text-align: left;
     padding: 0px !important;
     font-weight: 900;
 }
 
-.pdbe-int-menu-panel {
+.pdb-lig-env-menu-panel {
     background: #ccd4e0;
     opacity: 0.9;
     float: right;
@@ -47,28 +47,28 @@
     transition: .2s;
 }
 
-.pdbe-int-menu-panel>i {
+.pdb-lig-env-menu-panel>i {
     margin-right: 15px;
     cursor: pointer;
     font: 12px sans-serif;
 }
 
-.pdbe-int-menu-panel>i:last-child {
+.pdb-lig-env-menu-panel>i:last-child {
     margin-right: 0px;
 }
 
-.pdbe-int-menu-panel>i:hover {
+.pdb-lig-env-menu-panel>i:hover {
     color: #637ca0;
 }
 
-.pdbe-int-toolbar-container {
+.pdb-lig-env-toolbar-container {
     top: 20px;
     right: 20px;
     position: absolute;
     overflow: hidden;
 }
 
-#pdbe-int-help-container {
+#pdb-lig-env-help-container {
     font-family: sans-serif;
     background: #f6f5f3;
     display: none;
@@ -87,77 +87,77 @@
     transition: 1s;
 }
 
-#pdbe-int-help-container:first-child {
+#pdb-lig-env-help-container:first-child {
     font-weight: bold;
 }
 
-#pdbe-int-residue-label {
+#pdb-lig-env-residue-label {
     margin: 0 0 10px 10px;
     left: 10px;
     top: 10px;
 }
 
-#pdbe-int-tooltip span:first-child {
+#pdb-lig-env-tooltip span:first-child {
     text-align: left;
     padding-left: 0px !important;
     font-weight: 900;
 }
 
-#pdbe-int-tooltip span:last-child {
+#pdb-lig-env-tooltip span:last-child {
     padding-left: 10px;
 }
 
-.pdbe-int-help-table {
+.pdb-lig-env-help-table {
     border: none !important;
     margin: 0 !important;
     background-color: #f6f5f3 !important;
 }
 
-.pdbe-int-help-table td {
+.pdb-lig-env-help-table td {
     border: none !important;
 }
 
-.pdbe-int-help-table tr {
+.pdb-lig-env-help-table tr {
     height: 25px;
 }
 
-.pdbe-int-help-table tr td:first-child {
+.pdb-lig-env-help-table tr td:first-child {
     width: 25px;
     min-width: 25px;
     max-width: 25px;
 }
 
-.pdbe-int-help-table tr td:nth-child(2) {
+.pdb-lig-env-help-table tr td:nth-child(2) {
     min-width: 100px;
 }
 
-.pdbe-int-help-table tr td:nth-child(3) {
+.pdb-lig-env-help-table tr td:nth-child(3) {
     width: 25px;
     min-width: 25px;
     max-width: 25px;
 }
 
-#pdbe-int-help-bonds {
+#pdb-lig-env-help-bonds {
     display: none;
 }
 
-.pdbe-int-btn:hover {
+.pdb-lig-env-btn:hover {
     color: #637ca0;
 }
 
-.pdbe-int-help-residue {
+.pdb-lig-env-help-residue {
     width: 20px;
     height: 20px;
     border-radius: 50%;
     border: 1.2px solid #a9a9a9;
 }
 
-.pdbe-int-help-navbar {
+.pdb-lig-env-help-navbar {
     height: 20px;
     margin-bottom: 10px;
 }
 
-.pdbe-int-help-navbar a {
+.pdb-lig-env-help-navbar a {
     width: 49%;
     padding-bottom: 5px;
     border: none;
@@ -168,7 +168,7 @@
     cursor: pointer;
 }
 
-.pdbe-int-help-navbar a.active {
+.pdb-lig-env-help-navbar a.active {
     border-bottom: 2px solid #637ca0;
     color: #637ca0;
 }
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index 26381c6..2fa5b58 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,7 +10,7 @@
         "declaration": true,
         "module": "none",
         "moduleResolution": "node",
-        "out": "build/pdbe-interactions-plugin.js"
+        "out": "build/pdb-ligand-env-plugin.js"
     },
     "include": ["src/plugin/**/*", ],
     "exclude": [
diff --git a/webpack.config.js b/webpack.config.js
index 4481cb7..3019b60 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -4,26 +4,18 @@ const camelCase = require("camelcase");
 const CleanWebpackPlugin = require("clean-webpack-plugin");
 
 const PACKAGE_ROOT_PATH = process.cwd();
-//const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
 
 const config = {
   entry: ["./src/component/component.js"],
   output: {
     path: path.resolve(PACKAGE_ROOT_PATH, "build"),
-    filename: "pdbe-interactions-component-init.js"
+    filename: "pdb-ligand-env-component-init.js"
   },
   target: "web",
   devtool: "source-map",
   resolve: {
     extensions: [".js"]
   },
-//   externals: {
-//     d3: "d3",
-//     "protvista-track": "ProtvistaTrack",
-//     "protvista-sequence": "ProtvistaSequence",
-//     "resize-observer-polyfill": "ResizeObserver"
-//   },
-//   plugins: [new CleanWebpackPlugin([path.join(PACKAGE_ROOT_PATH, "dist")])],
   module: {
     rules: [
       {
@@ -39,39 +31,28 @@ const config = {
       },
       {
         test: /\.(js)$/,
-        exclude: function excludeCondition(path){
-            
-            const nonEs5SyntaxPackages = [
-              'lit-element',
-              'lit-html'
-            ]
-            
-            // DO transpile these packages
-            if (nonEs5SyntaxPackages.some( pkg => path.match(pkg))) {
-              return false;
-            }
-          
-            // Ignore all other modules that are in node_modules
-            if (path.match(/node_modules\\/)) { return true; }
-          
-            else return false;
-          },
+        exclude: function excludeCondition(path) {
+
+          const nonEs5SyntaxPackages = [
+            'lit-element',
+            'lit-html'
+          ]
+
+          // DO transpile these packages
+          if (nonEs5SyntaxPackages.some(pkg => path.match(pkg))) {
+            return false;
+          }
+
+          // Ignore all other modules that are in node_modules
+          if (path.match(/node_modules\\/)) { return true; }
+
+          else return false;
+        },
         use: {
           loader: "babel-loader",
           options: {
             babelrc: false,
-            presets: [
-              // [
-              //   "@babel/preset-env",
-              //   {
-              //     targets: {
-              //       ie: 11,
-              //       browsers: "last 2 versions"
-              //     },
-              //     modules: false
-              //   }
-              // ]
-            ],
+            presets: [],
             plugins: [
               [
                 "@babel/plugin-transform-runtime",
-- 
GitLab


From 7cfbd87dce38970ed05f4ba370dbcf7e27cb5d7c Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 24 Feb 2020 11:59:10 +0000
Subject: [PATCH 62/66] move demos to their folder

---
 README.md                                       | 2 +-
 demo_component.html => demo/demo_component.html | 6 +++---
 demo_plugin.html => demo/demo_plugin.html       | 0
 3 files changed, 4 insertions(+), 4 deletions(-)
 rename demo_component.html => demo/demo_component.html (84%)
 rename demo_plugin.html => demo/demo_plugin.html (100%)

diff --git a/README.md b/README.md
index 6353f85..42b360c 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ This is a web-component to display ligand structure in 2D along with its interac
 
 ```shell
 npm run-script build
-cp demo* build/ (this copies demo_component.html and demo_plugin.html to build folder)
+cp demo/demo* build/ (this copies demo_component.html and demo_plugin.html to build folder)
 cd build
 python3 -m http.server
 ```
diff --git a/demo_component.html b/demo/demo_component.html
similarity index 84%
rename from demo_component.html
rename to demo/demo_component.html
index fd06611..3bd18f7 100644
--- a/demo_component.html
+++ b/demo/demo_component.html
@@ -22,21 +22,21 @@
     <!--Mode A-->
     <div style="position: relative; float: left;">
       <div style="width: 500px; height: 500px; position: relative">
-        <pdb-interactions pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-interactions>
+        <pdb-ligand-env pdb-id="1cbs" pdb-res-id="200" pdb-chain-id="A"></pdb-ligand-env>
       </div>
     </div>
 
     <!--Mode B-->
     <div style="position: relative; float: left;">
       <div style="width: 500px; height: 500px; position: relative">
-        <pdb-interactions pdb-id="3d12" bound-molecule-id="bm1"></pdb-interactions>
+        <pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1"></pdb-ligand-env>
       </div>
     </div>
 
     <!--Mode C-->
     <div style="position: relative; float: left;">
         <div style="width: 500px; height: 500px; position: relative">
-          <pdb-interactions pdb-res-name="CLR" zoom-on></pdb-interactions>
+          <pdb-ligand-env pdb-res-name="CLR" zoom-on></pdb-ligand-env>
         </div>
       </div>
       
diff --git a/demo_plugin.html b/demo/demo_plugin.html
similarity index 100%
rename from demo_plugin.html
rename to demo/demo_plugin.html
-- 
GitLab


From e2ad2d600898e69f9efe403f49d17bb5d4722569 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 24 Feb 2020 14:37:37 +0000
Subject: [PATCH 63/66] add component minification

---
 README.md                |   4 +-
 demo/demo_component.html |   2 +-
 demo/demo_plugin.html    |   2 +-
 gulpfile.js              |  94 ++++++++++++++++++++---------------
 package-lock.json        | 103 +++++++++++++++++++++++++++++++++++++++
 package.json             |   1 +
 6 files changed, 164 insertions(+), 42 deletions(-)

diff --git a/README.md b/README.md
index 42b360c..4d3be49 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ A few files needs to be imported in the page before the component is attempted t
     charset="utf-8"></script>
 
 <!--PDBe interactions component-->
-<script type="module" src="pdb-ligand-env-component-0.1.0.js"></script>
+<script type="module" src="pdb-ligand-env-component-0.2.0-min.js"></script>
 ```
 
 #### A) Ligand interactions
@@ -107,7 +107,7 @@ The component can be also added to DOM directly from JavaScript. There are some
 <link rel="stylesheet" href="https://ebi.emblstatic.net/web_guidelines/EBI-Icon-fonts/v1.3/fonts.css" />
 
 <!--PDB ligand environment plugin-->
-<script src="pdb-ligand-env-plugin.js"></script>
+<script src="pdb-ligand-env-plugin-min.js"></script>
 <link rel="stylesheet" href="pdb-ligand-env.css" />
 
 ```
diff --git a/demo/demo_component.html b/demo/demo_component.html
index 3bd18f7..9957b57 100644
--- a/demo/demo_component.html
+++ b/demo/demo_component.html
@@ -13,7 +13,7 @@
     <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
         charset="utf-8"></script>    
     <!--PDBe interactions component-->
-    <script type="module" src="pdb-ligand-env-component-0.2.0.js"></script>
+    <script type="module" src="pdb-ligand-env-component-0.2.0-min.js"></script>
 
   </head>
   
diff --git a/demo/demo_plugin.html b/demo/demo_plugin.html
index 33903a0..2362187 100644
--- a/demo/demo_plugin.html
+++ b/demo/demo_plugin.html
@@ -16,7 +16,7 @@
         charset="utf-8"></script>
   
     <!--PDBe interactions plugin-->
-    <script src="pdb-ligand-env-plugin.js"></script>
+    <script src="pdb-ligand-env-plugin-min.js"></script>
     
     <!--Initialize Visualization-->
     <script>
diff --git a/gulpfile.js b/gulpfile.js
index 0fed71c..83ea795 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,74 +1,92 @@
-var gulp = require('gulp');
+const gulp = require('gulp');
 const path = require('path');
-var del = require('del');
-var concat = require('gulp-concat');
-var header = require('gulp-header');
+const del = require('del');
+const concat = require('gulp-concat');
+const header = require('gulp-header');
+const minify = require("gulp-minify");
 
 const PACKAGE_ROOT_PATH = process.cwd();
 const PKG_JSON = require(path.join(PACKAGE_ROOT_PATH, "package.json"));
 
 const banner = ['/**',
-  ` * ${PKG_JSON.name}`,
-  ` * @version ${PKG_JSON.version}`,
-  ' * @link https://gitlab.ebi.ac.uk/pdbe/web-components/ligand-env',
-  ' * @license Apache 2.0',
-  ' */',
-  ''].join('\n');
+    ` * ${PKG_JSON.name}`,
+    ` * @version ${PKG_JSON.version}`,
+    ' * @link https://gitlab.ebi.ac.uk/pdbe/web-components/ligand-env',
+    ' * @license Apache 2.0',
+    ' */',
+    ''
+].join('\n');
 
-  const license = ['/**',
-  ' * Copyright 2019-2020 Lukas Pravda <lpravda@ebi.ac.uk>',
-  ' * European Bioinformatics Institute (EBI, http://www.ebi.ac.uk/)',
-  ' * European Molecular Biology Laboratory (EMBL, http://www.embl.de/)',
-  ' * Licensed under the Apache License, Version 2.0 (the "License");',
-  ' * you may not use this file except in compliance with the License.',
-  ' * You may obtain a copy of the License at ',
-  ' * http://www.apache.org/licenses/LICENSE-2.0',
-  ' * ',
-  ' * Unless required by applicable law or agreed to in writing, software',
-  ' * distributed under the License is distributed on an "AS IS" BASIS, ',
-  ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
-  ' * See the License for the specific language governing permissions and ',
-  ' * limitations under the License.',
-  ' */',
-  ''].join('\n');
+const license = ['/**',
+    ' * Copyright 2019-2020 Lukas Pravda <lpravda@ebi.ac.uk>',
+    ' * European Bioinformatics Institute (EBI, http://www.ebi.ac.uk/)',
+    ' * European Molecular Biology Laboratory (EMBL, http://www.embl.de/)',
+    ' * Licensed under the Apache License, Version 2.0 (the "License");',
+    ' * you may not use this file except in compliance with the License.',
+    ' * You may obtain a copy of the License at ',
+    ' * http://www.apache.org/licenses/LICENSE-2.0',
+    ' * ',
+    ' * Unless required by applicable law or agreed to in writing, software',
+    ' * distributed under the License is distributed on an "AS IS" BASIS, ',
+    ' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
+    ' * See the License for the specific language governing permissions and ',
+    ' * limitations under the License.',
+    ' */',
+    ''
+].join('\n');
 
 
-gulp.task('clean', function() {
+gulp.task('clean', function () {
     return del([`build/${PKG_JSON.name}-component-${PKG_JSON.version}.js`, '!build']);
 });
 
-gulp.task('concatCSS', function () {
+gulp.task('concatCSS', () => {
     return gulp.src(['src/styles/pdb-ligand-env-svg.css'])
         .pipe(concat(`${PKG_JSON.name}-svg.css`))
-        .pipe(header(license, {} ))
-		.pipe(header(banner, {} ))
+        .pipe(header(license, {}))
+        .pipe(header(banner, {}))
         .pipe(gulp.dest('build/'));
 });
 
-gulp.task('copyIndex', function () {
+gulp.task('copyIndex', () => {
     return gulp.src(['dependencies/index.html'])
         .pipe(concat(`index.html`))
         .pipe(gulp.dest('build/'));
 });
 
-gulp.task('copyMapping', function () {
+gulp.task('copyMapping', () => {
     return gulp.src(['dependencies/het_mapping.json'])
         .pipe(concat(`het_mapping.json`))
         .pipe(gulp.dest('build/'));
 });
 
-gulp.task('copyXML', function () {
+gulp.task('copyXML', () => {
     return gulp.src(['dependencies/pdb-snfg-visuals.xml'])
         .pipe(concat(`pdb-snfg-visuals.xml`))
         .pipe(gulp.dest('build/'));
 });
 
-gulp.task('concat', function () {
-    return gulp.src([`build/${PKG_JSON.name}-plugin.js`,`build/${PKG_JSON.name}-component-init.js`])
+gulp.task('concat', () => {
+    return gulp.src([`build/${PKG_JSON.name}-plugin.js`, `build/${PKG_JSON.name}-component-init.js`])
         .pipe(concat(`${PKG_JSON.name}-component-${PKG_JSON.version}.js`))
-        .pipe(header(license, {} ))
-		.pipe(header(banner, {} ))
+        .pipe(header(license, {}))
+        .pipe(header(banner, {}))
+        .pipe(minify({
+            noSource: true
+        }))
         .pipe(gulp.dest('build/'));
 });
 
-gulp.task('default', gulp.series('clean', 'concat', 'concatCSS', 'copyXML', 'copyIndex', 'copyMapping'));
\ No newline at end of file
+gulp.task('minifyPlugin', () => {
+    return gulp.src([`build/${PKG_JSON.name}-plugin.js`])
+        .pipe(concat(`${PKG_JSON.name}-plugin.js`))
+        .pipe(header(license, {}))
+        .pipe(header(banner, {}))
+        .pipe(minify({
+            noSource: true
+        }))
+        .pipe(gulp.dest('build/'));
+});
+
+gulp.task('default', gulp.series('clean', 'concat', 'concatCSS',
+    'copyXML', 'copyIndex', 'copyMapping', 'minifyPlugin'));
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 3c5878e..cc09813 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1472,6 +1472,15 @@
         "ansi-wrap": "^0.1.0"
       }
     },
+    "ansi-cyan": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz",
+      "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
     "ansi-escapes": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
@@ -1487,6 +1496,15 @@
         "ansi-wrap": "0.1.0"
       }
     },
+    "ansi-red": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz",
+      "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
     "ansi-regex": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
@@ -5620,6 +5638,39 @@
         }
       }
     },
+    "gulp-minify": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/gulp-minify/-/gulp-minify-3.1.0.tgz",
+      "integrity": "sha512-ixF41aYg+NQikI8hpoHdEclYcQkbGdXQu1CBdHaU7Epg8H6e8d2jWXw1+rBPgYwl/XpKgjHj7NI6gkhoSNSSAg==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^1.0.1",
+        "minimatch": "^3.0.2",
+        "plugin-error": "^0.1.2",
+        "terser": "^3.7.6",
+        "through2": "^2.0.3",
+        "vinyl": "^2.1.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "terser": {
+          "version": "3.17.0",
+          "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
+          "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==",
+          "dev": true,
+          "requires": {
+            "commander": "^2.19.0",
+            "source-map": "~0.6.1",
+            "source-map-support": "~0.5.10"
+          }
+        }
+      }
+    },
     "gulplog": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
@@ -7940,6 +7991,58 @@
         "find-up": "^3.0.0"
       }
     },
+    "plugin-error": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
+      "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
+      "dev": true,
+      "requires": {
+        "ansi-cyan": "^0.1.1",
+        "ansi-red": "^0.1.1",
+        "arr-diff": "^1.0.1",
+        "arr-union": "^2.0.1",
+        "extend-shallow": "^1.1.2"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
+          "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "^1.0.1",
+            "array-slice": "^0.2.3"
+          }
+        },
+        "arr-union": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
+          "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=",
+          "dev": true
+        },
+        "array-slice": {
+          "version": "0.2.3",
+          "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+          "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
+          "dev": true
+        },
+        "extend-shallow": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
+          "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
+          "dev": true,
+          "requires": {
+            "kind-of": "^1.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
+          "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
+          "dev": true
+        }
+      }
+    },
     "pluralize": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
diff --git a/package.json b/package.json
index 6903dfc..fb953c6 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
     "gulp": "^4.0.2",
     "gulp-concat": "^2.6.1",
     "gulp-header": "^2.0.9",
+    "gulp-minify": "^3.1.0",
     "live-server": "^1.2.1",
     "npm-run-all": "^4.1.3",
     "onchange": "^6.1.0",
-- 
GitLab


From 78b257bbc0be0fa5c1c9fbb8f68a0589e79bb0a7 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 24 Feb 2020 16:02:24 +0000
Subject: [PATCH 64/66] fix typo

---
 dependencies/index.html | 2 +-
 src/plugin/depiction.ts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/dependencies/index.html b/dependencies/index.html
index 4f1e3fc..0296deb 100644
--- a/dependencies/index.html
+++ b/dependencies/index.html
@@ -18,7 +18,7 @@
 <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
     charset="utf-8"></script>
 
-<script type="module" src="pdb-ligand-env-component-0.2.0.js"></script>
+<script type="module" src="pdb-ligand-env-component-0.2.0-min.js"></script>
 <script>
     var renderBmInteractions = function (id, bmId) {
         var int =
diff --git a/src/plugin/depiction.ts b/src/plugin/depiction.ts
index 0a08a57..91b1d14 100644
--- a/src/plugin/depiction.ts
+++ b/src/plugin/depiction.ts
@@ -181,7 +181,7 @@ class Depiction {
         this.structure.selectAll()
             .data(this.atoms.filter(x => Object.keys(x.label).length != 0))
             .enter().append('circle')
-            .classed('pdbe-int-svg-shadow-node', true)
+            .classed('pdb-lig-env-svg-shadow-node', true)
             .attr('cx', (x: any) => x.position.x)
             .attr('cy', (x: any) => x.position.y)
             .attr('r', 15);
-- 
GitLab


From 1f6931dd77200172785f3b22cf81968399b356a4 Mon Sep 17 00:00:00 2001
From: Lukas Pravda <lpravda@ebi.ac.uk>
Date: Mon, 24 Feb 2020 16:02:50 +0000
Subject: [PATCH 65/66] increase visuals size by 20%

---
 dependencies/pdb-snfg-visuals.xml | 428 +++++++++++++++---------------
 src/plugin/config.ts              |   2 +-
 src/plugin/manager.ts             |   2 +-
 src/styles/pdb-ligand-env-svg.css |   8 +-
 4 files changed, 220 insertions(+), 220 deletions(-)

diff --git a/dependencies/pdb-snfg-visuals.xml b/dependencies/pdb-snfg-visuals.xml
index 1984d55..e1bd990 100644
--- a/dependencies/pdb-snfg-visuals.xml
+++ b/dependencies/pdb-snfg-visuals.xml
@@ -2,298 +2,298 @@
   <glycans>
     <!--Hexose-->
     <g name="Glc">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" r="30" />
     </g>
     <g name="Man">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" r="30" />
     </g>
     <g name="Gal">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" r="30" />
     </g>
     <g name="Gul">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" r="30" />
     </g>
     <g name="Alt">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" r="30" />
     </g>
     <g name="All">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" r="30" />
     </g>
     <g name="Tal">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" r="30" />
     </g>
     <g name="Ido">
-      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" r="25" />
+      <circle style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" r="30" />
     </g>
     <!--HexNAc-->
-    <g name="GlcNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
+    <g name="GlcNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
     </g>
-    <g name="ManNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+    <g name="ManNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
-    <g name="GalNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
+    <g name="GalNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
     </g>
-    <g name="GulNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
+    <g name="GulNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
     </g>
-    <g name="AltNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
+    <g name="AltNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
     </g>
-    <g name="AllNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
+    <g name="AllNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
     </g>
-    <g name="TalNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
+    <g name="TalNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
     </g>
-    <g name="IdoNAc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" />
+    <g name="IdoNAc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" />
     </g>
     <!--Hexosamine-->
-    <g name="GlcN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="ManN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#00a651;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="GalN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="GulN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#f47920;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="AltN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="AllN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#a54399;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="TalN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="IdoN" transform="translate(-25,-25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
+    <g name="GlcN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="ManN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#00a651;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="GalN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="GulN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#f47920;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="AltN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="AllN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#a54399;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="TalN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="IdoN" transform="translate(-30,-30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
     </g>
     <!--Hexuronate-->
-    <g name="GlcA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="ManA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#00a651;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="GalA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="GulA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#f47920;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="AltA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="AllA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#a54399;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="TalA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
-    </g>
-    <g name="IdoA" transform="translate(-25,-25) rotate(-45 25 25)">
-      <path style="stroke:none;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" d="M0 0 L50 0 L50 50 Z"/>
-      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 50 L50 50 Z"/>
-      <rect x="0" y="0" width="50" height="50" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
-      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L50 50" />
+    <g name="GlcA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="ManA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#00a651;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="GalA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="GulA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#f47920;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="AltA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="AllA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#a54399;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="TalA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
+    </g>
+    <g name="IdoA" transform="translate(-30,-30) rotate(-45 30 30)">
+      <path style="stroke:none;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" d="M0 0 L60 0 L60 60 Z"/>
+      <path style="stroke:none;fill-rule:nonzero;fill:#ffffff;fill-opacity:1" d="M0 0 L0 60 L60 60 Z"/>
+      <rect x="0" y="0" width="60" height="60" style="fill:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;"/>
+      <path style="fill:none;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" d="M 0 0 L60 60" />
     </g>
     <!--Deoxyhexose-->
-    <g name="Qui" transform="translate(-25,-25)">
-      <polygon points="25,0 0,50 50,50" style="fill-rule:nonzero;fill:#0090bc;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="Qui" transform="translate(-30,-30)">
+      <polygon points="30,0 0,60 60,60" style="fill-rule:nonzero;fill:#0090bc;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
-    <g name="Rha" transform="translate(-25,-25)">
-      <polygon points="25,0 0,50 50,50" style="fill-rule:nonzero;fill:#00a651;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="Rha" transform="translate(-30,-30)">
+      <polygon points="30,0 0,60 60,60" style="fill-rule:nonzero;fill:#00a651;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
-    <g name="6dGul" transform="translate(-25,-25)">
-      <polygon points="25,0 0,50 50,50" style="fill-rule:nonzero;fill:#f47920;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="6dGul" transform="translate(-30,-30)">
+      <polygon points="30,0 0,60 60,60" style="fill-rule:nonzero;fill:#f47920;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
-    <g name="6dAlt" transform="translate(-25,-25)">
-      <polygon points="25,0 0,50 50,50" style="fill-rule:nonzero;fill:#f69ea1;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="6dAlt" transform="translate(-30,-30)">
+      <polygon points="30,0 0,60 60,60" style="fill-rule:nonzero;fill:#f69ea1;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
-    <g name="6dTal" transform="translate(-25,-25)">
-      <polygon points="25,0 0,50 50,50" style="fill-rule:nonzero;fill:#8fcce9;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="6dTal" transform="translate(-30,-30)">
+      <polygon points="30,0 0,60 60,60" style="fill-rule:nonzero;fill:#8fcce9;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
-    <g name="Fuc" transform="translate(-25,-25)">
-      <polygon points="25,0 0,50 50,50" style="fill-rule:nonzero;fill:#ed1c24;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="Fuc" transform="translate(-30,-30)">
+      <polygon points="30,0 0,60 60,60" style="fill-rule:nonzero;fill:#ed1c24;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
     <!--DeoxyhexNAc-->
-    <g name="QuiNAc" transform="translate(-25,-25)">
-      <polygon points="25,0 25,50 50,50" style="fill-rule:nonzero;fill:#0090bc;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <polygon points="25,0 50,50 0,50" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <path d="M25 0 L25 50" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-    </g>
-    <g name="RhaNAc" transform="translate(-25,-25)">
-      <polygon points="25,0 25,50 50,50" style="fill-rule:nonzero;fill:#00a651;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <polygon points="25,0 50,50 0,50" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <path d="M25 0 L25 50" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-    </g>
-    <g name="6dAltNAc" transform="translate(-25,-25)">
-      <polygon points="25,0 25,50 50,50" style="fill-rule:nonzero;fill:#f69ea1;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <polygon points="25,0 50,50 0,50" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <path d="M25 0 L25 50" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-    </g>
-    <g name="6dTalNAc" transform="translate(-25,-25)">
-      <polygon points="25,0 25,50 50,50" style="fill-rule:nonzero;fill:#8fcce9;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <polygon points="25,0 50,50 0,50" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <path d="M25 0 L25 50" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-    </g>
-    <g name="FucNAc" transform="translate(-25,-25)">
-      <polygon points="25,0 25,50 50,50" style="fill-rule:nonzero;fill:#ed1c24;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <polygon points="25,0 50,50 0,50" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
-      <path d="M25 0 L25 50" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    <g name="QuiNAc" transform="translate(-30,-30)">
+      <polygon points="30,0 30,60 60,60" style="fill-rule:nonzero;fill:#0090bc;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <polygon points="30,0 60,60 0,60" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <path d="M30 0 L30 60" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    </g>
+    <g name="RhaNAc" transform="translate(-30,-30)">
+      <polygon points="30,0 30,60 60,60" style="fill-rule:nonzero;fill:#00a651;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <polygon points="30,0 60,60 0,60" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <path d="M30 0 L30 60" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    </g>
+    <g name="6dAltNAc" transform="translate(-30,-30)">
+      <polygon points="30,0 30,60 60,60" style="fill-rule:nonzero;fill:#f69ea1;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <polygon points="30,0 60,60 0,60" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <path d="M30 0 L30 60" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    </g>
+    <g name="6dTalNAc" transform="translate(-30,-30)">
+      <polygon points="30,0 30,60 60,60" style="fill-rule:nonzero;fill:#8fcce9;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <polygon points="30,0 60,60 0,60" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <path d="M30 0 L30 60" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+    </g>
+    <g name="FucNAc" transform="translate(-30,-30)">
+      <polygon points="30,0 30,60 60,60" style="fill-rule:nonzero;fill:#ed1c24;fill-opacity:1;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <polygon points="30,0 60,60 0,60" style="fill-rule:nonzero;fill:none;fill-opacity:1;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
+      <path d="M30 0 L30 60" style="fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:#000000;stroke-opacity:1;stroke-miterlimit:10;" />
     </g>
     <!--Di-deoxyhexose-->
-    <g name="Oli" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
+    <g name="Oli" transform="translate(-30,-15)">
+      <rect x="0" y="0" width="60" height="30" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
     </g>
-    <g name="Tyv" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+    <g name="Tyv" transform="translate(-30,-15)">
+      <rect x="0" y="0" width="60" height="30" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
-    <g name="Abe" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
+    <g name="Abe" transform="translate(-30,-15)">
+      <rect x="0" y="0" width="60" height="30" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
     </g>
-    <g name="Par" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
+    <g name="Par" transform="translate(-30,-15)">
+      <rect x="0" y="0" width="60" height="30" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
     </g>
-    <g name="Dig" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
+    <g name="Dig" transform="translate(-30,-15)">
+      <rect x="0" y="0" width="60" height="30" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
     </g>
-    <g name="Col" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
+    <g name="Col" transform="translate(-30,-15)">
+      <rect x="0" y="0" width="60" height="30" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
     </g>
     <!--Pentose-->
-    <g name="Ara" transform="translate(-47.5, -50.052)">
-      <polygon points="47.5,18.75 54.75,40.25 77.25,40.25 59.25,53.75 65.75,75.25 47.5,62.5 29.25,75.25 35.75,53.75 17.75,40.25 40.25,40.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+    <g name="Ara" transform="translate(-57, -60.06)">
+      <polygon points="57.0,22.5 65.7,48.3 92.7,48.3 71.1,64.5 78.9,90.3 57.0,75.0 35.1,90.3 42.9,64.5 21.3,48.3 48.3,48.3" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
-    <g name="Lyx" transform="translate(-47.5, -50.052)">
-      <polygon points="47.5,18.75 54.75,40.25 77.25,40.25 59.25,53.75 65.75,75.25 47.5,62.5 29.25,75.25 35.75,53.75 17.75,40.25 40.25,40.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
+    <g name="Lyx" transform="translate(-57, -60.06)">
+      <polygon points="57.0,22.5 65.7,48.3 92.7,48.3 71.1,64.5 78.9,90.3 57.0,75.0 35.1,90.3 42.9,64.5 21.3,48.3 48.3,48.3" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
     </g>
-    <g name="Xyl" transform="translate(-47.5, -50.052)">
-      <polygon points="47.5,18.75 54.75,40.25 77.25,40.25 59.25,53.75 65.75,75.25 47.5,62.5 29.25,75.25 35.75,53.75 17.75,40.25 40.25,40.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
+    <g name="Xyl" transform="translate(-57, -60.06)">
+      <polygon points="57.0,22.5 65.7,48.3 92.7,48.3 71.1,64.5 78.9,90.3 57.0,75.0 35.1,90.3 42.9,64.5 21.3,48.3 48.3,48.3" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
     </g>
-    <g name="Rib" transform="translate(-47.5, -50.052)">
-      <polygon points="47.5,18.75 54.75,40.25 77.25,40.25 59.25,53.75 65.75,75.25 47.5,62.5 29.25,75.25 35.75,53.75 17.75,40.25 40.25,40.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
+    <g name="Rib" transform="translate(-57, -60.06)">
+      <polygon points="57.0,22.5 65.7,48.3 92.7,48.3 71.1,64.5 78.9,90.3 57.0,75.0 35.1,90.3 42.9,64.5 21.3,48.3 48.3,48.3" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
     </g>
     <!--Deoxynonulosonate-->
-    <g name="Kdn" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+    <g name="Kdn" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
-    <g name="Neu5Ac" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
+    <g name="Neu5Ac" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
     </g>
-    <g name="Neu5Gc" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
+    <g name="Neu5Gc" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
     </g>
-    <g name="Neu" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" />
+    <g name="Neu" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" />
     </g>
-    <g name="Sia" transform="translate(-25,-25)">
-      <rect x="0" y="0" width="50" height="50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ed1c24;fill-opacity:1" />
+    <g name="Sia" transform="translate(-30,-30)">
+      <rect x="0" y="0" width="60" height="60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ed1c24;fill-opacity:1" />
     </g>
     <!--Di-deoxynonulosonate-->
     <g name="Pse" transform="translate(-20.625, -38.25) rotate(90, 20.625,41.25)">
-      <polygon points="20.625,0 0,41.25 20.625,82.5 41.25,41.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+      <polygon points="24.75,0 0,49.5 24.75,99 49.5,49.5" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
     <g name="Leg" transform="translate(-20.625, -38.25) rotate(90, 20.625,41.25)">
-      <polygon points="20.625,0 0,41.25 20.625,82.5 41.25,41.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
+      <polygon points="24.75,0 0,49.5 24.75,99 49.5,49.5" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
     </g>
     <g name="Aci" transform="translate(-20.625, -38.25) rotate(90, 20.625,41.25)">
-      <polygon points="20.625,0 0,41.25 20.625,82.5 41.25,41.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
+      <polygon points="24.75,0 0,49.5 24.75,99 49.5,49.5" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
     </g>
     <g name="4eLeg" transform="translate(-20.625, -38.25) rotate(90, 20.625,41.25)">
-      <polygon points="20.625,0 0,41.25 20.625,82.5 41.25,41.25" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
+      <polygon points="24.75,0 0,49.5 24.75,99 49.5,49.5" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
     </g>
     <!--Unkwnown-->
-    <g name="Bac" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
+    <g name="Bac" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
     </g>
-    <g name="LDmanHep" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+    <g name="LDmanHep" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
-    <g name="Kdo" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
+    <g name="Kdo" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
     </g>
-    <g name="Dha" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
+    <g name="Dha" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
     </g>
-    <g name="DDmanHep" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
+    <g name="DDmanHep" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
     </g>
-    <g name="MurNAc" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
+    <g name="MurNAc" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a54399;fill-opacity:1" />
     </g>
-    <g name="MurNGc" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
+    <g name="MurNGc" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#8fcce9;fill-opacity:1" />
     </g>
-    <g name="Mur" transform="translate(-18.5,-23)">
-      <polygon points="-15,25 0,0 35,0 50,25 35,50 0,50" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" />
+    <g name="Mur" transform="translate(-22.2,-27.6)">
+      <polygon points="-18,30 0,0 42,0 60,30 42,60 0,60" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#a17a4d;fill-opacity:1" />
     </g>
     <!--Assigned-->
-    <g name="Api" transform="translate(-25,-25)">
-      <polygon points="25,0 50,18 43,50 8,50 0,18" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
+    <g name="Api" transform="translate(-30,-30)">
+      <polygon points="30,0 60,22 52,60 8,60 0,22" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#0090bc;fill-opacity:1" />
     </g>
-    <g name="Fru" transform="translate(-25,-25)">
-      <polygon points="25,0 50,18 43,50 8,50 0,18" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
+    <g name="Fru" transform="translate(-30,-30)">
+      <polygon points="30,0 60,22 52,60 8,60 0,22" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#00a651;fill-opacity:1" />
     </g>
-    <g name="Tag" transform="translate(-25,-25)">
-      <polygon points="25,0 50,18 43,50 8,50 0,18" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
+    <g name="Tag" transform="translate(-30,-30)">
+      <polygon points="30,0 60,22 52,60 8,60 0,22" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#ffd400;fill-opacity:1" />
     </g>
-    <g name="Sor" transform="translate(-25,-25)">
-      <polygon points="25,0 50,18 43,50 8,50 0,18" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
+    <g name="Sor" transform="translate(-30,-30)">
+      <polygon points="30,0 60,22 52,60 8,60 0,22" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f47920;fill-opacity:1" />
     </g>
-    <g name="Psi" transform="translate(-25,-25)">
-      <polygon points="25,0 50,18 43,50 8,50 0,18" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
+    <g name="Psi" transform="translate(-30,-30)">
+      <polygon points="30,0 60,22 52,60 8,60 0,22" style="stroke:black;stroke-width:3;fill-rule:nonzero;fill:#f69ea1;fill-opacity:1" />
     </g>
   </glycans>
 </root>
diff --git a/src/plugin/config.ts b/src/plugin/config.ts
index 0e54cb7..3aa0c4a 100644
--- a/src/plugin/config.ts
+++ b/src/plugin/config.ts
@@ -1,5 +1,5 @@
 namespace Config {
-    export const nodeSize: number = 25;
+    export const nodeSize: number = 30;
     export const interactionClickEvent: string = 'PDB.interactions.click';
     export const interactionMouseoverEvent: string = 'PDB.interactions.mouseover';
     export const interactionMouseoutEvent: string = 'PDB.interactions.mouseout'
diff --git a/src/plugin/manager.ts b/src/plugin/manager.ts
index 3e03172..061ec17 100644
--- a/src/plugin/manager.ts
+++ b/src/plugin/manager.ts
@@ -670,7 +670,7 @@ class Visualization {
             .strength(0.5);
 
         let charge = d3.forceManyBody().strength(-100).distanceMin(40).distanceMax(80);
-        let collision = d3.forceCollide().radius(40);
+        let collision = d3.forceCollide().radius(45);
 
         this.simulation = d3.forceSimulation(this.bindingSite.interactionNodes)
             .force('link', forceLink)
diff --git a/src/styles/pdb-ligand-env-svg.css b/src/styles/pdb-ligand-env-svg.css
index 974929f..df14ba1 100644
--- a/src/styles/pdb-ligand-env-svg.css
+++ b/src/styles/pdb-ligand-env-svg.css
@@ -79,12 +79,12 @@
 }
 
 .pdb-lig-env-svg-node circle {
-    stroke-width: 2px;
+    stroke-width: 3px;
 }
 
 .pdb-lig-env-svg-node text {
     cursor: inherit;
-    font-family: Arial, Helvetica, sans-serif;
+    font-family: sans-serif;
     stroke: black !important;
     fill: black !important;
 }
@@ -92,13 +92,13 @@
 .pdb-lig-env-svg-node text tspan:first-child {
     cursor: inherit;
     font-weight: 100;
-    font-size: 0.75em;
+    font-size: 1em;
 }
 
 .pdb-lig-env-svg-node text tspan:nth-child(2) {
     cursor: inherit;
     font-weight: lighter;
-    font-size: 0.55em;
+    font-size: 0.75em;
 }
 
 .pdb-lig-env-svg-ligand-res {
-- 
GitLab


From 4dab3b430ba86fdb708bf4f19555cb14d3d28230 Mon Sep 17 00:00:00 2001
From: nurul <nurul@ebi.ac.uk>
Date: Thu, 26 Mar 2020 16:19:06 +0000
Subject: [PATCH 66/66] show 2aw3

---
 dependencies/index.html | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/dependencies/index.html b/dependencies/index.html
index 0296deb..99eaf80 100644
--- a/dependencies/index.html
+++ b/dependencies/index.html
@@ -123,6 +123,11 @@
             <pdb-ligand-env pdb-id="3d12" bound-molecule-id="bm1" zoom-on></pdb-ligand-env>
         </div>
     </div>
+    <div style="position: relative; float: left;">
+        <div id="rt 1" style="width: 500px; height: 500px; position: relative">
+            <pdb-ligand-env pdb-id="2aw3" bound-molecule-id="bm1" zoom-on></pdb-ligand-env>
+        </div>
+    </div>
 
     <!--
         Further use in the app for bound molecule interactions:
-- 
GitLab