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